CogVideoX SAT 权重推理与微调实战指南:从权重下载、DiT 配置到 LoRA 导出的完整工作流
CogVideoX SAT 权重推理与微调实战指南:从权重下载、DiT 配置到 LoRA 导出的完整工作流
本指南以仓库 sat/README_ja.md 为核心骨架,系统讲解基于 SAT(SwissArmyTransformer) 权重格式的 CogVideoX 系列模型(CogVideoX-2B / 5B / 1.5-5B)的推理与微调全流程。你将掌握:SAT 权重与 HuggingFace 权重格式的本质差异、模型/VAE/T5 三件套的下载与目录组织、cogvideox_*.yaml 与 inference.yaml 的每个关键参数、文本到视频的三种提示词输入方式、全量微调与 LoRA 微调的配置方法,以及最终将 SAT 权重转换为 HuggingFace Diffusers 格式、导出 LoRA 权重的实操命令。文中所有配置与命令均可在当前仓库 sat/ 目录下找到对应文件并直接复用。
一、SAT 权重体系与代码结构概览
当前仓库的 sat 目录承载的是使用 SAT 权重的推理代码与微调代码。SAT 是智谱 AI 开源的分布式训练与推理框架(SwissArmyTransformer),其 checkpoint 格式与 HuggingFace 的格式不同——前者是面向 DeepSpeed/模型并行训练组织的分片状态文件(典型如 mp_rank_00_model_states.pt),后者则是按 pytorch_model.bin/safetensors 组织。因此仓库专门提供了 sat/sample_video.py(推理入口)、sat/train_video.py(微调入口),以及 tools/convert_weight_sat2hf.py(SAT→HF 转换工具)。
需要特别留意版本边界:本分支(CogVideoX1.5 系列)仅支持 CogVideoX1.5 及更新模型;如果你关心 CogVideoX1.0 版本,需要切换到仓库对应的 v1.0 标签查找对应的 SAT 文件夹,切勿混用权重。从源码结构看,sat/diffusion_video.py 定义了 SATVideoDiffusionEngine,sat/dit_video_concat.py 定义了 DiffusionTransformer 及位置编码、Patch 嵌入、AdaLN、FinalLayer 等 Mixin,sat/data_video.py 定义了训练数据集 SFTDataset——这些正是配置文件中 target 字段指向的实现类,后续所有配置都围绕这三者展开。
二、环境准备与依赖安装
进入 sat 目录前,请先确保本文件夹所需依赖已全部安装:
pip install -r requirements.txt
sat/requirements.txt 会拉取 SAT、omegaconf、einops、imageio、torchvision 等推理/微调所需组件。微调场景还需要可用的 DeepSpeed 环境(见 sat/train_video.py 中 from sat.training.deepspeed_training import training_main 的调用链)。
三、模型权重下载:Transformers、VAE、T5 三件套
推理一个 CogVideoX 视频生成模型需要三类权重:DiT 主干(transformer)、3D VAE(vae)、T5 文本编码器(t5-v1_1-xxl)。以下按模型系列给出下载方式。
3.1 CogVideoX1.5 系列(推荐 git lfs)
CogVideoX1.5-5B 的 SAT 镜像仓库一次包含全部三件(Transformers、VAE、T5 Encoder):
git lfs install
git clone https://huggingface.co/THUDM/CogVideoX1.5-5B-SAT
由于权重文件体积大,官方建议使用 git lfs;未安装时可先执行 git lfs install 完成 LFS 初始化。
3.2 CogVideoX-2B(清华云盘 zip 方式)
mkdir CogVideoX-2b-sat
cd CogVideoX-2b-sat
wget https://cloud.tsinghua.edu.cn/f/fdba7608a49c463ba754/?dl=1
mv 'index.html?dl=1' vae.zip
unzip vae.zip
wget https://cloud.tsinghua.edu.cn/f/556a3e1329e74f1bac45/?dl=1
mv 'index.html?dl=1' transformer.zip
unzip transformer.zip
即分别下载 vae.zip 与 transformer.zip 并解压到同一目录。
3.3 CogVideoX-5B 系列
CogVideoX-5B 的 transformer 权重与 2B 不同(VAE 与 2B 相同,无需重复下载),并提供文生视频(T2V)与图生视频(I2V)两个版本:
- CogVideoX-5B:云盘目录
fcef5b3904294a6885e5 - CogVideoX-5B-I2V:云盘目录
5cc62a2d6e7d45c0a2f6
3.4 权重目录组织方式
下载完成后,transformer 与 vae 必须按下述结构摆放,推理与微调时通过配置中的 load / ckpt_path 指向它们:
.
├── transformer
│ ├── 1000 (or 1)
│ │ └── mp_rank_00_model_states.pt
│ └── latest
└── vae
└── 3d-vae.pt
从仓库源码 sat/sample_video.py 看,sat.training.model_io.load_checkpoint 负责加载这种 SAT 分片 checkpoint;latest 文件用于标记当前迭代版本,训练过程中每次保存都会更新。
3.5 准备 T5 文本编码器(safetensors 格式)
T5 仅作为文本编码器(Encoder)使用,不需要训练或微调。推荐从 HuggingFace 克隆 CogVideoX-2b 仓库,再抽取其中的 text_encoder 与 tokenizer 重组为 t5-v1_1-xxl 目录:
git clone https://huggingface.co/THUDM/CogVideoX-2b.git # HuggingFace 下载
# git clone https://www.modelscope.cn/ZhipuAI/CogVideoX-2b.git # Modelscope 下载
mkdir t5-v1_1-xxl
mv CogVideoX-2b/text_encoder/* CogVideoX-2b/tokenizer/* t5-v1_1-xxl
这样重组得到的 T5 为 safetensors 格式,可在 DeepSpeed 微调过程中无报错加载(safetensors 不受 torch 权重文件名的 pytorch_model.bin 限制)。重组后的 t5-v1_1-xxl 目录应包含 8 个文件:
├── added_tokens.json
├── config.json
├── model-00001-of-00002.safetensors
├── model-00002-of-00002.safetensors
├── model.safetensors.index.json
├── special_tokens_map.json
├── spiece.model
└── tokenizer_config.json
0 directories, 8 files
注意:CogVideoX1.5 系列配置直接使用 HuggingFace Hub 上的
google/t5-v1_1-xxl路径(见下节 1.5 配置差异对照),2B/5B 则使用本地t5-v1_1-xxl目录。二者以具体cogvideox_*.yaml中的model_dir为准。
四、推理配置详解:configs/cogvideox_*.yaml
下载完权重后,需要编辑 sat/configs/cogvideox_*.yaml(如 cogvideox_2b.yaml、cogvideox_5b.yaml、cogvideox1.5_5b.yaml)。该文件是模型架构 + 去噪器 + 条件编码器 + VAE + 采样器的完整声明,下面以文档给出的 2B 示例逐段拆解(以下配置与仓库 cogvideox_2b.yaml 一致,仅路径按注释填写):
model:
scale_factor: 1.55258426
disable_first_stage_autocast: true
log_keys:
- txt
denoiser_config:
target: sgm.modules.diffusionmodules.denoiser.DiscreteDenoiser
params:
num_idx: 1000
quantize_c_noise: False
weighting_config:
target: sgm.modules.diffusionmodules.denoiser_weighting.EpsWeighting
scaling_config:
target: sgm.modules.diffusionmodules.denoiser_scaling.VideoScaling
discretization_config:
target: sgm.modules.diffusionmodules.discretizer.ZeroSNRDDPMDiscretization
params:
shift_scale: 3.0
network_config:
target: dit_video_concat.DiffusionTransformer
params:
time_embed_dim: 512
elementwise_affine: True
num_frames: 49
time_compressed_rate: 4
latent_width: 90
latent_height: 60
num_layers: 30
patch_size: 2
in_channels: 16
out_channels: 16
hidden_size: 1920
adm_in_channels: 256
num_attention_heads: 30
transformer_args:
checkpoint_activations: True ## using gradient checkpointing
vocab_size: 1
max_sequence_length: 64
layernorm_order: pre
skip_init: false
model_parallel_size: 1
is_decoder: false
modules:
pos_embed_config:
target: dit_video_concat.Basic3DPositionEmbeddingMixin
params:
text_length: 226
height_interpolation: 1.875
width_interpolation: 1.875
patch_embed_config:
target: dit_video_concat.ImagePatchEmbeddingMixin
params:
text_hidden_size: 4096
adaln_layer_config:
target: dit_video_concat.AdaLNMixin
params:
qk_ln: True
final_layer_config:
target: dit_video_concat.FinalLayerMixin
conditioner_config:
target: sgm.modules.GeneralConditioner
params:
emb_models:
- is_trainable: false
input_key: txt
ucg_rate: 0.1
target: sgm.modules.encoders.modules.FrozenT5Embedder
params:
model_dir: "t5-v1_1-xxl" # CogVideoX-2b/t5-v1_1-xxl 权重文件夹的绝对路径
max_length: 226
first_stage_config:
target: vae_modules.autoencoder.VideoAutoencoderInferenceWrapper
params:
cp_size: 1
ckpt_path: "CogVideoX-2b-sat/vae/3d-vae.pt" # CogVideoX-2b-sat/vae/3d-vae.pt 文件的绝对路径
ignore_keys: [ 'loss' ]
loss_config:
target: torch.nn.Identity
regularizer_config:
target: vae_modules.regularizers.DiagonalGaussianRegularizer
encoder_config:
target: vae_modules.cp_enc_dec.ContextParallelEncoder3D
params:
double_z: true
z_channels: 16
resolution: 256
in_channels: 3
out_ch: 3
ch: 128
ch_mult: [ 1, 2, 2, 4 ]
attn_resolutions: [ ]
num_res_blocks: 3
dropout: 0.0
gather_norm: True
decoder_config:
target: vae_modules.cp_enc_dec.ContextParallelDecoder3D
params:
double_z: True
z_channels: 16
resolution: 256
in_channels: 3
out_ch: 3
ch: 128
ch_mult: [ 1, 2, 2, 4 ]
attn_resolutions: [ ]
num_res_blocks: 3
dropout: 0.0
gather_norm: False
loss_fn_config:
target: sgm.modules.diffusionmodules.loss.VideoDiffusionLoss
params:
offset_noise_level: 0
sigma_sampler_config:
target: sgm.modules.diffusionmodules.sigma_sampling.DiscreteSampling
params:
uniform_sampling: True
num_idx: 1000
discretization_config:
target: sgm.modules.diffusionmodules.discretizer.ZeroSNRDDPMDiscretization
params:
shift_scale: 3.0
sampler_config:
target: sgm.modules.diffusionmodules.sampling.VPSDEDPMPP2MSampler
params:
num_steps: 50
verbose: True
discretization_config:
target: sgm.modules.diffusionmodules.discretizer.ZeroSNRDDPMDiscretization
params:
shift_scale: 3.0
guider_config:
target: sgm.modules.diffusionmodules.guiders.DynamicCFG
params:
scale: 6
exp: 5
num_steps: 50
逐块要点如下:
scale_factor:潜空间缩放因子,用于将 VAE 编码得到的 latent 乘以该系数后再送入 DiT(反向则在解码前除以该系数)。需要说明的是,仓库实际 cogvideox_2b.yaml 中该值为1.15258426,5B 为0.7;文档示例中的1.55258426与仓库文件存在出入,请以仓库内实际配置文件为准。denoiser_config:离散去噪器DiscreteDenoiser,num_idx: 1000对应 1000 步离散时间表;weighting_config使用EpsWeighting(对 epsilon 预测目标加权),scaling_config使用VideoScaling(视频专用的噪声缩放),discretization_config使用ZeroSNRDDPMDiscretization并带shift_scale: 3.0——这是 CogVideoX 采用 Zero-SNR 时间离散化以改善视频生成首帧/连续性设计的体现。network_config:指向 sat/dit_video_concat.py 中的DiffusionTransformer。num_frames: 49、time_compressed_rate: 4表示 VAE 在时间维度压缩 4 倍,49 帧视频对应 13 帧 latent;latent_width/height: 90/60与patch_size: 2决定 token 数量;num_layers: 30、hidden_size: 1920、num_attention_heads: 30是 2B 主干的规模参数。transformer_args.checkpoint_activations: True开启梯度检查点(训练省显存)。modules:Basic3DPositionEmbeddingMixin使用可学习 3D 位置嵌入,text_length: 226与 T5 的max_length: 226对应;height_interpolation/width_interpolation: 1.875用于将 256×256 的基础位置编码插值到更高分辨率。ImagePatchEmbeddingMixin将文本隐状态(text_hidden_size: 4096,即 T5-XXL 的维度)与视频 patch 嵌入拼接。AdaLNMixin以qk_ln: True开启 Q/K 上的 LayerNorm(参考 LLaMA-Adapter 的归一化做法)。FinalLayerMixin输出最终的噪声预测。conditioner_config:GeneralConditioner+FrozenT5Embedder,ucg_rate: 0.1表示训练时以 10% 概率随机丢弃文本条件(classifier-free guidance 所需);is_trainable: false固定 T5 参数。对应源码 sgm/modules/encoders/modules.py 中的冻结 T5 封装。first_stage_config:3D VAE。VideoAutoencoderInferenceWrapper是推理包装器,cp_size: 1关闭上下文并行;编码器/解码器分别使用ContextParallelEncoder3D/ContextParallelDecoder3D,double_z: true、z_channels: 16说明 latent 维度为 16(与in_channels/out_channels: 16呼应),ch_mult: [1,2,2,4]、num_res_blocks: 3为 3D 卷积 U-Net 的通道缩放与残差块数。推理阶段loss_config用torch.nn.Identity占位,ignore_keys: ['loss']忽略 checkpoint 中的 loss 键。loss_fn_config:训练用VideoDiffusionLoss,offset_noise_level: 0、DiscreteSampling均匀采样 1000 个噪声档位。sampler_config:推理采样器为VPSDEDPMPP2MSampler(50 步 PPM 采样器),并搭配DynamicCFG引导器——scale: 6、exp: 5是动态 CFG 的缩放强度与指数,num_steps: 50与采样步数一致。这一引导策略在sgm/modules/diffusionmodules/guiders.py中有对应实现,用于在前几步使用较弱引导、逐步增强,从而改善提示词服从度。
4.1 2B / 5B / 1.5-5B 配置差异对照
同一 cogvideox_*.yaml 骨架在不同参数规模下数值不同,以下对照表整理自仓库实际配置文件(cogvideox_2b.yaml、cogvideox_5b.yaml、cogvideox1.5_5b.yaml),供选型与排查时对照:
| 配置项 | CogVideoX-2B | CogVideoX-5B | CogVideoX1.5-5B |
|---|---|---|---|
scale_factor |
1.15258426 | 0.7 | 0.7 |
shift_scale |
3.0 | 1.0 | (默认) |
num_frames |
49 | 49 | 81(10 秒用 161) |
latent_width/height |
90 / 60 | 90 / 60 | 300 / 300 |
num_layers |
30 | 42 | 42 |
patch_size |
2 | 2 | [2, 2, 2] |
hidden_size |
1920 | 3072 | 3072 |
num_attention_heads |
30 | 48 | 48 |
| 位置编码 | Basic3DPositionEmbeddingMixin |
Rotary3DPositionEmbeddingMixin |
Rotary3DPositionEmbeddingMixin |
text_length(T5 max_length) |
226 | 226 | 224 |
model_dir |
本地 t5-v1_1-xxl |
本地 t5-v1_1-xxl |
google/t5-v1_1-xxl |
| 精度建议 | fp16 | bf16 | bf16 |
可以看出 5B 相比 2B 主干加深加宽(42 层、3072 隐藏维、48 头),位置编码由可学习 3D 嵌入升级为旋转式 3D 位置嵌入(Rotary3DPositionEmbeddingMixin,按头维度 64 施加旋转);1.5 系列则进一步把时间帧数提升到 81(5 秒)/161(10 秒)、空间分辨率提升到 300×300 latent,并引入 latent_input: true(直接以 latent 作为输入,见 cogvideox1.5_5b.yaml)。
五、configs/inference.yaml 与三种输入方式
推理参数集中在 sat/configs/inference.yaml(文档示例,与仓库 inference.yaml 同骨架、数值略有差异,以下保留文档版本并标注当前仓库默认值):
args:
latent_channels: 16
mode: inference
load: "{absolute_path/to/your}/transformer" # CogVideoX-2b-sat/transformer 文件夹的绝对路径
# load: "{your lora folder} such as zRzRzRzRzRzRzR/lora-disney-08-20-13-28" # 加载不含 lora adapter 的全量模型时使用
batch_size: 1
input_type: txt # "txt" 表示纯文本文件输入,"cli" 表示命令行输入
input_file: configs/test.txt # 纯文本文件,可编辑
sampling_num_frames: 13 # CogVideoX1.5-5B 需为 42 或 22;CogVideoX-5B / 2B 需为 13、11 或 9
sampling_fps: 8
fp16: True # CogVideoX-2B 使用
# bf16: True # CogVideoX-5B 使用
output_dir: outputs/
force_inference: True
各参数含义与注意事项:
mode: inference:推理模式标记,与sample_video.py的分支逻辑对应(详见下文调用链)。load:指向第 3 节组织的transformer文件夹的绝对路径;若是加载微调产出的含 LoRA 适配器模型,则改为 LoRA 输出目录。当前仓库 inference.yaml 额外提供sampling_image_size: [768, 1360]与sampling_fps: 16(注释注明 42 帧约 10 秒、22 帧约 5 秒),并默认使用bf16: True——请以当前仓库默认值为准,按你的模型与卡型调整。sampling_num_frames:输出视频帧数,必须与模型系列匹配:1.5-5B 取 42 或 22,5B/2B 取 13、11 或 9。帧数最终会经 VAE 时间压缩率(4 倍)换算为实际视频帧数。sampling_fps:输出视频帧率,常见取值 8 或 16。fp16/bf16:按模型选择精度——CogVideoX-2B 用 fp16,CogVideoX-5B/1.5 用 bf16(二者互斥,只开其一)。force_inference: True:强制推理模式,忽略 checkpoint 中可能缺失的键(例如 T5 与 VAE 单独加载的场景)。
5.1 输入方式一:txt 文件批量提示词
使用包含多个提示词的文本文件时,编辑 configs/test.txt,每行一条 prompt。如果不知道怎么写提示词,可使用 inference/convert_demo.py 调用 LLM 对提示词进行补全与润色(该工具与 sat 目录同级,位于仓库 inference 目录)。
5.2 输入方式二:命令行交互
将配置改为:
input_type: cli
之后每次推理会从命令行读取 prompt。对应实现位于 sat/sample_video.py 的 read_from_cli():不断提示 Please input English text (Ctrl-D quit),按 Ctrl-D 结束输入循环;而 txt 文件方式则走 read_from_file(p, rank, world_size),并支持按 rank 分片读取(多卡并行时每条 prompt 分配给不同进程)。
5.3 输出位置
如需修改输出视频保存位置,编辑:
output_dir: outputs/
默认保存在 .outputs/ 文件夹下。
六、运行推理:inference.sh 与调用链
配置就绪后执行:
bash inference.sh
sat/inference.sh 的内容是(仓库当前默认指向 1.5-5B):
#! /bin/bash
echo "CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES"
environs="WORLD_SIZE=1 RANK=0 LOCAL_RANK=0 LOCAL_WORLD_SIZE=1"
run_cmd="$environs python sample_video.py --base configs/cogvideox1.5_5b.yaml configs/inference.yaml --seed $RANDOM"
echo ${run_cmd}
eval ${run_cmd}
echo "DONE on `hostname`"
底层调用链(可对照 sat/sample_video.py)为:sample_video.py 解析 --base 指定的模型配置与推理配置 → 通过 SATVideoDiffusionEngine 组装去噪器/条件器/VAE → load_checkpoint 加载 SAT 权重 → 按 input_type 读取 prompt → get_batch 构造带无条件分支(batch_uc,即空文本条件)的采样批次 → 经 DynamicCFG 引导完成 50 步 PPM 采样 → VAE 解码 → 以 save_video_as_grid_and_mp4 写出 mp4。多 prompt 时循环处理;--seed $RANDOM 每次运行随机种子,便于复现时改为固定值。
七、微调(Fine-tuning):全量微调与 LoRA
微调仅针对 transformer(DiT)部分,VAE 保持不变,T5 仅作为编码器不参与训练。支持两种方式:LoRA 与全量参数微调。
7.1 数据集准备
数据集必须组织为 labels 与 videos 两个平级目录,txt 标签文件与视频文件同名一一对应:
.
├── labels
│ ├── 1.txt
│ ├── 2.txt
│ ├── ...
└── videos
├── 1.mp4
├── 2.mp4
├── ...
- 每个 txt 文件包含对应视频的标签(描述文本),视频与标签一一对应;避免一个视频对应多个标签。
- 做风格微调时,建议准备至少 50 条风格相似的视频+标签,以促进风格拟合。
数据集加载由 data_video.SFTDataset 实现(见 sat/data_video.py 与 sft.yaml 中的 data 段:video_size: [480, 720]、fps: 8、max_num_frames: 49、skip_frms_num: 3),它会按帧数采样视频片段并配对标签文本。
7.2 全量微调配置:configs/sft.yaml
按如下方式修改 sat/configs/sft.yaml(文档片段,标注含义如下):
# checkpoint_activations: True ## 使用梯度检查点(配置文件中两处 `checkpoint_activations` 都需要设为 True)
model_parallel_size: 1 # 模型并行大小
experiment_name: lora-disney # 实验名(不要改动)
mode: finetune # 模式(不要改动)
load: "{your_CogVideoX-2b-sat_path}/transformer" ## Transformer 模型路径
no_load_rng: True # 是否加载随机数种子
train_iters: 1000 # 训练迭代数
eval_iters: 1 # 验证迭代数
eval_interval: 100 # 验证间隔
eval_batch_size: 1 # 验证批大小
save: ckpts # 模型保存路径
save_interval: 100 # 保存间隔
log_interval: 20 # 日志输出间隔
train_data: [ "your train data path" ]
valid_data: [ "your val data path" ] # 训练集与验证集可以相同
split: 1,0,0 # 训练、验证、测试集比例
num_workers: 8 # 数据加载器 worker 数
force_train: True # 加载 checkpoint 时允许 missing keys(T5 与 VAE 单独加载)
only_log_video_latents: True # 避免 VAE 解码带来的显存占用
deepspeed:
bf16:
enabled: False # CogVideoX-2B 设为 False,CogVideoX-5B 设为 True
fp16:
enabled: True # CogVideoX-2B 设为 True,CogVideoX-5B 设为 False
补充仓库 sft.yaml 中的实际完整 DeepSpeed 块,便于直接参考(当前默认面向 8×A100 的 5B 场景):
deepspeed:
train_micro_batch_size_per_gpu: 2
gradient_accumulation_steps: 1
steps_per_print: 50
gradient_clipping: 0.1
zero_optimization:
stage: 2
cpu_offload: false
contiguous_gradients: false
overlap_comm: true
reduce_scatter: true
reduce_bucket_size: 1000000000
allgather_bucket_size: 1000000000
load_from_fp32_weights: false
zero_allow_untested_optimizer: true
bf16:
enabled: True # For CogVideoX-2B Turn to False and For CogVideoX-5B Turn to True
fp16:
enabled: False # For CogVideoX-2B Turn to True and For CogVideoX-5B Turn to False
loss_scale: 0
loss_scale_window: 400
hysteresis: 2
min_loss_scale: 1
optimizer:
type: sat.ops.FusedEmaAdam
params:
lr: 0.00001 # Between 1E-3 and 5E-4 For Lora and 1E-5 For SFT
betas: [ 0.9, 0.95 ]
eps: 1e-8
weight_decay: 1e-4
关键点解读:
checkpoint_activations:模型配置(cogvideox_*.yaml的transformer_args)与sft.yaml两处都要设为 True,才真正启用梯度检查点。force_train: True:加载 checkpoint 时允许missing keys,因为 T5 与 VAE 是单独加载的,DiT checkpoint 天然缺少这些键。only_log_video_latents: True:验证阶段只记录 latent 而不走 VAE 解码,大幅降低显存占用。- 精度开关:2B 用 fp16(
bf16.enabled=False, fp16.enabled=True),5B 用 bf16(反之),避免溢出。 - 优化器:
sat.ops.FusedEmaAdam,学习率建议:LoRA 用1e-3 ~ 5e-4区间,SFT 全量微调用1e-5量级。 - 迭代量:
train_iters: 1000起步,LoRA 建议 1000 以上,SFT 500 即可(见 sft.yaml 注释)。
7.3 LoRA 微调配置:cogvideox_<参数规模>_lora.yaml
使用 LoRA 时,还需修改 cogvideox_<model parameters>_lora 文件。以 CogVideoX-2B 为例(对应仓库 cogvideox_2b_lora.yaml):
model:
scale_factor: 1.55258426
disable_first_stage_autocast: true
not_trainable_prefixes: [ 'all' ] ## 取消注释以解锁
log_keys:
- txt
lora_config: ## 取消注释以解锁
target: sat.model.finetune.lora2.LoraMixin
params:
r: 256
not_trainable_prefixes: ['all']:将所有前缀标记为不可训练,再通过LoraMixin注入低秩可训练矩阵——这正是 LoRA 只训练注入矩阵的实现机制(对应 SAT 的sat.model.finetune.lora2.LoraMixin)。lora_config.r:低秩维度。文档示例为 256,仓库 cogvideox_2b_lora.yaml 实际默认r: 128。r 越大,可训练参数量与拟合能力越强,同时占用更多显存。
7.4 修改运行脚本并启动训练
编辑 sat/finetune_single_gpu.sh 或 sat/finetune_multi_gpus.sh,选择对应配置。两个示例:
- CogVideoX-2B + LoRA:
run_cmd="torchrun --standalone --nproc_per_node=8 train_video.py --base configs/cogvideox_2b_lora.yaml configs/sft.yaml --seed $RANDOM"
- CogVideoX-2B + 全量微调:
run_cmd="torchrun --standalone --nproc_per_node=8 train_video.py --base configs/cogvideox_2b.yaml configs/sft.yaml --seed $RANDOM"
说明:当前仓库 finetune_single_gpu.sh 默认执行
configs/cogvideox_2b_lora.yaml configs/sft.yaml;finetune_multi_gpus.sh 默认指向test_cogvideox_5b_i2v_lora.yaml test_sft.yaml(示例文件,需按需替换为上述正式配置)。--standalone --nproc_per_node=8表示单机 8 卡启动;单卡场景可参考单卡脚本中的单进程启动方式。
启动训练:
bash finetune_single_gpu.sh # 单 GPU
bash finetune_multi_gpus.sh # 多 GPU
7.5 使用微调后的模型进行推理
微调产出的模型不能与原始模型合并(LoRA 权重以附加低秩矩阵形式存在)。修改推理启动脚本 inference.sh:
run_cmd="$environs python sample_video.py --base configs/cogvideox_<model parameters>_lora.yaml configs/inference.yaml --seed 42"
然后运行:
bash inference.sh
注意此时 --base 第一项必须是对应的 cogvideox_*_lora.yaml(加载 LoRA 适配器),inference.yaml 中的 load 应指向训练输出的 LoRA 目录(如 zRzRzRzRzRzRzR/lora-disney-08-20-13-28)。
八、权重转换与 LoRA 导出:对接 HuggingFace Diffusers
8.1 SAT → HuggingFace Diffusers 权重转换
SAT 权重格式与 HuggingFace 格式不同,需要转换。运行:
python ../tools/convert_weight_sat2hf.py
该脚本位于仓库 tools/convert_weight_sat2hf.py,负责将 SAT 的分片 checkpoint(mp_rank_00_model_states.pt)重命名重组为 Diffusers 可加载的权重布局。转换完成后即可在 HF 生态的 Diffusers 推理脚本中使用。仓库还提供 tools/convert_weight_deepspeed2hf.py 用于 DeepSpeed 零冗余优化状态到 HF 格式的转换。
8.2 导出 LoRA 权重(SAT → HuggingFace Diffusers)
支持将 SAT 的 LoRA 权重导出为 HuggingFace Diffusers 格式。训练完成后,可在 {args.save}/1000/1000/mp_rank_00_model_states.pt 找到带 LoRA 权重的 SAT 模型。
导出脚本 export_sat_lora_weight.py 位于仓库 tools/export_sat_lora_weight.py,导出后使用 tools/load_cogvideox_lora.py 进行推理加载。
导出命令:
python tools/export_sat_lora_weight.py --sat_pt_path {args.save}/{experiment_name}-09-09-21-10/1000/mp_rank_00_model_states.pt --lora_save_directory {args.save}/export_hf_lora_weights_1/
其中 --sat_pt_path 指向训练输出的 SAT 状态文件,--lora_save_directory 指定 HF 格式 LoRA 权重的输出目录。
8.3 SAT 与 HF 的 LoRA 结构映射
训练过程中模型结构被修改——LoRA 在注意力结构中添加低秩权重。以下映射表是 SAT 结构与 HF Diffusers LoRA 结构之间的对应关系:
'attention.query_key_value.matrix_A.0': 'attn1.to_q.lora_A.weight',
'attention.query_key_value.matrix_A.1': 'attn1.to_k.lora_A.weight',
'attention.query_key_value.matrix_A.2': 'attn1.to_v.lora_A.weight',
'attention.query_key_value.matrix_B.0': 'attn1.to_q.lora_B.weight',
'attention.query_key_value.matrix_B.1': 'attn1.to_k.lora_B.weight',
'attention.query_key_value.matrix_B.2': 'attn1.to_v.lora_B.weight',
'attention.dense.matrix_A.0': 'attn1.to_out.0.lora_A.weight',
'attention.dense.matrix_B.0': 'attn1.to_out.0.lora_B.weight'
解读:SAT 侧注意力模块为 attention.query_key_value(QKV 合并投影)与 attention.dense(输出投影),LoRA 注入的 matrix_A/matrix_B 分别对应 HF Diffusers 侧 attn1.to_q / to_k / to_v 与 attn1.to_out.0 的 lora_A.weight / lora_B.weight。export_sat_lora_weight.py 会依据该映射把 SAT LoRA 转成 HF 格式。
九、常见问题与注意事项
- 版本边界:本分支仅支持 CogVideoX1.5 系列及更新模型;CogVideoX1.0 需使用 v1.0 标签的 SAT 文件夹。
- 精度与显存:2B 走 fp16,5B/1.5 走 bf16;训练开启
checkpoint_activations(模型配置与 sft 配置两处)可显著降低显存;only_log_video_latents可避免验证阶段 VAE 解码的额外显存开销。 - T5 加载:2B/5B 需要把
text_encoder与tokenizer重组为本地t5-v1_1-xxl的 safetensors 目录,否则 DeepSpeed 加载会报错;1.5 直接使用 Hub 路径google/t5-v1_1-xxl。 - 配置数值:文档示例与仓库实际配置文件在个别数值上存在出入(如
scale_factor、sampling_fps),落地时以仓库内 sat/configs/ 下的实际 YAML 为准。 - 帧数取值:
sampling_num_frames必须匹配模型系列(1.5 取 42/22,5B/2B 取 13/11/9),否则 latent 时间维与模型预设不符,可能导致推理失败。 - LoRA 不可合并:微调后的 LoRA 模型必须通过
cogvideox_*_lora.yaml+ 指向 LoRA 目录的方式推理,导出 HF 格式后则用 tools/load_cogvideox_lora.py 加载。
至此,从 SAT 权重下载、模型配置、推理执行到全量/LoRA 微调、再到 HuggingFace 生态的权重导出,整套 CogVideoX SAT 工作流即可完整跑通。更多细节可对照 sat/README.md(英文版)与仓库内对应的源码与配置文件深入阅读。