跳转至

Reconstruction Preprocess Stage Timing — 2026-04-27

本文记录 sam3d_body 路线在真实 case 上的 preprocess 耗时拆解,以及当前最值得做的加速方向。

Scope

目标 case:

  • config family: oven_ours_track3d_sam3d_body
  • video: data/d3dhoi/original_videos/b009-0001_raw.mp4
  • object: data/d3dhoi/processed_cads/oven/101940
  • preprocess route:
  • segmentation: sam3
  • motion: sam3d_body
  • depth: moge
  • depth alignment: metric + offset_only
  • tracks: tapip3d

配置口径来自:

  • output/bench_d3dhoi_oven_ours_b009_0001_track3d_sam3d_body_smoke_clean/runtime/pipeline_config.yaml

Measurement Method

这版统计是混合口径,但都来自真实 case,不是拍脑袋估算。

A. GPU 6 独立 profiling 的精确 wall time

以下 stage 是在空闲 GPU 6 上单独重跑得到的精确值:

  • extract_frames
  • sam3_masks
  • ground_mask_frame0

对应产物与日志:

  • output/bench_d3dhoi_oven_ours_b009_0001_track3d_sam3d_body_profile_gpu6/preprocess_profile_report.txt
  • output/bench_d3dhoi_oven_ours_b009_0001_track3d_sam3d_body_profile_gpu6/profile_logs/*.log

其中 sam3_masks 已确认:

  • Triton GPU kernel 正常走 GPU
  • Falling back to CPU
  • Triton only support CUDA 10.0 or higher

B. 历史成功 run 的时间戳反推

后半段 stage 由于 arthoi4d 环境中 moge/utils3d.pt 旧接口兼容问题,profiling 时没有一次性完整跑通;因此以下 stage 使用同一 case 的历史成功 run 产物时间戳反推:

  • sam3d_body
  • moge_depth
  • human_depth_alignment
  • ground_align
  • tapip3d_tracks
  • project_tracks_2d

对应成功 run:

  • output/bench_d3dhoi_oven_ours_b009_0001_track3d/recon/preprocess_sam3d_body_moge_rerun.log
  • output/bench_d3dhoi_oven_ours_b009_0001_track3d_sam3d_body_regression/recon/preprocess/...

这是“真实 run 的文件时间差”,不是理论值,但精度弱于 A 类精确 wall time。

Stage Breakdown

Stage Time (s) Time Source
extract_frames 1.114 0m01s direct profile
sam3_masks 445.899 7m26s direct profile
ground_mask_frame0 60.531 1m01s direct profile
sam3d_body ~548.224 ~9m08s timestamp backsolve
moge_depth(full_video) ~1114.472 ~18m34s timestamp backsolve
human_depth_alignment ~41.817 ~0m42s timestamp backsolve
ground_align ~38.157 ~0m38s timestamp backsolve
tapip3d_tracks ~267.804 ~4m28s timestamp backsolve
project_tracks_2d ~6.883 ~0m07s timestamp backsolve

总时长约:

  • 2524.9s
  • 42m05s

Bottleneck Ranking

按总时长占比排序:

  1. moge_depth(full_video)44%
  2. sam3d_body22%
  3. sam3_masks18%
  4. tapip3d_tracks11%
  5. 其它全部加起来 ≈ 5%

结论很明确:

  • 真正拖慢 preprocess 的不是 ffmpegground_alignproject_tracks_2d
  • 主要问题是 “每帧 monocular depth” + “world-space human motion fitting” + “dense video segmentation”

Immediate Optimization Recommendations

1. 给 smoke / debug run 单独做 fast preset

最划算的一组改法:

  • moge.frame_source: full_video -> first_frame
  • tapip3d.n_query_points: 8192 -> 4096
  • tapip3d.num_iters: 6 -> 4
  • sam3d_body world optimization iterations 降到 fast preset

预期收益:

  • 单改 moge first_frame 就能省掉接近 18.5 分钟
  • tracks 再减 1 到 2 分钟
  • sam3d_body fast preset 再减数分钟

这套 fast preset 对 smoke / regression 很合适。

2. 不要重复做 frame-0 ground segmentation

ground_mask_frame0 本身要 ~60s
同一个视频 rerun 时应直接复用:

  • preprocess/masks/ground/00000.png

这一步应该缓存命中即跳过。

3. sam3d_body 复用已有 moge_first_frame.npz

当前流程存在重复:

  • sam3d_body 自己会跑一次 frame-0 MoGe2,只为拿 K0/points0
  • 后面的 moge_depth 又会再跑一遍完整 MoGe

应改成:

  • depth/moge_first_frame.npz 已存在,sam3d_body 直接复用

这不会改变算法语义,但能去掉重复首帧推理与重复模型初始化。

4. 给 sam3d_body 加显式 fast/accurate 两档 hparams

当前 pipeline/reconstruction/preprocess/human/sam3d_body.py_OPTIMIZE_HPARAMS 偏重:

  • n_iter=1000
  • min_iter=240

建议至少提供:

  • fast: 例如 400/120
  • accurate: 保持当前或接近当前配置

这样 smoke / regression 不需要每次都支付完整优化成本。

5. sam3d_body HMR batch 再往上探

当前默认:

  • --batch_size 32

在 V100 上值得试:

  • 48
  • 64

前提是显存稳定。
这主要影响 HMR inference 部分,对 world optimization 无效,但仍可能省下可见时间。

6. TAPIP3D 建议参数分级

当前 case:

  • n_query_frames=4
  • n_query_points=8192
  • num_iters=6
  • grid_size=16
  • resolution_factor=1

建议至少区分:

  • smoke:
  • n_query_points=4096
  • num_iters=4
  • benchmark:
  • 保持 8192 / 6

TAPIP3D 是中等大头,适合做“按 run 目的切档”,不适合所有场景都跑满。

Structural Optimization Directions

上面的建议主要是“调参省时间”。如果要继续降,真正值得做的是结构优化。

A. Depth 不再 every-frame 纯独立跑

当前最大头是 moge_depth(full_video)
真正的大收益方向不是继续抠几秒,而是改变策略:

  • 关键帧跑 MoGe
  • 非关键帧插值 / 传播 / 轻量 refine

这是最大的中长期加速点。

B. sam3d_body 与 depth 首帧信息共享

sam3d_body strict-world 只需要:

  • frame-0 K
  • frame-0 point map

而不是必须独立拥有自己的 MoGe 生命周期。
因此 human 和 depth 两条支路应共享 frame-0 geometry cache。

C. segmentation / motion / depth 的 cache key 更严格

当前 rerun 容易重复付出大成本。
建议把以下结果当成一级缓存产物:

  • masks/human/*.png
  • masks/object/*.png
  • masks/ground/00000.png
  • motion/result.pt
  • depth/moge_first_frame.npz
  • depth/depth_raw.npy
  • tracks/tapip3d_tracks.npz

只要输入 video、prompt、关键 hparams 不变,就不该重复算。

如果目标是“尽快看 preprocess 是否接通”,推荐一套单独 preset:

reconstruction:
  preprocess:
    motion:
      model: sam3d_body
      debug_mode: false
      fast_preset: true   # suggested future switch
    depth:
      model: moge
      moge:
        frame_source: first_frame
    tracks:
      n_query_points: 4096
      num_iters: 4

即便 fast_preset 这个字段现在还没实现,策略应该是这组。

按当前 timing 估计,这类 fast 路线有机会把 preprocess 从 ~42m 压到 ~15-20m

Environment Note

本次 profiling 还额外暴露了一个环境兼容问题:

  • arthoi4d 里的 moge 依赖旧接口名 utils3d.pt.*
  • 当前 utils3d==0.0.2 实际导出的是 utils3d.torch.*

因此 sam3d_bodyarthoi4d 中做 frame-0 MoGe2 推理时会撞旧接口兼容坑。
这属于环境修补问题,不属于 preprocess 算法本身的速度问题。

换句话说:

  • 本文的 bottleneck 结论仍然成立
  • 但若要做完整、连续、可重复的 profiling,需先把 moge/utils3d 接口兼容层彻底补齐

Bottom Line

当前 sam3d_body preprocess 的时间结构不是“哪里都慢一点”,而是非常集中:

  • MoGe full_video
  • sam3d_body
  • SAM3 masks
  • TAPIP3D

因此优化优先级也不应平均分配。
如果只做一件事,先改 MoGe full_video -> first_frame/关键帧
如果做两件事,再加上 sam3d_body fast preset。
如果做三件事,再把 TAPIP3D 分成 smoke / benchmark 两档。