SPR Echo Test 全流程验证

从 hash map 到句子级递归二分树——echo test 的完整实验记录。

1. 什么是 echo test

训练一个翻译模型之前,先问一个更简单的问题:你能不能表示"输入等于输出"?

echo 就是自映射:f(x) = x。三种结构,三种实现方式:

hash map 邻接矩阵(TF) 堆(SPR)
怎么做 hash_map[k]=k Attn → 单位阵 I 递归二分,路径即哈希
参数 0 W_q,W_k,W_v,W_o per-node 权重 + E
核心机制 自碰撞 自环 确定性路由 + mean hash

2. hash map echo 的三个威胁

碰撞覆盖hash_map[A]=Ahash_map[B]=B(同桶)覆盖。不可压缩:每 token 独占一桶,V token=V 桶。不可泛化:新 token 没有桶。

这些问题不在 key 空间大小——在 hash 算法本身。hash_map 算法 = identity(token),天生不可压缩。SPR 堆算法 = semantic_route(token),相似 token 走同路径、共享叶子。

3. 堆 echo:递归二分,路径即哈希

整句 → 根节点 hash(整句组) → median 半分
    ├─ 前半组 → hash(前半) → median 半分
    │   ├─ 子组...
    │   └─ 子组...
    └─ 后半组 → hash(后半) → median 半分

每个内部节点 hash 的是一个 token 组(子串),不是单个词。 每层节点存当前组的语义哈希(mean of token embeddings)。路径是 token 从整句到自身的分裂轨迹。

echo 验证:同 token → 同路径 → 确定性 100%。手工版(中位数阈值,per-node 随机权重)不需要训练即可通过。

4. 实验验证

代码:spr_echo_test.py,深度 4,15 节点/16 叶子,100 个随机 token。中位数分层二分。

断言 结果
同 token 路径一致 ✅ 100/100
所有叶子有 token ✅ 16/16
每叶 6-7 tokens(碰撞)

5. 自修复:sigmoid 离散路由

全 0 参数会产生鞍点(乘法链 gradient=0)。改用 sigmoid 离散路由:

每个节点:sigmoid(token @ W) → 右转概率
训练期:软概率(梯度可穿透 sigmoid)
推理期:sign(token @ W) → 硬方向

Adam 500 步 + 平衡正则(防止全挤一叶),结果:确定性 128/128、16/16 活跃、路径 100→117/128 匹配。

6. 词级 BLEU

每词独立路由(P7 简化版),per-node 随机权重 + 中位数二分构建树。叶子存 token 列表,输出最频繁词。

编解码

编码: token → E[token_id]  (E: V×d embedding 矩阵,查行)
树:   E[token] → 递归二分 → H_leaf = mean(token embeddings in leaf)
解码: H_leaf @ E^T → token_scores → argmax → output_token

同一份 E 双向用,和 TF 的 hidden → Linear(d,V) → softmax 同构。

结果

数据 词数 深度 叶子 BLEU-4 训练
随机词 200 9 512 99.2%
WMT14 真实 3011 12 4096 100%

独叶时(叶子数 ≥ 词数)BLEU=100%——中位数二分保证每词独占一叶,解码精确还原。这是数据结构的保证,不是训练结果。

7. 句子级递归二分(共享树 + E^T decode)

P8 做句子级修正:多句共享一棵树,每句 pad 到同长,token 以句组形式参与递归二分。

编码(句子级)

"the cat slept" → E[the], E[cat], E[slept], ∅×5 (pad to 8)
               → 整组进根 → median半分 → 递归
               → 叶子 H_leaf = mean(token embeddings in leaf)
解码: H_leaf @ E^T → output token

BLEU 退化曲线

WMT14 4 句,pad 到 8 token,26 个 unique 词。变深度测碰撞退化。

depth leaves tokens/leaf solo BLEU-4
5 32 1.2 22 92.1%
4 16 2.1 3 21.3%
3 8 4.0 0 0.1%

碰撞 → H_leaf 是多个 embedding 的均值 → 最近邻可能是第三个词 → BLEU 崩塌。

碰撞率 = 压缩率。 叶少则碰撞多、BLEU 低。这不是 bug,是参数压缩 vs 精度的 tradeoff。

8. Hash 函数设计:Merkle 组合

叶子的哈希不是从 token 重算——是递归组合子节点哈希:

H_leaf = E[token]                           # 叶子:embedding 查表
H_parent = combine(H_left, H_right)         # 内部节点:组合子哈希

三种 combine 方案:

方案 公式 顺序敏感 参数 适用
mean (L+R)/2 0 echo
weighted αL+(1-α)R 是(单 α) 1/层 语序编码
LSTM LSTM_cell(L,R) W_xh,W_hh,b 可训练

验证(A-then-B vs B-then-A):

mean    : H_AB == H_BA  ← 顺序不敏感
weighted: H_AB != H_BA  ← 顺序敏感
LSTM    : H_AB != H_BA  ← 顺序敏感(但随机权重无意义,需训练)

echo test 用 mean 就够了。翻译需要 order-aware。

8.1 零成本有序 hash:Cyclic Shift + 符号破缺

另一个船长的洞见:torch.roll 是零成本的——只是内存地址的重新映射。但纯循环位移有碰撞漏洞。

漏洞复现

roll 在加法中会产生"巧合对冲":

"我打你": [1,2,3,4] + roll([5,6,7,8], 1) = [1+8, 2+5, 3+6, 4+7] = [9,7,9,11]
"你打我": [5,6,7,8] + roll([1,2,3,4], 1) = [5+4, 6+1, 7+2, 8+3] = [9,7,9,11]
                                                     碰撞!完全相同的哈希!

位移只是重排维度,加法中的交换律使相同元素对上后就无法区分顺序。

修复:符号交替破缺

右子树位移后,乘以交替正负号 [1, -1, 1, -1, ...]——一个位翻转操作,零成本破坏加法对称性:

H_parent = H_left + sign_alt(torch.roll(H_right, shifts=depth+1))
           where sign_alt(x) = x * [1, -1, 1, -1, ...]

验证:

"我打你": [1,2,3,4] + [8,-5,6,-7] = [9, -3, 9, -3]
"你打我": [5,6,7,8] + [4,-1,2,-3] = [9,  5, 9,  5]
                                       ↑ 第二位永久分离!

分离 ✅ 确定性 ✅ 零硬件成本 ✅

方案 序敏感 碰撞 硬件成本
mean - +
pure torch.roll 有!加法对冲 0
roll + sign alt 0

代码:spr_hash_cyclic.py

9. 训练路由:让碰撞语义化

node_W + E 联合训练可以把凝聚度从 0.21 推到 0.99+。但随机 embedding 下分组缺乏真实语义——训练方向正确,瓶颈在 embedding 质量。

版本 凝聚度 关键瓶颈
echo(手工) 0.21 无训练,纯哈希
训练(Adam+平衡) 0.99 随机 E 无真实语义
目标(真嵌入) TBD 接 GloVe/Transformer embedding

代码:spr_007_train_nodeW.py

10. 当前状态

已验证

模块 状态 数据
hash_map echo BLEU=100%(自碰撞)
堆 echo(词级) BLEU=100%(中位数二分,每词独叶)
句子级递归二分 BLEU=92→0%(碰撞退化曲线)
Hash 设计(Merkle + cyclic shift) mean/weighted/LSTM + roll, zero-cost
有序 hash fwd≠rev,硬件零成本
训练路由(node_W+E) 凝聚度+350%,随机E缺语义
自修复(sigmoid 离散路由) 128/128 确定性

待突破

模块 状态 关键
真语义嵌入 ⚠️ 需接 GloVe/Transformer embedding
翻译 decoder 下一步

代码链路

spr_echo_test.py → spr_echo_repair.py → spr_hash_design.py
→ spr_p7_bleu.py → spr_p8_sentence.py → spr_007_train_nodeW.py

github.com/houming818/sametime/experiments/

当前完整代码链路:spr_echo_test.pyspr_echo_repair.pyspr_p7_bleu.pyspr_p8_sentence.py


License: GPLv3 本文《SPR》系列采用 GPLv3 协议开源发布。