Wan2.2 TI2V-5B 在 Linux 服务器上的本地部署与 HTTP 服务化实践
这篇文章记录我在一台 Linux 服务器上,从 0 开始部署 Wan2.2-TI2V-5B,到最终通过 HTTP 接口调用生成视频 的完整过程。
目标是两件事:
- 以后忘了流程时,可以按这篇文章重新部署成功
- 给后续做服务化、前端调用、自动化任务留一份可复用的基础文档
我的实际环境是:
- Linux 服务器
- NVIDIA RTX 4090
- Python 3.10
- 中国大陆网络环境
- 最终通过
python generate.py成功生成视频 - 后续再封装成 FastAPI HTTP 接口
一、为什么选 TI2V-5B
Wan2.2 有多个模型,我这次选的是 TI2V-5B,原因很直接:
- 支持 Text-to-Video
- 也支持 Image-to-Video
- 对消费级显卡更友好
- 比较适合单机本地部署验证
如果目标是先把流程跑通,TI2V-5B 是更合适的起点。
二、部署前最重要的一个认知:Python 环境一定要干净
我一开始机器登录后默认是:
which python
/usr/anaconda3/bin/python
也就是说,服务器默认在 conda base 里。
最开始我直接用:
python -m venv /home/chenqi/venvs/wan22
这样创建出来的 venv 虽然“技术上没错”,但它底层还是基于 Anaconda 的 Python 3.13。 这就带来两个问题:
- 环境容易混乱
torch、flash-attn这类大模型依赖对 Python 版本比较敏感,3.13 太新,不适合优先尝试
结论
不要直接用 conda base 的 python 去建这个环境。 更稳的做法是:用系统 Python 3.10 重建 venv。
三、重新创建正确的 Python 3.10 虚拟环境
1. 检查 Python 3.10 是否存在
/usr/bin/python3.10 --version
如果提示没有,就安装:
apt update
apt install -y python3.10 python3.10-venv python3-pip
2. 删除旧环境,重建新环境
rm -rf /home/chenqi/venvs/wan22
/usr/bin/python3.10 -m venv /home/chenqi/venvs/wan22
3. 激活环境
source /home/chenqi/venvs/wan22/bin/activate
4. 验证是否真的进入了正确环境
不要只看提示符,要看这些:
which python
which pip
echo $VIRTUAL_ENV
python --version
python -m pip --version
理想结果应该类似:
/home/chenqi/venvs/wan22/bin/python
/home/chenqi/venvs/wan22/bin/pip
/home/chenqi/venvs/wan22
Python 3.10.x
5. 升级安装工具链
python -m pip install -U pip setuptools wheel packaging
这一步很重要,因为后面要装:
- torch
- flash-attn
- modelscope
- 其他编译/依赖型包
如果 pip/setuptools/wheel/packaging 太旧,很容易出奇怪错误。
四、安装 PyTorch,并验证 CUDA
1. 安装 PyTorch
我最后成功使用的是:
- Python 3.10
- Torch 2.6.0+cu124
安装命令是按 PyTorch 官方 CUDA wheel 路线来的,实际装的时候可以按自己机器驱动情况选对应命令。
示例:
python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
2. 验证 torch 和 CUDA 是否正常
python - <<'PY'
import torch, sys
print("python:", sys.executable)
print("torch:", torch.__version__)
print("torch file:", torch.__file__)
print("cuda available:", torch.cuda.is_available())
if torch.cuda.is_available():
print("gpu:", torch.cuda.get_device_name(0))
PY
我最终的关键输出是:
torch: 2.6.0+cu124cuda available: Truegpu: NVIDIA GeForce RTX 4090
这说明:
- Python 环境已经正确
- PyTorch 已经能识别显卡
- CUDA 路径没问题
五、安装系统基础工具
后面要用到:
gitffmpeggcc/g++/makeninja
先检查:
command -v git
command -v ffmpeg
command -v gcc
command -v g++
command -v make
command -v ninja
如果缺了就安装:
apt update
apt install -y git ffmpeg build-essential ninja-build
六、克隆 Wan2.2 仓库
第一次部署时:
cd ~
git clone https://github.com/Wan-Video/Wan2.2.git
cd ~/Wan2.2
这里有一个容易误会的小点:
git clone是第一次拉代码git pull是本地已经有仓库时更新代码
所以:
- 第一次 clone 后,不需要立刻再 pull
- 只有以后你想更新仓库时才需要
git pull
七、安装依赖时最难的坑:flash-attn
1. 先安装普通依赖,不要一上来就装 flash-attn
我最后采用的是“普通依赖先装,flash-attn 单独装”的思路。
cd ~/Wan2.2
grep -v '^flash_attn$' requirements.txt > requirements.no_fa.txt
python -m pip install -r requirements.no_fa.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
这样做的原因很简单:
flash-attn最容易出问题- 单独装最方便排错
八、flash-attn 的真实踩坑过程
这是我这次部署里最典型的坑。
1. 一开始 flash-attn 导入失败
报错类似:
undefined symbol: ... c10::Error ...
这种错误不是“没装”,而是:
flash-attn 编译/安装时依赖的 torch 版本,和当前运行时加载的 torch 不匹配。
我当时的环境是:
torch 2.6.0+cu124flash-attn 2.8.3
结果导入失败。
2. 解决办法
先卸载:
python -m pip uninstall -y flash-attn flash_attn
python -m pip cache purge
再安装一个更稳的版本:
MAX_JOBS=4 python -m pip install flash-attn==2.7.4.post1 --no-build-isolation -i https://pypi.tuna.tsinghua.edu.cn/simple
3. 验证
python - <<'PY'
try:
import flash_attn
print("flash_attn ok")
except Exception as e:
print("flash_attn not ready:", e)
PY
最终成功输出:
flash_attn ok
4. 经验总结
如果看到这种导入时的 .so undefined symbol 错误,不要纠结“是不是没装上”,更可能是:
- torch 和 flash-attn 二进制不兼容
- 卸载重装一个更稳的 flash-attn 版本即可
九、国内网络环境下下载模型
在中国大陆,不建议优先走 Hugging Face。 更稳的方式是:
- 代码:GitHub
- 模型:ModelScope
- Python 包:清华/国内 PyPI 镜像
安装 ModelScope:
python -m pip install modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple
下载模型:
cd ~/Wan2.2
modelscope download Wan-AI/Wan2.2-TI2V-5B --local_dir ./Wan2.2-TI2V-5B
下载完后确认目录存在:
ls ~/Wan2.2/Wan2.2-TI2V-5B
十、第一次运行时又遇到的坑:requirements 不完整
模型下载完成后,我开始运行:
python generate.py \
--task ti2v-5B \
--size 1280*704 \
--ckpt_dir ./Wan2.2-TI2V-5B \
--offload_model True \
--convert_model_dtype \
--t5_cpu \
--prompt "一只白猫戴着墨镜坐在冲浪板上,夏日海边,电影感光影,镜头缓慢推进"
结果连续遇到了几个 ModuleNotFoundError:
1. 缺 decord
安装:
python -m pip install -U decord -i https://pypi.tuna.tsinghua.edu.cn/simple
验证:
python - <<'PY'
import decord
print("decord ok:", decord.__version__)
PY
2. 缺 librosa
安装:
python -m pip install -U librosa -i https://pypi.tuna.tsinghua.edu.cn/simple
验证:
python - <<'PY'
import librosa
print("librosa ok:", librosa.__version__)
PY
3. 缺 peft
安装:
python -m pip install -U peft -i https://pypi.tuna.tsinghua.edu.cn/simple
验证:
python - <<'PY'
import peft
print("peft ok:", peft.__version__)
PY
4. 经验总结
这说明这份仓库在当时的依赖声明里,并不是完全齐全的。 遇到这类错误时,处理方式很固定:
python -m pip show 包名- 没装就
python -m pip install -U 包名 - 再
import验证
十一、第一次真正生成时,误以为程序在用 CPU
运行时我看到 top 里 Python 进程占了很多 CPU,误以为没有使用 GPU。
实际上并不是。
因为我用的是这组参数:
--offload_model True
--convert_model_dtype
--t5_cpu
这意味着:
- 一部分工作故意放到 CPU
- 一部分工作仍然在 GPU 上
- 这是“CPU + GPU 混合运行”
真正的判断方式不是看 top,而是看:
nvidia-smi
我的实际输出显示:
- 显存占用 21GB+
- GPU-Util 100%
- Python 进程占着 GPU
这说明:
核心计算已经在 GPU 上,而且 GPU 已经满载。
结论: 看到 CPU 很忙,不代表没用 GPU。
十二、第一次 720P 生成失败:最后一步 OOM
第一次完整跑到结尾时,扩散采样 50/50 已经跑完了,但最后报:
torch.OutOfMemoryError: CUDA out of memory
而且出错点不在采样阶段,而是在 VAE decode 阶段。
这说明:
- 主体生成已经成功
- 最后把 latent 解码成视频时,显存差一点点
我的显卡是 4090 24GB,这种情况其实很常见。
解决办法 1:启用 PyTorch 显存碎片优化
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
解决办法 2:不要用有显示占用的那张卡
我的服务器有两张 4090,其中:
- GPU 0 连着显示
- GPU 1 几乎空闲
所以最后我改成:
export CUDA_VISIBLE_DEVICES=1
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
然后再跑同一条命令。
最终成功命令
export CUDA_VISIBLE_DEVICES=1
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
cd ~/Wan2.2
python generate.py \
--task ti2v-5B \
--size 1280*704 \
--ckpt_dir ./Wan2.2-TI2V-5B \
--offload_model True \
--convert_model_dtype \
--t5_cpu \
--prompt "一只白猫戴着墨镜坐在冲浪板上,夏日海边,电影感光影,镜头缓慢推进"
经验总结
如果 4090 跑到最后一步 OOM,不要第一时间怀疑环境坏了。 更大的可能是:
- 分辨率高
- decode 阶段显存峰值更大
- 显存碎片导致最后差一点
- 当前 GPU 还承担了显示/其他进程
优先尝试:
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True- 换一张更干净的 GPU
- 仍不行再降分辨率
十三、到这里,CLI 部署已经成功
当 generate.py 最终能成功输出视频时,说明以下环节都已经打通:
- Python 环境 OK
- torch + CUDA OK
- flash-attn OK
- 模型权重 OK
- Wan2.2 本体 OK
- 单机推理 OK
接下来进入第二阶段:HTTP 服务化。
十四、为什么要封装 HTTP 接口
直接用:
python generate.py ...
只能手工在服务器命令行里跑。
如果想让:
- 前端页面调用
- 其他程序调用
- 内网服务调用
- 自动化任务调用
最方便的办法就是封装成 HTTP API。
十五、服务化设计思路
因为单次生成时间比较长,不适合做同步阻塞接口,所以我最后采用的是这种思路:
POST /generate:提交任务GET /tasks/{task_id}:查询状态GET /files/{filename}:下载视频
实现方式:
- 用 FastAPI
- Web 进程接收请求
- 后台线程启动一个子进程去执行
generate.py - 子进程结束后,把结果记录下来
- 用户轮询任务状态
为什么不用“直接在 FastAPI 里 import 模型”
因为当前已经验证成功的是 CLI 路径。
直接包装 generate.py 是最稳的:
- 改动最小
- 出错边界清晰
- 不会把模型状态污染到 Web 主进程
十六、安装 Web 依赖
python -m pip install -U fastapi uvicorn[standard] python-multipart -i https://pypi.tuna.tsinghua.edu.cn/simple
其中:
fastapi:Web 框架uvicorn:ASGI 服务python-multipart:以后做图片上传用
十七、FastAPI 实现思路
核心要点:
- 请求进入 API
- 生成
task_id - 开后台线程
- 线程里调用
subprocess.run(["python", "generate.py", ...]) - 任务结束后记录输出文件
- 提供下载接口返回 mp4
关键设计原则
- 一次只跑一个任务
- 不建议并发多个任务抢同一张 4090
- 当前单次生成已经接近 24GB 显存上限
- 并发很容易直接 OOM
十八、启动服务
在项目目录中:
uvicorn app:app --host 0.0.0.0 --port 8000
十九、HTTP 调用示例
1. 文生视频
curl -X POST "http://你的服务器IP:8000/generate" \
-H "Content-Type: application/json" \
-d '{
"prompt": "一只白猫戴着墨镜坐在冲浪板上,夏日海边,电影感光影,镜头缓慢推进",
"size": "1280*704",
"task": "ti2v-5B",
"offload_model": true,
"convert_model_dtype": true,
"t5_cpu": true
}'
2. 查询任务状态
curl "http://你的服务器IP:8000/tasks/<task_id>"
3. 下载视频
curl -O "http://你的服务器IP:8000/files/<filename>.mp4"
4. 图生视频
curl -X POST "http://你的服务器IP:8000/generate-with-image" \
-F 'prompt=夏日海边度假风,一只戴墨镜的白猫坐在冲浪板上,近景镜头' \
-F 'size=1280*704' \
-F 'image=@/path/to/input.jpg'
二十、这次部署的完整最终结论
成功的关键点
- 必须用 Python 3.10 的干净 venv
- 不要直接沿用 conda base 的 Python 3.13 环境
- PyTorch 要先装好并验证 CUDA
flash-attn要单独处理,且版本要和 torch 匹配- 模型下载在大陆优先走 ModelScope
- Wan2.2 依赖可能不完整,缺什么补什么
- 4090 跑 720P 时,最后 decode 可能 OOM
- 用空闲 GPU +
expandable_segments:True可以提高成功率 - 服务化最稳的方式是 FastAPI + 子进程调用 generate.py
二十一、我最终可复现的最小成功路径
环境准备
apt update
apt install -y python3.10 python3.10-venv python3-pip git ffmpeg build-essential ninja-build
rm -rf /home/chenqi/venvs/wan22
/usr/bin/python3.10 -m venv /home/chenqi/venvs/wan22
source /home/chenqi/venvs/wan22/bin/activate
python -m pip install -U pip setuptools wheel packaging
安装 torch
python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
安装 Wan2.2 代码和依赖
cd ~
git clone https://github.com/Wan-Video/Wan2.2.git
cd ~/Wan2.2
grep -v '^flash_attn$' requirements.txt > requirements.no_fa.txt
python -m pip install -r requirements.no_fa.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
安装 flash-attn
python -m pip uninstall -y flash-attn flash_attn
python -m pip cache purge
MAX_JOBS=4 python -m pip install flash-attn==2.7.4.post1 --no-build-isolation -i https://pypi.tuna.tsinghua.edu.cn/simple
补齐额外缺失依赖
python -m pip install -U decord librosa peft modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple
下载模型
cd ~/Wan2.2
modelscope download Wan-AI/Wan2.2-TI2V-5B --local_dir ./Wan2.2-TI2V-5B
成功运行命令
export CUDA_VISIBLE_DEVICES=1
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
cd ~/Wan2.2
python generate.py \
--task ti2v-5B \
--size 1280*704 \
--ckpt_dir ./Wan2.2-TI2V-5B \
--offload_model True \
--convert_model_dtype \
--t5_cpu \
--prompt "一只白猫戴着墨镜坐在冲浪板上,夏日海边,电影感光影,镜头缓慢推进"
二十二、以后如果我忘了流程,按什么顺序排查
如果以后重新部署失败,我会按这个顺序检查:
第 1 层:Python 环境
which python
python --version
python -m pip --version
第 2 层:torch + CUDA
python - <<'PY'
import torch
print(torch.__version__)
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))
PY
第 3 层:flash-attn
python - <<'PY'
import flash_attn
print("flash_attn ok")
PY
第 4 层:模型目录
ls ~/Wan2.2/Wan2.2-TI2V-5B
第 5 层:运行时显卡状态
nvidia-smi
第 6 层:遇到缺包就补
decordlibrosapeft- 其他
ModuleNotFoundError指向的包
第 7 层:最后一步 OOM
优先尝试:
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
export CUDA_VISIBLE_DEVICES=1
二十三、后续可以继续优化的方向
这次我先做到“能本地稳定生成 + 能 HTTP 调用”。 后面还可以继续做:
- 用
systemd把 API 服务做成开机自启 - 用 Nginx 反向代理
- 加 API key 鉴权
- 加任务队列,避免并发冲突
- 把日志落盘
- 加 Web 管理页面
- 接 Redis / Celery 做异步任务系统
最后的总结
这次部署最核心的经验只有一句话:
Wan2.2 本地部署并不只是“装个包、跑条命令”,真正决定成败的是 Python 环境、torch/flash-attn 兼容、缺失依赖补齐,以及 24GB 显存下最后 decode 阶段的处理。
只要把这几个关键点记住,后面再重新部署,成功率就会非常高。
评论
欢迎留下反馈,评论发布后会立即显示。