🏠 总目录📚 本教程 06 · 推理优化:省显存 ← →
📑 本页目录(点开跳转)

06 · 推理优化:先弄清瓶颈,再省显存

⏱ 22 分钟 | ⭐ 自建部署省钱最大的杠杆,就从这两件事开始


🎯 一句话

推理优化解决一个矛盾:模型很大,显存很贵,用户很急。 这一页先解决前两件事 —— 搞清楚瓶颈在哪,然后用量化把模型压小、用批处理把卡榨满。 ⭐ 降延迟那一半(投机解码、缓存、指标怎么权衡)在下一页。


🧠 先理解瓶颈在哪:两个阶段

操作步骤

① Prefill(预填充)—— 处理你的输入提示词
所有 token 可以并行算→计算密集(GPU 算力吃满)
时间 ∝ 输入长度
决定了「首字延迟 TTFT」
② Decode(解码)—— 一个一个吐出回答
每次只算 1 个 token,但要把整个模型权重从显存搬到计算单元
访存密集(显存带宽吃满,算力大量闲置!)⭐
决定了「每字延迟 TPOT」

🔑 最反直觉也最重要的一条: Decode 阶段的瓶颈是显存带宽,不是算力。 GPU 的算力大部分时间在空转,卡在「把 14GB 权重搬过来」这件事上。

这一条解释了后面所有优化的底层逻辑。

💡 顺带把一件事说清楚:Decode 每一步吐出来的其实是一个概率分布,不是一个词。 从分布里挑出那一个词的规则叫解码策略——你天天在调的 temperature / top_p 就在那一步。 它和"跑得快"是两件正交的事,所以单独成章:06b · 解码策略。 这一章只管速度和成本,看到"输出飘/复读"这类问题就该去那一章。


🗜️ 武器一:量化(Quantization)

思路:权重本来用 16 位浮点存,改成 8 位甚至 4 位整数。

信息关系

FP16 (16bit)→INT8 (8bit)→INT4 (4bit)
显存 100% 50% 25%
7B 模型:14GB→7GB→3.5GB (消费级显卡能跑了!)
70B 模型:140GB→70GB→35GB (单卡 A100 能跑)

为什么还能用:神经网络对权重精度有惊人的容忍度。4bit 量化后,多数任务的效果损失在 1–3%。

主流方案速查:

方案 特点 场景
GGUF(llama.cpp) CPU/GPU 混合、格式通用 本地跑、Mac、消费级设备 ⭐
AWQ 激活感知,保护重要权重 GPU 服务,质量好
GPTQ 逐层校准量化 GPU 服务,经典方案
FP8 新硬件原生支持 H100 及以后的卡

⚠️ 注意:量化省的是显存和带宽(因此 decode 变快),不一定省计算。而且 KV Cache 也可以单独量化——长上下文时这个收益很大。

⚠️ 量化的三个真实代价(别只看省显存)

代价 说明
长尾能力先崩 ⭐ 平均分只掉 1-3%,但复杂推理、多语言、长上下文这些"边缘能力"掉得更多
量化后必须重测 别信"官方说损失很小"——用你自己的评测集测一遍(第 11 章)
不同任务敏感度差很多 分类/抽取类几乎无损;数学、代码、多步推理最敏感

🔑 一条实用的选择规则: 显存刚好够 → 别量化;差一点点 → INT8;差很多 → INT4。 量化是"为了能跑"的妥协,不是"免费的优化"。

🧮 显存怎么估(部署前先算这一笔)

算一算

总显存 ≈ 模型权重 + KV Cache + 激活/框架开销

模型权重 = 参数量 × 每参数字节数

FP16 = 2 字节,INT8 = 1,INT4 = 0.5

7B FP16 → 14GB;7B INT4 → 3.5GB

KV Cache = 2 × 层数 × KV头数 × 头维度 × 序列长 × batch × 精度字节

(第 2 章算过:70B 模型每 token 约 2.6MB)

开销 ≈ 权重的 10~20%

⭐ 最常见的翻车:只算了权重,没算 KV Cache

→ "3.5GB 的模型怎么在 8GB 卡上 OOM 了"


📦 武器二:批处理(提升吞吐)

既然 decode 卡在「搬权重」,那就搬一次权重,同时给多个用户算——这是吞吐提升的关键。

结果对照

❌ 静态批处理:等 8 个请求凑齐一起跑
问题:有的请求 10 字就答完,有的要 1000 字
短的必须干等长的,GPU 大量空转
✅ 连续批处理 (Continuous Batching) ⭐ vLLM 的核心
谁答完谁下车,新请求立刻上车
吞吐提升 几倍到 10 倍以上

PagedAttention:借鉴操作系统的虚拟内存

信息关系

问题:KV Cache 要预留最大长度的显存,但实际用不了那么多
大量显存浪费(碎片化),能同时服务的用户数被限制
解法:像操作系统管理内存页一样,把 KV Cache 切成小块按需分配
显存利用率大幅提升→能塞下更多并发用户

📌 这是 vLLM 成为事实标准的原因。同样的卡,吞吐能翻好几倍。


🔗 想再深一层,去哪一套

去哪 为什么
AI基础设施 18 · 量化 ⭐ 武器一的完整展开:为什么会掉点、离群值才是根因、什么时候干脆别量化
AI基础设施 17 · 连续批处理与PagedAttention 武器二的完整展开:块表、写时复制、抢占,以及连续批处理和静态批处理到底差在哪
AI基础设施 16 · KV Cache 「估显存最容易漏掉 KV Cache」那一条的正题:它到底有多大,以及 GQA / MQA 怎么砍

✅ 检查点

  1. Prefill 和 Decode 各自的瓶颈是什么?为什么这个区别重要?
  2. 4bit 量化把 70B 模型从多少压到多少?主要省的是什么?
  3. 量化的三个真实代价是什么?什么任务对量化最敏感?选择规则是什么?
  4. 估部署显存时最容易漏掉什么?
  5. 连续批处理比静态批处理好在哪?
👀 答案
  1. Prefill 计算密集(并行处理输入,决定首字延迟);Decode 访存密集(每步都要把整个模型搬一遍,决定每字延迟)。区别重要是因为两个阶段该优化的东西完全不同。
  2. 140GB → 35GB。主要省的是显存和带宽(所以 decode 变快),不一定省计算。
  3. ①长尾能力先崩(平均只掉 1–3%,但复杂推理、多语言、长上下文掉得更多)②必须自己在真实任务上评测 ③不同方法适合不同场景。对量化最敏感的是复杂推理这类长尾任务。
  4. KV Cache。最常见的翻车是「3.5GB 的模型怎么在 8GB 卡上 OOM 了」—— 只算了权重没算它。
  5. 静态批处理要等最长的那个请求结束,短请求占着位置空转;连续批处理谁答完谁下车,空位立刻补新请求。

🛑 可以停在这里

读到这里,你已经能回答「这个模型能不能塞进我这张卡」和「怎么把卡榨满」这两个问题 —— 对自建部署来说这就是最小闭环。

⚠️ 什么时候回来看下一页:显存够了、吞吐也够了,但用户还是觉得慢。那是延迟问题,不是容量问题,解法在下一页。

⚡ 走神救援

先记住这几件事

下一节 👉 06d-降延迟与三个指标.md

打卡记录保存在你的浏览器里,首页能看到总进度