Skip to content

10 · Tensor Parallel:把一层模型拆到多张 GPU

10 · Tensor Parallel:把一层模型拆到多张 GPU

为什么不是简单地复制模型

数据并行会在每张 GPU 放完整模型,适合训练或并行处理独立批次;但当单个模型放不进一张 GPU,或者希望单次前向由多 GPU 协作时,需要 Tensor Parallel,把层内矩阵切分。

两种基本线性层

Column Parallel

按输出维度切权重矩阵。每张 GPU 计算一部分输出列。QKV 投影和 MLP 的上投影常用这种方式,因为后续计算也可以继续使用分片输出。

Row Parallel

按输入维度切权重矩阵。每张 GPU 计算局部和,随后通常通过 all_reduce 汇总完整输出。Attention 输出投影和 MLP 下投影常见这种方式。

nano-vLLM 的实现位置

  • layers/linear.py:并行线性层、权重加载器和通信。
  • layers/embed_head.py:词嵌入与 LM Head 的词表并行。
  • models/qwen3.py:根据 world size 计算每个 rank 的 head 数和维度。
  • engine/model_runner.py:每个 rank 初始化 NCCL 进程组与对应 CUDA device。

多进程控制

rank 0 负责主控制流,其他 rank 作为 worker。源码使用共享内存传递序列化调用参数,并用事件 / barrier 协调。每张 GPU 都执行同一个逻辑操作,但持有不同权重分片。

必须满足可整除

总 attention head 数、KV head 数、相关隐藏维度必须能被 tensor parallel size 整除。源码中的 assert 不是保守限制,而是保证每个 rank 得到一致分片。

通信可能抵消收益

更多 GPU 不一定更快。小模型或小 batch 时,NCCL 通信、进程同步和 kernel 启动可能比计算本身更显著。Tensor Parallel 首先解决容量问题,其次才是性能问题。

HTML INTERACTIVE LAB10 · Tensor Parallel:把一层模型拆到多张 GPU
单独打开 ↗
课后习题等待完成

Row Parallel 线性层为什么通常需要 all-reduce?

动手任务

选择一个 8×8 矩阵和 2 张 GPU,分别画出 Column Parallel 与 Row Parallel 的切分方向,并标出哪一种需要汇总输出。

下一节:CUDA Graph

社区教程,与 nano-vLLM 上游项目无官方隶属关系。