AI编舞

AI 生成的舞一到快动作就"糊":FFMT 把编排骨架和发力细节拆成两套码本,AIST++ 上 FID 从 21.55 降到 9.91

2026年11月6日1 次阅读
AI 生成的舞一到快动作就"糊":FFMT 把编排骨架和发力细节拆成两套码本,AIST++ 上 FID 从 21.55 降到 9.91
AI 编舞 · 动作生成

一句话说清:让 AI 跟着音乐编舞,业内通用的做法是先把连续动作压成一串"动作单词"再让模型学着接龙。香港科技大学(广州)、上海交大、杜克和伯克利的团队 11 月 5 日挂出的论文 FFMT 指出,这套做法有个结构性毛病——慢的编排和快的发力被迫共用同一套"词汇表",快的部分就被压糊了。他们的解法很直接:把动作按频率拆成两半,各给各的更新速度、各给各的词汇量。

3分钟看懂

  • 谁做的:香港科技大学(广州)+ 上海交通大学 + 杜克大学 + 加州大学伯克利分校,6 位作者(前两位共同一作)
  • 什么时候:2026 年 11 月 5 日 03:35 UTC 挂上 arXiv(2611.07384),目前只有第一版
  • 做了什么:把一段舞拆成"低频编排骨架"和"高频发力残差",低频用慢的 token 速率 + 小码本,高频用快的 token 速率 + 大码本,再让高频生成时参考已经生成好的低频
  • 成绩:AIST++ 上 FID 从同组最好的 21.55 降到 9.91;FineDance 上从 47.20 降到 35.21
  • 能不能用:不能直接用。没有代码、没有权重、没有项目页,只有论文
  • 对谁有用:做动作生成、虚拟人、舞蹈动画的研究和工程团队;对普通创作者,这篇的价值是"知道瓶颈在哪",不是"今天能上手一个工具"

先说清楚问题:为什么生成出来的舞"糊"

音乐到舞蹈生成(music-to-dance)这条线,主流做法是两段式:先训练一个 tokenizer,把连续的三维关节动作压成离散的"动作单词"(这套技术叫 VQ-VAE,向量量化);再训练一个自回归模型,让它一边听音乐一边一个词一个词往外蹦。

这种结构下有两个旋钮决定成败:

  • token 速率:每秒切几个"单词"。切得粗,动作的变化就跟不上;切得细,序列长得可怕,模型记不住。
  • 码本大小:一共允许多少种"单词"。太少,不同的动作被硬塞进同一个词,细节就没了;太多,每个词见得太少,学不扎实。

问题在于,这两个旋钮过去是全局共用的。一支舞里,"身体慢慢转向左边"这种编排级的变化,可能两秒才发生一次;"手腕快速抖一下""脚步急促点两下"这种发力细节,一秒里发生好几次。用同一套速率和词汇量去编码这两件事,结果必然是:照顾了慢的,快的被抹平;照顾了快的,序列长度爆炸、算力吃不住。

论文里的说法是"时间容量分配问题"(temporal capacity allocation)。翻成大白话:预算就这么多,你得决定花在哪儿。

FFMT 干了什么:把动作按频率拆开,再分别量化

第一步拆得很干净。先把整段动作的全局位移去掉,只留"相对于根节点(骨盆)的关节位置"。然后拿一个固定的高斯低通滤波器沿着时间轴滑一遍,得到低频分量;原信号减去低频,剩下的就是高频残差。

这个拆法是精确可加的:低频 + 高频 = 原始信号,一点不丢。这一步很重要——不是为了省事,而是为了在量化之前把两种时间尺度彻底分开,让后面的码本各管各的。

第二步再按身体部位切一刀:上半身、下半身。低频上半身、低频下半身、高频上半身、高频下半身——四条独立的 VQ-VAE 分支,每条有自己的编码器、自己的码本、自己的解码器。

然后是关键的容量分配(论文 4 秒窗口的设置):

  • 低频:0.2 秒一个 token,码本 128 个词。因为它只描述"大致往哪儿走",不需要细。
  • 高频:0.1 秒一个 token,码本 512 个词。因为它要描述"怎么发力",需要细。
  • 结果:每个身体部位的低频流一个窗口 20 个 token,高频流 40 个 token。

对比一下:如果两路都用同样的速率(论文消融里的 "Same Rate" 设置是各 30 个 token),总 token 数其实是一样多的。FFMT 赢的不是"用了更多预算",而是"把同样的预算分给了更该拿的地方"。

生成端:先想编排,再抠细节

有了四路 token,生成分两步走:

  1. Plan(定编排):低频自回归模型先听音乐,把整段的粗编排吐出来——大概是"这一段在原地左右摆,那一段往前走两步"。
  2. Articulate(抠细节):高频模型在低频序列的指导下生成残差。因为两路速率不同(40 对 20),每个高频时刻会被对齐到对应的低频时刻,并取它附近一小段低频 token 当上下文。

这个"低频给高频当条件"的设计,是整篇论文里影响最大的一个环节——后面的消融会看到,把它砍掉,指标崩得比拆频本身还厉害。

还有一个不加参数的小技巧:解码时用一个从训练集统计出来的先验做重打分。它包含两部分,一是"这两种 token 在训练数据里经不经常挨着出现"(转移先验),二是"这个 token 倾向于落在拍点上还是拍点之间"(节拍先验)。候选集是模型打分最高的 64 组 token 加上训练集里实际出现过的后继。整个过程不引入任何新的可训练参数。

成绩单:赢在哪儿,别在哪儿被数字骗

先看 AIST++(一个 60fps 的街舞数据集,学术界的标准测试场)。FID 越低越好,衡量生成动作和真实动作的分布差距;FID_k 看动态特征,FID_g 看几何特征。

方法FID_kFID_gDiv_kDiv_gBAS
真实数据––8.197.450.2374
Bailando++21.2911.569.316.200.2330
EDGE42.1622.123.964.610.2334
Lodge37.0918.795.584.850.2423
TokenDance21.5511.858.057.120.2313
FFMT9.917.028.256.650.2374

FineDance(一个 30fps 的中国舞/民族舞数据集,动作更碎、风格更复杂):

方法FID_kFID_gDiv_kDiv_gBAS
真实数据––9.737.440.2120
Bailando++54.9446.296.175.780.2210
EDGE94.3450.388.136.450.2116
Lodge45.5634.296.755.640.2397
TokenDance47.2031.856.626.810.2385
FFMT35.2127.669.757.660.2125

三个必须说清楚的地方:

第一,竞品的数字不是他们自己跑的。 论文明确写了,EDGE、Lodge、TokenDance 三行的数字直接引自 TokenDance 那篇论文的对比表。只有 Bailando++ 是他们在 AIST++ 上自己复现的。这意味着这不是一次"同机同条件"的公平横评,跨论文抄表天然会有评测器版本、预处理差异。FID 从 21.55 掉到 9.91 这个幅度太大,值得等第三方复现。

第二,多样性没有全面赢。 在 AIST++ 上,FFMT 的 Div_k(8.25)比真实数据(8.19)略高,Div_g(6.65)比真实数据(7.45)低——论文自己也承认,几何多样性上 TokenDance(7.12)更接近真实数据。也就是说,保真度的提升并没有顺带把"动作覆盖不够广"这个问题一起解决。而且论文把多样性、BAS 都当作"中性指标",评判标准是"离真实数据有多近",不是"越高越好"——这一点很容易被误读。

第三,BAS 基本没进步。 AIST++ 上 FFMT 的 0.2374 和真实数据一模一样,FineDance 上 0.2125 对真实 0.2120,也只是贴着。这说明它没有解决"踩点"这件事的难度,它解决的是"动作像不像人做的"。对于真正编舞来说,踩点恰恰是最要紧的那一半。

消融:拆掉哪一块最疼

论文做了五组消融,每一组只改一个部件。看 AIST++ 的 FID_k:

变体AIST++ FID_kFineDance FID_k改了什么
完整版9.9135.21–
w/o Freq.28.7456.82不拆低频/残差,直接量化
Same Rate18.9248.01两路都用同样 token 数(各 30)
Uniform K15.1639.46两路码本都用 256
w/o L→H55.27140.77高频看不到低频上下文
w/o Prior13.1435.39去掉解码先验

这张表信息量比主表大:

  • 最疼的是 w/o L→H。频率拆了、码本分了,但高频生成时不看低频结果,AIST++ 的 FID_k 直接从 9.91 冲到 55.27,FineDance 更是从 35.21 飙到 140.77——比不拆频还差得多。这说明"低频当骨架、高频往上长"这个层级关系,比"拆不拆频"本身更关键。拆了频却不建立依赖,等于把两半各自搞乱。
  • 拆频本身次之。w/o Freq. 从 9.91 变成 28.74,说明频率分解确实在起作用,但不是唯一功臣。
  • 同预算下的分配有效。Same Rate 把总 token 数保持不变、只是平均分配,就掉到 18.92。这直接回答了"是不是单纯靠更多算力"的质疑:不是。
  • 码本分配的作用最小。Uniform K 是 15.16,比 Same Rate 好但比完整版差一截,说明"128 对 512"这个不对称设置有用,但没那么决定性。
  • 先验在 FineDance 上几乎没用。w/o Prior 在 FineDance 是 35.39,完整版 35.21,差 0.18——基本在噪声范围。论文也承认这个先验在 AIST++ 上的收益更大。所以别把"训练统计先验"当成通用招数。

论文还单独看了 tokenizer 的重建质量(不生成,只压缩再还原):完整版的 MPJPE 是 94.459mm(AIST++)/ 88.770mm(FineDance),高频重建误差 0.5514 / 0.3190,加速度误差 15.070 / 5.256 m/s²。和各个消融相比,MPJPE 的改善幅度明显小于高频误差和加速度误差的改善幅度——换句话说,这套设计主要保住的是"动态感"和"高频细节",而不是"每个关节的位置更准"。这恰好对应它想解决的问题。

对做舞蹈的人,这意味着什么

这篇论文不是给你一个能用的工具,它给的是一条可迁移的设计原则,而且这条原则对做编舞工具的人相当直白:

  • 别用一种粒度描述整支舞。 编排层的动作(走位、转身、队形)和发力层的动作(抖肩、手腕翻、脚步碎点)本来就该分开处理。这条在动画管线里其实早有对应——关键帧稀疏的地方和密集的地方不该用同一个采样率。
  • 分层不只是"粗到细",还要"粗给细当条件"。 消融已经说得很清楚:拆开但不建立依赖,比不拆还糟。做工具时,"先定骨架再抠细节"必须是硬约束,不能只是推荐流程。
  • 码本容量是可以调 priorities 的。 如果你想强调"爆发力""卡点力量感",往高频那一路加码本;如果想强调"整体走位准确",往低频加。这个旋钮在以前的统一 tokenizer 里根本不存在。

反过来说,如果你期待的是"输入一首歌,输出一支三分钟的成品舞",这篇帮不上——原因见下一节。

怎么用:三条现在就能走的路

没有代码,但论文给的信息足够你做三件事:

  1. 照抄它的分层结构。在你自己的动作中间表示上加一层:一路低频(大 stride、小码本)描述骨架,一路高频(小 stride、大码本)描述残差。低频用 P_L = Gaussian(P),高频用 P_H = P - P_L,精确可加,不用重新设计。
  2. 把"低到高"的条件连起来。高频解码时,取对齐后的低频 token 及其邻域(论文用的是 7 个 token 的窗口)作为额外上下文喂进 attention。这一步不做,指标会比不做分层还差。
  3. 按需分配容量。论文给了具体数字可直接当起点:低频 0.2 秒/token、码本 128;高频 0.1 秒/token、码本 512;上下半身各一套。要做风格化(比如强调爆发力),就往高频加码本,别整体加。

另外提醒一句:如果你只想验证"分层有没有用",最小实验是跑论文的 Same Rate 对照组(两路同速率同码本),成本最低,也最能说明问题。

冷静的一面:四条硬边界

  • 只有 4 秒。 论文所有实验都用 4 秒动作窗口,AIST++ 60fps、FineDance 30fps 都是这个设置。一支真正的舞是几分钟,长序列会漂移,这是所有自回归模型的通病,论文没有给长序列结果。它连"能不能撑住 16 秒"都没回答。
  • 没有代码、没有权重、没有项目页。 我用 GitHub 搜 FFMT dance 是 0 个仓库,Hugging Face 搜 FFMT 只有一个同名的无关语言模型。论文正文里也没有任何代码链接。致谢里只提到这项工作是港科大(广州)"红鸟硕士项目"支持的。也就是说,现在除了读论文,什么都不能做。
  • 只在两个学术数据集上验证。 AIST++ 是街舞,FineDance 偏中国舞/民族舞,都是学术界的标准集,几十小时的量级。真实商用场景里的服装、群舞、双人互动、道具,全都没有涉及。
  • 评测器本身有争议。 FID 这一类指标在动作生成领域一直被诟病——它衡量的是特征分布的距离,不等于"人看着像不像"。而且这篇论文部分对比数字是跨论文抄的,评测器版本不统一。

适用场景

  • 做动作生成研究的人:这是一篇方法干净、消融完整的论文。"频率分解 + 非对称容量分配 + 低到高条件"这套组合,可以整套搬到其他条件生成任务上(比如文本到动作、语音到手势)。
  • 做虚拟人/游戏动画管线的团队:如果你正在自研动作中间表示,"低频骨架 + 高频残差、各配码本"是一个可以直接拿去做原型的思路,不必等它的代码。
  • 评估技术路线的产品/技术负责人:这篇能帮你判断"当前音乐到舞蹈生成的瓶颈到底在哪"——不是模型不够大,是动作表示的组织方式不对。

不适用场景

  • 想今天就下载权重跑起来:没有。
  • 想生成完整的一支舞:只验证了 4 秒。
  • 想解决"卡点不准":BAS 基本没提升,这不是它的目标。
  • 想要手指、面部、表情级别的细节:它处理的是全身关节位置,没有手指和脸。
  • 想要商用:没有代码和 license,谈不上商用评估。

注意事项(避坑)

  • 别把主表的对比当排名。 EDGE、Lodge、TokenDance 的数字是抄来的,不是同条件重跑。看趋势可以,看小数点后的差距没意义。
  • 别把"多样性接近真实数据"理解成"多样性高"。 论文的评判是"离 GT 越近越好",不是"越大越好"。Div_k 8.25 对 GT 8.19,是"贴近",不是"超越"。
  • 别忽略 w/o L→H 那组数字。 它说明这类分层方法的失败模式很特定:拆开了但没连起来,会烂得非常彻底。自己做的时候,先把条件通路打通,再谈容量分配。
  • 4 秒窗口下的 FID 不等于长序列质量。 误差会累积,短窗口的漂亮数字在长序列上经常不成立。
  • 和站内 11 月 5 日那篇 Möbius 不是一回事。 Möbius 解决的是"用一个模型统一理解、生成、补全、编辑动作",走的是把扩散去噪搬进语言模型的路子,不做动作分词;FFMT 恰恰相反,它是在离散分词这条路线上做优化。两者是同一问题的两条相反路线,可以对照着读。

成本与时间

  • 现在:零成本,只能读论文(arXiv abs 页 + HTML 全文都开放)。
  • 如果要复现:论文给了完整的超参——4 秒窗口、高斯核 31 帧 / σ=6、码本 128 与 512、512 维 VQ 嵌入、低频模型 12 层(hidden 512、8 头)、高频模型 14 层(AIST++)/ 12 层(FineDance,hidden 320、5 头)。这套规模不算大,单机多卡可训。真正的成本在数据:AIST++ 和 FineDance 都要申请,且都是学术许可。
  • 如果要落地到自己的角色:还得自己做重定向——模型的输出是"相对根节点的关节位置 + 从根速度积分出的全局位移",要落到你的骨骼上需要一次 retarget。

行动建议

  1. 先读消融表(Table 2),不是主表(Table 1)。 主表告诉你它赢了,消融表告诉你它为什么赢、以及哪里最脆弱。
  2. 如果做研究:把"低频给高频当条件"这条单独拎出来,在你自己的任务上验证一遍。这可能是全文最可复用的部分。
  3. 如果做产品:把"动作表示要分层、且层间要有条件依赖"写进技术方案,具体用不用 VQ 可以再定。
  4. 别等代码。论文没给时间表,也没有项目页。真想跟进,盯 arXiv 的 v2 和作者主页比等媒体转述靠谱。

参考来源

  • 论文摘要页(一手,2026-11-05 03:35 UTC 提交 v1):https://arxiv.org/abs/2611.07384
  • 论文 HTML 全文(含 Table 1/2/3 与全部超参):https://arxiv.org/html/2611.07384v1
  • 代码可用性核查:GitHub 搜索 FFMT dance 返回 0 仓库;Hugging Face 模型搜索无相关条目(2026-11-06 核查)

评论

0 条已公开
登录或注册后可以参与评论。

正在加载评论...