> 转载请注明出处：小锋学长生活大爆炸[xfxuezhagn.cn]
> 如果本文帮助到了你，欢迎[点赞、收藏、关注]哦~

---

## 摘要

**T5（Text-To-Text Transfer Transformer）** 是 Google 在 2019 年提出的基于 Transformer Encoder-Decoder 的大规模预训练语言模型，其核心思想是将所有 NLP 任务统一转换为“**文本输入 → 文本输出**”的生成任务。例如：
- 分类任务变成生成类别名称；
- 翻译任务变成生成目标语言文本；
- 摘要任务变成生成摘要；
- 问答任务变成生成答案。

因此，T5 可以使用同一个模型结构解决不同类型的 NLP 问题。它采用标准 Encoder-Decoder Transformer 架构，并针对大规模预训练进行了改进，包括**相对位置编码、Span Corruption 预训练目标以及大规模 C4 数据集训练**。

T5 是一个**覆盖现代 Transformer 推理优化核心问题的典型计算图**，它包含：
-   大规模 GEMM
-   Multi-Head Attention
-   LayerNorm
-   Softmax
-   Residual Add
-   FFN
-   Encoder-Decoder Cross Attention
-   KV Cache
-   动态 Shape
-   INT8/FP16 混合精度

## 理解Encoder和Decoder
### Transformer 为什么设计 Encoder 和 Decoder？
最初的 Transformer 是为**机器翻译**设计的。例如，输入`I love machine learning`，输出`我喜欢机器学习`。这是一个典型的**输入序列 → 输出序列**问题。因此需要两个角色：

```
输入语言 → Encoder → 语义表示 → Decoder → 目标语言
```

- **Encoder**：阅读理解。负责把输入变成机器能够理解的语义表示。
- **Decoder**：写作生成。负责根据这个语义表示，一个 token 一个 token 地生成输出。

### Encoder 在做什么？

假设输入：

```
The animal didn't cross the street because it was tired.
```

Encoder 的目标是**理解**：

-   animal 是什么
-   it 指代什么
-   tired 和谁有关
-   整句话表达什么意思

Encoder 的最大特点是**双向 Attention**。例如，处理`it`这个词，Encoder 可以同时看到(即同时参考左右上下文)：
- 左边：`The animal didn't cross the street because`
- 右边：`was tired`

数学上，Encoder Self Attention的`Q,K,V`全部来自输入，因此**每个 token 可以关注所有 token**。

BERT 只使用 Encoder，因此它非常擅长：
-   分类
-   情感分析
-   文档理解
-   命名实体识别
-   阅读理解

因为这些任务本质都是**给我一句话，我需要理解它**。BERT 原论文也是基于双向 Encoder 表示进行语言理解任务微调。


### Decoder 在做什么？

Decoder 的目标是**生成新的文本**。例如，输入`Translate English to Chinese: I love AI`，输出`我喜欢人工智能`。

Decoder 的工作过程：

```
第一次：
输入: <BOS> => 预测: 我

第二次：
输入: <BOS> 我 => 预测: 喜欢

第三次：
输入: <BOS> 我 喜欢 => 预测: 人工智能

不断循环。
```

所以 Decoder 的核心是**根据已经生成的内容预测下一个 token**。这就是 GPT 的机制。



### 为什么 Decoder 不能像 Encoder 一样看全部文本？

因为会**作弊**。例如，目标是生成`我喜欢AI`，如果 Decoder 在生成`喜欢`的时候已经看到`AI`，那么它实际上提前知道答案。

所以 Decoder 使用 **Causal Mask（因果 Mask）**。例如生成`A B C D`，那么，Attention矩阵：

```bash
        A   B   C   D

A       √   ×   ×   ×

B       √   √   ×   ×

C       √   √   √   ×

D       √   √   √   √
```

`√`表示可见，`×`表示不可见。上述矩阵的含义是：
-   A只能看自己
-   B能看A
-   C能看A、B
-   D能看A、B、C

他们都能看到自身之前的状态，但是不能看未来。这就是 GPT 的核心：`Decoder Only = 只能基于历史生成未来`

### 三种架构本质区别

| 模型  | 结构  | 擅长  | 弱点  |
| --- | --- | --- | --- |
| BERT | Encoder Only | 理解  | 生成困难 |
| GPT | Decoder Only | 生成  | 复杂理解任务不如Encoder自然 |
| T5  | Encoder + Decoder | 理解+生成 | 计算量更大 |


### 为什么现在 GPT 系列反而不用 Encoder？

这是一个很有意思的问题。理论上`Encoder + Decoder`能力更完整。但是大模型时代发现 Decoder-only 有几个优势：

1. **训练目标简单**。只需要`预测下一个 token`，大量互联网文本天然就是这种形式。
2. **扩展容易**。GPT-3、GPT-4 等模型证明，增加**参数、数据、算力**，Decoder-only 可以持续提升。
3. **Prompt 可以代替 Encoder**。以前`Encoder`负责理解输入，现在`Prompt + Decoder`能同时完成理解和生成。

### 总结
**Encoder 是“读懂世界”，Decoder 是“表达世界”。**
-   BERT 只有 Encoder，所以它像一个非常强的阅读理解模型，但不会自然写文章。
-   GPT 只有 Decoder，所以它像一个非常强的写作者，通过不断预测下一个词生成内容。
-   T5 同时拥有 Encoder 和 Decoder，因此它先理解输入，再根据理解结果生成输出，适合翻译、摘要、问答等输入输出型任务。


## T5 整体架构
T5 基于原始 Transformer 的 Encoder-Decoder 结构。整体结构如下：

![](https://fastly.jsdelivr.net/gh/bucketio/img2@main/2026/07/29/1785342205863-0f784485-0b6b-4117-aa27-e8f892d04b31.png)

### Encoder Layer

T5 Encoder 由多个 Transformer Block 堆叠组成。一个 Encoder Layer：

![](https://fastly.jsdelivr.net/gh/bucketio/img10@main/2026/07/29/1785342370898-74f15745-202b-49ec-b641-425b4e3e64e5.png)


![](https://fastly.jsdelivr.net/gh/bucketio/img12@main/2026/07/29/1785344724723-347a23d8-5b63-4abc-9eba-6d9cd250af21.png)


一个完整 T5 模型通常包含多个这样的 Layer，例如：

| 模型  | Encoder Layer |
| --- | --- |
| T5-small | 6   |
| T5-base | 12  |
| T5-large | 24  |
| T5-3B | 24  |
| T5-11B | 24  |



### Self Attention 机制

Self Attention 是 Transformer 的核心，它解决的问题是：**一个 Token 如何知道其他 Token 对自己的重要程度？**。例如，对于`The animal didn't cross the street because it was tired.`，模型需要知道`it`指代`animal`而不是`street`，Attention 可以学习这种关系。


#### Q、K、V

输入`X`，通过三个线性变换：

$$
Q=XW_Q, \qquad
K=XW_K, \qquad
V=XW_V,
$$

得到：

![](https://fastly.jsdelivr.net/gh/bucketio/img16@main/2026/07/29/1785342749352-534891e9-5e33-49d1-aa8d-0839c5005915.png)

其中：
-   Query：当前 Token 想寻找什么信息；
-   Key：每个 Token 可以提供什么信息；
-   Value：实际携带的信息。


#### Attention 计算

标准公式：
$$
Attention(Q,K,V) = Softmax ( \frac{QK^T}{\sqrt{d_k}} ) V
$$

计算过程：

![](https://fastly.jsdelivr.net/gh/bucketio/img4@main/2026/07/29/1785342845224-9636dc90-9092-482b-be7b-1faa6e1d0014.png)


### Multi-Head Attention

单个 Attention 只能学习一种关系，因此 Transformer 使用多个 Head。例如：

```
Head 1: 学习语法关系
Head 2: 学习语义关系
Head 3: 学习长距离依赖
```

示意结构如下：

![](https://fastly.jsdelivr.net/gh/bucketio/img0@main/2026/07/29/1785343026464-d2372cf6-a9b1-445a-9ff8-692682f6423c.png)


### Feed Forward Network（FFN）

Attention 负责 Token 之间的信息交互，而FFN 负责**对每个 Token 的特征进行非线性变换**。它的结构如下：

![](https://fastly.jsdelivr.net/gh/bucketio/img5@main/2026/07/29/1785343155915-cf35ef15-2589-46f9-b1ea-e41259adeaf6.png)

它的结数学形式：
$$
FFN(x)=W_2\sigma(W_1x+b_1)+b_2
$$

通常第一层是 768 → 3072，第二层是 3072 → 768。因此 FFN 通常占 Transformer 大量计算量。


### Decoder 结构

Decoder 是 T5 与 BERT 最大的区别。

#### Decoder Layer

一个 Decoder Block 如下，相比 Encoder 增加了 **Cross Attention**：

![](https://fastly.jsdelivr.net/gh/bucketio/img17@main/2026/07/29/1785343270485-7782e3da-ba8b-4111-bd52-981dc95adcbe.png)


### Cross Attention

Cross Attention 是 Encoder-Decoder 模型的核心，它让 Decoder 在生成时参考输入文本。在 Self Attention 中，`Q,K,V`来自同一个序列；而在 Cross Attention中，`Q` 来自 Decoder，`K,V` 来自 Encoder。结构如下：

数学形式：
$$
Attention(Q_{dec},K_{enc},V_{enc})
$$

![](https://fastly.jsdelivr.net/gh/bucketio/img7@main/2026/07/29/1785343613670-6b4a20a0-1dca-4ce5-8ea6-41aacd31f957.png)



### T5 的位置编码

原始 Transformer 使用 `Absolute Position Encoding`。例如，`Token 1、Token 2、Token 3` 分别加入位置向量；而 T5 使用 `Relative Position Bias`，即**关注 Token 之间的相对距离**。例如，`Token A` 距离 `Token B` 是3个位置。这个距离信息直接加入 Attention Score：
$$
Attention= Softmax(\frac{QK^T+B}{\sqrt d}) V
$$
其中，`B`表示相对位置偏置。


### T5 的 LayerNorm

T5 对 Transformer 的 Normalization 进行了调整。


![](https://fastly.jsdelivr.net/gh/bucketio/img14@main/2026/07/29/1785343806152-086b05c8-f6fc-4b09-92cb-9458d294b70e.png)


这种结构称为 **Pre-LayerNorm**,它能够改善深层 Transformer 的训练稳定性。


### T5 的预训练方法

T5 使用 **Span Corruption** 方式，类似 BERT Mask，但不是随机 Mask 单词，而是 Mask 连续片段。例如：

- 原文本：`The quick brown fox jumps over the dog`

- 随机删除：`The quick <extra_id_0> jumps over <extra_id_1>`

- 目标：

```
<extra_id_0> brown fox

<extra_id_1> the dog
```

- 模型学习：根据上下文恢复缺失文本。

相比 BERT **预测一个词**，T5则是**生成一个文本片段**，因此更加适合生成任务。


### T5 模型规模

T5 发布多个规模：

| 模型  | 参数量 |
| --- | --- |
| T5-small | 60M |
| T5-base | 220M |
| T5-large | 770M |
| T5-3B | 3B  |
| T5-11B | 11B |

其中，T5-base：

```
Encoder Layer: 12

Decoder Layer: 12

Hidden Size: 768

Parameters: 220M
```

### T5 推理过程

假设任务：

```
translate English to German:
I love AI
```

#### 第一步：Encoder

输入 `I love AI`，得到 `Encoder Hidden States`


#### 第二步：Decoder

- 初始 `<BOS>`，生成 `Ich`；
- 继续输入 `<BOS> Ich`，生成 `liebe`；
- 继续 `<BOS> Ich liebe`，生成`KI`；
- 直到 `<EOS>` 结束。


#### Decoder Init (Prefill)
T5 在实际推理部署（尤其 ONNX Runtime、TensorRT、NPU 推理框架）中，通常会人为划分一个 **decoder initialization 阶段**。原因来自 Decoder 的**自回归生成**：

```
第一次输入 "<BOS>"，则输入 Decoder 的是 "<BOS> + Encoder Hidden States"，生成 "Ich"。
```

这里的第一次 Decoder 推理和后续 Decoder 推理是不一样的。第一次 Decoder 推理：

通常称：
- decoder init
- decoder prefill
- first decoder pass

它负责：
- 输入初始 token（通常 <pad> 或 <bos>）
- 计算 Decoder Self Attention
- 计算 Cross Attention
- 生成第一个 token
- 初始化 KV Cache

流程：

![](https://fastly.jsdelivr.net/gh/bucketio/img3@main/2026/07/29/1785345687341-eb100ca4-60cb-4fcb-b40e-c6603ee90386.png)

后续 Decoder 通常叫 **decoder with past** 或者 **decoder incremental**。

以 HuggingFace / ONNX Runtime 导出 T5 为例，通常会看到：

```bash
t5/
├── encoder_model.onnx            # Encoder
├── decoder_model.onnx            # Decoder Init
└── decoder_with_past_model.onnx  # Decoder With Past
```

**三个阶段特点：**
| 阶段  | 特点  | 优化重点 |
| --- | --- | --- |
| Encoder | 一次计算 | Attention/FFN融合、INT8 |
| Decoder Init | 第一次生成 | Attention + KV Cache初始化 |
| Decoder With Past | 循环生成 | KV Cache、动态Shape、低延迟 |


### T5 对 ONNX 图结构的影响

![](https://fastly.jsdelivr.net/gh/bucketio/img14@main/2026/07/29/1785344269380-696cc1fd-ee65-4146-a3a2-15ac06de3552.png)


### T5 与现代大模型的关系

虽然今天主流聊天模型大量采用 Decoder-only 架构，例如 GPT 系列，但 T5 的思想影响仍然非常深远。主要影响包括：

- **Instruction Tuning**：后来，FLAN-T5 就是在 T5 基础上加入大量指令数据。
- **Text-to-Text 范式**：今天很多，如指令模型、Agent、多任务模型等，仍然继承**任务描述 + 输入文本 => 统一生成**。

