去年一整年我都在跟机器人动作序列打交道,中间被“动作token化器”这个环节卡了整整两个月。同一个任务,换了token化器的训练细节之后,下游策略的成功率能从85%掉到61%,也能从61%拉回82%,这中间差出的不是一两行代码,而是对整个问题本质的理解。这篇文章把我在模拟项目X中拆过的问题、踩过的坑、验证过的结论整理出来,重点回答一个看起来特别基础但特别难回答的问题:一个动作token化器,到底凭什么算“优秀”。
这篇文章更适合正在做机器人操作策略、动作生成、模仿学习或者具身智能方向的人读。如果你只是跑通了VQ-VAE的官方示例,还没把token化器接到下游策略里,那我建议你先收藏,等遇到“重建指标很好但策略就是不行”这种鬼问题的时候再翻出来。下面所有内容都是基于实际实验结果,不是从论文里抄来的理论。
1. 动作token化器为什么这么难做
1.1 动作数据跟文本、图像有本质区别
很多人一开始都把动作token化器类比成图像里的VQ-VAE或者文本里的BPE,这个类比能帮你快速建立直觉,但也会把你带沟里。图像是空间冗余极高的数据,一张512x512的图切成256个patch,每个patch内部高度相关,你把它压缩成16个token问题不大。文本本身就是离散的,token化器做的只是把词汇合并归类。但动作序列是高频连续信号,一秒钟10到50个控制步,每个控制步里可能是7到30维的关节角度、笛卡尔末端位姿、速度甚至力矩,这些维度之间虽然有耦合,但远没有图像像素之间的冗余那么强。
更麻烦的是,动作的语义基本不落在单帧上。一个“抓取”动作从视觉上很容易理解,但你单独看第37帧的关节角度,它没有任何语义。语义分布在一个时间窗口上,窗口的长度又不是固定的。同样是推盘子这个动作,快推可能只需要0.2秒,慢推可能要1.5秒,前后关节轨迹的形状差得很远。这给时域压缩带来一个根本性的麻烦:你很难用一个固定的压缩比例去覆盖所有动作类型。
我做第一个版本的时候天真地用了4:1的时间压缩,也就是4个控制步压成1个token,结果其他动作还好,一个精细的转螺丝动作直接把策略成功率从90%打到54%。为什么?因为转螺丝的过程里,末端的微小旋转补偿动作频率很高,4帧压缩直接把这些细节抹平了。我当时意识到一个问题:动作token化器的本质不是“压缩”,而是“在什么时间分辨率上保留语义”。
1.2 压缩粒度和信息保真是核心矛盾
动作token化器设计的第一个矛盾就是压缩粒度。你当然可以把每个控制步都映射成1个token,这样信息完整,但一个30秒的任务在50Hz控制频率下就是1500个token,下游Transformer策略处理这么长的序列,计算量和建模难度都会爆炸。反过来,你也不能拍脑袋定一个压缩率,因为动作内部的时间结构差异太大。
1:1的方案,token序列长,信息无损。4:1的方案,序列短,但会丢掉高频细节。我在模拟项目X里做过一个消融实验,同一套任务集,分别用1:1、2:1和4:1三种压缩率训练token化器,再接同一个策略模型。结果是:1:1的成功率最高,但训练时间长了近三倍,推理时的自回归生成速度也慢得没法用;4:1快很多,但精细操作类任务全面崩盘;2:1是平衡点,整体成功率只比1:1低3到5个百分点,大部分情况下可以接受。
所以在你选任何架构之前,先想清楚你的任务集是什么频率的。如果全是pick-and-place这种低频粗粒度动作,4:1完全没问题;如果混了装配、插孔、穿线这类精细动作,我建议你先用2:1起步,甚至1:1跑通再压缩。
2. 优秀动作token化器的核心评估维度
2.1 重建指标不能只看MSE
大部分论文里报告的都是重建MSE,但我做了多次对比实验后必须说:只看MSE会严重误导你的判断。MSE是逐帧逐维度的均方误差,它把所有误差平均起来,一旦轨迹中间有一段和演示偏离,MSE会很大,但如果只是每个控制步上有微小的高频抖动,MSE可能非常小,而下游策略对这种抖动极其敏感。
我自己项目里遇到过最典型的例子:一个token化器的重建MSE是3.2e-4,看着已经很小了,但拿去做drop-in还原测试,策略成功率掉了11%。后来我分析了它的重建轨迹,发现问题集中在末端执行器的Z轴方向,有大量的几个毫米级别的高频抖动。人类肉眼看轨迹曲线都看不出毛病,但控制器的反馈环节会把抖动的累积误差放大,最终导致抓取姿态偏掉。
所以我现在评估重建质量,至少看四个维度,不要只看MSE:
| 指标 | 计算方式 | 关注点 |
|---|---|---|
| 关节空间MSE | 逐关节逐帧L2,除以动作维度 | 整体平均误差 |
| 末端轨迹误差 | 前向运动学之后的位置/旋转误差 | 任务空间实际误差 |
| 速度连续性 | 相邻帧差分误差、二阶差分最大跳变 | 高频抖动、不连续 |
| DTW距离 | 动态时间规整对齐后的平均距离 | 时间相位失真 |
这里面DTW是个容易被忽视的指标。普通MSE对时间偏差非常敏感,比如你的重建轨迹比原始轨迹滞后2帧,MSE会变大,但如果你是离线评估且有整段轨迹,滞后2帧在语义上可能完全没问题。DTW允许时间轴上轻微对齐,反而能还原出“形状对不对”。我建议你在训练过程中同时打印MSE和DTW,两个指标一起看,MSE低但DTW高,说明重建存在相位扭曲;MSE高但DTW低,说明时间对齐好但动作幅度还原差,后者反而是更容易通过调解码器修复的。
2.2 下游任务成功率才是金标准
重建指标再漂亮,最后都要看下游策略的性能。这里我说的“下游”,不是理论上的,而是具体的实验设计:把同一个策略模型的输入换成token化器重建出来的动作,在相同环境里跑,记录成功率,和原始动作输入的结果对比,这个差值我管它叫“重建损失率”。一个优秀的token化器,重建损失率应该控制在5个百分点以内;如果超过10个百分点,就算重建指标吹上天也不能用。
我在某次实验里对比了两个配置,一个用了更深的编码器和更大的codebook,重建MSE很低,但drop-in成功率掉了9个百分点;另一个配置看起来朴素很多,MSE比前者高一个数量级,但成功率只掉了2.8个百分点。为什么差距这么大?我分析之后发现,前者的重建误差分布比较“均匀”,它把误差均匀地撒在每个关节和每个时间步上,导致策略的每个决策都带少量干扰;后者的误差集中在少数几个低频成分上,大部分时间步的重建几乎完美,策略在关键节点上没受干扰。
这个现象后来影响了我对token化器整个方案的思考:你优化的目标不应该是“最小化重建误差”,而应该是“最大化下游策略的成功率”。这两个目标强相关但不完全等价。如果你能把下游策略也放进训练目标,比如在token化器训练时接入一个冻结的策略头,用策略loss信号反传到token化器,理论上会更直接。我们实际上试了这种耦合训练,效果确实比纯重建要好,但也带来了训练不稳定的问题,后面会细说。
2.3 codebook利用率和压缩效率
一个常常被忽略的问题是codebook的使用情况。简单来说,codebook是离散token的“字典”,字典太大,大部分词索引可能根本不会被用到;字典太小,表达力又不够。我发现许多开箱即用的VQ-VAE实现里,codebook利用率经常只有30%到50%,也就是说有一些token永远没有样本落进去,这些“死token”白白占据容量。
在动作token化器里,我建议把codebook的利用率作为训练日志里的一个常规指标来看。如果利用率低于60%,说明你的codebook太大,或者更新策略出了问题。一个比较健康的分布是:在训练结束时,85%以上的codebook条目都至少被激活过,并且各条目被使用的频次不要出现极端的长尾分布。如果某些token用了上千次,另一些只用了两三次,说明编码器倾向于输出某个固定区域,离散表达的空间没有被真正利用起来。
压缩效率是另一个要权衡的东西。同样一个任务集,你是用16个token长度的高维embedding,还是用8个token长度但每个embedding有更大信息容量的设计?没有标准答案。我是通过网格搜索来定的:给定codebook总大小(比如8192个条目),先固定embedding维度为64,然后用不同层数的残差VQ(1层到4层)去试,同时观察drop-in成功率。最终结果在绝大多数任务里是2层残差VQ、每层8192个条目最好,3层略好一点点但训练时间几乎翻倍,1层明显不够用。
2.4 泛化能力是分水岭
同一个token化器,换个机器人构型、换个仿真域、换个任务类别,还能不能用?如果只能用在一个固定场景,那它的工程价值会大打折扣。我见过一些论文里的token化器在单一数据集上表现很好,但一旦换到动作分布稍有偏移的新数据集,重建性能断崖式下跌。这背后是动作空间分布局限的问题。
举一个具体例子。我们在一个七轴机械臂的数据集上训练好token化器,直接拿到六轴机械臂的动作数据上做推理,重建误差从训练集上的1.8e-4涨到了2.1e-2,涨了两个数量级。这个结果很好理解:七轴和六轴不仅维度数量不同,关节限位范围和运动学特性也不同,token化器学的特征是高度绑定在特定动作空间上的。
如果你的目标是多机多任务通用token化器,我建议在训练数据里故意混入不同动作空间的数据,比如同时混入六轴和七轴数据。但这么做有个头痛的问题:不同动作空间的维度数不一致,网络输入维度没法统一。我们试过的办法是先用一个动作编码器把不同维度的动作统一映射到一个共享的表示空间,然后在这个共享空间里做VQ,再把token解码回原始动作空间。这个方案能工作,但多了一步训练,先预训练这个动作表示,再训练token化器,整体周期拉长了。
3. 架构选型和训练方法论
3.1 VQ-VAE还是残差VQ
动作token化器的主流方案基本都是VQ-VAE及其变体,核心结构是编码器、量化器、解码器三段。编码器把动作序列映射为潜变量序列,量化器把每个潜变量映射到最近的codebook条目,解码器把量化后的序列重建为动作序列。具体到工程实现,我强烈推荐用残差VQ(RVQ),而不是单层VQ。
单层VQ的问题是:你只能用一个离散码表示整个动作窗口的语义,信息瓶颈太紧。尤其是在复杂动作里,一个窗口既包含粗粒度的运动模式又包含细粒度的指尖调整,单层VQ只能二选一,要么留下轮廓丢掉细节,要么保留细节丢了整体方向。残差VQ的思路是把量化误差再送到下一层继续量化,第一层负责粗粒度的主方向,第二层负责残差细节,第三层再做进一步的补偿。
我在实际项目中用了两层RVQ,每层codebook大小8192,embedding维度64。push任务集上的结果是:单层VQ的drop-in成功率是73%,两层RVQ是82%,三层RVQ是84%,四层RVQ是83%。后面两层带来的增益很小,但训练时间和推理内存几乎翻倍,所以从性价比角度看两层是甜点。
3.2 训练的损失函数怎么设计
先给一个基础的损失组合,这在实际项目里作为起点是可行的。
- L2重建损失:重建动作和原始动作之间的均方误差,这是最基础的。
- 速度损失:重建动作的一阶差分和原始动作的一阶差分之间的L2距离,这个项非常重要,因为纯MSE会让重建轨迹在高频部分抖动,加入速度项能明显平滑轨迹。
- 加速度损失:二阶差分L2,进一步抑制高频抖动,但系数要小,太大了会把动作变得过度平滑,丢失必要的敏捷性。
- commitment loss:让编码器的输出不要离codebook条目太远,系数通常在0.1到0.5之间。
- codebook的EMA更新:不要用梯度更新codebook,用指数移动平均来更新。这个在工程上是稳定性的关键,梯度更新很容易让codebook崩溃。
先不要急着加感知损失或者对抗损失。动作数据不像图像那样有像素级感知统计规律,直接对动作张量做感知特征是困难的。我们在项目里试过给重建动作加判别器做对抗训练,训练不稳定不说,最终drop-in成功率反而不如不加。动作的高维连续时序信号不像图像那样容易区分真假,判别器很容易退化成只关注统计分布而丢掉局部细节。当然这是我们的实验结论,并不意味着这个方向没潜力,但你先不要指望它稳定产粮。
3.3 编码器结构:时域感受野是关键
我的编码器结构很简单:一维卷积堆叠,中间插入下采样(stride)来控制token序列长度,最后过一个量化层。真正影响性能的不是层数,而是感受野大小。我把一个动作窗口编码成一个token时,编码器能看到的时间范围要足够覆盖动作的基本单元。
拿搅拌咖啡这个动作来说,一个完整的搅拌循环大概一秒,在20Hz的控制频率下是20帧。如果你的感受野只有10帧,编码器无法感知整个循环的起止,token里就缺少循环的相位信息,重建出来的动作可能方向都对,但节奏是乱的。
我建议根据你的任务动作时长统计来定感受野。统计一下数据集里动作循环的平均长度和最大长度,把编码器的感受野设置成中位数长度的1.5到2倍。如果平均动作循环是0.8秒,20Hz就是16帧,感受野做到24到32帧比较稳。不是越大越好,感受野太大会把多个动作片段的语义混进同一个token里,反而增加解码难度。
3.4 因果性:训练和推理的隐藏陷阱
这个坑特别隐蔽。我最早训练token化器时,直接用了普通非因果的一维卷积,训练时编码器能看到整个窗口前后的信息,重建效果很漂亮。但接到在线策略后出了大问题:策略是在线逐步推理的,每到一个新的时间步,它的输入里只有当前以及历史动作信息,未来信息是看不到的。非因果卷积在训练时偷偷用了未来的数据,推理时没有,输入分布不一致,重建质量直接断崖。
如果你把token化器用在离线生成场景,比如从文本生成整段机器人动作,那非因果卷积没问题,因为整段动作都在手里。但如果要做在线控制策略的token化,请务必使用因果卷积或者保证推理时刻的输入窗口和训练时刻一致。
我在几次项目评审时发现很多同学没意识到这个区别,提到“runnable”就默认能在线跑,结果代码跑到一半就炸。我的建议是:即使在早期原型阶段,也用因果卷积或者padding方式保持严格的时间因果性,别贪图训练时高几个百分点的指标,后面积重难返。
3.5 加入策略反馈:要不要做耦合训练
一个比单纯重建更有意思的方向是引入下游策略的反馈。我在模拟项目X中做了一组对比实验:A组只训练token化器重建损失,B组在token化器训练完成后冻结,再接一个小型策略网络,用策略loss反传修改token化器的encoder和decoder。B组在相同策略结构下的drop-in成功率比A组高出6个百分点,效果很直接。
但代价是训练流程变复杂了。策略训练本身有探索噪声,token化器在探索噪声的影响下会不断调整自己的编码方式,训练后期容易出现震荡。我的处理办法是:先用纯重建训练把token化器训到收敛,再用很小的学习率(主学习率的十分之一)做策略反馈微调,并且策略侧也要固定一个相对成熟的checkpoint,不要用刚开始乱探索的策略。耦合训练适合你已经有一个能出结果的完整pipeline,想再榨出最后几个点成功率的时候用,不适合从零开始探索。
4. 数据与归一化:最容易被低估的一环
4.1 数据分布崩塌的教训
我必须用一整节篇幅来说说数据。因为我在踩过一系列坑之后才发现,token化器性能的上限根本不是网络结构决定的,而是数据决定的。
某次实验中,我用仿真环境采集了一万条演示轨迹,把动作序列存成关节角度。一开始训练很顺利,重建指标一路下降,但换到新的任务集时token化器表现极差,重建误差直接涨了一个数量级。回去检查数据时发现一个极其低级的错误:两批演示数据的动作单位不一样,第一批用的是弧度,第二批用的是角度。训练时编码器同时看到了两种单位的数据,但它无法区分,codebook里混入了比例差异极大的条目。你可能会觉得这么低级的错误不会发生在自己身上,但我确实见过不止一个项目因为数据单位问题反复返工。
所以我现在的原则是:数据进入训练pipeline之前,先做一遍完整的数据审计,确认动作单位、频率、坐标系、关节顺序在所有数据集中完全一致。尤其是做多源数据混合时,不同采集源的单位和坐标系最容易出岔子。动作维度虽然相同,但坐标系一个用全局坐标一个用基座坐标,token化器学出来的表示会变得完全不同。
4.2 归一化方式的细节
动作数据的归一化方式对训练VQ的影响非常大。最常见的做法是每个关节独立归一化到接近零均值单位方差,用的是数据集里的均值和标准差。这个方法简单,大部分情况够用。
但如果你混入了不同任务类型,每个任务的关节活动范围差异巨大,统一归一化会让低频任务的动作细节被压缩到极小的数值范围,影响重建精度。这种情况我推荐做分任务归一化或者分行为类别的归一化,然后保存每个任务单独的均值和标准差,解码时再映射回原空间。
还有一个容易忽视的点:随机初始化的动作和策略探索中产生的动作,分布跟演示数据差别很大。RL策略在训练初期会尝试大量离谱动作,这些动作如果进了token化器的训练集,会污染codebook。我在数据筛选时会把“探索产出的动作”单独清洗,只保留策略执行成功的轨迹或者与演示分布相近的轨迹,别来者不拒。
4.3 数据增强有没有用
我给动作token化器做数据增强时一开始很谨慎,因为动作是物理信号,随便加噪声、随机裁剪可能会产生不自然的轨迹。但实验结果是:适量加噪声确实能提升泛化能力,前提是噪声幅度要对齐动作尺度。
比如关节角度动作,噪声标准差设置在关节活动范围的1%到3%之间,太小没效果,太大则产生违反运动学的轨迹。我在增强时还会做随机时间轴拉伸,把轨迹按0.9到1.1的倍率伸缩。这个增强对解决“同一动作快慢不一致”的问题很有帮助,因为演示数据里同样一个任务,不同示教者执行速度往往差很多。
但注意一个前提:数据增强只能在训练阶段使用,评估阶段必须用原始无增强数据,不然你看到的指标都是虚高的。
5. 实操流程与评估实验设计
5.1 从零开始的一套完整流程
模拟项目X里跑过很多版本的训练流程,下面这一套是比较稳的,适合作为你的第一个原型。
第一步,数据准备。动作序列全部统一到相同的控制频率。原数据如果是50Hz,做重采样到50Hz,确保每个序列的每个动作步间隔均匀。然后统一动作空间维度、单位、坐标系,保存一份数据审计报告。
第二步,定义窗口。根据数据集的平均动作时长,设定动作窗口长度。这里注意窗口是“编码器的输入长度”,不是任务总长度。窗口可以比动作循环略长一些,我在项目中设置为64个控制步。
第三步,搭建模型。编码器用3层一维因果卷积,裁剪好padding。量化器用两层RVQ,每层8192个条目,embedding维度64。解码器用3层一维卷积(转置卷积)把token序列恢复到原始动作序列分辨率。这里说一下逆卷积的棋盘效应,动作数据里虽然没有像素棋盘问题,但逆卷积会产生周期性的纹波噪声,我用紧跟在逆卷积后面的平坦卷积层叠加来消除。
第四步,训练配置。批大小64,学习率3e-4,使用余弦退火。commitment loss系数0.25,速度损失系数0.1,加速度损失系数0.05。先训练100个epoch看看收敛情况。
第五步,评估。评估不只是看loss,必须跑drop-in还原测试。冻结策略模型,输入侧换成重建动作,对比原始动作,记录成功率差值。
5.2 一个可复用的评估模板
我在每个token化器版本发布前都会跑一套固定的评测流程,这里写给你参考。整套流程大约耗时半天,但能避免很多上线后才发现的问题。
第一,重建侧评估。准备一个和训练数据不同分布但同动作空间的测试集,计算MSE、DTW、速度连续性、末端轨迹误差。不要只用训练集里的测试分割,一定要加分布外数据。
第二,drop-in还原测试。选一个现成的策略模型(可以是随便一个已经收敛的模仿学习策略),输入换成token化器重建结果,跑至少50个episode,统计成功率。同时记录原始输入的成功率。两者差值是衡量token化器真实损失的核心指标。
第三,长时间稳定性测试。跑至少5分钟连续任务,观察重建轨迹是否存在漂移。很多token化器在单个窗口内重建很好,但跨窗口连贯执行时会在窗口边界出现跳变。
第四,消融测试。至少对比以下版本:单层VQ vs 两层RVQ vs 三层RVQ;有无速度损失;有无数据增强。用同一套测试集记录drop-in成功率。这能帮你明确到底是哪部分设计在工作。
5.3 参数选择对照表
我整理了我在多次实验中观察到的经验范围,给你做快速参考。具体的数字请以你的平台和任务为准:
| 参数 | 经验范围 | 备注 |
|---|---|---|
| 动作窗口长度 | 32~128控制步 | 根据任务动作周期调整 |
| 时间压缩比 | 1:1到4:1 | 精细任务用1:1或2:1 |
| RVQ层数 | 2~3 | 超过3层收益递减 |
| codebook大小 | 4096~16384 | 太小表达力不够,太大利用率低 |
| embedding维度 | 32~128 | 64是甜点 |
| commitment系数 | 0.1~0.5 | 太大导致编码器欠拟合 |
| 速度损失系数 | 0.05~0.3 | 抑制抖动,但别过量 |
| 学习率 | 1e-4~5e-4 | 带EMA时建议3e-4左右 |
这套参数表最大的价值不是告诉你具体数字,而是告诉你哪些旋钮值得调、哪些不值得调。我见过有人花了三周调codebook大小从8192调到65536,成功率纹丝不动,但把速度损失加进去之后一夜之间涨了5个点。
6. 常见问题与排查技巧实录
6.1 训练崩溃和NaN
训练过程中loss突然变成NaN,应该是最常见的问题了。原因主要集中在三方面:一是学习率过大,尤其配合EMA更新codebook时容易出现数值不稳定,我一般是先把学习率降到1e-4,如果还蹦NaN再检查数值范围;二是输入数据里出现了缺失值,有些轨迹在采集时有一帧关节角度是0或者无效值,模型会在一个batch里被这些异常值带崩;三是embedding维度和输入特征维度不匹配,某些深度学习框架在自动广播时会产生NaN而不报错,这个排查起来最耗时。
我从某次崩溃里得到的教训是:在数据加载模块中加一个显式的数值合法性检查,任何非有限值直接报错而不是静默处理。虽然慢一点点,但能省下大量调试时间。
6.2 codebook死条目怎么办
如果你通过usage统计发现codebook里很多条目从来没被激活过,先别急着加大codebook。死条目不是“字典不够大”,而是编码器的输出分布太窄,一直落在某些固定区域,其他条目压根没机会被匹配。
常用的解决办法有三个。第一种是把EMA更新换成更激进的更新策略,在每个batch强制随机初始化那些使用次数过低的码字。第二种是给编码器输出增加一个小的噪声扰动,让它的分布均匀扩散,这个办法我试过,能让死条目比例从40%降到12%。第三种是改用分类分布的soft量化(类似Gumbel-Softmax),避免硬匹配导致的分布窄化,但训练稳定性又要花功夫调。
这三种方法按顺序尝试,一般到第二种就能解决大部分问题。
6.3 在线推理速度跟不上
token化器的推理速度是另一个被低估的问题。训练时一切顺畅,但到线上一跑发现每个控制步要编解码若干个token,延迟爆表。我建议在架构选择时就注意:编码器只需要在“状态变化时”重算,解码器输出如果能用缓存增量计算,就不要从头跑整个网络。
另一个优化是降低自回归解码的粒度。如果每个token对应2个控制步,你可以把token序列整段并行解码,而不是逐个token循环。实际测试中,把解码器改成并行推理比循环快接近一个数量级。
6.4 长时程任务的漂移问题
长时程任务跑着跑着重建精度逐渐下降,这是token化器的累积误差效应。单个窗口重建误差很小,但每次窗口切换都会把上一窗口末端的微小误差带到下一窗口,几十个窗口之后误差积累到不可忽略。
应对方式有两种。一是用滑动窗口,每次保留前一个窗口末尾的一小段上下文作为当前窗口的初始状态,让重建连续化。二是设计一个“层级token化器”,第一层把长时间任务压缩成粗粒度的高层token序列,第二层负责在每个高层token内部做细粒度重建。第一种方式实现简单,我目前项目中用它就能解决漂移问题,第二种更优雅但训练复杂度高很多。
关于“优秀”的最终定义
虽然不能下什么权威定义,但经过这么多实验,我心里对“优秀动作token化器”已经有了很明确的画像:它在时间分辨率上找到了和任务语义匹配的平衡点,在重建保真和序列效率之间做出了合理的取舍;它在分布外数据上有稳定的表现,而不是只在训练集上刷分;它在接入下游策略时产生的损失是可解释的,而不是黑盒式地让策略性能莫名下降。
最后分享一个我反复验证过的判断标准:如果你的token化器在某个配置下重建指标特别好,但drop-in成功率很差,不要急着加复杂度,先回头看看重建误差的分布是不是均匀地侵蚀了每个时间步。一个把误差集中在“不重要的时间步”上的token化器,远比一个在所有时间步上都犯小错的token化器更适合做策略的输入。判断哪些时间步重要,需要你对自己任务集的深度理解,这恰恰是算法工程师比模型结构更值钱的地方。