通义万相开源 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秒)

📎013_concat.mp4

中国古典舞(2分41秒)

📎014_concat.mp4

(单视频备注:左-参考图;右:生成的舞蹈视频)

 

多风格泛化能力

在中国古典舞、踢踏舞、街舞、拉丁舞和K-Pop五种差异显著的舞蹈风格中均表现出色,展现了强大的跨风格适应能力。

中国古典舞

📎004_concat.mp4

踢踏舞

📎009_concat.mp4

街舞

📎007_concat.mp4

拉丁舞

📎011_concat.mp4

K-Pop

📎005_concat.mp4

(单视频备注:左-参考图;右:生成的舞蹈视频)

高效定制化能力

通过LoRA(Low-Rank Adaptation)技术,仅需少量特定舞蹈动作数据即可定制同款舞蹈视频,为个性化应用奠定基础。

“Spaghetti”舞

📎lora_spaghetti.mp4

“短裙”舞

📎lora_mini_skirt.mp4

“刀马”舞

📎lora_daoma.mp4

(单视频备注:左-参考图;右:生成的舞蹈视频)

 

核心技术

核心架构:全局规划与局部细化的协同生成

音乐驱动的舞蹈视频生成技术逐渐成为生成式AI领域的热点研究方向。然而,当前主流方法在生成长序列、复杂动作的舞蹈视频时普遍面临三大技术瓶颈:时序漂移导致动作与音乐节拍错位、生成角色身份特征不稳定、误差随视频时长增加不断累积。此外,现有模型对复杂舞蹈动作的支持能力有限,生成的舞蹈种类单一、动作重复性高,且受限于计算资源与建模能力,高质量视频的生成时长难以突破20秒大关。

 

针对这些挑战,我们提出了一种基于分层解耦策略的全新舞蹈生成框架,首次实现了分钟级别连贯高清舞蹈视频的稳定生成,为音乐视觉化表达开辟了新的技术路径。

该框架的核心创新在于采用了分层解耦的生成范式,将长序列舞蹈生成任务分解为两个关键阶段:

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

 

关键技术突破:从时序对齐到运动控制

为实现高质量长视频生成,我们在三个关键技术层面实现了突破:

  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
# Install package in editable mode
pip install -e .
# Install additional and specific versions dependencies
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/*"
)
# This is a specialized model with the following constraints on its input parameters:
# *   The model renders and outputs video based on a sequence of keyframes; therefore, `wantodance_keyframes` must be provided correctly.
# *   If you need to generate a long video, please generate it in segments, and ensure that `wantodance_music_path`, `wantodance_keyframes`, and `wantodance_keyframes_mask` are properly split accordingly.
# *   The audio file specified by `wantodance_music_path` must match the video duration, calculated as (`num_frames` / 30) seconds.
# *   The width and height of `wantodance_reference_image` must be multiples of 16.
# *   `wantodance_fps` is configurable, but since the model appears to have been trained exclusively at 30 FPS, setting it to other values is not recommended.
# *   In `wantodance_keyframes`, frames that are not keyframes should be solid black.
# *   `wantodance_keyframes_mask` indicates the positions of valid frames within `wantodance_keyframes`.
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,
                               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,
                               1, 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, 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 训练与全量训练。

 

环境搭建

首先安装 DiffSynth-Studio:


git clone https://github.com/modelscope/DiffSynth-Studio.git
cd DiffSynth-Studio
pip install -e .

此外,如需使用多 GPU 全量训练 14B 模型,还需额外安装 deepspeed

pip install deepspeed

准备数据集

我们构建了2个样例数据集,以方便您进行测试,通过以下命令可以下载这2个数据集:

数据集地址: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 模型(8*H200):


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 模型(8*H200):


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

模型链接:https://www.modelscope.cn/models/Wan-AI/Wan-Dancer-14B

Logo

ModelScope旨在打造下一代开源的模型即服务共享平台,为泛AI开发者提供灵活、易用、低成本的一站式模型服务产品,让模型应用更简单!

更多推荐