# 从Wan2.1-T2V-1.3B开始整个LightX2V项目

我们推荐从Wan2.1-T2V-1.3B开始整个LightX2V项目，不管你是想使用什么模型，我们都建议先看一下这个文档，了解整个LightX2V的运行流程。

## 准备环境

请参考[01.PrepareEnv](01.PrepareEnv.md)

## 开始运行

准备模型(huggingface和modelscope，任选其一下载)

```
# download from huggingface
hf download Wan-AI/Wan2.1-T2V-1.3B --local-dir Wan-AI/Wan2.1-T2V-1.3B

# download from modelscope
modelscope download --model Wan-AI/Wan2.1-T2V-1.3B --local_dir Wan-AI/Wan2.1-T2V-1.3B
```

我们提供三种方式，来运行Wan2.1-T2V-1.3B模型生成视频：

1. 运行脚本生成视频: 预设的bash脚本，可以直接运行，便于快速验证
2. 启动服务生成视频: 先启动服务，再发请求，适合多次推理和实际的线上部署
3. python代码生成视频: 用python代码运行，便于集成到已有的代码环境中

### 运行脚本生成视频

```
git clone https://github.com/ModelTC/LightX2V.git
cd LightX2V/scripts/wan

# 运行下面的脚本之前，需要将脚本中的lightx2v_path和model_path替换为实际路径
# 例如：lightx2v_path=/home/user/LightX2V
# 例如：model_path=/home/user/models/Wan-AI/Wan2.1-T2V-1.3B

bash run_wan_t2v.sh
```

解释细节

run_wan_t2v.sh脚本内容如下：
```
#!/bin/bash

# set path firstly
lightx2v_path=
model_path=

export CUDA_VISIBLE_DEVICES=0

# set environment variables
source ${lightx2v_path}/scripts/base/base.sh

python -m lightx2v.infer \
--model_cls wan2.1 \
--task t2v \
--model_path $model_path \
--config_json ${lightx2v_path}/configs/wan/wan_t2v.json \
--prompt "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage." \
--negative_prompt "镜头晃动，色调艳丽，过曝，静态，细节模糊不清，字幕，风格，作品，画作，画面，静止，整体发灰，最差质量，低质量，JPEG压缩残留，丑陋的，残缺的，多余的手指，画得不好的手部，画得不好的脸部，畸形的，毁容的，形态畸形的肢体，手指融合，静止不动的画面，杂乱的背景，三条腿，背景人很多，倒着走" \
--save_result_path ${lightx2v_path}/save_results/output_lightx2v_wan_t2v.mp4
```

`export CUDA_VISIBLE_DEVICES=0` 表示使用0号显卡

`source ${lightx2v_path}/scripts/base/base.sh` 设置一些基础的环境变量

`--model_cls wan2.1` 表示使用wan2.1模型

`--task t2v` 表示使用t2v任务

`--model_path` 表示模型的路径

`--config_json` 表示配置文件的路径

`--prompt` 表示提示词

`--negative_prompt` 表示负向提示词

`--save_result_path` 表示保存结果的路径

由于不同的模型都有其各自的特性，所以`config_json`文件中会存有对应模型的更多细节的配置参数，不同模型的`config_json`文件内容有所不同，

wan_t2v.json文件内容如下：
```
{
    "infer_steps": 50,
    "target_video_length": 81,
    "text_len": 512,
    "target_height": 480,
    "target_width": 832,
    "self_attn_1_type": "flash_attn3",
    "cross_attn_1_type": "flash_attn3",
    "cross_attn_2_type": "flash_attn3",
    "sample_guide_scale": 6,
    "sample_shift": 8,
    "enable_cfg": true,
    "cpu_offload": false
}
```
其中一些重要的配置参数说明：

`infer_steps` 表示推理的步数

`target_video_length` 表示目标视频的帧数(对于wan2.1模型来说，fps=16，所以target_video_length=81，表示视频时长为5秒)

`target_height` 表示目标视频的高度

`target_width` 表示目标视频的宽度

`self_attn_1_type`, `cross_attn_1_type`, `cross_attn_2_type` 表示wan2.1模型内部的三个注意力层的算子的类型，这里使用flash_attn3，仅限于Hopper架构的显卡(H100, H20等)，其他显卡可以使用flash_attn2进行替代

`enable_cfg` 表示是否启用cfg，这里设置为true，表示会推理两次，第一次使用正向提示词，第二次使用负向提示词，这样可以得到更好的效果，但是会增加推理时间，如果是已经做了CFG蒸馏的模型，这里就可以设置为false

`cpu_offload` 表示是否启用cpu offload，这里设置为false，表示不启用cpu offload，Wan2.1-T2V-1.3B模型的显存在480*832的生成分辨率下，消耗显存约21GB，如果显存不足，则需要开启cpu_offload。

上述wan_t2v.json文件，可以作为H100，H200，H20的标准配置文件，对于A100-80G, 4090-24G和5090-32G等显卡，把flash_attn3替换为flash_attn2


### 启动服务生成视频

在实际部署中，我们往往是启动一个服务，用户发送请求进行生成任务。

启动服务
```
cd LightX2V/scripts/server

# 运行下面的脚本之前，需要将脚本中的lightx2v_path和model_path替换为实际路径
# 例如：lightx2v_path=/home/user/LightX2V
# 例如：model_path=/home/user/models/Wan-AI/Wan2.1-T2V-1.3B

bash start_server.sh
```

start_server.sh脚本内容如下
```
#!/bin/bash

# set path firstly
lightx2v_path=
model_path=

export CUDA_VISIBLE_DEVICES=0

# set environment variables
source ${lightx2v_path}/scripts/base/base.sh


# Start API server with distributed inference service
python -m lightx2v.server \
--model_cls wan2.1 \
--task t2v \
--model_path $model_path \
--config_json ${lightx2v_path}/configs/wan/wan_t2v.json \
--host 0.0.0.0 \
--port 8000
```

`--host 0.0.0.0`和`--port 8000`，表示服务起在本机ip的8000端口上

`--config_json`和前面脚本推理所用的配置文件保持一致

向服务端发送请求

此处需要打开第二个终端作为用户
```
cd LightX2V/scripts/server

python post.py
```
发送完请求后，可以在服务端看到推理的日志

post.py脚本内容如下
```
import requests
from loguru import logger

if __name__ == "__main__":
    url = "http://localhost:8000/v1/tasks/video/"

    message = {
        "prompt": "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage.",
        "negative_prompt": "镜头晃动，色调艳丽，过曝，静态，细节模糊不清，字幕，风格，作品，画作，画面，静止，整体发灰，最差质量，低质量，JPEG压缩残留，丑陋的，残缺的，多余的手指，画得不好的手部，画得不好的脸部，畸形的，毁容的，形态畸形的肢体，手指融合，静止不动的画面，杂乱的背景，三条腿，背景人很多，倒着走",
        "image_path": "",
        "seed": 42,
        "save_result_path": "./cat_boxing_seed42.mp4"
    }

    logger.info(f"message: {message}")

    response = requests.post(url, json=message)

    logger.info(f"response: {response.json()}")

```

url = "http://localhost:8000/v1/tasks/video/" 表示向本机ip的8000端口上，发送一个视频生成任务

如果是图像生成任务，url就是

url = "http://localhost:8000/v1/tasks/image/"

message字典表示向服务端发送的请求的内容，其中`seed`若不指定，每次发送请求会随机生成一个`seed`，`save_result_path`若不指定也会生成一个和任务id一致命名的文件


### python代码生成视频

新建pytest.py文件，运行前需设置环境变量
```
#例如：
cd /pytest_path
export PYTHONPATH=lightx2v_path
#再运行代码
python pytest.py
```

pytest.py脚本内容如下
```
from lightx2v import LightX2VPipeline

# 步骤1: 创建LightX2VPipeline
pipe = LightX2VPipeline(
    model_path="/data/nvme0/models/Wan-AI/Wan2.1-T2V-1.3B",
    model_cls="wan2.1",
    task="t2v",
)

# 步骤2: 设置运行中的参数

# 可以通过传入config的方式，设置运行中的参数
# 也可以通过函数参数传入的方式，设置运行中的参数
# 二者只能选其一，不可同时使用

# 方式1: 传入config文件路径 (create_generator的方式1和方式2一次只能选择一个使用!)
# pipe.create_generator(config_json="path_to_config/wan_t2v.json")

# 方式2: 函数参数传入 (create_generator的方式1和方式2一次只能选择一个使用!)
pipe.create_generator(
    attn_mode="sage_attn2",
    infer_steps=50,
    height=480,  # Can be set to 720 for higher resolution
    width=832,  # Can be set to 1280 for higher resolution
    num_frames=81,
    guidance_scale=5.0,
    sample_shift=5.0,
)


# 步骤3: 开始生成视频，可以多次生成

# 第一个生成case
seed = 42
prompt = "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage."
negative_prompt = "镜头晃动，色调艳丽，过曝，静态，细节模糊不清，字幕，风格，作品，画作，画面，静止，整体发灰，最差质量，低质量，JPEG压缩残留，丑陋的，残缺的，多余的手指，画得不好的手部，画得不好的脸部，畸形的，毁容的，形态畸形的肢体，手指融合，静止不动的画面，杂乱的背景，三条腿，背景人很多，倒着走"
save_result_path = "./cat_boxing_seed42.mp4"

pipe.generate(
    seed=seed,
    prompt=prompt,
    negative_prompt=negative_prompt,
    save_result_path=save_result_path,
)

# 第二个生成case
seed = 1000
prompt = "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage."
negative_prompt = "镜头晃动，色调艳丽，过曝，静态，细节模糊不清，字幕，风格，作品，画作，画面，静止，整体发灰，最差质量，低质量，JPEG压缩残留，丑陋的，残缺的，多余的手指，画得不好的手部，画得不好的脸部，畸形的，毁容的，形态畸形的肢体，手指融合，静止不动的画面，杂乱的背景，三条腿，背景人很多，倒着走"
save_result_path = "./cat_boxing_seed1000.mp4"

pipe.generate(
    seed=seed,
    prompt=prompt,
    negative_prompt=negative_prompt,
    save_result_path=save_result_path,
)
```

注意1：步骤2设置运行中的参数中，推荐使用传入config_json的方式，用来和前面的运行脚本生成视频和启动服务生成视频进行超参数对齐

注意2：前面的运行脚本生成视频会额外设置一些环境变量，相关变量在[这里](https://github.com/ModelTC/LightX2V/blob/main/scripts/base/base.sh)，其中`export PROFILING_DEBUG_LEVEL=2`可以把推理耗时日志打开，为了完全对齐，可以在运行上面的python代码之前，把这些环境变量先设置好。
