[{"data":1,"prerenderedAt":278},["ShallowReactive",2],{"finding:p2-bench-harness-calibration":3,"finding-runs:p2-bench-harness-calibration":194,"finding-related:p2-bench-harness-calibration":212},{"meta":4,"impact":40,"sections":45},{"id":5,"title":6,"subtitle":7,"eyebrow":8,"date":9,"status":10,"category":11,"polarity":12,"axes":13,"tags":16,"task_code":25,"commit":26,"branch":27,"config_paths":28,"related_runs":34,"related_findings":36},"p2-bench-harness-calibration","splat bench harness 実装 + calibration — σ_replay 0.83%、full run 比 ~6x ノイズ削減","`train_step()` (refine 抜き 1 iteration) を N 回 replay する fixed-workload bench harness を実装。同一 config n=10 replay で \u003Cstrong>σ_replay = 0.234 ms\u002Fiter (mean比 0.83%)\u003C\u002Fstrong> を実測し、full run で観測されていた ~10% 分散から大幅に切り離した。3-regime (iter 1000 \u002F 5000 \u002F final checkpoint、各 n=5) でも 1.2-4.6% の低分散を確認、有意判定閾値を \u003Ccode>max(2σ, 1%)\u003C\u002Fcode> と規約化。parity mode (`--parity`) と checkpoint 保存 (`[output] save_ply_at`) も同梱。","P2 · bench harness · calibration","2026-08-16","stable","tooling","positive",[14,15],1,3,[17,18,19,20,21,22,23,24],"bench-harness","calibration","variance","reproducibility","c7","fixed-workload","gate-infra","lego","splat bench harness (2026-08-16 GPU 専有タスク)","fe68cfa11b55","main",[29,30,31,32,33],"splat\u002Fconfigs\u002F2026-08-16-bench-calib-sigma-final.toml","splat\u002Fconfigs\u002F2026-08-16-lego-bench-calib-checkpoints.toml","splat\u002Fconfigs\u002F2026-08-16-bench-calib-regime-1000.toml","splat\u002Fconfigs\u002F2026-08-16-bench-calib-regime-5000.toml","splat\u002Fconfigs\u002F2026-08-16-bench-calib-regime-final.toml",[35],"lego-bench-calib-checkpoints",[37,38,39],"p2-last-contributor","p2-c0-resident-binning","p2-gap-sweep-baseline",{"summary":41,"rank":42,"verdict":43,"delta_wallclock":44},"`splat bench --config bench.toml` を実装し、同一 config n=10 replay で \u003Cstrong>σ_replay = 0.234 ms\u002Fiter (mean 28.339 ms 比 0.83%)\u003C\u002Fstrong> を実測。full training run で観測されていた ~10% 分散に対し \u003Cstrong>約 6x のノイズ削減\u003C\u002Fstrong>。3-regime (iter 1000 \u002F 5000 \u002F final checkpoint、各 n=5) でも σ 1.2-4.6% の範囲に収まり、splat 数が少ない早期 regime ほど相対分散が大きい傾向を確認。有意判定閾値を \u003Ccode>max(2σ, 1%)\u003C\u002Fcode> と規約化し、以後の gate 判定をこの harness の計測に載せ替える。付随して `--parity` (kernel variant 間の勾配 \u002F binning 一致検証) と `[output] save_ply_at` (checkpoint 保存) を実装、parity mode の実測で production-scale シーンの `sorted_idx` tie-order 非決定性 (~0.2%、真の非決定性であって variant 差ではない) を発見し gate から除外した。","high","accepted","σ_replay 0.83% (n=10, final-scale workload) vs full run 実測 ~10% — 約 6x ノイズ削減",[46,49,54,57,94,96,99,137,139,166,168,175,177,181,184,186],{"type":47,"text":48},"lead","full training run の wallclock は run 間 ~10% の分散が観測されており、以後の全 gate 判定 (variant 採否) をこの分散から切り離すのが目的。`train_step()` (`crates\u002Fsplat-train-v1\u002Fsrc\u002Ftrain_loop.rs:39`) は refine\u002FMCMC tick を含まない — これを warmup + N 回呼ぶだけで「forward+backward+adam の fixed-workload replay」になる。`splat bench --config bench.toml` を実装し、Lego 12.5k checkpoint で n=10 \u002F n=5 の calibration を実施した。",{"type":50,"label":51,"variant":52,"text":53},"callout","Headline (σ_replay 0.83%、full run 比 ~6x ノイズ削減)","success","同一 config (Lego final checkpoint、407,267 splats) で n=10 replay (warmup=20, iters=200) を実測: \u003Cstrong>median 28.312 ms\u002Fiter、mean 28.339 ms\u002Fiter、σ = 0.234 ms\u002Fiter (0.83%)\u003C\u002Fstrong>。full run で観測されていた ~10% 分散に対し概ね \u003Cstrong>6x のノイズ削減\u003C\u002Fstrong>。3-regime (iter 1000 \u002F 5000 \u002F final の checkpoint、各 n=5) でも σ 1.2-4.6% の範囲に収まり harness の低分散性を再確認。有意判定閾値は \u003Ccode>max(2σ, 1%)\u003C\u002Fcode> と規約化し (n=10 headline では 1.65%)、以後この閾値を下回る wallclock delta は「ノイズ圏」として gate 判定に使わない。",{"type":55,"text":56},"heading","1. σ_replay 実測 (n=10、同一 config)",{"type":58,"columns":59,"align":62,"rows":65,"caption":93},"table",[60,61],"metric","値",[63,64],"left","right",[66,69,72,75,78,81,84,87,90],[67,68],"ply","runs\u002Flego-gap-baseline-12500\u002Ffinal.ply (407,267 splats)",[70,71],"view","0 (train split、固定)",[73,74],"warmup \u002F iters \u002F repeats","20 \u002F 200 \u002F 10",[76,77],"median ms\u002Fiter","28.312",[79,80],"mean ms\u002Fiter","28.339",[82,83],"σ (sample stddev)","0.234 ms\u002Fiter",[85,86],"σ_pct","**0.827%**",[88,89],"有意判定閾値 max(2σ, 1%)","**1.65%** (= 2σ、1% 下限より大)",[91,92],"参考: full run 実測分散","~10% (docs\u002Fstrategy 記載、run 間 dataset load \u002F refine cadence 交絡)","n=10 同一 config replay の σ_replay。full run の ~10% 分散に対し約 6x のノイズ削減。",{"type":55,"text":95},"2. 3-regime calibration (iter 1000 \u002F 5000 \u002F final、各 n=5)",{"type":97,"text":98},"paragraph","既存 baseline recipe (`configs\u002F2026-08-16-lego-gap-baseline-12500.toml`) をそのまま流用し、新 `[output] save_ply_at = [1000, 5000]` で 1 本の training run (`lego-bench-calib-checkpoints`、final PSNR 36.226 dB \u002F 360.96s \u002F 409,660 splats) から 3 checkpoint を生成、各 regime を n=5 で計測した。",{"type":58,"columns":100,"align":107,"rows":108,"caption":136},[101,102,103,76,104,105,85,106],"regime","iter","num_splats","mean","σ (ms)","閾値 max(2σ,1%)",[63,64,64,64,64,64,64,64],[109,118,127],[110,111,112,113,114,115,116,117],"早期 (iter 1000)","1000","8,224","13.462","13.377","0.621","4.65%","9.29%",[119,120,121,122,123,124,125,126],"中期 (iter 5000)","5000","373,933","30.038","30.039","0.373","1.24%","2.49%",[128,129,130,131,132,133,134,135],"後期 (final = 12500)","12500","409,660","31.515","31.415","0.901","2.87%","5.74%","regime が進むほど splat 数と per-iter GPU work が増え、OS scheduling jitter 等の絶対誤差が相対的に薄まって σ_pct が下がる傾向 (早期 regime ほど n を増やす運用を推奨、下記 §4)。final regime の n=5 σ (2.87%) が headline の n=10 σ (0.83%) より大きいのは同じ傾向のサンプルサイズ効果 — n=5 では σ 推定自体のノイズが大きい。",{"type":55,"text":138},"3. 実装内容",{"type":58,"columns":140,"align":143,"rows":144},[141,142],"項目","内容",[63,63],[145,148,151,154,157,160,163],[146,147],"`splat bench --config bench.toml`","`crates\u002Fsplat-cli\u002Fsrc\u002Fcmd\u002Fbench.rs` 新規。`[bench]` (ply\u002Fdataset\u002Fview\u002Fwarmup\u002Fiters\u002Frepeats\u002Foutput) + `[backend]` (既存 `BackendConfig`) を読み、repeat 毎に `Param` を ply から reload → `train_step()` を warmup+iters 回 replay。loss recipe (`l1_ssim`, λ=0.20, ssim window=7 σ=1.0, `AdamConfig`\u002F`McmcConfig` default) は現行 production 勝者と一致させ config で選べない固定値にした (workload の再現性を最優先、詳細は bench.rs 冒頭コメント)",[149,150],"`bench-result.toml` 出力","ms\u002Fiter (median\u002Fmean\u002Fσ\u002Fσ_pct\u002Fper-repeat)、per-kernel `{total_ms, calls, avg_us}` (`timing::snapshot()` 経由、repeat 間で集計)、num_splats、commit hash、os_build、config snapshot (raw TOML 埋め込み)",[152,153],"`timing::snapshot()`","`crates\u002Fsplat-train-v1\u002Fsrc\u002Ftiming.rs` に `pub fn snapshot() -> Vec\u003C(String, Duration, u64)>` を追加 (~10 行)。既存 `print_summary()` の stderr 出力と独立に、呼び出し側で好きな形式に整形できる",[155,156],"`--parity candidate.toml`","同一 ply から baseline (`bench.toml [backend]`) と candidate (`--parity` file `[backend]`) で 1 iteration を実行し比較。grad buffer (`means_grad` 等 5 種) は既存 C7 tolerance 体系 (abs\u002Frel 1e-4) で比較、`tile_offsets` は byte equality。判定は stdout の `PARITY ...` 行 (機械可読) + exit code (`Ok`→0 \u002F `Err`→1、main.rs の既存変換をそのまま利用)。GPU loss path (`loss_path=\"gpu\"`) 前提、host path は明示エラー",[158,159],"`sorted_idx` の扱い (発見)","**gate に使わない**: production-scale シーンで同一 config でも tie 内相対順序が emit_pairs の atomic 書き込み順に依存し ~0.2% 入れ替わる (`tile_bin.rs` の既存テスト註釈が示す通り、synthetic fixture でのみ byte-exact)。variant 差ではなく既知の非決定性なので informational 表示に変更 (実測で判明、当初 spec は byte equality gate を想定していた)",[161,162],"`[output] save_ply_at`","`crates\u002Fsplat-cli\u002Fsrc\u002Fconfig.rs` に `Vec\u003Cu32>` field 追加 (default 空、既存互換)。`train_loop()` に `checkpoint_iters: &[u32]` + `impl FnMut(u32, &Param)` callback を追加 (hot loop は `dyn` 禁止規約に従い generic で受ける、空 slice の線形 scan のみで per-iter alloc なし)。`train.rs` が `\u003Crun_dir>\u002Fckpt_\u003Citer>.ply` を保存するクロージャを渡す",[164,165],"`apply_backend_config` 抽出","`train.rs` 内 private fn だったものを `crates\u002Fsplat-cli\u002Fsrc\u002Futil.rs` に `pub fn apply_backend_config(trainer: &Trainer, backend: &BackendConfig)` として抽出、`train` \u002F `bench` 両 subcommand が共有 (`git_short_commit` \u002F `macos_build_version` も同様に共有化)",{"type":55,"text":167},"4. 運用ガイドライン",{"type":169,"items":170},"list",[171,172,173,174],"\u003Cstrong>gate 判定は n>=10 repeats を推奨\u003C\u002Fstrong>: n=5 の σ 推定自体がノイズを持つ (final regime で n=5→2.87% vs n=10→0.83%、同程度の workload でも 3x 以上ブレる)。variant 採否のような重要判定は n=10 以上で σ を再確定してから閾値と比較すること。","\u003Cstrong>早期 regime (splat 数が少ない) は相対分散が大きい\u003C\u002Fstrong>: iter 1000 regime は σ_pct 4.65% と他 regime の 2-4x。絶対 ms\u002Fiter が小さい workload は OS scheduling jitter 等の固定誤差が相対的に効くため、早期 regime を gate に使う場合は repeats を増やすか閾値を緩めること。","\u003Cstrong>有意判定閾値 = max(2σ, 1%)\u003C\u002Fstrong>: σ はそのベンチ実行自身の `sigma_pct` (bench-result.toml に出力済み) を使う。固定の全体閾値ではなく、計測毎に自己算出する運用とする (workload \u002F regime で σ が変わるため)。","\u003Cstrong>parity mode は GPU loss path 限定\u003C\u002Fstrong>: `[backend] loss_path = \"gpu\"` を両側で明示すること (host path は SSIM を host 側で計算し `rendered_buf` を経由しないため比較対象にならない)。",{"type":55,"text":176},"5. 使い方",{"type":178,"lang":179,"text":180},"code","toml","[bench]\nply = \"runs\u002Flego-gap-baseline-12500\u002Ffinal.ply\"\ndataset = \"\u002FUsers\u002Fotkrickey\u002Fdev\u002F3dgs-workspace\u002Fdatasets\u002Fnerf_synthetic\u002Flego\"\nview = 0\nwarmup = 20\niters = 200\nrepeats = 10\n\n[backend]\nloss_path = \"gpu\"",{"type":178,"lang":182,"text":183},"bash","splat bench --config bench.toml\nsplat bench --config bench.toml --parity candidate.toml   # candidate.toml は [backend] のみ",{"type":55,"text":185},"6. 関連",{"type":169,"items":187},[188,189,190,191,192,193],"harness 実装: \u003Ccode>splat\u002Fcrates\u002Fsplat-cli\u002Fsrc\u002Fcmd\u002Fbench.rs\u003C\u002Fcode>、共有 util: \u003Ccode>splat\u002Fcrates\u002Fsplat-cli\u002Fsrc\u002Futil.rs\u003C\u002Fcode>","checkpoint hook: \u003Ccode>splat\u002Fcrates\u002Fsplat-train-v1\u002Fsrc\u002Ftrain_loop.rs::train_loop\u003C\u002Fcode> (`checkpoint_iters` \u002F `on_checkpoint`)","timing snapshot accessor: \u003Ccode>splat\u002Fcrates\u002Fsplat-train-v1\u002Fsrc\u002Ftiming.rs::snapshot\u003C\u002Fcode>","BackendConfig 規約: \u003Ccode>docs\u002Farchitecture\u002Fbackend-and-compiler-conventions.md\u003C\u002Fcode>","3-regime checkpoint 生成 run: \u003Ccode>splat\u002Fruns\u002Flego-bench-calib-checkpoints\u002F\u003C\u002Fcode> (result.toml \u002F config.toml のみ commit)","raw bench 出力: \u003Ccode>splat\u002Fruns\u002Fbench-calib\u002F{sigma-final,regime-1000,regime-5000,regime-final}.toml\u003C\u002Fcode> (gitignore 対象、再生成可能)",[195],{"id":35,"title":35,"subtitle":196,"date":9,"workspace":197,"tags":198,"verdict":207,"psnr":208,"psnr_unit":-1,"wallclock":209,"splats":210,"summary_url":211,"detail_path":211},"P2 bench harness calibration — 3-regime (iter1000\u002F5000\u002Ffinal) checkpoint 生成用 (lego-gap-baseline-12500 と同一 recipe、save_ply_at 追加のみ)","splat",[199,200,201,202,203,204,205,206],"p1-g","phase-g","early-stop","sh-progressive","stacked","lego-15k","brush-compat","premultiplied","partial",36.225929260253906,"6m 0s",409660,"\u002Fruns\u002Flego-bench-calib-checkpoints\u002F",[213,237,259],{"id":38,"title":214,"date":9,"status":10,"polarity":12,"category":215,"axes":216,"tags":217,"task_code":226,"related_runs":227,"delta_psnr":232,"delta_wallclock":233,"rank":42,"verdict":234,"impact_summary":235,"detail_path":236},"P2 gap sweep Phase 2 — C0 resident arena + C1 pass skip で -48.4% (bit-exact)","experiment",[14,15],[218,219,220,221,222,223,224,225,24],"gap-sweep","phase-2","c0-resident-arena","c1-radix-pass-skip","binning","bit-exact","unified-memory","page-fault","2026-08 msplat gap sweep Phase 2 C0\u002FC1",[228,229,230,231],"lego-c0-day0-attrib-1k","lego-c0-ab-periter-1k","lego-c0-ab-resident-1k","lego-c0-resident-12500","12.5k gate: 36.216 → 36.183 dB = -0.033 dB (bit-exact 実装、atomic 非決定性 guard ±0.1 内で通過)","12.5k gate: 766.07 → 395.59s = **-48.4%** (emit -98% \u002F radix -53% \u002F extract -81%)","c0-c1-adopted-default-flip-minus-48-percent","\u003Cstrong>単発 -48.4% は本 project 最大の 1 施策改善\u003C\u002Fstrong>で、msplat 実測 gap (11m48s vs 3m40s ≈ 3.2×、Lego 30k) を大幅に詰める lever が確定。766.07 → 395.59s は kernel を 1 行も触らず host 側 buffer 管理だけで達成 (bit-exact)。emit_pairs は 38.2% → 1.2% に消滅し、新 bottleneck は backward_raster 31.4% (→ 2-BWD last_contributor の trigger 25% を初超過) と radix_sort 11.7% (GPU compute 本体)。STP (feat.F) は emit の alloc 成分が消えた今、相対効果の再 bench が必要 (Phase 1a の -7.45% は大半が同じ page fault の削減で C0 と重複していた可能性が高い)。教訓: unified memory 環境の profiling では「GPU 時間」に host メモリ管理コストが化ける — per-kernel wallclock だけでなく buffer lifecycle を疑うこと。","\u002Ffindings\u002Fp2-c0-resident-binning\u002F",{"id":39,"title":238,"date":9,"status":10,"polarity":12,"category":215,"axes":239,"tags":240,"task_code":246,"related_runs":247,"delta_psnr":254,"delta_wallclock":255,"rank":42,"verdict":256,"impact_summary":257,"detail_path":258},"P2 gap sweep Phase 0\u002F1a — binning 55% 実測 + C0 発見 + StopThePop -7.45%",[14],[218,241,242,243,244,245,222,220,24],"phase-0","phase-1a","profiling","per-kernel-breakdown","stop-the-pop","2026-08 msplat gap sweep Phase 0 + 1a",[248,249,250,251,252,253],"lego-gap-baseline-12500","lego-stp-12500","lego-stp-ab-original-5k-r1","lego-stp-ab-original-5k-r2","lego-stp-ab-stp-5k-r1","lego-stp-ab-stp-5k-r2","STP 12.5k: 36.216 → 36.193 dB = -0.023 dB (guard -0.05 内で通過)","STP 12.5k: 766.07 → 708.96s = **-7.45%** (emit -10.5% \u002F radix -8% \u002F backward -6%)","binning-55-percent-c0-discovered-stp-marginal-go","\u003Cstrong>Phase 2 の主戦場が確定\u003C\u002Fstrong>: strategy doc の trigger 3 候補 (separable SSIM \u002F last_contributor \u002F SH-Adam fusion) は全て閾値不発、代わりに \u003Cstrong>binning 経路 55% の主犯 = per-iter ~1.25GB alloc + Vec 三重往復 (C0)\u003C\u002Fstrong> が最大 lever。C0 (persistent buffer arena、bit-exact、3-4 日) の期待は \u003Cstrong>wallclock -30〜39% (766→~470s) で単独 gap ≤2.0× 到達圏\u003C\u002Fstrong>。C1 (radix 定数桁 pass skip 16→11、bit-exact、0.5-1 日) が +4-5%。StopThePop は -7.45% で adoption gate (-8%) に僅差未達、default 維持のまま C0 後再判定。5 連敗の教訓「profiling が指す順」が機能した初の事例 — 事前決め打ちなら SSIM (5.2%) に突撃していた。","\u002Ffindings\u002Fp2-gap-sweep-baseline\u002F",{"id":37,"title":260,"date":9,"status":10,"polarity":12,"category":215,"axes":261,"tags":262,"task_code":267,"related_runs":268,"delta_psnr":273,"delta_wallclock":274,"rank":42,"verdict":275,"impact_summary":276,"detail_path":277},"P2 gap sweep Phase 2 — 2-BWD last_contributor で -15.0% (数学的同値)、STP 再判定は棄却",[14],[218,219,263,264,245,265,266,24],"2-bwd-last-contributor","backward","re-eval","function-constant","2026-08 msplat gap sweep Phase 2 2-BWD \u002F STP 再判定",[269,270,271,272],"lego-lc-smoke-1k","lego-p2lc-12500","lego-stp-c0-12500","lego-stack-lc-stp-12500","LC 12.5k gate: 36.183 → 36.191 dB = +0.008 dB (数学的同値実装、atomic 非決定性 guard ±0.1 内)","LC 12.5k gate: 395.59 → 336.33s = **-14.98%** (backward_raster -40.3%)。STP: -2.51% (gate 未達)、LC+STP スタック: 343.63s (LC 単独より +2.2%)","lc-adopted-minus-15-percent-stp-rejected-final","C0 (-48.4%) に続く Phase 2 第 2 弾で、backward 31.4% の新 bottleneck を kernel 側から -40.3% 削減。\u003Cstrong>Lego 12.5k = 336.33s で msplat 30K (220s) 比 1.53× まで縮小\u003C\u002Fstrong>し、gap sweep の目標 (≤2.0×) を達成した。実装は「forward が既に知っている打ち切り位置を backward に伝えるだけ」で数学的同値 — 品質を 1 bit も動かさずに backward の replay 計算量を ~40% 削った。STP 再判定は負の結果だが価値が高い: Phase 1a の -7.45% の正体が C0 と同じ page fault 削減だったことを分離実証し、「効果の重複を疑って再 bench する」protocol の正しさを裏付けた。次の bottleneck は forward rasterize 9.8% \u002F radix 13.5% \u002F SSIM 7.5% でいずれも trigger 25% 未達 — Phase 2 はここで完了、Phase 3 (再計測 + Pareto v3) へ。","\u002Ffindings\u002Fp2-last-contributor\u002F",1790227326537]