GPU系统拆解-13-多 GPU 与通信:并行策略、拓扑与扩展代价
GPU系统拆解-13-多 GPU 与通信:并行策略、拓扑与扩展代价
本文是「GPU系统拆解」系列第 13 篇。
系列导读:GPU系统拆解-00-导读:从架构认知到推理系统的学习路线
上一篇:GPU系统拆解-12-LLM 推理的 GPU 主线:Prefill、Decode、KV Cache 与系统约束
下一篇:GPU系统拆解-14-从 PyTorch 到 CUDA Extension:把算子真正接入工程
这一篇要解决的是一个系统层问题:为什么单卡问题一旦跨到多卡,难度会突然上升。学完这一篇之后,你应该能把
PCIe / NVLink / NVSwitch、NCCL、tensor parallel、pipeline parallel、data parallel、KV 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. PCIe、NVLink、NVSwitch 本质区别是什么
5.1 PCIe:通用外设互连
PCIe 的设计目标是通用 I/O,不是专门为 GPU-GPU 高强度通信设计的。
所以它的特点是:
- 通用
- 灵活
- 但在高频大带宽 GPU 交换场景里更容易变成瓶颈
5.2 NVLink: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 的布局和调度是否合理。

