链载Ai

标题: 用Dynamic chunk去干掉tokenizer? [打印本页]

作者: 链载Ai    时间: 昨天 21:44
标题: 用Dynamic chunk去干掉tokenizer?
一般你们下AR模型的时候,都有这个,也就是tokenzier,tokenizer是干啥的,其实就是你的分词字典

不光有specal的token对应的还有实际的对应的分词对应的代码,比如:

也有tokenzier没显示的,比如,
为什么呢?
因为它不是文本模型,人家输入是声音,因为它是ASR
扯远了,回归主题
tokenizer之所以总是个独立的model,因为它和transformer
不是一个网络,它也不参与transformer训练时候的反向传播(和embedding层两回事,embedding参与BP和学习),也不共享参数(其实问你为什么没关系,你记住这点就够了)
一个正常的流程是这样的

传统自回归文本模型(如GPT/Llama)

训练时流程:
原始文本 → tokenizer切分 → token id序列 → embedding → Transformer → 输出概率/预测下一个token
推理时流程:
文本 → tokenizer → token id → embedding → 模型生成token id →detokenizer(还原文本)
这个沿用了多少年的架构的有什么问题吗?
其实是有的
静态分词:只能预定义/规则分割,不随语境、下游任务改变;
词表对非英文、代码、特殊字符等不友好,多语言/新词适应性差;
字符错位/扰动很容易破坏下游表现(比如 misspell、空格丢失等,鲁棒性差);
tokenizer/vocab词表一旦定型,后期无法弥补缺失、替换麻烦。
造车上面那几个问题的原因:

1. 词表构建机制决定的“偏见”和局限


2. 非英文/多语言适应困难


3. 新词/热词/代码/专业类token的弱势


4. 多语言词表扩展的工程复杂性


这时候如果有兄弟玩过LSTM可能会一起来,早起是没有tokenizer,也没BPE这玩意的,最早是char-level来建模(注意是最早,LSTM也有token level)
char-level (字符级) 建模,是指模型的输入输出都是“字符”,比如 ["m", "o", "d", "e", "l"],或者直接处理字节(每个字节一个embedding),其实就是字符映射为 embedding index,适用于玩具任务、OOV高风险任务、小数据集、很早期的英文句子生成等

那为啥都转去token level去了呢?
语义表达效率低:
汉语一个字的信息含量比英文小,随便一个新词(如“码农”)只能靠“码”、“农”两个单字序列表达,捕捉组合语义难,长依赖seqlen变长。
序列极长:
同长度内容,char-level序列会远比token-level长,计算/内存/推理慢(transformer类模型自注意力时间、显存正比于)。
模型收敛慢,捕捉高阶结构难:
大段话、句子、专业词都被拆为单字或字节,模型要学会组合成“自然语言片段”需要更多层、更多数据,效率和泛化难度高于“合理分块”的token-level或动态chunking方案。
但是最近有CMU的人给字符level编码翻案

这论文针对的场景就是刚才我们说的tokenizer的问题
分词器本身是手工预处理,对语义、语境缺乏自适应,“一刀切”方式不适合所有语种/信息结构(比如中文/代码/DNA等)。
静态Token也导致模型易受拼写噪声、字符级扰动破坏;跨领域迁移也更难。支持多语言费劲。
所以诞生了dynamic chunk机制(和我自己做的项目dc不是一回事,我那个不是分词和char level的)和H-net

H-Net总体架构

核心思想:创造支持“动态分块机制”(Dynamic Chunking, DC)的层次化神经网络(H-Net),让模型自己端到端学会:哪里是有意义的边界,该怎么自动分段、压缩和聚合输入序列。

1. 架构图如上面的图

流程:
  1. 原始字节输入 (从下面网上面看)→ 编码器(Encoder)做初步字节级embedding(这也可以用Mamba SSM层,线性注意力,当然也可以transformer);
  2. 动态分块模块(DC)
    模型自适应“切片”输入序列,按上下文/内容决定block(被分词的)位置。
  3. 主干网络(Main Network):主要参数集中于此,对已被压缩的chunk序列做深度建模(高语义、长距离依赖捕获)。
  4. 解分块(Dechunking):用上采样/smoothing等方法,将高层chunk输出重新映射回细粒度token,供解码器(Decoder)输出。


2. “分块”与常规分词对比:


常规 Tokenizer:全靠规则/人工预设,只能一分到底。
动态分块DC:模型自动检测上下文变化处(如语法/语义转换),预测边界概率→下采样成chunk embedding序列,高效又自适应。

我们用一个具体例子来说明H-Net的动态分块(Dynamic Chunking,DC)机制是怎么“自动检测上下文变化”并形成chunk的。

示例文本

假设输入文本为:"The end of tokens."

1. 传统tokenizer分割

例如使用BPE等,会直接把它分为
["The", "end", "of", "tokens", "."]

2. H-Net动态分块的流程与输出

第一步:编码各字节/字符

输入会转成:["T", "h", "e", " ", "e", "n", "d", " ", "o", "f", " ", "t", "o", "k", "e", "n", "s", "."]

每个字符/空格/符号作为一个输入位置,初步embedding。

第二步:模型自动“判别”边界概率

H-Net的routing module会对每两个相邻embedding进行相似度测量(比如用余弦相似度),如果发现:

["d", " "](即“单词结束后是空格”)、["s", "."](单词结束遇到句号)等位置,embedding变化大(语法/语义上有明显切换),相似度低,边界概率高
而像["e", "n"]、“["o", "f"]”等(单词内部连续字母),相似度高,边界概率低

这样,模型经过训练后,会在如下位置分块边界概率最高(比如):

T h e _ e n d _ o f _ t o k e n s .
↑ ↑ ↑ ↑ ↑ ↑
0 0 1 0 0 1

下划线和句号后的边界概率更高

第三步:根据概率做动态分块

H-Net的downsampler会筛选出边界概率超过一定阈值的位置,比如:

最终分块方式可能是:
["The end", "of", "tokens."]

或者更细粒度:
["The", "end", "of", "tokens", "."](这么分和BPE就一样了)

chunk的大小、边界完全由数据和上下文(而不是手工规则)自动学到,且不同上下文还能灵活变化

第四步:聚合chunk embedding并继续建模

被判定为一个chunk的所有原始字节embedding会聚合(池化/加权等方法),形成一个chunk级higher-level embedding,进入主干网络进行高抽象推理,这快就不用讲了,因为已经进transformer了

打个比方:


再举极端对照例子

  1. "I love applepie"

    普通tokenizer:["I", "love", "apple", "pie"],这就分错了呗,分成了 apple and pie
    H-Net:可能["I", "love", "applepie"] 或 ["I love", "applepie"](因为"applepie"常一起出现),这两个分都没毛病
  2. 代码场景:"def run_fast(x):"

    普通tokenizer:["def", "run", "_", "fast", "(", "x", ")", ":"],这么分也比较扯了(当然你们大多数看不见这么差的,是因为代码量大,special token和辅助字符机制让你们不止于碰到这么离谱的,我就是举个例子)
    H-Net:可能["def", "run_fast", "(", "x", "):"],甚至整个函数名+参数合成chunk


所以,动态分块DC让模型“自动发现结构”,而不是简单、固定地分词或分字,大大增强了理解、压缩和表达的能力。


我们最后再做一下流程对比

总结一下就是其实就是encoder+dc做了tokenizer的事了,然后上采样+decoder做了softmax到词表的logit
这么一上图就没那么抽象了,至于主干那块其实愿意用trasformer还是ssm,或者mamba甚至混着来(现在不都流行这样吗,隔一层一遍,确实能省掉一部分因为指数注意力造成的算力压力),就看你想怎么折腾了
最后看一下效果:

A. 语言建模主任务(英文+多语言)

1.验证困惑度/压缩效率(BPB)

H-Net(动态分块)在相同训练数据和算力预算下
1-stage结构已可匹配传统BPE-Transformer的困惑度;
2-stage递归结构大幅超越:

2.多语言与代码/DNA建模


B. 下游通用任务表现

大规模zero-shot评测在LAMBADA、HellaSwag、PIQA、ARC-e、ARC-c、Winograd、OpenBook等七大benchmark任务上,H-Net(2-stage)平均分比传统BPE Transformer高2%~3%

对比Mix-of-Experts(MoE) 、SpaceByte、LlamaByte等各种优化方法,H-Net也依然表现胜出,这里吐槽作者为什么方MOE,不过页能理解,虽然不是一个层面的,但是,也都是优化手段,姑且理解为主干(FFN)稀疏vs压缩冗余吧, 反正它敢比,我就敢把这个也粘过来了



C. 鲁棒性和泛化能力

抗文本扰动鲁棒性:在HellaSwag的五种perturbation(如随机大小写、字符重复、丢drop、混乱语法)测试下,H-Net鲁棒性-平均准确度远超过BPE Transformer和所有对照组。
可解释性更强:Chunk边界分布可视化表明模型学出的边界多能对应词/短语/语法块,而不是简单机械分词。


D. 数据/计算效率

同样训练数据和FLOPs下,H-Net能用更少数据、更少算力达到等同或更优效果,尤其在"hardcase"领域(如代码/DNA/多语种)差距巨大。
总之还成,我为什么讲这个呢,因为现在大家都在反transformer架构,但是也不能光喊口号,这个至少做出了一部分的关键工作(虽然tokenizer不属于transformer,但是它也是现在网络的基础啊),如果你把主干全换成ssm类的比如mamba,那就彻底告别现在的网络了,不过我觉得从主流视角看,这类的工作至少还要5年,因为transformer本身也都在外围进行线性化的优化,而transformer非线性的部分的attention短期我没看到能被取代的可能性。







欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5