02 推理服务化
学习目标:能部署 vLLM/SGLang 推理服务,通过 OpenAI-Compatible API 完成调用;能用 TP/PP 部署大模型到多卡;建立"引擎跑单模型、编排层管多节点"的分层认知;掌握多机多卡分布式推理的实战踩坑。 重点度:必会(20 分)
概述#
模型在本地通过 Python 脚本跑通只是第一步。生产环境需要:
- 把模型变成一个稳定、标准、可接入的 HTTP API
- 大模型单卡放不下时,切到多卡甚至多机
- 选对推理引擎,平衡吞吐、延迟、易用性和生态
- 多节点协同需要编排层处理 PD 分离、KV 路由
2026 年的推理服务化可以用一个关键的架构分层来理解:
┌────────────────────────────────────────┐
│ 编排层(管多节点) │
│ NVIDIA Dynamo / llm-d │
│ disaggregated serving · KV routing │
├────────────────────────────────────────┤
│ 引擎层(跑单模型) │
│ vLLM / SGLang / TRT-LLM / Triton │
│ PagedAttention · Continuous Batching │
├────────────────────────────────────────┤
│ API 层(对业务暴露) │
│ OpenAI-Compatible · Streaming │
│ Chat Completions · Embedding │
└────────────────────────────────────────┘这三层是 2026 推理服务的标准分层。引擎层和编排层的分离是这两年最重要的架构变化——引擎跑单模型,编排管多节点。
引擎层:四大推理引擎#
vLLM#
定位:社区最活跃的开源 LLM 推理引擎,"生产部署首选"。
核心武器:
- PagedAttention:将 KV Cache 按 block(默认 16 token)分页管理,类比操作系统虚拟内存,解决显存碎片,利用率从 ~60% 提升到 96%+
- Continuous Batching:每个 step 动态调整批次——完成的请求出队,新请求入队,GPU 几乎不等待
最简部署:
pip install vllm
# 部署 Qwen2.5-72B,4 卡张量并行
vllm serve Qwen/Qwen2.5-72B-Instruct \
--tensor-parallel-size 4 \
--gpu-memory-utilization 0.9 \
--max-model-len 32768 \
--host 0.0.0.0 --port 8000关键参数:
| 参数 | 含义 | 推荐 |
|---|---|---|
--tensor-parallel-size | TP 切分度 | 看卡数,须整除 num_attention_heads |
--gpu-memory-utilization | 显存使用比例 | 0.90(默认)~ 0.92(高并发) |
--max-model-len | 最大上下文 | 按业务真实需求设,不是模型上限 |
--max-num-seqs | 最大并发序列数 | 256(高吞吐)/ 64(低延迟) |
--max-num-batched-tokens | 每步 forward 的最大 token 数 | 8192-16384 |
--enable-prefix-caching | 前缀缓存 | 常开(RAG 效果拔群) |
--enable-chunked-prefill | 长 prompt 分块 | 长上下文场景开 |
--dtype | 权重精度 | auto / float16 / bfloat16 / float8 |
生产参数组合:
# 高吞吐场景
vllm serve Qwen/Qwen2.5-72B-Instruct \
--tensor-parallel-size 4 \
--gpu-memory-utilization 0.92 \
--max-model-len 32768 \
--max-num-seqs 256 \
--max-num-batched-tokens 16384 \
--enable-prefix-caching \
--enable-chunked-prefill \
--disable-log-requests
# 低延迟场景(首 token 敏感)
vllm serve Qwen/Qwen2.5-72B-Instruct \
--tensor-parallel-size 4 \
--gpu-memory-utilization 0.88 \
--max-model-len 8192 \
--max-num-seqs 64 \
--max-num-batched-tokens 2048 \
--enable-chunked-prefillSGLang#
定位:多轮对话/Agent/RAG 场景的最优选择,DeepSeek 官方推荐引擎。
核心武器:
- RadixAttention:用 Radix Tree(基数树)组织所有活跃请求的 KV Cache,不同请求可共享任意长度的公共前缀
- 约束解码:支持 JSON Schema、正则、EBNF 约束,保证结构化输出 100% 合法
- 前端 DSL:Python 函数式 prompt 编程(
sgl.gen、sgl.fork等) - DeepSeek 深度优化:MLA、MoE、EPLB、EAGLE 全面支持
RadixAttention vs vLLM Prefix Caching:
| 维度 | vLLM Prefix Caching | SGLang RadixAttention |
|---|---|---|
| 粒度 | block 级(16 token) | token 级 |
| 数据结构 | hash 表 + 引用计数 | radix tree |
| 共享范围 | 请求完成后即淘汰 | 请求完成后仍可共享 |
| 命中率 | 中 | 高(多轮场景 60-85%) |
| 管理复杂度 | 低 | 较高 |
部署命令:
python -m sglang.launch_server \
--model-path /models/Llama-3.1-70B-Instruct \
--tp-size 8 \
--mem-fraction-static 0.88 \
--context-length 8192 \
--max-running-requests 256 \
--schedule-policy lpm \
--disable-radix-cache=false \
--chunked-prefill-size 8192 \
--host 0.0.0.0 --port 30000关键参数:
| 参数 | 含义 | 推荐值 |
|---|---|---|
--tp-size | Tensor Parallel 度 | 看卡数 |
--mem-fraction-static | 类似 vLLM 的 gpu-memory-utilization | 0.85~0.92 |
--context-length | 最大上下文 | 按业务 |
--max-running-requests | 同时跑的请求数 | 128~512 |
--schedule-policy | fcfs / lpm(最长前缀匹配优先) | 多轮场景用 lpm |
--attention-backend | flashinfer / flashattention / triton | flashinfer(最优) |
适用场景选择:
你的业务是不是以多轮 / Agent / RAG 固定 prompt 为主?
├─ 是 → SGLang(RadixAttention 命中率可达 60-85%)
└─ 否
├─ 延迟敏感到极致 + NVIDIA 全栈 → TRT-LLM
└─ 否 → vLLM(最省心,社区最大)TensorRT-LLM#
定位:NVIDIA 官方的极致性能推理引擎,H100/H200 上压榨最后一丝性能。
核心特征:
- 离线编译:模型要先编译成
.engine文件(固化图结构和 kernel),运行期只做前向和调度 - FP8 原生:H100/H200 上 FP8 计算 + FP8 KV Cache,是最成熟的 FP8 方案
- Inflight Batching:和 Continuous Batching 等价
- 深度 kernel 融合:图级优化,把多个小 kernel 融合成大 kernel
编译流程:
# 1. 权重转换:HF checkpoint → TRT-LLM checkpoint
python convert_checkpoint.py \
--model_dir /models/Llama-3.1-70B-Instruct \
--output_dir /tmp/llama70b_ckpt \
--dtype float16 --tp_size 8
# 2. 编译 engine
trtllm-build \
--checkpoint_dir /tmp/llama70b_ckpt \
--output_dir /engines/llama70b_fp16_tp8 \
--gemm_plugin float16 \
--gpt_attention_plugin float16 \
--max_batch_size 64 --max_seq_len 8192TRT-LLM 的代价:
- 编译一次要 30 分钟到几小时,改参数要重新编译
- 调试困难(engine 是二进制,看不到中间结果)
- 只支持 NVIDIA 硬件
- 社区迭代快但版本兼容性差(TRT-LLM 0.x 到 0.y 经常 breaking change)
TRT-LLM vs vLLM 选择:
| 场景 | 推荐 |
|---|---|
| 新业务、快速上线 | vLLM |
| H100 极致性能、FP8 深度使用 | TRT-LLM |
| Agent / 多轮对话 | SGLang |
| 非 NVIDIA 硬件 | vLLM(多硬件支持更好) |
| 频繁迭代调参 | vLLM(编译一次太慢) |
Triton Inference Server#
定位:NVIDIA 的通用推理服务器,不仅限于 LLM。
与前面三者的关系:TRT-LLM 可以通过 tensorrtllm_backend 跑在 Triton 上;CV/NLP 的传统模型可以和 LLM 混部在同一个 Triton 实例里。Triton 提供统一接口(HTTP/gRPC)、动态批处理、模型编排(Ensemble)、Prometheus 监控。
Triton 的核心能力:
- 多框架后端:TensorRT、ONNX Runtime、PyTorch、TensorFlow、Python、vLLM(通过 OpenAI backend)
- 模型版本管理:多个版本同时在线,按策略(latest/specific/all)路由
- Ensemble:多个模型串联(如 tokenize → LLM → detokenize)
- 动态批处理:自动按延迟/吞吐目标打包请求
典型用法:一个 Triton 实例同时服务 LLM(TRT-LLM backend)+ Embedding 模型(ONNX backend)+ Rerank 模型(Python backend),业务侧统一接口。
编排层(2026 新增层级)#
2026 年的重要变化:推理引擎之上出现了编排层,专门处理多节点协同。
为什么要编排层:引擎层(vLLM/SGLang)擅长"单模型单节点",但当需要跨节点做 PD 分离、按 KV Cache 命中率路由、跨节点负载均衡时,需要一个上层调度器。
NVIDIA Dynamo#
GTC 2025 发布的编排层,核心能力:
- disaggregated serving:将 prefill 和 decode 分配到不同 GPU 节点,跨节点 PD 分离
- KV-aware routing:按 KV Cache 命中率将请求路由到"最不需要重复计算"的节点
- 动态 GPU 分配:根据负载动态调整 prefill/decode 节点的比例(高峰期加 decode,低峰期减)
- 多引擎后端:可以同时调度 vLLM、SGLang、TRT-LLM 等不同引擎
Dynamo 的架构定位:
┌─────────────────────────────────────┐
│ Dynamo 编排层 │
│ ┌───────────┐ ┌────────────────┐ │
│ │ Router │ │ Scheduler │ │
│ │ (KV-aware)│ │ (PD 分配) │ │
│ └─────┬─────┘ └────────┬───────┘ │
│ │ │ │
│ ┌─────▼──────────────────▼───────┐ │
│ │ Frontend (OpenAI API) │ │
│ └─────┬──────────────────┬───────┘ │
└────────┼──────────────────┼──────────┘
│ │
┌────▼────┐ ┌────▼────┐
│ Prefill │ │ Decode │
│ Workers │──KV──→ │ Workers │
│ (SGLang)│ 传输 │ (vLLM) │
└─────────┘ └─────────┘llm-d#
社区 / Red Hat 主导的轻量编排器,特点:
- 分级 KV offload:GPU → CPU → 远端存储三级 KV
- cache-aware 路由:与 KV-aware routing 类似
- scale-to-zero:空闲时把推理实例缩到零
- K8s 原生:以 CRD 形式部署,不依赖 Ray
Dynamo vs llm-d#
| 维度 | NVIDIA Dynamo | llm-d |
|---|---|---|
| 主导方 | NVIDIA | Red Hat / 社区 |
| 定位 | 全功能编排层(含 PD 分离、KV 路由) | 轻量级 KV-centric 路由 |
| 硬件绑定 | NVIDIA 生态(深度优化 NVLink/RDMA) | 硬件无关 |
| 部署复杂度 | 较高(依赖 NVIDIA 栈) | 较低(K8s CRD) |
| 适用场景 | 大规模 NVIDIA 集群、需要 PD 分离 | 中小规模、多硬件、需要 scale-to-zero |
引擎层 vs 编排层#
引擎层 = 跑好一个模型
编排层 = 管好一堆模型实例的协同
Dynamo/llm-d 不替代 vLLM/SGLang,而是站在它们之上做跨节点调度什么时候需要编排层:
- 单节点能扛住流量 → 不需要,直接用引擎层 + 网关
- 需要 PD 分离、跨节点 KV 路由 → 需要
- 多节点负载均衡 + KV 复用 → 需要
- 规模较小(< 10 节点)→ 引擎层 + LiteLLM 网关足够
OpenAI-Compatible API#
所有主流推理引擎都支持 OpenAI 兼容的 API 格式,这是行业事实标准。统一接口意味着业务侧换引擎不需要改代码。
Chat Completions#
from openai import OpenAI
client = OpenAI(
base_url="http://vllm:8000/v1",
api_key="EMPTY", # vLLM 默认不校验
)
response = client.chat.completions.create(
model="qwen2.5-72b",
messages=[
{"role": "system", "content": "你是代码审查助手"},
{"role": "user", "content": "review 这段代码..."},
],
temperature=0.3,
max_tokens=1024,
)Streaming#
stream = client.chat.completions.create(
model="qwen2.5-72b",
messages=[{"role": "user", "content": "写一首诗"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)Embedding API#
response = client.embeddings.create(
model="bge-m3",
input="AI Infra 是什么?",
)
embedding = response.data[0].embedding # 1024 维向量Batch Inference API#
离线批处理场景,OpenAI 和 Anthropic 都提供 Batch API(24 小时内返回,成本约 50% 折扣)。自建引擎可以通过 Argo Workflows + vLLM 离线推理实现类似能力。
多卡分布式推理#
大模型部署的核心挑战:70B/405B 甚至 1.6T 的模型,单卡装不下。即使装得下,单机吞吐也可能不够,需要多机扩展。
显存需求估算#
显存需求 ≈ 模型权重 + KV Cache + 激活 + workspace
模型权重:
FP16 → 参数量 × 2 byte
FP8 → 参数量 × 1 byte
INT4 → 参数量 × 0.5 byte
KV Cache 每 token:
2 × num_layers × num_kv_heads × head_dim × dtype_bytes| 模型 | 精度 | 权重 | 单机 8×H100-80G 能否装下 |
|---|---|---|---|
| LLaMA 70B | FP16 | 140 GB | 能(TP=8) |
| LLaMA 70B | FP8 | 70 GB | 能(TP=4 即可) |
| LLaMA 405B | FP16 | 810 GB | 装不下 |
| LLaMA 405B | FP8 | 405 GB | 勉强(KV 空间少) |
| DeepSeek-V4 1.6T MoE | FP8 | 1.6 TB | 必须多机 |
Tensor Parallelism (TP) — 张量并行#
做什么:把单层 Transformer 的权重矩阵按列/行切分到多张 GPU。
Megatron-LM 切分方式:
- QKV Projection:按 head 维度切,每个 rank 独立算自己那部分 head
- FFN:第一个矩阵乘按列切,第二个按行切,中间结果不做通信,只在 FFN 尾端做一次 AllReduce
通信代价:每层 2 次 AllReduce(Attention + FFN)。80 层模型前向一次就有 160 次 AllReduce。单机 NVLink 900GB/s 无感,跨机 100Gbps RDMA 明显掉速。
适用:单机 NVLink 域内(通常 TP ≤ 8);跨机 TP 带宽损耗严重。
# vLLM 4 卡 TP
vllm serve Qwen/Qwen2.5-72B-Instruct --tensor-parallel-size 4
# SGLang 8 卡 TP
python -m sglang.launch_server --model-path /models/model --tp-size 8TP 切分约束:TP size 必须能被 num_attention_heads 整除。很多模型 num_heads=64,TP=8 OK,TP=6 就炸。
Pipeline Parallelism (PP) — 流水线并行#
做什么:把模型的不同层放到不同 GPU/节点。如 80 层模型,PP=4 则每段 20 层。
通信代价:只在层边界传输激活值,比 TP 小得多。
代价:存在流水线气泡(bubble),第一个请求的首 token 要等所有段都过一遍;小 batch 时气泡占比更大。
适用:跨机部署首选。典型组合 TP=8, PP=2(2 台 8 卡),TP=8, PP=4(4 台 8 卡)。
# vLLM TP=8 PP=2,2 机 16 卡
python -m vllm.entrypoints.openai.api_server \
--model /models/405B-FP8 \
--tensor-parallel-size 8 \
--pipeline-parallel-size 2 \
--distributed-executor-backend rayExpert Parallelism (EP) — 专家并行#
做什么:MoE 模型中专家的分布策略。不同 expert 分布到不同 GPU。
核心问题:专家路由不均衡——热门 expert 所在的 GPU 显存爆满,冷门 expert 的 GPU 空闲。DeepSeek 开源了 EPLB(Expert Parallelism Load Balancer)解决此问题。
EP + TP 组合:MoE 模型通常用 TP 切 attention 层 + EP 切 expert 层。DeepSeek-V4 生产部署就是 TP+EP 组合。
Data Parallelism (DP) — 数据并行#
做什么:多份完整模型副本,各自服务一部分请求。
实现:不是引擎内部并行,而是上层网关(如 LiteLLM)将请求分发到多个 vLLM 实例。
优先级:能 DP 就不 TP(DP 最省心)。DP 不需要跨节点通信,没有 NVLink/RDMA 依赖,扩缩容简单。
并行策略选型#
| 业务特征 | 推荐方案 |
|---|---|
| 7B/13B,QPS < 100 | 单卡 + DP 多实例 |
| 70B FP16 | 单机 8 卡 TP=8 |
| 70B 高并发 | 多实例 × 单机 TP=8 + 网关分流 |
| 405B FP8 | 单机 TP=8(能装下)或 2 机 TP=8 PP=2 |
| MoE(DeepSeek V3/V4) | TP + EP 组合 |
| 极致吞吐 + 多机 | TP=8(单机内)+ PP(跨机)+ DP(多副本) |
NCCL / HCCL#
- NCCL(NVIDIA Collective Communications Library):NVIDIA GPU 间的集合通信库
- HCCL(Huawei Collective Communications Library):昇腾 NPU 间的集合通信库,API 层面与 NCCL 高度对照
NCCL 关键环境变量(跨机分布式必踩):
export NCCL_DEBUG=INFO # 首次上线开 INFO,稳定后改 WARN
export NCCL_IB_DISABLE=0 # 启用 InfiniBand(必须)
export NCCL_IB_GID_INDEX=3 # RoCEv2 常见值
export NCCL_SOCKET_IFNAME=eth0 # 必须指定,否则可能选错网卡(最常翻车的参数)
export NCCL_IB_HCA=mlx5_0,mlx5_1 # 显式指定 IB HCA
export NCCL_P2P_LEVEL=NVL # 单机走 NVLink
export NCCL_NET_GDR_LEVEL=PHB # 启用 GPU Direct RDMANCCL 翻车排查:
- Worker hang 在
ncclCommInitRank→ 检查NCCL_SOCKET_IFNAME是否选到 docker0/calico 虚拟网卡 - 跨机 TP 掉速 50%+ → 检查是否退化到 TCP(NCCL_DEBUG=INFO 看 Channel 类型)
- 错包数 > 0 → IB 链路质量问题,查
ibstat和交换机
网络要求#
| 部署形态 | 最低网络 | 推荐 |
|---|---|---|
| 单机 TP | NVLink/NVSwitch | 不涉及跨机 |
| 跨机 TP | 100Gbps RDMA | 400Gbps InfiniBand |
| 跨机 PP | 50Gbps RDMA | 200Gbps+ |
| 多实例 DP | 10Gbps TCP | 25Gbps+ |
跨机 TP 最吃网络,10Gbps TCP 别想了,LLaMA 70B TP=16 跨 10Gbps 会让首 token 延迟从 80ms 飙到 2s+。
模型加载与分发#
权重分发#
405B 模型权重约 810GB(FP16),分发到多机是真实痛点:
| 方案 | 适用 | 注意 |
|---|---|---|
| NFS/EFS 共享存储 | 中小规模 | 加载 10 分钟+,startup probe 要给够 |
| 提前 rsync 到本地 NVMe | 生产推荐 | 需要预热脚本,首次部署慢 |
| 镜像内置 | 小模型 | 大模型镜像太大(>50GB 镜像 K8s 拉取慢) |
| 对象存储 + 延迟加载 | 大规模 | 配合 lazy loading 按需加载 |
生产推荐:模型权重存对象存储(S3/OSS),部署时通过预热脚本 rsync 到本地 NVMe,启动时从本地加载(3-5 分钟)。
冷启动优化#
vLLM 加载 70B 模型需要 3-5 分钟,405B 需要 10-20 分钟。K8s 部署时注意:
startupProbe:
httpGet:
path: /health
port: 8000
failureThreshold: 60 # 给足够时间(60 × 15s = 15分钟)
periodSeconds: 15
readinessProbe:
httpGet:
path: /health
port: 8000
periodSeconds: 10
failureThreshold: 3冷启动加速手段:
- 权重预缓存到本地 NVMe(不从 NFS 加载)
- FP8 权重(加载量减半)
- 多线程加载(
VLLM_WORKER_MULTIPROC_METHOD=spawn) - 预热请求(启动后先发一个短 prompt 预热 KV Cache 和 CUDA Graph)
引擎选型决策树#
你的业务模型和场景是?
├─ MoE 模型(DeepSeek V3/V4)
│ └─ SGLang(MLA/MoE 优化最深度,DeepSeek 官方推荐)
├─ Agent / 多轮对话 / RAG
│ └─ SGLang(RadixAttention 命中率 60-85%)
├─ 极致低延迟 + NVIDIA 全栈
│ └─ TRT-LLM + Triton
├─ 快速上线 / 通用场景
│ └─ vLLM(社区最大、上手最快)
├─ 多模型混部(CV+NLP+LLM)
│ └─ Triton Inference Server
├─ 国产 NPU(昇腾)
│ └─ vllm-ascend 或 MindIE
└─ 需要跨节点 PD 分离 / KV 路由
└─ 引擎层 + Dynamo/llm-d 编排层实战要点#
max-model-len别设太大:很多团队设到模型上限(128K),结果 KV Cache 池子只能放几个请求,并发完全上不去。按业务真实需求设,99% 场景 8K-32K 足够。能 DP 不 TP:多实例 + 网关比多机 TP 简单得多。只有在单卡装不下模型时才考虑多卡 TP。70B FP8 单机 4 卡能装下,加机器时优先 DP(多实例 + LiteLLM 分流)而不是 TP=16。
模型文件和 tokenizer 严格对齐:engine 和 tokenizer 必须来自同一个 checkpoint,否则生成的 token ID 对不上导致乱码。换模型版本时连 tokenizer 一起换。
编排层是 2026 新能力:现在不一定要用,但面试和架构设计里要有这个认知——引擎层之上还有编排层,Dynamo 和 llm-d 代表了这个方向。大规模(>10 节点)+ 需要 PD 分离时才引入。
SGLang 前端 DSL 是可选的:后端部署(OpenAI API 模式)才是主力用法,不一定非要学前端 DSL。但结构化输出和约束解码在后端可以直接用。
NCCL 环境变量必须配齐:跨机分布式启动前,
NCCL_SOCKET_IFNAME、NCCL_IB_HCA、NCCL_P2P_LEVEL不配齐,要么 hang 住要么掉速。首次上线开NCCL_DEBUG=INFO观察拓扑。软件栈版本锁死:vLLM、PyTorch、CUDA、NCCL、FlashAttention 版本强耦合,升级时一次只动一个,测试集群双写一周再灰度。
TRT-LLM 的编译代价:改一次参数重新编译 30 分钟+,迭代期间用 vLLM,稳定后再转 TRT-LLM。
小结#
这一章建立了推理服务化的分层认知:
引擎层(vLLM/SGLang/TRT-LLM/Triton)→ 跑单模型
编排层(Dynamo/llm-d)→ 管多节点协同
API 层(OpenAI Compatible)→ 对业务暴露
多卡分布式(TP/PP/EP/DP)→ 解决单卡装不下的问题核心工程决策:
- 选对引擎(vLLM 通用 / SGLang Agent+MoE / TRT-LLM 极致性能)
- 设对 context length(按业务,不是模型上限)
- 用 DP 优先(能 DP 不 TP)
- 跨机用 PP 不用 TP(TP 留在单机 NVLink 域内)
- 模型文件和 tokenizer 对齐
- NCCL 环境变量配齐
- 大规模 + PD 分离引入编排层
下一章将进入全路线分值最高的 推理性能优化——TTFT、TPOT、KV Cache、PD 分离、MoE 推理、分级 KV Cache。