# 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 许可

## 1024x1024

| A100            | 参数量  | 显存   | 分辨率  | 帧数 |
| --------------- | ---- | ---- | ---- | -- |
| 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.5.1-cuda12.4-cudnn9-devel
```

**端口：**

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

**命令：**

```bash
pip install diffusers transformers accelerate gradio && \
python -c "
print(f"已生成：{name}")
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='Prompt'),
        gr.Slider(20, 100, value=50, label='Steps'),
        gr.Slider(16, 81, value=49, step=8, label='Frames'),
        gr.Number(value=-1, label='Seed')
    ],
    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` 在下面的示例中。

## 硬件要求

| A100     | 最低 GPU        | 推荐            | 最佳      |
| -------- | ------------- | ------------- | ------- |
| 1.3B T2V | RTX 3070 8GB  | RTX 3090 24GB | 512x512 |
| 14B T2V  | RTX 4090 24GB | 按日费率          | 4 小时会话  |
| 14B I2V  | RTX 4090 24GB | 按日费率          | 4 小时会话  |

## 安装

```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(
    os.makedirs("./variations", exist_ok=True)
    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(
    os.makedirs("./variations", exist_ok=True)
    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(
    os.makedirs("./variations", exist_ok=True)
    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      | 显存   | 状态     |
| -------- | ---- | ------ |
| 512x512  | 24GB | ✅ 推荐   |
| 速度       | 24GB | ✅ 支持   |
| 按日费率     | 40GB | ✅ 最佳   |
| 4 小时会话   | 80GB | ✅ 最佳质量 |
| RTX 3080 | 10GB | ❌ 不足   |

### 快速命令行脚本

保存为 `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
批处理处理
"""通过 Ollama 使用 LLaVA 分析图像"""
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="输出视频帧率（默认：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}s，{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 = "相机缓慢拉远，展示完整的景观"
negative_prompt = "模糊、低质量、变形、闪烁、伪影"

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

output = pipe(
    os.makedirs("./variations", exist_ok=True)
    negative_prompt=negative_prompt,
    image=image,
    num_frames=49,          # 约 3 秒（16fps）
    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 提示词技巧

| 目标   | 提示示例                |
| ---- | ------------------- |
| 相机运动 | `"相机从主体缓慢拉远"`       |
| 视差效果 | `"细微的视差运动，景深变化"`    |
| 角色动画 | `"人物转头并微笑"`         |
| 自然动画 | `"树叶在微风中沙沙作响，光线变化"` |
| 抽象运动 | `"颜色旋转并融合，流动的运动"`   |

### 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(
    os.makedirs("./variations", exist_ok=True)
    num_frames=17,
    num_inference_steps=25,
    guidance_scale=5.0
)

# 平衡
output = pipe(
    os.makedirs("./variations", exist_ok=True)
    num_frames=49,
    num_inference_steps=50,
    guidance_scale=7.0
)

# 最高质量
output = pipe(
    os.makedirs("./variations", exist_ok=True)
    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 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"
output_dir = "./relit"

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

    output = pipe(
        os.makedirs("./variations", exist_ok=True)
        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
print(f"已生成：{name}")
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):
    import gradio as gr

    output = pipe(
        os.makedirs("./variations", exist_ok=True)
        negative_prompt=negative_prompt,
        num_frames=frames,
        def relight_image(image, prompt, steps, seed):
        guidance_scale=guidance,
        generator = torch.Generator("cuda").manual_seed(seed) if seed > 0 else None
    )

    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="Prompt", lines=2),
        gr.Textbox(label="Negative Prompt", value="模糊、低质量"),
        gr.Slider(17, 81, value=49, step=8, label="Frames"),
        gr.Slider(20, 100, value=50, step=5, label="Steps"),
        gr.Slider(3, 12, value=7, step=0.5, label="Guidance"),
        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()
```

## background = Image.open("studio\_bg.jpg")

| A100 | 分辨率  | 帧数 | GPU     | 时间       |
| ---- | ---- | -- | ------- | -------- |
| 1.3B | 480p | 49 | 512x512 | \~2 分钟   |
| 1.3B | 480p | 49 | 按日费率    | \~1.5 分钟 |
| 14B  | 720p | 49 | 按日费率    | 约 5 分钟   |
| 14B  | 720p | 81 | 4 小时会话  | \~8 分钟   |

## 下载所有所需的检查点

典型 CLORE.AI 市场价格：

| GPU           | 验证 CUDA 兼容性 | \~49 帧视频/小时            |
| ------------- | ----------- | ---------------------- |
| RTX 3090 24GB | \~$0.06     | \~20（1.3B）             |
| RTX 4090 24GB | \~$0.10     | \~30（1.3B）             |
| 按日费率          | \~$0.17     | \~40（1.3B） / \~12（14B） |
| 4 小时会话        | \~$0.25     | \~8（14B 高分辨率）          |

*价格各异。查看* [*CLORE.AI 市场*](https://clore.ai/marketplace) *A100 40GB*

## # 使用固定种子以获得一致结果

### 内存不足

```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      |
| 支持 I2V | 是          | 是           | 是    | 是         |
| 许可     | Apache 2.0 | 打开          | 打开   | 打开        |

**何时使用 Wan2.1：**

* 需要开源的视频生成
* 希望快速生成速度
* 需要 Apache 2.0 许可
* 需要平衡的质量/速度

## 使用以下方式支付

* [混元视频（Hunyuan Video）](https://docs.clore.ai/guides/guides_v2-zh/shi-pin-sheng-cheng/hunyuan-video) - 替代的 T2V
* [OpenSora](https://docs.clore.ai/guides/guides_v2-zh/shi-pin-sheng-cheng/opensora) - Open Sora 替代方案
* [Stable Video Diffusion](https://docs.clore.ai/guides/guides_v2-zh/shi-pin-sheng-cheng/stable-video-diffusion) - 图像动画
* [RIFE 插值](https://docs.clore.ai/guides/guides_v2-zh/shi-pin-chu-li/rife-interpolation) - 帧插值


---

# Agent Instructions: 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:

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

The question should be specific, self-contained, and written in natural language.
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.
