云服务器CPU推理模型并封装成 API 的折腾记录

技术性踩雷  ·  2026-05-23

cirno.webp

前言

  • 光阴似箭,日月如梭,站长去年高考假期618期间买的优惠华为云,在11月为了更高的性能开支升级的一个mini服务器,最近马上就要过期了……我的博客和bot也近期从这台服务器上迁出了,这个服务器现在处于空闲状态。

    image.png

  • 什么?你问我为什么不续费?——啊啊天价的续费账单让人望而生畏:

    image.png

  • 啊哈哈哈哈,打扰了,转念一想,现在除了博客和bot还有自建邮箱之外(好像)就没有什么需要这么大内存的服务要跑了,阿里云99计划给的2H2G2M的服务器基本满足需求,所以就这样吧,让这台服务到期,然后消失。

  • 但是,在最近玩Gemma4-E4B的时候,我突然想到几个月前给服务器升级配置的初心——服务器推理大模型,正好服务器空闲,那么不跑白不跑,是骡子是马拉出来遛遛,于是我们开始折腾。


准备清单


过程

  • 其实很简单,就是把准备好的预编译包和模型上传到服务器后,解压程序包
  • 一定不要在本地解压,会导致包内硬链接失效程序无法运行
  • 接下来准备启动脚本,由于llamacpp专注高性能推理,不会自带配置或启动面板,我们需要先了解常用的llamacpp启动参数后使用命令行启动
  • 现贴出一个自用脚本,自行填入其中的PORTAPIKEY字段,在防火墙内配置放行PORT的端口号,并修改MODEL_PATHLLAMA_SERVER的字段能够指向本地模型:
#!/bin/bash
#===============================================================
# llama.cpp CPU 版启动脚本 —— Qwen 0.8B API 服务器
# 调优目标:单并发、零思考、最低延迟响应
#===============================================================
set -euo pipefail

# ------------------- 用户配置区 -------------------
# 模型文件路径(必须是 GGUF 格式)
MODEL_PATH="./models/Qwen3.5-0.8B-Q4_K_M.gguf"

# 服务监听地址与端口
HOST="0.0.0.0"
PORT=""
APIKEY=""

# 上下文长度(token 数)
CTX_SIZE=65535
# 最大生成 token 数(-1 表示无限,直到上下文填满)
N_PREDICT=-1

# 线程数:默认使用全部 CPU 核心
THREADS=$(nproc)
# 调优:单并发场景下批处理线程与生成线程保持一致即可
THREADS_BATCH=$(nproc)

# 并发限制:强制为 1,消除多 Slot 调度开销,换取最低延迟
N_PARALLEL=1

# Flash Attention(CPU 下也能降低内存占用,建议开启)
FLASH_ATTN="--flash-attn"
# 内存锁定(避免被 swap 到磁盘,提升稳定性)
# 若权限不足报错,请注释掉或运行前执行: ulimit -l 65536
MLOCK="--mlock"
# 调优:禁用内存映射,直接载入物理内存,减少推理时的页错误延迟
NO_MMAP="--no-mmap"

# Qwen3/3.5 官方推荐采样参数
TEMP=0.6
TOP_K=20
TOP_P=0.95
MIN_P=0.0

# ------------------- 预编译包配置 -------------------
LLAMA_SERVER="./llama-b9279/llama-server"
RELEASE_URL="https://github.com/ggml-org/llama.cpp/releases/latest/download/llama-bin-ubuntu-x64.zip"

# ------------------- 调优:禁用 Qwen3/3.5 思考功能 -------------------
# 方式1:环境变量硬关闭 chat_template 中的 enable_thinking
# 方式2:启动参数 --reasoning off 关闭 llama.cpp 的 reasoning 提取
# 双保险确保模型不生成 <think> / tthinking 块,直接输出最终答案
export LLAMA_CHAT_TEMPLATE_KWARGS='{"enable_thinking":false}'

# ------------------- 脚本逻辑 -------------------
echo "========================================"
echo "   llama.cpp CPU API Server (单并发)"
echo "========================================"

# 1. 检查模型文件
if [ ! -f "$MODEL_PATH" ]; then
    echo "[错误] 未找到模型文件: $MODEL_PATH"
    exit 1
fi

# 2. 检查 llama-server 是否存在
if [ ! -f "$LLAMA_SERVER" ]; then
    echo "[警告] 未找到 $LLAMA_SERVER"
    exit 1
fi
chmod +x "$LLAMA_SERVER"

# 3. 打印启动信息
echo ""
echo "模型路径: $MODEL_PATH"
echo "服务地址: http://\(HOST:\)PORT"
echo "Apikey: $APIKEY"
echo "并发限制: $N_PARALLEL (单请求独占全部资源)"
echo "CPU 线程: \(THREADS (生成) / \)THREADS_BATCH (批处理)"
echo "上下文长度: $CTX_SIZE"
echo "思考模式: 已强制禁用"
echo ""

# 4. 启动 llama-server
# 关键参数说明:
#   -m            模型路径
#   --host/--port 监听地址
#   --api-key      API 密钥
#   -c            上下文长度
#   -n            最大预测 token 数
#   -t / -tb      生成与批处理线程数
#   -np 1         限制并行 slot 为 1,消除调度开销
#   --reasoning off  禁用 Qwen3/3.5 思考模式 (服务端硬关闭)
#   --no-mmap     禁用内存映射,直接载入 RAM,降低延迟
#   --mlock       锁定内存防止 swap
#   --flash-attn  降低内存占用
#   --jinja       支持复杂 chat_template(Qwen3/3.5 必需)

"$LLAMA_SERVER" \
    -m "$MODEL_PATH" \
    --host "$HOST" \
    --port "$PORT" \
    --api-key "$APIKEY" \
    -c "$CTX_SIZE" \
    -n "$N_PREDICT" \
    -t "$THREADS" \
    -tb "$THREADS_BATCH" \
    -np "$N_PARALLEL" \
    --reasoning off \
    --temp "$TEMP" \
    --top-k "$TOP_K" \
    --top-p "$TOP_P" \
    --min-p "$MIN_P" \
    --jinja \
#    $FLASH_ATTN \
#    $MLOCK \
    $NO_MMAP \
    "$@"
# 注: "$@" 允许你在命令行追加额外参数,如 --verbose-prompt

保存为start_qwen_api.sh,在命令行中运行:

chmod +x start_qwen_api.sh
./start_qwen_api.sh
  • 下载、上传、解压、运行,怎么样?简单吧?

结果

使用任何支持调用api运行的对话模型,即可开始体验,

但是众所周知的,参数决定智力,这个参数量的模型一般都很傻。

  • 现在对api进行测速,使用万能的ai进行评估

  • 交给ai进行评估,服务器结果如下

    image.png

  • 但是在实际使用中,这个量级的模型跟傻子几乎没有区别,所以在保证服务器运行内存的情况下我换用2B模型进行测试:

    image.png

  • 尽管这个量级的模型依旧很傻,但是在速度和质量方面有所平衡,推荐使用

至此,我们就可以将这个api像正常调用其他大模型一样直接使用了!

进阶玩法:配置琪露诺的角色扮演prompt添加到聊群!毕竟token近似于不要钱,所以可以随便烧!

评论
xl233

森罗幻想. All Rights Reserved. Theme Jasmine_Plus by 罗伊