同事问我:"同样是那张卡,为什么我们训练时显存一上来就爆,线上推理跑得好好的,训练那边却说不够用?"
我一开始答不上来,因为两边用的是同一张卡。后来我把两边拆成四个维度看,才发现它们的诉求几乎是反的——训练要的是算力和通信,推理要的是带宽和容量。
显存:训练要装三样,推理只装两样
训练时显存里同时躺着三样东西:模型权重、梯度、优化器状态。
以 AdamW 为例,权重按 bf16 存:
- 权重:2 bytes/param
- 梯度:2 bytes/param
- 优化器状态:fp32 的 m 和 v,加上 fp32 master weight,合计 12 bytes/param
差不多 16 bytes/param。7B 模型就是 112GB 往上——单卡 80GB 都不够,所以全参微调 7B 通常要么上多卡切分,要么用 ZeRO 把优化器状态和梯度切出去。
推理只要权重 + KV cache。7B 的 bf16 权重 14GB,KV cache 取决于上下文长度和并发数。
所以推理反而是显存更省的那个。这跟"训练跑得久所以吃资源"的直觉相反:单卡上全量微调的显存压力远大于高并发推理——后者可以靠加实例横向扩,前者得在卡内做并行。
带宽:训练算力密集,推理访存密集
训练一个 batch 的前向反向是几千次矩阵乘,算术强度高,计算单元能被喂饱,瓶颈在 SM 的 FLOPS 上。
推理的生成阶段完全不一样。decode 是逐 token 的,每次只吐一个 token,却要把全部权重从显存读一遍。矩阵变成了矩阵-向量乘,访存量与计算量之比极高,于是推理是访存密集的,性能由显存带宽决定。
这解释了两件事:
- 推理选型要看显存带宽,标称算力高但带宽低的卡,推理可能比带宽高但算力低的卡慢好几倍。
- 同样的算力数字,两代卡在推理上的差距可能比训练上还大,因为带宽的代际提升通常比算力更猛。
再往下一层,"每秒能吐多少 token" 可以粗估:单请求解码速度的上限约等于 显存带宽 ÷ 权重大小。权重 14GB、带宽 2TB/s,理论上限约 140 token/s,实际因为小矩阵调度和访存效率损耗,一般打个三到五折。
互联:训练的通信量比推理大一个量级
多卡训练每一层反向都要 AllReduce 同步梯度,通信量和模型规模正相关,而且是每层每 step 都做。跨节点一旦走普通以太网,训练吞吐会明显掉,所以训练集群才需要 RDMA / InfiniBand。
推理侧的张量并行也需要卡间通信,但频率低得多,量也小。
由此得出一条很实用的结论:横向扩容(多副本 + 负载均衡)在推理场景通常比单实例多卡更划算。多副本不卡通信,加机器就行,故障域还小;单实例多卡一旦某张卡慢,整组都慢。
我们做过一次对比,同一批流量,8 副本单卡 对 2 副本 4 卡张量并行:总吞吐差不多,但 8 副本的 P99 延迟更低,扩缩容也灵活。当时为了"显得专业"选了多卡,现在回头看是弯路。
批处理:固定 batch 对连续批处理
训练 batch 固定,还能用梯度累积模拟更大 batch,负载曲线平滑。
推理完全相反:请求到达时间随机、输入长度不等、输出长度更随机。静态 batch 会在低峰空转算力、高峰排队。
所以在线推理基本都用 continuous batching:新请求补进正在跑的 batch,谁先结束谁退出,位置立刻让给下一个。
这里有个坑:continuous batching 下"最大并发数"往往不是被算力卡住的,而是被 KV cache 容量卡住的。显存放不下 KV cache,请求就得排队等位。表现出来是 GPU 利用率看着不满,延迟却已经上去了。
KV cache 的估算值得单独看一眼:
KV bytes ≈ 2 × layers × kv_heads × head_dim × seq_len × batch × dtype_bytes
单请求 4K 上下文、7B 全注意力(32 个 KV head)的 FP16 KV cache 约 2GB;换成 GQA(8 个 KV head)的同尺寸模型只要约 0.5GB。并发 32 路就是 64GB 对 16GB 的差别。
这就是为什么"换个模型"比"加显存"更划算——同样卡数,换成 GQA 架构的模型,等效并发能翻好几倍。
汇总对照
| 维度 | 训练 | 推理 |
|---|---|---|
| 显存占用 | 权重 + 梯度 + 优化器状态,约 16 bytes/param | 权重 + KV cache |
| 主要瓶颈 | 算力 | 显存带宽 |
| 卡间通信 | 每层每 step 同步 | decode 每层一次,量小 |
| 横向扩展方式 | 单机多卡 + 分片 | 多副本更划算 |
| 负载形态 | 固定 batch + 梯度累积 | 到达随机 + 连续批处理 |
| 典型故障 | step 时 OOM、卡间通信拖慢 | KV cache 不够,请求排队 |
OOM 的形态也不一样。训练通常在 backward 或 optimizer step 那一刻爆,堆栈指向优化器或梯度缓冲;推理通常在长上下文突发时爆,堆栈指向 attention 的 cache 分配。第一次排查时按错方向找,能白扔半天。
我实际怎么选
- 只做推理、不做微调:显存容量 + 带宽优先,算力排后面。
- 训练和推理共用一张卡:按训练的要求配,推理在同一个环境里跑。
- 需要微调:先确认是不是真的需要全参——LoRA 的显存画像完全是另一套。
最后补一句:上面提到的 bytes/param、带宽、KV cache 公式都是结构性数字,不随具体机型变。但如果拿文里的 FLOPS 和带宽去核对某个具体套餐,还是得去官方页面看当前规格——同名的卡在不同套餐里给的配置不一样,价格也会调整,具体以官方页面为准。