# 7.3 模型并行与张量并行：拆分权重的艺术

当单个 Transformer 层的参数量太大——即使用 ZeRO 也需要频繁的参数通信时——**模型并行**（Model Parallelism）提供了另一种思路：将模型的计算本身分配到多张 GPU 上。

## 7.3.1 张量并行的核心思想

**张量并行**（Tensor Parallelism，TP）由 NVIDIA 的 Megatron-LM 项目提出，核心思想是**将单层内的权重矩阵切分到多张 GPU 上，协同完成矩阵运算**。

以一个线性层 $$Y = XW$$ 为例，如果 $$W \in \mathbb{R}^{d \times d}$$，可以将 $$W$$ 按列切分为两半：$$W = \[W\_1, W\_2]$$，分别放在两张 GPU 上。每张 GPU 计算 $$Y\_i = XW\_i$$，得到输出的一半。最后拼接结果：$$Y = \[Y\_1, Y\_2]$$。

Multi-Head Attention 天然适合张量并行：不同的注意力头本来就是独立计算的，只需将不同的头分配到不同 GPU 上即可。

## 7.3.2 列并行与行并行的配对

只把单个矩阵按列切分还不够——如果每一层算完都要把分片的输出 AllGather 拼回完整张量再喂给下一层，通信会极其频繁。Megatron-LM 真正的精髓在于**把相邻的两个矩阵乘法一“列”一“行”成对切分**，让中间结果始终保持分片状态，从而把整个子层的通信压缩到只剩一次。

以 FFN 子层 $$Y = \text{GeLU}(XW\_1),W\_2$$ 为例（$$W\_1 \in \mathbb{R}^{d \times 4d}$$，$$W\_2 \in \mathbb{R}^{4d \times d}$$）：

* **第一个矩阵** $$W\_1$$ **按列切分**：$$W\_1 = \[W\_1^{(1)}, W\_1^{(2)}]$$，每张卡算出中间激活的一个分片 $$Z\_i = \text{GeLU}(XW\_1^{(i)})$$。由于 GeLU 是逐元素运算，按列切分后各分片可以独立通过激活函数，**无需任何通信**——这正是必须先列切的原因：若先行切，激活函数的非线性会让分片无法独立计算。
* **第二个矩阵** $$W\_2$$ **按行切分**：$$W\_2 = \[W\_2^{(1)}; W\_2^{(2)}]$$，每张卡用本地分片算出 $$Y\_i = Z\_i W\_2^{(i)}$$，得到一个**部分和**。最后只需一次 **AllReduce** 把各卡的部分和相加，即得完整的 $$Y$$。

这样，整个 FFN 子层在前向只需 **1 次 AllReduce**（反向传播再对称地需要 1 次）。注意力子层同理：$$Q/K/V$$ 投影按列切分（恰好对应把不同的头分到不同卡），输出投影 $$W\_O$$ 按行切分，使多头注意力也只需一次 AllReduce 收尾。因此一个标准 Transformer 层在前向总共只有 **2 次 AllReduce**（注意力、FFN 各一次）——通信量与切分卡数无关、只与层数成正比，这正是张量并行能在节点内高效运转的根本原因。

## 7.3.3 通信模式

张量并行的通信发生在层内——每个线性层的计算都需要在参与的 GPU 之间进行一次 AllReduce 或 AllGather 操作。由于 Transformer 每层包含多个线性层（注意力和 FFN 中各有两个），通信频率较高。

因此，张量并行**通常只在同一节点内的 GPU 之间使用**（利用 NVLink \~900 GB/s 的高带宽和微秒级的低延迟）。跨节点部署张量并行会导致通信成为严重瓶颈（InfiniBand 带宽约 100 GB/s），因为每个 Transformer 层都需要等待跨节点通信完成，难以高效扩展。

## 7.3.4 与数据并行的互补

实际的大规模训练通常**同时使用**张量并行和数据并行：

* **节点内**：使用张量并行（如在 8 张 GPU 之间进行 8 路 TP），解决单层权重太大的问题
* **节点间**：使用数据并行（配合 ZeRO），扩展训练吞吐量

这种组合策略是当前主流大模型训练框架（如 Megatron-LM、DeepSpeed）的标配。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yeasy.gitbook.io/llm_internals/di-er-bu-fen-xun-lian-pian/07_distributed_training/7.3_model_tensor_parallel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
