松田研究室
FindingID: p3-final-stack-v2
Status: stable / task 2026-09-seminar05-milestones M7 v2 (最終スタック独立再計測の再実施 + 多 scene 退行チェック)
← Findings Index
2026-09 第 5 回ゼミ milestones · M7 v2 · 最終スタック再計測 (session 汚染) + 多 scene breakage screen

M7 v2 — 最終スタック独立再計測 (post S4b) は session 汚染で +6.4%、paired control 122.77s を維持。多 scene (ficus/materials/drums) で退行なし確認

p3-final-stack.toml (M7、124.39s) 以降に S4b (ssim_reduce=gpu) が default flip されたため、Part 1 で同じ 12.5k n=3 手順を再実施した。<strong>as-measured mean は 130.657s (σ1.727%)</strong> だが、同日の paired control 2 本 (S4b gate on-arm 122.768s、p3-refine-nondrain off-arm 122.6467s、相互 0.13% 一致) と比べて +6.4〜6.5% 遅く、load sampler ログ・ms/iter trace の iter3000-9000 区間での一貫した elevation・<code>ps aux</code> で捕捉した実際の同時実行プロセス (Finder 147%CPU 等) という 3 系統の証拠が session 汚染を裏づけた。<strong>milestones.md の「現在地」はこの 130.657s では上書きせず、S4b paired 値 122.768s を維持する</strong> — 新事実は「今のスタックは前回 M7 より遅くなった」ではなく「単発の unpaired n=3 は無関係な同時プロセスに弱い」という計測論の知見。msplat 等価 gap は control 値ベースで <strong>0.745×</strong> (旧 0.755×)、throughput <strong>0.916×</strong> (旧 0.926×) にわずかに改善。Part 2 では 2026-08-30 に採用された 3 施策 (M4/A7/S4b、いずれも Lego 12.5k gate のみが根拠) を ficus (227k splats) / materials (355k splats) / drums (998k splats、Lego の 2.5 倍) で breakage screen し、<strong>3 scene とも ΔPSNR が a-10 の noise floor (σ±0.32dB) を大きく下回り退行なし</strong>を確認。drums は load がほぼクリーンで 5.72× の高速化を実測 (ficus/materials は load 汚染下のため方向感のみ)。

neutralrank: highmeasurement-methodology-finding-controls-retained-multiscene-no-regression第 1 軸第 3 軸m7m7v2seminar05-milestonesfinal-stackmsplat-paritypareto-v3bmulti-sceneregression-checkmeasurement-methodologysession-contaminationficusmaterialsdrums
Δ PSNR
Part1: finalv2 self-eval n=3 mean **36.257dB** (σ0.10%)、brush cross-eval q8 n=3 mean **36.289dB** (σ0.11%、M7比+0.04dB)。Part2 (§6、load汚染下 n=1): ficus -0.020dB / materials -0.027dB / drums -0.010dB (いずれも a-10 σ±0.32dB の1/10以下、退行なし)。PSNR は load非依存の量なので §14 の静穏再実行でも §6 の値 (ficus 34.261dB / materials 29.998dB) から変更しない。§14 の追加観測: materials は baseline/§6/静穏の3 runでPSNR range **0.028dB** (安定)。ficus は §6/q1/q2 の3 runで range **1.443dB** (34.261/32.836/34.279、a-10 のLego range 0.885dBの1.6倍) — config/RNG起因は排除済み、a-10のGPU非決定性の一事例と推測されるが、実用上の帰結は「a-10のσ±0.32dBをficusの退行判定に転用できない」というgate閾値の限界
Δ Wallclock
Part1: as-measured 12.5k n=3 mean **130.657s** (σ1.727%、session汚染のためmilestones非採用)。paired control (S4b on-arm 122.768s / rnd off-arm 122.6467s、相互0.13%一致) を現在値として維持。msplat等価gap **0.745×** (旧0.755×)、throughput **0.916×** (旧0.926×)。Part2 (§6、load汚染下): drums (load概ねクリーン) 3936s→687.85s=**5.72×**。ficus/materials は load汚染下で方向感のみ (≥3.7×/≥4.4×)。§14 静穏再実行 (in-runサンプラーで確認): ficus 349.63s→**254-256s** (-27.3%〜-26.7%、q1/q2で再現)、materials 421.90s→**319.54s** (-24.3%)
Impact
2026-09-seminar05-milestones M7 のフォローアップを実施した。**Part 1 (12.5k n=3 再計測)**: `2026-08-30-finalv2-12500-r{1,2,3}.toml` (final-12500-r{1,2,3}.toml の複製、backend flag 無指定で S4b flip 後の default = ssim_reduce=Gpu を含む全採用施策込み) を実行。各 run の `[backend] BackendConfig {...}` ログ行で `ssim_reduce: Gpu, radix_scatter: SimdBallot, refine_scratch_persist: true, refine_direct_write: true` を確認、AC 電源・pgrep 空・binary sha256/git rev 不変 (`c804b349...`/`9bb4ea5`) を series 前後で確認。**as-measured mean は 130.657s (σ1.727%)** — S4b flip で速くなるはずが M7 (124.39s) より遅いという逆方向の結果になった。追加調査で、(1) 10s 間隔 load sampler が r1 window 内で 5.77 まで load1 上昇 (iter6000-7000 相当のタイミング)、r2 window 内でも 4.22 まで上昇、(2) old M7 (r2-r4) と new (r1-r3) の 1000-iter segment ごとの ms/iter を突き合わせると iter0-3000 は new が -4〜-9% 速い (S4b の効果と整合) のに iter3000-12500 は new が一貫して +1.8〜+12.0% 遅い、(3) 実行後の `ps aux` で Finder (147%CPU)・別プロジェクト (otksynth) の Rust バイナリ・音声処理プロセスの実存を確認、という 3 系統の証拠が「同時実行された無関係なユーザープロセスによる session 汚染」を裏づけた。既存の汚染判定規約 (`p3-tier1-bit-exact.toml` §5「load 証拠 AND 自 arm 内 3σ 超」) はこの事例 (3 run 全体が相関して底上げされ、単一の outlier が無い) を検出できない構造的な穴であることも判明した (§2 に規約拡張案を記載)。**同日の paired control 2 本 (S4b gate on-arm 122.768s、`p3-refine-nondrain` off-arm 122.6467s — 後者は refine_gpu_snapshot という no-op field 追加のみの差で本 session の HEAD と事実上同一コード) が相互に 0.13% で一致**しており、この 2 点を「現在の真値」の推定として採用し、milestones.md の「現在地」は上書きしない。brush cross-eval q8 PSNR (final.ply への `splat eval` 実行、load 非依存) は 3 run 平均 **36.289dB** (M7 の 36.249dB から +0.04dB、ノイズ帯)。avg splats (trapezoid 積分による自前算出) は 321,011 (M7 の 321,637 と 0.2% 差で一致、算出法の再現性を裏づけ)。msplat 等価 gap は control 値 (122.768s) ベースで **0.745×** (旧 0.755×)、throughput は **0.916×** (旧 0.926×) とわずかに改善。Pareto v3b (`docs/figures/pareto-v3b-msplat-lego-final-stack-v2.png`) は 12.5k 点の x 座標を control 値、y 座標を finalv2 の brush cross-eval 実測に更新 (両者は異なる run 由来なので script docstring に明記)。**Part 2 (多 scene breakage screen)**: 2026-08-30 に採用された M4 (radix simd_ballot)・A7 (refine 3-pass 削減)・S4b (ssim_reduce=gpu) の 3 施策は全て Lego 12.5k gate のみを根拠にしており、他 scene での検証が無かった。`p1-axis1-phase-g-pareto-landscape.toml` §2 (G.3-alone 30k recipe、2026-05-25、[trainer]/[refine]/[adam] 節が現行 config と完全一致することを diff で確認済み) を baseline に、ficus (227k splats)・materials (355k splats)・drums (998k splats、Lego 407k の 2.5 倍で 3 施策が splat 数 non-uniform に依存する経路を初めてテストする scene) の 3 scene を n=1 で再計測した。**ΔPSNR は ficus -0.020dB / materials -0.027dB / drums -0.010dB で、いずれも `a-10-variance-baseline` の σ±0.32dB (Lego 30k での run-to-run noise floor) の 1/10 以下** — 3 scene とも退行なし。M4/A7/S4b はいずれも理論上 PSNR に影響しない施策 (M4: sort parity bit-exact、A7: 書き込みロジック不変、S4b: gradient 非変更) のため、この結果は「今回の 3 施策の改善効果」ではなく「壊れていないことの確認」として設計通り。Δsplats も ficus +0.32% / materials +1.50% / drums -0.31% と小さい。wallclock は ficus (load 9.6-32.6 で終始汚染)・materials (load 7-27 で終始汚染) は方向感のみ (旧比 ≥3.7×/≥4.4× 高速化) だが、**drums は iter 27000 まで load 0.8-5.5 とほぼクリーンで 3936s→687.85s = 5.72× 高速化を実測**、Lego の 2.5 倍規模の scene でも大幅改善が維持されることを確認した。
01

本文

p3-final-stack.toml (M7、124.39s) の直後に S4b (ssim_reduce=gpu) が default flip されたため、milestones.md の「現在地」を最新化するには同じ独立 n=3 手順を再実施する必要があった。本 finding は Part 1 (その再実施) と Part 2 (2026-08-30 に採用された M4/A7/S4b の 3 施策を Lego 以外の scene で breakage screen) をまとめる。Part 1 は「速度がさらに改善した」という当初の想定に反し、「同じ session 内の無関係な CPU 負荷が計測を汚染しうる」という計測論の finding になった — 詳細な証拠の連鎖を §1/§2 に記す。

0. 計測環境 — AC 電源 / GPU 専有 / pgrep 空確認

電源 / 機体
AC 接続 (`pmset -g batt` で series 開始前・完了後とも `AC Power` を確認)、M4 Max。GPU 権は main から付与済み、他 agent は worktree で実装のみ (GPU 不使用の前提)
binary / rev
release binary sha256 `c804b349223ffc68e9e1101d79c5ea9f058dfa8d34620504b66aa0a3eb10aa13`、series 前後で一致確認。git rev `9bb4ea563104e3c8de391ad59b7bf556fad0d373` で series 全体を通じて不変 (`cargo build --release` を作業開始前に実施、13.6s で完了 = 既存 binary は既に HEAD 相当だったため実質差分なし)
実行方式 (Part 1)
既存 `splat/scripts/final-stack-n3.sh` を流用。**前回 M7 の再実施時に script 自体の引数仕様上の罠を発見**: `strip_prefix` は先頭の `splat/` のみを除去するため、`config_prefix` は `configs/2026-08-30-finalv2-12500` のように `configs/` を含めて渡す必要がある (`2026-08-30-finalv2-12500` とだけ渡すと `splat/2026-08-30-finalv2-12500-r1.toml` を探しに行き rc≠0 で即 PARTIAL 終了する) — advisor レビューで実行前に検出、正しい引数で実行して回避した
実行方式 (Part 2)
n3 script は使わず、1 scene = 1 config = 1 run を `nohup ./target/release/splat train --config <cfg> > <log> 2>&1 & disown` で直列発注。完了検出は `ps aux | awk '$0 ~ /release\/splat train/ && $0 !~ /awk/'` (自己マッチ回避形)。**当初 `pgrep -f "multiscene-materials"` で完了ポーリングした際、ポーリングコマンド自身の argv (`tail ... multiscene-materials-30k.log`) に同じ文字列が含まれるため自己マッチし、実際には完了していたのにポーリングループが終了判定できず 10 分の tool timeout を1回消費した** — 次 session はプロセス名 (`release/splat train`) でマッチし `awk` 自身を除外する形を使うこと
run 後 pgrep / load 確認
Part1 series 完了後 `pgrep -fl "target/release/splat"` は空、binary sha256/git rev 不変、AC Power 維持。Part2 各 run 完了後も同様 (drums 完了後の確認込み)
Part2 の run_dir 実体パス (訂正)
Part 2 の 3 run は cwd=`/Users/otkrickey/dev/matsudalab` (splat/ 直下ではない) から起動したため、config の `run_dir = "splat/runs/multiscene-*"` は `splat/runs/` ではなく repo root 直下の `runs/multiscene-{ficus,materials,drums}-30k/` に書かれた (`.gitignore` 対象で追跡外、Part1 の `splat/runs/finalv2-*` とはディレクトリが異なる点に注意)
AC→Battery 切替イベント (00:3x、coordinator 通知) との照合
作業中に「00:3x に AC→Battery、1〜2分後 AC 復帰」という通知を受けた。各 run の `final.ply` mtime を確認したところ ficus 00:00:36 / materials 00:09:57 / drums 00:25:34 (JST) で、通知を受けた時点 (00:31 台) より前に Part2 の全 GPU run が完了しており、**いずれの run もこの Battery 区間と重なっていない** (`pmset -g batt` は通知確認時点で `AC Power` 100%充電済みを表示)。Part1 series は 23:42-23:51 台で更に早く、同様に無関係。よって Battery 汚染に該当する run は無く、再実行の必要なし
各 run の pre/post load1 (Part1)
r1: pre 1.71 → post 3.20 (window内 load sampler ピーク 5.77、iter6000-7000相当)。r2: pre 2.62 → post 3.08 (window内ピーク 4.22)。r3: pre 2.17 → post 2.38 (window内 2.1-3.0 で最もクリーン、詳細は §1/§2)

1. Part 1 — 12.5k full run 独立再計測 (as-measured)

runconfigtrain elapsed (s)self-eval PSNR (dB)brush cross-eval q8 (dB)final splatsavg splats (trapz)
r1finalv2-12500-r1132.3736.28236.317406,773320,936.5
r2finalv2-12500-r2131.5036.27436.306406,990321,320.6
r3finalv2-12500-r3128.1036.21436.244405,946320,776.5
**mean (n=3)**—**130.657** (σ1.727%)**36.257** (σ0.10%)**36.289** (σ0.11%)406,570321,011.2
3 run とも `[backend] BackendConfig {...}` ログで `ssim_reduce: Gpu, radix_scatter: SimdBallot, refine_scratch_persist: true, refine_direct_write: true` を確認済み (S4b flip 後の default が正しく効いている)。self-eval PSNR は training log の `mean val: PSNR` (100 views)、brush cross-eval q8 は `splat eval --convention brush --quantize-8bit` を各 run の `final.ply` に実行した実測 (load 非依存)。avg splats は 1000-iter checkpoint の trapezoid 積分、M7 の 321,637 と 0.2% 差で一致し算出法の再現性を裏づける。
n=3 のいずれも自 arm 内 3σ を超えない — 既存の汚染判定規約では『クリーン』判定になる

sample σ = 2.257s (1.727% of mean)。個別偏差: r1 +1.71s (0.76σ)、r2 +0.84s (0.37σ)、r3 -2.56s (1.13σ) — いずれも `p3-tier1-bit-exact.toml` §5 の事前登録条件 (load 証拠 AND 自 arm内 3σ 超) の後半を満たさないため、**この規約に従う限り 3 run とも棄却/再試行の対象にならない**。しかし §2 で示すとおり、3 run すべてが同じ iter3000-9000 区間で一貫して減速しており (=相関した底上げ)、単一 run の外れ値を検出する設計のこの規約は「session 全体が相関して汚染される」パターンを検出できない構造的な穴を持つ。

2. なぜ 130.657s を milestones.md の headline に採用しないか — 3 系統の証拠

iter 区間 (1000-iter segment)old (M7 r2-r4 mean, ms/iter)new (finalv2 r1-r3 mean, ms/iter)Δ
0-10003.413.15-7.4% (S4b の効果と整合、速い)
1000-20004.744.30-9.2% (同上)
2000-30008.358.02-4.0% (同上)
3000-40009.9310.83**+9.0%**
4000-500010.6311.39**+7.1%**
5000-600011.0712.40**+12.0% (最大)**
6000-700011.4712.37**+7.8%**
7000-800011.5612.11+4.8%
8000-900011.7112.34+5.3%
9000-1000011.7612.90**+9.7%**
10000-1100011.8712.26+3.3%
11000-1200011.8812.45+4.8%
12000-1250011.9512.17+1.8%
old (M7 r2-r4) と new (finalv2 r1-r3) を同じ 1000-iter checkpoint で突き合わせた segment cost。**iter0-3000 は new が一貫して速い (S4b の ssim host 仕事削減が効いている、期待どおりの符号)。iter3000 以降は new が一貫して遅く、iter5000-6000 でピーク (+12.0%)、その後 iter12500 まで +1.8〜+9.7% の高止まりが続く** — これは 3 run 全てに共通するパターンであり、単一 run の transient ではない。
load sampler ログとの相関 — 減速が始まる iter 区間と load1 スパイクのタイミングが一致

10s 間隔 load sampler (`runs-logs/finalv2-12500-loadsamples.log`) を r1/r2 window の epoch timestamp と突き合わせると: r1 window (pre 1788100979.56 → post 1788101115.01) 内で load1 が 1788101039.64 に **5.77** まで上昇 (window 開始から +59.4s、r1 の iter6000 (elapsed 51.36s) 〜 iter7000 (elapsed 64.71s) の区間に相当)。r2 window (pre 1788101165.15 → post 1788101299.60) 内でも 1788101239.96 に **4.22** まで上昇 (window 開始から +74.8s、r2 の iter7000 (61.00s) 〜 iter8000 (73.33s) 付近)。r3 window はサンプル値が終始 2.1〜3.0 で最も低く、実測 wallclock も 3 run 中最速 (128.10s) — load スパイクのタイミングと ms/iter の減速タイミング・run 間の速度順位がいずれも整合する。

`ps aux` で捕捉した実際の同時実行プロセス — Finder 147%CPU、無関係な別プロジェクトのバイナリ、音声処理

Part 2 (ficus) 実行直後の `uptime` で load average が 9.96→16.88→32.58 まで跳ね上がったため `ps aux | sort -rk3` で原因を確認したところ、/System/Library/CoreServices/Finder.app が **147.3%CPU**、ユーザーの別プロジェクト (/Users/otkrickey/dev/otksynth/target/debug/deps/analyze_queue-*、matsudalab とは無関係な Rust バイナリ) が **35.7%CPU**、音声処理プロセス (dj-lab) が **24.8〜49.9%CPU** で稼働しているのを直接確認した。これらは本タスクの一部ではなく、ユーザー自身が同じ機体上で並行して行っていた無関係な作業であり、Part 1 series (23:42〜23:51) の後半・Part 2 の ficus/materials (23:54〜00:13) にかけて発生・持続していたと推定される (Part 1 の load スパイクのタイミングと符合)。GPU 権の取り決め (「他 agent は GPU を使わない」) は agent 間の話であり、ユーザー自身の CPU 作業は対象外だった — Apple Silicon の unified memory 帯域は CPU/GPU で共有されるため、CPU 側の重い並行負荷が GPU バウンドな学習の host-side critical path (host_schedule=forward_shadow 等) を遅らせうる。

残る疑問 — r3 は load がクリーンでも control より +4.3% 遅い、load スパイクは『ばらつき』は説明するが『底上げ』の全量は説明しない

advisor レビューでの指摘: r3 (128.10s) の window 内 load サンプルは終始 2.1〜3.0 (最大 3.00) で、M7 が『クリーン』と判定した r2-r4 の window (0.93〜3.46) と同水準であるにもかかわらず、control (122.768s) より **+4.3%**・M7 の r2 (123.34s) より **+3.9%** 遅い。segment 単位でも iter11000-12000 (12.51ms/iter、M7 3-run 平均 11.88ms/iter 比 **+5.3%**) に load スパイクの証拠なしに減速が見える。**したがって load スパイクは r1>r2>r3 という 3 run 間の『ばらつき』の順位は説明するが、3 run 全てに共通する ~4〜6% の『底上げ』の全量までは説明できていない**。念のため 2 点を確認した: (1) `git diff --stat 2cb044bde530a425b89c3e90d2532d0e37673021 9bb4ea5 -- splat/crates/` は rasterize.rs / ssim.rs / tile_bin.rs / config.rs / refine.rs の 5 file に diff を持つが、内容を確認すると**全て gate 完了後の verdict 追記という doc comment のみ** (raw struct 初期値・実行ロジックは無変更、`git diff` は `git log` と異なりマージの履歴簡約を経ないため、この空でない diff の中身が doc-only であることを確認できて初めて『事実上同一コード』の主張が成立する)。(2) `diff splat/configs/2026-08-30-rnd-12500-off-r1.toml splat/configs/2026-08-30-finalv2-12500-r1.toml` は `[backend] refine_gpu_snapshot = false` の明示 vs 無指定 (どちらも解決値は `false`) のみで、他の `[backend]` field 差は無い。**この 2 点はいずれもクリーンで、control が本 session の HEAD と機能的に同一コードであることを裏づける** — が、これは「なぜ r3 でも+4%遅いか」を説明しない。残る有力候補は thermal/DVFS drift (本機は series 開始時点で既に 11h+ 連続稼働、当日を通じて M0〜M8 の多数の GPU gate を実行済み) だが、`sudo powermetrics` が使えない環境のため確認できていない。結論を『130.657s は完全に session 汚染で説明される』から『load スパイクは run 間のばらつきを説明するが、3 run 共通の残差 ~4〜6% は未解明で thermal/DVFS drift が有力候補 (未検証)』に修正する — この修正は milestones.md の headline (paired control 122.77s を採用) には影響しない、unpaired series が paired control に劣後するという結論はどちらの読み方でも同じだからである。

paired control 2 本 — 同日・実質同一コードで 122.65s/122.77s が相互 0.13% で一致

同日 22:25 の S4b gate は on-arm (ssim_reduce=gpu、12.5k n=3 交互 A/B) で **122.768s (σ0.864%)** を記録済み。さらに 23:30 の `p3-refine-nondrain` gate は off-arm (refine_gpu_snapshot=false、すなわち現行 default と同一の経路) で **122.6467s (σ0.330%)** を記録しており、このコード状態は本 session の HEAD (9bb4ea5) と refine_gpu_snapshot という no-op field の追加のみが差 (default false で経路変更なし、finding: p3-refine-nondrain 参照) で事実上同一である。この 2 点は独立の A/B gate の一方の arm として alternating 実行 (session 内 drift を打ち消す設計) で得られており、相互に **0.13%** で一致する — 単発の unpaired n=3 である本 finding の 130.657s よりもはるかに信頼できる「現在の真値」の推定である。milestones.md の「現在地」表はこの 122.768s (S4b の paired 値) を維持し、130.657s では上書きしない。

既存の汚染判定規約への拡張提案 (advisor 指摘、本 finding の house convention への貢献)

`p3-tier1-bit-exact.toml` §5 が定めた事前登録条件 (load 証拠 AND 自 arm 内 3σ 超) は「1 run だけが外れる」パターン (M7 の r1 のように) を検出するために設計されており、本 finding のように session 全体が相関して底上げされ、3 run のいずれも自 arm 内で 3σ を超えない パターンには構造的に無力である。拡張案: 「unpaired series の mean が、同一コードでの同日 paired control (存在する場合) から 2% 以上乖離している場合、intra-arm σ に関わらず session 汚染を疑い、paired control 側を優先する」という規則を house convention に追加することを提案する。今回のケース (mean 130.657s vs control 122.65-122.77s、乖離 6.4-6.5%) はこの閾値を大きく超えており、拡張規則があれば ms/iter trace の詳細分析を待たずに一次判定できた。

3. 累計 ablation 表 — S4b 行の追加 (paired Δ) + v2 独立再計測 (session 汚染、参考値)

段階施策Lego 12.5k train elapsed (s)PSNR (dB)Δ (対前段)msplat 比較値
Phase 0baseline (規約 v2 適用後)766.0736.216—4.51×
+ C0resident binning arena + radix pass skip 16→11395.5936.183-48.4%—
+ LCbackward last_contributor range336.3336.191-15.0%—
+ S1pipeline 全域 resident 化 (Tier A/B/C)261.5536.148-22.2%1.56×
+ W1warp sparse skip241.4136.201-7.7%1.44×
+ W2chained submission (adam+loss chain 統合)219.5136.170-9.1%1.31×
+ S2forward 1 CB 化 + hierarchical GPU scan187.6536.167-9.9%1.105×
+ S3iteration pipelining depth 2151.7036.202-18.1%0.907× (process wallclock 154.00s 基準、train elapsed 列とは分子が異なる点に注意)
+ radix simd_ballot (M4)radix scatter simdgroup ballot 2 段化127.5336.143-14.9%—
+ refine 3-pass 削減 (A7)refine scratch 永続化 + compact 直書き124.8136.241-2.15%—
+ 最終スタック独立再計測 (M7)M4+A7 済みスタックの独立 n=3 gate124.3936.219-0.33% (ノイズ帯)0.755×
**+ ssim_reduce=gpu (S4b)**read_mean_ssim を GPU 1-dispatch reduction 化**122.77** (gate on-arm, paired)36.179 (gate self-eval)**-1.4347%** (paired Δ、off 124.555→on 122.768)**0.745×** (§4)
最終スタック v2 独立再計測 (M7v2、参考値)S4b 込みスタックの独立 n=3、**session 汚染あり**130.657 (as-measured、σ1.727%)36.257 (self-eval) / 36.289 (brush cross-eval)— (§1/§2 の理由によりΔ算出せず、headlineに不採用)0.793× (as-measured、非公式値)
S4b 行は `p3-s4b-ssim-reduce.toml` の paired A/B (12.5k n=3 交互、off mean 124.555s → on mean 122.768s) の Δ をそのまま転記 — 「M7 124.39s → S4b 122.77s」という cross-session の引き算は前回 M7 finding 自身が明記したとおり reproducibility noise であり effect size ではないため、Δ 列には使わない (advisor 指摘)。v2 独立再計測行は §1/§2 の session 汚染により Δ 列を意図的に空欄・参考値扱いとし、累計 ablation の headline (Phase0 → 現在) は S4b paired 値 122.77s を用いる: Phase0 (766.07s) 比 **-83.98%**。

4. msplat 等価再比較 — control 値ベースで再計算 (headline) + as-measured 値 (参考)

断面M7 (2026-08-30、S4b前)M7v2 headline (S4b paired control 122.768s)M7v2 as-measured (session汚染、参考)
wallclock gap (block1 n=2 分母 164.69s)0.755×**0.745×**0.793× (非公式値)
同上、rnd off-arm 122.6467s でも算出—0.745× (独立 control で再現)—
per-splat·iter throughput (本実装/msplat)0.926× (msplat比7.4%優位)**0.916×** (msplat比8.4%優位)0.975× (非公式値)
brush convention PSNR (finalv2 final.ply 実測)+2.006dB (旧final.ply)brush cross-eval q8 mean **36.289dB** (msplat保守値34.243比 **+2.046dB**)同左 (load非依存のためload汚染の影響を受けない)
throughput は avg splats を新 3 run の trapezoid 積分で自前算出 (321,011、M7 の 321,637 と 0.2% 差で一致)。headline 0.916× は Pareto v3b の 12.5k 点と同じ『異なる run の混合』であることを明記する: wallclock (122.768s) は S4b on-arm の paired control、avg splats (321,011) は session 汚染下の finalv2 series からの算出 — ただし splat 数は load 汚染の影響を受けない量 (M7 の 321,637 との 0.2% 一致がこれを裏づける) なので、この混合は妥当と判断した (Pareto の x/y 混合を script docstring に明記したのと同じ理由で、ここでも黙らせず明示する)。M7 が明記した「msplat 側 avg splats (~165,000) は借用値で ±8.0% 未満の誤差なら本実装優位が成立」という留保は本 finding でもそのまま引き継ぐ — 本 session では msplat 側を再導出していないため確定させられない (numerator の再現性を確認しただけで、denominator の不確かさは変わらない)。brush cross-eval PSNR は PLY への静的評価なので load 汚染の影響を受けず、as-measured/headline の両方で同じ値を使う。

5. Pareto v3b

生成スクリプト
`docs/strategy/make_msplat_pareto.py` を複製した `docs/strategy/make_msplat_pareto_v3b.py`。12.5k 点の x 座標を S4b on-arm control (122.768s) に、y 座標を finalv2 の brush cross-eval q8 実測 (36.289dB) に更新。**x と y が異なる run 由来であることを script docstring に明記した** (advisor 指摘: 沈黙させず可視化すること) — control run 自体は brush cross-eval を実行していないため、load 非依存の PLY 評価値 (finalv2) を援用する形
旧 v3 の扱い
`docs/strategy/make_msplat_pareto.py` (v3 生成スクリプト) と `docs/figures/pareto-v3-msplat-lego-final-stack.png` は**一切変更していない** — 新スクリプト・新 png ファイルとして追加
出力
`docs/figures/pareto-v3b-msplat-lego-final-stack-v2.png`
注記表示
図中の gap 注記はスクリプトの既存慣習を継承し msplat n=4 mean 分母 (165.42s) で計算 — **0.742×** (v3b) / 旧 0.755× (v3, M7、n=4分母だと0.752×) / 旧 0.927× (2026-08-17) の 3 段書き。本 finding 本文の headline 0.745× は §4 と同じ n=2 分母 (164.69s、継続性のための主分母) を使っており、図中注記 (n=4分母) とは分母が異なる点に注意 (旧 v3 finding も両分母を併記していたのと同じ形式)

6. Part 2 — 多 scene breakage screen (ficus / materials / drums)

選定理由 — baseline recipe が完全一致する scene から、splat 数レンジが分散するよう 3 つ選定

2026-08-30 に採用された M4 (radix simd_ballot)・A7 (refine 3-pass 削減)・S4b (ssim_reduce=gpu) はいずれも Lego 12.5k gate のみを根拠にしている。`p1-axis1-phase-g-pareto-landscape.toml` §2 (G.3-alone 30k recipe、2026-05-25 実測、HEAD 5e222bd) の 8 scene 表から、baseline PSNR/wallclock/splats が全て記録済みかつ config の `[trainer]`/`[refine]`/`[adam]`/`[data]` 節が現行 (`2026-08-30-final-12500-r1.toml`) と (dataset_path/name/run_dir を除き) diff で完全一致することを確認した ficus (30k、227k splats)・materials (30k、355k splats)・drums (30k、998k splats) を選んだ。drums は Lego 12.5k (407k splats) の 2.5 倍規模で、3 施策がいずれも splat 数に non-uniform に依存する経路 (radix は pair 数、refine scratch は splat 数、SSIM 総和は image-size-bound で splat 数非依存) を持つ中で、初めて Lego gate のレンジ外の splat 数をテストする scene として選定した。config は元の `2026-05-25-2330-{scene}-phase-g3-sh-progressive-30k.toml` を複製し dataset_path/name/run_dir のみ変更、backend flag は無指定 (現行 default = M4/A7/S4b 込み全部が効く)。

scenesplats規模baseline PSNR (2026-05-25)new PSNR (2026-08-31)ΔPSNRbaseline wallclocknew wallclockwallclock系統性baseline splatsnew splatsΔsplats
ficus227k (最小)34.28134.261**-0.020dB**21m40s (1300s)349.63sload 9.6-32.6 で終始汚染、方向感のみ226,749227,481+0.32%
materials355k (中)30.02529.998**-0.027dB**30m46s (1846s)421.90sload 7-27 で終始汚染、方向感のみ349,784355,033+1.50%
drums998k (Lego比2.5倍)27.21727.207**-0.010dB**1h5m36s (3936s)687.85s**iter27000まで load 0.8-5.5、ほぼクリーン**1,001,014997,958-0.31%
3 scene とも ΔPSNR は `a-10-variance-baseline` の σ±0.32dB (Lego 30k での run-to-run noise floor、n=1 baseline vs n=1 new のため参考値だが目安として妥当) の 1/10 以下で退行なし。wallclock は ficus/materials が load 汚染下 (Part 1 の汚染と同一の原因、§2 参照) のため参考程度 (旧比 ≥3.7×/≥4.4× 高速化の方向感のみ)、drums は load がほぼクリーンで **3936s→687.85s = 5.72× 高速化**を確度高く実測できた。**§14 で ficus/materials を静穏条件 (in-run load サンプラーで監視) で再実行しており、wallclock はそちらの値 (ficus 254-256s、materials 319.54s) を正式値として使うこと** (PSNR は load 非依存の量のため本表の値のまま変更しない)。**§14 の追加 run (ficus q1/q2) により、この σ±0.32dB / 1/10以下という比較は ficus には無効であることが判明した** — 同一 modern-stack config を3回回した range が1.443dB (a-10 の range 0.885dB の1.6倍) に達し、n=1 ΔPSNR -0.020dB はこの range に埋もれる程度の情報量しか持たない。詳細は §14 を参照。
退行判定の位置づけ — breakage screen であって効果測定ではない (advisor 指摘)

M4 (radix scatter の rank 計算方式変更、sort parity は bit-exact)・A7 (refine の allocation/copy 経路変更、書き込みロジック自体は不変)・S4b (`read_mean_ssim` を gradient に触れない loss scalar の集約経路のみ変更) はいずれも「計算結果 (gradient / param 更新) を変えない」ことが設計上保証された施策であり、PSNR trajectory が理論上動く理由がない。したがって本 §6 の ΔPSNR が小さいことは「3 施策が効いた証拠」ではなく「3 施策が Lego 以外の scene・splat 数レンジで壊れていないことの確認 (breakage screen)」である。仮に 1 scene で ±0.1dB を超える差が出た場合の正しい結論も「その scene で回帰が確定した」ではなく「その scene に絞った scoped A/B gate が必要」であり、本 finding はその条件 (>0.1dB の乖離) が発生しなかったため追加 gate は不要と判断した。ただし §14 の追加計測により、この ±0.1dB という閾値自体が ficus には無効であることが判明した — ficus は同一 config・3 run で range 1.443dB を示す scene であり、n=1 の ΔPSNR がこの閾値を下回っても「退行なし」を確度高く主張する根拠にはならない。M4/A7/S4b が PSNR-neutral な設計 (grad/param 更新を変えない) であるという結論自体は変わらないが、n=1 の ΔPSNR でそれを「確認」できるのは range がタイトな scene (materials: 0.028dB) に限られる、という限定を追記する。

7. milestones.md への反映

  • 「現在地」表: Lego 12.5k train elapsed は **S4b gate on-arm の paired 値 122.77s を維持** (v2 の as-measured 130.657s では上書きしない、理由は §1/§2)。msplat 等価 gap を 0.755×→**0.745×**、throughput を 0.926×→**0.916×** に更新 (control 値ベース)。brush cross-eval PSNR を 36.249dB→**36.289dB** に更新 (load 非依存の実測、+0.04dB でほぼ不変)
  • 新規行: 「多 scene breakage screen (2026-08-31)」— ficus/materials/drums の 3 scene で M4/A7/S4b の退行なしを確認、drums (998k splats、Lego比2.5倍) で 5.72× 高速化を確度高く実測。出典: p3-final-stack-v2 §6
  • 進捗ログに M7v2 完了の 1 行を追記 (session 汚染の発見と control 値維持の判断を明記)

8. thermal/DVFS drift 検証 (2026-08-31)

手順 — 10 分 GPU idle cooldown 後に finalv2 と同一 config で n=2 独立再計測

§1/§2 で「r3 (load クリーン) でも control より +4.3%」が load スパイクだけでは説明できず、thermal/DVFS drift を未検証の有力候補として残した。本検証は同一 binary (sha256 `c804b349223ffc68e9e1101d79c5ea9f058dfa8d34620504b66aa0a3eb10aa13`、finalv2 と不変)・同一 git rev 系統 (5c731cf、finalv2 の 9bb4ea5 から docs-only commit 1 本のみ進んだ状態、`splat/` crate は無変更なことを確認済み) で、(1) AC 電源・`pgrep -f splat` 空・top CPU procs を記録、(2) GPU を 10 分 idle にして cooldown、(3) `configs/2026-08-31-finalv3-12500-r{1,2}.toml` (finalv2-r1/r2 の `[trainer]/[refine]/[adam]/[backend]` 節と `diff` で完全一致、`[experiment]`/`[output].run_dir` のみ変更) を `final-stack-n3.sh` で連続 2 本実行、load sampler (10s 間隔) で run 中の load を記録した。`pmset -g therm` はこの機体では cooldown 前後とも `No thermal warning level has been recorded` 等の空出力で、直接的な thermal telemetry は取得できなかった (`sudo powermetrics` 不使用の既知の制約)。

項目cooldown 前cooldown 後 (10分 idle)
pmset -g battAC Power, 100% chargedAC Power, 100% charged (不変)
pmset -g thermNo thermal/performance warning level / No CPU power status recorded同左 (不変、有効なシグナルなし)
pgrep -fl target/release/splat(none)(none)
top CPU procs (ps aux top5)`bfs -S dfs ...` (find代替、gpui検索) 292.7%CPU が最上位、他は coreaudiod 8.4% / windowserver 6.3% / ghostty 3.7% などbfs は終了済み。coreaudiod 10.7% / claude(本agent) 7.3% / ghostty 4.2% / corespeechd 4.1% / windowserver 3.6% — 重い競合プロセスなし
load averages (1/5/15min)(cooldown 開始前は未記録、系列サンプラー開始直後で 2.57/4.06/4.79)2.71/4.11/4.81 (cooldown 直後) → r1 実行前 quiesce 時点で 2.21
`pmset -g therm` は本機では cooldown 前後で全く同じ空出力を返し、GPU/CPU の thermal state を判定する直接的な材料にならなかった。CPU 側の重い同時プロセス (前回 finding が挙げた Finder 147%CPU 相当) は cooldown 前後とも不在で、cooldown 前に唯一目立った `bfs` (ファイル検索、292.7%CPU) も finalv3 系列開始前には自然終了していた。
runelapsedPSNR (self-eval)splatsrun 中 load (min-max, 10s sampler)
finalv3-12500-r1127.989s36.333405,7161.31-2.57 (系列全体)
finalv3-12500-r2131.512s36.178409,583同上 (r1/r2 共通サンプラー)
**mean (n=2)****129.750s**36.256 (平均)407,650 (平均)**max 2.57** — finalv2 r3 の 2.1-3.0 より更にクリーン
control 参考 (S4b on-arm / rnd off-arm)122.768s / 122.6467s (mean 122.707s)36.179 / — (gate self-eval)—paired alternating A/B (§3 参照)
finalv3 mean 129.750s は control mean (122.707s) 比 **+5.74%**、S4b on-arm (122.768s) 比 **+5.69%** — 判定基準の ±1.5% バンド (120.93-124.61s) を大きく超えて外れている。しかも run 中 load は finalv2 r3 (2.1-3.0) よりクリーンな 1.31-2.57 に収まっており、load 汚染 (同時プロセスによる CPU 競合) では今回の遅さを一切説明できない。
判定 — 10分 cooldown では回復せず。ただしコード起因も棄却: 未解決の『恒久的だが code-diff では説明できないドリフト』

事前登録した 2 分岐判定のどちらにも単純には当てはまらない。(1) 「10分 cooldown で control ±1.5% に戻れば thermal drift 確定」は不成立 — finalv3 mean 129.75s は control から 5.7% 乖離したままで、cooldown 前 (finalv2) とほぼ同水準 (finalv2 as-measured 130.657s との差はわずか 0.7%)。load は同時に測った sampler 上で finalv2 r3 より更にクリーンなので、cooldown 実施・同時プロセス不在という 2 条件をどちらも満たしてなお速度が戻らなかった。(2) 「130s 圏のままなら binary/環境の恒久的変化を疑う」に従い `git log --oneline -8` と `git diff 4405bb4 HEAD --stat -- splat/` を確認したところ、S4b gate (4405bb4) 以降に `splat-metal`/`splat-train-v1` の複数ファイル (`refine.rs` +598 行など) に実コード変更 (`refine_gpu_snapshot` flag 新設、C2 施策#4) があった。しかし該当 flag の default は `false` (config.rs Default impl で確認)、かつこの機能一式が **finalv2/finalv3 と bit-identical な binary (sha256 c804b349...)** で既に組み込み済みの状態のまま `p3-refine-nondrain` gate の off-arm が同日 23:30 に **122.6467s** を記録している (§2 既存記載)。つまり『遅い』finalv2/finalv3 と『速い』refine-nondrain off-arm は **文字通り同一バイナリ** であり、コード差分では今回の +5.7% を説明できないことを再確認した。結論: cooldown 前後で速度は変化せず (thermal drift の単純な仮説は反証)、コード差分でも説明できない (binary/環境の恒久的変化の単純な仮説も反証) — 残る説明は『10 分では解消しない、より長い時定数を持つ電源/サーマル状態のヒステリシス』(`pmset -g therm` がこの機体で無効なため直接確認不能) であり、これは未解決のまま残す。 最終値としては引き続き **paired control 122.77s (S4b on-arm) を採用**する — この判断は §2/§3 の既存結論と変わらない (unpaired 単発測定は paired control に劣後する)。今後の追加検証をするなら、10 分ではなく数十分〜完全な reboot 後の cooldown で再試行するのが次の一手になる。

9. drift 切り分け再実行 (2026-08-31、byte-identical control config を再実行)

手順 — 2026-08-30-s4b-12500-on-r1.toml を run 名のみ変えて再実行

§8 は finalv2/finalv3 (backend flag 明示なし、default 経由で ssim_reduce=Gpu 等が効く) が paired control (backend flag に `ssim_reduce = "gpu"` を明示) より恒常的に +5.7% 遅い件を検証したが、cooldown では説明できず未解決のまま残した。本節はもう一段単純な切り分けを行う: control config (`2026-08-30-s4b-12500-on-r1.toml`) を一切変更せず (`[experiment].name`/`description`/`[output].run_dir` のみ変更、`diff` で `[data]`/`[trainer]`/`[refine]`/`[adam]`/`[backend]` が 1 バイトも変わっていないことを確認済み) 、run 名だけ `s4b-12500-on-rerun` にして今この瞬間に 1 本再実行する。結果が ~122s (元の control と同水準) に戻れば「explicit flag の有無で経路が変わっている bug」、~130s (finalv2/v3 と同水準) のままなら「環境の時間依存 drift」と判定する事前登録。binary sha256 (`c804b349...`)・git rev (`1565fcc0`) は §8 と不変。

runelapsedPSNR (self-eval)splatspre load (1/5/15m)post load (1/5/15m)同時実行プロセス
control 原本 (2026-08-30-s4b-12500-on-r1, 参考再掲)122.768s (paired)36.179 (gate self-eval)———§3 記載、A/B 交互で汚染なし
finalv2/finalv3 (§1/§8, 参考再掲)130.657s / 129.750s36.257 / 36.256407,650 / 407,650 (平均)——finalv2: Finder 147%CPU 等。finalv3: **load はほぼクリーン (1.31-2.57) でも遅い**
**s4b-12500-on-rerun (本節、2026-08-31)****125.19s****36.218****409,606**1.78 / 2.05 / 3.065.29 / 2.79 / 3.17**`bfs -S dfs ...` (全ファイルシステム検索、他 agent の file search) が run 終盤に 500-600%CPU で実行中を `ps aux` で確認、load1 が pre 1.78 → run 中ピーク 3.87 → post 5.29 まで上昇**
rerun は control 原本比 **+1.973%** (122.768s→125.19s)、finalv2/finalv3 mean (130.204s) 比では **-3.85%** (finalv3 単体比 -3.51%) — 事前登録した 2 分岐 (~122s か ~130s) のどちらにも完全には一致しない中間値。ただし §8 の finalv3 (load 終始クリーン 1.31-2.57) が 129.75s だったのに対し、本 rerun は **finalv3 より明確に load が汚染されていた (peak 5.29) にもかかわらず finalv3 より 3.5% 速い** — 「load 汚染が遅さの原因」という説明とは逆方向の結果になっている。
判定 — 断定はできないが、explicit flag config は今も ~122-125s 帯を維持: 純粋な普遍的 drift 説を弱める材料

125.19s は ~122s 陣営 (+1.97%) の方に ~130s 陣営 (-3.85%) より 2 倍近く近い。加えて本 rerun は §8 の finalv3 (完全クリーンな load) より重い contamination (`bfs` 500-600%CPU) を run 終盤に受けながらも finalv3 より速く完走している。もし『今この機体は時刻に依存して一律 130s 圏まで遅くなっている』という単純な普遍的 drift が真であれば、contamination で下駄を履かされたはずの本 rerun がむしろ finalv3 を上回って速く終わる理由がない。したがって本結果は「explicit backend flag 明示の config は §8 以降も一貫して 122-125s 帯を保っており、backend flag 無指定 (default 依存) の config だけが 130s 圏に留まっている」という『flag 経路依存』説をわずかに支持する一方、rerun 自体が contamination を受けているため 122.77s ちょうどには戻っておらず、explicit flag 説を確定させるにも至らない。結論は「引き続き未確定」だが、§8 で立てた「10分では解消しない普遍的な電源/サーマルヒステリシス」という仮説の優先順位はやや後退し、次の一手としては『explicit flag config』と『default flag config』を同一 session・同時間帯・load クリーンな状態で back-to-back 実行する A/B が、cooldown 再試行より優先度が高いと判断する。milestones.md の現在地は引き続き §2/§8 の判断 (paired control 122.77s を採用) を変更しない。

10. Lego 30k 最終スタック headline — msplat 30K との同一 iter 数比較

手順 — config = 2026-08-31-final-lego-30k.toml (recipe: p1 phase-g3-sh-progressive、backend は明示せず default)

2026-06 時点で卒論・戦略文書が引用してきた「本実装 11m48s(708s、Phase H 12,500 iter)/36.26dB vs msplat 3m40s(219.8s、30,000 iter)/35.48dB」(`p1-msplat-baseline-spike.toml`) は iter 数が非対称 (本実装 12,500 iter vs msplat 30,000 iter) な比較であることに加え、msplat 側の 219.8s/35.48dB 自体も init 点群・holdout・解像度スケジュールが不明な条件非対称の初期 spike 値であることが `p2-msplat-parity-lego.toml` (2026-08-16、同日・同一 init 点群・同一 evaluator の対称条件再計測) で判明している。同 finding は msplat 30K の対称値を 167.7s (n=2 mean) / native 36.53 dB / brush cross-eval (q8) 33.05-34.47 dB (非決定性 1.4dB) と確定し、219.8s/35.48dB は「条件非対称、参考」として脚注化する規約を定めた。本節は現行 HEAD (1565fcc、M4 radix_scatter=SimdBallot / A7 refine_scratch_persist,refine_direct_write=true / S4b ssim_reduce=Gpu 込みの最終スタック) で 本実装も 30,000 iter で 1 run 実行し、初めて msplat と同一 iter 数・かつ p2-msplat-parity-lego の対称値を基準にした headline 比較を作る。config は `2026-05-25-2030-lego-phase-g3-sh-progressive-30k.toml` (brush 規約: gt_convention=premultiplied、opacity_decay_rate=0.004、SH progressive init=0/max=3/unlock_interval=1000。`[trainer]`/`[refine]`/`[adam]`/`[data]` は現行 breakage screen で使用中の `2026-08-30-multiscene-drums-30k.toml` と diff で完全一致することを確認済み) を dataset_path/run_dir/name のみ変更して複製、`[backend]` は一切明示せず default に任せた。`splat check` で validate 後、pre-run に load1 9-33 (他 agent の `bfs` full-FS 検索 + 同一ユーザーの `otksynth_analyze` 別プロジェクトバイナリが同時実行中) を確認したため load1 < 6.0 が 60 秒継続するまで能動的に quiesce 待機してから起動 (pre load1 3.86 まで低下)。self-eval はトレーナー内蔵 (premultiplied 収束と同一 convention)、brush cross-eval は `splat eval --convention brush --quantize-8bit --split val` を final.ply に実行 (load 非依存の静的評価)。self-eval (premultiplied) と msplat の native/self-eval (white-bg) は convention が異なるため直接比較しない — 同一 convention での優劣判定は brush cross-eval 列のみで行う。

実装 / 断面iterwallclockself-eval PSNRbrush cross-eval (q8) PSNRfinal splats
msplat 30K r1 (2026-08-16、p2-msplat-parity-lego)30,000167.85s36.539 (native/white)33.049190,674
msplat 30K r2 (2026-08-16、p2-msplat-parity-lego)30,000167.48s36.513 (native/white)34.470194,986
**msplat 30K mean (n=2、同日対称条件、比較基準)****30,000****167.7s****36.53 (native/white)****33.76 (best 34.47)****192,830**
msplat 30K 2026-06-26 spike (条件非対称、脚注 †)30,000219.8s (3m40s)35.48 (native)—208,215
本実装 6月時点 (Phase H 12.5k、p1-msplat-baseline-spike)12,500708s (11m48s)36.26——
本実装 現行最終スタック 30k r1 (2026-08-31)30,000413.56s (6m53.6s)36.45736.501490,866
本実装 現行最終スタック 30k r2 (2026-08-31)30,000482.96s (8m2.96s)36.44336.486488,491
**本実装 現行最終スタック 30k mean (n=2)****30,000****448.26s** (σ10.95%)**36.450** (σ0.03%)**36.494** (σ0.03%)**489,679** (σ0.34%)
msplat 側の比較基準は p2-msplat-parity-lego (2026-08-16、同日・同一 init 点群・同一 evaluator の対称条件) を採用し、167.7s (n=2 mean) / native 36.53dB / brush ce 33.05-34.47dB とする。† 2026-06-26 spike (219.8s/35.48dB/208,215 splats) は init 点群・holdout・解像度スケジュール不明の条件非対称値であり、p2-msplat-parity-lego の規約に従い 脚注 (参考値、gap 算出には不使用) とする。本実装側: r1 は `training done in 413.56s` / `final splats: 490866`、r2 は `training done in 482.96s` / `final splats: 488491` (r2 も `[backend] BackendConfig` ログで M4/A7/S4b の実効値が r1 と完全一致することを確認済み)。self-eval は trainer 内蔵 `mean val: PSNR` (100 views、premultiplied 収束と同一 convention)、brush cross-eval (q8) は `splat eval --convention brush --quantize-8bit --split val` を各 run の `final.ply` に実行した実測 (load 非依存)。r2 は pre-run load1 4.47→3.48 (quiesce 済み) だったが post-run load1 が **24.44** まで跳ね上がった (`ps aux` で `mds_stores` = Spotlight metadata indexing が 98.6%CPU、機体ディスク残 1.9GiB という逼迫が誘因と推定) ため r1 より wallclock が **+16.8%** 遅く、n=2 σ (10.95%) は §1 の n=3 (1.727%) より大幅に大きい — n=2 では外れ値を統計的に検出・除外できないため、この σ は『クリーンな計測』の主張ではなく『ばらつきの大きさの記録』として扱う。self-eval / brush cross-eval PSNR と final splats は load 非依存でありσも小さく (0.03-0.34%)、両 run で安定している。self-eval PSNR 列は msplat が white-bg convention・本実装が premultiplied convention のため convention が異なり直接比較不可 (併記のみ)、同一 convention での優劣は brush cross-eval (q8) 列でのみ判定する。
比較軸旧 (非対称: 本実装12.5k vs msplat30k spike、参考・非推奨)新 (対称: 本実装30k vs msplat30k 同日対称条件)解釈
wallclock gap (本実装/msplat)**3.221×** (708s/219.8s、iter非対称+msplat条件非対称の二重非対称、参考)**r1 2.466× (413.56s/167.7s) / n=2 mean 2.673× (448.26s/167.7s)**msplat 側基準を spike (219.8s) から p2-msplat-parity-lego の同日対称値 (167.7s) に置き換え。r1 単体では 2.47×、r2 (482.96s、Spotlight 汚染疑い) を含む n=2 mean では 2.67× まで拡大する。旧 3.22× は iter 数非対称・msplat 条件非対称の二重の非対称を含むため参考値に降格、gap 算出には用いない
本実装 6月12.5k → 現行30k のwallclock (本実装内の時系列比較、msplatとは無関係)708s (12,500 iter)448.26s (30,000 iter、n=2 mean)**iter数2.4倍 (12,500→30,000) にもかかわらず wallclock は逆に-36.7% (1.58×高速、n=2 mean)** — per-iter throughput は概算 3.79倍改善 (6月17.7 iter/s → 現行 n=2 mean 66.9 iter/s)。r1単体では-41.6%/1.712×/72.5 iter/s。本行は msplat を含まない本実装内比較であり、上の wallclock gap 行 (msplat比較) とは別軸
PSNR (本実装 vs msplat 30K、brush 同一convention cross-eval)実測なし (spike に brush ce 記録なし)**本実装 brush ce n=2 mean 36.494 vs msplat 30K対称条件 brush ce best 34.47 (r1 33.05/r2 34.47) → +2.02dB (best比) / +2.73dB (mean比)**同一 evaluator・同一 convention (brush, premultiplied) での比較。msplat の brush ce は run 間で 1.4dB のブレがある (p2-msplat-parity-lego §4 非決定性) ため +2.02〜+3.45dB の幅で読む。convention 非依存の同一 evaluator 比較としてはこの行のみが優劣判定に使える
PSNR (self-eval/native、convention相違につき参考併記のみ・優劣判定せず)36.26 (本実装12.5k) vs 35.48 (msplat spike native)本実装 premultiplied self-eval n=2 mean 36.450 (r1 36.457/r2 36.443) vs msplat white-bg native mean 36.53 (r1 36.539/r2 36.513、p2-msplat-parity-lego)各実装は自分の学習 convention 下で評価されており (p1-a-3 の convention coupling)、直接比較は原理的に無効。優劣は上の brush cross-eval 行でのみ判定する
PSNR (本実装 現行30k vs 6月12.5k 36.26dB)—**+0.190dB (self) / +0.234dB (brush ce)** (n=2 mean)iter数2.4倍・大幅高速化と両立しつつ品質もわずかに向上 (30k化・最終スタック施策の複合効果、ノイズ帯に近いが方向は正)。本行も本実装内比較で msplat とは無関係
final splats (本実装30k vs msplat30k)—489,679 vs 192,830 (対称mean比、**2.54×**、n=2 mean。r1単体では490,866/192,830=2.55×)spike基準 (208,215) では489,679/208,215=2.35×だったが対称mean (192,830) 基準では2.54×とやや拡大。本実装は msplat 対称条件の2.5倍超の splat 数で高PSNR (brush convention) を達成 — 密な表現とrobustnessの傾向は従来のnarrativeと整合
msplat 側の比較基準は p2-msplat-parity-lego (2026-08-16、同日対称条件) の 167.7s (n=2 mean) / native 36.53dB / brush ce 33.05-34.47dB を採用し、2026-06-26 spike (219.8s/35.48dB) は条件非対称のため参考値に降格した (詳細は上表キャプション)。n=2 (r1 413.56s / r2 482.96s) の headline mean で見ると、gap は対称基準で r1 2.47×/n=2 mean 2.67× (旧 spike 基準 3.22× は参考)。PSNR は同一 convention (brush) でのみ優劣を判定でき +2.02dB (best比) 〜+2.73dB (mean比)、self-eval/native 同士 (36.45 vs 36.53) は convention 相違のため優劣を断定しない。r2 が r1 より遅い理由は post-run load1=24.44 (mds_stores 起因と推定) であり、σ10.95%は §1 の n=3 (σ1.727%) より大きい — n=2 では load 汚染を統計的に検出・除外できないため、この gap 2.67× は 2.47× (n=1) より保守的な (悪化方向に振れやすい) 値として扱う。
含意 — headline narrative の更新候補 (n=2 反映、変動幅に留意)

2026-06 spike が使っていた「本実装11m48s/36.26dB (12.5k) vs msplat3m40s/35.48dB (30k)」という比較は、iter数の非対称 (12,500 vs 30,000) に加え、msplat側の219.8s/35.48dBという数値自体がinit点群・holdout・解像度スケジュール不明の条件非対称な初期spike値である (`p2-msplat-parity-lego.toml`、2026-08-16の同日対称条件再計測で判明) という二重の限定を持つ。iter数を揃え、msplat側もp2-msplat-parity-legoの対称値 (167.7s (n=2 mean) / native 36.53dB / brush ce 33.05-34.47dB) に置き換えると、比較は「本実装 n=2 mean 7m28s(448.26s)/36.45dB(self, convention相違につき参考)・36.49dB(brush ce) (30k) vs msplat 167.7s(n=2 mean)/36.53dB(native, convention相違につき参考)・33.76-34.47dB(brush ce) (30k)」に置き換えられる。gap は r1(413.56s) で2.47×、n=2 mean(448.26s) で2.67× (旧3.22×はspike基準・iter数非対称の二重非対称値であり参考扱いに降格)。PSNR は同一convention (brush) でのみ優劣を判定でき、本実装が+2.02dB(best比)〜+2.73dB(mean比)優位 — ただしmsplat側のbrush ceは非決定性1.4dBを含む。self-eval/native convention同士の比較 (36.45 vs 36.53) はconvention相違のため優劣を断定しない — p1-a-3のconvention couplingの再確認である。final splatsは489,679 vs 192,830 (対称mean比) で2.54×。卒論§5のdirect comparison表・Paretoナラティブを更新する際はこの対称断面 (msplat側も対称条件)を優先すべきである。ただし r2 (482.96s) は r1 (413.56s) より+16.8%遅く、post-run load1=24.44 (`mds_stores` = Spotlight indexing 起因と推定、機体ディスク残 1.9GiB という逼迫も一因の可能性) の影響が疑われるため n=2 σ (10.95%) は §1 の n=3 (σ1.727%) より大きい。n=2 のみでは load 汚染を統計的に切り分けられないため、公式headline化するには (1) n=3 以上への拡張 (できれば load クリーンな条件での paired 実行)、(2) msplat側の同日再実行 (p2-msplat-parity-lego と同様のinterleave手順、本節では2026-08-16実測を借用しており本実装30k runとは別日) の両方を推奨する。PSNR (self-eval / brush cross-eval) と final splats は load 非依存でσが小さく (0.03-0.34%)、こちらは n=2 でも安定した根拠として扱ってよい。「6月708s/36.26dBはPhase H 12,500 iterであり、本節の30k比較 (本実装/msplat双方とも30,000 iter) とは別条件」という点を卒論反映時にも明記すること。

12. msplat 30K の同日再実行 — §10 headline の対称比較を完成させる

手順 — p2-msplat-parity-lego と同一条件 (culled init.ply 5207 pts、train 100 view 全量、常時フル解像度)

§10 の含意で挙げた申し送り事項 (「公式headline化には msplat 側の同日再実行を推奨」) を実施する。msplat venv (wheel v1.1.3、`uv venv --python 3.12` + `uv pip install msplat==1.1.3 numpy pillow`、torch 不要 — msplat は Metal ネイティブ実装で `_core.cpython-312-darwin.so` を直接 import する) をスクラッチパッドに再構築 (前回 session のセッション専用パスは既に消えていたため再作成)、`docs/strategy/msplat_parity_lego.py convert` で dataset を再変換 (5207 pts の culled init.ply、100 train view の white-bg composite、常時 800×800 — p2-msplat-parity-lego と完全同一条件) し、`train --iters 30000` を 1 run 実行した。pre-run に AC 電源・`pgrep -fl "splat|msplat|python"` 空・load1 2.43 (<6) を確認済み。§10 の 本実装 30k r1 (413.56s、commit 1565fcc、2026-08-31 実行) と同じ HEAD 系列・同じ M4 Max で日付を跨いでいない (同日 01:54-01:58 実行)。brush cross-eval は §10・p2-msplat-parity-lego と同じ `splat eval --convention brush --quantize-8bit --split val` (q8 が公式値、no-quant は overshoot で 21.4dB まで崩壊し p2-msplat-parity-lego §4 の再現)。

実装 / 断面iterwallclockself/native PSNRbrush cross-eval (q8)final splats
msplat 30K (2026-08-16 parity、p2-msplat-parity-lego 参考再掲)30,000167.7s (r1/r2 mean)36.53 (native)33.05 / 34.47 (r1/r2)190,674 / 194,986
**msplat 30K (2026-08-31 本節、同日実行)**30,000**165.65s****36.462 (native)****33.927****191,941**
本実装 現行最終スタック 30k r1 (§10、2026-08-31 同日)30,000413.56s36.457 (self)36.501490,866
本実装 現行最終スタック 30k n=2 mean (§10)30,000448.26s36.450 (self)36.494489,679
msplat 実測は `TRAIN_WALLCLOCK_S 165.65` / `FINAL_SPLATS 191941` / `MSPLAT_NATIVE_VAL_PSNR 36.4620 dB` (msplat 内蔵 white-bg eval、100 views) をログから直接取得。2026-08-16 parity 実測 (167.7s / 36.53dB) と 0.2dB・1.2% 以内で一致し、msplat 側の再現性を確認 (venv 再構築・dataset 再変換を経ても同水準)。brush cross-eval (q8) は `msplat_parity_lego.py convert-ply` で本実装配列に変換した PLY を `splat eval --convention brush --quantize-8bit` に通した値。raw 成果物 (final PLY 2 形式、driver log) は `/Users/otkrickey/dev/3dgs-workspace/msplat-parity-20260831/` に保存。
比較軸値解釈
wallclock gap (本実装 r1 / msplat、真の同日 n=1 対 n=1)**2.497×** (413.56s / 165.65s)§10 は本節の実行前に msplat 側を 2026-08-16 の借用値 (167.7s、非同日) に更新済みで gap 2.466× だった。真の同日実測 (165.65s) に置き換えると gap は **2.497×** とわずかに拡大 — msplat が今回さらに速かった (165.65s < 167.7s) ことが主因で、2026-06 spike (219.8s) 基準の旧 1.882× からは大きく拡大する。
wallclock gap (本実装 n=2 mean / msplat、真の同日)**2.706×** (448.26s / 165.65s)§10 の 2026-08-16 借用値基準 (2.673×) からわずかに拡大。n=2 mean (r2 の load 汚染込み) を分母にすると gap はさらに拡大する。§10 の n=2 σ10.95% の議論はそのまま有効 — 保守的な (悪化方向の) 参考値として扱う。
PSNR (brush cross-eval q8、同一 evaluator・真の同日)本実装 **+2.574dB** (36.501 vs 33.927)p2-msplat-parity-lego §4 の convention coupling が同日 30k iter 断面でも再現: msplat は white-bg 学習のため premultiplied (brush) 評価で native (36.46) から -2.5dB 落ちる。§10 の 2026-08-16 借用値基準 (best比+2.02dB/mean比+2.73dB) と比べても、本節の真の同日値 (+2.574dB) は同じレンジに収まり、msplat 側の brush ce 非決定性 (1.4dB) の範囲内で整合する。
PSNR (native/self、各実装の学習 convention)msplat **+0.005dB** (36.462 vs 36.457、ほぼ同値)各実装が自分の convention で測ると真の同日 30k iter でも事実上互角 (§10 の 2026-08-16 借用値 36.53 との差も 0.07dB でノイズ帯)。品質優位の主張は native 断面では成立せず、brush cross-eval (本実装の学習 convention) でのみ成立する点に注意 (p2-msplat-parity-lego §4 と同型の限定)。
final splats 比**2.557×** (490,866 vs 191,941)§10 の 2.54× (2026-08-16 借用値 mean 基準) とほぼ一致。本実装は同 iter 数で msplat の 2.5 倍超の splat 数を使って同水準の native PSNR / brush 優位を達成 — 密な表現という傾向は不変。
§10 は本節の直前に p2-msplat-parity-lego (2026-08-16、非同日) の借用値 (167.7s / 36.53dB / brush ce 33.05-34.47dB) で spike (219.8s) を置き換え、gap を 1.88×/3.22× (spike基準) から 2.47×/2.67× (2026-08-16借用値基準、n=1/n=2 mean) に更新した。本節はさらに一歩進め、msplat 側も 真に本実装と同日 (2026-08-31) に再実行 (165.65s / 36.462dB / brush ce 33.927dB) し、gap を **2.50×(n=1)/2.71×(n=2 mean)** に微調整した。2026-08-16 借用値 (167.7s) と真の同日値 (165.65s) の差はわずか1.2%・0.07dBで、p2-msplat-parity-lego の非同日借用が導入するバイアスは小さかったことも確認できた — ただし『同日実測』こそが本 finding の当初の申し送り事項であり、本節でその条件を完全に満たした。
結論 — headline gap は本節の真の同日対称比較 (2.50×/2.71×) を正式値とする

msplat 30K = 165.65s / native 36.462dB / brush ce (q8) 33.927dB / 191,941 splats (2026-08-31 真の同日実測、本実装 30k r1/r2 と同一日・同一 M4 Max)。本実装 30k r1 (413.56s / self 36.457dB / brush ce 36.501dB / 490,866 splats、§10) との完全対称 gap は wallclock 2.497× (n=1) / 2.706× (n=2 mean)、brush cross-eval PSNR +2.574dB。この値は §10 が用いた 2026-08-16 借用値基準 (2.466×/2.673×、+2.02〜2.73dB) とほぼ同水準 (差 1-2%) であり、非同日借用によるバイアスは実質的に無視できる大きさだったと確認された。卒論 §5 の direct comparison 表・Pareto v3 系列の headline gap は、より厳密な根拠を持つ本節の 2.497×(n=1)/2.706×(n=2 mean) を正式値として採用すべきである。native/self PSNR 断面では両者ほぼ互角 (msplat +0.005dB) という事実は、品質優位の主張が brush convention (本実装の学習 convention) に限定されるという p2-msplat-parity-lego §4 の結論を 30k iter 断面・真の同日条件下でも裏づける。

13. 静穏時再計測 — control config (s4b-12500-on) の byte-identical 複製を n=3 取り直し (2026-08-31)

手順 — 実装なし・計測のみ。control config を run 名だけ変えて複製し、load クリーンな状態で直列実行

§8/§9 は「finalv2/finalv3 (backend flag 無指定、default 経由) が paired control (backend flag に ssim_reduce = "gpu" を明示) より恒常的に +5.7% 遅い」件を、10分 cooldown (§8、解消せず) と explicit-flag config の単発 rerun (§9、125.19s、bfs 500-600%CPU の contamination 込みで断定不能) で切り分けようとしたが、いずれも決着していなかった。本節はもう一段厳密に、control config 自体 (2026-08-30-s4b-12500-on-r{1,2,3}.toml) を 1 バイトも変更せず ([experiment].name/description/[output].run_dir のみ変更、diff で [data]/[trainer]/[refine]/[adam]/[backend] が完全一致することを確認済み — splat/configs/2026-08-31-quiet-12500-r{1,2,3}.toml)、n=3 を 静穏条件を能動的に確認してから 直列実行する。事前チェック: df -h / 空き26GiB (閾値5GiB を大きく超過)、pmset -g batt series 前後とも AC Power (不変)、pgrep -fl "splat|msplat|mds_stores" は mds_stores (PID 885) のみ検出したが ps -p 885 -o pcpu で 0.0%CPU (アイドル) と確認できたため待機は不要と判断、series 開始時 load1=1.15 (<4)。splat/scripts/final-stack-n3.sh (LOAD_LIMIT=4.0 に明示指定、既存 default 6.0 より厳しい閾値) を configs/2026-08-31-quiet-12500 / quiet-12500 で起動し、各 run 前に load1<4.0 が 60 秒 (6 サンプル) 連続するまで能動 quiesce。加えて 10 秒間隔の ps aux | sort -nrk3 | head -3 サンプラーを script の load sampler と並行して独立に走らせ、各 run の pre_date/post_date epoch で window 切り出しし、同時実行プロセスの実体を記録した。binary sha256 c804b349223ffc68e9e1101d79c5ea9f058dfa8d34620504b66aa0a3eb10aa13・git rev f5b7a81987323a6f369b8d5da5da2b3621e3b8fa は series 前後・§8/§9 の rev 系統 (5c731cf/1565fcc) から splat/ crate に実コード変更なし (git log 1565fcc..HEAD -- splat/ は docs/config/log 系の 2 commit のみ) を確認済みで不変。判定は事前登録: mean が control ±1.5% バンド (120.93-124.61s、§8 で定義) 内 → drift 解消。mean が finalv2/finalv3 の ~129-130s 圏に達する → drift 継続 (session汚染起因の当初仮説が正しい可能性が高まる)。その中間 → straddle として mean±σ が両陣営のどちらと重なるか (または どちらとも重ならないか) を明示して報告し、第三の narrative を後付けしない。

runtrain elapsed (s)self-eval PSNR (dB)final splatsrun 中 load1 (min-max, 10s sampler)pre uptime (load 1/5/15m)post uptime (load 1/5/15m)
r1124.9136.171406,8502.12-2.853.03 3.03 3.951.95 2.70 3.69
r2127.2236.214407,9462.35-3.192.40 2.67 3.623.66 2.94 3.59
r3126.1336.192407,5532.47-3.032.86 2.99 3.542.99 2.95 3.43
**mean (n=3)****126.087** (σ1.156s, 0.917%)**36.192** (σ0.0594%)407,449.7 (σ0.136%)2.12-3.19 (系列全体、finalv2 r3 の 2.1-3.0 と同水準、finalv3 の 1.31-2.57 よりわずかに高いが LOAD_LIMIT=4.0 を終始下回る)——
3 run とも [backend] BackendConfig {...} ログで ssim_reduce: Gpu, radix_scatter: SimdBallot, refine_scratch_persist: true, refine_direct_write: true, refine_gpu_snapshot: false が完全一致することを確認 (§11 の「実効 flag は一致、flag 経路依存 bug ではない」を再確認)。self-eval PSNR は training log の mean val: PSNR (100 views)。σ は標本標準偏差 (n-1)。ps aux 独立サンプラーで各 run window を確認したところ、r1 の pre 直前に dj-lab (ユーザーの音声処理プロセス、§2 で既出) が PID 8971 で 22.8%CPU 検出されたがこの個体は r1 の post 時点では上位3位から消えており、その後 r2 開始直前 (2:13AM) に 別 PID (10175) の dj-lab が新規に起動し、r2/r3 の pre/post を通じて 33-40%CPU で稼働し続けた (WindowServer の系列全体を通じた baseline ~40-48%CPU は macOS の通常の compositor 負荷で、過去 finding の Finder 147%CPU/bfs 500-600%CPU のような突発的 contamination とは性質が異なる)。dj-lab の新規起動タイミングが r1 (124.91s、最速) と r2/r3 (127.22s/126.13s、やや遅い) の速度順位と符合する。
判定 — straddle: mean 126.09s は control バンドの外・finalv2/finalv3 圏の外の中間値。drift は「解消」でも「全量継続」でもなく縮小した形で継続

事前登録した 2 分岐 (control バンド 120.93-124.61s / finalv2-finalv3 圏 ~129-130s) のどちらにも該当しない。3 run 全てが control バンド上限 (124.61s) を超えている (r1 +1.75% / r2 +3.63% / r3 +2.74%、control 122.768s 比)。mean±σ = 124.93-127.24s — この区間は control バンド (120.93-124.61s) の直上に隙間 (0.32s) を空けて存在し、重ならない。finalv2 (130.657s) / finalv3 (129.750s) の側とも重ならない (最短距離は finalv3 との 2.51s = mean+σ からの差)。相対距離で見ると、mean (126.087s) は control (122.768s) から +2.70%、finalv2/finalv3 mean (130.204s) からは -3.16% — control 側にやや近いが、control バンド自体には入っていない。§9 の単発 rerun (125.19s、bfs contamination あり) とは +0.72% で近く、本 n=3 の結果はその単発値をおおむね裏づける形になった。結論: 静穏条件 (load1 終始2.1-3.2、LOAD_LIMIT=4.0 を維持、突発的 contamination なし) を確保してもなお、control config は元の paired gate 値 (122.77s) を再現できず、恒常的に +2.7% 程度遅い状態が続いている。一方で、backend flag 無指定の finalv2/finalv3 が示した +5.7〜6.5% ほど極端ではなく、ほぼ半分程度の drift 幅にとどまる。§9 で切り分けた「explicit flag config は default-flag config より drift 幅が小さい」というパターンは本節でも再現されており (explicit flag: 122.77→126.09s、+2.70%。default flag: 124.39(M7)→130.657(finalv2)、+5.05%)、『flag 経路依存』ではなく『環境の時間依存 drift が config 種別に関わらず存在し、その絶対量が session ごとに変動する』という §8/§11 の結論を補強する。今回新たに観測された dj-lab の断続的な起動/停止 (r1→r2 の間で新規プロセスが立ち上がった) は、load average だけでは捉えきれない低〜中負荷の同時実行プロセスが依然として drift の一因でありうることを示唆するが、その寄与度を本 n=3 だけで定量化することはできない。milestones.md の「現在地」は §2/§8/§9 の判断を変更せず、paired control 122.77s (S4b on-arm) を引き続き採用する — 本節は「静穏条件でも drift は完全には消えない」という追加の計測論的事実を記録するにとどめる。次の一手としては、§9 が提案した『explicit flag config』と『default flag config』の同一 session・同時間帯 back-to-back A/B に加え、dj-lab のような低負荷バックグラウンドプロセスの有無を意図的に制御した A/B が優先度が高い。

14. §6 (ficus/materials) の静穏再実行 — in-run load サンプラーで監視、ficus は PSNR 外れ値を q2 再実行で解消 (2026-08-31)

手順 — §6 の n=1 config を run 名のみ変えて複製し、10s 間隔の in-run load サンプラーで全区間を実況監視

§6 の ficus (349.63s)・materials (421.90s) の wallclock は post-run uptime で load 9.6-32.6 / 7-27 の汚染が確認され「方向感のみ」に格下げされていた。本節はゼミの多 scene 表用に静穏条件で取り直す。splat/runs/multiscene-{ficus,materials}-30k/config.toml (§6 で実際に使われた config の snapshot、元 config と diff でバイト一致を確認済み) を base に、[experiment].name/description/[output].run_dir のみ変更 ([data]/[trainer]/[refine]/[adam]/[backend] は無変更、diff で確認済み) した splat/configs/2026-08-31-multiscene-{ficus,materials}-30k-q.toml を splat check で validate。実行前チェック: df -h / 空き26-27GiB、pmset -g batt 系列前後とも AC Power、pgrep -fl "target/release/splat" 空、load1<4 が 60秒 (6サンプル×10s) 連続することを各 run 前に個別に確認 (ficus 前: 0.94-1.25、materials 前: 1.48-1.66)。完了検出は §6 の教訓 (pgrep -f の自己マッチで 10分 timeout を1回消費) を踏まえ、nohup sh -c '... ; echo $? > .DONE' の sentinel ファイルを foreground until loop でポーリングする方式に変更 (プロセス名マッチを一切使わない)。加えて §13 と同様の 10s 間隔 uptime+ps aux サンプラーを 2 run の実行区間全体にわたって独立に走らせ、各 run の起動/終了 epoch で window 切り出しして run 中の load1 推移を実況で 記録した (§6 は post-run uptime の単発値のみで in-run 推移は無かった)。2 run は直列実行 (ficus → 完了確認 → 60秒 quiesce 再確認 → materials)。binary sha256 c804b349223ffc68e9e1101d79c5ea9f058dfa8d34620504b66aa0a3eb10aa13・git rev 63266e409404dd7cdc9cd109b2a17944781f9ca1 は §6 (binary sha 同一値) 以降 splat/ crate に変更なし (docs コミットのみ) で不変。抽出は §6 と同じ 3 フィールド — training done in Xs (wallclock)、mean val: PSNR X dB (100 views)、final splats: X — をログから読み取り、result.toml [metrics] と一致することを確認した。ficus の 1 回目 (以下 q1) で PSNR が baseline から -1.4dB 台乖離する事象が生じたため、コードの RNG (StdRng::seed_from_u64(cfg.output.seed)、run 名/run_dir に非依存であることを grep で確認) を排除した上で、同一 config を -q2 として複製・再 quiesce・再実行した (追加の n=1、直列)。

scenebaseline PSNR (2026-05-25)初回 PSNR (§6、2026-08-31)静穏 run の PSNR (参考、variance観測)baseline wallclock初回 wallclock (§6、load汚染)静穏 wallclock (正式値)静穏 run 中 load1 (min-max)baseline splats静穏 splats
ficus (227k)34.28134.261q1 32.836 / q2 34.2791300s (21m40s)349.63s**254.09s (q1) / 256.21s (q2)**q1: 0.81-1.62 (終始クリーン)。q2: 0.94-4.79 (iter中盤に mds/cargo 由来の短時間スパイクあり、LOAD_LIMIT=4.0 を一時超過)226,749228,147 (q1) / 228,595 (q2)
materials (355k)30.02529.99829.9971846s (30m46s)421.90s**319.54s**1.18-2.07 (終始クリーン)349,784354,917
PSNR は load 汚染の影響を受けない量 (brush cross-eval が load 非依存であることは §1 で確認済み) なので、静穏再実行はそもそも PSNR の再計測を目的にしていない — 本 finding の PSNR 公式値は §6 のまま変更しない (ficus 34.261dB / materials 29.998dB)。静穏 run の PSNR (q1/q2) は「同一 config を複数回回すと何が起きるか」の run-to-run variance 観測として併記する。wallclock は §6 比 ficus **-27.3%〜-26.7%** (349.63s→254.09s/256.21s、q1/q2 で 0.8% 差と安定)、materials **-24.3%** (421.90s→319.54s) — in-run 10s サンプラーで全区間クリーンを実況確認できたため (q2 の一時的スパイクを除く)、この短縮は load 汚染除去の効果として §6 より高い確度で言える正式値である (n=1〜2 のため σ なし、baseline 側 [2026-05-25、旧 HEAD] も単発 run で条件不記載という留保は残る)。materials は §6・baseline・静穏の 3 run で PSNR range 0.028dB (30.025/29.998/29.997) と極めてタイト。ficus は同じ modern-stack config の 3 run (§6 34.261 / q1 32.836 / q2 34.279) で PSNR range **1.443dB** — a-10-variance-baseline が Lego 30k で報告した range 0.885dB (4 run) の 1.6 倍 — 詳細と、この range が退行判定の gate 閾値に与える影響は次の callout。
ficus PSNR range 1.443dB — 系統的な劣化ではなく GPU 非決定性の run-to-run variance、ただし a-10 の Lego gate 閾値をこの scene に適用するのは無効

静穏 config は diff で [data]/[trainer]/[refine]/[adam]/[backend] が §6 の config と完全一致 (name/description/run_dir のみ変更) しており、BackendConfig ログも一致するため config 起因ではないことは確認済み。コードの RNG は StdRng::seed_from_u64(cfg.output.seed) (config の seed フィールドのみに依存、splat-cli/src/cmd/train.rs) で、run 名や run_dir をハッシュに含む経路は grep で確認した限り存在しない — 「run_dir の違いが結果に影響した」という仮説は事前に排除した上で、同一 config を -q2 として再度 splat check validate・quiesce (60秒 load1<4) を経て再実行した。結果は 34.279dB (baseline 34.281dB 比 -0.002dB) で、q1 の -1.4dB 台とは全く異なり baseline/§6 と整合した。final splats も q1 228,147 / q2 228,595 と近く (0.2%差)、wallclock も q1 254.09s / q2 256.21s と近い (0.8%差) — 不安定だったのは PSNR のみで、wallclock・splats は 2 run で再現性がある。事前登録した 2 分岐のうち「~34.2 に着地」が的中したため、「ficus は GPU 非決定性に特に脆弱な scene である」という強い仮説 (機構の特定) は撤回する。q1 の -1.4dB 自体は a-10-variance-baseline が報告する SIMD backward の atomic_fetch_add 順序非決定性 (→ refine の split/clone 判定 flip → splat trajectory 分岐 → PSNR drift) の一事例である可能性が高い。ただし機構の特定とは別に、§6/q1/q2 の同一 modern-stack config・3 run で観測された range は 1.443dB (34.261/32.836/34.279) であり、これは a-10 が Lego 30k・4 run で確立した range 0.885dB の 1.6 倍 — materials の同条件 3 run range (0.028dB) とは対照的に、ficus では a-10 の σ±0.32dB / range 0.885dB を「退行判定の noise floor」としてそのまま転用するのは無効である。§6 の「3 scene とも ΔPSNR は σ±0.32dB の1/10以下」という記述、および §6 退行判定callout の「±0.1dB を超えたら scoped gate」という基準は、ficus に限っては n=1 の ΔPSNR -0.020dB がこの range (1.443dB) 内に埋もれる程度の情報量しか持たないことを意味する — M4/A7/S4b が PSNR-neutral な設計 (grad/param 更新を変えない) であるという §6 の結論そのものは変わらないが、「ficus の n=1 ΔPSNR が小さいことをもって退行なしと確度高く言える」という強さの主張はできない。本 finding では追加 run による σ の確定は行わない (観測された range を記録し、multi-scene gate 閾値の見直しが必要という指摘にとどめる)。

  • wallclock: §6 の「方向感のみ」を「静穏条件下で確度高く実測」に格上げできる — ficus 349.63s→254-256s (-27.3%〜-26.7%、q1/q2 で再現)、materials 421.90s→319.54s (-24.3%)、いずれも in-run load1 が LOAD_LIMIT=4.0 をほぼ終始下回った (ficus q1: 0.81-1.62 終始クリーン、q2: 0.94-4.79 で iter中盤に短時間スパイクあり、materials: 1.18-2.07 終始クリーン)
  • materials の PSNR/splats は §6・baseline と実質不変 (noise floor 内) — M4/A7/S4b の breakage screen 結論 (退行なし) を追加で裏づける
  • ficus の PSNR は §6/q1/q2 の同一 modern-stack config 3 run で range 1.443dB (34.261/32.836/34.279) を示した (materials の同条件 range 0.028dB とは対照的)。config/backend flag 同一・RNG が run 名や run_dir に依存しないことを確認済みなので config bug ではなく、a-10-variance-baseline の GPU 非決定性メカニズムの一事例と推測されるが range 超過分の機構は未確定。実用上の帰結は「ficus が特に脆弱」という機構特定ではなく、a-10 の Lego 由来の noise floor (σ±0.32dB) をこの scene の退行判定にそのまま転用できないという gate 閾値の限界の発見
  • 本節は commit していない (計測のみのタスク、config 3 本 [-q ficus/materials、-q2 ficus] と本 finding の追記のみ working tree に残る)
02

関連する run

この finding が観測された / 言及している実験 run。

03

関連 finding

© 2026 大竹律輝 — 松田研究室