编程与 AI14 分钟阅读更新于 2026-08-03

Transformer 编码器是什么:如何把一段序列变成上下文表示

沿着 Transformer 编码器的完整数据流,理解输入嵌入、位置编码、堆叠编码器层和上下文表示之间的关系,并看清编码器与解码器各自承担的任务。

相关工具

编码器先把输入读懂

在编码器—解码器架构中,编码器的任务不是直接生成目标文字,而是把源序列转换成一组适合后续使用的上下文表示。输入可以是一句话、一段需要摘要的内容,或者翻译任务中的源语言句子。

编码器会让每个位置的表示逐渐吸收其他位置的信息。经过一层自注意力后,一个词不再只代表它自己的词嵌入,而会带上句子中与它相关的上下文;经过多层堆叠后,表示可以包含更复杂的语义和结构关系。

因此,编码器输出不是一个单独的句子标签,而是序列长度保持不变的一组向量。每个位置都有自己的表示,同时这些表示已经不再是彼此孤立的。

Transformer 编码器从输入序列到上下文表示的整体流程图
Transformer 编码器的整体作用

输入序列经过词嵌入、位置编码和多层编码器后,得到每个位置都包含上下文的表示。

编码器的输入从哪里开始

原始文本首先被切分成词元,每个词元通过嵌入表转换为 d_model 维向量。词嵌入只表达内容,还没有充分表达词元位于序列中的哪个位置,所以需要再加入位置编码。

位置编码和词嵌入逐元素相加后,得到第一层编码器的输入。这个输入既包含词元内容,又带有顺序线索,后面的自注意力才能在理解关系时区分不同位置。

如果输入序列包含填充位置,通常还会配合填充掩码,避免模型把无意义的 PAD 当作正常内容读取。填充掩码和解码器的因果掩码作用不同:前者处理补齐位置,后者限制未来信息。

一层编码器包含哪些模块

经典 Transformer 编码器层包含两个主要子层。第一个是多头自注意力,负责让不同位置交换信息;第二个是逐位置前馈网络,负责在每个位置内部对已经融合的表示做非线性变换。

两个子层周围都配有残差连接和层归一化。这样,输入可以沿直接路径保留,子层则学习需要添加的变化;归一化帮助控制每个位置特征的尺度,让很多层能够稳定地堆叠起来。

编码器层的具体归一化顺序可能是 Post-LN 或 Pre-LN,但阅读结构时可以先抓住核心顺序:自注意力交换上下文,前馈网络加工表示,残差和归一化维持计算稳定。

Transformer 编码器单层中注意力、前馈网络和残差归一化的结构图
Transformer 编码器单层结构

编码器层依次包含多头自注意力、残差归一化、逐位置前馈网络和第二次残差归一化。

自注意力如何让每个位置获得上下文

编码器中的自注意力使用同一组输入生成 Q、K、V。每个位置的 Query 会和所有位置的 Key 计算相关性,再根据得到的权重从 Value 中汇总信息。由于编码器通常没有因果限制,一个位置可以查看源序列中的其他有效位置。

多头结构让这种查看拥有多个视角。某个头可能更关注局部邻近关系,另一个头可能更容易发现远距离依赖。多个头的输出经过拼接和线性变换后,形成这一层的上下文更新。

自注意力改变的是每个位置的表示,而不是序列长度。输入有 L 个位置,输出仍然有 L 个位置,只是每个位置的向量已经包含了来自其他位置的信息。

同一个词为什么会得到不同表示

词嵌入表通常为同一个词提供相同的初始向量,但编码器输出会受到上下文影响。例如“银行”出现在“我去银行存钱”和“这家银行服务很好”中,周围词不同,自注意力汇总到它的信息也不同。

经过编码器后,同一个词在两个句子里的上下文表示可以不同。这种表示既保留了词本身的内容,又带上了当前句子对它的解释。它和只查表得到的静态词嵌入不同,所以也常被称为上下文表示。

上下文表示不是依赖某一个固定规则生成的,而是多层注意力、前馈网络、残差和位置编码共同作用的结果。层数越深,表示通常经历的上下文变换越多。

相同词元在不同上下文中得到不同编码器表示的示意图
从词嵌入到上下文表示

相同词元在不同句子中经过自注意力后,会结合不同上下文,得到不同的上下文表示。

为什么编码器要堆叠多层

一层编码器可以完成一次上下文交换和特征加工,但复杂关系通常需要多轮交互。堆叠多层后,每一层接收上一层已经处理过的表示,再进行新的注意力和前馈变换。

浅层表示可能更接近词形、局部关系和简单组合,深层表示则可能包含更抽象的语义关系。这里不是硬性规定每一层只能负责一种信息,而是说多层变换为模型提供了逐步建立复杂表示的空间。

残差连接让每一层可以在已有表示上添加变化,而不是完全重写。层归一化和合适的参数组织则帮助这些层保持稳定。没有这些辅助结构,简单地增加层数并不会自动带来更好的表示。

编码器输出的形状和含义

如果输入表示形状是 B×L×d_model,经过编码器后,输出通常仍是 B×L×d_model。B 是批次大小,L 是序列长度,d_model 是模型主维度。编码器不会把整段序列直接压成一个向量,除非后续任务额外使用池化或特殊位置汇总。

输出中的第 i 个向量对应输入序列的第 i 个位置,但它已经融合了该位置可以访问到的上下文。对于分类任务,可以使用特殊位置的表示或池化结果;对于标注任务,则可以直接使用每个位置的表示;对于编码器—解码器任务,整组输出会作为解码器的 Key 和 Value。

因此,看编码器输出时要同时记住两个层面:位置对应关系仍然存在,内容信息已经发生了上下文融合。它不是无序的句子摘要,也不是原始词嵌入的简单复制。

编码器和解码器的分工

编码器通常完整读取源序列,在源序列内部进行不受未来限制的自注意力,目标是得到充分的上下文表示。解码器则接收目标前缀,通过掩码自注意力保持生成顺序,再通过编码器—解码器注意力读取源序列表示。

一句话概括:编码器负责把源序列整理成可查询的上下文,解码器负责根据这些上下文逐步生成目标序列。两者并不是相互替代的两个版本,而是输入来源、可见范围和输出任务不同的两类模块。

在只需要理解文本、不需要自回归生成的任务中,编码器输出本身就可能是最终的特征基础;在翻译和摘要等任务中,它则作为解码器的重要输入。

如何检查编码器结构是否写完整

第一看输入:词嵌入和位置编码是否在第一层注意力前合成,填充位置是否有相应掩码。第二看每层:是否包含多头自注意力、前馈网络,以及两处残差归一化。第三看输出:序列长度和主维度是否保持,后续任务取用的是单个位置还是整组表示。

还要确认编码器自注意力和解码器掩码自注意力没有混用。编码器通常可以在源序列的有效位置之间自由交互,解码器为了自回归生成才需要屏蔽未来位置。

如果结构图只画了“输入—若干层—输出”,可以继续追问每一层内部发生了什么;如果只画了注意力,没有前馈网络、残差和归一化,也不能算完整的经典编码器层。

编码器的四个检查点
步骤 1
内容与位置

词嵌入和位置编码在第一层前合成。

步骤 2
上下文交互

多头自注意力让有效位置交换信息。

步骤 3
逐位置加工

前馈网络对融合后的每个位置独立变换。

步骤 4
输出对应

输出保持序列位置对应关系,并包含上下文信息。

把编码器放回 Transformer 的整体理解

编码器是 Transformer 中负责理解和表示的一条主线:词元进入嵌入层,位置编码补充顺序,多头自注意力进行跨位置交互,前馈网络加工每个位置,残差和层归一化让多层结构稳定地重复这些操作。

它的输出仍然是一串与输入位置对应的向量,但每个向量已经回答了更多问题:这个位置是什么、它和哪些位置相关、在当前句子里应该怎样解释。解码器或其他下游任务可以继续利用这些上下文表示。

理解编码器之后,Transformer 的整体结构可以拆成两种能力:编码器把序列变成上下文表示,解码器把上下文表示和目标前缀变成新序列。后续学习 BERT、机器翻译和各种生成模型时,这条分工仍然是重要的参照。

常见问题

编码器输出是不是整句话的一个向量?

通常不是。编码器一般输出与输入序列长度对应的一组向量,每个位置都有自己的上下文表示。后续任务可以再使用特殊位置或池化得到单个句子表示。

编码器自注意力为什么通常不需要因果掩码?

编码器的任务是理解完整源序列,源序列中的有效位置通常可以互相查看;限制未来位置主要是解码器自回归生成时的需要。

同一个词的词嵌入相同,为什么编码器输出可以不同?

自注意力会把周围上下文聚合到当前位置,前馈网络还会继续加工,因此同一词元在不同句子中的上下文表示可能不同。