msplat wheel v1.1.3 と本実装 default スタック (resident + last_contributor、profile=false) を <strong>同日・同一 M4 Max・同一 init 点群 (culled init.ply 5207 pts)・同一 evaluator</strong> で interleave 実行。msplat 30K は <strong>167.7s / native val 36.53 dB / 190-195k splats</strong> — 2026-06 spike (219.8s / 35.48 dB) より 24% 速く 1.05 dB 高く、<strong>従来の gap 1.53× は過小評価で実際は 2.10×</strong> (12.5k 352.3s 比)。PSNR 断面は convention coupling が支配的: <strong>brush convention (premultiplied GT) cross-eval では本実装 12.5k 36.27 dB vs msplat 34.47 dB (+1.79 dB)</strong>、<strong>white-bg convention では msplat 36.28 dB vs 本実装 35.19 dB (-1.09 dB)</strong> と、同一 evaluator でも各実装が自分の学習 convention で勝つ。convention 非依存の事実は wallclock (2.10× @ 12.5k、1.08× @ 7.5k) と per-splat·iter throughput (msplat ~2.6× 高速: 33.9 vs 88.9 ns/splat·iter)。
msplat (rayanht, PyPI wheel v1.1.3) と本実装 (commit 2fb7554、default = binning resident + last_contributor) を、msplat → splat 12.5k → msplat → splat 7.5k の interleave 直列実行 (thermal 打ち消し) で同日比較した。dataset は同一 (NeRF Synthetic lego 800×800)、init 点群は本実装と同じ cull (||pos|| ≤ 1.5) を適用した 同一の 5207 点、学習 view は両者とも train 100 view 全量、eval は 両実装の final PLY を同じ `splat eval` (val 100 view) に通す cross-eval。wallclock は両者とも profiling オーバーヘッドなし。
msplat 30K = 167.7s / native 36.53 dB / 190-195k splats — 2026-06 spike (219.8s / 35.48 dB / 208k) より速く・高品質。従来引用してきた gap 1.53× は過小評価で、実際の同日 gap は 2.10× (12.5k) / 1.08× (7.5k)。PSNR は同一 evaluator でも convention で勝敗が反転する (brush: 本実装 +1.79 dB、white-bg: msplat +1.09 dB) — 「速さの msplat vs 品質+robustness の本実装」という Pareto 直交 narrative 自体は維持されるが、品質優位は『本実装の学習 convention (premultiplied) 下で』という限定付きに修正が必要。
| run (実行順) | iter | wallclock | final splats | 自己 eval PSNR | brush cross-eval (q8) | white-bg cross-eval |
|---|---|---|---|---|---|---|
| msplat r1 | 30,000 | 167.85s | 190,674 | 36.539 (white, native) | 33.049 | 36.247 |
| splat 12.5k #1 | 12,500 | 352.27s | 407,572 | 36.236 (brush, trainer) | 36.265 | 35.185 |
| msplat r2 | 30,000 | 167.48s | 194,986 | 36.513 (white, native) | 34.470 | 36.277 |
| splat 7.5k | 7,500 | 181.36s | 346,860 | 35.388 (brush, trainer) | 35.411 | 33.990 |
| splat 12.5k rep2 (参考、非 interleave) | 12,500 | 385.25s | 412,688 | 36.140 (brush, trainer) | 36.166 | 35.081 |
splat eval --convention brush --quantize-8bit (val 100 view) に通した同一 evaluator 値。「white-bg cross-eval」= 両 PLY を本実装 renderer で描画し α 合成で white-bg 化して white GT と比較 (8-bit RGBA 経由)。splat 側の brush cross-eval が trainer 値と一致 (36.236/35.388) することで evaluator の整合性を確認済み。| 項目 | spike (2026-06-26) | 本日 (2026-08-16) | 差 |
|---|---|---|---|
| wallclock (30K) | 219.8s | 167.7s (×2 mean) | **-52.1s (-23.7%)** |
| PSNR (msplat 自己 eval) | 35.48 dB | 36.53 dB | **+1.05 dB** |
| final splats | 208,215 | 190,674 / 194,986 | -15k |
| init 点群 | 不明 (spike 記録なし) | **本実装と同一の culled init.ply 5207 点 (色付き)** | 対称化 |
| 学習 view | 不明 (eval_mode holdout の可能性) | train 100 view 全量 (本実装と同一) | 対称化 |
| 解像度スケジュール | 不明 | num_downscales=0 (常時 800×800、本実装と同一) | 対称化 |
| 断面 | 比較 | wallclock 比 | PSNR 差 (同一 evaluator) |
|---|---|---|---|
| **matched-PSNR (brush conv)** | splat 7.5k (35.41 dB) > msplat 30K best (34.47 dB) | **1.08×** (181.4s vs 167.7s) | brush conv では msplat 30K の到達 PSNR を 7.5k で +0.94 dB 上回る — matched-PSNR gap は **≤1.08×** |
| **matched-PSNR (white conv)** | msplat 36.28 dB に対し本実装 12.5k で 35.19 dB | 12.5k = 2.10× | white conv では本実装 Pareto 上に matched 点が**存在しない** (12.5k でも -1.09 dB) |
| **matched-wallclock** | msplat 167.7s ≈ splat 7.5k 181.4s (1.08×) | ≈1× | brush: 本実装 +0.94 dB / white: msplat +2.29 dB |
| **12.5k 公式点** | splat 12.5k vs msplat 30K | **2.10×** (352.3s vs 167.7s) | brush: +1.79 dB / white: -1.09 dB |
| per-splat·iter throughput | mean splats 正規化 (splat 317k / msplat 165k) | msplat **~2.6×** | 28.18 ms/iter ÷ 317k = 88.9 ns vs 5.59 ms/iter ÷ 165k = 33.9 ns per splat·iter |
msplat は white-bg composite で学習するため、半透明領域の色は「white 合成後に GT と一致する」よう最適化される。これを premultiplied (bg=0) で評価すると背景 haze と edge の色 shift が systematic に乗り、native 36.53 → brush cross-eval 34.47 (q8) に -2.1 dB 低下する。逆に本実装 (premultiplied 学習) を white-bg で評価すると 36.24 → 35.19 に -1.05 dB 低下する。同一 evaluator・同一 renderer でも、各実装は自分の学習 convention で勝つ — PSNR 単一値の直接比較は原理的に convention の選択を含み、卒論では両断面を並記する。
# msplat 環境 (wheel v1.1.3)
uv venv msplat-venv --python 3.12
uv pip install --python msplat-venv/bin/python "msplat==1.1.3" numpy pillow
# dataset 変換 (blender lego → nerfstudio 形式、white-bg composite + culled init.ply)
LEGO=/Users/otkrickey/dev/3dgs-workspace/datasets/nerf_synthetic/lego
python docs/strategy/msplat_parity_lego.py convert --lego $LEGO --out /tmp/lego-ns
# interleave 実行 (msplat → splat 12.5k → msplat → splat 7.5k)
python docs/strategy/msplat_parity_lego.py train --dataset /tmp/lego-ns --lego $LEGO \
--iters 30000 --out-ply msplat-r1.ply # → 167.85s / 36.539 dB
( cd splat && ./target/release/splat train \
--config configs/2026-08-16-lego-parity-noprof-12500.toml ) # → 352.27s / 36.236 dB
# (msplat r2, splat 7.5k を同様に)
# cross-eval (同一 evaluator)
python docs/strategy/msplat_parity_lego.py convert-ply --inp msplat-r1.ply --out msplat-r1-brush.ply
splat/target/release/splat eval --ply msplat-r1-brush.ply --dataset $LEGO \
--split val --convention brush --quantize-8bit
splat/target/release/splat eval --ply splat/runs/lego-parity-noprof-12500/final.ply \
--dataset $LEGO --split val --convention brush
# white-bg cross-eval は 3dgs-workspace/msplat-parity-20260816/white_eval.py
この finding が観測された / 言及している実験 run。