HVM-SVG 用于缓解 OmniSVG 在复杂样本上的长序列退化(重复 path 命令、循环输出、被 max length 截断)。
核心做法:
核心文件:
build_faiss_index/precompute_hvm_data.py
build_faiss_index/run_precompute.sh
hvm_dataset.py
hvm_modules.py
hvm_decoder.py
train_hvm.py
run_train_hvm.sh
每个 batch 训练侧输入主要包括:
input_ids, attention_mask, labelsref_features: [B, 3, 256, 3584](Top-3 参考图的整图 post-merge 特征, for GME)group_features_list: List[List[Tensor]],每个 Tensor 为 [256, 3584](Top-1 参考图逐 group 独立渲染特征, for PME)ref_text_ids: [B, Nt]ref_text_mask: [B, Nt]┌─── GME (Global) ───┐ ┌─── PME (Local) ────┐
│ │ │ │
│ 3张参考图整图特征 │ │ Top-1参考逐group │
│ [B, 3, 256, 3584] │ │ 独立渲染后特征 │
│ (post-merge) │ │ list of [256, 3584] │
│ │ │ │ (post-merge) │
│ ▼ │ │ │ │
│ QFormer (6 层) │ │ QFormer (4 层) │
│ 768 tokens → 32 Q │ │ 256 tok → 4 Q/group │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ gist_feats │ │ part_feats │
│ [B, 32, 3584] │ │ [B, 16, 3584] │
└─────────────────────┘ └─────────────────────┘
│ │
└─────────┬─────────────────┘
▼
┌─── PIM × 7 ──────────────────┐
│ Step 1: Part × Gist cross-attn│
│ Step 2: Part self-attn │
│ Step 3: Visual × Text cross │
│ Step 4: Hidden × Aligned cross│
│ Step 5: AdaptiveGate │
└───────────────────────────────┘
↓
注入 decoder hidden states
[B, 3, 256, 3584][B, 768, 3584](3×256 tokens)gist_feats [B, 32, 3584][256, 3584]part_feats [B, 16, 3584](padded)part_mask [B, 16]每个 PIM 执行:
text_mask)deltahidden + gate * delta注意:PIM 是通过 hvm_decoder.py 的 decoder layer hook 注入,不改 base model 代码。
gme(~106M params)pme(~72M params)pims × 7(~251M params)脚本:build_faiss_index/precompute_hvm_data.py
metadata
metadata.jsonl, id_to_idx.jsonrag
rag_results.jsonl, text_embeddings.npy, faiss_index.binfeatures(整图特征, for GME)
features/{idx//1000}/{idx}.pt,每个 [256, 3584] float16groups
groups.jsonlgroup_features(逐 group 渲染特征, for PME)
group_features/{idx//1000}/{idx}.pt,每个 list of [256, 3584] float16一键运行(推荐,自动 8 GPU 并行提取特征和 group 特征):
cd build_faiss_index
bash run_precompute.sh
至少应包含:
metadata.jsonlrag_results.jsonlgroups.jsonlfeatures/(每个样本一个 .pt)group_features/(每个有 groups 信息的样本一个 .pt)并且三份 jsonl 记录数应一致。
主入口:run_train_hvm.sh
默认 8 卡:
bash run_train_hvm.sh
单卡调试:
bash run_train_hvm.sh --num_gpus 1 --batch_size 1
恢复完整训练状态(含 optimizer/scheduler/step):
bash run_train_hvm.sh --resume /path/to/checkpoint-step-XXXX
只加载 HVM 权重初始化:
bash run_train_hvm.sh --hvm_ckpt /path/to/hvm_step_XXXX.pt
--resume 对应 train_hvm.py --resume_from
--hvm_ckpt 对应 train_hvm.py --hvm_checkpoint
train_hvm.py 都会检查当前默认(脚本):
batch_size=2(每卡)grad_accum=4num_gpus=82*4*8=64train_hvm.py 默认 warmup_steps = total_steps * 10%。
若 epochs 设很大(如 30000),warmup 会非常长,前期学习率非常小,看起来像"不收敛"。
建议实验期显式传入 --warmup,例如 500~2000。
训练日志会打印:
Step xxxx | Gates: [...]含义:tanh(base_alpha),初始接近 0 是正常的。
如果长期几乎不变,可检查 lr / weight_decay 配置。
output_dir(默认 outputs_hvm)中常见内容:
hvm_config.json:运行参数快照hvm_model_config.json:HVM 配置(含 PIM 层索引)checkpoint-step-XXXX/
training_metadata.jsonlr_scheduler.pthvm_step_XXXX.pt
swanlog/
[256, 3584] per image, float16list of [256, 3584] per sample, 1~4 个 group, float16ref_features: [B, 3, 256, 3584](3 张参考图整图特征, for GME)group_features_list: List[List[Tensor]](Top-1 参考逐 group 特征, for PME)gist_feats: [B, 32, 3584](GME 输出)part_feats: [B, 16, 3584](PME 输出, padded)part_mask: [B, 16](bool)ref_text_ids: [B, Nt]ref_text_mask: [B, Nt]text_feats: [B, Nt, 3584]hidden_state: [B, L, 3584]delta: [B, L, 3584]| 参数 | 默认值 | 说明 |
|---|---|---|
d_model | 3584 | LLM hidden dim (Qwen2.5-7B) |
d_vision | 3584 | Vision post-merge dim (GME & PME 统一) |
d_qformer | 1024 | QFormer 内部维度 |
d_pim_inner | 512 | PIM attention bottleneck 维度 |
gme_num_queries | 32 | GME queries |
gme_num_layers | 6 | GME QFormer 层数 |
pme_queries_per_group | 4 | PME 每 group queries |
pme_num_layers | 4 | PME QFormer 层数 |
pme_max_groups | 4 | 最大 group 数 |
pim_layer_interval | 4 | 每隔 N 层插入 PIM |
1 commits
Python
95.5%
Shell
3.1%
kvlang
1.4%
HVM-SVG 用于缓解 OmniSVG 在复杂样本上的长序列退化(重复 path 命令、循环输出、被 max length 截断)。
核心做法:
核心文件:
build_faiss_index/precompute_hvm_data.py
build_faiss_index/run_precompute.sh
hvm_dataset.py
hvm_modules.py
hvm_decoder.py
train_hvm.py
run_train_hvm.sh
每个 batch 训练侧输入主要包括:
input_ids, attention_mask, labelsref_features: [B, 3, 256, 3584](Top-3 参考图的整图 post-merge 特征, for GME)group_features_list: List[List[Tensor]],每个 Tensor 为 [256, 3584](Top-1 参考图逐 group 独立渲染特征, for PME)ref_text_ids: [B, Nt]ref_text_mask: [B, Nt]┌─── GME (Global) ───┐ ┌─── PME (Local) ────┐
│ │ │ │
│ 3张参考图整图特征 │ │ Top-1参考逐group │
│ [B, 3, 256, 3584] │ │ 独立渲染后特征 │
│ (post-merge) │ │ list of [256, 3584] │
│ │ │ │ (post-merge) │
│ ▼ │ │ │ │
│ QFormer (6 层) │ │ QFormer (4 层) │
│ 768 tokens → 32 Q │ │ 256 tok → 4 Q/group │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ gist_feats │ │ part_feats │
│ [B, 32, 3584] │ │ [B, 16, 3584] │
└─────────────────────┘ └─────────────────────┘
│ │
└─────────┬─────────────────┘
▼
┌─── PIM × 7 ──────────────────┐
│ Step 1: Part × Gist cross-attn│
│ Step 2: Part self-attn │
│ Step 3: Visual × Text cross │
│ Step 4: Hidden × Aligned cross│
│ Step 5: AdaptiveGate │
└───────────────────────────────┘
↓
注入 decoder hidden states
[B, 3, 256, 3584][B, 768, 3584](3×256 tokens)gist_feats [B, 32, 3584][256, 3584]part_feats [B, 16, 3584](padded)part_mask [B, 16]每个 PIM 执行:
text_mask)deltahidden + gate * delta注意:PIM 是通过 hvm_decoder.py 的 decoder layer hook 注入,不改 base model 代码。
gme(~106M params)pme(~72M params)pims × 7(~251M params)脚本:build_faiss_index/precompute_hvm_data.py
metadata
metadata.jsonl, id_to_idx.jsonrag
rag_results.jsonl, text_embeddings.npy, faiss_index.binfeatures(整图特征, for GME)
features/{idx//1000}/{idx}.pt,每个 [256, 3584] float16groups
groups.jsonlgroup_features(逐 group 渲染特征, for PME)
group_features/{idx//1000}/{idx}.pt,每个 list of [256, 3584] float16一键运行(推荐,自动 8 GPU 并行提取特征和 group 特征):
cd build_faiss_index
bash run_precompute.sh
至少应包含:
metadata.jsonlrag_results.jsonlgroups.jsonlfeatures/(每个样本一个 .pt)group_features/(每个有 groups 信息的样本一个 .pt)并且三份 jsonl 记录数应一致。
主入口:run_train_hvm.sh
默认 8 卡:
bash run_train_hvm.sh
单卡调试:
bash run_train_hvm.sh --num_gpus 1 --batch_size 1
恢复完整训练状态(含 optimizer/scheduler/step):
bash run_train_hvm.sh --resume /path/to/checkpoint-step-XXXX
只加载 HVM 权重初始化:
bash run_train_hvm.sh --hvm_ckpt /path/to/hvm_step_XXXX.pt
--resume 对应 train_hvm.py --resume_from
--hvm_ckpt 对应 train_hvm.py --hvm_checkpoint
train_hvm.py 都会检查当前默认(脚本):
batch_size=2(每卡)grad_accum=4num_gpus=82*4*8=64train_hvm.py 默认 warmup_steps = total_steps * 10%。
若 epochs 设很大(如 30000),warmup 会非常长,前期学习率非常小,看起来像"不收敛"。
建议实验期显式传入 --warmup,例如 500~2000。
训练日志会打印:
Step xxxx | Gates: [...]含义:tanh(base_alpha),初始接近 0 是正常的。
如果长期几乎不变,可检查 lr / weight_decay 配置。
output_dir(默认 outputs_hvm)中常见内容:
hvm_config.json:运行参数快照hvm_model_config.json:HVM 配置(含 PIM 层索引)checkpoint-step-XXXX/
training_metadata.jsonlr_scheduler.pthvm_step_XXXX.pt
swanlog/
[256, 3584] per image, float16list of [256, 3584] per sample, 1~4 个 group, float16ref_features: [B, 3, 256, 3584](3 张参考图整图特征, for GME)group_features_list: List[List[Tensor]](Top-1 参考逐 group 特征, for PME)gist_feats: [B, 32, 3584](GME 输出)part_feats: [B, 16, 3584](PME 输出, padded)part_mask: [B, 16](bool)ref_text_ids: [B, Nt]ref_text_mask: [B, Nt]text_feats: [B, Nt, 3584]hidden_state: [B, L, 3584]delta: [B, L, 3584]| 参数 | 默认值 | 说明 |
|---|---|---|
d_model | 3584 | LLM hidden dim (Qwen2.5-7B) |
d_vision | 3584 | Vision post-merge dim (GME & PME 统一) |
d_qformer | 1024 | QFormer 内部维度 |
d_pim_inner | 512 | PIM attention bottleneck 维度 |
gme_num_queries | 32 | GME queries |
gme_num_layers | 6 | GME QFormer 层数 |
pme_queries_per_group | 4 | PME 每 group queries |
pme_num_layers | 4 | PME QFormer 层数 |
pme_max_groups | 4 | 最大 group 数 |
pim_layer_interval | 4 | 每隔 N 层插入 PIM |
1 commits
Python
95.5%
Shell
3.1%
kvlang
1.4%