目录

TP(Tensor Parallelism,张量并行)和 DP(Data Parallelism,数据并行)

在 vLLM 里,TP(Tensor Parallelism,张量并行)和 DP(Data Parallelism,数据并行)都是为了让多个 GPU 一起跑模型,但分工完全不同。

可以先记一句:

TP:一个模型拆到多个 GPU 上。DP:一个模型复制多份,每份放到不同 GPU 上。

1. TP:Tensor Parallelism

假设你有一个 70B 模型,单张 GPU 放不下。

比如有 4 张 24GB GPU:

snippet.text
              70B 模型
                 │
        ┌────────┼─────────────────┐
        ↓        ↓        ↓        ↓
      GPU0     GPU1     GPU2     GPU3
       1/4      1/4      1/4      1/4

模型的权重、计算矩阵等被切分到多个 GPU。

vLLM:

snippet.bash
vllm serve model \
    --tensor-parallel-size 4

也就是:

snippet.text
TP=4

意味着一个模型实例使用 4 张 GPU。

TP 的主要目的

让“大模型能够装进去”。

例如:

snippet.text
模型需要 80GB 显存
 
GPU0 24GB
GPU1 24GB
GPU2 24GB
GPU3 24GB
 
TP=4
↓
每张 GPU 大约承担 20GB

因此 4 张 GPU 可以共同加载模型。


2. DP:Data Parallelism

DP 完全不同。

假设一个模型只需要 1 张 GPU 就能装下:

snippet.text
        模型
         │
   ┌─────┼─────┐
   ↓     ↓     ↓
 GPU0   GPU1   GPU2
 模型   模型   模型
 ①      ②      ③

每张 GPU 都有完整的一份模型。

然后不同请求分发给不同 GPU:

snippet.text
请求1 ──→ GPU0
请求2 ──→ GPU1
请求3 ──→ GPU2
请求4 ──→ GPU0
请求5 ──→ GPU2

所以 DP 的主要目的不是让模型变大,而是:

提高吞吐量。

3. TP 和 DP 的核心区别

TP DP
———– —————— —————-
全称 Tensor Parallelism Data Parallelism
模型 拆开 复制
每 GPU 模型的一部分 完整模型
主要目的 让大模型跑起来 提高吞吐量
GPU 间通信 很频繁 相对少
对 GPU 间网络要求 较高 较低
显存利用 模型被分摊 每份模型都占一份
典型场景 70B/100B 等大模型 多请求、高并发

4. vLLM 里 TP + DP 可以一起用

这个比较重要。

假设你有:

snippet.text
8 × 24GB GPU

模型需要 2 张 GPU 才能放下。

那么可以:

snippet.text
TP = 2
DP = 4

整体结构:

snippet.text
                 8 GPUs
                   │
        ┌──────────┴──────────┐
        │                     │
      DP副本1               DP副本2
      TP=2                   TP=2
     ┌─────┐                 ┌─────┐
     │GPU0 │                 │GPU2 │
     │GPU1 │                 │GPU3 │
     └─────┘                 └─────┘
 
        DP副本3               DP副本4
        TP=2                   TP=2
       ┌─────┐                 ┌─────┐
       │GPU4 │                 │GPU6 │
       │GPU5 │                 │GPU7 │
       └─────┘                 └─────┘

也就是:

snippet.text
每个模型副本 = 2 GPU
模型副本数量 = 4
总 GPU = 2 × 4 = 8

这样既解决了模型太大的问题,又可以增加吞吐。


5. 一个非常实用的理解

假设:

snippet.text
模型 = 40GB
GPU = 24GB
GPU数量 = 4

TP=1

snippet.text
40GB
 ↓
GPU0:放不下 ❌

TP=2

snippet.text
40GB
 ↓
20GB + 20GB
 
GPU0:20GB
GPU1:20GB
 
可以 ✅

但是只有一个模型副本。


如果:

snippet.text
TP=2
DP=2

那么:

snippet.text
        模型40GB
           │
     ┌─────┴─────┐
     ↓           ↓
   副本1        副本2
   TP=2         TP=2
  GPU0 GPU1    GPU2 GPU3

现在有两个完整的模型实例。

因此:

snippet.text
4 GPU
= TP2 × DP2

6. 为什么不全部用 TP?

例如你有:

snippet.text
8 × H100

模型只需要 2 张 H100 就能跑。

你可以选择:

snippet.text
TP=8

但通常不一定划算。

因为 TP 会产生大量 GPU 间通信:

snippet.text
GPU0 ←→ GPU1
  ↕       ↕
GPU2 ←→ GPU3
  ↕       ↕
...

特别是模型推理过程中,会频繁进行 All-Reduce、All-Gather 等通信。

如果你的目标是高并发推理,更合理的方案可能是:

snippet.text
TP=2
DP=4

而不是:

snippet.text
TP=8
DP=1

前者相当于:

snippet.text
2 GPU × 4 个模型副本

后者:

snippet.text
8 GPU × 1 个模型副本

通常前者更适合提高整体吞吐。