CatV2TON 代码解读
先说结论:这不是 Wan 2.2,也不是“开源了 LoRA 训练脚本”
我把官方仓库拉到了本地 ~/code/CatV2TON,读完后最关键的判断是:CatV2TON 代码里的默认基座是 alibaba-pai/EasyAnimateV4-XL-2-InP,模型类名是 HunyuanTransformer3DModel,论文也说明 DiT backbone 初始化自 EasyAnimateV4,而 EasyAnimateV4 是在 HunyuanDiT 基础上 fine-tune 的 #CatV2TON。所以它不是 Wan 2.2 路线;如果一定在“Wan 2.2 还是混元”之间二选一,答案更接近混元 / HunyuanDiT 系。
attention 与 posenet 权重。问题 1:代码仓库的整体结构是怎么样的?
这个仓库不是一个从零写起的“小项目”,而是把 CatV2TON 的任务逻辑包在 EasyAnimate、DensePose、Detectron2 等组件之上。最外层只有几个真正属于 CatV2TON 的入口:图像/视频试穿推理、图像/视频指标评测,以及 modules/pipeline.py 里的 V2TON 推理流程。
eval_image_try_on.py图像试穿评测入口。默认 base_model_path 是 alibaba-pai/EasyAnimateV4-XL-2-InP,默认 resume_path 是 zhengchong/CatV2TON,实际加载 512-64K 子目录。eval_video_try_on.py视频试穿评测入口。根据数据集选择 512-64K 或 256-128K,并支持 slice_frames、pre_frames、use_adacn。modules/pipeline.pyCatV2TON 最核心的工程文件:初始化 VAE、DiT、PoseNet;实现 temporal concatenation、denoising、overlapping clip inference 和 AdaCN。modules/posenet.py轻量姿态编码器。它按基座 transformer config 构造,但只保留一个 HunyuanDiTBlock,用于把 DensePose latent 编成可加到 DiT 的 pose embedding。easyanimate/内嵌 EasyAnimate 代码,包含 models/transformer3d.py、MagViT VAE、pipeline、LoRA 工具和 UI 等。CatV2TON 的 DiT 类来自这里。densepose/ 与 detectron2/人体 DensePose 相关依赖。仓库把这些代码也带进来了,便于生成 pose 条件。| 目录 / 文件 | 作用 | 读代码时的定位 |
|---|---|---|
| README.md | 论文链接、权重链接、评测和推理命令 | 用户入口,不含训练命令 |
| eval_image_metrics.py / eval_video_metrics.py | 计算图像与视频指标 | 复现实验指标用 |
| data/ | 视频数据读取与预处理工具 | 主要服务评测/推理数据组织 |
| modules/cloth_masker.py、modules/densepose.py | 衣服 mask 与 DensePose 条件处理 | 把原始图片/视频转成模型条件 |
| modules/fid_metrics/ | FID/VFID 等指标实现 | 视频质量评测依赖 |
| easyanimate/utils/lora_utils.py | EasyAnimate 通用 LoRA 合并/创建工具 | 存在 LoRA 工具,但不是 CatV2TON 训练入口 |
从调用链看,推理入口先下载或读取 base_model_path 与 resume_path,然后构造 V2TONPipeline。这个 pipeline 会从 EasyAnimateV4 读取 MagViT VAE、HunyuanTransformer3DModel 和 scheduler,再从 CatV2TON checkpoint 里加载 attention 与 posenet 两部分权重。
问题 2:模型基于哪个大模型?多少层?多大参数量?
代码里的直接证据在 eval_image_try_on.py:--base_model_path 默认值就是 alibaba-pai/EasyAnimateV4-XL-2-InP。论文进一步说明,CatV2TON 的 DiT backbone 初始化自 EasyAnimateV4,而 EasyAnimateV4 是基于 HunyuanDiT fine-tune 的视频生成模型;视频 VAE 使用预训练 MagViT #CatV2TON。
基座归属
不是 Wan 2.2。代码类名是 HunyuanTransformer3DModel,论文说 EasyAnimateV4 fine-tuned based on HunyuanDiT。因此 CatV2TON 应理解为 EasyAnimateV4 / HunyuanDiT 系 DiT 上的试穿适配。
层数方面,本地 easyanimate/models/transformer3d.py 中 HunyuanTransformer3DModel 的默认 num_layers 是 28,并据此构造 self.blocks = nn.ModuleList([... for layer in range(num_layers)])。PoseNet 也读取同一份 transformer config,但实现上只实例化一个 HunyuanDiTBlock,不是复制完整 28 层。
| 问题 | 答案 | 依据 |
|---|---|---|
| 基座模型 | alibaba-pai/EasyAnimateV4-XL-2-InP | 推理参数默认值;论文 implementation details |
| Wan 2.2 还是混元 | 混元 / HunyuanDiT 系,不是 Wan 2.2 | HunyuanTransformer3DModel 类名;论文称 EasyAnimateV4 fine-tuned based on HunyuanDiT |
| DiT 层数 | 28 个 transformer blocks | HunyuanTransformer3DModel(num_layers=28) |
| 可训练参数量 | 89.90M | 论文称 Pose Encoder 完全解锁、整体可训练部分 89.90M,少于 backbone 20% #CatV2TON |
| 总参数量 | 代码/论文未给出一个明确总数;按“89.90M 少于 20%”只能推出 backbone 至少约 449.5M | 这是由论文比例反推的下界,不应误写成官方总参数 |
不要把 89.90M 写成总参数量
89.90M 是论文报告的可训练参数,不是整个 EasyAnimateV4/HunyuanDiT backbone 的总参数。仓库发布的推理代码也没有提供一个直接打印总参数的配置或脚本。
问题 3:本文如何训练 LoRA?加到了哪些层之上?
这里要先纠正一个说法:CatV2TON 论文和开源仓库更准确地说是参数高效训练 attention + Pose Encoder,而不是公开了一个标准 LoRA 训练脚本。仓库里确实有 easyanimate/utils/lora_utils.py,但这是 EasyAnimate 通用 LoRA 工具;CatV2TON 的 README 没有训练命令,仓库根目录也没有 train.py、finetune.py 或专门的 LoRA 训练配置。
从推理加载方式可以反推训练产物。modules/pipeline.py 初始化 DiT 后,会把无关模块设为 None,再遍历 transformer3d.named_modules(),把名字里包含 attn1 的模块收集成 attn_blocks,从 checkpoint 的 attention 目录加载权重;PoseNet 则从 checkpoint 的 posenet 目录加载权重。加载完成后,推理阶段全部 requires_grad_(False)。
代码能确认的训练对象
CatV2TON checkpoint 分成两块:attention 与 posenet。前者对应 backbone 中名为 attn1 的 self-attention 模块,后者对应一个轻量 Pose Encoder。论文口径是 Pose Encoder fully unlocked,同时 backbone 只解锁涉及交互的 self-attention layers,最终可训练参数为 89.90M #CatV2TON。
所以,如果把用户问题里的“LoRA”理解成“参数高效微调”,答案是:它不是把 LoRA adapter 加到 Wan/Hunyuan 的所有线性层上,而是训练 self-attention 交互层和 Pose Encoder。在代码层面,这个 self-attention 交互层具体落在 attn1 模块;Pose Encoder 是 modules/posenet.py 中的单个 HunyuanDiTBlock。
| 对象 | 是否属于 CatV2TON 可训练部分 | 代码证据 | 解释 |
|---|---|---|---|
| Backbone self-attention | 是 | if "attn1" in name: attn_blocks.append(param) | 推理加载 finetuned_model_path/attention,对应论文说的 self-attention layers。 |
| Pose Encoder | 是 | PoseNet(**config) + load_checkpoint_in_model(..., "posenet") | 一个由 PatchEmbed、time embedding 和单个 HunyuanDiTBlock 构成的轻量姿态编码器。 |
| Cross-attention / text path | 否 | 初始化时将 attn2、norm2 等设为 None | 试穿任务不依赖文本 prompt,服装/人物条件通过 temporal concatenation 进入 self-attention。 |
| EasyAnimate 通用 LoRA | 不是 CatV2TON 训练入口 | easyanimate/utils/lora_utils.py | 工具会给 Transformer/Text Encoder 的 Linear/Conv2d 创建 LoRA,但仓库没有调用它训练 CatV2TON。 |
如果严格问“LoRA 加到了哪些层之上”,只能回答:官方 CatV2TON 仓库没有开源其 LoRA 训练脚本,因此无法从仓库确认一个 CatV2TON 专属 LoRA target_modules 列表。能确认的是 EasyAnimate 通用 LoRA 工具会扫描 Transformer2DModel、Transformer3DModel、HunyuanTransformer3DModel 中的 Linear、LoRACompatibleLinear、Conv2d、LoRACompatibleConv,默认跳过名字包含 attn_temporal 的子模块;但这只是通用工具能力,不等于 CatV2TON 论文训练方案。
关键实现:temporal concatenation 在代码里在哪里?
论文讲 temporal concatenation,代码里对应 modules/pipeline.py 的 denoising():conditioned_latents 是 garment 条件,masked_latents 是 masked person 条件,二者通过 torch.cat(..., dim=2) 沿 frame/time 维拼接。mask 条件也用同样方式拼接,最后和 masked latents 在 channel 维组合成 inpaint_latents。
masked_latents_cat = torch.cat([conditioned_latents, masked_latents], dim=2)
mask_latents_cat = torch.cat([conditioning_mask_latents, mask_latents], dim=2)
inpaint_latents = torch.cat([mask_latents_cat, masked_latents_cat], dim=1)
输出时 return latents[:, :, 1:],也就是把作为条件放进时间序列的 garment 帧去掉,只保留真正生成的人物试穿帧。这正好对应论文的核心思想:服装不是走一个额外 GarmentNet,而是作为同一时序 token 序列的一部分参与 DiT self-attention。
视频长序列则在 video_try_on() 里分片处理。代码把 slice_frames 和 pre_frames 换算到 latent 时间维,每个 clip 生成后,把前一段输出的重叠帧作为下一段 prompt;若启用 use_adacn,就用重叠区域的统计量对当前 clip 做归一化校正。这和论文的 Overlapping Clip-based Inference + AdaCN 完全对应 #CatV2TON。
最终回答速查
三个问题的简明答案
- 仓库结构:外层是评测/推理入口;
modules/是 CatV2TON 核心逻辑;easyanimate/是基座视频 DiT 与 VAE 相关代码;densepose/、detectron2/是姿态条件依赖。 - 基座模型:默认
alibaba-pai/EasyAnimateV4-XL-2-InP;论文说 EasyAnimateV4 基于 HunyuanDiT fine-tune,所以不是 Wan 2.2,而是 HunyuanDiT 系。代码类HunyuanTransformer3DModel默认 28 层。 - 参数量:论文报告可训练参数 89.90M,少于 backbone 20%;仓库/论文没有给出一个可直接引用的总参数量。
- 训练/LoRA:严格说官方仓库没有 CatV2TON LoRA 训练脚本。论文训练的是 Pose Encoder + backbone self-attention layers;代码推理加载
attention与posenet两块权重。