AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
  • Bonus 手册

    • Bonus 专栏:LLM 训练全景手册(框架 / 训练模式 / 输入输出 / 最简测试)
    • Bonus-2 · RAG / Agent 全景实战手册
    • Bonus-3 · LLM 推理优化全景实战手册
    • Bonus-4 · LLM 上下文长度原理全景手册
    • Bonus-5 · Agent 开发原理与面试准备手册
    • Bonus-6 · 面试深挖项实战手册
  • 扩展

    • 训练专栏 v2 · LLaMA-Factory / DeepSpeed / Megatron 深度调参手册

Bonus-3 · LLM 推理优化全景实战手册

🎯 目标:从框架选型 → 量化 → speculative decoding → KV cache,搞清 LLM 推理优化的全套手段,并落地实测 benchmark。 🧪 实测环境:gpu1 (A800-SXM4-40GB) · vLLM 0.6.5 · Qwen2.5-3B-Instruct (BF16) · max_model_len=2048 · gpu-memory-utilization=0.85 📅 实测日期:2026-05-27


0. 为什么推理优化是 LLM 应用的"命门"

维度训练推理
频率一次性 / 偶发每个请求都触发
成本主要是工程师工资 + 一次性 GPU每月 7×24 GPU 账单
体感用户无感TTFT 200ms vs 2000ms 直接决定产品体验
瓶颈算力 (FLOPs)显存 (KV cache) + 带宽 (memory-bound)

裸跑 Hugging Face Transformers model.generate() 的 LLM serving,在 A800 上单流 ~30 tok/s,30 并发?抱歉,堆 30 个 process,显存爆。 vLLM/SGLang 这类专用推理引擎单卡可以做到 500+ tok/s,显存利用率 95%+,这就是为什么推理优化是必修。


1. 主流推理框架全景

1.1 八大引擎对比

引擎出品方核心技术长板短板
vLLMUC BerkeleyPagedAttention + Continuous Batching生态最大,易上手,功能全极端 latency 不如专精引擎
SGLangLMSYS / BerkeleyRadixAttention(自动 prefix cache) + 协程调度prompt 复用场景吞吐 vLLM 1.5-2x生态较新,功能在追赶
TensorRT-LLMNVIDIA编译期 graph 优化 + CUDA kernel 融合 + INT4/FP8绝对极致 latency, NVIDIA 自家硬件最优闭源 kernel,Triton 部署复杂
TGIHugging Facecontinuous batching + flash attention与 HF Hub 无缝性能落后 vLLM 一截
LMDeployOpenMMLab(上海)TurboMind kernel + AWQ + W4A16国产模型(Qwen/InternLM) 适配最好多模态支持一般
DeepSpeed-MIIMicrosoftDeepSpeed inference engine与 DeepSpeed 训练栈一体体验不如 vLLM
Llama.cppggerganovGGUF + CPU/Apple Silicon端侧 / CPU 推理王者GPU 性能远不及 vLLM
Ollama基于 llama.cpp一行命令,本地 model 管理个人电脑零门槛不适合 serving

1.2 选型决策树

追求极致 latency, 全 NVIDIA + 愿意搞 Triton → TensorRT-LLM
通用 LLM serving, 中文 + 国产模型为主         → LMDeploy
通用 LLM serving, 国际生态                    → vLLM (默认)
prompt 大量复用 (RAG / agent)                 → SGLang
端侧 / 笔记本 / CPU                           → llama.cpp / Ollama
HF Hub 强绑定, 已有 HF infrastructure         → TGI
和 DeepSpeed 训练栈打通                       → DeepSpeed-MII

2. 实测 1:vLLM Concurrency Benchmark (主菜)

2.1 测试代码 (/opt/bonus2/bench_vllm.py)

import asyncio, time, statistics
from openai import AsyncOpenAI

client = AsyncOpenAI(base_url="http://10.43.165.182:8000/v1", api_key="not-needed")

async def one_call(prompt, max_tokens=128):
    t0 = time.perf_counter(); first_t = None; n_out = 0
    stream = await client.chat.completions.create(
        model="qwen2.5-3b",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=max_tokens, temperature=0.3, stream=True,
    )
    async for chunk in stream:
        if chunk.choices and chunk.choices[0].delta.content:
            if first_t is None: first_t = time.perf_counter()
            n_out += 1
    t_end = time.perf_counter()
    return {
        "ttft":     (first_t - t0) * 1000,
        "tpot":     (t_end - first_t) * 1000 / max(n_out - 1, 1),
        "total_ms": (t_end - t0) * 1000,
        "n_out": n_out,
    }

固定 8 条不同 prompts,流式 (stream=True),max_tokens=128,采集每请求 TTFT + TPOT。

2.2 实测结果(Qwen2.5-3B-Instruct on A800-40GB,2026-05-27)

并发n_reqwall(s)req/stok/sTTFT p50TTFT p95TPOT p50TPOT p95
1820.110.446.845.0 ms388.5 ms20.7 ms21.4 ms
2810.990.7384.245.0 ms59.0 ms21.5 ms22.3 ms
485.671.41164.454.3 ms77.7 ms22.0 ms23.6 ms
8165.902.71315.984.7 ms96.3 ms22.7 ms23.7 ms
16326.345.05588.5120.6 ms152.7 ms24.3 ms25.6 ms

2.3 数据解读 — Continuous Batching 在表演

关键观察:

指标conc=1 → conc=16解释
吞吐 (tok/s)46.8 → 588.5 (12.6×)Continuous Batching 把多请求塞到一次 forward
TPOT p5020.7 → 24.3 ms (+17%)几乎线性增长完全没出现 —— PagedAttention 把 batch 内 attention 算并行
TTFT p5045 → 120.6 ms (+170%)prefill 阶段 batched,但每个请求要排队进 batch

💡 TPOT 不变是 vLLM 的"魔法":传统 batched inference,batch=16 时单个 token 生成时间应该接近线性增长(每步矩阵更大,显存带宽更紧)。但 PagedAttention 把 KV cache 分页,attention 计算在 batch 维度真正并行化,token 生成时间几乎独立于 batch size。

⚠️ TTFT 上涨快:不是 vLLM 的锅,是 prefill 本身计算密度高(整个 prompt 一次性进 attention),batch 越大 prefill 越慢。生产里要么(1)--enable-chunked-prefill 让 prefill 跟 decode 混合调度,(2)用 SGLang 的 prefix caching 把重复 system prompt 一次性命中,降低 prefill 量。

2.4 容量推算

  • 单 A800 40GB 跑 Qwen2.5-3B (~6 GB BF16),conc=16 时吞吐 588 tok/s
  • 假设单请求平均 200 tokens 输出 → 单请求 ~0.34s 输出
  • 单卡稳态承接 ~2.9 req/s ≈ 250K req/day(假设 24×7)
  • 月成本(按 A800 公有云 ¥15/h 估):¥10,800 → 每 request 约 ¥0.0014

3. 量化技术全景

3.1 主流量化方法

方法bit算法适用阶段工具评价
FP16/BF1616直接降精度推理(默认)任意框架baseline,无损
FP8 (E4M3 / E5M2)8Hopper / Ada 原生支持推理TensorRT-LLM, vLLMH100/H200 必选,接近 BF16 质量,2× 吞吐
AWQ4Activation-aware Weight QuantPTQAutoAWQ, vLLM, LMDeploy中文 LLM 主流, 损失 <1%
GPTQ4Hessian 近似 + per-group quantPTQauto-gptq, vLLM较老,大多被 AWQ 替代
GGUF Q4_K_M4k-means + 分块PTQllama.cppCPU/端侧首选
SmoothQuant8 (W8A8)平滑 outliers 后均匀量化PTQTensorRT-LLM, vLLMactivation 也量化,极致显存
W4A16 (Marlin)W4A16Mixed precision GEMM kernelPTQvLLM (awq_marlin), LMDeployvLLM 上 AWQ 的"加速版"
INT4 (QAT)4Quantization Aware Training训练时bitsandbytes / NF4训练时量化,推理直接用
HQQ1-8半二次量化PTQHQQ lib实验性,极低 bit

3.2 量化方式选择

H100/H200 卡 + 极致吞吐         → FP8 (TensorRT-LLM)
A100/A800/L40 + 通用 LLM         → AWQ + Marlin (vLLM / LMDeploy)
RTX 3090/4090 个人推理          → AWQ 4bit
端侧 / Apple Silicon / CPU      → GGUF Q4_K_M (llama.cpp)
显存极紧需要 W8A8 都量化         → SmoothQuant
训练就要量化感知                → QLoRA (NF4)

3.3 AWQ vs BF16 — 现场实测对比(本环境已部署但 weights pull 超时)

⚠️ 环境备注:本节点上 vllm-7b-awq pod 已部署但 NotReady — HF weights 拉取被 WAN 卡住,日志最后停在 Using model weights format ['*.safetensors']。Pod manifest 完整、配置正确,只欠 weights 落盘。

因此 AWQ vs BF16 的"现场实测"留待 weights 拉取完成后补做。表格中给出业内公认数据(参考 vLLM 官方 benchmark + Qwen 团队论文):

模型精度显存占用单请求 latency吞吐 (16 并发)MMLU 损失
Qwen2.5-7BBF16~14 GB1.0×1.0× (baseline)0
Qwen2.5-7BAWQ-W4A16 (Marlin)~4.5 GB0.7× (更快)1.3×<1%
Qwen2.5-7BGPTQ-W4A16~4.5 GB0.8×1.1×1-2%
Qwen2.5-7BFP8 (H100)~7 GB0.6×1.5×0.5%

核心结论:在 A800 上 AWQ 量化把同尺寸模型的显存压到 1/3,latency 反而降低(因为 memory-bound 场景下 4bit 加载更快),质量损失可接受 <1%。生产 LLM serving 默认就上 AWQ。


4. Speculative Decoding 全景

4.1 核心思想

慢路 (target model, 7B):    输出 1 token / step
快路 (draft model, 0.5B):  快速猜 N 个 token
然后 target 一次 forward 验证 N 个猜测 → 接受多少算多少

如果 draft 猜得准,N step 的工作量被压缩到 1 step,latency 直接 2-3×。

4.2 三种 speculative 方法

方法draft 来源适用加速
Draft model小模型(同系列,如 Qwen 7B + Qwen 0.5B)通用,经典1.5-2.5×
n-gram历史输出的 n-gram 统计重复模式多的输出(代码、表格、JSON)1.5-3×
EAGLE / Medusa在 target model 上加 headlatency 关键,有训练资源2-4×
Lookahead Decoding自动并行解码多 token不需要 draft 模型1.5-2×
DeepSeek MTPMulti-Token Prediction(训练时设计)DeepSeek V3 / R1 系列原生1.8×

4.3 vLLM 开启 speculative decoding 的方式

# 1. n-gram (零额外模型, 最简)
vllm serve Qwen/Qwen2.5-7B-Instruct \
  --speculative-model "[ngram]" \
  --ngram-prompt-lookup-max 4 \
  --num-speculative-tokens 5

# 2. draft model (经典)
vllm serve Qwen/Qwen2.5-7B-Instruct \
  --speculative-model Qwen/Qwen2.5-0.5B-Instruct \
  --num-speculative-tokens 5

# 3. eagle (需要 EAGLE checkpoint)
vllm serve meta-llama/Llama-3.1-70B \
  --speculative-model yuhuili/EAGLE-LLaMA3.1-Instruct-70B \
  --num-speculative-tokens 5

4.4 何时开 / 何时关

场景是否启用
代码生成 / JSON / 表格输出✅ 强烈建议(n-gram 命中率高)
多语言混合输出✅ 通常 OK
极致 latency 关键应用✅ 必须
高并发(conc > 32)⚠️ 视情况 — 高并发下 batched 已经很满, spec 加速边际效益小
draft model 质量差(<1B) 跟 target(70B)⚠️ 接受率低,反而拖慢

5. KV Cache 优化

KV cache 是 LLM serving 的"显存吞噬兽"。对 7B 模型,seq_len=2048 时,单 sequence KV cache ≈ 1.5 GB。

5.1 PagedAttention(vLLM 原创)

把 KV cache 切成固定大小 block (默认 16 token / block),用类似 OS 虚拟内存的方式管理:

传统连续分配PagedAttention
每 seq 预分配 max_seq_len KV cache按需分配 block
显存碎片 60-80%显存碎片 <4%
显存利用率 ~30%显存利用率 ~95%

效果:同样显存,vLLM 能塞下 3-4× 的并发请求(本次 conc=16 比 conc=1 吞吐 12.6× 一半归功于此)。

5.2 Prefix Caching

system prompt 通常很长(几百 tokens)且大量请求复用。Prefix Caching = 把 system prompt 的 KV cache 算一次,后续请求复用。

vllm serve ... --enable-prefix-caching

效果:RAG/Agent 场景 system prompt 占比 80% 时,TTFT 降低 60-90%。

💡 SGLang 的 RadixAttention 是 prefix caching 的"自动版"——基于 radix tree 自动识别共享前缀,不需要手动声明 cache 项。这就是 SGLang 在 RAG/Agent 场景能比 vLLM 快 1.5-2× 的原因。

5.3 KV Cache Offload

显存装不下?把不活跃的 sequence 的 KV cache swap 到 CPU memory:

vllm serve ... --swap-space 16  # 16 GB CPU swap

代价:swap 时 latency 抖动几百 ms。生产建议只用做峰值保护,稳态尽量靠 PagedAttention + prefix caching 解决。

5.4 KV Cache Quantization(FP8 KV cache)

vllm serve ... --kv-cache-dtype fp8_e5m2

KV cache 显存减半,质量损失 <1%。H100/H200 上几乎免费午餐。


6. 端到端选型决策表

6.1 按场景选

场景引擎量化其他优化
生产中文对话(A800)vLLM 或 LMDeployAWQ-W4A16 (Marlin)prefix caching, chunked prefill
极致 latency(H100)TensorRT-LLMFP8FP8 KV cache, EAGLE spec decoding
RAG/Agent 频繁复用 promptSGLangAWQRadixAttention(自动 prefix cache)
代码补全 / Copilot 类vLLMBF16n-gram speculative decoding
个人电脑 / MacBookOllama (llama.cpp)GGUF Q4_K_Mmetal/CUDA
端侧 / Edge / 手机mlc-llm / executorchINT4NPU 加速

6.2 综合优化 checklist

  • [ ] 基础选 vLLM 起步(生态最大,坑最少)
  • [ ] 必开 prefix caching(--enable-prefix-caching)
  • [ ] 必开 chunked prefill(--enable-chunked-prefill,TTFT 抖动减少)
  • [ ] 必开 AWQ 量化(Qwen/Llama/InternLM 都有官方 AWQ 版)
  • [ ] 试 speculative decoding([ngram] 零成本,先试再说)
  • [ ] 试 FP8 KV cache(H 系列卡免费午餐)
  • [ ] --max-num-seqs 调到 256-1024(默认 256,大显存可调高)
  • [ ] --max-num-batched-tokens 调到 4096-8192(看 prompt 长度)
  • [ ] 加 Prometheus + Grafana 监控(vllm_* metrics 都有)
  • [ ] 配 HPA 基于 vllm_num_requests_waiting(本 bootcamp Day 11 做过)

7. 实测进一步可做的扩展(留作 follow-up)

方向怎么做预期效果
BF16 vs AWQ 现场对比等 vllm-7b-awq weights 下载完, 用同 benchmark 跑一遍显存 14→4.5GB, latency -30%, 吞吐 +30%
Prefix caching on/off重启 vllm-3b 加 --enable-prefix-caching, 同一 system prompt 跑 RAGTTFT 降 60%+
n-gram speculative加 --speculative-model "[ngram]", 跑 JSON/代码输出tok/s +50%
SGLang vs vLLMpip install sglang + 起 server, 跑同 benchmark复用 prompt 时 SGLang +50%

8. 一句话总结

PagedAttention 解决显存碎片 · Continuous Batching 解决调度并行 · AWQ 量化解决模型尺寸 · Speculative Decoding 解决 latency 上限 · Prefix Caching 解决重复 prompt。

这五项叠起来,单 A800 把 Qwen2.5-3B 推到 588 tok/s @ TPOT 24ms,这就是 2026 年 LLM serving 的工程基线。


附录 A:本次实测原始数据(2026-05-27)

$ python3 bench_vllm.py
conc   n wall(s)   req/s   tok/s  TTFT p50  TTFT p95  TPOT p50  TPOT p95
--------------------------------------------------------------------------------
   1   8   20.11     0.4    46.8      45.0     388.5      20.7      21.4
   2   8   10.99    0.73    84.2      45.0      59.0      21.5      22.3
   4   8    5.67    1.41   164.4      54.3      77.7      22.0      23.6
   8  16     5.9    2.71   315.9      84.7      96.3      22.7      23.7
  16  32    6.34    5.05   588.5     120.6     152.7      24.3      25.6

环境信息:

  • GPU: NVIDIA A800-SXM4-40GB
  • vLLM: 0.6.5
  • Model: Qwen/Qwen2.5-3B-Instruct (BF16)
  • max-model-len: 2048, gpu-memory-utilization: 0.85
  • runtime: k3s + nvidia container runtime
  • ClusterIP endpoint: http://10.43.165.182:8000/v1

✅ benchmark 代码 + 数据均已在 /opt/bonus2/bench_vllm.py 实跑落盘。

在 GitHub 上编辑此页
Prev
Bonus-2 · RAG / Agent 全景实战手册
Next
Bonus-4 · LLM 上下文长度原理全景手册