Ditto 技术解读:把 talking head diffusion 从像素潜空间挪到运动空间
2026/7/1 16:02:34 网站建设 项目流程

Ditto 技术解读:把 talking head diffusion 从像素潜空间挪到运动空间

Ditto 这篇工作最有意思的地方,不是又做了一个音频驱动数字人,而是它把问题拆得很干净:扩散模型负责生成运动,渲染器负责把运动落到具体身份上。这个分工看起来朴素,但它直接绕开了很多 talking head diffusion 过去绕不开的问题,比如 VAE latent 太重、可控性弱、推理慢,以及生成结果只能靠重采样碰运气。

论文全名是《Ditto: Motion-Space Diffusion for Controllable Realtime Talking Head Synthesis》,Ant Group 团队在 2024 年 11 月放出 arXiv,2025 年 7 月 README 更新显示被 ACM MM 2025 接收。项目已经开源推理代码、Hugging Face 模型,后续也放出了 PyTorch 模型和训练分支。对想复现或者做后续研究的人来说,这比 VASA-1 那类不开源系统友好很多。

这篇文章主要讲清楚四件事:Ditto 的 motion space 到底是什么;为什么它比直接在 VAE latent 里做扩散更适合实时 talking head;条件信号和训练策略怎么补 LivePortrait motion 表征的坑;最后看实验数字时应该看哪些,不该被哪些指标带偏。

一句话概括 Ditto

Ditto 用 LivePortrait 类似的运动抽取器,把人脸运动表示成 identity-agnostic 的 keypoint deformation、head rotation 和 translation,再训练一个 conditional Diffusion Transformer 从音频和控制信号生成这组运动参数。生成出来的运动参数交给 one-shot renderer 渲染回视频。

换句话说,它不是让扩散模型直接学“下一帧长什么样”,而是让模型学“脸应该怎么动”。这一步把纹理、身份、背景这些对运动生成没那么必要的信息先剥掉,扩散模型看到的是低维、可控、和人脸语义有一定对应关系的运动空间。

一个简化流程如下:

输入音频 + 单张参考图 │ ├─ HuBERT 提取音频特征 │ ├─ Motion Extractor 从参考图取 canonical keypoints / 初始 motion │ ├─ Conditional DiT 在 motion space 里生成 m = {δ, R, t} │ └─ Face Renderer 使用参考身份外观 + 生成 motion 渲染视频

这个设计的核心收益有两个。第一,motion 表征比视频 VAE latent 小得多,扩散生成更轻。第二,motion 表征里有旋转、平移、局部 deformation 这些可以操作的量,所以 gaze、pose、emotion、局部幅度限制都更容易接进去。

为什么不要直接在视频 latent 里扩散

EMO、EchoMimic、Hallo、Hallo2 这类方法把 diffusion 带进了 talking head,一般会比早期 GAN/landmark 方法更自然:表情细节、头部节奏、说话时的非口型运动都更丰富。但代价也很明显,推理慢,而且生成结果的控制粒度有限。

论文指出,常见 latent diffusion 的 VAE latent 对 talking head 来说有两个不合适的地方。它同时混着纹理和运动,扩散模型要学的东西太多;它又是隐式空间,很难直接对应到“眼睛张开一点”“头往右转一点”“嘴部幅度别太夸张”这样的控制。

Ditto 的判断是:既然 talking head 的身份外观可以由渲染器保留,扩散模型就没必要反复生成纹理。把运动拿出来单独建模,才是更贴近任务结构的选择。

论文中的 motion 表征来自 LivePortrait 系列的 motion extractor。对一帧图像,模型提取 canonical keypointsccc、expression deformationδ\deltaδ、head rotationRRR和 translationttt。最终交给扩散模型预测的是:

m={δ,R,t} m = \{\delta, R, t\}m={δ,R,t}

渲染阶段再用参考图的身份信息和生成的 motion 组合出隐式 3D keypoints:

x^=crefR^+δ^+t^ \hat{x} = c_{ref}\hat{R} + \hat{\delta} + \hat{t}x^=crefR^+δ^+t^

然后 renderer 根据参考外观特征和这些 keypoints 合成帧。这里的关键不是公式复杂,而是责任边界清楚:DiT 学运动分布,renderer 负责 photorealistic synthesis。

Conditional DiT:音频只是条件之一

如果只看标题,容易误以为 Ditto 就是“音频到 motion 的 diffusion”。实际实现里,音频只是条件信号的一部分。作者给 DiT 塞了多种条件:HuBERT 音频特征aaa、canonical keypointscrefc_{ref}cref、emotion labelsss、eye stateeee、reference initial motionmrefm_{ref}mref

这些条件解决的是不同问题:

条件信号作用
HuBERT audio featureaaa提供口型和语音节奏的主要驱动
canonical keypointscrefc_{ref}cref让生成 motion 适配目标身份的脸型几何
emotion labelsss给表情一个显式控制入口,避免全靠音频猜表情
eye stateeee控制眨眼和视线,这些和音频相关性很弱
initial motionmrefm_{ref}mref保持片段间连续性,也能把长序列拉回指定状态

这里有一个容易忽略但很重要的点:Ditto 没有假设 LivePortrait 的 motion 表征已经完全去身份化。论文明确说,即使是 LivePortrait,也很难完全 disentangle motion 和 identity。因此作者把 canonical keypoints 作为 identity feature 输入 DiT,让生成的运动适配目标脸,而不是强行要求运动空间天然纯净。

这其实是比较务实的工程判断。很多论文会把“identity-agnostic representation”写得很理想,但真实系统里总会残留身份信息。Ditto 的做法是承认这个残留,然后用条件建模去补偿。

训练策略:motion space 小了,但并不自动好学

motion space 降低了扩散学习难度,但它也带来新问题。不同 motion 分量的幅度、频率、和音频相关性都不一样。嘴唇、眼睛、头部姿态、表情 deformation 不能用同一套 loss 权重粗暴处理。

Ditto 做了几件比较有针对性的事情。

第一是 horizontal flip。真实视频里的头部朝向分布不一定平衡,如果训练集里某些朝向更多,motion extractor 提取出的运动也会带偏。论文用水平翻转增强,让 audio-to-motion 的对应关系在左右方向上更平衡。

第二是 adaptive loss weights。作者把 motion representation 按控制区域分组,根据不同组在训练中 loss 下降情况动态调权。直觉上,嘴部和头部不是同一种运动,统一 MSE 很容易让某些分量学得快、某些分量学崩。

第三是 temporal loss。除了 DDPM 风格的去噪目标,作者还回归 motion 的一阶和二阶导数,约束速度和加速度:

L=Ld+Lt+Lini L = L_d + L_t + L_{ini}L=Ld+Lt+Lini

其中LtL_tLt关注 motion 的 temporal stability,LiniL_{ini}Lini让生成片段的起始 motion 和参考初始 motion 对齐。这个设计是为了避免片段生成在长视频里慢慢漂移。

从 ablation 看,这些细节不是装饰。Table 4 里去掉 emotion label 后,Talk9 上 FID 从 17.254 变成 23.036,FVD 从 219.368 变成 324.078;去掉 adaptive loss weights 后,FVD 直接恶化到 588.821,Sync-C 也从 8.069 掉到 0.289。这个结果说明 Ditto 的质量不只是来自“换了 motion space”,训练怎么处理不同 motion 分量同样关键。

控制能力来自 motion 语义映射

Ditto 的控制不是在 prompt 层面说“高兴一点”这么粗。它在 motion deformation 上建立了更接近 blendshape 的操作方式。

论文把 expression deformation 视为 63 维向量,也就是 21 个隐式 3D keypoints 的x,y,zx,y,zx,y,z坐标。作者对每一维加小的正负偏移,再观察渲染后哪个面部区域变化。结果发现一些维度能相对清楚地对应到局部动作,比如第 34 维控制右眼开合,第 58 维类似 ARKit 里的 jaw open。

这带来两类控制:

Regional control: 限制某些局部区域的运动 Magnitude control: 限制 deformation 幅度,减少夸张表情或局部 artifact

论文里比较典型的例子是 gaze correction。早期测试中,生成的 gaze 会和 head pose 绑定,头一动眼神也跟着漂,角色很难稳定看向镜头。作者录制了一个模板视频,让演员平滑转头但保持眼睛看镜头、表情恒定,然后拟合 head pose variation 到 gaze-related deformation 的映射δe=K(Re)\delta_e = K(R_e)δe=K(Re)。推理时用这个映射修正 gaze,让眼神和头部姿态解耦。

这个点对交互式 avatar 很实际。口型对齐只是底线,眼神乱飘会让人立刻觉得不对劲。Ditto 把 gaze 当成可修正 motion,而不是寄希望于 diffusion 一次生成完美结果,这个思路更适合产品化。

实时性:Ditto 真正在优化端到端链路

很多 talking head 论文说自己快,其实只报某个模块的速度。Ditto 的实时性部分比较具体:它同时优化了 audio feature extraction、motion generation、video synthesis,还报告了 RTF 和 FFD。

RTF 是 Real-Time Factor,小于 1 才能跑得比实时更快。FFD 是 First-Frame Delay,交互场景里越低越好。

论文里的几个关键数字:

设置RTFFFD
talking-head offline0.635-
talking-head online0.895385ms
full-body offline0.648-
full-body online0.914392ms

模块级别上,Audio2Feat 单步 23ms,Motion DiT 62ms,Face Rendering 15ms,对应 RTF 分别是 0.115、0.310、0.375。论文测试环境是 12-core Intel Xeon Platinum 8369B CPU、1 张 NVIDIA A100 GPU 和 100G 内存。

它能做到这个速度,主要靠几层优化叠加:HuBERT 做 streaming audio feature extraction,用 KV cache 和 causal mask 处理很短音频片段;DiT 推理从 50 步降到 10 步;motion DiT 和 renderer 都转 TensorRT;视频输出时 CPU 侧 FFmpeg 可以并行压缩。

Table 1 里也能看到速度差距。Talk9 上,EchoMimic 的 RTF 是 35.528,Hallo 是 53.082,Hallo2 是 56.838;Ditto-s10 是 0.635。也就是说,传统 diffusion talking head 在这个测试里比实时慢几十倍,而 Ditto 进入了在线交互可用的区间。

实验怎么读:别只盯着 FID

Ditto 在 Talk9 和 HDTF100 上都报了定量指标。Talk9 上,Ditto-s50 / Ditto-s10 的 FID 分别是 17.254 / 17.060,FVD 是 219.368 / 231.182,CSIM 是 0.864 / 0.861,Sync-C 是 8.069 / 8.111,Sync-D 是 7.114 / 7.291,RTF 是 2.121 / 0.635。

这里最值得看的不是 s50 比 s10 略好,而是 s10 在质量基本接近的情况下把 RTF 压到了 1 以下。实时系统里,50 步 diffusion 如果跑不动,指标再好也很难进交互链路。

HDTF100 上,Ditto 的 FVD 是 134.640,优于 EchoMimic 的 532.733、Hallo 的 366.066、Hallo2 的 239.517;Sync-C 是 8.939,也高于这些 baseline。这个结果支持作者的主张:motion space diffusion 对口型和时序一致性都有帮助。

用户研究更有意思。10 名参与者、5 组 image-audio 输入、每种方法生成 5 个 driving clips,然后成对比较。Ditto 在 visual quality 和 lip synchronization 上胜出比例最高,分别是 84.0% 和 80.7%。但在 naturalness of facial expressions and head movement 上,Ditto 是 48.7%,低于 Hallo2 的 59.3%。作者也承认,motion representation 会削弱一些高频运动信息。

这点很关键。Ditto 不是“所有维度都赢”。它在实时性、可控性、口型和稳定性上很强,但 motion space 的压缩也可能损失细微自然度。对研究来说,这反而给后续工作留出了清晰方向:如何在保持可控和实时的同时,把高频微表情和头部自然运动补回来。

复现和工程使用注意点

官方 README 给出的测试环境是 CentOS 7.2、A100、Python 3.10、TensorRT 8.6.1。推理分支已经提供 TensorRT 模型,路径大致如下:

checkpoints/ ├── ditto_cfg/ │ ├── v0.4_hubert_cfg_trt.pkl │ └── v0.4_hubert_cfg_trt_online.pkl ├── ditto_onnx/ └── ditto_trt_Ampere_Plus/

基本推理命令是:

python inference.py\--data_root"./checkpoints/ditto_trt_Ampere_Plus"\--cfg_pkl"./checkpoints/ditto_cfg/v0.4_hubert_cfg_trt.pkl"\--audio_path"./example/audio.wav"\--source_path"./example/image.png"\--output_path"./tmp/result.mp4"

如果 GPU 不支持官方提供的 Ampere_Plus TensorRT engine,需要从 ONNX 重新转换:

python scripts/cvt_onnx_to_trt.py\--onnx_dir"./checkpoints/ditto_onnx"\--trt_dir"./checkpoints/ditto_trt_custom"

README 还给了 PyTorch 模型路径,方便二次开发。但如果目标是实时推理,TensorRT 仍然是主线。训练代码在train分支,官方也提醒它可能和论文版本略有差异,这种差异复现实验时要记下来。

我会特别注意三件事。

第一,Ditto 的强项依赖 LivePortrait 风格 renderer。如果你换 renderer,motion space 的语义和 artifact 分布都会变,不能假设论文结论自动迁移。

第二,实时数字是在 A100 + TensorRT 下测出来的。消费级 GPU、不同 TensorRT 版本、不同分辨率都会影响 RTF 和 FFD。尤其 online streaming 里 inter-segment overlap 会抬高 RTF,不能只用 offline 输出速度估计交互延迟。

第三,Ditto 的控制接口很适合接产品逻辑,比如 gaze lock、head pose bound、mouth-open clamp、局部 deformation 限幅。但这些控制如果调得太硬,也可能让动作变僵。真正要落地,最好把这些参数暴露成可调策略,而不是固定 magic number。

和 LivePortrait、VASA-1 的关系

Ditto 很像站在两个系统之间:LivePortrait 给它 motion extractor 和 renderer 的基础;VASA-1 给它“在 motion/appearance disentangled space 里训练 DiT”的方向。但 Ditto 更偏开源可复现,也更强调控制。

LivePortrait 本身适合做图像驱动、姿态/表情迁移和编辑,但它不是一个完整的 audio-to-motion diffusion system。Ditto 借它的 motion space,把音频到人脸运动这部分补上。

VASA-1 展示了实时 talking face 的潜力,但论文里用的是更隐式的 motion representation,而且没有公开代码,后续研究很难直接沿着它改。Ditto 的 explicit motion space 和开源实现,使它更像一个可接续的研究基座。

如果要给 Ditto 一个定位,我会说它不是追求端到端视频扩散的“更大模型”,而是把 talking head 重新拆成了可生成、可控制、可渲染的几个环节。这种拆法没那么炫,但很有工程生命力。

局限:motion space 不是免费午餐

Ditto 的局限也来自它的优点。

motion space 越 compact,推理越快,控制越容易;但如果这个空间表达不了某些高频细节,模型也生成不出来。用户研究里 naturalness 指标不如 Hallo2,论文解释为 motion representation attenuating high-frequency motion information。这个说法可信。

另一个问题是控制语义仍然是半经验的。通过逐维 offset 观察渲染结果,可以找到一些局部对应关系,但这和标准化 blendshape 还不一样。不同 renderer、不同训练版本、不同人脸风格下,这些维度的语义稳定性还需要更多验证。

再就是数据规模。论文训练用了约 50 小时广播场景视频、330 个 identities。这个规模对学术 paper 不小,但对泛化到任意人像、任意语言、任意拍摄条件的产品来说仍然有限。尤其唱歌、夸张表演、侧脸、大幅身体动作这类 case,可能需要更专门的数据和控制策略。

结语

Ditto 的价值在于它把 talking head diffusion 的瓶颈从“生成视频帧”改写成了“生成可渲染的运动”。这让实时性和可控性第一次变得很像同一个设计目标,而不是互相牺牲。

如果你关心数字人、音频驱动头像、实时 avatar 或者 gesture/face generation,Ditto 值得认真读。它给出的不是一个完美终点,而是一条很清楚的路线:motion representation 要足够轻,语义要足够可控,renderer 要足够稳,最后再让 diffusion 去补运动分布。后续工作真正难的地方,大概就是在这条线上把自然度和微表情补回来。

参考资料

  • Li Tianqi, Zheng Ruobing, Yang Minghui, Chen Jingdong, Yang Ming. 《Ditto: Motion-Space Diffusion for Controllable Realtime Talking Head Synthesis》, arXiv:2411.19509v3, 2025-04-30. https://arxiv.org/abs/2411.19509
  • Ditto project page, Ant Group / Digital Avatar. https://digital-avatar.github.io/ai/Ditto/
  • antgroup/ditto-talkinghead GitHub README. https://github.com/antgroup/ditto-talkinghead
  • digital-avatar/ditto-talkinghead Hugging Face model repository. https://huggingface.co/digital-avatar/ditto-talkinghead

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询