位置嵌入Position Embedding:Transformer如何感知词序?(train-llm-from-scratch)
2026/8/30 11:11:05 网站建设 项目流程

位置嵌入Position Embedding:Transformer如何感知词序?(train-llm-from-scratch)

【免费下载链接】train-llm-from-scratchA straightforward method for training your LLM, from downloading data to generating text.项目地址: https://gitcode.com/GitHub_Trending/tr/train-llm-from-scratch

在大语言模型(LLM)训练中,位置嵌入(Position Embedding)是让 Transformer 感知词序的关键机制。本项目 train-llm-from-scratch 用一个极简的 GPT 式模型,从数据下载到生成文本完整展示了 LLM 的训练全流程,其中位置嵌入的实现只用了两行核心代码——是新手理解"模型如何区分『我爱你』和『你爱我』"的绝佳切入点。

为什么 Transformer 天生"看不见"词序?

Transformer 的核心运算——自注意力(Self-Attention)——本质上是 token 向量之间的点积打分。它只看"内容",不看"位置":把输入词的顺序打乱,注意力算出的结果只是跟着打乱,输出完全等价(学术上叫置换等变性)。

这意味着:如果没有位置信息,模型会把「今天天气真好」和「真好天气今天」看成同一句话。

上图是项目中单个注意力头的数据流(Q/K/V 投影 → 打分 → 因果掩码 → 加权求和),可以看到整个过程只涉及 token 向量本身,没有任何"位置"参与——这就是为什么必须额外注入位置信息。

train-llm-from-scratch 如何实现位置嵌入?

本项目采用的是最经典的方案:可学习的绝对位置嵌入(Learnable Absolute Position Embedding)

核心实现位于 src/models/transformer.py,只有两个关键部分:

# 位置嵌入表:为上下文中的每个位置 t(0 ~ context_length-1) # 分配一个独立的可学习向量,维度与 token 嵌入相同 self.position_embed = nn.Embedding(context_length, n_embed) # 前向时取出 0..T-1 的位置,索引出位置向量 pos_embedding = self.position_embed(self.pos_idxs[:T]) return tok_embedding + pos_embedding # 直接相加,送进 Transformer 块

整个过程可以总结为三步:

  1. 词嵌入:把 token id 查表成向量e_t(表示"这个词是什么意思");
  2. 位置嵌入:按位置 t 查表得到向量(表示"这个词出现在第几个位置");
  3. 相加融合h_t = e_t + pos_t,两个信息叠加后送入每一层 Transformer 块。

官方文档 docs/foundations/transformer.md 中对此有完整的公式推导,明确指出:

位置嵌入是必要的,因为注意力本身是置换等变的——没有位置信息,模型无法知道一个 token 是出现在句首、句尾还是句中。

多层的注意力头会在这些"带位置信息"的向量上继续加工:

位置嵌入带来的两个重要特性

📌上下文长度的天然上限位置嵌入表的行数固定为context_length,因此模型最多"认识"这么长的序列。超过上限的输入会被截断(见 src/models/transformer.py 中generate方法对idx[:, -self.context_length:]的裁剪)。这也是为什么长上下文能力一直是 LLM 的重要指标。

📌相对位置是被"学"出来的位置向量本身没有预设为"距离",训练过程中模型会自动学会利用位置向量的差异来表达"两个词相隔多远"。本项目在 docs/foundations/transformer.md 的架构决策表中记录了这一选择:

设计选择项目实现结果
绝对位置编码nn.Embedding(context_length, n_embed)简单、易读;上下文长度固定

其他常见的位置编码方案

了解了本项目的做法后,再看业界其他方案会一目了然:

  • 正弦/余弦位置编码(原始 Transformer 论文):用固定公式生成,不增加参数,理论上可外推到更长序列;
  • 可学习绝对位置嵌入:✅ 本项目采用,效果稳定、实现最简单;
  • RoPE(旋转位置编码):把位置信息以"旋转角度"的形式融入 Q/K 向量,是当前主流大模型(Llama 等)的首选。

对新手而言,本项目选择可学习方案正是为了易读性——你能在 src/models/transformer.py#L48-L61 的_pre_attn_pass方法里一眼看懂"词嵌入 + 位置嵌入"是如何融合的。

动手实践:跑通训练,验证你的理解

读完原理后,建议直接跑一遍预训练脚本验证:

python scripts/pretrain_base.py

训练完成后的损失曲线长这样——模型正在同时学习词嵌入、位置嵌入和全部注意力参数:

配套学习材料推荐按此顺序阅读:

  • docs/foundations/transformer.md — 前向传播与嵌入层详解
  • docs/foundations/attention.md — 注意力、因果掩码与多头机制
  • docs/foundations/README.md — 全部基础概念总览
  • 源码入口:src/models/(transformer、attention、mlp、transformer_block 四个文件)

一句话总结

位置嵌入就像给每个 token 发了一张"座位号牌":注意力机制负责"谁能看到谁",位置嵌入负责"你坐在第几个座位"。两者缺一不可——这正是 train-llm-from-scratch 用两行代码[src/models/transformer.py#L42](https://link.gitcode.com/i/278f9dd62b9fce28de748e6af55ae417#L42)讲清楚的 Transformer 核心秘密,也是你从零训练 LLM 时绕不开的第一课 🎓

【免费下载链接】train-llm-from-scratchA straightforward method for training your LLM, from downloading data to generating text.项目地址: https://gitcode.com/GitHub_Trending/tr/train-llm-from-scratch

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询