MECHANISTIC REPRODUCTION NOTE2026-08-06code: ngram-gap-lab ↗

n-gram Gap:最小复现与机制证据

只问一个问题:在 vanilla nanoGPT 中,仅加入可训练的 bigram / trigram value memory,是否足以让固定顺序 replay 产生 train/val gap?这里把 setting、曲线和频率证据放在主线;术语、伪代码、debug 过程和历史分支放到背景页。

v10 克隆:本页为 validation 每 10 步 · 2000 steps 的重跑版本(原版为 val 每 50 步 · 1000 steps,见 原版页面)。
版本说明:本页保留早期 injection-point ablation 作为历史对照,并在下方合并新的 collision-free exact-frequency baseline。旧版完整分析(含 current-shell、exp4/exp5、toy、P1/P2)仍保留在 index_archive_20260805.html;背景与 debug 子文档解释这些概念为何不属于最小 setting。
一句话结果

是的。n-gram table 在训练集上逐渐记住 context-specific value;固定顺序多 epoch replay 后,train loss 继续下降,而 val loss 在 epoch 边界后上升,形成 gap。

bigram + trigram→train-specific memory→replay gap
本页的判断标准

不把 current shell、Muon、RoPE 或复杂观测系统当作必要条件。用同一份 vanilla 模型,只改变 n-gram 的注入点,观察 gap 强弱是否随信号到达输出的方式变化。

1. 最小 setting

标准主线是 baseline_input。它对应最朴素的 over-encoding:先查 n-gram value,再加到 token embedding,后面运行普通 Transformer。

模型vanilla nanoGPT
memorybigram + trigram
注入点input / wte
数据顺序fixed replay
table optimizerRMSProp
backbone optimizerAdamW
规模8L · 6H · 768D
实验seed 42 · 2000 steps
validation每 10 步
freq eval每 10 步

训练 shard 约 226 steps / epoch(含 freq eval 消耗的 train batches;虚线为数据自动标注的 epoch 边界:230, 460, 680, 910, 1130, 1360, 1580, 1810)。validation 与 freq-bin eval 均每 10 步一次。三种注入点仅用于消融,不是三个不同的模型家族。

2. 核心结果:注入点改变 gap 强度

同一个 n-gram table 放在不同位置,得到不同的信号路径。y 直接绕过 attention 到达 residual stream;input 在最开始加入 embedding;v 则先进入 attention 的 value,再被权重混合。

v 注入
5.04
gap @ 2000 steps
y 注入
5.05
gap @ 2000 steps
input 注入
1.93
gap @ 2000 steps
无 n-gram
0.23
negative control
y:最强、最快

n-gram 信号在 attention 之后加入,每层都能直接影响后续输出。

input:最基础

查表结果一次加到 wte;这是后续实验默认采用的最朴素 setting。

v:较弱、较晚

value residual 会被 attention 混合,且当前 norm 只有 V 的约 6.5%。

3. 训练曲线:epoch replay 后 train / val 分叉

Loss 与 gap 曲线虚线:epoch boundary · 点击图例可隐藏/恢复曲线

4. Table norm × gap

table 的参数 RMS 是一个直接的 memory growth 指标。它帮助确认 n-gram 确实在被写入,但不能单独决定 gap 的大小:y 的 gap 最大,并不意味着它的 table RMS 增长最快。

Loss、gap 与 table RMS 的时间对齐input 主 setting · 点击图例可隐藏/恢复曲线
stepv gapy gapinput gapv table RMSy table RMSinput table RMS

5a. 历史频率分解视图

我们用训练集中的真实 token context统计 hit count,再把 train / val token 按频率分桶。每个 bucket 都保留 token count、token fraction、平均 token loss 和总贡献(fraction × loss)。novel(train hit count = 0)保留在 raw 统计和直方图中,但不画 gap:train 中没有对应 token loss,无法定义同桶的 train/val 差值。

按 hit count 分桶的 loss / gap每条线是一个真实频率桶;可切换 per-token loss / total contribution;点击图例可隐藏曲线
命中频次直方图 + 末态 gap 曲线柱:train/val 命中占比;曲线:末态 gap;novel 不画 gap;点击图例可隐藏系列
Log–log:frequency 与 gap 的定量关系x 轴和 y 轴均为 log scale;使用原始 15 个真实桶,只显示正 gap
Log-x:frequency 与 gap 的定量关系x 轴为 log scale,y 轴保持线性,便于直接读取 gap 大小
读图重点:直方图回答“不同频率的 context 占多少”;gap 曲线回答“这些频率桶最终产生多大 train/val 差异”;Log–log 图用于观察 frequency 增加时 gap 是否近似按幂律衰减。

5b. 频率分解:gap 从哪些 context 来?

这组图保留早期主线中的 hit-count 分桶与交互视图。新的 exact-frequency 定义、2000-step baseline、最终 gap 和完整训练曲线已在下一节作为当前主结果重新合并。

历史频率分解视图保留用于与早期 injection-point ablation 对照
注意:不要将这一组历史图与下方的 exact baseline 数值混合解读;当前频率主结论以 exact train-epoch context count 为准。

6. Exact-frequency baseline:主结果

这里合并 collision-free exact trigram baseline。r(c) 只来自完整 train epoch 的真实 context count;hash bucket occupancy 不参与频率或 gap 定义。最终 gap 按 step 2000 的 train / validation per-frequency loss 计算,训练曲线也来自同一个 run。

数据账本:22,759,032 个 distinct exact contexts;62,931,706 个 train context instances;P50=1,P99=28,最大频率=77,928;NanoGPTOriginal,input injection,bigram + trigram,seed 42,2000 steps。
Exact-frequency report训练曲线、频率直方图、final gap scatter、分 bin gap、gap trajectory 与 norm trace

7. 受控样本量复播:Transformer 与 MLP trunk 对照

这是同一条 real-text trigram controlled baseline 的样本量重采样和 trunk 对照,不是新的频率定义。完整 upstream train/val block 流先按整行均匀下采样,使一个 epoch 固定为 285 steps;随后只改变 n-gram 表之后的 backbone。

实验口径:train=20,520 rows,val=288 rows,device batch=72,batch tokens=147,456,2000 steps,约 7 个 replay epochs;seed=42,input-position bigram+trigram VE,unigram/fourgram 关闭,mixed n-gram optimizer,learning rate=0.004。两组 batch hashes 完全一致。频率仍是完整 upstream train epoch 的 exact context count:P50=1、P90=4、P99=28、max=77,928。
Transformer and MLP train validation loss over repeated epochsExact train trigram frequency distributionFinal gap by exact trigram frequency
真实频率 bin有效点数Transformer gapMLP gap
117.177.82
6–1056.027.23
11–20105.406.55
21–50304.785.57
51–100504.264.32
101–2001003.583.01
201–5002962.661.68
501–1k3452.621.40
1k–5k3912.290.82
5k+502.100.37
结论边界:MLP-only 仍产生 gap,因此 gap 不是 attention 才能产生的现象;但 MLP 的 train/val loss 更高,存在欠拟合,所以这不是“机制完全等价”的证明。它是一个干净的存在性/边界验证:更强的 Transformer trunk 能把训练侧记忆拟合得更深,并放大低频 context 的 replay-specific gap。

8. 结论

  1. 最小充分条件:vanilla nanoGPT + bigram / trigram value table + fixed-order multi-epoch replay + 能到达输出的注入方式。
  2. 默认 setting:input / wte 注入。它简单、可解释,也最接近 over-encoding 这类 n-gram memory 用法。
  3. 注入点是强度变量,不是 gap 的来源变量:v、y、input 都能产生不同程度的现象;差别来自信号路径和尺度。
  4. 低频结构解释现象:table 在重复看到的 train context 上形成强烈的 train-specific value,而 novel / 低频 context 在 val 上暴露出这种记忆的局限。

背景、术语与 debug

展开背景说明(已拆到子文档)

如果你需要理解 gate、V / y / input 的伪代码、current shell 为什么是实验分支而不是必要变量,或早期 hash-row 频率统计为什么会把 novel trigram 错判成 seen,请阅读:

打开《背景与 debug:从 current shell 回到最小 n-gram setting》

展开历史实验记录与旧版完整页面

Agent experiment log保留了旧实验的逐项记录;旧版完整 guide保留了历史章节与原始图表。