The Functionalizer: Lossless Functional Decomposition for Subword Tokenization
Connor Makowski, Willem Guter
cs.CL
2026-07-08
把大小写、变音和字符重复拆成Unicode私用区里的opcode,只给规范词根占词表。无约束穷尽合并时词表最多少19.7%;98M GPT-2上Python语法通过率从7.70%升到9.12%。
子词词表面对大小写和变音时只有两条路。把 hello、Hello、HELLO、Héllo 当成四个词,词表膨胀,Hello 的梯度也帮不上 hello。先小写、再剥变音,词表是瘦了,信息没了,下游再也还原不回来。
Functionalizer 走第三条路:把表面变化拆成可逆算子,词根只留一份。做法直接借自 CPU 指令集:不会为每个立即数各做一条 ADD1、ADD2,opcode 加 operand 就够。这里 operand 是规范小写词根,opcode 写在 Unicode 私用区(PUA)里,告诉解码器在哪个位置大写、加重音、或把某个字符重复几次。
流程接在 Llama 风格 regex 切分之后,在每个局部片段上操作,位置参数限制在 0–255,刚好塞进一个字节。编码时抽出组合变音、记下大写下标,剥记号并小写,再把算子前缀接到规范词根前面。解码按相反顺序还原,声称完全双射。大小写混杂的重复(如 Abcabcabc)不折叠。
当前算子:
默认 splitoperators=true,算子作为独立前缀 token,强制所有大小写变体共享词根嵌入,代价是序列变长。也可以关掉拆分,让 BPE 自己决定高频大小写词要不要熔合。论文下游实验用的是完全拆开的配置。
前缀而不是后缀,是为了多 subword 的词:opcode 挂在最前面,后面每一截都能在注意力里看见格式信息。
词表实验把目标词表开到 4096k,让 BPE 合并到再也合不动,看覆盖语料到底要多少槽。最多抽 10 万篇。
| 语料 | 基线词表 | Functionalizer | 降幅 |
| Wikitext | 106,023 | 90,531 | −14.61% |
| Python-Codes | 68,471 | 57,012 | −16.74% |
| FineWeb-Edu | 1,214,684 | 975,169 | −19.72% |
| GitHub-Code-Python | 4,071,598 | 3,356,761 | −17.56% |
四处平均少 17.16% 槽。同时 chars/token 掉 12.88%–17.73%,独立前缀把序列拉长了。这是「穷尽覆盖」口径,不是 32k/128k 生产词表上的对比。
下游用约 98M 的 GPT-2 Small(12 层、768 维、词表 16k、上下文 512),FineWeb-Edu 和 GitHub-Code-Python 各训 5 万步、5 个种子。
字符级困惑度:散文 2.2656 vs 2.2662,基本打平;Python 1.5328 vs 1.5697。序列开销在 16k 词表下是散文 +8.6%、代码 +18.8%。因为步数固定,Functionalizer 实际少吃了约 8%–16% 的原始字节。
生成(贪心、1000 条 prompt):Python ast.parse 通过率 9.12% vs 7.70%,相对高 18.4%,种子方差也更紧。重复 n-gram 散文 66.0%→55.8%,代码 25.5%→17.9%。另一面很难看:散文空序列 0.1%→7.1%,崩溃率 70.3%→78.4%,崩溃前有效字符 357.9→217.7。小模型会吐出只有 opcode、没有词根的前缀。
这是一条可接到现有 BPE 管线上的预处理,不换模型、不学 codebook。词表实验说明大小写和空白重复确实在吃槽;代码侧 REPEAT 把缩进变成「同一个空格 × 次数」,比 BPE 切出来的不规则空白块更像结构。
98M 上的收益是渐进的,而且用序列长度换来。生产上更合理的可能是熔合高频大小写、长尾继续拆开。框架里有这个开关,论文没做这组实验。GitHub 和 Hugging Face 上有实现和 100M 模型。
作者列了四条。只做到 98M、5 万步;序列变长导致同等 step 下少看 8%–16% 字节,表征收益和训练预算缠在一起。熔合阈值没评。位置不超过 255,变音只有 13 个拉丁组合记号,没有非拉丁脚本、没有 ALLCAPS、没有词形还原。下游是 CAPITALIZE + 变音 + REPEAT 的打包结果,分不开是大小写还是缩进在起作用。
另外,19.7% 的词表数字来自无约束穷尽合并,和真实 32k 词表不是一回事。语法通过率绝对值仍低于 10%。散文侧空序列和更早崩溃,说明独立 opcode 在小模型上的解码税很实在。没有和 TokenMonster、InCa/InDia 做下游对照,只有方法叙述上的差异。