云镜收藏

稍后阅读

清单保存在当前浏览器,方便下次回来继续阅读。

清单还是空的

在笔记卡片或正文页点击“加入稍后阅读”即可收藏。

卷2 · LLM 内功

2.8 推理优化与 vLLM:把模型变成服务

约 6 分钟阅读
全书目录

展开本章目录与同卷章节1. 优化地图:瓶颈决定技术2. 量化:4bit 的数学直觉3. PagedAttention 与 vLLM4. 投机解码:memory-bound 下的免费午餐5. 并发容量的算账方法(部署前必做)6. 自测题7. 动手作业8. 延伸资源同卷章节2.1 语言模型前史:n-gram → RNN → 注意力(20 分钟走完 30 年)2.2 BPE tokenizer 原理与实现2.3 GPT 架构工程版:从 TinyGPT 到 nanoGPT2.4 预训练:数据、Scaling Law 与训练稳定性2.5 SFT 与指令微调实战2.6 参数高效微调:LoRA 与 QLoRA2.7 对齐技术:RLHF → DPO → GRPO2.8 推理优化与 vLLM:把模型变成服务2.9 架构前沿:MoE、长上下文与注意力变体2.10 小模型时代的科研机会:1B–7B 甜点区

本章目标:理解推理侧优化的全貌——量化、KV 压缩、批处理、投机解码——并把你的微调模型用 vLLM 部署成 OpenAI 兼容服务。学完标准:能算一张卡的并发容量,能跑一次量化前后对比实验,知道每项技术解决的是 2.3 章哪一种瓶颈。

1. 优化地图:瓶颈决定技术

2.3 章的结论是钥匙:prefill 是 compute-bound,decode 是 memory-bound。所有推理技术都在攻三个指标:显存(决定能否装下+并发)、吞吐(tokens/s 总量)、延迟(首个 token 时间 TTFT + 逐 token 间隔 TPOT)。对应关系:

技术攻的瓶颈一句话原理
权重量化显存(权重本体)4bit 存权重,计算时反量化
GQA / KV 量化显存(KV cache)少存、省存
PagedAttention显存碎片 → 并发OS 分页思想管理 KV
Continuous batching吞吐decode 的 memory-bound 让并发近乎免费
投机解码decode 延迟小模型草稿、大模型并行验证
CUDA Graphdecode 延迟消除 kernel 启动开销

2. 量化:4bit 的数学直觉

线性量化的内核一句话:用缩放因子和零点把 fp16 的连续范围映射到 256 个整数档位:x≈s⋅(q−z)x \approx s \cdot (q - z)。精度损失来自档位间的舍入。工业方案三条路:

  • GPTQ:训练后量化(PTQM),基于二阶信息(Hessian)逐列量化并补偿误差,权重紧凑、推理快——GPU 服务端主流;
  • AWQ:激活感知——不是所有通道同等重要,按激活分布保护少量”关键权重”不量化/精细量化,实现简单效果好,出镜率高;
  • bitsandbytes:运行时即时量化(QLoRA 的底座),易用性第一;
  • GGUF / llama.cpp:CPU/端侧生态(Ollama 的底层),消费级硬件跑大模型的另一条路。

现实精度预期:8bit 几乎无损;4bit 掉 1–2%(多数任务无感,数学/代码类敏感);2bit 明显掉。量化是免费午餐但有保质期——你的评测必须在你自己的任务上重跑,不能信厂商数字。

3. PagedAttention 与 vLLM

传统 KV cache 管理:为每个请求预留连续最大长度显存 → 大量内部碎片 + 外部碎片,实际利用率常常不到一半。

PagedAttention(vLLM 的核心,2023):借鉴操作系统虚拟内存分页——KV cache 切成固定大小的 block(如 16 token/块),按需分配、逻辑连续物理分散。效果:显存利用率逼近满载,同样显存并发量翻数倍。

vLLM 的第二个杀手锏 continuous batching:静态 batching 等最慢请求结束才进下一批;continuous 版本每步动态增删请求——decode 阶段 memory-bound 的经济学(2.3 §4)被彻底兑现。

实操(寒假里程碑的最后一环):

pip install vllm
vllm serve Qwen/Qwen2.5-7B-Instruct \        # 或你 merge 后的本地模型路径
  --max-model-len 8192 --gpu-memory-utilization 0.9
# 得到 OpenAI 兼容 API:http://127.0.0.1:8000/v1
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="none")
resp = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "用三句话解释 KV cache"}],
)
print(resp.usage)            # prompt_tokens / completion_tokens——计费与容量的单位

你的微调模型从此获得”产品形态”:任何 OpenAI SDK 代码、任何前端(LobeChat 等)直接对接。

4. 投机解码:memory-bound 下的免费午餐

decode 逐 token 生成时 GPU 算力大量闲置。投机解码:小草稿模型(或大模型自己的小头)一口气猜 k 个 token → 大模型一次前向并行验证 k 个 → 接受最长的正确前缀。接受率高的领域(代码、模板化文本)加速 2–3 倍,输出分布数学上等价于大模型单独生成——加速不改变质量,这是它优于”直接用小模型”的关键。vLLM 里 --speculative-model 一行开启。延伸:自投机版本(Medusa/MTP 多预测头)是多 token 预测路线的起点,前沿在继续演化。

5. 并发容量的算账方法(部署前必做)

一张卡的容量账,三步:

  1. 权重:7B bf16 = 14GB(或 4bit ≈ 3.5GB);
  2. KV cache 预算:剩余显存 ÷ 单请求单 token KV(2.3 §3 的公式)= 可容纳的总 token 数;例:4090 上 7B bf16(24GB,留 2GB 余量)→ KV 预算 8GB → 单请求 4k 上下文约 500 个并发槽(GQA 后更多);
  3. 实际并发 = min(显存槽位, 算力能跟上的 batch) ——decode 时 batch 大到一定程度后 TPOT 开始恶化,压测找拐点。

吞吐指标速记:单请求 decode 速度 ≈ 显存带宽 ÷ 模型字节数(7B bf16 ≈ 14GB / 1000GB/s ≈ 70 tokens/s 理论上限,实测 40–60)。这个公式让你不看任何宣传就能估”这张卡跑这个模型多快”。

6. 自测题

  1. 为什么 4bit 量化”大多无感”而 2bit 明显掉?(档位数对信息保真的非线性;权重大部分冗余、少数关键——AWQ 的洞察)
  2. PagedAttention 解决什么?类比什么系统?(KV 显存碎片;OS 虚拟内存分页)
  3. continuous batching 比静态 batching 强在哪?(不等最慢请求,每步动态增删——兑现 memory-bound 的并发经济学)
  4. 投机解码为什么不损害输出质量?(拒绝采样保证分布等价;只是用并行验证替代串行生成)
  5. 单请求 decode 速度的估算公式?(带宽÷权重字节数;算出 7B bf16 在 4090 上 ≈ 50–70 tok/s)
  6. 部署你 merge 后的 7B,4090 上第一个该调的参数是什么?(—gpu-memory-utilization 和 —max-model-len——KV 预算的两个把手)

7. 动手作业

  1. vLLM 部署 2.6 的微调模型(LoRA 也可直接挂载:--enable-lora),用 OpenAI SDK 调通;
  2. 压测:写 50 行脚本(asyncio + 50 并发),测吞吐/TTFT/TPOT 随并发数的变化,找出你这张卡的拐点;
  3. 量化对比:同一模型 fp16 vs GPTQ-4bit(或 AWQ),在你 2.5 构造的评测集上对比质量、速度、显存三件套,出一张表;
  4. 挑战:开投机解码对比延迟;或用 llama.cpp 把 4bit 模型跑到你的 CPU 上,体验端侧路线。

8. 延伸资源

  • vLLM 官方文档(quickstart + 性能调优页)
  • PagedAttention 论文(Efficient Memory Management for LLM Serving)——十分钟
  • AWQ / GPTQ 论文——按需精读
  • SGLang——另一主流引擎(RadixAttention 前缀缓存是亮点),vLLM 学扎实后对照看