init
This commit is contained in:
@@ -0,0 +1,517 @@
|
||||
# 数字人视频生成 — 研究与验证记录
|
||||
|
||||
> 本文档记录了从零开始探索「单图 + 音频 → 说话视频」的完整过程,
|
||||
> 包括工具选型、环境踩坑、最终跑通的完整流程,以及对产品化的建议。
|
||||
>
|
||||
> 日期:2026-03-25
|
||||
> 硬件:RTX 5090 (Blackwell, sm_120), CUDA 12.9, WSL2
|
||||
|
||||
---
|
||||
|
||||
## 一、目标
|
||||
|
||||
给定一张人物图片和一段音频,生成该人物"说话"的视频:
|
||||
- 嘴型与音频内容同步
|
||||
- 头部有自然动作(非僵硬的照片)
|
||||
- 可扩展至实时/直播场景
|
||||
|
||||
---
|
||||
|
||||
## 二、工具选型过程
|
||||
|
||||
### 2.1 最初方向:LivePortrait
|
||||
|
||||
- **项目**:https://github.com/KlingTeam/LivePortrait(快手)
|
||||
- **本质**:视频驱动的人脸动画,需要一个"驱动视频"来控制人物表情和头部运动
|
||||
- **误区澄清**:网上有描述称 LivePortrait 支持"音频驱动",这是**不准确的**。它只能从驱动视频中提取音频附加到输出,无法用音频生成嘴型
|
||||
- **结论**:LivePortrait 适合生成头部动作底片,不能单独完成任务
|
||||
|
||||
### 2.2 调研其他工具
|
||||
|
||||
| 工具 | 厂商 | 核心能力 | 实时性 | 结论 |
|
||||
|------|------|---------|--------|------|
|
||||
| LatentSync 1.6 | 字节跳动 | 扩散模型唇形同步,512x512 | ❌ 约4fps | 质量好,但太慢 |
|
||||
| MuseTalk 1.5 | 腾讯 | 单步推理唇形同步 | ⚠️ 约7fps | 速度可接受,质量好 |
|
||||
| Live Avatar | 阿里 | 140B 扩散模型 | ❌ 需集群 | 单卡不可行 |
|
||||
| SadTalker | 开源 | 音频驱动全脸动画 | ❌ | 未测试 |
|
||||
| Sonic | 腾讯 | 音频驱动 | 未知 | 项目在 `/home/xsl/work/Sonic`,未测试 |
|
||||
|
||||
### 2.3 最终方案
|
||||
|
||||
**两阶段流水线:**
|
||||
|
||||
```
|
||||
hairstyle-result.jpg
|
||||
↓
|
||||
[LivePortrait] ← 驱动视频 (d3.mp4, 自然头部动作)
|
||||
↓
|
||||
头动底片视频 (hairstyle-result--d3.mp4, 11.8s)
|
||||
↓
|
||||
[MuseTalk] ← 音频 (test_speech_10s.wav)
|
||||
↓
|
||||
最终视频 (嘴型同步 + 头部运动)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、环境配置(重要踩坑记录)
|
||||
|
||||
### 3.1 RTX 5090 的核心问题
|
||||
|
||||
RTX 5090 是 Blackwell 架构(sm_120),**PyTorch 稳定版(2.6 及以下)不支持**。
|
||||
所有项目都必须使用 PyTorch nightly cu128:
|
||||
|
||||
```bash
|
||||
pip install --pre torch torchvision torchaudio \
|
||||
--index-url https://download.pytorch.org/whl/nightly/cu128
|
||||
# 已验证版本:torch-2.12.0.dev20260324+cu128
|
||||
```
|
||||
|
||||
**这是最先要做的事,否则所有 CUDA 推理都会报错:**
|
||||
```
|
||||
CUDA error: no kernel image is available for execution on the device
|
||||
```
|
||||
|
||||
### 3.2 HuggingFace CLI 命令名
|
||||
|
||||
在某些 conda 环境中,命令名是 `hf` 而不是 `huggingface-cli`:
|
||||
|
||||
```bash
|
||||
which hf # /home/xsl/miniconda3/envs/MuseTalk/bin/hf
|
||||
hf --version # 1.7.2
|
||||
```
|
||||
|
||||
下载需要 Token:
|
||||
```bash
|
||||
export HF_TOKEN=<your_token>
|
||||
hf download <repo> <file> --local-dir <dir>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、LivePortrait 部署
|
||||
|
||||
### 4.1 环境
|
||||
|
||||
```bash
|
||||
conda create -n LivePortrait python=3.10 -y
|
||||
conda activate LivePortrait
|
||||
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu128
|
||||
cd /home/xsl/work/LivePortrait
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 4.2 权重
|
||||
|
||||
```bash
|
||||
# 约 1.1GB
|
||||
huggingface-cli download KlingTeam/LivePortrait \
|
||||
--local-dir pretrained_weights \
|
||||
--exclude "*.git*" "README.md" "docs"
|
||||
```
|
||||
|
||||
目录结构:
|
||||
```
|
||||
pretrained_weights/
|
||||
├── insightface/ (~21MB)
|
||||
├── liveportrait/ (~608MB)
|
||||
└── liveportrait_animals/ (~500MB)
|
||||
```
|
||||
|
||||
### 4.3 生成头动底片
|
||||
|
||||
```bash
|
||||
conda activate LivePortrait
|
||||
cd /home/xsl/work/LivePortrait
|
||||
|
||||
python inference.py \
|
||||
-s /path/to/portrait.jpg \
|
||||
-d assets/examples/driving/d3.mp4 \
|
||||
--flag_crop_driving_video \
|
||||
-o /home/xsl/work/head_motion_base
|
||||
```
|
||||
|
||||
**驱动视频参考**(位于 `assets/examples/driving/`):
|
||||
|
||||
| 文件 | 时长 | 特点 |
|
||||
|------|------|------|
|
||||
| d3.mp4 | 11.8s | 自然说话动作,与10s音频匹配 |
|
||||
| d6.mp4 | 33.6s | 长片段,适合循环 |
|
||||
| d10.mp4 | 15.0s | 较长 |
|
||||
|
||||
**技巧**:选择时长接近音频时长的驱动视频;`--flag_crop_driving_video` 会自动裁剪驱动视频。
|
||||
|
||||
### 4.4 已知警告(可忽略)
|
||||
|
||||
```
|
||||
[E:onnxruntime] Failed to load library libonnxruntime_providers_cuda.so
|
||||
```
|
||||
onnxruntime-gpu 依赖 CUDA 11.x,与系统 CUDA 12.9 不兼容,人脸检测自动回退 CPU,不影响结果。
|
||||
|
||||
---
|
||||
|
||||
## 五、LatentSync 部署(已验证,非推荐方案)
|
||||
|
||||
> **结论**:质量好,但速度太慢(4fps),不适合产品化。作为备选方案保留。
|
||||
|
||||
### 5.1 环境
|
||||
|
||||
```bash
|
||||
conda create -y -n latentsync python=3.10.13
|
||||
conda activate latentsync
|
||||
conda install -y -c conda-forge ffmpeg
|
||||
|
||||
pip install -r /home/xsl/work/LatentSync/requirements.txt
|
||||
|
||||
# RTX 5090 必须卸载稳定版再装 nightly
|
||||
pip uninstall torch torchvision torchaudio -y
|
||||
pip install --pre torch torchvision torchaudio \
|
||||
--index-url https://download.pytorch.org/whl/nightly/cu128
|
||||
```
|
||||
|
||||
### 5.2 权重(约 4.9GB)
|
||||
|
||||
```bash
|
||||
cd /home/xsl/work/LatentSync
|
||||
huggingface-cli download ByteDance/LatentSync-1.6 whisper/tiny.pt --local-dir checkpoints
|
||||
huggingface-cli download ByteDance/LatentSync-1.6 latentsync_unet.pt --local-dir checkpoints
|
||||
```
|
||||
|
||||
### 5.3 输入准备
|
||||
|
||||
LatentSync 需要**视频**(非图片)+ **WAV 音频**:
|
||||
|
||||
```bash
|
||||
# 图片 → 视频
|
||||
ffmpeg -loop 1 -i portrait.jpg \
|
||||
-t <duration> \
|
||||
-vf "scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2" \
|
||||
-r 25 -c:v libx264 -pix_fmt yuv420p input_video.mp4 -y
|
||||
|
||||
# mp3 → wav
|
||||
ffmpeg -i audio.mp3 -ar 16000 -ac 1 input_audio.wav -y
|
||||
```
|
||||
|
||||
### 5.4 推理
|
||||
|
||||
```bash
|
||||
conda activate latentsync
|
||||
cd /home/xsl/work/LatentSync
|
||||
python -m scripts.inference \
|
||||
--unet_config_path "configs/unet/stage2_512.yaml" \
|
||||
--inference_ckpt_path "checkpoints/latentsync_unet.pt" \
|
||||
--inference_steps 20 \
|
||||
--guidance_scale 1.5 \
|
||||
--enable_deepcache \
|
||||
--video_path "assets/input_video.mp4" \
|
||||
--audio_path "assets/input_audio.wav" \
|
||||
--video_out_path "video_out.mp4"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、MuseTalk 部署(推荐方案)
|
||||
|
||||
### 6.1 项目路径
|
||||
|
||||
```
|
||||
/home/xsl/work/MuseTalk
|
||||
```
|
||||
|
||||
### 6.2 环境搭建(完整步骤,含所有踩坑修复)
|
||||
|
||||
```bash
|
||||
conda create -y -n MuseTalk python=3.10
|
||||
conda activate MuseTalk
|
||||
conda install -y -c conda-forge ffmpeg
|
||||
|
||||
# 1. PyTorch nightly(RTX 5090 必须)
|
||||
pip install --pre torch torchvision torchaudio \
|
||||
--index-url https://download.pytorch.org/whl/nightly/cu128
|
||||
|
||||
# 2. 项目依赖
|
||||
cd /home/xsl/work/MuseTalk
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 3. 修复 chumpy 构建问题
|
||||
pip install --no-build-isolation chumpy
|
||||
|
||||
# 4. MMLab(版本必须严格匹配,不可随意升降)
|
||||
pip install mmengine
|
||||
MMCV_WITH_OPS=1 pip install mmcv==2.1.0 --no-build-isolation # 需要系统 nvcc
|
||||
pip install "mmdet>=3.3.0" # ≥3.3.0 才兼容 mmcv 2.1.0
|
||||
pip install "mmpose>=1.3.0" # ≥1.3.0 才兼容 mmcv 2.1.0
|
||||
pip install xtcocotools json-tricks munkres
|
||||
|
||||
# 5. 更新 transformers(旧版与 huggingface-hub 1.x 冲突)
|
||||
pip install "transformers>=4.45.0"
|
||||
```
|
||||
|
||||
### 6.3 MMLab 版本兼容矩阵(关键)
|
||||
|
||||
```
|
||||
mmcv 2.1.0 ←→ mmdet ≥3.3.0 ←→ mmpose ≥1.3.0
|
||||
```
|
||||
|
||||
| 踩坑 | 原因 | 修复 |
|
||||
|------|------|------|
|
||||
| mmcv 构建失败 | nightly PyTorch 没有预编译轮子 | `MMCV_WITH_OPS=1 pip install mmcv==2.1.0 --no-build-isolation`(需系统 nvcc) |
|
||||
| `MMCV==2.1.0 is used but incompatible` | mmdet 3.1.0 要求 mmcv < 2.1.0 | 升级到 mmdet ≥3.3.0 |
|
||||
| `mmpose 1.1.0 incompatible` | 同上 | 升级到 mmpose ≥1.3.0 |
|
||||
| `transformers ImportError` | huggingface-hub 1.x 与旧 transformers 冲突 | 升级 transformers ≥4.45.0 |
|
||||
|
||||
### 6.4 权重下载
|
||||
|
||||
```bash
|
||||
cd /home/xsl/work/MuseTalk
|
||||
export HF_TOKEN=<your_token>
|
||||
|
||||
# 注意:此环境中命令是 hf,不是 huggingface-cli
|
||||
hf download TMElyralab/MuseTalk \
|
||||
"musetalkV15/musetalk.json" "musetalkV15/unet.pth" \
|
||||
--local-dir models
|
||||
|
||||
hf download stabilityai/sd-vae-ft-mse \
|
||||
config.json diffusion_pytorch_model.bin \
|
||||
--local-dir models/sd-vae
|
||||
|
||||
hf download yzd-v/DWPose \
|
||||
dw-ll_ucoco_384.pth \
|
||||
--local-dir models/dwpose
|
||||
|
||||
hf download openai/whisper-tiny \
|
||||
config.json pytorch_model.bin preprocessor_config.json \
|
||||
--local-dir models/whisper
|
||||
|
||||
hf download ByteDance/LatentSync \
|
||||
latentsync_syncnet.pt \
|
||||
--local-dir models/syncnet
|
||||
|
||||
# face-parse 权重(不在 HuggingFace)
|
||||
pip install gdown
|
||||
gdown --id 154JgKpzCPW82qINcVieuPH3fZ2e0P812 -O models/face-parse-bisent/79999_iter.pth
|
||||
curl -L https://download.pytorch.org/models/resnet18-5c106cde.pth \
|
||||
-o models/face-parse-bisent/resnet18-5c106cde.pth
|
||||
```
|
||||
|
||||
权重总大小约 **5GB**:
|
||||
```
|
||||
models/
|
||||
├── musetalkV15/
|
||||
│ ├── unet.pth (3.2GB)
|
||||
│ └── musetalk.json
|
||||
├── sd-vae/
|
||||
│ ├── diffusion_pytorch_model.bin (320MB)
|
||||
│ └── config.json
|
||||
├── dwpose/
|
||||
│ └── dw-ll_ucoco_384.pth (389MB)
|
||||
├── whisper/
|
||||
│ └── pytorch_model.bin (145MB)
|
||||
├── syncnet/
|
||||
│ └── latentsync_syncnet.pt (1.4GB)
|
||||
└── face-parse-bisent/
|
||||
├── 79999_iter.pth (51MB)
|
||||
└── resnet18-5c106cde.pth (45MB)
|
||||
```
|
||||
|
||||
### 6.5 PyTorch 2.6+ 兼容性补丁(必须)
|
||||
|
||||
PyTorch 2.6+ 将 `torch.load` 的 `weights_only` 默认值改为 `True`,导致 MuseTalk 加载旧格式权重失败。
|
||||
已在 `scripts/inference.py` 中加入 monkey-patch:
|
||||
|
||||
```python
|
||||
# 在 inference.py 开头的 import torch 后面加入:
|
||||
_orig_torch_load = torch.load
|
||||
def _patched_torch_load(f, *args, **kwargs):
|
||||
kwargs.setdefault('weights_only', False)
|
||||
return _orig_torch_load(f, *args, **kwargs)
|
||||
torch.load = _patched_torch_load
|
||||
```
|
||||
|
||||
同样的补丁也需要加到 `scripts/realtime_inference.py`(如果使用实时模式)。
|
||||
|
||||
### 6.6 推理配置文件
|
||||
|
||||
创建 YAML 配置文件(`configs/inference/my_task.yaml`):
|
||||
|
||||
```yaml
|
||||
task_0:
|
||||
video_path: "/path/to/head_motion_video.mp4"
|
||||
audio_path: "/path/to/audio.wav"
|
||||
bbox_shift: 0 # 可选:调整嘴部区域位置,负值下移,正值上移
|
||||
```
|
||||
|
||||
### 6.7 运行推理
|
||||
|
||||
```bash
|
||||
conda activate MuseTalk
|
||||
cd /home/xsl/work/MuseTalk
|
||||
|
||||
python -m scripts.inference \
|
||||
--inference_config configs/inference/my_task.yaml \
|
||||
--result_dir results/output \
|
||||
--unet_model_path models/musetalkV15/unet.pth \
|
||||
--unet_config models/musetalkV15/musetalk.json \
|
||||
--version v15
|
||||
```
|
||||
|
||||
输出路径:`results/output/v15/<video_name>.mp4`
|
||||
|
||||
---
|
||||
|
||||
## 七、完整流水线(已验证示例)
|
||||
|
||||
### 输入
|
||||
|
||||
- 图片:`/home/xsl/work/LivePortrait/hairstyle-result.jpg`(1080x1920,正面人像)
|
||||
- 音频:`/home/xsl/work/LivePortrait/test_speech_10s.mp3`(11.8秒,中文语音)
|
||||
|
||||
### Step 1:生成头动底片
|
||||
|
||||
```bash
|
||||
conda activate LivePortrait
|
||||
cd /home/xsl/work/LivePortrait
|
||||
|
||||
python inference.py \
|
||||
-s /home/xsl/work/LivePortrait/hairstyle-result.jpg \
|
||||
-d assets/examples/driving/d3.mp4 \
|
||||
--flag_crop_driving_video \
|
||||
-o /home/xsl/work/head_motion_base
|
||||
```
|
||||
|
||||
输出:`/home/xsl/work/head_motion_base/hairstyle-result--d3.mp4`(11.8s, 2.1MB)
|
||||
|
||||
### Step 2:音频转 WAV
|
||||
|
||||
```bash
|
||||
ffmpeg -i /home/xsl/work/LivePortrait/test_speech_10s.mp3 \
|
||||
-ar 16000 -ac 1 /tmp/input_audio.wav -y
|
||||
```
|
||||
|
||||
### Step 3:MuseTalk 嘴型同步
|
||||
|
||||
```bash
|
||||
conda activate MuseTalk
|
||||
cd /home/xsl/work/MuseTalk
|
||||
|
||||
cat > configs/inference/hairstyle.yaml << 'EOF'
|
||||
task_0:
|
||||
video_path: "/home/xsl/work/head_motion_base/hairstyle-result--d3.mp4"
|
||||
audio_path: "/tmp/input_audio.wav"
|
||||
EOF
|
||||
|
||||
python -m scripts.inference \
|
||||
--inference_config configs/inference/hairstyle.yaml \
|
||||
--result_dir results/hairstyle \
|
||||
--unet_model_path models/musetalkV15/unet.pth \
|
||||
--unet_config models/musetalkV15/musetalk.json \
|
||||
--version v15
|
||||
```
|
||||
|
||||
输出:`/home/xsl/work/MuseTalk/results/hairstyle/v15/hairstyle-result--d3_input_audio.mp4`
|
||||
|
||||
### 性能数据
|
||||
|
||||
| 阶段 | 耗时 | 帧数 | 等效速度 |
|
||||
|------|------|------|---------|
|
||||
| LivePortrait 头动生成 | ~30s | 295帧 | ~10fps |
|
||||
| MuseTalk 嘴型合成 | ~50s | 354帧 | ~7fps |
|
||||
| 总计 | ~80s | — | 生成12s视频 |
|
||||
|
||||
---
|
||||
|
||||
## 八、产品化建议
|
||||
|
||||
### 8.1 当前方案的局限
|
||||
|
||||
1. **非实时**:总体约 7fps 生成速度,12秒视频需要 80 秒处理
|
||||
2. **两套环境**:LivePortrait 和 MuseTalk 分别用不同 conda 环境,pipeline 不够整洁
|
||||
3. **头动单调**:驱动视频固定,长时间使用会重复
|
||||
4. **图片分辨率**:MuseTalk 处理区域限定在 256x256 嘴部区域
|
||||
|
||||
### 8.2 提速方向
|
||||
|
||||
- **MuseTalk 实时模式**:`scripts/realtime_inference.py` 支持流式处理,延迟更低
|
||||
- **头动循环库**:预先用 LivePortrait 生成多种头动视频(点头、摇头、思考等),运行时随机选取
|
||||
- **TensorRT 量化**:对 MuseTalk UNet 做 TRT 优化,预计可提速 2-3x
|
||||
|
||||
### 8.3 架构建议(产品级)
|
||||
|
||||
```
|
||||
音频输入
|
||||
↓
|
||||
[ASR/VAD] → 静音检测、分段
|
||||
↓
|
||||
[MuseTalk 实时流] ← 头动视频循环
|
||||
↓
|
||||
[后处理:美颜/超分](可选)
|
||||
↓
|
||||
视频输出流
|
||||
```
|
||||
|
||||
### 8.4 替代方案调研建议
|
||||
|
||||
在正式产品开发前,建议调研以下工具:
|
||||
- **Sonic**(`/home/xsl/work/Sonic`):已有项目,未测试,可能支持更好的实时性
|
||||
- **EchoMimic**:阿里的音频驱动方案,支持半身动作
|
||||
- **AniPortrait**:同时驱动头部和嘴型
|
||||
|
||||
---
|
||||
|
||||
## 九、目录结构总览
|
||||
|
||||
```
|
||||
/home/xsl/work/
|
||||
├── LivePortrait/ # 头部动作驱动
|
||||
│ ├── pretrained_weights/ (~1.1GB)
|
||||
│ ├── hairstyle-result.jpg # 测试图片
|
||||
│ ├── test_speech_10s.mp3 # 测试音频
|
||||
│ └── DEPLOYMENT.md # 详细部署笔记
|
||||
│
|
||||
├── LatentSync/ # 扩散模型唇形同步(备用)
|
||||
│ ├── checkpoints/ (~4.9GB)
|
||||
│ └── video_out.mp4 # 测试输出
|
||||
│
|
||||
├── MuseTalk/ # 单步推理唇形同步(推荐)
|
||||
│ ├── models/ (~5GB)
|
||||
│ └── results/hairstyle/v15/hairstyle-result--d3_input_audio.mp4
|
||||
│
|
||||
├── head_motion_base/ # LivePortrait 生成的头动底片
|
||||
│ └── hairstyle-result--d3.mp4
|
||||
│
|
||||
└── Sonic/ # 待调研
|
||||
```
|
||||
|
||||
### Conda 环境
|
||||
|
||||
```bash
|
||||
conda env list
|
||||
# LivePortrait /home/xsl/miniconda3/envs/LivePortrait
|
||||
# latentsync /home/xsl/miniconda3/envs/latentsync
|
||||
# MuseTalk /home/xsl/miniconda3/envs/MuseTalk
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、快速复现命令(Cheat Sheet)
|
||||
|
||||
```bash
|
||||
# === 生成一个说话视频(完整流程)===
|
||||
|
||||
# 1. 生成头动底片
|
||||
conda activate LivePortrait && cd /home/xsl/work/LivePortrait
|
||||
python inference.py -s portrait.jpg -d assets/examples/driving/d3.mp4 \
|
||||
--flag_crop_driving_video -o /tmp/head_motion
|
||||
|
||||
# 2. 音频转 WAV
|
||||
ffmpeg -i input.mp3 -ar 16000 -ac 1 /tmp/audio.wav -y
|
||||
|
||||
# 3. 嘴型同步
|
||||
conda activate MuseTalk && cd /home/xsl/work/MuseTalk
|
||||
python -m scripts.inference \
|
||||
--inference_config <(echo "task_0:\n video_path: /tmp/head_motion/*.mp4\n audio_path: /tmp/audio.wav") \
|
||||
--result_dir /tmp/output \
|
||||
--unet_model_path models/musetalkV15/unet.pth \
|
||||
--unet_config models/musetalkV15/musetalk.json \
|
||||
--version v15
|
||||
```
|
||||
Reference in New Issue
Block a user