第二十五篇写出来的模型,对着 2017 年的原论文看是解码器那一半、去掉交叉注意力;对着 nanoGPT 看,结构几乎一模一样,差别都在工程。最值得啃的是多头合并那三行:c_attn 把小矩阵并排,view + transpose 把「头」挪到前面 —— 用一个 2 头的小例子手算到底。顺带修正一个说法(q 的偏置不是白加的),算清 6N 那笔账,最后看预训练、SFT、RLHF 怎么把一个只会续写的模型变成 ChatGPT。
把第二十四篇的注意力头装进模型,再堆深、放大,val 从 2.49 一路降到 1.48。多头的参数一个没多,提升来自分工;FFN 补上唯一的非线性;残差让深网络在初始化时约等于浅网络,LayerNorm 换个方向归一化,Dropout 只扔分支、不碰主干。同一个问题问了四次 —— thou 后面接什么:原文里一次都没出现过的 r,从第一名一路跌到 0.001。
换数据集重开:莎士比亚、65 个字符的词表、一条 val 2.49 的 bigram 基线 —— 后面每加一个模块都跟它比。这三段没有新数学,但引入了两样贯穿整集的东西:token 是你自己定义的(顺带解释了阶段四为什么选 Qwen),以及 (B, T, C) 这三个形状。还有一个能一眼看穿的等价:查表就是一层没有偏置的全连接。
六层网络跑通,四张诊断图全部拿到手。前三张是某一步的快照,全绿;真正给出行动项的是第四张 —— 它把「lr 该调多少」从扫描曲线只能排除的范围,变成一个可以直接算出来的倍数。
隐藏层就是 3B1B 那个加权求和,只是一次算完 22 万个样本。张量是一条内存加一份说明书,view 零成本、转置之后就不能 view;手写 loss 和 F.cross_entropy 数值相同,却会算出 nan。