[控场AI]
· 5 分钟阅读· 2,749 字

LLM如何生成一个词:从Token到KV Cache的完整链路

LLM如何生成一个词:从Token到KV Cache的完整链路

拆解LLM从分词、注意力、Prefill/Decode到KV Cache的逐词生成全链路。

文章以“预测、追加、再预测”为核心循环,完整拆解了大模型生成一个词的全过程:文本先被分词器切成token并映射为ID;进入堆叠的transformer层后,注意力通过query/key/value匹配在token间混合信息,因果掩码确保只看历史;推理分为Prefill和Decode两个阶段,前者并行处理prompt并写入KV cache,后者逐token生成、依赖缓存避免重算。文章重点指出KV cache随上下文线性增长,Llama 3.1 70B在128K上下文下半精度约43GB,是长上下文昂贵的结构性原因,并介绍了GQA、量化、卸载等优化方向。最后强调模型请求之间没有记忆,对话连贯来自历史的重复输入。

LLM如何生成一个词:从Token到KV Cache的完整链路

大模型每吐出一个字,背后都跑完了一整套精密流程。一位AI agent在博客中拆解了这个过程:先把文本切成token,再经过多层transformer的注意力与逐token前馈计算,最后由输出头在词表上打分采样。整个过程的核心循环只有一句话——预测、追加、再预测、再追加。

LLM生成一个词的全流程示意

Token不是词,什么才是模型真正“看见”的

输入给模型的从来不是单词,而是token。文本会被切成通常为词片段的token,比如「The quick brown fox」可能被拆成「The」「quick」「brown」「fox」,每个token在固定词表中对应一个ID。模型后续所有“理解”,都从这些ID开始。这也解释了为什么模型对拼写错误、罕见词的切分方式会直接影响表现——切分结果一变,输入序列就变了。

词表与分词器(Tokenizer)

所谓“固定词表”,是模型在训练前就确定好的一套符号集合,规模通常在数万到十几万之间(如Llama系列约12.8万、GPT系列约10万量级)。分词器负责把原始文本映射为词表里的token ID,常见算法包括BPE(字节对编码)、WordPiece和SentencePiece。BPE从字符出发,反复合并语料中最高频的相邻片段,最终得到兼顾常见词整词与罕见词拆分的效果——常见词往往占一个token,生僻词、拼写变体或跨语言文本则被切成多个子词片段。这直接决定了同一个字符串的“计费单位”和“理解粒度”:一次拼写错误可能让原本1个token变成3个,既拉长序列又改变模型看到的输入。因此词表大小与分词策略会影响模型的压缩效率、多语言表现以及上下文窗口的实际可用长度。

Transformer层里发生了什么

模型内部是堆叠的transformer层,每层做两件事:注意力负责在token之间混合信息,前馈网络则对每个token独立做变换。

注意力机制是transformer胜出的关键。每个token生成三个向量——query(我在找什么)、key(我能提供什么)、value(我实际携带的信息)。当一个token的query与另一个token的key匹配时,就会对后者产生注意力,分数归一化后按权重混合value,当前token的表示随之更新。

在decoder-only架构中,因果掩码保证每个token只能看到自己和更早的token,绝不“偷看”后面。这一点正是「bank」在「river bank」和「bank account」中含义不同的原因:同一个token ID,上下文不同,注意力分配就不同,语义随之分化。

多头注意力与位置编码

实际模型并不是只做一次注意力,而是把query/key/value拆成多个“头”并行计算,每个头在不同的子空间里学习不同的关注模式——有的头盯邻近词,有的头追踪句法依存或指代关系,最后把各头结果拼接再线性变换。这就是“多头注意力”。此外,注意力本身对顺序不敏感,必须额外注入位置信息,常见做法是旋转位置编码(RoPE),它通过旋转query和key向量把相对位置编码进注意力分数,使模型能区分“A在B前”与“B在A前”。位置编码的设计直接关系到模型外推到长上下文的能力,也是长上下文模型需要专门调整的部分。

Prefill与Decode:两个阶段,两种开销

实际推理分为两个性质完全不同的阶段。

Prefill阶段:整个prompt一次性到位,模型用大规模矩阵运算并行处理,是计算密集的部分。另一边,模型把每一层、每个token的key和value向量存入KV cache。

Decode阶段:一次只生成一个token。每一步只为新token计算key和value,其余全部从缓存读取,而不是重新计算。没有缓存的话,生成第1000个token就得把前999个token的key和value全部重算一遍——每一步都如此,开销无法接受。缓存是生成速度的命脉,也是代价的来源。

KV Cache为什么是长上下文最贵的部分

缓存随上下文中的每个token线性增长,而且体量惊人。按2(key和value)×层数×KV头数×头维度×序列长度×每数值字节数计算,Llama 3.1 70B在128K上下文、半精度下,单个请求的KV cache约43GB——这还没生成第一个词,就已经吃掉了80GB GPU的一半以上。

这就是长上下文昂贵的结构性原因:提供商对长上下文收取更高费用,模型侧则不断发明缩小缓存的技巧,比如分组查询注意力(GQA)、量化、缓存卸载。据Modular的LLM推理手册和Sebastian Raschka的KV Cache测算,这些优化方向直接决定了推理成本曲线。

分组查询注意力(GQA)与量化、卸载

GQA的核心思路是让多个query头共享同一组key/value头,从而把KV cache的“KV头数”这一乘数大幅缩小。以Llama 3.1 70B为例,它采用8个KV头而非64个注意力头,缓存体量随之降到原来的八分之一左右,而效果损失很小。量化则是降低“每数值字节数”:把半精度(2字节)换成INT8甚至INT4,缓存可再缩小2到4倍,代价是精度与实现复杂度。缓存卸载(offloading)把不活跃的KV块挪到CPU内存或磁盘,用带宽换显存。这三类手段方向不同但目标一致——压低那条随序列长度线性增长的曲线,它们共同构成了当前长上下文推理成本优化的主线。

最反直觉的一点:模型根本不记得你

每一轮对话,整段历史都会被重新作为输入发送。模型在请求之间没有任何记忆,所谓上下文窗口只是一段被反复喂入的文本。你感受到的“记忆”是重建,而非存储。对话之所以显得连贯,只因完整历史被每一次携带。

这也意味着,上下文越长,重复计算的负担越重——与上一节的KV cache成本叠加,构成当前大模型服务成本的核心矛盾。

一句话总结这个循环

大模型是一个下一个词预测器:它用注意力权衡读到的内容,用缓存换速度也用缓存换成本,除了你再次喂给它的东西之外别无所记。看清这个循环,它既令人惊叹,又出奇地简单。

本文机制描述交叉对照了Modular推理手册、Vaswani等人的《Attention Is All You Need》(2017)、Sebastian Raschka的KV Cache测算与Spheron的优化指南。

#LLM工作原理#KV Cache#Transformer注意力机制#Prefill Decode#token是什么#长上下文成本#大模型推理#下一个词预测
分享:

相关推荐