多卡并行策略:张量并行、流水线并行、数据并行及其显存影响
核心原理:三种并行策略的切分维度
多卡部署大模型时,显存碎片治理不能脱离并行策略单独讨论。不同的并行方式决定了每张卡上张量的形状、生命周期和通信模式,进而直接影响显存分配与释放的粒度。理解三种基本并行策略的切分维度,是分析碎片问题的前提。
- 数据并行(Data Parallelism, DP):将训练批次按卡数切分,每张卡持有完整的模型副本。梯度在反向传播后通过 AllReduce 聚合。显存中主要存在的是完整参数、梯度和优化器状态,各卡完全相同。
- 张量并行(Tensor Parallelism, TP):将单个 Transformer 层的权重矩阵按行或列切分到多张卡上。每张卡只持有权重的一部分,但需要在前向/反向过程中通过 AllGather 和 ReduceScatter 通信来拼接中间结果。显存中保存的是分片权重和完整的激活值(或激活值分片)。
- 流水线并行(Pipeline Parallelism, PP):按层切分模型,将不同层分配到不同卡上。每张卡只负责若干层的计算,中间激活值通过点对点通信传递。显存中保存的是本卡负责的层参数,以及流水线中暂存的微批次激活。
三种策略可以组合使用(如 3D 并行),但组合后显存分配模式会叠加,碎片风险也随之上升。下图展示了三种并行策略在 4 卡场景下的显存分布逻辑。
方法流程:并行策略选择与显存配置
在实际部署中,选择并行策略需要结合模型规模、卡间带宽和显存容量。以下是推荐的决策流程:
- 评估单卡显存容量:计算模型权重、梯度、优化器状态和激活值所需的总显存。若单卡可容纳,优先使用数据并行,碎片风险最低。
- 判断是否启用张量并行:当单卡放不下完整模型时,优先考虑张量并行。TP 将权重切分到多卡,但需要高带宽的卡间通信(如 NVLink)。TP 的通信频率极高,每层前向/反向都要进行 AllGather 和 ReduceScatter,因此 TP 通常限制在单机内部。
- 引入流水线并行:当模型层数过多或 TP 规模受限时,使用 PP 按层切分。PP 通信量较小(仅传递激活值),但会产生流水线气泡(bubble),降低计算效率。PP 适合跨机部署。
- 组合并行策略:大模型通常采用 3D 并行(DP + TP + PP)。例如,8 卡场景可配置为 DP=2, TP=4, PP=1,或 DP=1, TP=4, PP=2。组合时需注意各并行维度的显存叠加效应。
在 vLLM 中,并行策略通过 --tensor-parallel-size 和 --pipeline-parallel-size 参数控制。数据并行在 vLLM 中通常由推理引擎自动处理(通过复制模型副本实现)。
# 示例:4卡张量并行启动 vLLM
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3-8B-Instruct \
--tensor-parallel-size 4 \
--gpu-memory-utilization 0.90 \
--max-num-seqs 32
# 示例:2路张量并行 + 2路流水线并行
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3-70B-Instruct \
--tensor-parallel-size 2 \
--pipeline-parallel-size 2 \
--gpu-memory-utilization 0.85
案例场景:Llama-3-70B 在 8×A100 上的显存分配
以 Llama-3-70B 为例,模型权重约 140GB(FP16)。单张 A100(80GB)无法容纳,必须使用多卡并行。假设采用 TP=4, PP=2 的配置:
| 并行维度 | 配置 | 每卡权重显存 | 每卡激活显存(估算) | 碎片风险点 |
|---|---|---|---|---|
| 张量并行 | TP=4 | 140GB / 4 = 35GB | 约 8-12GB(取决于序列长度) | 通信缓冲区的反复分配 |
| 流水线并行 | PP=2 | 35GB / 2 ≈ 17.5GB | 约 4-6GB(仅本卡层) | 微批次切换时的激活释放 |
| KV Cache | — | — | 动态分配,可达 30-40GB | 高碎片风险区域 |
在该配置下,每张卡的总显存占用约为 17.5GB(权重)+ 5GB(激活)+ 35GB(KV Cache)+ 通信缓冲 ≈ 60GB,剩余约 20GB 作为余量。KV Cache 的显存分配是碎片治理的重点——vLLM 通过 PagedAttention 将 KV Cache 划分为固定大小的块(block),每个 block 默认 16 个 token 的 KV 数据。这种分块机制显著减少了碎片,但块大小的选择会影响碎片率:块过小则管理开销大,块过大则内部碎片增多。
--block-size 参数调整 KV Cache 块大小(默认 16)。对于长序列场景,适当增大块大小(如 32)可减少块数量,降低管理开销;对于短序列高并发场景,保持默认或减小块大小可减少内部碎片。
误区与复盘:并行策略中的显存碎片陷阱
在实际部署中,以下误区容易导致显存碎片加剧或性能下降:
- 误区一:TP 规模越大越好。TP 虽然能减少每卡权重显存,但通信开销随 TP 规模线性增长。当 TP=8 时,每层前向需要 8 次 AllGather,通信等待时间可能超过计算时间。此外,TP 的通信缓冲区(用于暂存分片数据)在每次迭代中反复分配释放,容易产生碎片。建议 TP 不超过单机 GPU 数量,且优先使用 NVLink 互联。
- 误区二:忽略 PP 的微批次调度。PP 将训练批次拆分为多个微批次(micro-batch),逐层流水线执行。微批次切换时,前一微批次的激活值被释放,后一微批次的激活值被分配,这种高频分配/释放模式会在显存中留下大量不连续的空洞。若 PP 的微批次数量设置不当(如过多),碎片率会显著上升。
- 误区三:KV Cache 与并行策略脱节。在 TP 场景下,KV Cache 通常按 TP 维度切分,每张卡只保存部分注意力头的 KV 数据。若 KV Cache 的块分配未与 TP 切分对齐,可能导致跨卡访问,增加通信开销并加剧碎片。vLLM 的 PagedAttention 已支持 TP 场景下的 KV Cache 分片,但需确保
--tensor-parallel-size与注意力头数匹配(即头数能被 TP 整除)。
--block-size 调整为 32。调整后碎片率降至 8%,吞吐量提升 35%。
复盘要点:并行策略的选择直接影响显存分配模式。TP 减少权重显存但增加通信缓冲碎片;PP 减少激活显存但引入微批次切换碎片;DP 显存分配最规整但需要完整模型副本。实际部署中应结合模型规模、卡间拓扑和序列长度分布,综合权衡并行维度与 KV Cache 块大小,才能有效控制显存碎片,提升多卡推理性能。