分词与嵌入

模型并不直接「读」字符串,而是先把文本切成离散单元(Token),再映射成稠密向量送入网络。这一段决定了模型的输入表示,也决定了上下文窗口、词表大小、对多语言/代码的友好程度等关键工程指标。


Token 与分词(Tokenization)

Token 是模型处理的最小单位。中文里一个汉字通常是 1~2 个 token,英文里一个常见单词约 1 个 token,但生僻词、长词或代码会被拆成多个子词。

直接按「字符」或「单词」切分都有缺点:字符级序列过长、单词级词表爆炸且无法处理未登录词(OOV)。主流方案是子词分词(Subword Tokenization),在词表大小与序列长度之间取平衡。

BPE(Byte Pair Encoding)

从字符级别开始,统计语料中相邻 token 出现频率最高的对,把它们合并为新 token;反复迭代直到达到目标词表大小。GPT 系列使用的 Byte-level BPE 进一步把输入退化到字节级,使得任何 UTF-8 文本都能被无损编码,对多语言与表情符号天然友好。

WordPiece

与 BPE 思路相近,但合并准则换成「合并后语言模型似然提升最大」的对。BERT 使用 WordPiece,子词常以 ## 前缀标记非词首位置(如 play##ing)。

SentencePiece

把输入直接当作 Unicode 字符串处理,不依赖空格切词,因此对中文、日文等无空格语言更友好。常与 Unigram 或 BPE 算法搭配,T5、LLaMA 系列使用此方案。

分词的工程影响

  • 词表大小:常见在 3 万 ~ 20 万之间。词表越大,平均 token 数越少但 Embedding 矩阵越大。
  • 计费与限速:API 通常按 token 计费,前端在估算成本/截断长度时要用对应的分词器(如 tiktoken)实测,而不是按字符数估。
  • 跨语言差异:同一段中文相比英文往往会消耗更多 token,是 LLM 应用本地化时的隐性成本。

词嵌入(Embedding)

分词得到的是一串整数 ID,模型需要把它们转成向量才能参与计算。Embedding 即一张可训练的查找表:词表中每个 token 对应一个 d 维向量(如 d = 768、4096)。

相比早期的 one-hot(只有一位是 1,向量正交、无语义关系),Embedding 把 token 映射到稠密的连续空间,语义相近的 token 在向量空间中距离更近。这是后续注意力计算能「按相似度聚合」的前提。

这里的「Embedding」与 RAG 场景里说的「句子 Embedding」不是同一个东西:前者是模型内部的 token 级查找表,后者是把整段文本编码成单个向量用于检索,通常由专门的 Embedding 模型(如 BGE、text-embedding-3)产出。


位置编码(Positional Encoding)

自注意力本身是位置无关的:把输入打乱后,每个 token 的 Q/K/V 不变,输出也不变。但语言显然有顺序,因此需要把位置信息显式注入。

绝对位置编码

最早的 Transformer 论文用一组正余弦函数为每个位置生成固定向量,与词嵌入相加后送入网络。BERT、GPT-2 等改用可学习的位置 Embedding,但都属于「绝对位置」:每个位置有自己的固定/可学向量。

局限:训练时见过的最长位置决定了推理上限,外推到更长序列效果会迅速劣化。

RoPE(旋转位置编码)

当前主流 LLM(LLaMA、Qwen、DeepSeek 等)普遍采用 RoPE(Rotary Position Embedding)。其核心思想是:不再「加」位置向量,而是按位置 m 对 Q、K 在复数平面做旋转,使得点积 (Q_m \cdot K_n) 自然地只依赖于相对位置 m − n

数学上,每个 token 旋转时只需自己的位置:(Q'_m = R(\theta_m) \cdot Q_m),(K'_n = R(\theta_n) \cdot K_n)。点积时由旋转矩阵的性质 (R(\theta_m)^T \cdot R(\theta_n) = R(\theta_n - \theta_m)),相对位置 (n − m) 自然涌现。这意味着所有 token 的位置编码可以独立并行完成,无需互相交换位置信息。

  • 相对位置感知:注意力分数天然反映两个 token 的距离,更契合语言中「相对位置才重要」的直觉。
  • 长度外推友好:配合 NTK 插值、YaRN 等扩展方案,可以把训练时 4K 的窗口推到 32K、128K 甚至更长,是「长上下文模型」的工程基石。

ALiBi

部分模型(如 BLOOM、MPT)使用 ALiBi(Attention with Linear Biases):不修改 Q/K/V,而是直接在注意力分数矩阵上按相对距离加一个线性惩罚 score = Q·K^T + bias[i − j],距离越远扣分越多。实现极简,外推性意外地好。

注入时机对比

不同方案的注入位置差异很大,直接决定了每一层是否要参与位置计算:

编码方式注入位置执行次数
绝对位置(sinusoidal / learned)embedding 输出端,与词向量相加仅 1 次(layer 0)
RoPEQ/K 投影之后、点积之前,对 Q/K 做旋转每一层都做一次
ALiBiQKT 之后、softmax 之前,给注意力分数加距离偏置每一层都做一次

注意 RoPE 与 ALiBi 都只作用于 Q/K(或 attention score),不修改 V——位置信息只用于「匹配」,不进入「聚合内容」。

「位置编码能支持多长」直接决定了模型的上下文窗口上限,长度外推方案(NTK / YaRN 等)也由 RoPE 衍生而来;详见 inference.md 中的 上下文窗口