AniPortrait 出自腾讯游戏知几团队(Huawei Wei、Zejun Yang、Zhisheng Wang),论文是 arXiv:2403.17694《AniPortrait: Audio-Driven Synthesis of Photorealistic Portrait Animation》,代码在 github.com/Zejun-Yang/AniPortrait,Apache-2.0。它的做法分两段:先用 wav2vec2-base-960h 把音频编码成特征,经 audio2mesh 还原成 3D 面部网格、经 audio2pose 生成头部位姿,投影成 2D 关键点序列;再把这串关键点当作条件,喂给一套 Stable Diffusion v1.5 改造的扩散管线——reference UNet 抓参考图外观、denoising UNet 挂 AnimateDiff 式运动模块保时序连贯、pose guider 注入关键点。代码谱系上它承认借了 Moore-AnimateAnyone、AnimateDiff、magic-animate 和 EMO 的思路。
落到显存上,这套结构的账很清楚。官方权重仓库 ZJYang/AniPortrait 里 denoising_unet.pth 和 reference_unet.pth 各 3.44GB、motion_module.pth 1.82GB、pose_guider.pth 670MB、audio2pose.pt 482MB、audio2mesh.pt 382MB、film_net_fp16.pt 69MB,合计约 10.3GB,另外还要拉 SD 1.5 底模、sd-vae-ft-mse、1.22GB 的 image_encoder 和 wav2vec2-base-960h。配置里 weight_dtype 是 fp16,所以常驻显存大致是磁盘体积折半后的 7GB 量级。仓库 issue #130 记录了 10GB 卡直接 CUDA OOM(10.00 GiB 总量、8.97 GiB 已分配时崩)。更要命的是它会随片长涨:pipeline_pose2vid_long 用 16 帧滑窗、重叠 4 帧推理,但整段 latent 和整段 pose 条件张量常驻 GPU,VAE 还逐帧解码后在显存里拼接——60 秒 30fps 就是 1800 帧,光这两块就多吃 8GB 左右。
还有个事实得直说:这个仓库最后一次提交停在 2024 年 7 月 2 日,更新日志止于 2024/04/21 放出 audio2pose 权重。这两年同赛道跑出了 Sonic(CVPR 2025,单张 32G 卡实测,但 CC BY-NC-SA 4.0 不可商用)、EchoMimicV3(蚂蚁集团 1.3B,量化后 12G 显存跑 768×768)、腾讯混元 HunyuanVideo-Avatar(704×768×129 帧最低 24GB,接 TeaCache 后 10GB 可跑)、复旦与百度的 Hallo3(CogVideoX-5B I2V 微调,实测 H100)。AniPortrait 今天仍然被大量部署,理由很实在:Apache-2.0、SD1.5 底座、依赖固化、单卡 24GB 就能全流程跑通,是同类里最容易在自有 GPU 上复现的一套。你要做的只是找一张对的卡——这正是 NexGPU 存在的意义:1,175 个已验证节点、2,498 张 GPU、75 种型号,按秒计费,跑完就停。
01 —
四条推理路径与两段训练,分别吃多少显存
AniPortrait 不按版本号发布,实际要选的是运行模式与权重组合
| 版本 | 参数量 | 显存 | 上下文 | 说明 |
|---|---|---|---|---|
| scripts.audio2vid(音频驱动) | SD1.5 UNet 0.86B ×2 + 运动模块 + wav2vec2-base-960h | fp16 常驻约 7GB;512×512 十秒片建议 16GB 起、24GB 舒适;10GB 实测 OOM | 16 帧滑窗 / 重叠 4 帧,运动模块时序位置编码上限 32 | 主线用法:一张参考图 + 一段 wav 出说话视频。默认 --steps 25、--cfg 3.5、--seed 42、-W 512 -H 512。 |
| scripts.vid2vid(面部重演 face reenactment) | 同上,外加 MediaPipe 468 点面部网格提取 | 与 audio2vid 同级;显存随源视频总帧数线性增长 | 输出跟随源视频原始 fps,可用 --fps 覆盖 | 2024/04/02 加的姿态重定向:先按参考图初始位移归一化源姿态,再做 3 帧窗口平滑,参考图与驱动视频头位差别大时也能跟。 |
| scripts.pose2vid(self-driven 姿态序列驱动) | pose_guider 670MB + denoising UNet | 与 audio2vid 同级,省掉 audio2mesh / audio2pose 的约 0.9GB | 16 帧滑窗,context_batch_size 默认 1 | 已有关键点序列时直接驱动,跳过整条音频链路,做批量重渲染或 A/B 对照最省。 |
| audio2pose.pt(头部位姿模型) | 482MB 独立权重 | 已计入上面的 7GB 常驻 | 逐帧生成头部欧拉角与位移 | 2024/04/21 才放出,且默认不启用——必须把 animation_audio.yaml 里的 pose_temp 项删掉,否则走的是 head_pose_temp/pose_temp.npy 固定模板,头部动作千篇一律。 |
| -acc + film_net_fp16.pt(FILM 插帧加速) | 69MB 插帧网络 | 额外不到 1GB | fi_step 默认 3,扩散只算三分之一帧,其余插出来 | 2024/04/07 加的加速路径。出片时间大致降到三分之一,代价是快速唇动细节会被抹平,做终稿时建议关掉。 |
| train_stage_1 / train_stage_2(自有数据微调) | 阶段一训 reference UNet + denoising UNet + pose guider;阶段二只训运动模块 | 80GB 级。阶段一 train_bs 2 @512²;阶段二 train_bs 1 × 16 帧,已开 gradient checkpointing 与 8-bit Adam | sample_n_frames 16,sample_size [512, 512] | max_train_steps 分别是 300000 与 40000,阶段二额外要 mm_sd_v15_v2.ckpt。issue #208 里多张 4090 微调仍然 OOM——这活儿老实上 80GB 卡。 |
02 —
该租哪张卡:按片长和用途选,别按直觉选
AniPortrait 的依赖钉在 torch 2.0.1 / CUDA 11.7,卡的新旧不等于好用
跑通全流程、十秒量级样片反复调参
RTX 3090 24GB$0.193/卡·时
Ampere sm_86 被 torch 2.0.1 原生覆盖,requirements.txt 原样装就能跑,24GB 给 16 帧上下文窗和整段条件张量留足余量。
一分钟以上长音频一次成片,不想切段拼接
RTX A6000 48GB$0.817/卡·时
显存随帧数线性涨,1800 帧的 pose 条件张量加逐帧 VAE 解码结果就要多吃 8GB 左右,48GB 让你不用为了显存去改管线。
批量出片、跑量优先、单价压到最低
Tesla V100 32GB$0.188/卡·时
sm_70 在 CUDA 11.7 里是完整支持的老架构,管线本来就是 fp16 不需要 bf16;32GB 比 3090 还多 8GB,单价却是全站最低。
stage-1 / stage-2 微调自有形象数据
A100 SXM4 80GB$1.088/卡·时
阶段二每步要吃下 16 帧时序窗口,开了梯度检查点和 8-bit Adam 仍然把多张 4090 撑爆,80GB 是能安心跑的起点。
03 —
从开机到出第一条视频,四步
用 PyTorch 预置镜像开机,避开 README 里已经过期的两个坑
- 01
开一台 3090,拉代码装依赖
选 Python 3.10 以上、CUDA 11.7 的 PyTorch 镜像开机,SSH 进去。requirements.txt 钉得很死:torch==2.0.1、torchvision==0.15.2、xformers==0.0.22、diffusers==0.24.0、transformers==4.30.2、numpy==1.24.4、mediapipe==0.10.11。别顺手升级 numpy 到 2.x,mediapipe 和 decord 都会当场炸。
git clone https://github.com/Zejun-Yang/AniPortrait && cd AniPortrait && pip install -r requirements.txt - 02
拉 10.3GB 自有权重 + 底模
官方权重从 ZJYang/AniPortrait 一次拉全。底模这里有个 README 没更新的坑:它写的 runwayml/stable-diffusion-v1-5 已经从 HuggingFace 下架,改用社区镜像 stable-diffusion-v1-5/stable-diffusion-v1-5。另外还要 sd-vae-ft-mse、lambdalabs/sd-image-variations-diffusers 里的 image_encoder(1.22GB)和 facebook/wav2vec2-base-960h,全部按 README 的目录树摆进 ./pretrained_model/。
huggingface-cli download ZJYang/AniPortrait --local-dir ./pretrained_model && huggingface-cli download stable-diffusion-v1-5/stable-diffusion-v1-5 --local-dir ./pretrained_model/stable-diffusion-v1-5 - 03
跑音频驱动,先出一条十秒样片
把参考图和 wav 路径写进 configs/prompts/animation_audio.yaml 的 test_cases。想要头部自然摆动就删掉配置里的 pose_temp 项启用 audio2pose,留着它就是固定模板动作。-L 控制帧数,30fps 下 300 帧正好十秒;-acc 走 FILM 插帧,出片快三倍,终稿时去掉。
python -m scripts.audio2vid --config ./configs/prompts/animation_audio.yaml -W 512 -H 512 -L 300 -acc - 04
起 Gradio 交互调参,或换成面部重演
scripts.app 会拉起官方 Gradio 界面,适合让不写代码的同事自己试参考图。要做面部重演就换 vid2vid,它会用 MediaPipe 提源视频的 3D 关键点再重定向到参考脸上。调完参数把实例停掉,算力计费立刻停止,权重留在存储里下次直接开机接着用。
python -m scripts.app
一条十秒数字人视频,到底花多少钱
按 RTX 3090 24GB $0.193/卡·时算。第一步装环境加拉 10.3GB 权重与约 5GB 底模,走完大约 0.5 小时 → 0.5 × $0.193 = $0.097。接着调参:假设一条 10 秒(300 帧,开 -acc 后扩散实算约 100 帧、25 步、cfg 3.5)在 3090 上耗时 6 分钟——这个数你上机后自己测一遍再定——连跑 30 条样片就是 3 小时 → 3 × $0.193 = $0.579。两步合计 $0.676,六毛八美金,你已经拿到 30 条可用素材,摊到每条约 $0.023。要跑量的话,10 条/小时意味着单条成本 $0.0193,出 1000 条约 $19.3。长音频换 RTX A6000 48GB $0.817/卡·时,一分钟音频一次成片按 35 分钟估 → 0.583 × $0.817 ≈ $0.476/条,省掉切段拼接的返工时间。别忘了两项尾巴:权重加依赖占盘约 25GB,存储 $0.414/GB·月 → 25 × 0.414 = $10.35/月,实例停机后算力停止计费但存储继续算,不用了就销毁;成片外传按 $0.0081/GB,1000 条 512×512 MP4 大约 2GB → 约 $0.016,可以忽略。整套跑下来,比你为这事单独买一张卡便宜两个数量级。
04 —
