深色模式
LLM 推理服务架构总览
摘要:本文面向需要把大模型落到生产的 SRE / 平台工程师。先用"自回归生成为什么慢"讲清推理服务的本质约束(显存、KV Cache、内存带宽),再拆解一套推理服务的通用架构(接入层、调度器、执行引擎、显存管理、并行层),最后给出 vLLM / TGI / SGLang / TensorRT-LLM / LMDeploy 的选型决策树。适用版本:推理引擎以 2025–2026 年主线为准(vLLM 0.8.x–0.9.x 区间、TGI v3、SGLang v0.4.x),命令以官方文档为准,版本相关项见文内标注。
适用版本与前提
- 推理引擎:vLLM、TGI v3、SGLang、TensorRT-LLM、LMDeploy(均为开源主线,版本迭代快,命令请核对官方文档)
- 硬件:NVIDIA A100/H100(80GB)、L40S(48GB)、消费级 RTX 4090(24GB)等;AMD / Intel / 昇腾等亦有插件支持
- 读者需了解:Transformer 自回归生成、GPU 显存(HBM)、KV Cache 基本概念
本文是"总览"而非"逐字命令手册"
推理引擎的 CLI 参数、默认值随版本变化很大。下文出现的命令示例仅用于说明架构意图,生产部署前请以对应引擎官方文档核对该版本的参数名与默认值,并标注 [版本相关]。
核心概念:为什么 LLM 推理和常规推理不一样
常规模型(CV、小模型)推理是"一次前向、输出固定张量",可以放心地用静态 batch、padding 凑齐形状。LLM 是自回归生成:每生成一个 token 都要做一次完整前向,且第 N 个 token 依赖前 N-1 个 token。这带来三个本质约束:
- 显存被 KV Cache 主导。为不重复计算注意力历史,模型要缓存每一层每个位置的 Key/Value。KV Cache 随序列长度线性增长,长上下文下常超过权重本身占用的显存。
- Decode 阶段是内存带宽瓶颈,不是算力瓶颈。生成一个 token 需要把全部权重从 HBM 读进计算单元,但只算出 1 个 token。算力大量闲置,瓶颈在"每秒能从显存搬多少字节"。
- 请求长短不一、完成时间不同步。静态 batch 必须等长、同速,否则短请求被长请求"拖累"到整个 batch 结束,GPU 利用率可能只有 30–40%。
记住一句话
LLM 推理优化 = 把"显存(尤其是 KV Cache)"和"GPU 计算单元的空闲气泡"都榨干。所有引擎的创新都围绕这两点。
通用架构:一套推理服务由什么组成
一套生产级推理服务(以 vLLM 为例)自上而下大致是:
| 层 | 职责 | 关键设计 |
|---|---|---|
| 接入层 | 兼容 OpenAI API、鉴权、限流、流式 | 与业务逻辑解耦,便于替换引擎 |
| 路由层 | 多副本负载均衡、prefix-aware 路由 | SGLang/TGI 可把相同前缀路由到同一副本 |
| 调度器 | 决定哪些请求进哪个 batch、何时抢占 | 连续批处理、优先级、公平 |
| 批处理 | 把不同进度请求拼成一次 step | token-level batching |
| 执行引擎 | 真正跑前向、融合 kernel | FlashAttention、PagedAttention、量化 |
| 显存管理 | 分配/回收 KV Cache | 分页(vLLM)、基树(SGLang) |
| 并行层 | 多卡多机切分模型 | TP/PP/DP/EP |
关键指标:用同一套语言沟通
部署前先定义要优化的目标,避免被厂商 benchmark 带偏:
- TTFT(Time To First Token):从发请求到出第一个 token 的延迟,受 prefill(处理输入)影响。
- TPOT(Time Per Output Token)/ ITL:每个输出 token 的间隔,决定"打字机"体感,受 decode 阶段影响。
- 吞吐(tokens/s、req/s):单位时间产出的 token 数或完成的请求数。
- P50/P99 延迟:尾部延迟比平均值更影响真实体验。
- 显存利用率 / 最大并发:能同时服务的请求数。
吞吐和延迟常互相打架
增大 batch 能拉高吞吐,但会让单个请求的 TTFT/TPOT 变差。聊天场景看 P99 延迟,离线批量摘要看总吞吐。先定场景再调参。
引擎横评:本质都在"把 KV Cache 当一等公民"
各引擎的差异化(来源见参考资料,厂商数字请以实测为准):
- vLLM:PagedAttention 分页管理 KV Cache + Continuous Batching,开源生态最活跃,多硬件支持最广,是"先跑起来"的默认选择。社区/厂商常见说法是对比原生 HF Transformers 吞吐 2–4×,属相对值,请勿当作绝对 SLA。
- TGI v3:HuggingFace 出品,长 prompt 路径与 prefix caching 强,适合长对话历史。
- SGLang:RadixAttention 用基树(radix tree)按 token 前缀复用 KV,Agent / RAG / 多轮对话前缀重复高时收益明显;厂商 benchmark 声称结构化负载最高 ~6.4× 吞吐,属特定场景峰值。
- TensorRT-LLM:N 卡专属,编译 kernel + KV 复用/卸载,延迟最低但需为模型专门 build,灵活性差。
- LMDeploy(TurboMind):blocked KV + 量化,厂商测试称相对 vLLM 最高 ~1.8× 吞吐。
选型的真正分水岭是 KV Cache 复用模式
无论哪个引擎,战胜瓶颈的方式都是:把 KV Cache 当成可分页、可量化、可复用、可卸载的数据结构,而不是"糊在显存里的一大块张量"。选型时问自己:我的流量里可复用的前缀多吗?多 → 偏 SGLang/TGI;少、要通用 → vLLM。
生产部署步骤(以 vLLM 跑通最小可用为例)
bash
# 1) 拉取官方镜像(latest 跟随最新版;生产建议锁版本,如 v0.9.x)
docker pull vllm/vllm-openai:latest
# 2) 启动 OpenAI 兼容服务;--ipc=host 让共享内存足够,避免 KV 分页报错
docker run --gpus all --ipc=host -p 8000:8000 \
-v /mnt/models:/models \
vllm/vllm-openai:latest \
--model /models/Qwen2.5-7B-Instruct \
--max-model-len 32768 \
--gpu-memory-utilization 0.90 \
--tensor-parallel-size 1
# [版本相关] 参数名与镜像 tag 以官方文档为准;Qwen2.5-7B 约 15GB(fp16),
# 单张 24GB/4090 或 40GB/A100 即可,无需张量并行。1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
bash
# 3) 冒烟测试
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"/models/Qwen2.5-7B-Instruct",
"messages":[{"role":"user","content":"用一句话解释 KV Cache"}],
"max_tokens":128}'1
2
3
4
5
6
2
3
4
5
6
验证
- 看启动日志里的
GPU KV cache size与Maximum concurrency两行,确认 KV 池大小和预估并发是否符合预期。 - 用
curl或openaiSDK 跑几条不同长度请求,观察流式返回是否稳定。 - 接入后做压测(见
perf-tuning.md),用 TTFT/P99/吞吐三条曲线判断是否达标。
回滚与清理
换引擎/换版本的回滚
推理引擎升级可能改变量化、前缀缓存、API 行为。变更前:①保留旧镜像 tag;②用网关灰度切 5% 流量;③保留回滚脚本。删除容器用 docker rm -f <id>;模型权重若挂载在宿主机目录,勿误删 --volume 源路径。
安全与合规
- 越权:推理 API 必须前置鉴权(API Key / mTLS / 网关),不要裸暴露 8000 端口到公网。vLLM 自身不带强鉴权,靠外部网关。
- 成本失控:无限制并发 + 超长
max_tokens会被恶意刷爆 GPU。必须在网关层做:每用户 QPS/并发限制、单请求max_tokens上限、输入长度上限。 - 内容合规:对外服务建议接内容审核与日志脱敏,模型权重遵守许可证(如 Llama/Qwen 的社区许可)。
成本与性能(示意,非报价)
以 Qwen2.5-7B-Instruct(fp16 约 15GB)单副本为例:
| 配置 | GPU | 数量 | 估算单价[未实测] | 说明 |
|---|---|---|---|---|
| 开发/小流量 | RTX 4090 24GB | 1 | ~¥1.5–3/小时[未实测] | 本地或云游戏卡,无 NVLink |
| 通用服务 | A100 80GB | 1 | ~¥8–15/小时[未实测] | 留足 KV Cache 空间 |
| 高并发 | H100 80GB | 1–2 | ~¥20–40/小时[未实测] | FP8 显存更省 |
成本优化顺序
- 先上量化(FP8/AWQ)减小权重与 KV;2) 再调 batch/并发把 GPU 利用率拉到 80%+;3) 最后才加卡。多数团队卡在"利用率没拉满就加机器"。