跳转至

Infinigen V41R-Style Object Reconstruction 中文交接

日期:2026-06-29
目标读者:接手把 Infinigen cases 跑 object reconstruction 的同学。本文假设读者没有任何聊天上下文。

0. 任务定义

目标:把 configs/datasets/infinigen/summary.json 里的 Infinigen cases 跑出 V41R-style object reconstruction 结果。

这次 不跑 HOI align

  • 不跑 scripts/experiments/run_hoi_align_track_refine.py
  • 不跑已移除的 V41R chain-gate 调参实验
  • 不启用 optimization.hoi_align_chain
  • 不启用 stages.hoi_align
  • 只跑 object preprocess + object pose/articulation reconstruction

这里说的 “V41R-style” 不是把 D3D-HOI 的 V41R config 原样套到 Infinigen。Infinigen 是 synthetic/generated-video 路线,应该使用 Infinigen/synthetic recipe;V41R-style 指的是延续当前 object reconstruction 的最佳实践:FoundationPose init、DA3 depth、CoTracker3 tracks、active joint selection、object pose + articulation refine,并显式关闭 HOI align。

1. 先读这些文件

从 repo 根目录开始:

cd /DATA/intern/hoi4d/projects/zhanbaiting/ArtHOI4D

必读:

  • AGENTS.md
  • docs/infinigen_v41r_object_recon_handoff_zh.md
  • configs/datasets/infinigen/summary.json
  • scripts/run/infinigen/full.sh
  • scripts/run/infinigen/run_selected_cases_recon.py
  • configs/methods/recon/ours_track_refine_synthetic.yaml
  • configs/methods/recon/ours_track_refine_synthetic_vlm_contact.yaml

编码/实验习惯:

  • required config 字段必须显式访问,缺字段 fail fast。
  • 不要加 silent fallback。
  • 长日志写到 output/runs/.../logs,聊天/报告只写摘要和路径。
  • 每个重要 run 记录 run root、config、case list、成功/失败数、主要失败原因。

2. 环境

推荐 Python:

/DATA/intern/hoi4d/miniconda3/envs/arthoi4d/bin/python

推荐环境变量:

export PYTHON=/DATA/intern/hoi4d/miniconda3/envs/arthoi4d/bin/python
export IMAGEIO_FFMPEG_EXE=/usr/bin/ffmpeg
export PYOPENGL_PLATFORM=egl

data/infinigen 必须直接存在于当前 repo;路径缺失时脚本会报错,不再从其他 worktree 建软链或回退读取。

3. 数据集和 case 列表

Inventory:

configs/datasets/infinigen/summary.json

当前有 35 个 cases:

idx category case_id asset
0 cabinet infinigen_cabinet_p00_i00_1_videogen 1008
1 cabinet infinigen_cabinet_p00_i01_videogen 1006
2 cabinet infinigen_cabinet_p00_i02_videogen 1007
3 cabinet infinigen_cabinet_p00_i03_videogen 1009
4 cabinet infinigen_cabinet_p01_i02_videogen 1007
5 dishwasher infinigen_dishwasher_p00_i04_videogen 1005
6 dishwasher infinigen_dishwasher_p01_i03_videogen 1001
7 dishwasher infinigen_dishwasher_p01_i04_videogen 1005
8 door infinigen_door_p00_i01_videogen 1001
9 door infinigen_door_p00_i02_videogen 1013
10 door infinigen_door_p00_i03_videogen 1019
11 door infinigen_door_p01_i01_videogen 1001
12 door infinigen_door_p01_i02_videogen 1013
13 door infinigen_door_p01_i03_videogen 1019
14 drawer infinigen_drawer_p00_i00_videogen 1006
15 drawer infinigen_drawer_p00_i01_videogen 1007
16 drawer infinigen_drawer_p00_i02_videogen 1008
17 drawer infinigen_drawer_p00_i03_videogen 1001
18 drawer infinigen_drawer_p01_i00_videogen 1006
19 drawer infinigen_drawer_p01_i01_videogen 1007
20 microwave infinigen_microwave_p00_i02_videogen 1004
21 microwave infinigen_microwave_p00_i03_videogen 1006
22 microwave infinigen_microwave_p00_i04_videogen 1007
23 microwave infinigen_microwave_p01_i03_videogen 1006
24 microwave infinigen_microwave_p01_i04_videogen 1007
25 oven infinigen_oven_p00_i04_videogen 1008
26 oven infinigen_oven_p01_i03_videogen 1002
27 oven infinigen_oven_p01_i04_videogen 1008
28 refrigerator infinigen_refrigerator_p00_i03_videogen 1003
29 refrigerator infinigen_refrigerator_p01_i03_videogen 1003
30 window infinigen_window_p00_i00_videogen 1007
31 window infinigen_window_p00_i02_videogen 1001
32 window infinigen_window_p00_i03_videogen 1005
33 window infinigen_window_p01_i02_videogen 1001
34 window infinigen_window_p01_i03_videogen 1005

4. 推荐 config

默认 runner scripts/run/infinigen/full.sh 当前使用:

METHOD_CONFIG="configs/methods/recon/ours_track_refine_synthetic_vlm_contact.yaml"

这个 config:

  • 使用 ours_track_refine_synthetic.yaml 作为 base。
  • preprocess 用 DA3 depth、CoTracker3、FoundationPose object init、SAM3D body。
  • optimization 跑 object pose recon 和 object articulation recon。
  • stages.hoi_align.enabled: false
  • 使用 VLM contact labels 和 contact loss 辅助 object reconstruction。

关键片段:

reconstruction:
  optimization:
    stages:
      object_pose_recon:
        enabled: true
      object_articulation_recon:
        enabled: true
      hoi_align:
        enabled: false

如果你想严格避免 VLM contact/API,只跑最纯 object reconstruction,用:

configs/methods/recon/ours_track_refine_synthetic.yaml

注意:full.sh 默认 hard-code 到 ours_track_refine_synthetic_vlm_contact.yaml。如果要用 no-VLM config,建议手动调用 create_exp_json.py,见第 6 节。

5. 推荐跑法 A:使用现有 full.sh

5.1 小 smoke

先不要全 35 个 case。建议先跑 3 个不同类别:

  • 8 door
  • 14 drawer
  • 20 microwave

预处理:

RUN_ID=infinigen_v41r_object_smoke \
STAGE=preprocess \
bash scripts/run/infinigen/full.sh 8 14 20

重建:

RUN_ID=infinigen_v41r_object_smoke \
STAGE=recon \
bash scripts/run/infinigen/full.sh 8 14 20

输出位置:

output/runs/infinigen_v41r_object_smoke/cases/<case_id>/

每个 case 至少检查:

runtime/pipeline_config.yaml
recon/preprocess/
recon/output/result.pt

5.2 全 35 cases

预处理:

RUN_ID=infinigen_v41r_object_full35 \
STAGE=preprocess \
bash scripts/run/infinigen/full.sh 0-34

重建:

RUN_ID=infinigen_v41r_object_full35 \
STAGE=recon \
bash scripts/run/infinigen/full.sh 0-34

5.3 多卡手动切分

如果单进程太慢,可以按 case index 切分多卡。每个命令用同一个 RUN_ID,不同 case range 会生成不同 exp_<range>.json,输出仍落到同一个 cases/ 目录。

示例:

CUDA_VISIBLE_DEVICES=0 RUN_ID=infinigen_v41r_object_full35 STAGE=recon bash scripts/run/infinigen/full.sh 0-5  > output/runs/infinigen_v41r_object_full35/log_gpu0.log 2>&1 &
CUDA_VISIBLE_DEVICES=1 RUN_ID=infinigen_v41r_object_full35 STAGE=recon bash scripts/run/infinigen/full.sh 6-11 > output/runs/infinigen_v41r_object_full35/log_gpu1.log 2>&1 &
CUDA_VISIBLE_DEVICES=2 RUN_ID=infinigen_v41r_object_full35 STAGE=recon bash scripts/run/infinigen/full.sh 12-17 > output/runs/infinigen_v41r_object_full35/log_gpu2.log 2>&1 &
CUDA_VISIBLE_DEVICES=3 RUN_ID=infinigen_v41r_object_full35 STAGE=recon bash scripts/run/infinigen/full.sh 18-23 > output/runs/infinigen_v41r_object_full35/log_gpu3.log 2>&1 &
CUDA_VISIBLE_DEVICES=4 RUN_ID=infinigen_v41r_object_full35 STAGE=recon bash scripts/run/infinigen/full.sh 24-29 > output/runs/infinigen_v41r_object_full35/log_gpu4.log 2>&1 &
CUDA_VISIBLE_DEVICES=5 RUN_ID=infinigen_v41r_object_full35 STAGE=recon bash scripts/run/infinigen/full.sh 30-34 > output/runs/infinigen_v41r_object_full35/log_gpu5.log 2>&1 &
wait

如果 preprocess 也要多卡/并行,先确认各 case 的 output 目录不会互相覆盖。不要多个进程同时跑同一个 case。

6. 推荐跑法 B:严格 no-VLM object-only

如果明确要求“不调用 VLM contact,不依赖 contact labels”,不要用 full.sh 默认 config。用下面的方式生成 exp json。

6.1 Smoke

export PYTHON=/DATA/intern/hoi4d/miniconda3/envs/arthoi4d/bin/python
RUN_ID=infinigen_v41r_object_novlm_smoke
EXP_JSON=output/runs/${RUN_ID}/exp_8_14_20.json

${PYTHON} scripts/config_generation/create_exp_json.py \
  --inventory configs/datasets/infinigen/summary.json \
  --base-config configs/methods/recon/ours_track_refine_synthetic.yaml \
  --run-id ${RUN_ID} \
  --output ${EXP_JSON} \
  --cases-output-dir output/runs/${RUN_ID}/cases \
  --case-name case_id \
  --case-range 8 \
  --case-range 14 \
  --case-range 20

${PYTHON} scripts/run/infinigen/preprocess_from_exp.py --exp_json ${EXP_JSON}
${PYTHON} cli/pipeline/run_all.py --exp_json ${EXP_JSON} --stage recon

6.2 Full35

export PYTHON=/DATA/intern/hoi4d/miniconda3/envs/arthoi4d/bin/python
RUN_ID=infinigen_v41r_object_novlm_full35
EXP_JSON=output/runs/${RUN_ID}/exp_0_34.json

${PYTHON} scripts/config_generation/create_exp_json.py \
  --inventory configs/datasets/infinigen/summary.json \
  --base-config configs/methods/recon/ours_track_refine_synthetic.yaml \
  --run-id ${RUN_ID} \
  --output ${EXP_JSON} \
  --cases-output-dir output/runs/${RUN_ID}/cases \
  --case-name case_id \
  --case-range 0-34

${PYTHON} scripts/run/infinigen/preprocess_from_exp.py --exp_json ${EXP_JSON}
${PYTHON} cli/pipeline/run_all.py --exp_json ${EXP_JSON} --stage recon

7. run_selected_cases_recon.py 的使用条件

已有脚本:

scripts/run/infinigen/run_selected_cases_recon.py

它默认读取:

output/runs/infinigen_preprocess_1/selected_cases.json
output/runs/infinigen_preprocess_2/selected_cases.json
output/runs/infinigen_preprocess_3/selected_cases.json
output/runs/infinigen_preprocess_4/selected_cases.json

然后并行执行:

STAGE=recon bash scripts/run/infinigen/full.sh <case_index>

使用前先检查这些文件是否存在:

ls output/runs/infinigen_preprocess_{1,2,3,4}/selected_cases.json

如果这些 selected json 不存在,不要直接用这个脚本。改用第 5 节的手动 range 切分,或者自己先生成 selected json。

可用时示例:

/DATA/intern/hoi4d/miniconda3/envs/arthoi4d/bin/python \
  scripts/run/infinigen/run_selected_cases_recon.py \
  --gpus 0,1,2,3,4,5 \
  --log-dir output/runs/infinigen_selected_recon/logs

8. 检查输出是否完整

统计 result:

RUN_ID=infinigen_v41r_object_full35
find output/runs/${RUN_ID}/cases -path '*/recon/output/result.pt' | sort | wc -l
find output/runs/${RUN_ID}/cases -path '*/recon/output/result.pt' | sort

检查失败 logs:

RUN_ID=infinigen_v41r_object_full35
find output/runs/${RUN_ID} -type f -name '*.log' | sort

每个 case 的最小交付:

output/runs/<RUN_ID>/cases/<case_id>/runtime/pipeline_config.yaml
output/runs/<RUN_ID>/cases/<case_id>/recon/preprocess/
output/runs/<RUN_ID>/cases/<case_id>/recon/output/result.pt

建议另外保存/汇总:

  • 每个 case 是否成功。
  • object init 是否失败。
  • active joint selection 是否合理。
  • object pose / articulation qualitative overlay。
  • 若有 eval/visualization 输出,记录关键图片或视频路径。

Active-joint 选择策略

默认一律使用 auto:由 FoundationPose、objects/full 的 CoTracker 轨迹和 CAD link 投影自动选择 active joint。每个 auto 结果必须先做可视化 review;不能因为 auto 没有结果或结果可疑,就在运行时静默回退成 manual。

确认 auto 错误或无结果时,才把该 case 设为显式 manual exception:

object:
  active_joint_names: [<review-confirmed joint name>]
reconstruction:
  preprocess:
    active_joints:
      selection: manual

然后只覆盖该 case 的 recon/preprocess/active_joints/result.json;不重跑 SAM3、CoTracker 或 FoundationPose。结果中的 selection 必须保留为 automanual,review HTML 也必须显示该来源,避免把人工例外混入 auto robustness 指标。

9. 成功标准

第一阶段不要用 HOI/contact acceptance 标准。这里只评估 object reconstruction。

建议按下面口径汇报:

case status result.pt object init active joint pose visual q visual read

其中:

  • status: success / failed / partial
  • object init: FP init 是否正常,物体是否大致对齐图像
  • active joint: active link/joint 是否选对
  • pose visual: rigid pose/scale 是否明显错
  • q visual: 开合方向、幅度、时序是否合理
  • read: 简短失败归因

常见 read:

  • object init bad
  • scale/depth mismatch
  • active joint wrong
  • q under-open
  • q over-open
  • track binding wrong
  • mask/depth corrupted
  • asset/contact selector issue

10. 常见坑

10.1 不要跑 HOI align

确认每个 runtime config 里:

reconstruction:
  optimization:
    stages:
      hoi_align:
        enabled: false

也确认没有启用:

optimization:
  hoi_align_chain:
    enabled: true

如果是 Infinigen object-only,本阶段不应该生成 HOI-align result 或 HOI-align substage。

10.2 D3D-HOI V41R config 不能直接套

D3D-HOI V41R:

configs/methods/recon/d3dhoi_tuning/v041r_select_seed_track2_part75_smooth9000.yaml

这个 config 针对 D3D-HOI/PartNet/fullvid benchmark,不应直接用于 Infinigen generated-video cases。

Infinigen 应使用:

  • 默认含 VLM contact:configs/methods/recon/ours_track_refine_synthetic_vlm_contact.yaml
  • 严格 no-VLM:configs/methods/recon/ours_track_refine_synthetic.yaml

10.3 full.sh 默认用 VLM contact config

如果没有设置 API 或不想调用 VLM,使用第 6 节的 no-VLM 命令,而不是默认 full.sh

如果使用 VLM contact,需要确认:

echo $OPENAI_VLM_BASE_URL
echo $OPENAI_VLM_API_KEY
echo $OPENAI_VLM_MODEL

不要在新代码或文档里继续写入新的明文 API key。

10.4 RUN_ID 的行为

full.sh 有一个特殊逻辑:

  • 如果 STAGE != preprocess 且没有显式设置 RUN_ID,它会尝试把 case index 映射到 infinigen_preprocess_1..4
  • 如果你显式设置了 RUN_ID,它会使用这个 run root。

为了避免混乱,建议总是显式设置:

RUN_ID=infinigen_v41r_object_full35

10.5 数据路径

Inventory 里的资产和视频路径依赖:

  • data/infinigen/sim_exports/urdf
  • output/hoi_video_midstate_frontmax_batch_full/reference
  • output/hoi_first_frame_qwen/...

这些路径必须位于当前 repo。缺失时先补齐数据,不要从其他 worktree 回退读取。

11. 建议的交付物

完成后写一个短 summary,例如:

Run root:
  output/runs/infinigen_v41r_object_full35

Config:
  configs/methods/recon/ours_track_refine_synthetic_vlm_contact.yaml

Cases:
  35 total, N success, M failed

Outputs:
  output/runs/infinigen_v41r_object_full35/cases/*/recon/output/result.pt

Failure reads:
  ...

Qualitative paths:
  ...

不要只说“跑完了”。必须列出:

  • run root
  • config
  • exact case indices / case ids
  • result count
  • failed logs
  • qualitative checks
  • 是否确认 hoi_align.enabled=false

12. 推荐接手人第一天 checklist

  1. git status --short,确认当前 worktree 状态。
  2. 读本文和 scripts/run/infinigen/full.sh
  3. 检查 configs/datasets/infinigen/summary.json 能读到 35 cases。
  4. 跑 smoke:case 8,14,20
  5. 检查 smoke 的 runtime/pipeline_config.yaml,确认 hoi_align.enabled=false
  6. 检查 smoke 的 result.pt 和 qualitative visual。
  7. smoke 通过后再跑 full35。
  8. 跑完写 summary,并把失败归因按 case 记录下来。

本 handoff 的重点是 object reconstruction,不要把 HOI alignment 的 contact 指标混进这一步。