句子级递归二分

P7 证明了词级 echo 可行。P8 回答:如果整句进共享树,递归二分后能从哈希向量还原句子吗?

1. 从词级到句级

P7 把每个词当独立 token 处理——3011 个词在一棵树里各自路由,互相独立。真实的 SPR 不是这样——句子里的词属于同一个组,以组的身份进入节点、被 hash、被分裂。

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

2. 设计

编码

句 "cat slept" → E[cat], E[slept], ∅, ∅  (embedding 矩阵查行)
                → 整组进根节点
                → hash(组) @ node_W → scores → median 半分
                → 递归到叶子
                → H_leaf = mean(token_embeddings in leaf)

解码(与 TF 的 Linear→Softmax 同构)

H_leaf @ E^T → (V,) token scores → argmax → output_token

同一份 E 双向用:编码时查行(token→向量),解码时矩阵乘(向量→token)。和 TF 的 hidden → Linear(d,V) → softmax 完全对应。

3. 实验

WMT14 4 句,pad 到 8 token。32 个 token(26 个实词 + 6 个 ∅),25 个 unique 词。变深度测碰撞退化。

结果

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

解读

  • depth=5 (32 叶):22/26 个词独占叶子,BLEU=92%。那 4 个共享叶的碰撞拉低了 8%。
  • depth=4 (16 叶):碰撞全面爆发,每个叶子平均 2.1 个词。H_leaf 是两个词 embedding 的均值,decode 出的词往往不是原词。BLEU 崩塌到 21%。
  • depth=3 (8 叶):4 个词挤一叶,哈希向量完全失真,decode 几乎猜不到原词。BLEU=0.1%。

4. 碰撞的本质

叶子哈希向量 H_leaf = mean(E[tokens_in_leaf])。独叶时 H_leaf = E[token]H_leaf @ E^T 的最大分量就是 token 自己 → decode 完美。多叶碰撞时 H_leaf 是多个 embedding 的平均 → H_leaf @ E^T 的最大分量可能是另一个词——靠近均值但不等于任何原词。

碰撞率 = 压缩率。 叶少则碰撞多,BLEU 低。叶多则碰撞少,BLEU 高。这个 tradeoff 就是翻译模型中"参数压缩 vs 精度"的数学本质。

5. 结论

句子级递归二分 + E^T decode 的链路走通。编码→树→解码的闭环完整。碰撞退化是自然结果,不是故障。下一步要做的不是消除碰撞——是让碰撞发生在语义相似的词之间,使 decode 出的"折中词"仍然合理。

代码:spr_p8_sentence.py


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