
这几个并行方式,本质上是在回答同一个问题:
❝一个大模型太大、请求太多、计算太慢时,如何把模型和请求拆到多张 GPU 上?
可以先用一句话理解:
并行方式 | 拆的是什么 | 直观类比 | 主要目标 |
|---|---|---|---|
DP 数据并行 | 拆请求 / batch | 多个完整厨师各做一桌菜 | 提高并发吞吐 |
TP 张量并行 | 拆矩阵计算 | 几个人一起切同一块大肉 | 让单层计算放得下、算得快 |
PP 流水线并行 | 拆模型层 | 工厂流水线,每人负责几道工序 | 让超深模型分层放到多卡 |
EP 专家并行 | 拆 MoE 专家 | 不同专家坐在不同办公室 | 支撑超大 MoE 模型 |
DP 的核心思想是:每组 GPU 上都有一份完整模型,请求被分发到不同副本上处理。
例如有 4 张 GPU,每张 GPU 都能完整放下模型,那么可以这样:
用户请求队列
│
├── 请求 A ──> GPU0:完整模型副本
├── 请求 B ──> GPU1:完整模型副本
├── 请求 C ──> GPU2:完整模型副本
└── 请求 D ──> GPU3:完整模型副本
这就像开了 4 个独立窗口,每个窗口都能完整服务用户。
很多人第一次接触 DP 是在训练中。
训练时:
不同 GPU 处理不同 batch
↓
各自计算梯度
↓
AllReduce 同步梯度
↓
更新相同模型参数
但是在推理阶段,一般没有反向传播,也没有梯度同步,所以 DP 更简单:
请求分发到不同模型副本
↓
各自独立推理
↓
返回结果
因此,推理中的 DP 更像是:
❝多开几个模型服务实例,提高并发处理能力。
Load Balancer / Scheduler
│
┌────────────────┼────────────────┐
│ │ │
DP Replica 0 DP Replica 1 DP Replica 2
│ │ │
完整模型副本 完整模型副本 完整模型副本
│ │ │
GPU Group 0 GPU Group 1 GPU Group 2
注意,这里的一个 DP Replica 不一定只是一张 GPU。
比如大模型太大,需要 TP=8 才能放下,那么一个 DP 副本可能是:
DP Replica 0 = 8 张 GPU 做 TP
DP Replica 1 = 8 张 GPU 做 TP
DP Replica 2 = 8 张 GPU 做 TP
也就是:
DP = 3
TP = 8
总 GPU 数 = 3 × 8 = 24
DP 最大的优点是简单、稳定、吞吐扩展好。
当单个模型副本已经可以正常运行时,增加 DP 副本通常可以接近线性提升并发能力。
例如:
1 个副本:每秒处理 100 tokens
2 个副本:理论上接近 200 tokens
4 个副本:理论上接近 400 tokens
当然,真实场景还会受调度、显存、CPU、网络、KV Cache、请求长度差异影响。
DP 的主要问题是:
❝每个副本都要保存一份模型权重,显存开销大。
如果模型本身已经需要 8 张 GPU 才能放下,那么做 DP 就需要更多 GPU。
例如:
一个模型副本需要 TP=8
如果 DP=4
总共需要 8 × 4 = 32 张 GPU
所以 DP 适合:
模型已经能在一个 GPU 组内放下
并且你想提高并发吞吐
不适合:
模型太大,连一个副本都放不下
这种情况要先考虑 TP、PP、EP。
TP 是把模型中的大矩阵切开,让多张 GPU 一起完成同一层的计算。
Transformer 里面最重的计算主要是矩阵乘法,例如:
Y = XW
其中:
X:输入激活
W:模型权重矩阵
Y:输出
如果 W 太大,一张 GPU 放不下,或者计算太慢,就可以把 W 切开。
假设一个线性层权重矩阵 W 被切成 4 份:
原始权重矩阵 W
┌──────────────────────────────┐
│ │
│ W │
│ │
└──────────────────────────────┘
切成 4 份:
┌───────┬───────┬───────┬───────┐
│ W_0 │ W_1 │ W_2 │ W_3 │
└───────┴───────┴───────┴───────┘
│ │ │ │
GPU0 GPU1 GPU2 GPU3
每张 GPU 只保存一部分权重,并计算一部分结果。
以列切分为例:
输入 X
│
├── GPU0: X × W0 → Y0
├── GPU1: X × W1 → Y1
├── GPU2: X × W2 → Y2
└── GPU3: X × W3 → Y3
│
↓
拼接 / 通信
↓
完整输出 Y
也就是:
Y = concat(Y0, Y1, Y2, Y3)
在一些层里面还需要做 AllReduce:
GPU0 局部结果
GPU1 局部结果
GPU2 局部结果
GPU3 局部结果
│
↓
AllReduce 汇总
│
↓
每张 GPU 得到完整或所需结果
因为 Dense Transformer 模型的很多层都很大,例如:
Attention 的 Q/K/V/O 投影
MLP 的 up_proj、gate_proj、down_proj
这些矩阵可能非常巨大。
TP 可以解决两个问题:
1. 单卡显存放不下完整模型
2. 单卡算力不够,需要多卡一起算一层
TP 的优点是:
1. 可以把单层权重拆到多张 GPU 上
2. 适合 Dense 大模型
3. 对单请求延迟也可能有帮助
4. 是 vLLM、TensorRT-LLM、Megatron-LM 等框架常用方式
比如一个 70B 或 100B 级别模型,可能需要:
TP=4
TP=8
才能比较舒服地跑起来。
TP 的缺点主要是通信频繁。
因为每一层内部都可能需要 GPU 之间通信:
Attention 层通信
MLP 层通信
Residual 相关通信
Logits 相关通信
所以 TP 对硬件互联要求较高。
理想情况:
同一台机器内 NVLink / NVSwitch
可以比较高效。
如果跨机器做 TP:
机器 A 的 GPU 需要频繁和机器 B 的 GPU 通信
可能通信开销很大,效率下降明显。
所以经验上:
TP 优先放在单机内部
跨机器慎用 TP
PP 是把模型按层切开,不同 GPU 负责不同层。
比如一个 Transformer 有 80 层,可以这样切:
GPU0:第 1 ~ 20 层
GPU1:第 21 ~ 40 层
GPU2:第 41 ~ 60 层
GPU3:第 61 ~ 80 层
请求从第一段流向最后一段。
输入 Token
│
▼
┌──────────────┐
│ GPU0 │
│ Layer 1-20 │
└──────┬───────┘
│ 激活传递
▼
┌──────────────┐
│ GPU1 │
│ Layer 21-40 │
└──────┬───────┘
│ 激活传递
▼
┌──────────────┐
│ GPU2 │
│ Layer 41-60 │
└──────┬───────┘
│ 激活传递
▼
┌──────────────┐
│ GPU3 │
│ Layer 61-80 │
└──────┬───────┘
│
▼
输出 Token
这就像工厂流水线:
工人 1 负责切菜
工人 2 负责炒菜
工人 3 负责装盘
工人 4 负责上菜
每个人只负责一部分工序。
如果只有一个请求,它必须依次经过 GPU0、GPU1、GPU2、GPU3:
时间 1:GPU0 工作,GPU1/GPU2/GPU3 空闲
时间 2:GPU1 工作,GPU0/GPU2/GPU3 空闲
时间 3:GPU2 工作,GPU0/GPU1/GPU3 空闲
时间 4:GPU3 工作,GPU0/GPU1/GPU2 空闲
这会造成大量空闲,叫做:
❝Pipeline Bubble,流水线气泡。
图示:
时间 → T1 T2 T3 T4
GPU0 工作 空闲 空闲 空闲
GPU1 空闲 工作 空闲 空闲
GPU2 空闲 空闲 工作 空闲
GPU3 空闲 空闲 空闲 工作
为了提高利用率,需要多个 micro-batch 或多个请求同时进入流水线:
时间 → T1 T2 T3 T4 T5 T6
GPU0 A B C D ...
GPU1 空闲 A B C D
GPU2 空闲 空闲 A B C
GPU3 空闲 空闲 空闲 A B
这样 GPU 就能更连续地工作。
PP 的优点是:
1. 可以把很多层拆到不同 GPU
2. 适合模型深度很大、层数很多的模型
3. 跨机器时比 TP 更容易一些,因为层间只传激活
4. 可以和 TP 组合,形成 TP + PP
例如:
模型总共 80 层
PP=4
每个 stage 20 层
每个 stage 内部再 TP=8
总 GPU = PP × TP = 4 × 8 = 32
结构如下:
Pipeline Stage 0 Pipeline Stage 1 Pipeline Stage 2 Pipeline Stage 3
输入 ───> Layer 1-20 ───> Layer 21-40 ───> Layer 41-60 ───> Layer 61-80 ───> 输出
TP=8 TP=8 TP=8 TP=8
PP 的主要缺点:
1. 单请求延迟可能变高
2. 有流水线气泡
3. 调度复杂
4. 不同 stage 负载不均会拖慢整体
比如某些层更重,某些层更轻,如果切分不均匀,就会出现:
GPU0 很忙
GPU1 很闲
GPU2 很忙
GPU3 很闲
这会降低整体效率。
EP 主要用于 MoE 模型。
MoE 全称是:
Mixture of Experts
混合专家模型
MoE 模型里面有很多专家网络,但每个 token 通常只激活其中少数几个专家。
例如:
总共有 64 个专家
每个 token 只选择 Top-2 个专家
这意味着:
模型参数很大
但每次实际计算只用一小部分
普通 Dense MLP 是这样:
输入 Token
│
▼
一个巨大的 MLP
│
▼
输出
MoE MLP 是这样:
输入 Token
│
▼
Router / Gate
│
├── Expert 0
├── Expert 1
├── Expert 2
├── Expert 3
├── ...
└── Expert N
│
▼
加权合并输出
Router 会判断:
这个 token 应该交给哪些专家处理?
假设有 8 个专家,分布在 4 张 GPU 上:
GPU0: Expert 0, Expert 1
GPU1: Expert 2, Expert 3
GPU2: Expert 4, Expert 5
GPU3: Expert 6, Expert 7
图示:
MoE Router
│
┌────────────┼────────────┐
│ │ │
Token A Token B Token C
│ │ │
▼ ▼ ▼
Expert 1 Expert 4 Expert 7
GPU0 GPU2 GPU3
每个 token 被路由到不同专家,因此需要 token 在 GPU 之间流动。
典型 MoE 推理流程如下:
输入 Token
│
▼
Router 计算每个 token 应该去哪个专家
│
▼
All-to-All:把 token 发送到对应专家所在 GPU
│
▼
各 GPU 上的专家计算
│
▼
All-to-All:把专家输出送回原位置
│
▼
合并输出
更形象一点:
Token 分发前:
GPU0: token a, token b
GPU1: token c, token d
GPU2: token e, token f
GPU3: token g, token h
Router 判断后:
token a → GPU2 的 Expert 5
token b → GPU1 的 Expert 3
token c → GPU3 的 Expert 7
token d → GPU0 的 Expert 1
...
经过 All-to-All 重新分发后,各专家开始计算。
EP 的核心价值是:
❝把大量专家参数分布在多张 GPU 上,同时每个 token 只激活少量专家。
优点:
1. 支持超大 MoE 模型
2. 专家权重不用每张 GPU 都保存
3. 激活参数少,计算量相对可控
4. 对 DeepSeek-V3 / DeepSeek-V4 / Mixtral / Qwen-MoE 这类模型很重要
比如一个 MoE 模型总参数很大,但每个 token 只用一部分专家:
总参数:数百 B
激活参数:几十 B
EP 就是为了高效管理这些专家。
EP 的主要问题是通信和负载均衡。
EP 需要频繁把 token 发送到专家所在 GPU:
GPU0 发 token 给 GPU1/GPU2/GPU3
GPU1 发 token 给 GPU0/GPU2/GPU3
GPU2 发 token 给 GPU0/GPU1/GPU3
GPU3 发 token 给 GPU0/GPU1/GPU2
这种通信叫:
All-to-All
它比普通 AllReduce 更复杂,对网络要求高。
如果 Router 总是喜欢某几个专家,就会出现:
Expert 3 非常忙
Expert 7 非常忙
Expert 1 几乎没活
Expert 5 几乎没活
这会导致:
部分 GPU 很忙
部分 GPU 空闲
整体速度被最忙的专家拖慢
所以 MoE 推理里经常会考虑:
expert load balancing
专家负载均衡
可以用这张总图理解:
大模型多 GPU 推理并行
│
┌───────────────────┼───────────────────┐
│ │ │
拆请求 拆模型 拆专家
│ │ │
▼ ▼ ▼
DP 数据并行 TP / PP 模型并行 EP 专家并行
│ │ │ │
│ │ │ │
多个完整副本 拆每一层矩阵 拆模型层 拆 MoE 专家
│ │ │ │
提高并发吞吐 降低单层压力 支撑深层模型 支撑超大 MoE
假设大模型是一家超级餐厅。
开 4 家一模一样的餐厅
每家餐厅都有完整厨师团队
不同顾客去不同餐厅
对应:
多个完整模型副本
不同请求分给不同副本
一块巨大的牛排,一个厨师切不动
4 个厨师一起切同一块牛排
对应:
一个大矩阵太大
多张 GPU 一起算同一层
厨师 A 负责洗菜
厨师 B 负责切菜
厨师 C 负责炒菜
厨师 D 负责装盘
对应:
不同 GPU 负责不同 Transformer 层
中餐专家、西餐专家、甜品专家、烧烤专家分别在不同工位
不同订单被分配给不同专家
对应:
不同 GPU 保存不同 MoE Expert
不同 token 路由到不同专家
DP 是复制模型,所以:
每个 DP 副本都需要一份完整模型权重
如果一个模型副本需要 8 张 GPU,那么 DP=2 就需要 16 张 GPU。
DP 显存特点:
模型权重复制
KV Cache 也按副本独立保存
TP 会切分权重:
TP=4
每张 GPU 大约保存 1/4 的部分权重
但是实际显存不一定严格等于 1/4,因为还有:
激活
KV Cache
通信 buffer
CUDA graph buffer
临时 workspace
框架额外开销
所以只能近似理解为:
TP 越大,单卡模型权重压力越小,但通信压力越大。
PP 按层切模型:
PP=4
每个 stage 保存大约 1/4 的层
但不同层大小可能不完全一样,尤其 MoE 模型中,某些层可能有专家模块,显存不一定均匀。
EP 主要切专家权重。
例如:
64 个专家
EP=8
每张 GPU 放 8 个专家
这样每张 GPU 不需要保存全部专家。
但是 EP 不能切掉所有权重,因为模型中还有:
Attention 层
Router
Embedding
Norm
非 MoE 层
这些部分可能还需要 TP、DP 或 PP 配合。
并行方式 | 通信强度 | 主要通信类型 | 说明 |
|---|---|---|---|
DP | 低 | 请求级调度 | 推理时副本之间通常不需要频繁通信 |
TP | 高 | AllReduce / AllGather | 每层内部都可能通信 |
PP | 中 | Stage 间激活传递 | 每个 stage 之间传激活 |
EP | 高 | All-to-All | token 要发到对应专家所在 GPU |
简单排序:
通信复杂度大致:
DP < PP < TP ≈ EP
但这不是绝对的,具体取决于模型结构、batch size、序列长度、并行度、网络拓扑。
DP 主要提高吞吐,不一定降低单请求延迟。
单个请求还是只在某一个副本上跑
所以:
DP 对高并发有利
DP 对单请求延迟帮助有限
TP 可能降低单请求延迟,因为一层计算被多卡分担。
但是 TP 通信频繁,如果通信慢,反而可能变慢。
TP 好不好,取决于:
计算节省 > 通信开销
PP 更偏向解决模型放置问题和吞吐问题。
如果请求少,PP 容易有流水线气泡,单请求延迟可能变差。
PP 适合较大 batch 或持续请求流
EP 对 MoE 模型非常关键。
如果专家分布合理,EP 可以显著降低单卡专家权重压力。
但如果 All-to-All 很慢,或者专家负载不均衡,速度会下降。
真实大模型部署一般不是只用一种并行,而是组合使用。
例如 LLaMA、Qwen Dense、Baichuan Dense 等:
TP + DP
或者更大时:
TP + PP + DP
示意:
请求调度器
│
┌───────────┴───────────┐
│ │
DP Replica 0 DP Replica 1
│ │
┌────┴────┐ ┌────┴────┐
│ TP=4 │ │ TP=4 │
│ GPU0-3 │ │ GPU4-7 │
└─────────┘ └─────────┘
含义:
每 4 张 GPU 组成一个 TP 模型副本
一共有 2 个副本
所以 DP=2,TP=4,总 GPU=8
如果模型太深、太大:
PP=2
TP=8
DP=2
总 GPU:
总 GPU = PP × TP × DP
= 2 × 8 × 2
= 32
结构:
DP=2
┌─────────────────────────────┐
│ │
Replica 0 Replica 1
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ │ │ │
PP Stage 0 PP Stage 1 PP Stage 0 PP Stage 1
TP=8 TP=8 TP=8 TP=8
对于 DeepSeek-V3、DeepSeek-V4、Mixtral、Qwen-MoE 这类模型,常见组合是:
TP + EP + DP
更大规模时:
TP + EP + PP + DP
示意:
一个 MoE 模型副本
│
┌────────────────┼────────────────┐
│ │ │
Attention 部分 MoE Expert 部分 层间结构
│ │ │
TP EP PP 可选
也就是说:
Attention / Dense 层:常用 TP
MoE Expert 层:常用 EP
模型太深:再加 PP
并发不够:再加 DP
假设你有 8 张 GPU。
建议:
DP=8
TP=1
PP=1
EP=1
结构:
8 个独立模型副本
每张 GPU 一个副本
适合:
小模型
高并发
低通信
建议:
TP=4
DP=2
结构:
GPU0-3:模型副本 1,TP=4
GPU4-7:模型副本 2,TP=4
适合:
模型较大
还想保留一定并发能力
建议:
TP=8
DP=1
结构:
GPU0-7 一起跑一个模型副本
适合:
大 Dense 模型
单副本推理
缺点:
只有一个副本,并发能力主要靠 continuous batching
可能使用:
EP=8
TP=1 或 TP=2/4
DP=1
或者:
TP=4
EP=8
具体要看框架是否支持这种组合,以及模型结构。
第一步不是问“哪个最快”,而是问:
模型能不能放进 GPU?
如果单卡能放下:
优先 DP,提高并发
如果单卡放不下:
优先 TP
如果 TP 到单机极限还放不下:
考虑 PP
如果是 MoE 模型:
必须重点考虑 EP
如果目标是高并发吞吐:
DP 更重要
continuous batching 更重要
KV Cache 管理更重要
如果目标是降低单请求延迟:
TP 可能有帮助
但通信不能太慢
如果目标是部署超大模型:
TP / PP / EP 是基础
DP 是锦上添花
不一定。
DP 的优势是:
副本之间通信少
扩展吞吐简单
但是前提是:
每个副本能放下模型
如果一个模型需要 8 张 GPU 才能放下,你不能简单地说 DP=8 效率最高,因为每张 GPU 单独根本放不下模型。
所以更准确地说:
❝当模型副本已经能放下时,DP 通常是最简单、最稳定的吞吐扩展方式。
但它不是万能的。
不是。
TP 增大以后:
单卡权重变少
单卡计算变少
但同时:
GPU 间通信变多
同步等待变多
通信延迟变高
所以 TP 有一个合适范围。
常见经验:
单机内 TP=2/4/8 比较常见
跨机 TP 要谨慎
通常不是特别适合单请求低延迟。
PP 更适合:
模型太大
层数太多
需要跨多组 GPU 放置
如果请求流稳定、batch 足够大,PP 的吞吐可以较好。
但如果请求少,流水线气泡明显,GPU 利用率会差。
是的,严格来说 EP 主要针对 MoE 中的专家模块。
对于普通 Dense 模型,没有专家结构,也就谈不上专家并行。
Dense 模型主要用:
DP
TP
PP
MoE 模型才会重点使用:
EP
大模型推理时,KV Cache 非常关键。
每个 DP 副本有自己的 KV Cache:
Replica 0 保存自己请求的 KV Cache
Replica 1 保存自己请求的 KV Cache
Replica 2 保存自己请求的 KV Cache
不同副本之间通常不共享。
优点是简单,缺点是缓存不能跨副本复用,除非系统做了额外的粘性调度或分布式缓存。
TP 下,一个请求会跨多个 GPU 共同计算。
KV Cache 通常也会按照 attention head 或张量维度分布在 TP 组内。
一个请求的 KV Cache
├── 一部分在 GPU0
├── 一部分在 GPU1
├── 一部分在 GPU2
└── 一部分在 GPU3
所以 TP 组内 GPU 是强绑定的。
PP 下,不同 GPU 保存不同层的 KV Cache。
GPU0:Layer 1-20 的 KV Cache
GPU1:Layer 21-40 的 KV Cache
GPU2:Layer 41-60 的 KV Cache
GPU3:Layer 61-80 的 KV Cache
请求必须按相同的 pipeline 路径走完整个模型。
EP 主要作用在 MoE 专家层。
KV Cache 主要来自 Attention 层,因此 EP 本身不是直接切 KV Cache 的主要方式。
不过 MoE 层的 token 分发会影响整体调度、显存和通信效率。
┌──────────────────────────────────────────────────────────────┐
│ 大模型推理并行体系 │
├──────────────────────────────────────────────────────────────┤
│ │
│ DP 数据并行 │
│ - 多个完整模型副本 │
│ - 分摊不同请求 │
│ - 提高并发吞吐 │
│ │
│ TP 张量并行 │
│ - 拆单层矩阵计算 │
│ - 多 GPU 一起算同一层 │
│ - 适合大 Dense 模型 │
│ │
│ PP 流水线并行 │
│ - 按 Transformer 层切分 │
│ - 不同 GPU 负责不同层 │
│ - 适合超深、超大模型 │
│ │
│ EP 专家并行 │
│ - 拆 MoE Expert │
│ - token 被路由到不同专家 │
│ - 适合 DeepSeek / Mixtral / Qwen-MoE 等 MoE 模型 │
│ │
└──────────────────────────────────────────────────────────────┘
一句话记忆:
❝DP 拆请求,TP 拆矩阵,PP 拆层,EP 拆专家。
更工程化地说:
❝DP 解决并发问题,TP 解决单层太大的问题,PP 解决层数太多和模型太深的问题,EP 解决 MoE 专家太多的问题。