打开网易新闻 查看精彩图片

你有没有想过,一段游戏里角色挥刀的动作,存起来到底要花多少存储空间?

一个角色身上可能有几十到上百个关节,每一帧都要记录每个关节转了多少角度、挪了多少位置。一部动作捕捉的影视级动画,几十秒钟的数据量就能轻松超过一兆字节。如果是一个拥有几百小时素材的动作数据库,那存储和传输的压力可想而知。

游戏行业早就意识到这个问题,于是有了一款叫ACL的压缩工具。

**ACL**:全称Animation Compression Library,动画压缩库,是当前游戏行业事实上的工业标准,被广泛用在各类商业游戏引擎里。

它的厉害之处在于,能在微秒级的时间里随机读取任意一帧的姿势,这对需要实时渲染的游戏来说是刚需。但它有个明显的短板:压缩率不算特别高,而且完全不懂动作的时间规律,也不懂统计学意义上的数据分布。

这篇论文的作者团队就抛出了一个很直接的问题:动作数据里,到底哪些部分是真正的信息,哪些只是骨架结构本身必然带来的冗余?如果能把这两者分开,是不是就能让压缩这件事做得更聪明?

**先搞清楚:骨架决定了大部分,表演者只决定一小部分**

想象你在看一个人挥手告别。

决定这个动作"是什么"的,是这个人想表达再见的意图,这部分信息量其实很小。但手臂从肩膀转动到手腕摆动,中间牵涉的每一根骨头的转动角度,大部分其实是人体结构本身决定的,不需要表演者"决定"太多东西。

论文的核心洞察就是:如果把骨架当成一个先验知识,那么压缩编码真正要传输的信息,应该只是"身体没能预测到的那部分"。这也是为什么研究团队把这个工具命名为CurveCodec(曲线编解码器)系列的原因,它把每一根骨骼的运动,看作一条独立的时间曲线来处理。

这个团队此前已经做过第一代CurveCodec,用学习到的先验知识从稀疏的锚点重建每条关节曲线,效果不错,平均误差能打平ACL,但有两个硬伤:最坏情况下的误差比ACL还大,而且它存的是浮点数值而不是真正压缩过的比特流,解码还得靠GPU。

这次的CurveCodec 2,就是要把这些问题一个个解决掉。

**第一个发现:ACL的压缩效率主要来自两招,剩下的空间很小**

研究团队先把ACL拆开来看,一步步测量它的每个处理阶段到底省了多少字节。

结果发现,ACL的整体压缩比(相比原始浮点数据)里,绝大部分贡献来自两个步骤。第一步是把那些压根没动的关节折叠成一个固定值,这一步贡献了将近3倍的压缩;第二步是对剩下会动的关节做范围压缩和变比特宽度编码,又贡献了将近4倍。这两步加起来,占了ACL几乎全部的压缩效果。

那后面还有没有空间可以挤?

研究者又做了个实验:如果在ACL已经量化好的符号基础上,再套一层信息论意义上最优的无损编码(也就是用符号出现的概率来编码,常见符号用更少比特,这是信息论的基本思路),能再省多少?答案是,顶多省16%到20%。

**熵**:信息论里衡量一个信号平均需要多少比特才能无损表达的量,熵越低,理论上能压缩得越小。

这个结果说明一件事:ACL给每个样本分配的比特数,已经相当接近理论最优了,前提是把每个样本当成互相独立的。换句话说,ACL在"每一帧单独看"这件事上已经做得很好了,继续在它的输出上面叠加熵编码,收益有限。

这就像你已经把一个房间收拾得整整齐齐,东西该叠的叠、该收的收,这时候再找个收纳盒试图把已经叠好的衣服塞得更紧,能省的空间其实不多了。真正能省出大空间的办法,是换一种完全不同的整理逻辑,比如发现其实有好几件衣服几乎每天都穿同一套搭配,根本不需要分开叠放。如果不换思路,继续在同一套折叠方式上抠细节,收益会越来越薄。

真正的突破点在别的地方:如果每个样本不是独立的,而是能从它自己的历史推测出来,那省下来的空间就完全不一样了。

**第二个发现:时间上的可预测性,才是最大的省钱办法**

既然"每帧独立看"已经被ACL压榨得差不多了,那换个角度:如果一个关节这一帧的转动角度,能从它前几帧的历史推算出来呢?

研究团队测试发现,光是用"用过去预测现在"这一招,就能让曲线压缩后的数据量再减少39%到55%。而且不同关节、不同动作捕捉场景下,最适合的预测方式还不一样:根关节(比如骨盆,是整个骨架运动链的起点)用二阶差分预测比一阶差分预测要好18%,但到了第六层以下的末端关节(比如手指尖),这个优势只剩下4%到7%,因为末端的抖动噪声已经掩盖了规律。

还有一种自适应的预测器(一种能根据数据自己调整参数的滤波算法,叫NLMS),在37%到44%的曲线上表现最好。这说明没有一种预测方式能包打天下,得按曲线自己的脾气来选。

**第三个发现:不是每一帧都值得存,省略也是一种压缩**

除了预测,研究团队还发现了第二个大杀器:关键帧选择。

一条运动曲线不需要记录每一个采样点,只需要记录一些关键点,中间的部分用插值(根据前后关键点的数值,推算中间点大概是多少)去补上就行。这个思路本身不新鲜,老式的关键帧压缩技术一直在用。但这篇论文的做法不一样的地方在于:它不是孤立地看每条曲线自己的误差能不能接受,而是把整个骨架的运动链条串起来算总账。

**正向运动学**:根据每个关节相对父关节的局部旋转和位移,逐级推算出这个关节在世界空间里最终所在位置的计算过程,是动画和机器人学里的基础工具。

具体来说,如果想删掉手腕上的一个采样点,不能只看手腕自己的误差够不够小,还得把这条信息顺着骨架结构往下传:手腕的误差会影响到手指,手指末端的误差可能被放大到超过容忍范围。研究团队管这叫"闭环"验证,每次尝试删掉一个关键帧,都要重新通过正向运动学算一遍,看看整个子树(从这个关节往下的所有骨骼分支)的误差有没有超标。

这个闭环验证到底值不值得?研究团队专门做了对比:如果只用局部误差判断要不要删关键帧(也就是不考虑对下游关节的连锁影响),只能省下0%到0.6%的空间。但换成这种贯穿骨架结构的闭环判断,效果完全是另一个量级。

这就好比在公司里做预算削减。如果每个部门只看自己账上的数字够不够用,可能会删掉一个看起来不起眼的培训预算,但这笔培训恰好是下游团队效率的关键支撑,砍掉之后下游反而要花更多钱返工。真正有效的削减,得从整个公司的运营链条去算总账,看一笔钱砍掉之后,对整条业务链的最终影响是放大还是可以忽略。不这样算账,省下来的钱可能连零头都不到。

研究团队还发现一个规律:关节越靠近骨架的根部(离身体中心越近),保留的关键帧比例越高,因为根部的误差会传导给所有下游关节,容错空间最小;越靠近末梢,能删掉的采样点比例越高。精度要求越宽松,这种"删样本"策略带来的省钱效果就越明显,在最松的精度设定下,删关键帧和用历史预测两种手段贡献的压缩效果差不多持平了。

**第四个发现:用更聪明的插值方法去补那些被删掉的点,其实没多大用**

这是整篇论文里最让人意外的一个结论。

按理说,既然关键帧之间的空白需要靠插值去填,那如果用更聪明的插值算法,是不是应该能填得更准,从而可以删掉更多关键帧?

**神经网络内插器**:用深度学习模型,根据给定的起止姿态,推算中间缺失帧的技术,在动画生成领域一直是热门方向,比如用于游戏里动作之间的平滑过渡。

研究团队做了个挺狠的实验:建了一个"检索式神谕"模型,简单说就是拿几百万个训练样本当记忆库,每次遇到一个空白,就去几百万个样本里找最相似的情境,直接把那段真实数据复制过来填空。这个模型在随机抽取的空白上表现确实很好,比普通的三次曲线插值要好23%到37%,而且训练样本越多,效果还在持续变好。

但当研究团队把这个神谕模型放到"编码器实际会留下的那些空白"上测试时,结果却是:效果和最简单的线性插值差不多,甚至还不如基础的三次插值。

这是为什么?

原因其实挺直白的:编码器在选择要不要删掉一个采样点的时候,本身就是优先删掉那些"连平滑插值都能猜中"的点。真正留下来的那些关键帧,恰恰是运动里发生突然转折、接触碰撞、方向突变的地方,这些地方在它自己的历史数据里根本没有任何预兆。换句话说,容易预测的点早就被删掉了,剩下的空白恰恰是最难预测的。

这就像一个老练的编辑在审稿子时,会把那些读者一看就能猜到后续情节的段落直接删掉,只留下真正出人意料的转折点。这时候如果你请来一个更厉害的续写模型,想根据上下文"猜"出被删掉的内容,会发现根本没什么可猜的,因为留下来的恰恰都是没有预兆的转折,续写模型手里的线索和普通读者是一样的,它能看到的上下文根本不包含任何能推出下文的蛛丝马迹。如果不理解这一点,继续往插值器上砸算力,只会做无用功。

研究团队还往编码器里塞了四种不同的学习型插值器,包括一个340万参数的变换器模型,结果没有一个真正带来净收益,有的甚至让压缩后的体积反而增大了5.7%。

**那神经网络到底该放在哪才有用?**

这是整篇论文最关键的转折。

既然插值这个位置用不上神经网络,那研究团队就把目标转向了压缩流程里的最后一环,也就是把量化后的整数流编码成实际比特的那一步。

**熵编码**:根据符号出现的概率分配比特长度的无损压缩技术,常见符号用短编码,罕见符号用长编码,这样平均下来总长度最短。rANS是其中一种具体的高效实现方式。

研究团队设计了一个很小的因果变换器(只能看过去,不能看未来的神经网络结构),只有十万左右参数,专门用来预测每条曲线的"残差"分布。这里的残差,指的是实际值和预测值之间的差距,也就是预测没能覆盖的那一小部分信息。

这个小模型不预测残差具体是多少,它预测的是残差的概率分布,比如这个残差大概率落在哪个范围、是不是经常接近零、是不是有周期性规律。这个概率分布直接喂给rANS编码器,让常见的残差模式用更少的比特表示。

实验显示,这个小模型相比手工设计的上下文编码器,在动作捕捉数据上能再省3%到7%,在游戏资产数据上能省13%。它不需要知道这是哪个关节、哪个骨架、哪个数据集,只看这条曲线自己过去的36个特征,包括最近几次残差的大小、残差的指数滑动平均、关键帧之间的间隔、这个关节在骨架里大概的深度位置。

**骨架无关性**:模型不依赖具体的骨架结构或关节身份信息进行训练或推理,所以同一套模型可以直接用在完全没见过的新骨架上,不需要重新训练。

这个设计思路其实是整篇论文最巧妙的地方。因为模型完全不认识"这是左手肘关节"这种具体身份信息,只看数字序列本身的统计规律,所以同一个训练好的模型,可以直接拿去压缩一只四足动物的骨架、一只昆虫的骨架、甚至一个完全没在训练集里出现过的物种,都不需要重新训练。

研究团队专门拿了一个训练时完全没见过的四足动物数据集(一只狗的动作捕捉)做测试,结果这个模型依然能带来5.7%到6.9%的额外压缩收益,差不多是"专门为狗训练一个模型"所能带来收益的九成以上。

这就像一个语言学家研究的不是某一种具体语言的语法规则,而是所有人类语言共通的"音节出现频率"规律。这样的研究成果,换到一门全新发现的语言上,依然能派上用场,哪怕这门语言的词汇和句法完全陌生。如果这个语言学家一开始就把研究建立在某种语言专属的语法规则上,那换一门语言就得全部推翻重来。

**最终成绩单:到底省了多少**

把以上几个发现整合起来,就是CurveCodec 2这个完整系统。它把每一条关节曲线,用对数映射(一种处理旋转数据的数学技巧,能避免四元数表示法在某些角度下产生的精度损失)编码旋转,用厘米为单位编码位移,配合闭环验证的量化步长、基于码率失真优化挑选的关键帧集合,外加这个小小的学习型熵编码模型,组成一条完整的压缩流水线。

**码率失真优化**:在允许的误差范围内,寻找用最少比特数表达信号的过程,是压缩领域的核心方法论。

整套系统还设计了两套误差合同,确保压缩绝不会无限制地牺牲精度。一套叫最大误差合同,保证每个关节的最坏情况误差,都控制在ACL同等设置下误差的5%容忍范围以内;另一套叫均值误差合同,保证整条动画片段的平均误差不超过ACL的水平。如果某条动画压缩完验证不通过,系统会自动放宽一点重新压缩,实在不行就直接存成ACL的格式作为兜底方案,确保永远不会比ACL更差。

在一个由33个数据集、总时长906小时的测试语料库上,这套系统在ACL默认精度(0.01厘米)、最大误差合同下,只需要ACL所需字节数的0.37倍;如果精度放宽到0.1厘米、用均值误差合同,这个比例能降到0.22倍。

换算一下更直观:原本1兆字节的动画数据,现在大约270KB到370KB就能存下来,而且解码全程只需要一个CPU核心,通常几分之一秒就能解完一整段动画。

下面这张表格,摘录了论文里几个测试精度下的核心对比数据:

精度(厘米) ACL所需比特数(每关节每帧) CurveCodec2最大误差合同比特数 压缩比

0.01 16.4 6.1 **0.373倍**

0.1 10.1 2.2 **0.217倍**

1 8.7 1.3 **0.148倍**

从这组数字能看出一个规律:精度要求越松,CurveCodec 2相对ACL的优势越明显。这背后的原因就是前面说过的,精度放松之后,可以删掉的关键帧比例越来越高,而ACL对每一帧都分配固定比特数的做法,在这种场景下就显得很笨重了。

写在后面

读这篇论文的过程中,有一处细节让我反复琢磨。研究团队测试了四种不同角色的学习型组件,包括插值器、变换编码器、离散化的动作词典(残差向量量化)、还有神经隐式场,结果只有放在熵编码这个位置的小模型真正产生了净收益,其它几个要么没用,要么还帮倒忙。

这其实是一种挺朴素但容易被忽视的工程纪律:不是什么地方都适合塞神经网络,一个系统里真正值得用学习方法解决的,往往只是某个很窄的环节,剩下的部分交给传统的、可验证的、确定性的算法反而更靠谱。这几年深度学习的叙事里,常常给人一种错觉,好像什么问题扔个神经网络进去就能解决。这篇论文算是用扎实的对照实验,给这种直觉泼了一盆冷水。

另外论文里提到一个细节,他们专门测过把残差向量量化的码本当作一种动作压缩工具,结果发现它天生有个精度地板,没办法把误差压到动作幅度的1.3%以下,而生产级压缩要求的精度是0.01%到0.1%。这意味着,那些专注于动作生成和动作理解的学术模型,拿去直接当压缩工具用,可能完全达不到工业场景要求的精度门槛,这也侧面说明了"面向生成的表示"和"面向压缩的表示"根本不是一回事,不能简单画等号。

这套压缩系统目前只能整段解码,没法像ACL那样随机读取某一帧,这意味着它更适合存储和传输场景,而不是游戏运行时实时读取动画的场景。如果以后能在"随机访问"和"压缩率"之间找到一个更好的平衡点,会不会催生出下一代真正通用的动画压缩标准?

Q&A

Q1:CurveCodec 2相比ACL到底能省多少存储空间?

A:在ACL默认精度0.01厘米下,按最坏误差合同计算,CurveCodec 2只需要ACL所需字节数的0.37倍;如果精度放宽到0.1厘米并用均值误差合同,这个比例能降到0.22倍,意味着原本1兆字节的动画数据能压缩到270KB到370KB左右。

Q2:为什么用更聪明的神经网络插值器反而没有帮助?

A:因为压缩编码器本身就只删除那些靠简单插值就能猜中的采样点,留下的空白恰恰是动作突变、没有历史规律可循的地方,神经网络插值器能看到的上下文信息和普通插值法一样有限,所以派不上用场。

Q3:CurveCodec 2能不能直接用在没训练过的新骨架上?

A:可以。它的学习模型完全不依赖具体关节身份或骨架结构信息,只看数字序列自身的统计规律,论文测试了一个训练时完全没出现过的四足动物骨架,依然获得了接近专门训练模型九成的压缩收益。