llama.cpp:llama-server 与生产部署

llama.cpp:llama-server 与生产部署

「本系列第 8/17 章」。前两章已经说明:llama_model 只读可共享,llama_context 不能跨线程乱调,llama_decode 按 ubatch 推进。llama-server 并不另造一套推理引擎,它只是把这些约束做成可并发的 HTTP 服务。源码在 tools/server/,HTTP 用 cpp-httplib,JSON 用 nlohmann/json。

1. 请求怎么走进 decode

服务端主路径可以看成四段:

1
server-http.cpp  →  server-queue.cpp  →  server-context.cpp (slots)  →  server-chat.cpp

server-http 负责路由与协议。请求进入 queue 后排队、合并、调度。真正算 token 的是 context slots:每个 slot 对应一份推理会话,内部仍是上一章的 memory 与 llama_decodeserver-chat.cpp 把 OpenAI 风格的 messages 收成模型能吃的 token 序列(Jinja chat template 在 common/chat.cpp),再把采样结果写回响应。Function calling 在 server-tools.cpp,多模型路由在 server-models.cpp

--parallel 控制 slot 数量。slot 不是「开几个线程就安全」,而是「同时能挂起几路会话」。上一章写过 context 非线程安全:服务端用 slot 把并发请求隔开,再在调度器里决定哪些序列可以放进同一次 batch。slot 太少,请求在 queue 里等;slot 太多,每路都要占一份 KV,内存会先于 CPU 撑满。

2. 连续批处理与 SSE

生产环境很少「一个人 prefill 完再独占整段 decode」。连续批处理(--cont-batching,默认打开)允许不同请求处于不同阶段:有的还在灌 prompt,有的已经在逐 token 生成,调度器把它们合成一次 decode。新请求可中途加入,完成的序列立刻释放 slot。吞吐来自「同一张图里塞进更多活着的序列」,而不是无限加进程。slot 还可以 seq_cp fork、保存 / 恢复。

流式输出走 SSE。客户端把 stream: true 打开后,每个新 token 以 data: {"choices":[{"delta":{"content":"..."}}]} 推送,最后 data: [DONE]。这与 decode 循环一一对应:每成功一步 llama_decode 并采样,就多写一帧。不要把 SSE 理解成另一个推理后端。

投机解码用 -md draft.gguf --draft-max 16:draft 模型先吐若干 token,target 模型一次性验证。多模型目录用 --models-dir。这些都建立在同一套 slot / ubatch 之上。

3. 先认这些端点

端点 用途
GET /health 健康检查,部署探活
GET /props 当前服务属性
GET /v1/models 模型列表,LlamaIndex 先对这个
POST /v1/chat/completions Chat 补全,可 SSE
POST /v1/completions 文本补全
POST /v1/embeddings 向量,embedding 进程才开
POST /tokenize /detokenize /apply-template 排词表与模板
GET /metrics 需要 --metrics

探活用 /health,确认加载用 /v1/models,对话走 /v1/chat/completions。模板或词表异常时,先打 /tokenize 看 token 是否符合预期。还有 Anthropic 风格的 /v1/messages、以及 /infill/slots,不是最小闭环必需。

关键旋钮:-c 上下文、-b / -ub batch、-ngl 卸层、-fa Flash Attention、--host / --port。环境变量 LLAMA_ARG_THREADSLLAMA_ARG_CTX_SIZELLAMA_ARG_N_GPU_LAYERSLLAMA_ARG_HOST / PORT 可以少写命令行。默认 --host127.0.0.1,局域网访问必须改成 0.0.0.0

4. 冒烟部署

编译与 GGUF 仍沿用第 5 章:静态链接、GGML_NATIVE=OFF,需要界面时备好 tools/ui/dist。模型继续用 Qwen2.5-0.5B-Instruct-GGUFq4_k_m,先证明链路,再换大模型。

1
2
3
4
./build/bin/llama-server \
-m qwen2.5-0.5b-instruct-q4_k_m.gguf \
--host 0.0.0.0 --port 8080 \
-c 8192 -t 4 --parallel 4 --verbose

必须等到 HTTP server is listening。先打 /health,再发一条最短的 /v1/chat/completions。slot 不够会排队,KV 满会从 llama_decode 返回 1 一路冒到请求失败——这时应回到上一章检查 n_ctx 与 memory,而不是先改 HTTP 框架。集成测试在 tools/server/tests/,用 pytest 打 chat / tool / vision / slot。

llama-server 是调度壳,不是新的模型格式。权重仍是 GGUF,计算仍是 libggml,会话仍是一份份 context。推理这一段到此闭环。下一章《LLaMA Factory:环境、双架构与调用链》转回训练侧:在 Hugging Face 权重上做微调,再经第 5 章那条转换链回到 GGUF。

文章互动

阅读 --

留言

0 条留言

正在加载留言…