原来是 LLM 生成文本
原来是 LLM 生成文本,不知道的还以为是把输入剁成一堆。
拿大量文本统计出的最常见字符串组合的词元(token),高频组合各占一个词元,而生僻词拆成更小的子词元,通过查询一张几万行的对照表,把每个词元换成几千维的数字串,也就是向量表示(embedding)。
每一层先进行 RMS Norm(均方根归一化),然后把每串数字分别与三个不同的矩阵相乘,得到 Q、K、V 三个值。
在 Q 和 K 上,根据各自的位置加入旋转位置编码(RoPE,Rotary Positional Embedding),把位置信息融合进去。然后所有位置之间通过 QK 点积计算注意力分数,再除以 \sqrt{d_k},把数值压回正常量级。
计算完成后,先使用因果掩码(Causal Mask),把后面的未来词元全部用负无穷遮住,防止模型看到未来信息。然后通过 Softmax 将分数归一化,根据权重对 V 进行加权混合,生成新的数字串。
多个注意力头并行运行,也就是多头注意力(Multi-Head Attention),然后把多个头的结果横向拼接,再经过一个 W₀ 输出投影矩阵(Output Projection Matrix)进行线性变换。
之后通过残差连接(Residual Connection)加回原始数字串,避免几十层堆叠后原始信息丢失,同时保证梯度能够有效传播。
再次经过 RMS Norm,然后进入一个 前馈网络(FFN):
先把维度扩大(通常约为原来的数倍),再压缩回来。中间使用类似 SwiGLU 激活函数的结构:
把输入拆成两路,一路经过 SiLU 激活函数,一路保持线性变换,然后逐元素相乘,再加回网络中。
这个流程重复几十层,最后通过一个将隐藏维度映射到词表大小(Vocabulary Size)的线性矩阵,得到每个词元的预测分数。
再经过 Softmax 转换成概率分布。
采样阶段:
可以通过温度(Temperature)控制概率分布的平滑程度;
或者使用 Top-K 采样,只保留概率最高的 K 个词元,将其他概率归零;
也可以使用 Top-P(核采样,Nucleus Sampling),按照概率从高到低累加,超过阈值后截断,只保留概率质量最高的一部分候选词元。
然后根据这个概率分布随机选择一个词元,把它接到输入序列后面,再继续进行下一轮计算。
在生成过程中,每一层每个注意力头都会把之前计算过的 Key 和 Value 缓存在显存中(KV Cache)。
生成新的词元时,只需要计算当前词元对应的一行 Q,然后与缓存中的 K 做注意力计算,再利用对应的 V 得到新的表示。
这个过程不断循环,直到模型生成特殊结束词元 EOS(End Of Sequence)。
最后,把每一次生成的词元按照顺序拼接起来,经过词元解码(Detokenization),组合成为最终输出文本