Wan-Dancer-14B LoRA训练:DiffSynth-Studio指南

近期开源的Wan-Dancer是一款音乐驱动的人像舞蹈视频生成模型,仅需输入一张人物照片与一段音乐,即可自动生成节奏精准、动作流畅且风格鲜明的高质量舞蹈视频。该模型首次突破了分钟级时序生成瓶颈,支持15秒至3分钟的连贯视频输出,同时覆盖中国古典舞、韩舞、街舞、踢踏舞、拉丁舞五大舞种,用户还可通过在线创作平台直接上传素材一键生成,无需本地部署环境。
可用资源链接
- 项目主页:https://humanaigc.github.io/wan-dancer-project/
- 模型权重:https://www.modelscope.cn/models/Wan-AI/Wan-Dancer-14B
- 代码仓库:https://github.com/Wan-Video/Wan-Dancer
- 在线体验:https://www.modelscope.cn/studios/Wan-AI/Wan-Dancer
核心性能亮点
超长视频生成能力
该模型能够稳定生成超过1分钟的720P分辨率、30FPS帧率的高质量舞蹈视频,打破了传统方法仅能支持20秒以内内容的限制。例如可直接生成时长2分8秒的拉丁舞视频,以及2分41秒的中国古典舞视频,生成内容的连贯性与细节表现都保持了极高水准。
注:生成视频的参考图与最终效果左右对应展示,确保用户可以清晰对比原始素材与生成结果的差异。
多风格泛化适配
模型在五种差异显著的舞蹈风格中均有出色表现,无论是注重韵律的中国古典舞、活力动感的韩舞、节奏强烈的街舞、步伐清晰的踢踏舞还是热情奔放的拉丁舞,都能生成贴合风格的自然动作,展现了极强的跨风格适应能力。
高效定制化能力
通过LoRA(Low-Rank Adaptation)技术,开发者仅需少量特定舞蹈动作的样本数据,即可快速定制专属的舞蹈生成模型,为个性化舞蹈视频创作打下了坚实基础。例如针对特色舞种,都可以通过少量样本完成精准定制。
核心技术架构与突破
分层解耦的生成框架
音乐驱动的舞蹈视频生成此前面临诸多技术瓶颈:比如时序漂移导致动作与音乐节拍错位、角色身份特征不稳定、长视频生成时误差累积加剧,同时复杂舞蹈动作的支持能力不足,生成内容容易出现动作重复单一的问题。针对这些痛点,Wan-Dancer提出了基于分层解耦策略的全新生成框架,首次实现了分钟级别连贯高清舞蹈视频的稳定生成,为音乐视觉化提供了全新技术路径。
该框架的核心创新在于将长序列舞蹈生成拆分为两个关键阶段:
- 全局关键帧规划:基于完整的音乐信息生成具备长时一致性的视频关键帧。通过对音乐整体结构与节奏模式的深度理解,规划出舞蹈动作的基本骨架与关键姿态,确保生成内容在全局时间尺度上的连贯性与合理性,同时生成的关键帧支持二次编辑与创作,为艺术创作提供了灵活空间。
- 局部时序细化:在全局关键帧的基础上,专注于动作细节的完善与帧间过渡的平滑性。通过局部时序建模,有效解决了传统方法中动作单一重复的问题,显著提升了复杂舞蹈动作的细腻度与表现力。
关键技术突破
为实现高质量长视频生成,项目团队在三个核心技术层面实现了突破:
- 动态帧率适配机制:通过引入RoPE(Rotary Position Embedding)映射绝对时间信息,确保不同时长的音乐与生成的舞蹈动作在时序上实现精确对齐,从根源上解决了长序列生成中的时序漂移问题,让生成动作与音乐节拍保持高度同步。
- 运动连续性增强:基于光流的损失函数优化帧间过渡效果,在快速旋转、复杂步法等挑战性动作场景中,实现了更加自然的运动连贯性,大幅提升了生成视频的视觉质量。
- 精细化运动速度控制:通过Prompt对人物动作的速度进行标注,让系统能够在快速动作场景下依然保持高保真的细节表现,让生成的舞蹈不仅节奏准确,更能体现不同舞蹈风格特有的动态特征。
模型推理部署
方式一:官方代码推理
环境安装
git clone https://github.com/Wan-Video/Wan-Dancer.git
cd Wan-Dancer
python -m venv venv_wan_dancer
source venv_wan_dancer/bin/activate
pip install -e .
pip install moviepy loguru librosa
pip install https://mirrors.aliyun.com/pytorch-wheels/cu124/torch-2.6.0+cu124-cp310-cp310-linux_x86_64.whl
pip install torchvision==0.21.0
pip install diffusers==0.34.0
pip install yunchang==0.5.0
pip install flash_attn==2.6.3
pip install xfuser==0.4.0
pip install transformers==4.46.2
模型下载
pip install modelscope
modelscope download Wan-AI/Wan-Dancer-14B --local_dir ./Wan-Dancer-14B
推理执行
Wan-Dancer的推理分为两个阶段:首先生成全局关键帧,再完成局部时序帧的补全。
全局推理脚本:
cd /path/to/Wan-Dancer
./gen_video_global.sh
局部推理脚本:
cd /path/to/Wan-Dancer
./gen_video_local.sh
方式二:使用Diffsynth-Studio推理
环境安装
git clone https://github.com/modelscope/DiffSynth-Studio.git
cd DiffSynth-Studio
pip install -e .
全局推理代码示例
import torch
from PIL import Image
from diffsynth.utils.data import save_video, VideoData
from diffsynth.pipelines.wan_video import WanVideoPipeline, ModelConfig
from modelscope import dataset_snapshot_download
pipe = WanVideoPipeline.from_pretrained(
torch_dtype=torch.bfloat16,
device="cuda",
model_configs=[
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="global_model.safetensors"),
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="models_t5_umt5-xxl-enc-bf16.pth"),
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="Wan2.1_VAE.pth"),
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="models_clip-open-clip-xlm-roberta-large-vit-huge-14.pth"),
],
tokenizer_config=ModelConfig(model_id="Wan-AI/Wan2.1-T2V-1.3B", origin_file_pattern="google/umt5-xxl/"),
)
dataset_snapshot_download(
"DiffSynth-Studio/diffsynth_example_dataset",
local_dir="data/diffsynth_example_dataset",
allow_file_pattern="wanvideo/Wan-Dancer-14B-global/*"
)
wantodance_keyframes = VideoData("data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-global/keyframes.mp4")
wantodance_keyframes = [wantodance_keyframes[i] for i in range(149)]
video = pipe(
prompt="一个人正在跳舞,舞蹈种类是韩舞。帧率是7.5000",
negative_prompt="色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
seed=0, tiled=False,
height=1280, width=720, num_frames=149,
num_inference_steps=48,
wantodance_music_path="data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-global/music.WAV",
wantodance_reference_image=Image.open("data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-global/refimage.jpg"),
wantodance_fps=7.5,
wantodance_keyframes=wantodance_keyframes,
wantodance_keyframes_mask=[1] + [0] * 148,
framewise_decoding=True,
)
save_video(video, "video_Wan-Dancer-14B-global.mp4", fps=7.5, quality=5)
局部推理代码示例
import torch, os
from PIL import Image
from diffsynth.utils.data import save_video, VideoData
from diffsynth.pipelines.wan_video import WanVideoPipeline, ModelConfig
from modelscope import dataset_snapshot_download
pipe = WanVideoPipeline.from_pretrained(
torch_dtype=torch.bfloat16,
device="cuda",
model_configs=[
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="local_model.safetensors"),
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="models_t5_umt5-xxl-enc-bf16.pth"),
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="Wan2.1_VAE.pth"),
ModelConfig(model_id="Wan-AI/Wan-Dancer-14B", origin_file_pattern="models_clip-open-clip-xlm-roberta-large-vit-huge-14.pth"),
],
tokenizer_config=ModelConfig(model_id="Wan-AI/Wan2.1-T2V-1.3B", origin_file_pattern="google/umt5-xxl/"),
)
dataset_snapshot_download(
"DiffSynth-Studio/diffsynth_example_dataset",
local_dir="data/diffsynth_example_dataset",
allow_file_pattern="wanvideo/Wan-Dancer-14B-local/*"
)
wantodance_keyframes = VideoData("data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-local/keyframes.mp4")
wantodance_keyframes = [wantodance_keyframes[i] for i in range(149)]
video = pipe(
prompt="一个人正在跳舞,舞蹈种类是古典舞,图像清晰程度高,人物动作平均幅度中等,人物动作最大幅度中等。, 帧率是30fps。",
negative_prompt="色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
seed=0, tiled=True,
height=1280, width=720, num_frames=149,
num_inference_steps=24,
wantodance_music_path="data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-local/music.wav",
wantodance_reference_image=Image.open("data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-local/refimage.jpg"),
wantodance_fps=30,
wantodance_keyframes=wantodance_keyframes,
wantodance_keyframes_mask=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
)
save_video(video, "video_Wan-Dancer-14B-local.mp4", fps=30, quality=5)
模型微调训练
DiffSynth-Studio已经支持Wan-Dancer-14B模型的LoRA训练与全量训练,具体流程如下:
环境搭建
基础环境安装
git clone https://github.com/modelscope/DiffSynth-Studio.git
cd DiffSynth-Studio
pip install -e .
如果需要使用多GPU全量训练14B模型,还需要额外安装deepspeed依赖:
pip install deepspeed
数据集准备
项目提供了两个样例数据集用于测试,可通过以下命令下载:
数据集总地址:https://modelscope.cn/datasets/DiffSynth-Studio/diffsynth_example_dataset
下载global数据集:
modelscope download --dataset DiffSynth-Studio/diffsynth_example_dataset --include "wanvideo/Wan-Dancer-14B-global/*" --local_dir ./data/diffsynth_example_dataset
下载local数据集:
modelscope download --dataset DiffSynth-Studio/diffsynth_example_dataset --include "wanvideo/Wan-Dancer-14B-local/*" --local_dir ./data/diffsynth_example_dataset
启动训练任务
Wan-Dancer-14B模型包含两个DiT模型,需要分别进行训练:
训练Global DiT的LoRA模型
accelerate launch --config_file examples/wanvideo/model_training/full/accelerate_config_14B.yaml examples/wanvideo/model_training/train.py \
--dataset_base_path data/diffsynth_example_dataset/wanvideo/Wan2-Dancer-14B-global \
--dataset_metadata_path data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-global/metadata.json \
--data_file_keys "video,wantodance_reference_image,wantodance_keyframes,wantodance_music_path" \
--height 1280 \
--width 720 \
--num_frames 149 \
--dataset_repeat 100 \
--model_id_with_origin_paths "Wan-AI/Wan-Dancer-14B:global_model.safetensors,Wan-AI/Wan-Dancer-14B:models_t5_umt5-xxl-enc-bf16.pth,Wan-AI/Wan-Dancer-14B:Wan2.1_VAE.pth,Wan-AI/Wan-Dancer-14B:models_clip-open-clip-xlm-roberta-large-vit-huge-14.pth" \
--learning_rate 1e-4 \
--num_epochs 5 \
--remove_prefix_in_ckpt "pipe.dit." \
--output_path "./models/train/Wan-Dancer-14B-global_lora" \
--lora_base_model "dit" \
--lora_target_modules "q,k,v,o,ffn.0,ffn.2" \
--lora_rank 32 \
--extra_inputs "wantodance_music_path,wantodance_reference_image,wantodance_fps,wantodance_keyframes,wantodance_keyframes_mask,framewise_decoding" \
--use_gradient_checkpointing_offload \
--framewise_decoding
训练Local DiT的LoRA模型
accelerate launch --config_file examples/wanvideo/model_training/full/accelerate_config_14B.yaml examples/wanvideo/model_training/train.py \
--dataset_base_path data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-local \
--dataset_metadata_path data/diffsynth_example_dataset/wanvideo/Wan-Dancer-14B-local/metadata.json \
--data_file_keys "video,wantodance_reference_image,wantodance_keyframes,wantodance_music_path" \
--height 1280 \
--width 720 \
--num_frames 149 \
--dataset_repeat 100 \
--model_id_with_origin_paths "Wan-AI/Wan-Dancer-14B:local_model.safetensors,Wan-AI/Wan-Dancer-14B:models_t5_umt5-xxl-enc-bf16.pth,Wan-AI/Wan-Dancer-14B:Wan2.1_VAE.pth,Wan-AI/Wan-Dancer-14B:models_clip-open-clip-xlm-roberta-large-vit-huge-14.pth" \
--learning_rate 1e-4 \
--num_epochs 5 \
--remove_prefix_in_ckpt "pipe.dit." \
--output_path "./models/train/Wan-Dancer-14B-local_lora" \
--lora_base_model "dit" \
--lora_target_modules "q,k,v,o,ffn.0,ffn.2" \
--lora_rank 32 \
--extra_inputs "wantodance_music_path,wantodance_reference_image,wantodance_fps,wantodance_keyframes,wantodance_keyframes_mask" \
--use_gradient_checkpointing_offload


