当模型训练完成,进入生产部署时,你面临的就不再是“能否收敛”,而是“能否在预算范围内稳定服务用户”。这一转变的硬指标有三个:延迟(Latency)、吞吐量(Throughput) 和 显存占用(GPU Memory)。它们彼此深度耦合,任何一项的优化几乎都以牺牲至少另一项为代价。
本节的目标不是罗列公式,而是帮助你建立一套实用的直觉框架,在接到“延迟得降到 200ms 以内”或“一张 A10 要能撑 50 并发”这类需求时,能快速判断可不可能,以及牺牲点在哪里。
一、三根支柱:到底是什么、怎么量
1. 延迟(Latency)——用户体感的生命线
延迟是从模型收到请求到返回第一个 Token 的时间,以及“逐 Token 生成”的总持续时间。常用的两个指标:
- TTFT(Time To First Token):首个 Token 的生成延迟,决定了用户点击“发送”后看到第一条回复的快慢;
- TPOT(Time Per Output Token):之后每个 Token 的间隔,决定了文字流式输出时的流畅感。
延迟主要受限于单 Batch 下的模型计算量(由参数规模和序列长度决定),以及显存带宽。高延迟直接杀死用户体验,尤其在对话、代码补全等实时场景。
2. 吞吐量(Throughput)——服务规模的核心
吞吐量是系统单位时间内能处理的 Token 总量,通常以 Tokens per second(Token/s) 衡量。在 GPU 算子级,它也经常被表达为 FLOPS。从服务端看,吞吐量决定了你一台机器(或一个集群)能同时承载多少用户。延迟要求越松,就能堆积更多请求形成更大的 Batch,从而榨干 GPU 的计算单元,达到更高吞吐。
3. 显存占用(GPU Memory)——部署的上限围墙
显存是所有资源的物理边界。大模型推理时,显存被三大块占据:
- 模型权重(Model Weights):模型参数本身,以 16 位(FP16/BF16)存储时,每 1B 参数约占 2GB 显存;
- KV-Cache(键值缓存):注意力机制需要缓存每层的 Key 和 Value,供后续 Token 生成时复用,其占用与批次大小 × 序列长度 × 层数强相关;
- 激活与临时缓冲:推理时的中间计算值,通常占比相对较小但不可忽视。
显存不足,模型根本装不进 GPU,或者因频繁做显存溢出(Offloading)导致延迟暴涨。
二、三角博弈:为什么你永远在“牺牲”
这三个指标之间的冲突,可以用一个“魔咒三角形”来概括:
显存占用
/ \
/ \
/ 不 \
/ 可能 \
/ 三角 \
/________\
延迟 -------- 吞吐量
三角形三个顶点不可能同时达到最优,实际工程就是在可行区域内找最贴近需求的那个点。
1. 延迟 vs 吞吐量:批处理的“零和困局”
- 降低延迟的天敌是串行处理:为了让单个请求快,你需要增大显存带宽利用率、减少无用计算,最简单的做法是 Batch Size = 1。此时 TTFT 可以做到毫秒级;
- 但吞吐量的靠山是批处理(Batching):GPU 的计算核心需要同时处理大量 Token 才能喂饱。如果把请求攒成一批(Batch Size = 32 甚至更大),每秒处理的 Token 数可以提升数倍,但代价是:后来的请求必须排队等前面的请求凑足批次,TTFT 暴涨。
这就是连续批处理(Continuous Batching) 或叫 In-flight Batching 的价值所在:不等固定批次,来一个请求就加入当前计算,已有请求全部算完再一起更新 KV-Cache。它部分缓解了延迟和吞吐的矛盾,但不能根本消除。
2. 显存 vs 吞吐量:KV-Cache 的“空间换时间”
KV-Cache 是块典型的显存黑洞。例如,一个 7B 模型,处理 2048 长度的序列,Batch Size = 8,仅 KV-Cache 就可能吃掉几个 GB。如果不设 KV-Cache,每次生成下一个 Token 都要重新计算前面所有 Token 的 Key 和 Value,计算量暴增,吞吐量一落千丈。
因此,为换取高吞吐,必须给 KV-Cache 留足显存。当显存吃紧时,工程师只能:
- 减小 Batch Size → 牺牲吞吐;
- 缩短最大上下文窗口 → 牺牲功能。
3. 显存 vs 延迟:量化的“精度折扣”
当权重占满显存,最直接的卸压手段是量化(Quantization),把 FP16 权重压缩到 INT4 或 INT8(详见 22.2 节)。量化显著降低显存占用(甚至能让 70B 模型跑进消费级显卡),但会带来:
- 计算精度损失,模型回答质量可能下降;
- 部分量化方案(如 GPTQ 需要校准数据)增加落地复杂度。
对于延迟而言,低精度计算本身可能更快,但如果量化使得生成质量恶化导致用户需要反复跟模型纠缠,那总体任务延迟反而是恶化的。
三、不同场景的取舍实战
理解了三角关系后,我们来看三类典型部署场景,应该如何选择平衡点:
| 场景 | 延迟要求 | 吞吐要求 | 显存策略 | 典型优化组合 |
|------|---------|----------|---------|--------------|
| 实时对话 / Copilot | 极低(TTFT < 200ms,TPOT 几十 ms) | 中等(几十 QPS) | 单卡放模型,留足 KV-Cache,Batch=1 | 小模型(7B),用 FP16/BF16,显存过剩则增大 Context Len |
| 批量文档处理(夜间跑批) | 高延迟可接受 | 极高(榨干 GPU) | 量化 + 大 Batch | 中等模型 + INT4 量化 + PagedAttention + 连续批处理 |
| 高并发 API 服务 | 较低(但不能忍秒卡) | 很高(上千 Token/s) | 多卡分布式推理 + 显存平衡 | 模型分片(TP, PP) + 高带宽互联 + 连续批处理 |
四、调优起点:先量后切,再调参
在实际项目中,面对这三个指标不应该凭直觉,而要按以下顺序动手:
第一步:测量基线
用 vLLM、TensorRT-LLM 等框架(23 章会详细介绍)部署模型,记录默认配置下的:
- 不同 Pressure 下的 TTFT、TPOT P50/P95/P99;
- 不同 Batch Size 下的 Token/s;
- GPU 显存占用峰值与利用率。
第二步:确认硬约束
问清楚业务真正的底线。是每个请求延迟必须稳定,还是可以容忍偶尔的排队?是否有预算加卡?必须支持多大的上下文长度?
第三步:沿约束做抉择
- 如果延迟是第一要义:牺牲吞吐,减小 Max Batch,可以增加 GPU 数量,不做量化,直到延迟达标;
- 如果吞吐是第一要义:接受较长排队延迟,或用连续批处理压低 P50,增大 Batch Size,谨慎调整 GPU 显存分配;
- 如果显存是唯一瓶颈:启用 INT4/INT8 量化(AWQ 等精度友好方案),或使用 CPU Offloading(会大幅增加延迟),或做张量并行将模型分摊到多卡。
第四步:使用前沿优化手段微调
如投机采样(Speculative Decoding,用草稿模型加速生成)、PagedAttention(高效管理 KV-Cache)、FlashAttention(降低注意力计算显存占用)等。这些技术在 22.3 和 22.4 节会详细展开。
五、小结
- 延迟、吞吐、显存是推理落地的永恒三角。没有一个神奇的参数或框架能同时将它们推到最优。
- 显存是物理墙:权重 + KV-Cache 的组合决定了批次与上下文的上限,也因此间接画出延迟与吞吐的可行域。
- 取舍无普适解,只有场景解。对话要保延迟,批处理要保吞吐,高并发要分布式。做决策前务必测量真实压测数据,并用业务硬指标“倒逼”优化路径。
- 连续批处理与量化是行业标配,前者部分润滑延迟与吞吐的矛盾,后者强行撞破显存墙,但各自有代价。
在下一节(22.2)中,我们将深入剖析达成显存优化最直接有力的武器——量化技术,拆解 INT8、INT4、GPTQ、AWQ 等方案的实际效果与落地坑点。