一、项目背景
最近在看数字人相关内容,找到这个项目,JoyVASA 是京东健康(JD Health International Inc.)与浙江大学联合开源的扩散模型驱动的音频→肖像动画框架,论文:
JoyVASA: Portrait and Animal Image Animation with Diffusion-Based Audio-Driven Facial Dynamics and Head Motion Generation
它解决的是单张静态图 + 一段音频 → 一段会说话、有表情、会点头的视频,论文侧重点是长视频的稳定性与多类主体(人/动物)的统一建模。
- 音频驱动 ------ 仅需一张参考图 + 一段音频,自动生成唇形同步
- 真人肖像动画 ------ 写实人像说话视频
- 动物肖像动画 ------ 猫、狗等动物面部说话动画
- 多语种适配 ------ 训练数据为私有中文 + 公开英文混合,中英文都可用
- 长视频稳定 ------ 滑动窗口推理,避免长序列崩坏
二、技术原理
JoyVASA 不是端到端直接出视频,而是两阶段解耦的:

┌─────────────────────────────────────────────────────────────┐
│ Stage 1: 离线/一次性 - 训练解耦的人脸表征 │
│ (LivePortrait 提供 appearance encoder + motion encoder) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Stage 2: 推理时 - 扩散 Transformer 采样运动序列 │
│ audio features (HuBERT/wav2vec2) → motion sequences │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Warping + Generator - 用采样到的关键点 warp 表征,渲染出视频 │
└─────────────────────────────────────────────────────────────┘
2.1 解耦面部表征(Decoupled Facial Representation)
参考图 → appearance encoder(LivePortrait)提取静态 3D 面部外观特征
参考图 → motion encoder 提取 3D 关键点
这一拆分的好处:外观与运动解耦,任意静态 3D 表征都能和任意运动序列组合,所以长视频可以分段生成运动、复用同一张外观,天然解决帧间连续性问题。
2.2 扩散 Transformer 生成运动
音频 → 音频编码器(chinese-hubert-base 适配中文) → 音频特征
音频特征 → DiT(Diffusion Transformer) 滑动窗口采样 → 目标运动序列
identity-independent:运动生成不依赖人物身份,所以同一段运动可以驱动不同的人/动物。
2.3 渲染
源关键点 + 采样到的目标关键点 → 计算变形场 → warp appearance feature → generator → 视频帧。
三、环境准备
3.1 硬件与系统(官方已测试)
| 平台 | 系统 | CUDA | 显卡 |
|---|---|---|---|
| Linux | Ubuntu 20.04 | 12.1 | A100 |
| Windows | Windows 11 | 12.1 | RTX 4060 Laptop 8GB |
实际社区反馈:RTX 3090 / 4090 / 4090D 都能跑,显存建议 ≥ 8GB。
3.2 软件依赖
bash
# 1. 基础环境
conda create -n joyvasa python=3.10 -y
conda activate joyvasa
# 2. Python 依赖
pip install -r requirements.txt
# 3. 系统依赖 ffmpeg
sudo apt-get update
sudo apt-get install ffmpeg -y
# 4. 可选:仅当你需要跑 animal 模式时
cd src/utils/dependencies/XPose/models/UniPose/ops
python setup.py build install
cd -
MultiScaleDeformableAttention不是pip install,而是要进子目录setup.py源码编译。这是新手最常踩的坑之一。
3.3 源码克隆
bash
git clone https://github.com/jdh-algo/JoyVASA.git
cd JoyVASA
四、权重下载
这是全网最容易出错的地方。原仓库默认目录名是 pretrained_weights/,不是 checkpoints/。整套项目需要 5 套权重:
4.1 JoyVASA 主模型
bash
mkdir -p pretrained_weights
cd pretrained_weights
git lfs install
git clone https://huggingface.co/jdh-algo/JoyVASA
cd ..
4.2 音频编码器
bash
cd pretrained_weights
# 中文 HuBERT
git clone https://huggingface.co/TencentGameMate/chinese-hubert-base
# 可选:wav2vec2-base
# git clone https://huggingface.co/facebook/wav2vec2-base-960h
cd ..
4.3 LivePortrait 权重
bash
cd pretrained_weights
# 方法 A:huggingface_hub CLI
pip install -U "huggingface_hub[cli]"
huggingface-cli download KwaiVGI/LivePortrait \
--local-dir . \
--exclude "*.git*" "README.md" "docs"
cd ..
4.4 InsightFace buffalo_l 模型
bash
# 一般随 huggingface-cli 下载 LivePortrait 时会自动包含
# 若缺失,自行:
mkdir -p pretrained_weights/insightface/models/buffalo_l
# 从 insightface 官方源或 LivePortrait 仓库的对应位置取
# 2d106det.onnx、det_10g.onnx 是关键文件
4.5 最终目录结构(官方要求)
JoyVASA/
./pretrained_weights/
├── insightface
│ └── models
│ └── buffalo
│ ├── 2d106det.onnx
│ └── det_10g.onnx
├── JoyVASA
│ ├── motion_generator
│ │ └── iter_0020000.pt
│ └── motion_template
│ └── motion_template.pkl
├── liveportrait
│ ├── base_models
│ │ ├── appearance_feature_extractor.pth
│ │ ├── motion_extractor.pth
│ │ ├── spade_generator.pth
│ │ └── warping_module.pth
│ ├── landmark.onnx
│ └── retargeting_models
│ └── stitching_retargeting_module.pth
├── liveportrait_animals
│ ├── base_models
│ │ ├── appearance_feature_extractor.pth
│ │ ├── motion_extractor.pth
│ │ ├── spade_generator.pth
│ │ └── warping_module.pth
│ ├── retargeting_models
│ │ └── stitching_retargeting_module.pth
│ └── xpose.pth
├── TencentGameMate:chinese-hubert-base
│ ├── chinese-hubert-base-fairseq-ckpt.pt
│ ├── config.json
│ ├── gitattributes
│ ├── preprocessor_config.json
│ ├── pytorch_model.bin
│ └── README.md
└── wav2vec2-base-960h
│ ├── config.json
│ ├── feature_extractor_config.json
│ ├── model.safetensors
│ ├── preprocessor_config.json
│ ├── pytorch_model.bin
│ ├── README.md
│ ├── special_tokens_map.json
│ ├── tf_model.h5
│ ├── tokenizer_config.json
│ └── vocab.json
├── src/
├── inference.py
├── app.py
├── requirements.txt
└── train.py
五、三种运行方式
5.1 命令行推理(inference.py)
5.1.1 真人模式
bash
python inference.py \
-r assets/examples/imgs/joyvasa_003.png \
-a assets/examples/audios/joyvasa_003.wav \
--animation_mode human \
--cfg_scale 2.0
joyvasa_003_joyvasa_003
5.1.2 动物模式
bash
python inference.py \
-r assets/examples/imgs/joyvasa_001.png \
-a assets/examples/audios/joyvasa_001.wav \
--animation_mode animal \
--cfg_scale 2.0
5.1.3 短命令 vs 全命令
| 短 | 全 | 说明 |
|---|---|---|
-r |
--reference |
参考图 |
-a |
--audio |
驱动音频 |
--animation_mode |
human / animal |
|
--cfg_scale |
表情强度 | |
--driving_option |
expression-friendly / pose-friendly |
|
--driving_multiplier |
运动幅度倍率 | |
--flag_normalize_lip |
是否归一化唇形 | |
--flag_relative_motion |
是否相对运动 | |
--do_crop / --scale / --vx_ratio / --vy_ratio |
裁剪控制 |
5.2 WebUI(app.py)
bash
python app.py
启动后浏览器打开:
http://127.0.0.1:7862 ← 注意是 7862,不是 7860
WebUI 包含三大区:
- Input Section:上传参考图 + 音频
- Configuration Section:动画模式、CFG、裁剪、归一化
- Generate Button + 输出视频
Gradio 默认端口是 7860,但官方
app.py写的是 7862,这是为了避免和 LivePortrait 等同生态项目冲突。
六、参数详解
6.1 关键参数
| 参数 | 官方说明 | 默认 | 范围 |
|---|---|---|---|
animation_mode |
动画模式 | human |
human / animal |
cfg_scale |
表情强度 | 4.0 | 0.0 ~ 10.0 |
driving_option |
驱动风格 | expression-friendly |
expression-friendly / pose-friendly |
driving_multiplier |
运动强度倍率 | 1.0 | 0.0 ~ 2.0 |
flag_normalize_lip |
唇形归一化 | True | True/False |
flag_relative_motion |
相对运动 | True | True/False |
flag_remap_input |
贴回原图 | True | True/False |
flag_stitching_input |
拼接模块 | True | True/False |
do_crop |
是否裁剪 | True | True/False |
scale |
裁剪缩放 | 2.3 | 1.8 ~ 4.0 |
vx_ratio |
横向裁剪偏移 | 0.0 | -0.5 ~ 0.5 |
vy_ratio |
纵向裁剪偏移 | -0.125 | -0.5 ~ 0.5 |
cfg_scale推荐 1.5~2.5,官方源码默认值是 4.0,实测 2.0~4.0 出自然结果,>5 表情夸张、<1.5 表情平淡。
6.2 参数作用图谱
┌──────────────────┐
│ cfg_scale │
│ ↑ 更夸张 │
│ ↓ 更含蓄 │
└──────────────────┘
↕
animation_mode ──► human / animal pipeline 选择
↕
┌────────────────────┐ ┌────────────────────┐
│ driving_option │ │ driving_multiplier │
│ expression-friendly│ │ ↑ 运动更明显 │
│ pose-friendly │ │ ↓ 运动更轻微 │
└────────────────────┘ └────────────────────┘
裁剪三件套(scale / vx_ratio / vy_ratio) ──► 控制人脸在画面中的取景位置
6.3 调参经验值
| 目标 | 推荐参数组合 |
|---|---|
| 自然口播 | cfg_scale=2.0 driving_option=expression-friendly driving_multiplier=1.0 |
| 头部动作多 | driving_option=pose-friendly driving_multiplier=1.3 |
| 夸张表情(主播风格) | cfg_scale=4.0~5.0 driving_multiplier=1.5 |
| 几乎不动(配静态BGM) | cfg_scale=1.0 driving_multiplier=0.5 |
七、输入素材规范
7.1 图片
| 项 | 建议 |
|---|---|
| 主体 | 单一人物或单一动物面部 |
| 角度 | 正面 / 轻微侧脸最佳,大侧脸容易崩 |
| 清晰度 | 面部无遮挡、无重度美颜、无糊脸 |
| 分辨率 | ≥ 512×512,过低影响关键点提取 |
| 动物 | 眼睛、嘴部必须清晰可见 |
7.2 音频
| 项 | 建议 |
|---|---|
| 格式 | WAV PCM 16-bit |
| 采样率 | 16 kHz 单声道(官方最优) |
| 时长 | 任意,内部用滑动窗口 |
| 质量 | 人声清晰、低背景噪音、无明显混响 |
格式转换示例:
bash
ffmpeg -i input.mp3 -vn -ar 16000 -ac 1 -c:a pcm_s16le output.wav
八、能力边界
官方明确擅长
- 真人 / 猫狗等动物面部说话动画
- 中英文双语文本驱动
- 唇形同步质量高、表情自然
- 长视频通过滑动窗口稳定推理
- 轻量级、依赖干净、MIT 可商用
官方不擅长 / 文档未声明
- 大幅转头、大幅肢体动作
- 复杂背景动态、镜头运镜
- 多人 / 多动物同时动画
- 二次元 / 插画肖像(虽然
human模式勉强能跑,但官方未声明) - 实时推理(论文自述:real-time 是 future work)
- 水印、溯源、防深伪(没有任何机制)
⚠️ 商用合规提醒
- MIT 协议本身允许商用,但 依赖项(LivePortrait、wav2vec2、HuBERT)各自的协议需要单独核查
- 训练数据含京东私有中文数据 + 公开英文数据,商业化前建议法务审一遍数据来源
九、常见问题与排查
| 现象 | 原因 | 解决 |
|---|---|---|
ModuleNotFoundError: MultiScaleDeformableAttention |
animal 模式必装,源码编译 | 跑 src/utils/dependencies/XPose/models/UniPose/ops 下 setup.py build install |
ffmpeg: command not found |
缺系统依赖 | apt-get install ffmpeg |
| WebUI 打开 7860 端口空白 | 端口错了 | 实际是 7862 |
cfg_scale=2 表情仍夸张 |
误用全音轨 wav,采样率不是 16k | 用 ffmpeg 转 16k mono wav |
动物图跑 human 模式脸崩 |
mode 不匹配 | --animation_mode animal |
| 推理非常慢 | 缺 CUDA / 用 CPU 跑 | 必须有 NVIDIA GPU + CUDA 12.x |
| 生成的视频没声音 | 这是正常的 | inference.py 只输出画面,声音需自己用 ffmpeg 合回 |
把声音合回的官方习惯做法:
bash
ffmpeg -i generated_video.mp4 -i input.wav -c:v copy -c:a aac final.mp4
十、总结
JoyVASA 把音频驱动肖像动画这件事,做到了一个比较舒服的折中点:
- 架构上用LivePortrait 解耦表征 + DiT 扩散生成运动的两阶段设计,绕开了端到端扩散模型长视频崩坏的硬伤。
- 生态上原生支持动物、中文友好、MIT 协议、依赖干净,部署门槛低。
- 能力上对自然表情 + 唇形同步 + 轻点头这一档需求,目前是开源里做得比较像样的。
- 取舍上明确不追求大幅动作、镜头运镜、实时性,这些是显式不擅长。