笔记 / AI 原理tokenization推理KV Cache

架构(自注意力与 Transformer)之外,语言模型还有一整套「文字怎么进出模型」的约定:切分成什么单位、怎么变成向量、位置怎么编码、生成时怎么采样、推理为什么快得起来。这篇从任务定义开始一次讲完。本分类全部笔记见 AI 原理。

一、唯一的任务:预测下一个 token

GPT 类模型的训练目标压缩到极致是一句话:给定前文,预测下一个 token 的概率分布。没有语法标注、没有知识库——语言建模本身迫使模型把句法、事实、推理全部编码进权重,因为每一样都影响下一个词的概率。这叫自监督学习:标签(下一个词)直接来自数据本身,互联网规模的文本都是现成的训练集。

推理就是把这个任务循环执行:预测一步、把结果拼回输入、再预测一步——自回归生成。训练与推理的差异值得注意:训练时每一步的前文都是数据集里的正确前文(teacher forcing),推理时前文里混着自己生成的 token——一步错、步步放大,这是幻觉滚雪花的机制性来源之一。

二、token 与 BPE 分词

模型不直接看字符,看 token——介于字符与词之间的片段。主流算法是 BPE(字节对编码):从字符级词表出发,反复合并语料中出现最多的相邻对,直到词表达到目标规模(现代模型 10 万上下)。「低功耗」可能被切成「低/功耗」,「的」独占一个 token——高频成词、低频拆件。

词表大小是三笔账的平衡:

词表序列长度embedding 参数低频词
太小(字符级)长,注意力 O(n2)O(n^2) 爆炸最省无 OOV
太大(词级)短embedding 矩阵巨大覆盖不全,新词全是 OOV
BPE 平衡点中中未登录词拆成子词仍可表示

子词化的要点在最后一列:「prompt 工程师」从没见过也不怕——拆成「prompt/工程师」,每块都认识。代价是tokenizer 决定了模型眼中的世界粒度:同样的意思,英文一个 token、中文可能要两三个,这就是中文用户按 token 计费时感觉更贵、上下文显得更短的直接原因。tokenizer 一旦训练完成就冻结——预训练数据再大,词表定了就定了。

三、Embedding:查表即一层

每个 token id 对应词表矩阵里的一行向量(维度几百到几千)。所谓 embedding 层就是一次查表——数学上等价于 one-hot 向量乘矩阵,工程上直接按行索引。向量从随机初始化开始,随预训练调整,最终语义相近的 token 在向量空间里靠近,「国王 − 男 + 女 ≈ 女王」这类线性关系成立。

这个矩阵不小:GPT-3 词表 50257 × 12288 维,约 6.2 亿参数——占整个模型参数的 16%,但每个 token 只激活一行。它顺带是 MoE 思路的一个先声:参数多不等于每个输入都要付全部算力,见 自注意力与 Transformer 的 MoE 一节。

四、位置编码:注意力不知道顺序

注意力对输入是无序集合——打乱 token 顺序,每一步的加权和结构不变。但「猫咬狗」和「狗咬猫」必须不同,所以要显式注入位置信息:

方案机制现状
正弦编码(原始 Transformer)固定三角函数,加在输入上不可学习,外推一般
可学习绝对位置(GPT-2)每个 slot 一条可训练向量训练多长就会多长
RoPE 旋转位置编码把相对位置 i−ji-j 编进 Q/K 向量的旋转角当前主流

RoPE 的直觉:给 Q 和 K 各乘一个随位置旋转的矩阵,两向量点积时旋转角相减——注意力分数只依赖相对位置。外推性好(相对量天然泛化)、与线性注意力和部分长上下文技术兼容,LLaMA 之后的开源模型几乎清一色 RoPE。

五、解码:从概率分布到一句话

模型每步输出的是整个词表上的分布,怎么选下一个 token 是解码策略的事:

参数机制效果
temperaturelogits 除以 TT 再 softmaxT→0T\to0 逼近贪心;调高更发散
top-p(核采样)只在累计概率达 pp 的最小集合内采样自适应候选集,主流选择
top-k只在概率前 kk 名里采样固定宽度,分布尖锐时候选过多
repetition penalty已出现 token 的 logit 减分治贪心解码的复读机病

贪心解码(永远取最大概率)会陷入复读:「很好很好很好很好」。根源是模型分布本身平坦时,贪心路径会自我强化。实用配置大致是 temperature 0.7 + top-p 0.9 一档;代码等要确定性的任务直接 temperature 0。

六、KV Cache 与推理优化

自回归生成的朴素实现每步都重算全部历史的注意力——nn 步总共 O(n2)O(n^2)。但历史 token 的 K/V 不变,缓存起来每步只算新 token 的一列,单步复杂度从 O(n2)O(n^2) 降到 O(n)O(n)。代价是显存:KV Cache 随上下文线性增长,长对话里动辄几个 GB,成了推理服务的头号显存项。三个应对,都已在 自注意力与 Transformer 铺垫过:

  • GQA:多头共享 KV,缓存直接缩小数倍;
  • 量化:FP16 存不下的存 INT8/INT4——权重和 KV Cache 都可以压,显存与带宽同步省;量化是有损的,但好的量化方案(如分组量化)损失小到可接受,已是部署标配;
  • 投机解码:用一个小模型草拟几个 token,大模型一次性并行验证——数学上与逐 token 生成完全等价(拒绝采样保证分布不变),却能吃掉大模型的并行空闲,2–3 倍加速零质量损失。

至此,「一个训练好的模型怎么生成文本」闭环了。但模型是怎么训出来的——万亿 token 的预训练、指令微调、偏好对齐——是另一条生产线的事,见 大语言模型的训练与对齐。