视频模型部署
- [LongCat-Video 部署历险记](#LongCat-Video 部署历险记)
-
- 视频模型和LLM模型区别
- [LongCat-Video 模型比较](#LongCat-Video 模型比较)
- 环境准备
LongCat-Video 部署历险记
刷魔塔的时候发现美团新上架了一个 LongCat-Video-Avatar-1.5 模型,是 LongCat-Video的新版,本着好奇心,打算利用手头的凉快 A800 部署下尝尝鲜,毕竟还没部署过视频模型。
书接上回,假设已经读过前两篇文章,大模型部署,vllm 部署 GLM-4.7 了解了基础大模型环境。
视频具有上传至视频托管平台https://catbox.moe/,可直接预览。
GLM-4.7 使用vllm 部署,使用的是uv环境;LongCat-Video 使用的是 conda 工具,是 python 的另一个虚拟环境管理工具。
视频模型和LLM模型区别
md
文本大模型:
模型权重 + vLLM/Ollama/SGLang → 文本推理服务
LongCat-Video:
模型权重 + LongCat-Video 项目代码 → 视频生成推理
LongCat-Video 代码 = 运行 LongCat 视频模型权重的推理代码/工具
但它和 vLLM/Ollama 有几个区别。
1. vLLM/Ollama 是通用文本 LLM 推理框架
它们主要处理:
- 文本 token 输入
- 文本 token 输出
- KV Cache
- 并发调度
- OpenAI API
所以能跑很多模型:
Qwen
GLM
DeepSeek
Llama
Mistral
2. LongCat-Video 是专用视频生成推理管线
它处理的是:
文本 / 图片 / 音频
↓
视频生成模型
↓
VAE 解码
↓
多帧图像
↓
ffmpeg 合成视频
所以它要自己处理:
- 视频帧
- 音频
- VAE
- diffusion/DiT 采样
- 多卡 context parallel
- 输出 mp4
- 输入 JSON
- 随机种子
- 分辨率/帧数
这些不是 vLLM/Ollama 的职责。
3. 它不会默认提供 API
vLLM/Ollama 启动后一般直接有 HTTP API。
LongCat-Video 官方代码更多是:
torchrun run_demo_xxx.py ...
也就是"跑一次生成任务"。
如果你要对外提供服务,需要自己再包一层:
FastAPI / Flask
↓
调用 LongCat-Video 推理代码
↓
返回 task_id / 视频地址
所以最终可以总结为:
vLLM/Ollama 是通用推理服务框架
LongCat-Video 仓库是专用多模态推理工程
两者本质上都在做:
加载模型权重 → 执行推理 → 得到输出
只是文本模型已经高度标准化,而视频生成模型还需要专用代码来承载。
LongCat-Video 模型比较
- LongCat-Video
- LongCat-Video-Avatar
- LongCat-Video-Avatar-1.5
meituan-longcat/LongCat-Video
这是基础视频生成模型 foundational video generation
它主要做:
- 文本生成视频:Text-to-Video
- 图片生成视频:Image-to-Video
- 视频续写:Video-Continuation
- 长视频生成
- 交互式视频生成
meituan-longcat/LongCat-Video-Avatar
这是第一版 Avatar 模型
single- and multi-character audio-driven video generation (wav2vec2)
它主要做:
- 音频 + 文本 → 人物说话视频
- 音频 + 图片 → 人物说话视频
- 多人音频驱动视频
- Avatar 视频续写
它用的是 wav2vec2 音频编码器,适合:
给一段音频,让人物开口说话
meituan-longcat/LongCat-Video-Avatar-1.5
这是升级版 Avatar 模型
upgraded avatar model with Whisper-large-v3 audio encoder, distillation-based fast inference
相对 Avatar 1.0,它主要升级了:
- 用 Whisper-large-v3 替代 wav2vec2
- 唇形同步更好
- 支持蒸馏加速,--use_distill
- 支持 INT8 降显存,--use_int8
- 长视频稳定性更好
- 对动漫、动物、复杂真实场景泛化更好
对应命令里会加:
--model_type avatar-v1.5 --use_distill --use_int8
环境准备
安装 conda
conda 是一个 Python 环境管理工具。它的作用类似 uv venv / virtualenv,但更擅长处理一些带 C/CUDA/音视频依赖的包,比如 ffmpeg、librosa、pytorch 这类。 -- 摘自 GPT-5.5
shell
cd /tmp
curl -L -o Miniconda3-latest-Linux-x86_64.sh \
https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
# 这个shell 脚本150mb,震惊,,,
bash Miniconda3-latest-Linux-x86_64.sh
# 安装过程一路回车、敲 yes
# 安装后 刷新下shell 环境,做验证
source ~/.bashrc
conda --version
conda 26.3.2
# 安装成功
# 关闭自动进入conda base 环境
conda config --set auto_activate_base false
下载 LongCat-Video 代码
shell
mkdir LongCat-Video && cd LongCat-Video
conda create -n longcat-video python=3.10
conda activate longcat-video
# 会下载安装一下依赖,中间按 y 同意
# 下载源码
git clone https://github.com/meituan-longcat/LongCat-Video.git
安装相关依赖
这里,有很多坑,一步一步踩过来的,建议可以同步下载模型权重文件
shell
pip install torch==2.6.0+cu124 torchvision==0.21.0+cu124 torchaudio==2.6.0+cu124 \
-i https://mirrors.aliyun.com/pypi/simple \
--extra-index-url https://download.pytorch.org/whl/cu124 \
--trusted-host mirrors.aliyun.com
# ... ...
Successfully installed MarkupSafe-3.0.3 filelock-3.29.0 fsspec-2026.4.0 jinja2-3.1.6 mpmath-1.3.0 networkx-3.4.2 numpy-2.2.6 nvidia-cublas-cu12-12.4.5.8 nvidia-cuda-cupti-cu12-12.4.127 nvidia-cuda-nvrtc-cu12-12.4.127 nvidia-cuda-runtime-cu12-12.4.127 nvidia-cudnn-cu12-9.1.0.70 nvidia-cufft-cu12-11.2.1.3 nvidia-curand-cu12-10.3.5.147 nvidia-cusolver-cu12-11.6.1.9 nvidia-cusparse-cu12-12.3.1.170 nvidia-cusparselt-cu12-0.6.2 nvidia-nccl-cu12-2.21.5 nvidia-nvjitlink-cu12-12.4.127 nvidia-nvtx-cu12-12.4.127 pillow-12.2.0 sympy-1.13.1 torch-2.6.0+cu124 torchaudio-2.6.0+cu124 torchvision-0.21.0+cu124 triton-3.2.0 typing-extensions-4.15.0
# ################### 这一步很慢,手动 export http_proxy https_proxy 一把。
conda install -y cuda-toolkit=12.4 \
--override-channels \
-c nvidia \
-c conda-forge
## 使用镜像加速安装,多个安装项整理成一条
pip install ninja psutil packaging -i https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com && pip install flash_attn==2.7.4.post1 --no-build-isolation -i https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com && pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
# 继续安装 conda 依赖,注意, 这里会有版本关联性
conda install -y -c conda-forge librosa && conda install -y -c conda-forge ffmpeg
# 最后一步,安装 requirements_avatar.txt 这里也有大坑,要调整下安装版本 https://www.modelscope.cn/models/meituan-longcat/LongCat-Video-Avatar-1.5/feedback
tr ' ' '\n' < requirements_avatar.txt | grep -v -E '^(libsndfile1|tritonserverclient)==' > /tmp/requirements_avatar_fixed.txt
pip install -r /tmp/requirements_avatar_no_libsndfile.txt -i \
https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
# 生成视频的时候也会出错,在安装一个依赖
pip install accelerate
整个过程挺折磨的,失败了一次又一次,不停的调整 脚本,也许下一次可以直接让 codex 生成一段提示词,然后交给他来干。
下载模型
直接开了三个终端,放那里慢慢下,下班回家了。我是用vllm-env 环境中的 hf 工具下载的,下载完成后在 mv weights LongCat-Video 目录中。
shell
export HF_ENDPOINT=https://hf-mirror.com
export HF_XET_HIGH_PERFORMANCE=1
hf download meituan-longcat/LongCat-Video --local-dir ./weights/LongCat-Video
hf download meituan-longcat/LongCat-Video-Avatar --local-dir ./weights/LongCat-Video-Avatarhf download meituan-longcat/LongCat-Video-Avatar-1.5 --local-dir ./weights/LongCat-Video-Avatar-1.5
生成视频尝鲜
直接运行官方的demo
显存不够也会 oom
rank0: torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 32.00 MiB. GPU 0 has a total capacity of 79.25 GiB of which 22.69 MiB is free. Process 3249812 has 2.18 GiB memory in use. Process
1035443 has 73.24 GiB memory in use. Including non-PyTorch memory, this process has 3.77 GiB memory in use. Of the allocated memory 3.37 GiB is allocated by PyTorch, and 1.87 MiB is reserved by PyTorch but
unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management
(https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)
文生视频
shell
torchrun --nproc_per_node=2 run_demo_text_to_video.py \
--context_parallel_size=2 \
--checkpoint_dir=./weights/LongCat-Video \
--enable_compile
# 大概要等10分钟,期间显存占用40G左右,负载是100%
# 在深度学习里,模型权重训练过程中, checkpoint 是模型权重目录,hf 下载模型权重的时候执行了目录,执行的时候指定模型权重目录。
# 推理过程中显卡使用情况
Wed Jun 3 14:24:36 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 595.58.03 Driver Version: 595.58.03 CUDA Version: 13.2 |
+-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA A800 80GB PCIe Off | 00000000:0A:00.0 Off | 0 |
| N/A 65C P0 332W / 300W | 47841MiB / 81920MiB | 100% Default |
| | | Disabled |
+-----------------------------------------+------------------------+----------------------+
| 1 NVIDIA A800 80GB PCIe Off | 00000000:AE:00.0 Off | 0 |
| N/A 63C P0 344W / 300W | 45305MiB / 81920MiB | 99% Default |
| | | Disabled |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 2048957 C .../longcat-video/bin/python3.10 45596MiB |
| 0 N/A N/A 3249812 C /usr/bin/python3 2230MiB |
| 1 N/A N/A 2048958 C .../longcat-video/bin/python3.10 45296MiB |
+-----------------------------------------------------------------------------------------+
最终会生成三个视频
shell
-rw-r--r-- 1 root root 1.4M Jun 3 14:32 output_t2v_distill.mp4
-rw-r--r-- 1 root root 1.5M Jun 3 14:30 output_t2v.mp4
-rw-r--r-- 1 root root 16M Jun 3 14:36 output_t2v_refine.mp4
run_demo_text_to_video.py 脚本描述内容大概是
- 正向提示词
它描述的是一个写实摄影风格的公园场景:
一个 7-8 岁左右的白人男孩坐在公园长椅上,穿浅蓝 T 恤、牛仔短裤、白色运动鞋,手里拿着香草和巧克力口味的冰淇淋。旁边有一只中等体型的金色拉布拉多。男孩微笑着把冰淇淋递给狗,狗伸舌头舔冰淇淋。阳光明媚,背景是绿色草坪和高树,整体是温暖、有爱的场景。
- 约束重点:
realistic photography style 写实摄影风格
主体:男孩 + 金色拉布拉多
动作:男孩递冰淇淋,狗舔冰淇淋
环境:公园长椅、草坪、高树、阳光
氛围:warm and loving scene
- 负向提示词
negative_prompt 是用来约束"不希望出现什么"的:
tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers,
poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards
大意是避免:
过曝、画面静止、细节模糊、字幕、绘画感、低质量、JPEG 压缩痕迹、丑、不完整、多手指、手/脸画坏、肢体畸形、融合手指、静态图片、背景混乱、三条腿、背景人太多、倒着走
这些负向词主要是在压制视频生成常见问题:畸形、静态、模糊、低质、背景混乱。
-
生成参数
-
第一阶段 output_t2v.mp4:
height=480
width=832
num_frames=93
num_inference_steps=50
guidance_scale=4.0
fps=15
大约是:
93 帧 / 15 fps ≈ 6.2 秒
-
第二阶段 output_t2v_distill.mp4:
num_inference_steps=16
use_distill=True
guidance_scale=1.0
它加载了:
lora/cfg_step_lora.safetensors
用于更快的蒸馏版本生成。
-
第三阶段 output_t2v_refine.mp4:
加载 refinement_lora.safetensors
开启 BSA
基于 output_distill 做 refine
num_inference_steps=50
fps=30
crf=10
所以 output_t2v_refine.mp4 是精修后的最终版本,质量和码率更高。
这个 demo 做了三件事:
- 用固定 prompt 生成 480p 文生视频:output_t2v.mp4
- 用蒸馏 LoRA 快速生成一版:output_t2v_distill.mp4
- 用 refinement LoRA 把 distill 结果精修成最终视频:output_t2v_refine.mp4
-
图生视频
shell
torchrun --nproc_per_node=2 run_demo_image_to_video.py --context_parallel_size=2 --checkpoint_dir=./weights/LongCat-Video --enable_compile
这次生成大概耗时20分钟,生成产物
shell
-rw-r--r-- 1 root root 9.7M Jun 3 15:07 output_i2v_distill.mp4
-rw-r--r-- 1 root root 11M Jun 3 15:05 output_i2v.mp4
-rw-r--r-- 1 root root 55M Jun 3 15:12 output_i2v_refine.mp4
run_demo_image_to_video.py 拆解
- 正向提示词
它描述的是一个咖啡馆里的女性动作场景:
一个女人坐在窗边舒适咖啡馆的木桌旁。她伸出右手,从杯碟上拿起白色咖啡杯,轻轻送到嘴边喝了一口。喝完后,她把杯子放回桌上,然后看向窗外,享受安静平和的氛围。
- 输入图片约束
脚本固定读取:
assets/girl.png
所以这个 demo 不是凭空生成画面,而是基于这张图片生成后续动作视频。
- 约束重点
场景:窗边、咖啡馆、木桌
主体:一个女人
关键物体:白色咖啡杯、杯碟
动作链路:伸右手 → 拿起杯子 → 送到嘴边 → 喝一口 → 放回桌上 → 看向窗外
氛围:cozy café、peaceful atmosphere,温暖、安静、生活感
生成模式:保持输入图像主体和场景一致,让图片"动起来"
- 负向提示词
negative_prompt 是用来约束"不希望出现什么"的:
Bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers,
poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards
大意是避免:
过亮色调、过曝、画面静止、细节模糊、字幕、绘画感、低质量、JPEG 压缩痕迹、丑、不完整、多手指、手画坏、脸画坏、变形、毁容、肢体畸形、手指融合、静态图片、背景混乱、三条腿、背景人太多、倒着走。
这些负向词主要是在压制图生视频常见问题:
人物手部畸形、脸部崩坏、动作不自然、画面不动、背景混乱、低清晰度、错误肢体。
-
生成参数
-
第一阶段 output_i2v.mp4
基于 assets/girl.png 做普通图生视频:
resolution='480p'
num_frames=93
num_inference_steps=50
guidance_scale=4.0
fps=15
crf=18
大约是:
93 帧 / 15 fps ≈ 6.2 秒
这一阶段会先生成一个 480p 的基础图生视频,然后再 resize 回输入图片的原始尺寸。
-
第二阶段 output_i2v_distill.mp4
使用蒸馏 LoRA 做更快的图生视频:
resolution='480p'
num_frames=93
num_inference_steps=16
use_distill=True
guidance_scale=1.0
fps=15
crf=18
它加载了:
lora/cfg_step_lora.safetensors
作用是用更少采样步数生成一版快速结果。这里没有传 negative_prompt,约束比第一阶段更少,主要依赖 prompt 和蒸馏 LoRA。
-
第三阶段 output_i2v_refine.mp4
对第二阶段的 output_i2v_distill.mp4 做 refine 精修:
加载 lora/refinement_lora.safetensors
开启 BSA
stage1_video=output_distill
num_cond_frames=1
num_inference_steps=50
spatial_refine_only=False
fps=30
crf=10
这一阶段基于第二阶段生成的视频再做细化,输出码率更高、帧率更高:
output_i2v_refine.mp4
通常它是最终更值得看的版本。
-
-
这个 demo 做了三件事
- 读取固定图片 assets/girl.png,用 prompt 生成基础图生视频:output_i2v.mp4
- 加载 cfg_step_lora.safetensors,用 16 步快速生成蒸馏版本:output_i2v_distill.mp4
- 加载 refinement_lora.safetensors,开启 BSA,把蒸馏结果精修成最终视频:output_i2v_refine.mp4
-
和 run_demo_text_to_video.py 的核心区别
run_demo_text_to_video.py 是从文本直接生成画面。
run_demo_image_to_video.py 是先给一张图片,再用文本控制图片里的主体做动作。
所以这个脚本的 prompt 不是单纯描述"要生成什么画面",而是在描述:
这张输入图片里的女人接下来应该如何运动。
视频续写
生成耗时 20分钟,
生成产物
shell
-rw-r--r-- 1 root root 31M Jun 3 15:30 output_vc_distill.mp4
-rw-r--r-- 1 root root 33M Jun 3 15:27 output_vc.mp4
-rw-r--r-- 1 root root 112M Jun 3 15:35 output_vc_refine.mp4
run_demo_video_continuation.py 拆解
- 正向提示词
它描述的是一个摩托车骑行的第一视角公路场景:
一个人骑着摩托车沿着一条笔直的长路前进,道路位于一片水域和森林山坡之间。骑手持续加速,让摩托车保持在护栏之间的中央位置,两侧风景不断掠过。视频从骑手视角记录这段旅程,强调运动感和冒险感。
- 输入视频约束
脚本固定读取:
assets/motorcycle.mp4
所以这个 demo 不是从零生成视频,而是基于已有视频做续写。
- 约束重点
场景:笔直长路、水域、森林山坡、护栏
主体:骑摩托车的人
视角:rider's perspective,骑手第一视角
动作:持续加速、沿道路向前行驶
运动感:两侧风景掠过
氛围:motion and adventure,速度感、旅程感、冒险感
生成模式:保持输入视频的运动方向、场景连续性和视角一致性
- 负向提示词
negative_prompt 是用来约束"不希望出现什么"的:
Bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers,
poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards
大意是避免:
过亮色调、过曝、画面静止、细节模糊、字幕、绘画感、低质量、JPEG 压缩痕迹、丑、不完整、多手指、手画坏、脸画坏、变形、毁容、肢体畸形、手指融合、静态图片、背景混乱、三条腿、背景人太多、倒着走。
这些负向词主要是在压制视频续写常见问题:
画面不动、运动方向错乱、背景混乱、画质下降、畸形物体、错误人物/肢体、出现字幕或绘画风格。
-
条件帧约束
-
num_cond_frames=13
使用输入视频中的前 13 帧作为条件帧,让模型从这段已有视频继续生成。
这些条件帧约束了续写视频的初始画面、视角、场景和运动方向。
-
target_fps=15
脚本会读取原视频 FPS,然后按 target_fps=15 做抽帧:
stride = max(1, round(current_fps / target_fps))
这意味着输入视频会被降采样到接近 15fps 后再作为条件视频使用。
-
-
生成参数
-
第一阶段 output_vc.mp4
基于 assets/motorcycle.mp4 做普通视频续写:
resolution='480p'
num_frames=93
num_cond_frames=13
num_inference_steps=50
guidance_scale=4.0
use_kv_cache=True
offload_kv_cache=False
fps=15
crf=18
大约是:
93 帧 / 15 fps ≈ 6.2 秒
但其中前 13 帧来自输入视频条件帧,所以真正新生成的续写部分大约是:
(93 - 13) / 15 ≈ 5.3 秒
输出时脚本会把输入视频条件帧拼回前面:
output = video::stride + outputnum_cond_frames:
-
第二阶段 output_vc_distill.mp4
使用蒸馏 LoRA 做更快的视频续写:
resolution='480p'
num_frames=93
num_cond_frames=13
num_inference_steps=16
use_distill=True
guidance_scale=1.0
use_kv_cache=True
offload_kv_cache=False
enhance_hf=False
fps=15
crf=18
它加载了:
lora/cfg_step_lora.safetensors
作用是用更少采样步数生成一版快速续写结果。这里没有传 negative_prompt,约束比第一阶段更少。
-
第三阶段 output_vc_refine.mp4
对第二阶段的 output_vc_distill.mp4 做 refine 精修:
加载 lora/refinement_lora.safetensors
开启 BSA
stage1_video=output_distill
spatial_refine_only=False
cur_num_cond_frames=num_cond_frames * 2,也就是 26 帧
num_inference_steps=50
fps=30
crf=10
这里因为 spatial_refine_only=False,所以 refine 阶段使用:
13 * 2 = 26 个条件帧
最终输出:
output_vc_refine.mp4
它通常是最终更值得看的版本,帧率更高、码率更高、画面更精细。
-
-
这个 demo 做了三件事
- 读取固定视频 assets/motorcycle.mp4,用前 13 帧作为条件,生成基础视频续写:output_vc.mp4
- 加载 cfg_step_lora.safetensors,用 16 步快速生成蒸馏续写版本:output_vc_distill.mp4
- 加载 refinement_lora.safetensors,开启 BSA,把蒸馏结果精修成最终视频:output_vc_refine.mp4
-
和前两个 demo 的核心区别
run_demo_text_to_video.py 是从文本直接生成新视频。
run_demo_image_to_video.py 是给一张图片,让图片里的主体动起来。
run_demo_video_continuation.py 是给一段已有视频,让模型沿着原视频内容继续生成后续片段。
所以这个脚本的 prompt 不是单纯描述"生成什么视频",而是在描述:
输入视频后续应该如何运动、如何延续场景和视角。