[{"data":1,"prerenderedAt":385},["ShallowReactive",2],{"finding:p1-a-2-splat-eval-audit":3,"finding-runs:p1-a-2-splat-eval-audit":321,"finding-related:p1-a-2-splat-eval-audit":336},{"meta":4,"impact":30,"sections":35},{"id":5,"title":6,"subtitle":7,"eyebrow":8,"date":9,"status":10,"category":11,"polarity":12,"axes":13,"tags":16,"task_code":23,"related_runs":24,"related_findings":26},"p1-a-2-splat-eval-audit","P1.A.2 splat-rs eval audit — val split 100view・α 除外・rendered 黒背景の RGB-only PSNR","splat-rs trainer の eval (PSNR 計算) を定式化。PSNR は train.rs::compute_psnr の 1 箇所のみで、(a) transforms_val.json (100 view、test 200 view ではない)、(b) RGB only \u002F α 除外、(c) rendered は raw f32 (clamp なし)、(d) target は white-bg pre-composite、(e) rendered には bg 合成を行わず Σ α_i T_i c_i のみで終わる。training 側 loss は同じ 4ch (α 含む) を見るため、α=1-T が暗黙に white-bg collapse を引っ張る。brush 標準 (test split \u002F 加重 \u002F clamp \u002F α-mask) と複数の convention diff があり、P1.A.3 reproducer で 7 項目を順次切り分けて潜在的 −3〜−6 dB の apparent 部分を分離する。","P1 audit · splat-rs side · eval-only","2026-05-24","stable","audit","neutral",[14,15],1,3,[17,18,19,20,21,11,22],"phase-1","brush-parity","eval","psnr-formula","convention-diff","self-trainer","P1.A.2",[25],"lego-sh3-30k",[27,28,29],"brush-vs-splat-37dB-gap-analysis","c32-orig3dgs-bench","a-4-nerf-synthetic-scene-results",{"summary":31,"rank":32,"verdict":12,"delta_wallclock":33,"delta_psnr":34},"splat-rs trainer の eval は (1) val split 100 view・brush は test split 200 view、(2) PSNR は RGB のみ・α 除外、(3) rendered は raw f32 (clamp \u002F quantize なし)・brush 標準は u8 quant 後、(4) rendered は bg 合成なしで Σαi·Ti·ci のみ・target は white-bg pre-composite — の 4 つの diff 軸を持つ。training loss は 4ch (α 含む) で動くため、α 通り collapse が暗黙の white-bg 効果を作るが、convergence は不完全。P1.A.3 で 7 項目の切り分け reproducer を作り apparent gap (推定 −3〜−6 dB) を分離する。","high","N\u002FA (audit のみ)","N\u002FA (本タスクでは PSNR を変えない、audit 結果のみ提示)",[36,39,54,57,60,64,74,76,78,80,85,87,89,91,97,99,101,129,131,165,167,169,171,178,180,182,229,231,239,241,289,291,300,302,308,312,314],{"type":37,"text":38},"lead","splat-rs (自作 trainer) と brush (37.40 dB) の lego sh3 30k での \u003Cstrong>12.56 dB gap\u003C\u002Fstrong> の真因 audit のため、splat-rs 側 eval (PSNR 計算) の数式・dataset 範囲・前処理を file:line 単位で定式化する。並行で P1.A.1 が brush 側を audit 中、本 doc はそれと diff を取って P1.A.3 reproducer script で convention-diff 部分の apparent gap を分離するための入力データを提供する。",{"type":40,"items":41},"kv",[42,45,48,51],{"key":43,"value":44},"実施日","2026-05-24 P1 brush parity loop",{"key":46,"value":47},"audit 対象","splat-cli\u002Fsrc\u002Fcmd\u002Ftrain.rs::compute_psnr + 周辺 (eval pipeline 全体)",{"key":49,"value":50},"binary","main HEAD (lego sh3 30k で 24.879 dB を出す stamp)",{"key":52,"value":53},"確認 grep","PSNR\u002Feval 計算は train.rs L182 の 1 箇所のみ (render.rs \u002F check.rs \u002F splat-summary には別 PSNR 経路なし)",{"type":55,"text":56},"heading","1. PSNR の数式定式化",{"type":58,"text":59},"paragraph","splat-rs の PSNR は \u003Ccode>splat-cli\u002Fsrc\u002Fcmd\u002Ftrain.rs:182-200 fn compute_psnr\u003C\u002Fcode> で定義される唯一の経路。数式は以下のとおり:",{"type":61,"language":62,"text":63},"code","text","MSE = (1 \u002F (3·H·W)) · Σ_{p ∈ pixels} Σ_{c ∈ {R,G,B}} (rendered[p,c] − target[p,c])²\nPSNR = -10 · log10(MSE)        [α channel は和から除外、MAX = 1.0]\n\n  if MSE \u003C= 1e-12: return 100.0    # 飽和カットオフ\n\n入力:\n  rendered : Vec\u003Cf32> 長さ H·W·4  (chunks(4) で per-pixel RGBA、α 列 = 1 - T)\n  target   : Vec\u003Cf32> 長さ H·W·4  (chunks(4) で per-pixel RGBA、α 列 = 1.0 固定)\n\n実装: train.rs:187-194\n  for chunk in rendered.chunks(4).zip(target.chunks(4)):\n      for c in 0..3:           # ← α channel index 3 は除外\n          diff = (r[c] - t[c]) as f64\n          sum_sq += diff * diff\n          count  += 1\n  mse = sum_sq \u002F count          # count = pixels · 3\n",{"type":65,"items":66},"list",[67,68,69,70,71,72,73],"\u003Cstrong>MAX = 1.0\u003C\u002Fstrong> 固定 ([0,1] 線形 RGB 前提)、255 系ではない","\u003Cstrong>α 除外\u003C\u002Fstrong> (chunk[3] は MSE 和に入らない、target α = 1.0 固定)","\u003Cstrong>per-pixel 平均\u003C\u002Fstrong> (per-channel 平均ではない、Σ÷count で count = 3·H·W)","\u003Cstrong>clamp なし\u003C\u002Fstrong> (raw f32 をそのまま使う、shader comment が「\u003C 0 や > 1 を許可」と明記)","\u003Cstrong>quantize なし\u003C\u002Fstrong> (u8 化 → 戻し をしない、brush 標準は通常 u8 quant 後)","\u003Cstrong>per-view PSNR の mean\u003C\u002Fstrong> (mean-PSNR、PSNR-of-mean-MSE ではない、train.rs:147-149)","MSE ≤ 1e-12 で PSNR = 100 dB に飽和 (lossless 時の log10(0) 回避)",{"type":55,"text":75},"2. eval が見る画像 — rendered の作られ方",{"type":58,"text":77},"\u003Ccode>train.rs:130 trainer.forward_rgba(&param, cam, img_size)\u003C\u002Fcode> 経由で \u003Ccode>shaders\u002Fforward\u002Frasterize.metal::render_splats_f32\u003C\u002Fcode> が動く。compositing 数式は brush\u002Frasterize.wgsl と同一の volumetric front-to-back:",{"type":61,"language":62,"text":79},"per-pixel state: pix_out = float3(0.0)、T = 1.0\nper-splat:\n  sigma = 0.5·(conic_x·dx² + conic_z·dy²) + conic_y·dx·dy\n  alpha = min(0.999, color.a · exp(-sigma))\n  if alpha \u003C 1\u002F255: skip\n  next_T = T · (1 - alpha)\n  if next_T \u003C= 1e-4: break               # early termination (T 飽和)\n  pix_out += rgb · (alpha · T)\n  T = next_T\n\n最終出力 (rasterize.metal:215):\n  out[idx] = float4(pix_out,  1.0 - T)   # α channel = foreground occupancy\n",{"type":81,"label":82,"variant":83,"text":84},"callout","重要","warning","\u003Cstrong>rendered には background color が合成されていない\u003C\u002Fstrong>。RGB は単に \u003Ccode>Σ α_i T_i c_i\u003C\u002Fcode> で終わり、T が残る部分 (背景 pixel) の RGB は \u003Ccode>(0, 0, 0)\u003C\u002Fcode> のまま。一方 target は \u003Ccode>load_rgba_white_bg\u003C\u002Fcode> で \u003Cstrong>白背景 pre-composite\u003C\u002Fstrong> される (PNG 4ch RGBA から \u003Ccode>rgb·α + (1-α)·1.0\u003C\u002Fcode>)。よって training は「splat 自身が白を学ぶ」前提に依存しており、α channel (1-T = target=1.0) を loss に含めることで暗黙の white-bg collapse を強制する。完全 convergence できない場合、background 領域での MSE が大きく残り、apparent PSNR を下げる。",{"type":55,"text":86},"3. eval が見る画像 — target の作られ方",{"type":58,"text":88},"\u003Ccode>splat-io\u002Fsrc\u002Fdataset.rs:140-166 fn load_rgba_white_bg\u003C\u002Fcode>:",{"type":61,"language":62,"text":90},"for px in PNG.pixels():                    # 8-bit RGBA を [0,1] 正規化\n    r, g, b, a = px \u002F 255.0\n    # 白背景 α blend: 真の white-bg composite\n    rgb_out = rgb · α + (1 - α) · 1\n    α_out   = 1.0                          # 出力 α は常に 1 (mask 情報は捨てる)\n\ntarget は H·W·4 RGBA、値域 [0, 1]、α channel = 1.0 固定。\n",{"type":65,"items":92},[93,94,95,96],"前景の α-mask 情報は \u003Cstrong>捨てられる\u003C\u002Fstrong> (α_out = 1.0 hardcode、L163)","つまり brush の \u003Ccode>image *= alpha_mask\u003C\u002Fcode> 風 eval (前景のみ評価) は構造的に不可能","linear RGB \u002F sRGB 区別なし (PNG を単純に 255 で割る、gamma curve 補正なし)","tonemap なし、HDR clip なし",{"type":55,"text":98},"4. dataset split — どの json を eval に使うか",{"type":58,"text":100},"\u003Ccode>train.rs:115 val_path = cfg.data.dataset_path.join(\"transforms_val.json\")\u003C\u002Fcode>。\u003Cstrong>val split (100 view)\u003C\u002Fstrong> を eval に使用。NeRF Synthetic は train\u002Fval\u002Ftest = 100\u002F100\u002F200 の 3 split。\u003Cstrong>brush と original 3DGS は test split (200 view) で報告\u003C\u002Fstrong>するのが標準。これは apples-to-oranges の最大候補で、camera 分布が異なるため絶対 PSNR が違う。",{"type":102,"columns":103,"align":108,"rows":110},"table",[104,105,106,107],"項目","splat-rs (本実装)","brush \u002F orig 3DGS 標準","影響",[109,109,109,109],"left",[111,116,121,125],[112,113,114,115],"split file","transforms_val.json","transforms_test.json","camera 分布差",[117,118,119,120],"view 数","100","200","mean のばらつき",[122,123,124,12],"eval 順序","全 view 順 iterate (skip なし)","通常全 view、論文 figure は subset",[126,127,127,128],"per-view weight","等加重 mean","同等",{"type":55,"text":130},"5. 画像前処理 (eval 時) — diff の温床",{"type":102,"columns":132,"align":136,"rows":138},[104,133,134,135],"splat-rs","brush 標準 (推測、P1.A.1 で確定)","推定 diff 寄与",[109,109,109,137],"right",[139,144,149,153,156,160],[140,141,142,143],"値域","f32 raw (clamp なし)","u8 quantize 後または clamp 済み","+1 dB 程度?",[145,146,147,148],"α channel","MSE 和に含めない (RGB only)","通常 RGB only、α-mask 適用ありの場合あり","convention",[150,151,152,12],"sRGB↔linear","なし (両方 raw linear)","なし (両方 raw linear) と思われる",[154,155,155,12],"tonemap","なし",[157,155,158,159],"α-mask 適用","image *= alpha_mask が brush eval にある (gap doc §6)","−1〜−3 dB?",[161,162,163,164],"bg composite","rendered には未合成 (黒)、target は white 合成済み","通常 rendered にも同 bg を合成して MSE 計算","training の暗黙吸収次第",{"type":55,"text":166},"6. training loss との関係 (内部 consistency)",{"type":58,"text":168},"Training loss は \u003Ccode>shaders\u002Floss\u002Floss.metal::loss_l1_only\u003C\u002Fcode> および \u003Ccode>loss_l1_combine_ssim\u003C\u002Fcode>。重要点は \u003Cstrong>n_total = W·H·4\u003C\u002Fstrong> で \u003Cstrong>α channel を含めて\u003C\u002Fstrong> L1 loss を取ること:",{"type":61,"language":62,"text":170},"loss_metal::n_total = W · H · 4         # ← 4 channel すべて\ndldr[gid] = sign(r - t) \u002F n_total       # all 4 channels\nloss_sum = Σ |r[gid] - t[gid]|          # all 4 channels\n",{"type":65,"items":172},[173,174,175,176,177],"\u003Cstrong>training は α channel を loss に含める\u003C\u002Fstrong>。target α=1.0 vs rendered α=1-T で diff |T| が常に loss に効く","結果として、splat 群は背景 pixel で T → 0 (= 完全 occupancy) になるように pressure を受ける","rendered.rgb が黒のまま T → 0 になると \u003Ccode>pix_out = Σ α_i T_i c_i → 1\u003C\u002Fcode> (白) になる学習が暗黙に進行 — つまり background 領域は「白の splat を生やす」方向に学ぶ","ただし完全 convergence には至らないため、background 領域での MSE は完全には消えない (eval 時に apparent gap として現れる)","eval は RGB のみ (α 除外)、training は α 含む — \u003Cstrong>内部 inconsistency\u003C\u002Fstrong>",{"type":55,"text":179},"7. brush との diff 候補 (P1.A.3 reproducer 設計用)",{"type":58,"text":181},"P1.A.3 で「同じ trained ply \u002F camera から、convention を 1 つずつ揃えていって brush に近づける」reproducer を組むときに切り分けるべき軸を、潜在 impact 順 (確信度高い順) に列挙する:",{"type":102,"columns":183,"align":189,"rows":190},[184,185,186,187,188],"#","convention 軸","splat-rs 現状","brush 想定","推定 impact",[137,109,109,109,137],[191,196,202,206,212,218,224],[192,112,193,194,195],"D1","transforms_val.json (100view)","transforms_test.json (200view)","absolute 差 ±1〜2 dB",[197,198,199,200,201],"D2","rendered の bg","未合成 (T 残り部分 RGB=0)","white-bg 合成 (rendered.rgb += T·1)","−2〜−4 dB? (training 不完全分)",[203,157,155,204,205],"D3","image *= alpha_mask (gap doc 推定)","−1〜−3 dB",[207,208,209,210,211],"D4","rendered clamp","raw f32 (負値・>1 もそのまま)","u8 quant or [0,1] clamp","+0.5〜1 dB",[213,214,215,216,217],"D5","PSNR formula","RGB only、MAX=1、per-pixel mean、view mean","同等と推測 (要 P1.A.1 確認)","neutral か ±0.3 dB",[219,220,221,222,223],"D6","α channel in MSE","除外","通常除外、ただし α-mask path で実質含まれる","D3 と相関",[225,226,227,228,12],"D7","lossless saturation","MSE≤1e-12 で 100 dB clamp","実装依存",{"type":55,"text":230},"8. 現状 splat-rs eval が brush 準拠でない可能性が高い箇所 (疑い順)",{"type":65,"items":232},[233,234,235,236,237,238],"\u003Cstrong>(最強疑い) D1: val vs test split\u003C\u002Fstrong> — train.rs:115 が \u003Ccode>transforms_val.json\u003C\u002Fcode> を hardcode、brush は \u003Ccode>transforms_test.json\u003C\u002Fcode>。100 view ≠ 200 view で camera 分布も違うため、apples-to-oranges。これだけで absolute PSNR の起点が違う可能性。","\u003Cstrong>(強い疑い) D2: rendered に bg を合成していない\u003C\u002Fstrong> — rasterize.metal:215 が \u003Ccode>float4(pix_out, 1-T)\u003C\u002Fcode> で終わる。brush では rendered 側も同じ white-bg composite を行う実装が多い (training\u002Feval の対称性を保つため)。training の不完全 convergence 分が background 残差として eval MSE を膨らませる可能性。","\u003Cstrong>(中程度) D3: α-mask 適用なし\u003C\u002Fstrong> — splat-rs eval は前景マスクなし、brush は \u003Ccode>image *= alpha_mask\u003C\u002Fcode> で前景のみ eval する path を持つ (gap doc 推定)。前景のみで PSNR を取ると背景の MSE 不一致がキャンセルされ +3 dB 級の上振れがあり得る。","\u003Cstrong>(弱い疑い) D4: clamp \u002F quantize 欠如\u003C\u002Fstrong> — render_splats_f32 の comment に「\u003C 0 や > 1 を許可 (debug 用)」とある。eval で raw f32 を MSE に入れると overshoot が二乗で増幅される。brush 標準は通常 u8 quant 後の MSE。","\u003Cstrong>(neutral) D5: PSNR formula 自体\u003C\u002Fstrong> — RGB only \u002F MAX=1 \u002F per-pixel mean \u002F view mean — orig 3DGS 標準と同じはず、ただし P1.A.1 で brush 側数式を確認するまでは 100% 同等とは断定不可。","\u003Cstrong>(構造的) D6 training-eval inconsistency\u003C\u002Fstrong> — training loss は α 含む 4ch、eval は RGB のみ。training は「α=1.0 にせよ」と loss を流すが eval は α を見ない。α channel に費やされる gradient 分が RGB 改善のための gradient と competing し、convergence を遅らせる可能性 (gap への寄与は二次的、しかし潜在的)。",{"type":55,"text":240},"9. P1.A.3 reproducer に持ち込むべき file:line",{"type":102,"columns":242,"align":247,"rows":248},[243,244,245,246],"役割","file","line","備考",[109,109,137,109],[249,254,258,261,266,271,276,280,284],[250,251,252,253],"PSNR 関数本体","splat\u002Fcrates\u002Fsplat-cli\u002Fsrc\u002Fcmd\u002Ftrain.rs","182-200","compute_psnr (-10·log10(MSE))",[255,251,256,257],"eval driver","112-151","val_ds.views を iterate",[259,251,260,113],"split hardcode","115",[262,263,264,265],"forward (rasterize)","splat\u002Fcrates\u002Fsplat-train-v1\u002Fsrc\u002Ftrainer.rs","97-104","forward_rgba",[267,268,269,270],"rasterize shader","splat\u002Fshaders\u002Fforward\u002Frasterize.metal","140-218","render_splats_f32 (bg 合成なし)",[272,273,274,275],"target loader","splat\u002Fcrates\u002Fsplat-io\u002Fsrc\u002Fdataset.rs","140-166","load_rgba_white_bg (target に bg 合成)",[277,273,278,279],"dataset split file","32-71","load_nerf_synthetic",[281,251,282,283],"PNG dump (debug)","293-318","save_rgba_png (eval には影響しない、参考)",[285,286,287,288],"training loss (α 含む)","splat\u002Fshaders\u002Floss\u002Floss.metal","31-88","loss_l1_only \u002F loss_l1_combine_ssim、n_total = W·H·4",{"type":55,"text":290},"10. 不明点 (P1.A.1 brush 側 audit 結果との突合で確定)",{"type":65,"items":292},[293,294,295,296,297,298,299],"brush の test split file 名・view 数の確認 (transforms_test.json で 200 view?)","brush の rendered output が background 合成済みか否か (training loss \u002F eval 共通で同じ canvas を使うか)","brush eval が clamp \u002F u8 quant を入れるか (raw f32 MSE か u8 MSE か)","brush eval が α-mask gating を本当にやっているか (gap doc は「推定」止まり、ソース確認必要)","brush の PSNR formula が MAX=1 か MAX=255 か (前者なら同じ、後者なら +48 dB の系統差で gap が逆向きに反転する罠)","brush は per-view mean か per-view MSE → 全体 MSE → 1 回 PSNR か (前者と後者で値が違う、splat-rs は前者)","brush eval が sRGB → linear に変換するか (target \u002F rendered 両方 linear なら不問)",{"type":55,"text":301},"11. P1.A.3 reproducer に必要な最小資材リスト",{"type":65,"items":303},[304,305,306,307],"\u003Cstrong>同一 trained ply\u003C\u002Fstrong> (splat-rs lego sh3 30k final.ply、必要に応じて brush 30k final も)","\u003Cstrong>NeRF Synthetic lego dataset\u003C\u002Fstrong> の transforms_val.json と transforms_test.json (両方欠かさず)","\u003Cstrong>切り分け 7 軸を ON\u002FOFF できる小さい python or rust script\u003C\u002Fstrong> (PIL\u002Fnumpy で十分): (i) bg composite render side、(ii) clamp [0,1]、(iii) u8 quant、(iv) α-mask 適用、(v) split 切替、(vi) MAX=1 vs 255、(vii) per-view mean vs aggregate MSE","\u003Cstrong>brush 側 eval を C 経由で叩く方法\u003C\u002Fstrong> または brush の rendered output を PNG dump して同じ script に流す方法 (どちらかでも diff 切り分け可能)",{"type":81,"label":309,"variant":310,"text":311},"次アクション (P1.A.3 へ申し送り)","info","本 audit で「splat-rs 側の eval 全体像」は \u003Cstrong>file:line で完全に確定\u003C\u002Fstrong>。残る不確実性は brush 側 eval の挙動 (D1〜D7 の対応関係) であり、P1.A.1 finding doc とこの doc を並べて読めば reproducer の最小実装は (i) 同一 ply で同 camera を render し、(ii) 上記 7 軸を変えながら PSNR を計測する 1 つの python script で済む。expected outcome: 12.56 dB gap のうち \u003Cstrong>−3〜−6 dB が convention diff (apparent)\u003C\u002Fstrong>、残り \u003Cstrong>−6〜−9 dB が真の trainer 品質差\u003C\u002Fstrong> という仕分けが付くこと。",{"type":55,"text":313},"関連",{"type":65,"items":315},[316,317,318,319,320],"P1.A.1 brush eval audit (並走中、本 doc と diff する): 起草中","P1.A.3 reproducer script (本 doc + P1.A.1 を入力): 未着手","brush vs splat 37 dB gap 既存分析: \u003Ccode>brush-vs-splat-37dB-gap-analysis\u003C\u002Fcode>","c32 orig 3DGS eval convention 注意点: \u003Ccode>c32-orig3dgs-bench\u003C\u002Fcode>","lego sh3 30k 自作 trainer 24.879 dB の root run: \u003Ccode>a-4-nerf-synthetic-scene-results\u003C\u002Fcode>",[322],{"id":25,"title":25,"subtitle":323,"date":324,"workspace":325,"tags":326,"verdict":331,"psnr":332,"psnr_unit":-1,"wallclock":333,"splats":334,"summary_url":335,"detail_path":335},"A.8 SH degree ablation — sh_degree=3 (DC only, no view-dependence)","2026-05-22","splat",[327,328,329,330],"sh-ablation","lego-30k","sh-3","phase-5","partial",24.87872886657715,"23m 13s",83734,"\u002Fruns\u002Flego-sh3-30k\u002F",[337,362],{"id":29,"title":338,"date":9,"status":10,"polarity":339,"category":340,"axes":341,"tags":342,"task_code":349,"related_runs":350,"delta_psnr":358,"delta_wallclock":359,"rank":32,"verdict":331,"impact_summary":360,"detail_path":361},"A.4 NeRF Synthetic 他シーン展開 — 8 シーン complete 30k 結果","mixed","experiment",[14],[330,343,344,345,346,347,348],"nerf-synthetic","multi-scene","psnr","scene-dependency","evaluation","8-scenes","A.4",[25,351,352,353,354,355,356,357],"chair-30k","ficus-30k","drums-30k","hotdog-30k","mic-30k","materials-30k","ship-30k","-5.93 dB (8 シーン平均 18.95 vs lego 24.879、std ±6.0)","21-29 min (シーン非依存的、materials のみ +5 min)","8 シーン complete (lego + 7 新規) 30k 完遂。シーン依存性が PSNR で 17.6 dB の幅 (materials 12.71 〜 hotdog 30.29)、mean 18.95 ± 6.0 dB。本実装の brush SoTA 比 gap は scene-dependent で -7.4 dB (hotdog) 〜 -22.3 dB (ficus 含む)。共通要因仮説: SfM init.ply の sparsity (細い枝 \u002F マイク \u002F 反射 PBR で薄い) + refine grad_threshold の lego\u002Fhotdog tuning over-fit。卒論 evaluation で「lego baseline + multi-scene mean ± std」併記必須。","\u002Ffindings\u002Fa-4-nerf-synthetic-scene-results\u002F",{"id":28,"title":363,"date":364,"status":10,"polarity":339,"category":340,"axes":365,"tags":367,"task_code":376,"related_runs":377,"delta_psnr":380,"delta_wallclock":381,"rank":32,"verdict":382,"impact_summary":383,"detail_path":384},"c32 V100 原著 3DGS 30k bench — A.5 三層対比表の最終 row & eval convention 乖離 finding","2026-05-23",[366],2,[368,369,370,371,372,373,374,375],"phase-2","original-3dgs","v100","c32","cuda","bench","eval-convention","abstraction-cost","A.3",[378,379],"orig3dgs-lego-1k-smoke","orig3dgs-lego-30k",28.384,"10m37s","investigative","原著 3DGS を V100 で 30k 学習 (PSNR 28.38 dB \u002F 10m37s \u002F 237k splats)。同 V100・同 30k で brush (wgpu→Vulkan) 8m24s \u002F 37.46 dB を上回れず、抽象コスト ≪ 実装最適化レベル を CUDA 機でも再確認。さらに codebase eval と paper-standard eval で 12 dB 乖離 (28.4 vs 14.6) を発見、A.5 表は eval convention 注記必須。","\u002Ffindings\u002Fc32-orig3dgs-bench\u002F",1782449788629]