F15|从最后一排数到一个Token,再到一句回答
从具体对象与小例子开始,理解计算过程与适用条件。
本章目录
一次输入如何连着预测,直到结束
预测到的Token什么时候显示,什么时候成为下一轮输入?
生成像接一条未完的序列,但不是把整句想好再逐字揭幕。每一轮使用已有前缀产生下一项分布,选择一个Token,把它加入已生成序列,再进行下一轮。使用KV缓存时,程序只把尚未处理的新Token送入模型;历史并没有被丢掉,而是通过每层缓存参与计算。
输入与适用条件:独立、可复算的微型模型:7项教学词表、4维表示、单层单头因果Attention、残差与tanh前馈;省略归一化和位置编码。输出头只用三条指定前缀拟合,目的是演示“学习→!→EOS”,不具有通用语言能力。完整参数与中间值随包提供。
1 / 10 · 输入是“我爱”,还没有输出
窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。
本例教学分词得到[1,2]。这是一台极小的因果模型;下面的候选分数由程序计算,不是商业模型实测。
输入=[1,2];缓存长度=0默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。
为什么需要
先区分已处理、已选出、待处理三种状态,才能正确实现生成与缓存。
怎样实现
循环中先前向、再选Token、判停止;未停止时只追加新Token作为下一次输入。
可能的代价与误解
把刚选出的Token算进缓存长度,会造成位置偏移、重复追加或漏算;更改模型参数还会让缓存失效。
如何判断是否做对
本图实际算出三轮选择[3,5,6],缓存长度[2,3,4];每轮与从头计算整个前缀的结果比较。
最后一层还不是文字
网络处理完输入后,每个位置得到一排d个数。为了生成文字,要给词表每个候选打分。这一步叫输出投影或语言模型输出头。
假设最后一个有效位置的隐藏状态h=[1,2],词表只有6项,使用一个2行6列的教学权重:
Wout = [[0,1,0,1,-1,0],
[0,0,1,1, 0,-1]]
hWout = [0,1,2,3,-1,-2]
输入宽度2变成6个候选分数。取最大会得到编号3。这里的数字与前面字符映射都只是演示,不代表这个没有训练的网络真正理解了中文。
为什么看最后一个有效位置
自回归语言模型在一个位置上产生的是“接在此前缀之后的下一Token”分布。若输入Token为a、b、c,则c所在位置的最后表示用于预测接下来的d。
早先位置也可产生分布,但分别对应更短前缀后的预测。生成当前答案要用最后有效位置,不是任意平均所有位置。带右PAD的batch尤其要选对位置,不能无条件取数组最后一列。
Prefill和Decode只是两种运行阶段
Prefill(预填充)是处理已经给定的整段输入,生成各层所需表示及可保留的中间结果。Prefill结束时最后位置已有下一Token分数,所以可以选出第一个输出Token。
Decode(逐步解码)是把刚选出的新Token再送入模型,继续预测下一个。因为未来Token尚未选出来,后一个生成步骤依赖前一个结果。
已有输入:[a,b,c]
处理a,b,c -> 选出d
再处理d -> 选出e
再处理e -> 选出f
缓存可帮助“不重复处理全部历史”,但不消除生成之间的依赖。缓存内部在下一课解释。
选出来不等于已经处理过
第一步输出d时,模型刚处理过的是a、b、c;d只是从分数中选出的编号,还没有经过自己的Embedding和各层。因此如果缓存保存的是已计算Token的K/V,它此刻只覆盖3个位置,而非4个。
下一步将d作为新输入,才生成d在各层的K/V。这个一位之差决定你是否重复追加输入、是否用错位置和是否错误估计缓存长度。
生成Token与界面显示字符的关系
输出编号要通过对应分词器解回文本片段。某个Token可能对应几个字符,也可能只提供一个多字节字符的一部分。流式显示是让部分结果逐步到达界面,不代表每出现一个汉字就恰好完成一次模型计算。
网络传输也会将数据分成不固定大小的片段,F23会解释为什么半段JSON不能执行。这里先分清生成单位、文本编码单位、网络分片单位。
它怎样停止
模型可以生成特殊EOS(结束)Token;宿主也可以设置最大输出长度、停止字符串或接收取消请求。这些只是不同的停止原因,不能都读成“任务成功完成”。
例如达到输出长度上限可能截断JSON;得到工具调用意味着模型希望宿主做下一步,未必是最终回答;用户取消更不意味着工具一定没有完成副作用。
训练为什么能同时算多个位置
训练时完整样本a、b、c、d已给定,可以同时对a预测b、对ab预测c、对abc预测d,因果mask限制每个位置读取范围。这叫在已知前缀条件下并行计算训练目标,不是提前知道实际推理未来会生成什么。
读到“训练可并行、生成要顺序”时,用这个区别解释,不要以为两者使用了完全无关的语言能力。
预测出一个Token,不等于已经把它写入KV缓存
输入与条件。已处理的Prompt编号是 [1,2,3]。模型最后位置输出三候选概率 [0.6,0.3,0.1],候选编号为4、5、EOS;这些是教学给定。
| 步骤与对象 | 内部动作 | 中间结果 / 新状态 |
|---|---|---|
| 1完成Prefill | 处理Prompt的3个位置 | KV中有3个位置,logits预测接下来的Token。 |
| 2选出ID4 | 例如贪心取最大概率 | 输出序列变 [1,2,3,4],但ID4尚未跑前向,KV仍长3。 |
| 3开始Decode | 把新输入 [4] 和旧KV送入模型 | 本轮才计算ID4各层K/V,缓存增长到4。 |
| 4再预测ID5 | 读取位置4的输出分布 | 输出序列长度5,KV长4,仍差一个刚选出的Token。 |
| 5停止检查 | 下一轮若选择EOS | 根据生成器规则停止展示;不需要为了展示EOS再虚构一次工具执行。 |
把过程连起来。“处理过的Token数”与“已经选出的Token数”在两次调用之间可以相差1。弄错会重复输入或错位缓存。
边界与反例。候选概率与Token号是人为给定;这个状态例不声称模型真的生成某段自然语言。
依据与适用范围:[CACHE]。示例输入和场景由本书明确设定。
课后自检
输入长度3,Prefill刚选出第一个新Token,此时已计算位置通常有几个?
查看参考答案收起参考答案
生成遇到长度上限停止,是否可直接宣告工作完成?
查看参考答案收起参考答案
机制依据:[GENERATION][F-CACHE][TR]。本节数值与情景除另注外均为原创教学示例;来源不代替中文讲解。