☰
别再手 K 动画了?普林斯顿 UniMate: 一个模型可以驱动万物“动起来”!
2026/10/9 10:21:22 网站建设 项目流程

如果让你给一只章鱼设计"走路"的动作,你会怎么做?

它有八条腿,没有骨头,你该先迈哪条?再换一个:一条蛇怎么"跑"?一只老鹰怎么"落地"?一个机器人大白怎么"打架"?

这些问题,在动画和游戏行业里有个朴素的答案:找动画师,一帧一帧手调。一个角色,几天甚至几周。换一个角色,一切重来。

而最近,普林斯顿大学、加州大学伯克利分校、MIT、南洋理工的研究者联合发表了一项工作,名字叫UniMate,已经被计算机图形学顶会SIGGRAPH Asia 2026接收。它做的事用一句话就能说清:

给它一个 3D 角色,再写一句话,它就能让这个角色动起来。不管这个角色是人、猫、鲨鱼、鸟、蛇,还是一把会开合的剪刀。普林斯顿、伯克利、MIT 联手,让鲨鱼、老鹰、大白用同一个 AI 大脑动起来

等等,这不是早就有了吗?

你可能会说:AI 生成动作不是早就有了吗?

确实有,但有一个大坑:以前的 AI 是"偏科生"。

打个比方。以前的模型像一个只会做川菜的厨师,你让他做粤菜,他会懵;你给他一堆粤菜食材,他得先"回炉重造"一遍,也就是研究里说的针对每种骨架重新训练、或者需要参考动作。

原因很简单:不同生物的"骨架"长得完全不一样。

  • 人有两条腿、两只手;

  • 猫有四条腿和一条尾巴;

  • 蛇是一长串关节;

  • 鸟有翅膀;

  • 昆虫的腿多得数不过来。

AI 习惯处理"规整"的数据,而骨架的"形状"千奇百怪,没法塞进同一个模子。所以过去的方法,要么只能做人,要么每种动物单独训练一个模型。

UniMate 的野心是:一个模型,通吃所有骨架。

而且论文强调,推理时不需要针对每个骨架重新训练,也不需要现场优化。它能做到实时生成。

它到底能干嘛?

1. 同一句话,不同角色,各演各的
输入"走路",人类走得像人,四足动物走得像动物,每个角色都按自己的骨架结构来动,而不是生硬地套同一套动作。

2. 同一个角色,不同台词,随心换
给"大白"(对,就是那个充气机器人)、老鹰、鲨鱼分别输入不同指令,它们都能生成符合描述的动作。

3. 同一个角色,同一句话,每次还不一样
这点很关键。真实的生物不会每次走得一模一样,UniMate 每次生成的动作"既符合描述,又各有变化"。

4. 三个"零样本"小技能(不用额外训练,直接复用同一个模型):

  • 动作编辑

    :原动作是"站着转头",你只想保留转头,让身体改成"向前走",它能做到"头不动,身体换"。

  • 动作补间

    :给个起始姿势和结束姿势,再写一句"蹲下再站起来",中间的过程它自己补全。

  • 动作续写

    :连续输入"起飞 → 向前冲 → 降落",一只鸟的连贯飞行动作就接出来了。

如果你是做游戏、动画、短视频特效的,是不是已经开始坐不住了?

所以,动画师要失业了吗?

短期内不会。原因有三:

  1. 论文解决的是"让任意骨架有个靠谱的基础动作",而不是替代导演的艺术判断。影视级的表演、情绪、风格,仍然需要人来把关。

  2. 这是学术成果,离"稳定好用的商业工具"还有距离,官方代码也尚未完全开放。

  3. 它自己的数据里都有人工逐条审核的环节,说明高质量动作离不开人的参与。

但长期会改变分工:过去动画师花大量时间做"从零到六十分"的体力活,未来这部分很可能被 AI 接手,人去做"六十分到一百分"的创意活。

对独立游戏开发者、小团队来说,这反而是好事。以前养不起动画师的人,终于有机会让自己的怪物"活"起来了。

它为什么能做到?

前面是科普,下面是干货。

一、核心难题:怎么让 AI "看懂"骨架的形状?

UniMate 用的是拓扑感知的扩散 Transformer(Topology-aware Diffusion Transformer)。

扩散模型你可能听过:Stable Diffusion 画图就是它。Transformer 就更熟了:ChatGPT 的底座。UniMate 把二者结合起来生成动作,关键创新是:让注意力机制"知道"骨架的连接结构。

论文提出了三个机制:

① 图感知的注意力偏置(Graph-aware attention bias)
基于关节之间的成对关系和测地距离(沿着骨架走的距离,而不是直线距离)来调整注意力。通俗说:肩膀和手肘离得近,注意力就该"亲"一点;脚趾和头顶离得远,就该"疏"一点。

② 谱旋转位置编码(Spectral RoPE)
这是最有意思的一点。RoPE 是大语言模型里常用的位置编码,但它是为"一维序列"设计的,词有先后顺序。可骨架是一棵树,没有天然的"第几个"。论文把 RoPE 推广到了任意运动学树上,借助的是图拉普拉斯矩阵(Graph Laplacian)。

③ 全局拓扑条件器(Global topological conditioner)
从静止姿态(rest pose)的骨架里,通过注意力池化提取一个"整体骨架特征",告诉模型:"你现在要驱动的是一条蛇,不是一个人。"

二、数据:13,006 条动作,是怎么"洗"出来的?

光有模型不够,还得有"多才多艺"的训练数据。作者整合了 Truebones、Mixamo、Objaverse-XL 三个来源,构建了UniML3D:13,006 条带文本描述的动作序列,覆盖两足、四足、鸟类、海洋生物、昆虫、蛇形和关节刚体。

但原始数据"脏"得惊人:骨架断开、根节点错位、有的关节根本不动、动作违反物理、坐标系和朝向不统一。项目页公开了一套16 步的清洗流程,分三个阶段:

阶段

做了什么

过滤

只保留主骨架树;用正向运动学校正根节点;删掉 IK 控制器等"幽灵关节";剔除静止、抖动、速度异常的片段

标注

用 LLM 统一关节命名;用 LLM 选出左右对称关节对来判断朝向;30FPS 重采样并四视角渲染;用多模态 LLM 写描述;最后人工逐条审核

规范化

广度优先序列化骨架树;按拓扑直径缩放;统一到 y 轴向上、初始根在原点;朝向对齐到 +z;旋转表示相对静止姿态;做特征归一化

这一套下来,才让"一只章鱼"和"一个人"的数据能放进同一个模型里训练。

三、代码长什么样?

先声明:官方的训练/推理代码尚未发布。下面第一部分是官方已公开的环境配置,第二、三部分是根据论文描述写的概念示意,用来帮助理解思路,不是官方实现,细节以论文和后续开源代码为准。

官方已公开:环境搭建

..Python

conda create -n unimate python=3.10 -y
conda activate unimate
pip install "setuptools<81"
pip install -r requirements.txt --no-build-isolation

示意代码 1:图感知注意力偏置(概念示意)

思路:用骨架树上的最短路径距离,给注意力分数加一个"距离惩罚"。

...Python

import torch
import torch.nn as nn
class GraphBiasedAttention(nn.Module):
def __init__(self, dim, heads=8):
super().__init__()
self.h = heads
self.qkv = nn.Linear(dim, dim * 3)
self.out = nn.Linear(dim, dim)
# 每个注意力头学一个"距离衰减"系数
self.dist_scale = nn.Parameter(torch.zeros(heads))

def forward(self, x, geo_dist):
# x: (B, J, D) J 个关节
# geo_dist: (B, J, J) 关节间的测地距离(沿骨架走的距离)
B, J, D = x.shape
q, k, v = self.qkv(x).chunk(3, dim=-1)
q, k, v = [t.view(B, J, self.h, -1).transpose(1, 2) for t in (q, k, v)]

attn = (q @ k.transpose(-1, -2)) / (q.shape[-1] ** 0.5)
# 离得越远,注意力越被压低(偏置对每个头可学习)
bias = -self.dist_scale.view(1, -1, 1, 1) * geo_dist.unsqueeze(1)
attn = (attn + bias).softmax(dim=-1)

out = (attn @ v).transpose(1, 2).reshape(B, J, D)
return self.out(out)

示意代码 2:用图拉普拉斯给骨架"编号"(概念示意)

思路:骨架没有"第几个",但图拉普拉斯的特征向量能给每个关节一个反映其结构位置的坐标,再用它去做类似 RoPE 的旋转。

...Python

import torch

def laplacian_positions(adj, k=8):
"""adj: (J, J) 骨架邻接矩阵 -> 每个关节的 k 维结构坐标"""
deg = torch.diag(adj.sum(-1))
L = deg - adj # 图拉普拉斯
eigvals, eigvecs = torch.linalg.eigh(L)
return eigvecs[:, 1:k + 1] # 去掉平凡的第 0 个特征向量

def spectral_rotary(x, pos, base=10000.0):
"""x: (J, D), pos: (J, K),用结构坐标代替序列下标做旋转"""
J, D = x.shape
K = pos.shape[1]
half = D // 2
# 把 D/2 个频率分配给 K 个谱坐标
freqs = base ** (-torch.arange(half) / half)
theta = pos[:, torch.arange(half) % K] * freqs # (J, half)
x1, x2 = x[..., :half], x[..., half:2 * half]
return torch.cat([x1 * theta.cos() - x2 * theta.sin(),
x1 * theta.sin() + x2 * theta.cos()], dim=-1)

说明:特征向量存在符号和重根的不确定性,真实实现需要额外处理,论文里应有更严谨的做法,这里只展示核心想法。

示意代码 3:"零样本"编辑的原理(概念示意)

论文提到,编辑、补间、续写都是同一个预训练模型,区别只在于采样时固定哪些动作 token。这和图像修复(inpainting)的思路很像:

...Python

@torch.no_grad()

def sample_with_constraint(model, skeleton, text, known, mask, steps=50):

"""

known: 已知动作(比如保留的头部转动 / 起止姿势)

mask : 1 表示"固定不动",0 表示"让模型自由生成"

"""

x = torch.randn_like(known)

for t in reversed(range(steps)):

x = model.denoise_step(x, t, skeleton, text) # 正常去噪一步

noisy_known = model.add_noise(known, t) # 把已知部分加同等噪声

x = mask * noisy_known + (1 - mask) * x # 已知部分"钉死"

return x

  • 动作编辑

    :mask 钉住头部关节,其余自由生成;

  • 动作补间

    :mask 钉住首尾帧;

  • 动作续写

    :mask 钉住上一段的末尾帧。

一个模型,三种玩法,这也是"统一基础模型"的魅力所在

想自己上手玩?

  • 交互式 Demo

    项目页提供网页版 3D 展示,可以直接拖拽旋转看结果,还支持拖入 .fbx / .glb / .gltf 文件预览

  • 数据集 UniML3D

    已在 Hugging Face 发布,配套数据处理代码已开源(MIT 协议)

  • 注意版权

    其中 Truebones 动物动作是商业素材包,不允许再分发,需要自行购买;Mixamo、Objaverse-XL 也各自遵循原有许可

  • 训练与推理代码

    :官方标注"即将发布"

最后

回到开头那个问题:怎么让一条蛇"走路"?

过去的答案是:找一个懂蛇的动画师,花几天。
UniMate 给出的新答案是:写一句话。

当然,距离"人人都能一键让万物起舞"还有一段路。但每一次让 AI 少一点"偏科",创作的门槛就低一点。

更多transformer,VIT,swin tranformer 参考头条号:人工智能研究所 v号:人工智能研究Suo, 启示AI科技

动画详解transformer 在线视频教程


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

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

立即咨询