返回博客

/ AI Infra

[Infra-3] 分布式训练和分布式推理

从目标、计算流程、显存结构、通信模式、性能指标和调度逻辑出发,系统区分分布式训练与分布式推理,并结合 vLLM 多机多卡场景总结分析重点。

10 minInfra · Distributed Training · Distributed Inference · vLLM

我一开始理解分布式训练和分布式推理时,很容易把它们放在同一个抽屉里:不都是把一个模型拆到多张卡、多台机器上跑吗?

这个说法不能算错,但它只说到了表面。真正做系统分析时,分布式训练和分布式推理的目标、数据流、通信模式、显存压力、性能指标和工程关注点其实都不一样。把这两件事混在一起,很容易导致分析方向跑偏:明明是推理尾延迟问题,却一直按训练里的梯度同步去想;明明是训练扩展效率问题,却用在线服务的 QPS 视角去看。

我现在更愿意用一句话先把它们分开:

分布式训练关注:如何更快、更大规模地更新模型参数。
分布式推理关注:如何更快、更稳定、更低成本地服务用户请求。

训练是在“把模型训练出来”,推理是在“把模型服务出去”。这两个目标不同,后面的系统形态自然也不同。

1. 核心目标不同#

分布式训练的目标是训练模型。一次训练 step 通常要经历:

  1. 前向计算;
  2. loss 计算;
  3. 反向传播;
  4. 梯度同步;
  5. 参数更新。

这意味着训练过程中模型参数会不断变化。系统要解决的问题通常是:

更大的模型
更多的数据
更快的收敛
更高的训练吞吐
更好的多卡扩展效率

例如训练一个 70B 级别的大模型时,单卡通常放不下完整参数、梯度、activation 和优化器状态。这个时候就需要数据并行、张量并行、流水线并行、ZeRO/FSDP 等方法,把模型状态和计算拆到多张卡甚至多台机器上。

分布式推理的目标则不同。模型已经训练好了,参数通常是固定的。系统要做的是加载权重、接收请求、执行前向计算,然后持续生成 token。它更关注:

更低延迟
更高并发
更高吞吐
更低显存占用
更稳定的在线服务

例如用 vLLM 部署 Qwen、Llama、Kimi 这类大模型时,如果单卡放不下模型,或者单卡吞吐无法满足业务,就需要 tensor parallel、pipeline parallel、多副本服务、连续 batching 和 KV Cache 管理。

所以两者虽然都在用多卡多机,但目标完全不同:训练是为了高效更新参数,推理是为了高效响应请求。

2. 计算流程不同#

训练的完整流程可以粗略写成:

输入数据

Forward 前向计算

Loss 计算

Backward 反向传播

Gradient 梯度同步

Optimizer 参数更新

推理的流程更像:

用户请求

Prefill 阶段:处理 prompt

Decode 阶段:逐 token 生成

返回结果

这就是最根本的差异之一:训练既有 forward,也有 backward;推理通常只有 forward。

这会带来一串连锁反应。训练要保存 activation 供反向传播使用,要计算梯度,要维护优化器状态,还要同步梯度或参数分片。推理不需要这些训练状态,但需要面对在线请求的动态性,尤其是长上下文、高并发和逐 token decode 带来的 KV Cache 压力。

因此,训练的复杂性更多来自“反向传播和参数更新”,推理的复杂性更多来自“在线请求调度和生成过程”。

3. 显存压力不同#

训练显存主要包括:

模型参数
梯度
优化器状态
activation
临时计算 buffer
通信 buffer

其中优化器状态非常占显存。以 Adam 为例,除了参数本身,还需要保存一阶动量和二阶动量。如果再考虑混合精度训练中的 master weights,显存压力会进一步上升。

所以训练时经常要用:

  • activation checkpointing;
  • ZeRO;
  • FSDP;
  • tensor parallel;
  • pipeline parallel;
  • optimizer state offload。

这些方法的核心目的之一,就是把训练状态拆开、重算、转移或分片,尽量让超大模型能够训练起来。

推理显存主要包括:

模型参数
KV Cache
临时计算 buffer
请求调度相关 buffer

推理没有梯度和优化器状态,但多了一个非常关键的显存消耗项:

KV Cache

大模型自回归生成时,每生成一个 token,attention 都需要复用历史 token 的 key 和 value。上下文越长、并发请求越多、batch 组织越复杂,KV Cache 占用就越明显。在很多推理系统里,KV Cache 最后会成为比权重本身更麻烦的动态资源。

这也是为什么 vLLM 里会特别关注:

  • PagedAttention;
  • block manager;
  • prefix caching;
  • chunked prefill;
  • preemption;
  • KV Cache block 分配与回收。

这些机制本质上都是在解决推理阶段的动态显存管理问题。

4. 通信模式不同#

训练和推理都会通信,但通信的语义不一样。

4.1 训练里的通信:同步梯度和训练状态#

训练中最典型的通信是梯度同步。

以数据并行为例,每张卡有一份完整模型,各自处理不同 batch。反向传播之后,每张卡都会得到一份梯度。为了让所有模型副本保持一致,就需要做 AllReduce:

GPU0 梯度 \
GPU1 梯度  \
GPU2 梯度   → AllReduce → 每张卡拿到平均梯度
GPU3 梯度  /

所以训练里常见的通信包括:

AllReduce:同步梯度
AllGather:收集参数或 activation
ReduceScatter:切分规约结果
Broadcast:广播参数
Send/Recv:流水线并行中传递 activation 和梯度

大规模训练中,通信往往是主要瓶颈之一。尤其是从 8 卡扩到 16 卡、32 卡、更多节点时,如果通信不能和计算很好地重叠,scaling efficiency 就会下降。

4.2 推理里的通信:合并分片结果和服务请求#

推理里也可能使用 AllReduce、AllGather、Send/Recv,但语义通常不是“同步梯度”,而是“合并分片计算结果”。

以 tensor parallel 为例,一个线性层被切到多张卡上,每张卡只计算一部分输出:

输入 x

GPU0 计算一部分
GPU1 计算一部分
GPU2 计算一部分
GPU3 计算一部分

AllReduce / AllGather

得到完整输出或继续分片传递

推理中的通信主要来自:

Tensor Parallel 层内同步
Pipeline Parallel 阶段间传输
Expert Parallel 中 MoE 路由
多机推理中的跨节点通信
KV Cache 分布式管理
请求调度与结果汇聚

和训练相比,推理没有梯度同步,但它对通信延迟更敏感。训练里一次 step 慢一点,影响的是整体吞吐和训练时间;在线推理里一次通信慢一点,可能直接进入用户看到的 TTFT、ITL、TPOT 或 P99 latency。

这也是为什么推理系统经常不仅看带宽,还要特别看尾延迟和抖动。

5. 并行方式相似,但关注点不同#

训练和推理都可能用到相似的并行方式,但每种并行在两种场景下的意义不同。

并行方式训练中的用途推理中的用途
数据并行 DP多卡处理不同 batch,并同步梯度多个模型副本服务不同请求,提高并发
张量并行 TP切分大矩阵,降低单卡显存压力切分模型权重,让大模型能部署
流水线并行 PP切分模型层,训练超大模型切分模型层,部署超大模型
专家并行 EPMoE 模型训练中的 expert 分布MoE 模型推理中的 expert 路由
ZeRO/FSDP切分参数、梯度和优化器状态推理中通常不需要完整训练状态切分

这里最容易混淆的是数据并行。

训练里的数据并行不是简单地“多份模型各跑各的”。每个 step 结束后,所有副本必须同步梯度,否则参数会越走越不一致。

推理里的数据并行通常更像多副本服务。每个模型副本独立接收不同请求,不需要在请求之间同步梯度,也不需要保持某种训练状态一致。它更接近服务层面的横向扩容。

所以同样叫 data parallel,在训练和推理中,背后的通信要求完全不同。

6. 性能指标不同#

分布式训练常看的指标包括:

tokens/s
samples/s
GPU 利用率
scaling efficiency
通信占比
loss 曲线
收敛速度
checkpoint 开销

比如从 8 卡扩到 16 卡,理想情况下吞吐接近翻倍。如果只提升了 40%,就要回头看通信、负载均衡、数据加载、pipeline bubble 或 kernel efficiency。

分布式推理常看的指标包括:

QPS
吞吐 tokens/s
TTFT:Time To First Token
ITL:Inter-Token Latency
TPOT:Time Per Output Token
P50/P90/P99 latency
显存利用率
请求排队时间
batching 效率
KV Cache 命中率

之前我关注的 P99 ITL,就是典型的推理指标,而不是训练指标。它描述的是高分位请求在 decode 阶段 token 间隔是否变差。这个指标一旦恶化,用户体感就会非常明显:输出开始卡顿,长尾请求变得不稳定。

训练更关心“这一批训练任务整体跑得快不快、扩展效率高不高、能不能收敛”;推理更关心“每个在线请求是否足够快、足够稳、成本是否可控”。

7. 调度逻辑不同#

训练调度相对规则。一个 step 处理一个 batch,batch size 和 sequence length 通常比较稳定。虽然也有 dynamic shape、sequence packing、curriculum、数据倾斜等问题,但整体计算图和执行节奏比较可预测。

可以粗略理解成:

step 0: batch A
step 1: batch B
step 2: batch C
...

推理调度则复杂得多,因为在线请求是动态到达的:

用户 A:prompt 100 tokens,生成 50 tokens
用户 B:prompt 8000 tokens,生成 200 tokens
用户 C:prompt 200 tokens,生成 1000 tokens

这些请求的 prompt 长度不同、到达时间不同、生成长度不同、退出时间也不同。推理系统必须动态决定谁进入 batch,谁等待,谁抢占,谁释放 KV Cache。

这就引出了推理框架里的很多关键机制:

continuous batching
prefill/decode 分离
chunked prefill
prefix caching
KV Cache block 分配
preemption
请求排队与释放

这也是 vLLM、SGLang、TensorRT-LLM 这类推理框架的重点。它们不是在解决训练收敛问题,而是在解决“请求调度 + KV Cache 管理 + 高并发吞吐 + 低尾延迟”的问题。

8. Prefill 和 Decode 是推理里的关键分界线#

在训练里,我们通常习惯按 forward/backward 来拆问题。但在大模型推理里,更常见的拆法是 prefill/decode。

Prefill 阶段负责处理用户输入的 prompt。这个阶段通常并行度更高,矩阵计算更大,比较像一次完整 forward:

prompt tokens → attention/MLP 计算 → 初始化 KV Cache

Decode 阶段负责逐 token 生成。每一步只生成一个或少量 token,但需要不断读取和追加 KV Cache:

上一步 token + KV Cache → 生成下一个 token → 更新 KV Cache

这两个阶段的瓶颈不同:

阶段主要特点常见瓶颈
Prefillprompt 长度可能很长,计算量大算力、带宽、长 prompt 调度
Decode逐 token 生成,小步多次latency、KV Cache、调度开销、同步点

所以分析推理性能时,不能只看总 tokens/s。一个系统可能 prefill 很快,但 decode 的 ITL 很差;也可能总吞吐不错,但 P99 latency 很糟。真正做在线服务时,这些指标要拆开看。

9. 容错和 checkpoint 机制不同#

训练任务可能持续几天、几周甚至更久,所以必须定期保存 checkpoint。训练 checkpoint 通常包括:

模型参数
优化器状态
学习率调度器状态
随机数状态
数据加载状态

这样机器故障、进程崩溃或集群抢占后,训练才能从某个位置恢复。训练关注的是“训练进度不能丢”。

推理系统一般不需要保存训练状态,因为权重是固定的。它更关注服务可用性:

健康检查
请求失败重试
节点故障切流
副本扩缩容
模型热加载
负载均衡
限流与熔断

推理关注的是“线上服务不能断”。一个 worker 挂掉了,理想情况是流量快速切到其他副本;某个请求失败了,服务层要能重试或返回可控错误;高峰流量来了,要能扩容或降级。

这也是两类系统在工程上很不同的地方:训练更像长时间批处理任务,推理更像低延迟在线服务。

10. 网络要求不同#

训练和推理都依赖高速网络,但侧重点不同。

训练中有大量 AllReduce、AllGather、ReduceScatter,非常吃带宽。训练集群通常强调:

高带宽
低延迟
拓扑对称
IB / RoCE
NCCL / CNCL / HCCL 通信效率
通信与计算重叠

推理同样需要高速通信,尤其是 tensor parallel 跨机时。但在线推理更怕尾延迟和抖动。问题经常表现为:

单个请求卡住
P99 latency 变差
decode 阶段 token 间隔变大
跨机 TP 通信拖慢整体
高并发下队列堆积

所以推理除了看带宽,还要看通信稳定性、尾延迟、消息大小分布和同步点数量。一次小消息 AllReduce 如果出现在每层 decode 路径上,即使单次耗时不大,也可能因为重复次数太多而放大成明显的 ITL 问题。

11. 一张表总结差异#

维度分布式训练分布式推理
核心目标训练模型、更新参数部署模型、响应请求
是否反向传播通常没有
是否更新参数没有
主要显存压力参数、梯度、优化器、activation参数、KV Cache
典型通信梯度 AllReduce、参数分片同步TP/PP 通信、KV Cache、请求调度
主要指标tokens/s、samples/s、scaling efficiency、lossTTFT、ITL、TPOT、P99 latency、QPS
输入形态batch 相对规则请求动态、长度不一
调度复杂度相对规则很复杂
框架代表Megatron-LM、DeepSpeed、FSDP、HorovodvLLM、SGLang、TensorRT-LLM、TGI
失败恢复checkpoint 恢复训练服务重试、切流、扩缩容
性能瓶颈通信同步、显存、算力利用率KV Cache、调度、尾延迟、prefill/decode imbalance

如果只记一个区别,我会记这个:

训练的瓶颈经常来自“大家必须同步后才能继续训练”。
推理的瓶颈经常来自“请求动态到达且共享有限服务资源”。

12. 一个直观类比#

分布式训练有点像多人一起写一本书。每个人负责一部分内容,但每写一步都要同步,确保所有人的版本一致。它最怕的是:

大家都算完了,但互相同步太慢。

这对应训练里的梯度同步、参数一致性和通信拖慢。

分布式推理更像多人一起接客服电话。知识库已经准备好了,目标是尽快服务用户。它最怕的是:

用户请求太多,长短不一,有些请求占用资源太久,导致其他请求排队。

这对应推理里的动态 batching、KV Cache 分配、队列堆积和尾延迟恶化。

这个类比不严谨,但很有助于建立直觉:训练是协作式更新,推理是在线式服务。

13. 对 vLLM 多机多卡推理的启发#

如果分析 vLLM 多机多卡推理,我会先提醒自己:这不是分布式训练问题,而是分布式推理问题。

所以分析重点应该放在:

1. TP/PP 是否跨机
2. 跨机通信走什么网卡
3. CNCL/NCCL/HCCL 通信是否高效
4. prefill 和 decode 是否被合理调度
5. KV Cache 是否成为瓶颈
6. chunked prefill 是否改变了算子调用路径
7. 高并发下 P99 ITL 是否恶化
8. Ray 只是进程/资源调度,不等价于真正的数据通信后端

尤其是双机 16 卡推理时,真正影响模型并行性能的通常不是 Ray 本身,而是:

GPU 间通信库
网卡和驱动
跨节点网络
物理拓扑
TP/PP 切分方式
rank 到 device 的映射

Ray 主要负责拉起 worker、管理 actor 和组织分布式执行;真正的大 tensor 通信通常还是由 NCCL、CNCL、HCCL、Gloo 等后端完成。也就是说,Ray 更偏控制和编排,通信库更偏数据面。

在实际排查时,我会按这个顺序看:

  1. 先确认并行策略:TP、PP、EP、数据副本分别怎么切。
  2. 再确认 rank 映射:哪些 rank 在同机,哪些 rank 跨机。
  3. 再看通信后端:NCCL/CNCL/HCCL 是否走到预期网卡和链路。
  4. 再拆 prefill/decode:到底是首 token 慢,还是 token 间隔慢。
  5. 最后看调度和 KV Cache:是否有排队、抢占、cache 碎片或 block 分配问题。

这样分析会比直接盯着“多机多卡为什么慢”更可控,因为它把问题拆回了推理系统真正关心的几个层。

14. 总结#

分布式训练和分布式推理都在使用多卡、多机、通信库和并行策略,但它们解决的是两类问题。

分布式训练解决的是:

如何把模型训练出来。

重点是梯度同步、参数更新、训练状态切分、收敛效率和多卡扩展效率。

分布式推理解决的是:

如何把模型高效服务出去。

重点是请求调度、KV Cache、prefill/decode 拆分、延迟、吞吐、并发和服务稳定性。

所以在做系统分析时,我不能只看到“多卡多机”这个共同外壳,而要先问一句:

现在的问题发生在训练路径,还是推理服务路径?

这个问题一旦问清楚,后面的指标、日志、profile、网络分析和优化手段才会落到正确的位置。