> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-zh/shi-pin-sheng-cheng/wan-video.md).

# Wan2.1 视频

在 Clore.ai GPU 上使用阿里巴巴的 Wan2.1 模型生成视频

在 CLORE.AI GPU 上使用阿里巴巴的 Wan2.1 文生视频和图生视频模型生成高质量视频。

{% hint style="success" %}
所有示例都可以在通过以下方式租用的 GPU 服务器上运行 [CLORE.AI 市场](https://clore.ai/marketplace).
{% endhint %}

## 为什么选择 Wan2.1？

* **高质量** - 业界领先的视频生成
* **多种模式** - 文生视频、图生视频
* **多种规模** - 1.3B 到 14B 参数
* **长视频** - 最多 81 帧
* **开源权重** - Apache 2.0 许可证

## 模型变体

| 模型              | 参数   | 显存   | 分辨率  | 帧数 |
| --------------- | ---- | ---- | ---- | -- |
| Wan2.1-T2V-1.3B | 1.3B | 8GB  | 480p | 81 |
| Wan2.1-T2V-14B  | 14B  | 24GB | 720p | 81 |
| Wan2.1-I2V-14B  | 14B  | 24GB | 720p | 81 |

## 在 CLORE.AI 上快速部署

**Docker 镜像：**

```
pytorch/pytorch:2.11.0-cuda12.8-cudnn9-devel
```

**端口：**

```
22/tcp
7860/http
```

**命令：**

```bash
pip install diffusers transformers accelerate gradio && \
python -c "
import gradio as gr
import torch
from diffusers import WanPipeline
from diffusers.utils import export_to_video

pipe = WanPipeline.from_pretrained('alibaba-pai/Wan2.1-T2V-1.3B', torch_dtype=torch.float16)
pipe.to('cuda')
pipe.enable_model_cpu_offload()

def generate(prompt, steps, frames, seed):
    generator = torch.Generator('cuda').manual_seed(seed) if seed > 0 else None
    output = pipe(prompt, num_frames=frames, num_inference_steps=steps, generator=generator)
    export_to_video(output.frames[0], 'output.mp4', fps=16)
    return 'output.mp4'

gr.Interface(
    fn=generate,
    inputs=[
        gr.Textbox(label='提示词'),
        gr.Slider(20, 100, value=50, label='步数'),
        gr.Slider(16, 81, value=49, step=8, label='帧数'),
        gr.Number(value=-1, label='种子')
    ],
    outputs=gr.Video(),
    title='Wan2.1 - 文生视频'
).launch(server_name='0.0.0.0', server_port=7860)
"
```

## 访问你的服务

部署后，找到你的 `http_pub` URL 在 **我的订单**:

1. 前往 **我的订单** 页面
2. 点击你的订单
3. 找到 `http_pub` URL（例如， `abc123.clorecloud.net`)

使用 `https://YOUR_HTTP_PUB_URL` 替代 `localhost` 在下面的示例中。

## 硬件要求

| 模型        | 最低 GPU        | 推荐            | 最佳        |
| --------- | ------------- | ------------- | --------- |
| 1.3B 文生视频 | RTX 3070 8GB  | RTX 3090 24GB | RTX 4090  |
| 14B 文生视频  | RTX 4090 24GB | A100 40GB     | A100 80GB |
| 14B 图生视频  | RTX 4090 24GB | A100 40GB     | A100 80GB |

## 安装

```bash
pip install diffusers transformers accelerate torch
```

## 文生视频

### 基础用法（1.3B）

```python
import torch
from diffusers import WanPipeline
from diffusers.utils import export_to_video

pipe = WanPipeline.from_pretrained(
    "alibaba-pai/Wan2.1-T2V-1.3B",
    torch_dtype=torch.float16
)
pipe.to("cuda")
pipe.enable_model_cpu_offload()

prompt = "一只猫在阳光明媚的花园里玩球"

output = pipe(
    prompt=prompt,
    num_frames=49,
    num_inference_steps=50,
    guidance_scale=7.0
)

export_to_video(output.frames[0], "cat_video.mp4", fps=16)
```

### 高质量（14B）

```python
import torch
from diffusers import WanPipeline
from diffusers.utils import export_to_video

pipe = WanPipeline.from_pretrained(
    "alibaba-pai/Wan2.1-T2V-14B",
    torch_dtype=torch.float16
)
pipe.to("cuda")
pipe.enable_model_cpu_offload()
pipe.enable_vae_tiling()

prompt = "一条龙在日落时分飞越群山的电影级镜头，4K，细节丰富"

output = pipe(
    prompt=prompt,
    negative_prompt="模糊、低质量、失真",
    num_frames=81,
    height=720,
    width=1280,
    num_inference_steps=50,
    guidance_scale=7.0
)

export_to_video(output.frames[0], "dragon.mp4", fps=24)
```

## 图像转视频

### 为图片添加动画

```python
import torch
from diffusers import WanI2VPipeline
from diffusers.utils import load_image, export_to_video

pipe = WanI2VPipeline.from_pretrained(
    "alibaba-pai/Wan2.1-I2V-14B",
    torch_dtype=torch.float16
)
pipe.to("cuda")
pipe.enable_model_cpu_offload()

# 加载输入图像
image = load_image("input.jpg")

prompt = "图中的人物开始向前行走"

output = pipe(
    prompt=prompt,
    image=image,
    num_frames=49,
    num_inference_steps=50,
    guidance_scale=7.0
)

export_to_video(output.frames[0], "animated.mp4", fps=16)
```

## 使用 Wan2.1-I2V-14B 的图生视频

{% hint style="info" %}
Wan2.1-I2V-14B 使用文本提示来引导动作，使静态图像动起来。需要 **24GB 显存** （推荐 RTX 4090 或 A100 40GB）。
{% endhint %}

### 模型详情

| 属性    | 数值                            |
| ----- | ----------------------------- |
| 模型 ID | `Wan-AI/Wan2.1-I2V-14B-480P`  |
| 参数    | 140 亿                         |
| 所需显存  | **24GB**                      |
| 最大分辨率 | 480p（854×480）或 720p（1280×720） |
| 最大帧数  | 81                            |
| 许可证   | Apache 2.0                    |

### 硬件要求

| GPU       | 显存   | 状态     |
| --------- | ---- | ------ |
| RTX 4090  | 24GB | ✅ 推荐   |
| RTX 3090  | 24GB | ✅ 支持   |
| A100 40GB | 40GB | ✅ 最优   |
| A100 80GB | 80GB | ✅ 画质最佳 |
| RTX 3080  | 10GB | ❌ 不足   |

### 快速 CLI 脚本

另存为 `generate_i2v.py` 并运行：

```bash
python generate_i2v.py --model Wan-AI/Wan2.1-I2V-14B-480P --image input.jpg --prompt "camera slowly zooms out"
```

### generate\_i2v.py — 完整脚本

```python
#!/usr/bin/env python3
"""
Wan2.1 图生视频 CLI 脚本。
用法：python generate_i2v.py --model Wan-AI/Wan2.1-I2V-14B-480P \
           --image input.jpg --prompt "camera slowly zooms out"
"""

import argparse
import os
import sys
import torch
from diffusers import WanImageToVideoPipeline
from diffusers.utils import load_image, export_to_video
from PIL import Image


def parse_args():
    parser = argparse.ArgumentParser(description="Wan2.1 图生视频生成器")
    parser.add_argument(
        "--model",
        type=str,
        default="Wan-AI/Wan2.1-I2V-14B-480P",
        help="来自 Hugging Face 的模型 ID（默认：Wan-AI/Wan2.1-I2V-14B-480P）",
    )
    parser.add_argument(
        "--image",
        type=str,
        required=True,
        help="输入图像路径（JPEG 或 PNG）",
    )
    parser.add_argument(
        "--prompt",
        type=str,
        required=True,
        help='描述所需运动的文本提示词（例如："camera slowly zooms out"）',
    )
    parser.add_argument(
        "--negative-prompt",
        type=str,
        default="模糊、低质量、失真、抖动运动、伪影",
        help="用于避免不需要的伪影的负面提示词",
    )
    parser.add_argument(
        "--frames",
        type=int,
        default=49,
        help="要生成的视频帧数（默认：49，最大：81）",
    )
    parser.add_argument(
        "--steps",
        type=int,
        default=50,
        help="扩散步数（默认：50）",
    )
    parser.add_argument(
        "--guidance",
        type=float,
        default=7.0,
        help="无分类器引导缩放（默认：7.0）",
    )
    parser.add_argument(
        "--seed",
        type=int,
        default=-1,
        help="用于复现的随机种子（-1 = 随机）",
    )
    parser.add_argument(
        "--fps",
        type=int,
        default=16,
        help="输出视频 FPS（默认：16）",
    )
    parser.add_argument(
        "--output",
        type=str,
        default="output_i2v.mp4",
        help="输出视频文件路径（默认：output_i2v.mp4）",
    )
    parser.add_argument(
        "--height",
        type=int,
        default=480,
        help="输出视频高度（像素，默认：480）",
    )
    parser.add_argument(
        "--width",
        type=int,
        default=854,
        help="输出视频宽度（像素，默认：854）",
    )
    parser.add_argument(
        "--cpu-offload",
        action="store_true",
        default=True,
        help="启用模型 CPU 卸载以节省显存（默认：True）",
    )
    parser.add_argument(
        "--vae-tiling",
        action="store_true",
        default=False,
        help="为高分辨率输出启用 VAE 分块",
    )
    return parser.parse_args()


def load_and_resize_image(image_path: str, width: int, height: int) -> Image.Image:
    """从路径加载图像并调整到目标尺寸。"""
    if not os.path.exists(image_path):
        print(f"[ERROR] 找不到图像：{image_path}", file=sys.stderr)
        sys.exit(1)

    img = Image.open(image_path).convert("RGB")
    original_size = img.size
    img = img.resize((width, height), Image.LANCZOS)
    print(f"[INFO] 已加载图像：{image_path}（{original_size[0]}x{original_size[1]}）→ 调整为 {width}x{height}")
    return img


def load_pipeline(model_id: str, cpu_offload: bool, vae_tiling: bool):
    """加载带内存优化的 Wan I2V 流水线。"""
    print(f"[INFO] 正在加载模型：{model_id}")
    print(f"[INFO] CUDA 是否可用：{torch.cuda.is_available()}")
    if torch.cuda.is_available():
        vram_gb = torch.cuda.get_device_properties(0).total_memory / 1e9
        print(f"[INFO] GPU：{torch.cuda.get_device_name(0)}（{vram_gb:.1f} GB 显存）")
        if vram_gb < 23:
            print("[WARN] 检测到少于 24GB 的显存——请启用 --cpu-offload 或使用 1.3B 模型")

    pipe = WanImageToVideoPipeline.from_pretrained(
        model_id,
        torch_dtype=torch.float16,
    )

    if cpu_offload:
        print("[INFO] 启用模型 CPU 卸载")
        pipe.enable_model_cpu_offload()
    else:
        pipe.to("cuda")

    if vae_tiling:
        print("[INFO] 启用 VAE 分块以进行高分辨率生成")
        pipe.enable_vae_tiling()

    return pipe


def generate_video(pipe, args) -> None:
    """运行 I2V 流水线并保存输出视频。"""
    image = load_and_resize_image(args.image, args.width, args.height)

    generator = None
    if args.seed >= 0:
        generator = torch.Generator("cuda").manual_seed(args.seed)
        print(f"[INFO] 使用种子：{args.seed}")
    else:
        print("[INFO] 使用随机种子")

    print(f"[INFO] 正在生成 {args.frames} 帧，分辨率 {args.width}x{args.height}")
    print(f"[INFO] 步数：{args.steps} | 引导：{args.guidance} | FPS：{args.fps}")
    print(f"[INFO] 提示词：{args.prompt}")

    output = pipe(
        prompt=args.prompt,
        negative_prompt=args.negative_prompt,
        image=image,
        num_frames=args.frames,
        height=args.height,
        width=args.width,
        num_inference_steps=args.steps,
        guidance_scale=args.guidance,
        generator=generator,
    )

    export_to_video(output.frames[0], args.output, fps=args.fps)
    print(f"[INFO] 视频已保存到：{os.path.abspath(args.output)}")
    duration = args.frames / args.fps
    print(f"[INFO] 时长：{duration:.1f} 秒，{args.fps}fps（{args.frames} 帧）")


def main():
    args = parse_args()

    if not torch.cuda.is_available():
        print("[ERROR] 未找到 CUDA GPU。Wan2.1-I2V-14B 需要支持 CUDA 的 GPU。", file=sys.stderr)
        sys.exit(1)

    pipe = load_pipeline(args.model, args.cpu_offload, args.vae_tiling)
    generate_video(pipe, args)
    print("[DONE] 图生视频生成完成！")


if __name__ == "__main__":
    main()
```

### 高级 I2V 流水线（Python API）

```python
import torch
from diffusers import WanImageToVideoPipeline
from diffusers.utils import load_image, export_to_video
from PIL import Image

# ── 加载流水线 ──────────────────────────────────────────────────────────────
pipe = WanImageToVideoPipeline.from_pretrained(
    "Wan-AI/Wan2.1-I2V-14B-480P",
    torch_dtype=torch.float16,
)
pipe.enable_model_cpu_offload()   # 将显存保持在 24GB 以下
pipe.enable_vae_tiling()          # 可选：有助于 720p

# ── 加载并准备输入图像 ─────────────────────────────────────────────────
image = load_image("input.jpg").resize((854, 480))

# ── 生成 ───────────────────────────────────────────────────────────────────
prompt = "camera slowly zooms out, revealing the full landscape"
negative_prompt = "模糊、低质量、失真、闪烁、伪影"

generator = torch.Generator("cuda").manual_seed(42)

output = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    image=image,
    num_frames=49,          # 16fps 下约 3 秒
    height=480,
    width=854,
    num_inference_steps=50,
    guidance_scale=7.5,
    generator=generator,
)

export_to_video(output.frames[0], "i2v_output.mp4", fps=16)
print("已保存：i2v_output.mp4")
```

### I2V 提示词技巧

| 目标   | 提示词示例                                              |
| ---- | -------------------------------------------------- |
| 镜头运动 | `"camera slowly zooms out from the subject"`       |
| 视差效果 | `"subtle parallax motion, depth of field shift"`   |
| 角色动画 | `"the figure turns their head and smiles"`         |
| 自然动画 | `"leaves rustle in a gentle breeze, light shifts"` |
| 抽象运动 | `"colors swirl and blend, fluid motion"`           |

### I2V 显存技巧（24GB GPU）

```python
# 在 24GB GPU 上必需
pipe.enable_model_cpu_offload()

# 可选：减少约 10% 的峰值显存
pipe.enable_vae_tiling()
pipe.enable_vae_slicing()

# 在每次运行之间清理
import gc
gc.collect()
torch.cuda.empty_cache()
```

## 提示词示例

### 自然与风景

```python
prompts = [
    "云层掠过山峰的延时摄影，戏剧性光照",
    "海浪拍击礁石，慢动作，电影感",
    "夜空中跳动的极光，鲜艳色彩",
    "秋天的森林，树叶飘落，宁静氛围"
]
```

### 动物与角色

```python
prompts = [
    "一只金毛猎犬在花田中奔跑",
    "一只蝴蝶从茧中破茧而出，微距镜头",
    "武士拔刀，戏剧性光照",
    "机器人行走在未来城市街道中"
]
```

### 抽象与艺术

```python
prompts = [
    "彩色颜料在水中旋转，抽象艺术",
    "几何形状变换和变形，霓虹色彩",
    "墨滴在牛奶中扩散，微距摄影"
]
```

## 高级设置

### 画质与速度

```python
# 快速预览
output = pipe(
    prompt=prompt,
    num_frames=17,
    num_inference_steps=25,
    guidance_scale=5.0
)

# 平衡
output = pipe(
    prompt=prompt,
    num_frames=49,
    num_inference_steps=50,
    guidance_scale=7.0
)

# 最高画质
output = pipe(
    prompt=prompt,
    num_frames=81,
    num_inference_steps=100,
    guidance_scale=7.5
)
```

### 分辨率选项

```python
# 480p（1.3B 模型）
output = pipe(prompt, height=480, width=854, num_frames=49)

# 720p（14B 模型）
output = pipe(prompt, height=720, width=1280, num_frames=49)

# 1080p（14B 模型，高显存）
output = pipe(prompt, height=1080, width=1920, num_frames=33)
```

## 批量生成

```python
import os
import torch
from diffusers import WanPipeline
from diffusers.utils import export_to_video

pipe = WanPipeline.from_pretrained("alibaba-pai/Wan2.1-T2V-1.3B", torch_dtype=torch.float16)
pipe.to("cuda")
pipe.enable_model_cpu_offload()

prompts = [
    "火箭发射进入太空",
    "鱼儿在珊瑚礁中游动",
    "夜晚城市街道上下着雨"
]

output_dir = "./videos"
os.makedirs(output_dir, exist_ok=True)

for i, prompt in enumerate(prompts):
    print(f"正在生成 {i+1}/{len(prompts)}：{prompt[:40]}...")

    output = pipe(
        prompt=prompt,
        num_frames=49,
        num_inference_steps=50
    )

    export_to_video(output.frames[0], f"{output_dir}/video_{i:03d}.mp4", fps=16)
    torch.cuda.empty_cache()
```

## Gradio 界面

```python
import gradio as gr
import torch
from diffusers import WanPipeline
from diffusers.utils import export_to_video
import tempfile

pipe = WanPipeline.from_pretrained("alibaba-pai/Wan2.1-T2V-1.3B", torch_dtype=torch.float16)
pipe.to("cuda")
pipe.enable_model_cpu_offload()

def generate_video(prompt, negative_prompt, frames, steps, guidance, seed):
    generator = torch.Generator("cuda").manual_seed(seed) if seed > 0 else None

    output = pipe(
        prompt=prompt,
        negative_prompt=negative_prompt,
        num_frames=frames,
        num_inference_steps=steps,
        guidance_scale=guidance,
        generator=generator
    )

    with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as f:
        export_to_video(output.frames[0], f.name, fps=16)
        return f.name

demo = gr.Interface(
    fn=generate_video,
    inputs=[
        gr.Textbox(label="提示词", lines=2),
        gr.Textbox(label="负面提示词", value="模糊、低质量"),
        gr.Slider(17, 81, value=49, step=8, label="帧数"),
        gr.Slider(20, 100, value=50, step=5, label="步数"),
        gr.Slider(3, 12, value=7, step=0.5, label="引导"),
        gr.Number(value=-1, label="种子")
    ],
    outputs=gr.Video(label="生成的视频"),
    title="Wan2.1 - 文生视频生成",
    description="根据文本提示生成视频。在 CLORE.AI 上运行。"
)

demo.launch(server_name="0.0.0.0", server_port=7860)
```

## 内存优化

```python
# 启用所有优化
pipe.enable_model_cpu_offload()
pipe.enable_vae_tiling()
pipe.enable_vae_slicing()

# 适用于超低显存
pipe.enable_sequential_cpu_offload()

# 在生成之间清理缓存
torch.cuda.empty_cache()
```

## 性能

| 模型   | 分辨率  | 帧数 | GPU       | 时间       |
| ---- | ---- | -- | --------- | -------- |
| 1.3B | 480p | 49 | RTX 4090  | 约 2 分钟   |
| 1.3B | 480p | 49 | A100 40GB | 约 1.5 分钟 |
| 14B  | 720p | 49 | A100 40GB | \~5 分钟   |
| 14B  | 720p | 81 | A100 80GB | \~8 分钟   |

## 成本估算

CLORE.AI 市场的典型费率：

| GPU           | 小时费率    | 约 49 帧视频/小时           |
| ------------- | ------- | --------------------- |
| RTX 3090 24GB | \~$0.06 | 约 20（1.3B）            |
| RTX 4090 24GB | \~$0.10 | 约 30（1.3B）            |
| A100 40GB     | \~$0.17 | 约 40（1.3B）/ 约 12（14B） |
| A100 80GB     | \~$0.25 | 约 8（14B 高分辨率）         |

*价格会变化。请查看* [*CLORE.AI 市场*](https://clore.ai/marketplace) *以获取当前费率。*

## 故障排查

### 内存不足

```python
# 使用更小的模型
pipe = WanPipeline.from_pretrained("alibaba-pai/Wan2.1-T2V-1.3B")

# 启用所有优化
pipe.enable_model_cpu_offload()
pipe.enable_vae_tiling()

# 减少帧数
output = pipe(prompt, num_frames=17)

# 降低分辨率
output = pipe(prompt, height=480, width=854)
```

### 质量较差

* 增加步数（75-100）
* 编写更详细的提示词
* 使用负面提示词
* 尝试使用 14B 模型以获得更好的质量

### 视频太短

* 增大 `num_frames` （最多 81）
* 使用 RIFE 插帧进行补帧
* 串联多次生成

### 伪影/闪烁

* 提高引导尺度
* 使用固定种子以保持一致性
* 使用视频稳定化进行后期处理

## Wan2.1 与其他模型对比

| 功能     | Wan2.1     | Hunyuan | SVD  | CogVideoX |
| ------ | ---------- | ------- | ---- | --------- |
| 质量     | 优秀         | 优秀      | 好    | 很高        |
| 速度     | 快          | 中等      | 快    | 慢         |
| 最大帧数   | 81         | 129     | 25   | 49        |
| 分辨率    | 720p       | 720p    | 576p | 720p      |
| 支持图生视频 | 是          | 是       | 是    | 是         |
| 许可证    | Apache 2.0 | 打开      | 打开   | 打开        |

**在以下情况下使用 Wan2.1：**

* 需要开源视频生成
* 希望生成速度快
* 需要 Apache 2.0 许可
* 需要兼顾质量和速度

## 下一步

* [Hunyuan Video](/guides/guides_v2-zh/shi-pin-sheng-cheng/hunyuan-video.md) - 替代的文生视频
* [OpenSora](/guides/guides_v2-zh/shi-pin-sheng-cheng/opensora.md) - Open Sora 替代方案
* [Stable Video Diffusion](/guides/guides_v2-zh/shi-pin-sheng-cheng/stable-video-diffusion.md) - 图像动画
* [RIFE 插帧](/guides/guides_v2-zh/shi-pin-chu-li/rife-interpolation.md) - 帧插值


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/shi-pin-sheng-cheng/wan-video.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
