AI4AnimationPy:用 Python 做 AI 驱动的角色动画

AI4AnimationPy:用 Python 做 AI 驱动的角色动画

Meta 开源了一个 Python 框架,把 AI 角色动画的训练、推理、可视化全部统一到一个环境里。不需要 Unity 了。

一、它是什么

AI4AnimationPy 是 Meta(Facebook Research)开源的 Python 框架,用于基于神经网络的角色动画。它是 AI4Animation(一个知名的 Unity 项目)的 Python 重写版,由原作者 Sebastian Starke 和 Paul Starke 开发。

核心思路:把动捕数据处理、神经网络训练、实时推理、动画可视化全部放在一个 Python 环境里完成,不再需要 Unity 作为中间环节。

项目地址:https://github.com/facebookresearch/ai4animationpy
文档:https://facebookresearch.github.io/ai4animationpy/
在线 Demo:https://paulstarke-ai4animationpy.hf.space/

二、为什么需要它

AI 角色动画的研究一直有一个痛点:工具链断裂

传统流程是这样的:

动捕数据 → Unity 处理特征提取 → 导出数据 → Python 训练模型 → 导出 ONNX → 回到 Unity 推理和可视化

这个来回切换的过程非常低效。原版 AI4Animation 在 Unity 中处理 20 小时的动捕数据需要 4 小时以上,搭建一个新实验需要 4 小时以上。

AI4AnimationPy 把这些全部统一了:

环节 AI4AnimationPy AI4Animation (Unity)
处理 20h 动捕数据 < 5 分钟 > 4 小时
搭建新实验 ~10 分钟 > 4 小时
训练时可视化输入/输出 内置支持 需要额外的数据流通信
反向传播穿过推理 ✅ 支持 ❌ 不可能
量化 完整 PyTorch 支持 仅 ONNX

一句话:研究迭代速度提升了一个数量级

三、核心特性

游戏引擎式架构(ECS)

虽然是 Python 框架,但它的架构设计借鉴了游戏引擎的 Entity-Component-System 模式:

生命周期回调跟 Unity 几乎一样:Start()Update()Draw()GUI()

动捕数据导入

支持三种主流格式,开箱即用:

内部统一存储为 .npz 格式(每帧每关节 3D 位置 + 4D 四元数)。

内置渲染器

基于 Raylib 的实时渲染管线,支持:

神经网络

内置多种网络架构:

三种运行模式

四、安装

环境准备

需要 Python 3.12+ 和 Conda。

macOS:

conda create -y -n AI4AnimationPY python=3.12 pip
conda activate AI4AnimationPY
pip install torch torchvision torchaudio onnx raylib numpy scipy matplotlib scikit-learn einops pygltflib pyscreenrec tqdm pyyaml ipython
pip install onnxruntime

Linux:

conda create -y -n AI4AnimationPY python=3.12 pip
conda activate AI4AnimationPY
pip install torch torchvision torchaudio onnx raylib numpy scipy matplotlib scikit-learn einops pygltflib pyscreenrec tqdm pyyaml ipython
pip install onnxruntime-gpu

Windows(带 CUDA):

conda create -n AI4AnimationPY python=3.12
conda activate AI4AnimationPY
pip install msvc-runtime==14.40.33807
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
pip install nvidia-cudnn-cu12==9.3.0.75 nvidia-cuda-runtime-cu12==12.5.82 nvidia-cufft-cu12==11.2.3.61
pip install onnxruntime-gpu==1.19.0

安装框架

git clone https://github.com/facebookresearch/ai4animationpy.git
cd ai4animationpy
pip install -e .

验证安装

# 无窗口模式验证
python Demos/Empty/Program.py

# 有窗口模式验证(会弹出一个渲染窗口)
python Demos/Actor/Program.py

五、快速上手

Hello World:最简程序

from ai4animation import AI4Animation


class Program:
    def Start(self):
        print("Hello World")

    def Update(self):
        pass

    def Draw(self):
        pass

    def GUI(self):
        pass


if __name__ == "__main__":
    AI4Animation(Program(), mode=AI4Animation.Mode.HEADLESS)

引擎会调用一次 Start(),然后无限循环 Update()。把 HEADLESS 换成 STANDALONE 就会打开一个渲染窗口。

加载角色模型

from ai4animation import Actor, AI4Animation, Rotation, Time, Vector3


class Program:
    def Start(self):
        entity = AI4Animation.Scene.AddEntity("Actor")
        self.Actor = entity.AddComponent(Actor, "path/to/character.glb")
        self.Actor.Entity.SetPosition(Vector3.Create(0, 0, 0))

    def Update(self):
        self.Actor.Entity.SetRotation(Rotation.Euler(0, 120 * Time.TotalTime, 0))
        self.Actor.SyncFromScene()


if __name__ == "__main__":
    AI4Animation(Program(), mode=AI4Animation.Mode.STANDALONE)

这会在窗口中显示一个持续旋转的 3D 角色。

导入动捕数据

from ai4animation import Motion

# 从不同格式加载
motion = Motion.LoadFromGLB("character.glb")
motion = Motion.LoadFromBVH("character.bvh", scale=0.01)  # BVH 通常是厘米,需要缩放

# 保存为内部格式
motion.SaveToNPZ("character")

# 从内部格式加载
motion = Motion.LoadFromNPZ("character.npz")

批量转换整个目录:

convert --input_dir path/to/motions --output_dir path/to/output --skeleton Cranberry

播放动画

from ai4animation import (
    AI4Animation, ContactModule, Dataset, MotionEditor,
    MotionModule, GuidanceModule, RootModule,
)


class Program:
    def Start(self):
        editor = AI4Animation.Scene.AddEntity("MotionEditor")
        editor.AddComponent(
            MotionEditor,
            Dataset(
                "path/to/npz/folder",
                [
                    lambda x: RootModule(x, "Hips", "LeftUpLeg", "RightUpLeg", "LeftArm", "RightArm"),
                    lambda x: MotionModule(x),
                    lambda x: ContactModule(x, [
                        ("LeftFoot", 0.1, 0.25),
                        ("LeftToeBase", 0.05, 0.25),
                        ("RightFoot", 0.1, 0.25),
                        ("RightToeBase", 0.05, 0.25),
                    ]),
                    lambda x: GuidanceModule(x),
                ],
            ),
            "path/to/character.glb",
            bone_names,
        )
        AI4Animation.Standalone.Camera.SetTarget(editor)

    def Update(self):
        pass


if __name__ == "__main__":
    AI4Animation(Program())

MotionEditor 提供了一个 GUI 时间轴,可以拖动浏览动画片段,同时可视化各个 Module 提取的特征(根轨迹、脚部接触、引导信号等)。

六、训练神经网络

这是框架最核心的价值——训练和可视化在同一个环境里。

完整训练流程

Dataset(加载 .npz)→ DataSampler(采样批次)→ FeedTensor(组装输入)
    → Network(前向传播)→ ReadTensor(读取输出)→ Loss → Optimizer

示例:训练一个 MLP

import numpy as np
import torch
from ai4animation import AdamW, AI4Animation, CyclicScheduler, MLP, Plotting, Tensor


class Program:
    def Start(self):
        self.Network = Tensor.ToDevice(
            MLP.Model(input_dim=1, output_dim=100, hidden_dim=128, dropout=0.1)
        )
        self.Optimizer = AdamW(self.Network.parameters(), lr=1e-4, weight_decay=1e-4)
        self.Scheduler = CyclicScheduler(
            optimizer=self.Optimizer,
            batch_size=32, epoch_size=320,
            restart_period=10, t_mult=2, policy="cosine", verbose=True,
        )
        self.LossHistory = Plotting.LossHistory("Loss", drawInterval=500, yScale="log")
        self.Trainer = self.Training()

    def Update(self):
        try:
            next(self.Trainer)
        except StopIteration:
            pass

    def Training(self):
        for epoch in range(1, 151):
            for _ in range(10):
                x = np.random.uniform(0, 1, (32, 1)).astype(np.float32)
                y = (np.linspace(-1, 1, 100).reshape(1, -1) ** 2) * x

                xBatch = Tensor.ToDevice(torch.tensor(x))
                yBatch = Tensor.ToDevice(torch.tensor(y))

                _, losses = self.Network.learn(xBatch, yBatch, epoch == 1)
                self.Optimizer.zero_grad()
                sum(losses.values()).backward()
                self.Optimizer.step()
                self.Scheduler.batch_step()

                for k, v in losses.items():
                    self.LossHistory.Add((Plotting.ToNumpy(v), k))
                yield

            self.Scheduler.step()
            self.LossHistory.Print()


if __name__ == "__main__":
    AI4Animation(Program(), mode=AI4Animation.Mode.STANDALONE)

关键设计:Training() 是一个 generator,每个 batch 后 yield 一次,让引擎有机会更新渲染。这样你可以在 Standalone 模式下实时看到训练过程中的 loss 曲线和动画效果。

导出模型

训练完成后导出为 ONNX 用于部署:

from ai4animation import Utility, ONNXNetwork

# 导出
Utility.SaveONNX(network, input_dim, "model.onnx")

# 推理
model = ONNXNetwork("model.onnx")
output = model.Run(input_tensor)

七、可用的公开数据集

框架兼容多个公开动捕数据集:

数据集 角色 格式 说明
Cranberry Cranberry FBX & GLB SIGGRAPH 2024 论文配套
100Style retargeted Geno BVH / FBX 100 种风格化运动
LaFan Ubisoft LaFan BVH Ubisoft 开源动捕数据
ZeroEggs retargeted Geno BVH / FBX 语音驱动手势
Motorica retargeted Geno BVH / FBX 多样化运动
NSM Anubis BVH 场景交互运动
MANN Dog BVH 四足动物运动

八、内置 Demo

项目自带多个交互式 Demo,都在 Demos/ 目录下:

Demo 说明
Biped Locomotion 基于 100Style 数据集训练的风格化双足运动控制器
Quadruped 四足动物(狗)运动控制,支持步态切换和动作姿势
Training 未来运动预测的交互式训练可视化
ECS Entity 层级和组件系统演示
IK 实时逆运动学(FABRIK)求解
MocapImport GLB/FBX/BVH 动捕数据导入
MotionEditor 动画浏览和特征可视化编辑器

运行方式:

python Demos/Locomotion/Program.py
python Demos/Quadruped/Program.py
python Demos/IK/Program.py

也可以直接在浏览器里体验 Web Demo:https://paulstarke-ai4animationpy.hf.space/

九、架构速览

ai4animation/
├── AI4Animation.py          # 引擎入口
├── Scene.py                 # 场景管理
├── Entity.py                # 场景图节点
├── Components/
│   ├── Actor.py             # 骨骼角色
│   ├── MotionEditor.py      # 动画播放 UI
│   └── MeshRenderer.py      # 静态网格渲染
├── Animation/
│   ├── Motion.py            # 帧数据 + 骨骼层级
│   ├── Dataset.py           # NPZ 文件加载
│   ├── RootModule.py        # 根轨迹
│   ├── ContactModule.py     # 脚部接触检测
│   ├── MotionModule.py      # 全身轨迹
│   └── GuidanceModule.py    # 姿态引导
├── Math/
│   ├── Tensor.py            # NumPy/PyTorch 双后端
│   ├── Quaternion.py        # 四元数运算
│   └── Vector3.py           # 3D 向量运算
├── AI/
│   ├── DataSampler.py       # 多线程批次生成
│   ├── Networks/            # MLP、AE、Flow 等
│   ├── FeedTensor.py        # 输入缓冲
│   ├── ReadTensor.py        # 输出缓冲
│   └── ONNXNetwork.py       # ONNX 推理
├── Import/
│   ├── GLBImporter.py       # GLB 解析
│   ├── BVHImporter.py       # BVH 解析
│   └── BatchConverter.py    # CLI 批量转换
├── IK/
│   └── FABRIK.py            # 逆运动学求解器
└── Standalone/
    ├── RenderPipeline.py    # 延迟渲染管线
    ├── Camera.py            # 相机系统
    └── SkinnedMesh.py       # GPU 骨骼蒙皮

八层架构:Engine → ECS → Animation → Math → AI → Import → Rendering → IK,每层职责清晰,可以独立使用。

十、适合谁

不适合的场景:如果你需要的是生产级游戏引擎集成,目前还是用原版 AI4Animation(Unity)更合适。AI4AnimationPy 的定位是研究和快速迭代。

十一、相关资源


最后更新:2026-04-21