用 WMT 真语料做 Echo:先证明 TreeHeap Kernel 能写入真实 BPE 序列
这次我们回到 Houming818 一直强调的问题:
TreeHeap 怎么把真实数据写进自己的高维结构?
如果连真实语料的 token 序列都不能稳定写入、读出,那么后面谈翻译、世界模型、概率坍缩都太早。
所以 SPR-030 不直接做 WMT 翻译。
它先做一个更低一级、但更必要的实验:
WMT 真语料
-> SentencePiece BPE token
-> TreeHeap kernel 写入
-> TreeHeap kernel 读出
-> 和原 token 序列比较
这叫 echo 实验。
它不是翻译。 它测试的是:
TreeHeap kernel 是否能处理真实语料的离散 token 序列。
为什么不是马上做翻译?
翻译任务太复杂。
一句英文到一句中文,中间至少包含:
词义
语序
短语结构
跨语言对齐
生成概率
目标语言流畅性
如果直接上 WMT BLEU,结果不好时我们不知道问题在哪里。
可能是 encoder 不行。 可能是 decoder 不行。 可能是 kernel 不行。 可能是 loss 不行。 也可能只是训练规模太小。
所以这次先拆开:
第一步:真实 token 能不能写入 TreeHeap?
第二步:写入后能不能读出来?
第三步:结构化 kernel 是否比普通 flat 模型更适合这个问题?
这就是 S1 echo 的意义。
数据来自哪里?
实验使用 io 上的 WMT17 数据:
source file:
/mnt/nas/datasets/wmt17/train.zh-en
SentencePiece model:
/mnt/nas/datasets/wmt17/sp_bpe.model
我们取英文侧文本,然后用 SentencePiece 切成 BPE token。
实验只取短序列:
token length = 3..8
samples = 3000
train/test/ood = 2400/300/300
vocab limit including PAD = 2048
average non-pad length = 5.9533
为什么先限制长度?
因为这次不是要证明长文本翻译。 这次要先验证最小写入机制:
一个真实 BPE 序列,能不能被 TreeHeap 地址结构保存。
Echo 任务具体是什么?
输入是一段 BPE token:
[t1, t2, t3, ...]
目标输出还是它自己:
[t1, t2, t3, ...]
这看起来很简单,但它能测出一个关键点:
模型是否保存了 token 的位置、顺序、地址。
如果模型只是知道句子里有哪些 token,但不知道顺序,就会失败。
例如:
[A, B, C]
和:
[C, B, A]
bag-of-words 看起来差不多,但 echo 必须区分它们。
所以 echo 不是语义任务,却是结构写入任务。
三个模型对比
这次比较三个模型。
| Model | 含义 |
|---|---|
bow_linear |
只看 token 集合,不看顺序 |
seq_mlp |
把固定位置拼平,交给普通 MLP |
treeheap_kernel_echo |
把 token 写到 TreeHeap 叶子地址,再用共享 kernel 自底向上 compose |
1. bow_linear
bow_linear 看到的是:
这个句子里出现过哪些 token
它不知道 token 在第几个位置。
所以它适合作为反例 baseline:
如果 BoW 也能做好 echo,那说明任务太简单。
2. seq_mlp
seq_mlp 是普通 flat MLP。
它看到的是固定位置展开后的向量:
position 1 token
position 2 token
position 3 token
...
它有顺序信息。 但它没有显式树地址、子结构、compose kernel。
可以理解为:
把序列压平成一张大表,然后学习 input -> output。
3. treeheap_kernel_echo
TreeHeap 模型做的是:
token id -> shared token embedding
position -> fixed heap leaf address
internal nodes -> shared bottom-up compose kernel
leaf readout -> shared decoder
换成人话:
每个 token 先写到树堆的一个叶子地址上。
然后树里的父节点用同一个 compose kernel 汇总左右孩子。
最后从叶子状态读回 token。
关键点是:
模型必须利用 TreeHeap 的地址结构。
它不是把整个句子拼成一个大向量随便读。 它被迫经过:
叶子地址
子结构
自底向上 compose
共享 decoder
这就是 kernel 设计的意义。
实验结果
脚本:
ara/s1-echo/src/s1_wmt_echo_kernel_probe.py
证据:
ara/s1-echo/evidence/s1_wmt_echo_kernel_probe/
执行主机:
io.grepcode.cn
结果如下:
| Model | Params | Test token | Test exact | OOD token | OOD exact |
|---|---|---|---|---|---|
bow_linear |
33,570,816 | 0.1679 | 0.0033 | 0.1659 | 0.0033 |
seq_mlp |
16,794,112 | 0.5801 | 0.0567 | 0.5986 | 0.0533 |
treeheap_kernel_echo |
423,104 | 0.9818 | 0.8900 | 0.9818 | 0.9000 |
这里有两个指标:
token accuracy:
每个位置的 token 是否预测正确。
exact:
整个序列是否完全预测正确。
exact 更严格。 只要一个位置错了,整个序列就算错。
结果说明什么?
第一,BoW 几乎失败。
OOD exact = 0.0033
这说明任务不是只靠 token 集合就能完成。 顺序和地址确实重要。
第二,flat MLP 训练集可以学会,但 OOD 很差。
seq_mlp OOD exact = 0.0533
它有 16,794,112 个参数,比 TreeHeap 多很多。 但它在新样本上不能稳定复制完整序列。
第三,TreeHeap kernel 表现明显更好。
treeheap_kernel_echo OOD token = 0.9818
treeheap_kernel_echo OOD exact = 0.9000
而且参数更少:
TreeHeap params = 423,104
seq_mlp params = 16,794,112
大约是:
TreeHeap 参数量约为 seq_mlp 的 2.5%
这支持一个小 claim:
在真实 WMT 短 BPE echo 任务上,
TreeHeap kernel 可以更有效地利用地址和路径结构。
这和 kernel 设计有什么关系?
前面我们反复讨论:
TreeHeap 的核心操作不是普通矩阵拼接,
而是 kernel 在树结构上的卷积。
这次实验里的 kernel 很朴素:
leaf write kernel:
把 token embedding 写到固定叶子地址。
compose kernel:
对每个内部节点,用同一个函数合并 left/right child。
read kernel:
从叶子状态预测原 token。
它像一维 CNN 里的卷积核,但滑动对象不是平面像素,而是 TreeHeap 子结构。
CNN 的 3x3 kernel 看局部像素。 TreeHeap kernel 看局部树堆:
parent
├── left child
└── right child
所以它天然带着:
地址
路径
子结构
组合
分解
这些信息。
这正是 flat MLP 没有显式拥有的归纳偏置。
这次 claim 是什么?
ARA 里记录为:
S1-WMT-ECHO-C01
claim:
A structured TreeHeap kernel can write and read real WMT SentencePiece short
sequences in an echo setting, using tree addresses and shared compose/read
kernels rather than only a flat memorization map.
状态:
supported pilot
用中文说:
结构化 TreeHeap kernel 能在真实 WMT 短 BPE 序列上完成写入和读出。
这个结果支持 TreeHeap 的地址/路径结构是有用的。
这没有证明什么?
边界要说清楚。
这次没有证明:
TreeHeap 已经会翻译。
TreeHeap 已经有语义世界模型。
TreeHeap 已经能压缩长文本。
TreeHeap 已经解决长距离句法。
TreeHeap 已经击败 Transformer。
它只证明一件更基础的事:
真实 WMT token 可以被 TreeHeap kernel 稳定写入和读出。
这对 S1 是有意义的。 但离 S2/S3 还有距离。
下一步怎么做?
下一步不是立刻喊胜利。 应该继续加难度。
1. 更长序列
现在是:
length = 3..8
下一步要测:
length = 8..16
length = 16..32
如果长度一长就崩,说明 TreeHeap kernel 还只是短序列技巧。
2. 噪声 echo
普通 echo 是原样复制。
下一步可以做:
mask 一个 token,让模型恢复。
drop 一个 token,让模型恢复。
swap 两个 token,让模型判断并修正。
这开始接近推理。
因为模型不能只照抄,它必须利用上下文。
3. subheap query
不要总是读整个句子。 可以问:
读左子树。
读右子树。
读某个短语窗口。
读某条路径下的 token。
这能测试 TreeHeap 的子结构是否真的可查询。
4. 更公平的 baseline
这次的 seq_mlp 不是最强序列模型。
下一步要加:
pointer/copy baseline
small Transformer
tiny RNN/GRU
matched parameter sequence model
如果这些模型在相同参数和数据预算下追上 TreeHeap,那么 claim 要收缩。
总结
SPR-030 的结论是:
可以用 WMT 真语料做 echo。
TreeHeap kernel 在短 BPE 序列写入/读出上表现很好。
它用更少参数,明显超过 BoW 和 flat seq MLP。
这说明:
kernel 设计是关键。
TreeHeap 的存在性不能只靠抽象代数。 它必须在具体任务上显示:
地址有用。
路径有用。
子结构有用。
组合/分解有用。
这次只是第一块真实语料证据。 下一步要从:
短序列 echo
推进到:
长序列 echo
噪声恢复
subheap query
copy/pointer baseline battle
如果这些也成立,S1 才能更稳地往 S2 翻译折叠推进。