本节导读:单卡装不下、或者单卡吞吐不够时,就需要多GPU并行。本节讲清vLLM三种并行方式(TP/PP/DP)的原理与适用场景,给出选型决策树,并覆盖从单机多卡到多机集群的完整部署与排障。
| 并行方式 | 切分对象 | 通信开销 | 适用场景 |
|---|---|---|---|
| 张量并行 TP | 层内权重矩阵 | 高(每层2次all-reduce) | 单卡放不下的中等模型 |
| 流水线并行 PP | 层间切分 | 低(只传边界激活) | 超大模型、跨机扩展 |
| 数据并行 DP | 完整模型副本 | 无(请求级分流) | 提升吞吐、副本扩展 |
TP把每个注意力头和FFN矩阵切到多卡上,各卡算完自己的分片后用NCCL all-reduce汇总。关键约束与开销:
tensor_parallel_size 必须整除 num_attention_heads(7B级模型通常16/32头,TP=4没问题;但如64头的模型不能设TP=6)PP按层切分:GPU0放前1/4层,GPU1放第二个1/4层。通信量极小(只传层间激活),适合跨机;代价是存在"气泡"(流水线空转)且单请求延迟反而增加。vLLM用interleaved调度(micro-batch交错)压低气泡比例。
DP不切模型,每卡跑一个完整副本,前面用负载均衡分发请求。没有通信开销,扩展近乎线性,前提是单卡装得下整个模型。生产高吞吐场景"TP=2/4 + 多副本DP"往往优于"纯TP=8"。
单卡能放下模型? ├─ 是 → 吞吐不够?→ 多副本数据并行(每卡独立实例,前置LB分流) └─ 否 → 模型多大? ├─ 单机多卡放得下 → 张量并行(TP=2/4/8,保持NVLink域内) └─ 需跨机 → TP(机内) + PP(机间),或直接用Ray集群
vllm serve Qwen/Qwen2.5-32B-Instruct \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.9
启动日志中确认每张卡各自加载了分片权重,显存占用约为全量的1/4加激活与KV Cache。
# 两台机器各4卡跑70B:机内TP=4,机间PP=2 vllm serve Qwen/Qwen2.5-72B-Instruct \ --tensor-parallel-size 4 \ --pipeline-parallel-size 2
多机部署用Ray管理进程。先在所有节点启动Ray集群:
# 主节点 ray start --head --port=6379 # 工作节点 ray start --address=<主节点IP>:6379
然后只在主节点启动vLLM,指定GPU总数:
vllm serve meta-llama/Llama-3.1-70B-Instruct \ --tensor-parallel-size 8 \ --pipeline-parallel-size 2 \ --distributed-executor-backend ray
两块卡各跑一个TP=1实例,用nginx做least_conn分流:
upstream vllm_pool { least_conn; server 127.0.0.1:8001; server 127.0.0.1:8002; } server { listen 8000; location / { proxy_pass http://vllm_pool; } }
注意:多副本间不共享KV Cache,带prefix缓存的流量按会话哈希路由可提升命中率。
# 对比单卡与并行的输出是否一致(temperature=0) curl -s http://localhost:8000/v1/completions -d '{ "model": "...", "prompt": "北京是中国的", "temperature": 0, "max_tokens": 8 }'
TP/PP只是切分方式不同,数值上可能有极微小的浮点差异,但语义必须一致;若输出明显混乱,优先怀疑通信或权重切分配置。
| 方案 | 配置 | 相对吞吐 | 延迟 | 特点 |
|---|---|---|---|---|
| 纯TP=8 | 1机8卡 | 1.0x | 最低 | 通信开销大,单请求延迟最优 |
| TP=4×2副本 | 1机8卡 | 1.4x | 低 | 吞吐更优,需前置LB |
| TP=2+PP=4 | 2机4卡 | 0.8x | 中 | 显存极度紧张时的兜底 |
结论:机内优先TP=4,剩下的卡做副本扩展,吞吐比纯TP=8高40%;只有当显存实在不够时才上PP。
Q1:启动报错 "tensor parallel size is not divisible by num_attention_heads"?
TP必须整除注意力头数。检查模型config.json中的 num_attention_heads,调整 tensor_parallel_size 为其因子(如32头可选1/2/4/8/16/32)。
Q2:多机Ray启动后卡在等待worker?
依次排查:①各节点CUDA版本与vLLM版本完全一致;②RAY_ADDRESS/防火墙放行6379及10001端口;③共享存储挂载路径相同(模型文件各节点都能读到同一路径);④ray status 确认节点与GPU都已被识别。
**Q3:TP=2比TP=1慢,正常吗?**
小模型上完全可能。TP的all-reduce开销是固定的,7B以下模型单卡算力过剩,切分后通信占比反而超过计算节省。经验:7B以下不切,14B以上才考虑TP。
Q4:NCCL超时报错怎么排查?NCCL timeout 通常源于网络或P2P问题:①同机卡间确认nvidia-smi topo -m显示NVLink而非PCIe;②容器内需要 --gpus all --ipc=host --shm-size=16g;③跨机网卡带宽不足时调大超时 export NCCL_TIMEOUT=1800 只能缓解,根治要升级IB/RoCE。
Q5:DP多副本怎么做灰度发布?
LB层按权重分流(如新版本实例先接5%流量),对比两版本的错误率与P99延迟,逐步放量。副本间天然隔离,是成本最低的灰度方案。
pip install 导致版本漂移。用统一的Docker镜像保证各节点CUDA/torch/vLLM严格一致;本节讲清了三种并行的取舍:TP用通信换显存、适合机内;PP用延迟换扩展、适合跨机;DP零通信、是吞吐扩展首选。核心方法论是"最小TP + 多副本"。下一节转向另一个免费午餐——缓存策略优化。