GPU系统拆解-13-多 GPU 与通信:并行策略、拓扑与扩展代价

本文是「GPU系统拆解」系列第 13 篇。
系列导读:GPU系统拆解-00-导读:从架构认知到推理系统的学习路线
上一篇:GPU系统拆解-12-LLM 推理的 GPU 主线:Prefill、Decode、KV Cache 与系统约束
下一篇:GPU系统拆解-14-从 PyTorch 到 CUDA Extension:把算子真正接入工程

这一篇要解决的是一个系统层问题:为什么单卡问题一旦跨到多卡,难度会突然上升。学完这一篇之后,你应该能把 PCIe / NVLink / NVSwitchNCCLtensor parallelpipeline paralleldata parallelKV cache 和推理里的多卡部署取舍放到同一张图里理解。

1. 先给结论

  • 多 GPU 的核心收益不是“卡变多了”,而是你获得了容量扩展、吞吐扩展和更大的资源池。
  • 多 GPU 的核心代价也很明确:为了用到更多算力,你必须付出通信、同步、拓扑和调度成本。
  • 真正影响多卡效率的,不只是并行策略本身,还有互连方式和实际拓扑。
  • 训练和推理的通信主矛盾不同:训练更重梯度同步,推理更重权重切分、激活传输和 KV cache 管理。
  • tensor parallel 适合切单层计算,但会频繁引入层内通信;pipeline parallel 更适合容量扩展,但会引入 bubble 和 stage 间激活传输。
  • 推理里如果单卡能装下模型,优先做模型复制通常更简单;单卡装不下时,才被迫上更复杂的模型切分。
  • 多卡推理最容易吃亏的阶段是 decode,因为它本来计算粒度就小,通信更容易“不值”。

2. 为什么多卡会让问题突然变复杂

单卡时你主要关心:

  • kernel 快不快
  • 显存够不够
  • 算子和调度怎么组织

进入多卡后,问题立刻升级成:

  • 权重怎么切
  • 激活怎么传
  • KV cache 怎么放
  • 哪些卡之间直连,哪些要绕路
  • 通信和计算能不能重叠
  • 通信值不值得

所以多卡系统的本质不是“有更多算力就行”,而是:

为了使用更多算力,你必须先把数据移动和系统协作的问题解决掉。

3. 多 GPU 里真正会传哪些东西

无论训练还是推理,多卡里真正会动的对象无非几类。

3.1 参数

如果模型被切到多张卡,每张卡只持有部分权重,那么某些层前后必须交换局部结果或完整结果。

3.2 激活

一层输出可能是下一层另一张卡的输入,所以激活会在卡间移动。

3.3 梯度

这是训练特有的主角。推理没有反向传播,所以一般不传梯度。

3.4 KV cache

这对 LLM 推理特别关键。只要你开始做张量并行、流水并行或者跨卡调度,KV cache 的布局和读取方式就会直接决定 decode 的通信形态。

4. 互连为什么是第一性问题

很多人会说“我有 8 张卡”,但真正有用的问题是:

  • 这 8 张卡怎么连的
  • 哪些卡直连
  • 哪些通信要跨 PCIe / root complex / NUMA
  • 是否有 NVLink
  • 是否有 NVSwitch

因为:

不是所有 GPU 到 GPU 的路径代价都一样。

这会直接影响:

  • all-reduce
  • all-gather
  • pipeline stage 划分
  • tensor parallel 效率
  • 请求调度

5.1 PCIe:通用外设互连

PCIe 的设计目标是通用 I/O,不是专门为 GPU-GPU 高强度通信设计的。

所以它的特点是:

  • 通用
  • 灵活
  • 但在高频大带宽 GPU 交换场景里更容易变成瓶颈

NVLink 的价值不只是“更快”,而是它更贴近 GPU 工作负载需要的通信形态。

它特别适合:

  • 张量并行
  • 高频 collective
  • 大模型推理里的 GPU 间交换

5.3 NVSwitch:更大规模 GPU fabric

当 GPU 数量继续扩大,单纯点对点直连不够用,NVSwitch 的意义就是把更多 GPU 组织成高带宽、更均衡的互连网络。

所以可以先粗略记成:

  • PCIe:通用道路
  • NVLink:GPU 高速路
  • NVSwitch:更大规模的 GPU 高速路网

6. NCCL 为什么几乎绕不过去

在 NVIDIA 生态里,多 GPU collective 通信几乎绕不开 NCCL

它最重要的价值不是“有 all-reduce API”,而是:

  • 识别拓扑
  • 选择合适的通信路径
  • 选择合适的 collective 算法
  • 尽量减少 CPU 参与

所以你可以把它理解成:

多 GPU collective communication 的高性能运行时。

7. 这些 collective 至少要会区分

这是面试高频基础题。

7.1 Broadcast

一份数据发给所有卡。

7.2 Reduce

多卡结果汇总到一张卡。

7.3 All-Reduce

先 reduce,再让每张卡都拿到最终结果。训练里最典型。

7.4 All-Gather

每张卡各有一部分,最后每张卡都拿到完整结果。推理里的 tensor parallel 很常见。

7.5 Reduce-Scatter

先 reduce,再把结果切回各卡。它常常和 all-gather 配对出现。

真正重要的不是背定义,而是知道:

  • 训练里 all-reduce 更常见
  • 推理里 all-gather、point-to-point 和 stage 间传输更常见

8. 为什么训练和推理的通信结构不一样

8.1 训练更重梯度同步

训练有反向传播,所以 data parallel 下梯度同步是核心矛盾,all-reduce 是主角。

8.2 推理更重权重切分、激活传输和 KV 管理

推理没有梯度同步,但会遇到:

  • 单卡装不下模型
  • decode 时 KV 占显存
  • 每层局部结果需要拼接或传递

所以推理里更常见的是:

  • tensor parallel
  • pipeline parallel
  • 请求级调度
  • KV cache 分片

9. Tensor Parallel 到底在切什么

tensor parallel 最直观的理解,就是把单层的大张量或大矩阵切到多张卡。

例如一层:

1
Y = XW

如果 W 太大,就可以把它切到不同 GPU。每张卡算一部分局部结果,然后再做拼接或归约。

9.1 它的主要好处

  • 单层参数分摊到多卡
  • 单层计算也能分摊
  • 超大模型或超大层才能跑起来

9.2 它的主要代价

  • 每层可能都要通信
  • 层越多,通信次数越多
  • decode 阶段尤其容易吃亏,因为单步计算本来就小

所以 tensor parallel 的本质是:

用层内切分换容量和单层吞吐,但把通信引入到每一层。

10. Pipeline Parallel 到底在切什么

如果说张量并行是在切“层内部”,那么 pipeline parallel 是在切“层与层之间”。

例如:

  • GPU0 负责前 10 层
  • GPU1 负责中间 10 层
  • GPU2 负责后面 10 层

token 或 micro-batch 像流水线一样在不同 GPU 间流动。

10.1 它的好处

  • 参数按层分摊
  • 每张卡只负责一段网络
  • 很适合做容量扩展

10.2 它的代价

  • 会有 pipeline bubble
  • 最慢的 stage 决定整体节奏
  • stage 间激活传输不可避免

10.3 在推理里该怎么理解

它常常更像:

模型装不下时的容量扩展手段,而不是最低延迟手段。

11. Data Parallel 在推理里有没有用

有,而且很常用,但含义和训练里不同。

训练里的 data parallel 主要是为了同步梯度。
推理里的 data parallel 更像:

每张卡放一份完整模型副本,各自服务不同请求。

它的优点很直接:

  • 没有层内通信
  • 每卡比较独立
  • 吞吐扩展简单

它的缺点也很直接:

  • 模型副本重复,占更多显存
  • 超大模型装不下时没法用

所以一个很重要的工程判断是:

  • 模型装得下时,复制模型通常是最舒服的方案
  • 模型装不下时,才必须切模型

12. 为什么推理里的多卡更容易出现“通信不值”

这是推理和训练最容易被混淆的一点。

训练往往有:

  • 更大的 batch
  • 更大的算子
  • 单次通信前后有更多计算可以摊薄成本

而推理尤其是 decode 阶段往往有:

  • 单步计算粒度小
  • batch 不一定大
  • 延迟更敏感

这会导致一种很典型的现象:

多卡理论算力更高,但单请求 decode 延迟未必更漂亮。

所以推理里的多卡设计不能简单照搬训练并行。

13. KV cache 在多 GPU 下为什么会变得更麻烦

单卡时,KV cache 主要是显存对象管理问题。
多卡时,问题马上升级:

  • KV 是按层切还是按头切
  • 一个请求的 KV 是否分散在多卡
  • attention 时是否要跨卡读取 KV
  • 请求迁移时 KV 怎么搬
  • prefill 和 decode 是否采用相同切分策略

这会直接影响:

  • decode 延迟
  • 显存利用率
  • 调度灵活性
  • 请求 rebalance 的可行性

所以很多推理系统的精髓,根本不是“某个 matmul 多快”,而是:

KV cache 的布局和调度是否聪明。

14. 为什么 continuous batching 一旦多 GPU 化,会更复杂

单卡 continuous batching 主要考虑:

  • 哪些请求一起进 batch
  • 哪些完成了移除
  • 哪些新请求插入
  • KV page 如何复用

多卡时还要加上:

  • 请求分到哪张卡
  • 哪张卡剩余显存更多
  • 不同卡 batch 是否均衡
  • 某个请求的 KV 已经在哪张卡
  • 是否允许请求迁移
  • 迁移代价值不值得

所以多 GPU 推理调度本质上变成:

batching + memory placement + communication cost optimization

这已经是完整的系统问题,而不只是 kernel 问题。

15. 一个特别重要的系统判断:切模型还是复制模型

这几乎是推理系统设计里的核心判断题。

15.1 多卡切模型

适用场景:

  • 单卡装不下
  • 单卡带宽或算力不够
  • 必须服务超大模型

代价:

  • 通信复杂
  • 延迟更容易上升
  • 调度更难

15.2 多卡复制模型

适用场景:

  • 单卡能装下模型
  • 目标主要是扩吞吐
  • 希望保持工程简单

代价:

  • 模型副本重复
  • 显存利用率不如切分激进

15.3 更实用的一句话

能复制就先复制,装不下再切;需要容量扩展时才被迫接受通信复杂度。

这不是绝对规则,但对很多推理系统是很实用的默认判断。

16. 这一篇必须记住的几句话

  • 多 GPU 的本质是用更多设备换容量和吞吐,但同时引入通信、同步和拓扑约束。
  • 真正影响多卡效率的,不只是并行策略,还有互连和拓扑。
  • 训练更重梯度同步,推理更重权重切分、激活传输和 KV 管理。
  • tensor parallel 切单层,通信频繁;pipeline parallel 切层,适合容量扩展但会有 bubble。
  • 推理里如果单卡装得下,复制模型通常比复杂切分更简单有效。
  • decode 阶段最容易让多卡通信“不值”,因为它本来计算粒度就小。
  • 多卡推理里很多难点最终都会落到 KV cache 的布局和调度上。

17. 精简版面试表达

如果面试官问你怎么理解多 GPU 推理系统,可以这样答:

多 GPU 的核心不是多几张卡,而是为了拿到更大的容量和更高吞吐,你必须付出通信和调度成本。训练里主矛盾通常是梯度同步,所以 all-reduce 很关键;推理里没有梯度,但会遇到权重切分、激活传输和 KV cache 管理,所以 tensor parallel、pipeline parallel 和请求级调度更重要。对推理来说,如果单卡装得下模型,通常优先做模型复制,因为延迟和工程复杂度都更友好;装不下时才必须切模型。真正决定多卡推理上限的,往往不是理论算力,而是互连、拓扑、通信是否值得,以及 KV cache 的布局和调度是否合理。


系列导航