Skip to content

推理 vs 训练 vs 微调

本页速览 训练算 FLOPs 多、激活多;推理访存重、batching 紧、KV cache 必须。微调是训练的轻量化尾声。本文从算力、访存、批处理、KV cache、精度、硬件、微调位置七个维度把三者切清楚。

推理 vs 训练 vs 微调

这是被问得最多、也最容易答混的一组概念。先给结论:训练是"把模型教会",微调是"训练的轻量化尾声",推理是"把毕业的模型送上岗"。三者都用神经网络前向,但工程上几乎是三个领域——算力分布、访存特征、批处理形态、精度选择、硬件利用方式都不一样。

很多人把"会跑 transformers 训一个模型"等同于"懂推理工程",于是在面试时把推理岗答成训练岗。本文从七个维度把三者切清楚,每一维都给出可量化的差异。

一、本质差异:算 FLOPs、访存、激活

把一个 Transformer 层的"前向 + 反向"算力拆开看:

维度训练(前向 + 反向 + 优化器更新)推理(仅前向)
FLOPs / token前向 ≈ 2P,反向 ≈ 4P,优化器 ≈ 2P(Adam),合计 ≈ 8P2P(仅前向)
激活显存必须保留前向所有激活用于反向(O(seq_len × hidden))不保留激活,用完即丢
访存特征算力瓶颈(batch 大、算术强度高)访存瓶颈(batch 小、算术强度低,LLM decode 尤甚)
GPU 利用率(MFU)50-60%(A100 训练大模型)5-50%(batch=1 decode <5%,prefill 50%+)

其中 P 是参数量。一个直接推论:训练算 1 个 token 的 FLOPs 是推理的 4 倍——但这只是冰山一角。真正的差距在于算力分布的形态

  • 训练:一个 batch 内算力密集均匀,所有 token 同等对待,GPU 利用率可以稳定压满;
  • 推理:prefill 阶段算力密集(算 prompt),decode 阶段算力稀疏(每步 1 个 token),同一个请求的两个阶段算术强度差 100 倍以上。

这就是为什么训练工程师关心"MFU 多少",推理工程师关心"tokens/s 多少、HBM 带宽用了多少"——两者关心的根本不是同一类指标。详见延迟与吞吐访存与带宽

反向传播不是"算两遍前向"

很多人误以为反向 = 算两遍前向,所以训练算力是推理的 2 倍。实际反向要算权重和激活两路梯度,加上 Adam 的一阶/二阶矩更新,总 FLOPs 是推理的 4-6 倍。这个差距决定了训练永远是"算力优先",推理永远是"访存优先"。

二、批处理差异:训练 static batching,推理 continuous batching

批处理是训练和推理工程上最大的形态差异。

训练:static batching,batch 越大越好

训练的 batch 在一个 step 内是固定的:从数据集采 N 个样本,padding 到等长,一次 forward+backward,更新参数,下一个 step 再采 N 个。N 越大,算术强度越高,GPU 利用率越高——所以训练工程师的日常是"想办法把 batch 开大"(梯度累积、ZeRO 分片、张量并行让显存够装)。

训练 batch 大小可以从几十到几千,且同一个 batch 内样本长度通常 padding 到最长那个,浪费可接受。

推理:请求随时来、长度各不同,static batching 会爆炸

推理的请求是用户随时来的,prompt 长度从几十到几千不等。如果用 static batching:

  • 方案 A:等凑齐 batch 再算——延迟爆炸(用户等几秒看到首 token);
  • 方案 B:立刻算但每个请求单独跑——吞吐爆炸(GPU 利用率 <5%);
  • 方案 C:凑到固定 batch、padding 到最长——短请求被长请求拖累,算力浪费 50%+。

vLLMcontinuous batching 解决了这个问题:让请求动态加入和退出 batch——某个请求生成完最后 token 就立刻退出,新请求立刻补位,其他请求继续 decode。配合 PagedAttention 把 KV cache 分页管理,显存利用率从 ~20% 拉到 ~90%,吞吐提升 10-20 倍。

text
t=0:  [A][B][C]          ← 三个请求一起 decode
t=1:  [A][B][C][D]       ← D 来了,加入 batch
t=2:  [A][B]__[D]        ← C 生成完退出,A、B、D 继续
t=3:  [A][B][D][E]       ← E 来了加入

continuous batching 是 vLLM、TGI、SGLang 的核心机制,详见批处理与调度

三、KV cache:训练无,自回归推理必须

KV cache 是 LLM 自回归推理的命脉,但训练里根本不存在。

训练为什么不需要 KV cache

训练时数据是"整段序列一起进",attention 一次性算完整个序列的 Q×K^T×V——没有"下一步"的概念,自然不需要缓存。训练的 attention 显存占用是 O(seq_len²)(attention 矩阵),但用 FlashAttention 后可以压到 O(seq_len)。

推理为什么必须有 KV cache

自回归推理是"每次生成一个新 token",第 N 步要算 attention(Q_N, K_{1..N}, V_{1..N})。如果没有 KV cache,每生成一个 token 都要把前面所有 token 的 K、V 重新算一遍——O(N²) 重复计算,对 1000 token prompt 生成 200 个 token,重复算力约是真正需要的 1000 倍。

KV cache 的本质是:把每层每头的 K、V 张量缓存下来,下一步只算新 token 的 Q/K/V,拼接到缓存里。这样每步算力从 O(N) 降到 O(1),但显存占用变成 O(N × layers × hidden × heads)——70B 模型、4k 上下文,单请求 KV cache 就要 ~5GB。

KV cache 的工程代价

KV cache 的显存占用公式(粗略):

KV_cache_size = 2 (K and V) × num_layers × seq_len × hidden_dim × num_kv_heads × dtype_bytes

以 Llama-2-70B(80 层、hidden 8192、64 头、8 KV 头、FP16)为例,单请求 4k 上下文:

2 × 80 × 4096 × 8192 × 8 × 2 bytes ≈ 8.6 GB

这意味着 80GB 显存的 A100,单卡装下 70B 权重(140GB FP16 装不下,需 INT4 量化到 35GB)后,剩下的 45GB 只够约 5 个并发请求的 KV cache。这就是 PagedAttention 要解决的问题——把 KV cache 分页管理,消除碎片,把并发数提升 5-10 倍。

四、精度差异:训练 BF16/FP32 主力;推理 INT8/INT4/FP8 主力

精度选择是训练与推理最直观的分裂之一。

阶段主力精度原因
训练BF16 / FP32(部分混合)反向传播对梯度数值范围敏感,BF16 的 8 位指数 + 7 位尾数兼顾范围与精度
推理FP16(基线)→ INT8 / INT4 / FP8(优化)前向不需要梯度,权重和激活可量化到低精度,访存与算力同时获益

训练几乎不用 INT8/INT4——量化误差在反向传播中会累积爆炸。但推理只用前向,低精度的"小误差"是可以接受的。详见模型量化基础

精度选择的关键差异:

  • 训练精度迭代慢:从 FP32 → FP16 → BF16,每一步都用了 3-5 年才普及(BF16 在 2020 年 Ampere 才硬件支持);
  • 推理精度迭代快:INT8 在 2018 年 Volta 就硬件支持,2023 年 INT4 在 LLM 上工程化(GPTQ/AWQ),2024 年 FP8 在 H100 上普及,每代硬件都会带来一档新精度

为什么推理偏爱 FP8

H100 引入 FP8(E4M3 / E5M2)后,FP8 在 LLM 推理上比 INT8 更受欢迎——因为它保留了浮点的指数范围,对激活的异常值不敏感,量化掉点比 INT8 小,且 Tensor Core 原生支持。详见权重 only 与混合精度

五、硬件利用差异:训练大集群通信密集;推理单机多卡 + batching + KV cache

训练与推理在硬件拓扑上的偏好几乎相反。

训练:大集群、通信密集

训练大模型必须用多机多卡,且通信是瓶颈——数据并行要 AllReduce 梯度、张量并行要 AllReduce / AllGather 激活、流水线并行要 P2P 传激活。训练瓶颈常常在通信而非算力,所以训练集群的网卡(400G InfiniBand)和拓扑(NVLink、NVSwitch)极其关键。

训练集群规模:GPT-3 训练用几千张 V100,Llama-3-405B 训练用 16k+ H100,集群通信设计是训练工程的核心。

推理:单机多卡为主,靠 batching + KV cache 喂饱

推理绝大多数场景不需要大集群——一个 70B 模型用 INT4 量化后 35GB,单卡 80GB A100 就装得下,加上 KV cache 还能并发 10-20 个请求。推理的硬件优化重点不是通信,而是:

  • batching:把多请求塞进一次 forward,抬算术强度;
  • KV cache 管理:PagedAttention 减少碎片;
  • 算子优化:FlashAttention、FlashInfer 提升单算子效率;
  • 量化:降显存、降访存、提算力。

只有当单卡装不下(如 405B 模型)或单机多卡也撑不住流量时,推理才用张量并行(TP)/流水线并行(PP)。推理的 TP/PP 比训练的更简单——没有梯度同步、没有流水线 bubble,只需要在 forward 时切分权重。详见分布式推理

六、微调位置:LoRA/QLoRA 是训练但常用于推理服务前最后一步

微调(fine-tuning)是训练,但在现代 LLM 工程流程里,它常出现在"推理服务上线前"的环节,所以值得在这里厘清位置。

微调的本质

微调是"在已经预训练好的模型上,用小学习率、小数据集继续训练"。它的算力特征介于训练和推理之间——有梯度更新,但 batch 小、steps 少、算力远小于预训练

LoRA 与 QLoRA:让微调能跑在推理卡上

  • LoRA(Low-Rank Adaptation):冻结原模型权重,只训练一个低秩矩阵 A×B(rank 通常 8-64)。可训练参数从 70B 降到几十 M,单卡 24GB 显存就能微调 7B 模型。
  • QLoRA:把原模型量化到 4bit(NF4),只训练 LoRA 部分。让 70B 模型也能在单卡 48GB 上微调。

QLoRA 是"训练侧用量化"的典型——但它的量化只作用于冻结的基模型,LoRA 部分仍是 BF16/FP32 训练,避免了低精度梯度爆炸的问题。这是量化"在训练侧的边界用法",不是推理专属。

微调在部署流程中的位置

一个典型的"模型权重 → 生产服务"流程:

预训练权重(公开仓库)

微调(LoRA/QLoRA,可选)   ← 训练,但常作为部署前定制步骤

合并 LoRA / 转换格式

量化(GPTQ/AWQ/FP8)        ← 推理优化第一步

引擎转换(TensorRT-LLM/vLLM 部署)

在线服务(含 batching/KV cache/路由)

微调是训练,但它经常是部署前最后一步定制——业务领域适配、风格对齐、安全微调(RLHF/DPO)。理解这条流水线,才能看清"为什么 LoRA 仓库常和推理引擎放在一起"。

微调不是推理优化

注意:微调本身不是推理加速手段。它改变模型权重,不改变推理引擎。但微调配合量化时,需要重新校准量化参数——否则会出现"微调后的权重在 INT4 量化下大幅掉点"。这是部署流水线里最常见的隐藏陷阱之一,详见常见陷阱

七、对比表 + 一句话总结

维度训练微调推理
目标让模型学会规律在已训好模型上做领域适配把模型权重变成生产服务
FLOPs / token~8P(前向+反向+优化器)~8P(同训练,但 steps 少)~2P(仅前向)
算力分布密集均匀密集均匀prefill 密集、decode 稀疏
批处理static batching,越大越好static batching,中等 batchcontinuous batching(vLLM/TGI/SGLang)
KV cache不需要(整段序列一次算)不需要必须(自回归生成)
精度BF16/FP32BF16/FP32(QLoRA 例外)FP16/INT8/INT4/FP8
激活显存保留所有前向激活同训练不保留
硬件拓扑大集群 + 高速互联单/多卡,要求低单机多卡为主,靠 batching
典型工具Megatron-LM、DeepSpeed、FSDPPEFT、Unsloth、AxolotlvLLM、TensorRT-LLM、SGLang、TGI
关心指标MFU、loss、收敛收敛、领域指标延迟、吞吐、显存、SLO
在流水线中的位置第一步(预训练)部署前定制(可选)上线服务

一句话总结:训练关心"算力能否压满",推理关心"访存能否喂饱";微调是训练的轻量化尾声,但常作为推理服务上线前的最后一步定制。三者工程上几乎是三个领域,理解这条边界,是判断一个工程师"懂训练还是懂部署"的第一道分水岭。

延伸阅读

参考资料