文章摘要
文章围绕Wan-Dancer-14B模型展开,它是音乐驱动的人像舞蹈视频生成模型,支持五大舞种、15秒至3分钟连贯视频输出。该模型核心性能亮点在于超长视频生成、多风格泛化适配和高效定制化。其采用分层解耦生成框架,实现关键技术突破。还介绍了模型推理部署及微调训练的方法,包括使用Diffsynth-Studio的具体操作。

近期开源的Wan-Dancer是一款音乐驱动的人像舞蹈视频生成模型,仅需输入一张人物照片与一段音乐,即可自动生成节奏精准、动作流畅且风格鲜明的高质量舞蹈视频。该模型首次突破了分钟级时序生成瓶颈,支持15秒至3分钟的连贯视频输出,同时覆盖中国古典舞、韩舞、街舞、踢踏舞、拉丁舞五大舞种,用户还可通过在线创作平台直接上传素材一键生成,无需本地部署环境。

可用资源链接

核心性能亮点

超长视频生成能力

该模型能够稳定生成超过1分钟的720P分辨率、30FPS帧率的高质量舞蹈视频,打破了传统方法仅能支持20秒以内内容的限制。例如可直接生成时长2分8秒的拉丁舞视频,以及2分41秒的中国古典舞视频,生成内容的连贯性与细节表现都保持了极高水准。

注:生成视频的参考图与最终效果左右对应展示,确保用户可以清晰对比原始素材与生成结果的差异。

多风格泛化适配

模型在五种差异显著的舞蹈风格中均有出色表现,无论是注重韵律的中国古典舞、活力动感的韩舞、节奏强烈的街舞、步伐清晰的踢踏舞还是热情奔放的拉丁舞,都能生成贴合风格的自然动作,展现了极强的跨风格适应能力。

高效定制化能力

通过LoRA(Low-Rank Adaptation)技术,开发者仅需少量特定舞蹈动作的样本数据,即可快速定制专属的舞蹈生成模型,为个性化舞蹈视频创作打下了坚实基础。例如针对特色舞种,都可以通过少量样本完成精准定制。

核心技术架构与突破

分层解耦的生成框架

音乐驱动的舞蹈视频生成此前面临诸多技术瓶颈:比如时序漂移导致动作与音乐节拍错位、角色身份特征不稳定、长视频生成时误差累积加剧,同时复杂舞蹈动作的支持能力不足,生成内容容易出现动作重复单一的问题。针对这些痛点,Wan-Dancer提出了基于分层解耦策略的全新生成框架,首次实现了分钟级别连贯高清舞蹈视频的稳定生成,为音乐视觉化提供了全新技术路径。

该框架的核心创新在于将长序列舞蹈生成拆分为两个关键阶段:

  • 全局关键帧规划:基于完整的音乐信息生成具备长时一致性的视频关键帧。通过对音乐整体结构与节奏模式的深度理解,规划出舞蹈动作的基本骨架与关键姿态,确保生成内容在全局时间尺度上的连贯性与合理性,同时生成的关键帧支持二次编辑与创作,为艺术创作提供了灵活空间。
  • 局部时序细化:在全局关键帧的基础上,专注于动作细节的完善与帧间过渡的平滑性。通过局部时序建模,有效解决了传统方法中动作单一重复的问题,显著提升了复杂舞蹈动作的细腻度与表现力。

关键技术突破

为实现高质量长视频生成,项目团队在三个核心技术层面实现了突破:

  1. 动态帧率适配机制:通过引入RoPE(Rotary Position Embedding)映射绝对时间信息,确保不同时长的音乐与生成的舞蹈动作在时序上实现精确对齐,从根源上解决了长序列生成中的时序漂移问题,让生成动作与音乐节拍保持高度同步。
  2. 运动连续性增强:基于光流的损失函数优化帧间过渡效果,在快速旋转、复杂步法等挑战性动作场景中,实现了更加自然的运动连贯性,大幅提升了生成视频的视觉质量。
  3. 精细化运动速度控制:通过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
以上内容不代表本平台立场,仅供读者参考