فهرست منبع

4x r39 perf: warm re-baseline via perf-only reruns (cold d0 c1 1772 -> 2018-2103), spec numbers corrected

Alexander Korolev 1 ماه پیش
والد
کامیت
c2e6c33d79

+ 34 - 0
recipes/glm53-flash-nvfp4-lab-4x-r39/reports/2026-09-22_075441_r39-4x-v270-perfrerun.log

@@ -0,0 +1,34 @@
+^D{"event": "backend_detected", "backend": "vllm"}
+
+╭──────────────────── ⚡ llama-benchy Throughput Benchmark ────────────────────╮
+│ glm53                                                                        │
+│ pp=[2048]  tg=[128]  depth=[0, 4096, 8192]  concurrency=[1, 2]  runs=3       │
+│ latency=generation                                                           │
+╰──────────────────────────────────────────────────────────────────────────────╯
+
+  ✓ Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 18/18 0:01:48
+
+  llama-benchy 0.4.0
+  Estimated latency: 28.8 ms
+
+                               llama-benchy Results                             
+┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━
+┃                      ┃    ┃         ┃         ┃     TTFT ┃    Total ┃         
+┃ Test                 ┃ c  ┃  pp t/s ┃  tg t/s ┃     (ms) ┃     (ms) ┃   Tokens
+┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━
+│ pp2048 tg128 @ d0    │ c1 │   2,018 │    58.6 │      951 │    3,106 │ 2048+128
+│ pp2048 tg128 @ d0    │ c2 │   2,149 │    69.2 │    1,286 │    4,414 │ 2048+128
+│ pp2048 tg128 @ d4096 │ c1 │   2,498 │    59.4 │    2,231 │    4,358 │ 2048+128
+│ pp2048 tg128 @ d4096 │ c2 │   2,468 │    67.4 │    4,049 │    7,249 │ 2048+128
+│ pp2048 tg128 @ d8192 │ c1 │   2,515 │    58.7 │    3,600 │    5,754 │ 2048+128
+│ pp2048 tg128 @ d8192 │ c2 │   2,489 │    51.4 │    6,593 │   10,253 │ 2048+128
+└──────────────────────┴────┴─────────┴─────────┴──────────┴──────────┴─────────
+
+  ℹ Metrics sourced from llama-benchy — see https://github.com/eugr/llama-benchy
+for methodology.
+
+
+  Report saved to 
+/Users/kilork/.cache/sm121/bench/2026-09-22_075441_r39-4x-v270-perfrerun/runs/20
+26/09/2026-09-22T07-56-30.349354Z_feffd52f.md
+

+ 45 - 0
recipes/glm53-flash-nvfp4-lab-4x-r39/reports/2026-09-22_075441_r39-4x-v270-perfrerun.md

@@ -0,0 +1,45 @@
+# Throughput Benchmark — glm53
+
+- **Run ID**: `2026-09-22T07-56-30.349354Z_feffd52f`
+- **Date**: `2026-09-22T07:56:30.349678+00:00`
+- **Mode**: throughput-only
+- **tool-eval-bench**: `v2.7.0`
+
+## Run Context
+
+| Parameter | Value |
+|---|---|
+| Backend | vllm |
+| Server | `http://***:30000/v1` |
+| Model (API) | `glm53` |
+| Model (Root) | `local-inference-lab/GLM-5.3-Flash-NVFP4` |
+| Temperature | 0.0 |
+| Seed | 42 |
+| Max Turns | 8 |
+| Timeout | 120.0s |
+| Scenarios | all (88) |
+| Parallel | 1 (sequential) |
+| Error Rate | 0.0 |
+| Thinking | enabled |
+| Max Tokens | 16384 |
+
+## Inference Engine
+
+| Property | Value |
+|---|---|
+| Engine | vLLM 0.26.1rc0+glm53.r39.vllm9e5d1793 |
+| Max Model Length | 524,288 |
+| Host | `localhost` |
+| Platform | `macOS-26.6.2-arm64-arm-64bit-Mach-O` |
+| Python | 3.14.7 |
+
+## Results
+
+| Test | pp t/s | tg t/s | TTFT (ms) | Total (ms) | Tokens |
+|---|---:|---:|---:|---:|---:|
+| pp2048 tg128 @ d0 | 2,018 | 58.6 | 951 | 3,106 | 2048+128 |
+| pp2048 tg128 @ d0 c2 | 2,149 | 69.2 | 1,286 | 4,414 | 2048+128 |
+| pp2048 tg128 @ d4096 | 2,498 | 59.4 | 2,231 | 4,358 | 2048+128 |
+| pp2048 tg128 @ d4096 c2 | 2,468 | 67.4 | 4,049 | 7,249 | 2048+128 |
+| pp2048 tg128 @ d8192 | 2,515 | 58.7 | 3,600 | 5,754 | 2048+128 |
+| pp2048 tg128 @ d8192 c2 | 2,489 | 51.4 | 6,593 | 10,253 | 2048+128 |

+ 34 - 0
recipes/glm53-flash-nvfp4-lab-4x-r39/reports/2026-09-22_075936_r39-4x-v270-perfrerun2.log

@@ -0,0 +1,34 @@
+^D{"event": "backend_detected", "backend": "vllm"}
+
+╭──────────────────── ⚡ llama-benchy Throughput Benchmark ────────────────────╮
+│ glm53                                                                        │
+│ pp=[2048]  tg=[128]  depth=[0, 4096, 8192]  concurrency=[1, 2]  runs=3       │
+│ latency=generation                                                           │
+╰──────────────────────────────────────────────────────────────────────────────╯
+
+  ✓ Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 18/18 0:01:47
+
+  llama-benchy 0.4.0
+  Estimated latency: 48.0 ms
+
+                               llama-benchy Results                             
+┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━
+┃                      ┃    ┃         ┃         ┃     TTFT ┃    Total ┃         
+┃ Test                 ┃ c  ┃  pp t/s ┃  tg t/s ┃     (ms) ┃     (ms) ┃   Tokens
+┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━
+│ pp2048 tg128 @ d0    │ c1 │   2,103 │    61.5 │      900 │    2,933 │ 2048+128
+│ pp2048 tg128 @ d0    │ c2 │   2,157 │    64.9 │    1,279 │    4,557 │ 2048+128
+│ pp2048 tg128 @ d4096 │ c1 │   2,502 │    53.5 │    2,266 │    4,609 │ 2048+128
+│ pp2048 tg128 @ d4096 │ c2 │   2,410 │    67.0 │    4,135 │    7,314 │ 2048+128
+│ pp2048 tg128 @ d8192 │ c1 │   2,570 │    54.0 │    3,546 │    5,868 │ 2048+128
+│ pp2048 tg128 @ d8192 │ c2 │   2,504 │    60.2 │    6,540 │    9,709 │ 2048+128
+└──────────────────────┴────┴─────────┴─────────┴──────────┴──────────┴─────────
+
+  ℹ Metrics sourced from llama-benchy — see https://github.com/eugr/llama-benchy
+for methodology.
+
+
+  Report saved to 
+/Users/kilork/.cache/sm121/bench/2026-09-22_075936_r39-4x-v270-perfrerun2/runs/2
+026/09/2026-09-22T08-01-24.526186Z_55a62203.md
+

+ 45 - 0
recipes/glm53-flash-nvfp4-lab-4x-r39/reports/2026-09-22_075936_r39-4x-v270-perfrerun2.md

@@ -0,0 +1,45 @@
+# Throughput Benchmark — glm53
+
+- **Run ID**: `2026-09-22T08-01-24.526186Z_55a62203`
+- **Date**: `2026-09-22T08:01:24.526501+00:00`
+- **Mode**: throughput-only
+- **tool-eval-bench**: `v2.7.0`
+
+## Run Context
+
+| Parameter | Value |
+|---|---|
+| Backend | vllm |
+| Server | `http://***:30000/v1` |
+| Model (API) | `glm53` |
+| Model (Root) | `local-inference-lab/GLM-5.3-Flash-NVFP4` |
+| Temperature | 0.0 |
+| Seed | 42 |
+| Max Turns | 8 |
+| Timeout | 120.0s |
+| Scenarios | all (88) |
+| Parallel | 1 (sequential) |
+| Error Rate | 0.0 |
+| Thinking | enabled |
+| Max Tokens | 16384 |
+
+## Inference Engine
+
+| Property | Value |
+|---|---|
+| Engine | vLLM 0.26.1rc0+glm53.r39.vllm9e5d1793 |
+| Max Model Length | 524,288 |
+| Host | `localhost` |
+| Platform | `macOS-26.6.2-arm64-arm-64bit-Mach-O` |
+| Python | 3.14.7 |
+
+## Results
+
+| Test | pp t/s | tg t/s | TTFT (ms) | Total (ms) | Tokens |
+|---|---:|---:|---:|---:|---:|
+| pp2048 tg128 @ d0 | 2,103 | 61.5 | 900 | 2,933 | 2048+128 |
+| pp2048 tg128 @ d0 c2 | 2,157 | 64.9 | 1,279 | 4,557 | 2048+128 |
+| pp2048 tg128 @ d4096 | 2,502 | 53.5 | 2,266 | 4,609 | 2048+128 |
+| pp2048 tg128 @ d4096 c2 | 2,410 | 67.0 | 4,135 | 7,314 | 2048+128 |
+| pp2048 tg128 @ d8192 | 2,570 | 54.0 | 3,546 | 5,868 | 2048+128 |
+| pp2048 tg128 @ d8192 c2 | 2,504 | 60.2 | 6,540 | 9,709 | 2048+128 |

+ 12 - 4
specs/tech-architecture/glm53-recipe-state.md

@@ -1409,10 +1409,18 @@ was never measurable on r38); consider cutting the GLM-5.3 prod to r39
 - **Bench (v2.7.0, seed 42, hardmode, c1,2): 164/176 (93%)** — same as the
   r39 2x; failures TC-43/68/80 (the 2x set was TC-43/49/51/68; TC-43+68
   overlap = model ceiling, the rest is run noise).
-- **Perf vs r39 2x (pp2048/tg128 micro):** prefill d0 c1 1,772 vs 1,158
-  (+53%), d4096 c2 2,395 vs ~1,427; long decode d4096 c2 tg 4,111 vs ~2,104
-  (≈2×). 4x wins the perf game as expected (prefill compute-bound, decode
-  bandwidth-bound — both scale with the extra ranks).
+- **Perf vs r39 2x (pp2048/tg128 micro, WARM — the first campaign row d0 c1
+  1,772 was cold; two perf-only reruns (07:54/07:59) converge at 2,018–2,103,
+  `--perf-only` added to `sm121 bench` for exactly this):** d0 c1 2,103 vs
+  1,158 (+82%), d4096 c2 2,410 vs ~1,427; long decode d4096 c2 tg 4,135 vs
+  ~2,104 (≈2×), d8192 c2 tg 6,540. 4x wins the perf game as expected
+  (prefill compute-bound, decode bandwidth-bound — both scale with the extra
+  ranks).
+
+Perf-only rerun convention: the first perf row of a campaign can be cold
+(JIT/graph state after the scenario phase); re-baseline with
+`sm121 bench ... --perf-only` (skips scenarios, no run package — the
+campaign run stays the provenance record).
 
 **Verdict: r39 tip is the first engine generation that is simultaneously
 (1) deadlock-free on GB10 (2x and 4x), (2) quality-at-parity with the r35

+ 39 - 26
src/bench.rs

@@ -275,37 +275,50 @@ pub async fn run(config: &Config, a: &Args, dry_run: bool) -> Result<()> {
     fs::copy(&md_src, &md_dest)?;
 
     // Summary: final score from the JSON + the perf table from the log.
-    let j: serde_json::Value = serde_json::from_str(&fs::read_to_string(&json_path)?)?;
-    let sc = &j["scores"];
-    let final_score = sc["final_score"].as_u64();
-    if let Some(score) = final_score {
-        let completion = sc["completion_rate"]
-            .as_f64()
-            .map(|v| v.to_string())
-            .unwrap_or_default();
-        eprintln!(
-            "bench: final score {score} / {} ({} points), completion {completion}",
-            sc["max_points"], sc["total_points"]
-        );
-    } else {
-        eprintln!("bench: perf-only run (no quality score)");
-    }
+    // Perf-only runs have no quality score and the tool writes no JSON —
+    // the run package is skipped for them (the campaign run is the record).
+    let j = match a.perf_only {
+        true => {
+            eprintln!("bench: perf-only run (no quality score, no run package)");
+            None
+        }
+        false => {
+            let j: serde_json::Value = serde_json::from_str(&fs::read_to_string(&json_path)?)?;
+            let sc = &j["scores"];
+            let final_score = sc["final_score"].as_u64();
+            if let Some(score) = final_score {
+                let completion = sc["completion_rate"]
+                    .as_f64()
+                    .map(|v| v.to_string())
+                    .unwrap_or_default();
+                eprintln!(
+                    "bench: final score {score} / {} ({} points), completion {completion}",
+                    sc["max_points"], sc["total_points"]
+                );
+            } else {
+                eprintln!("bench: perf-only run (no quality score)");
+            }
+            Some(j)
+        }
+    };
     for line in fs::read_to_string(&log_path)?.lines() {
         if line.contains("pp2048") && line.contains("tg128") {
             println!("{line}");
         }
     }
-    crate::bench_artifacts::write_run_package(&crate::bench_artifacts::RunPackage {
-        config,
-        cluster: &cluster,
-        recipe: &recipe,
-        recipe_file: &file,
-        stem: stem.as_str(),
-        reports_dir: &reports_dir,
-        bench_args: &args,
-        bench_json: &j,
-    })
-    .await?;
+    if let Some(j) = &j {
+        crate::bench_artifacts::write_run_package(&crate::bench_artifacts::RunPackage {
+            config,
+            cluster: &cluster,
+            recipe: &recipe,
+            recipe_file: &file,
+            stem: stem.as_str(),
+            reports_dir: &reports_dir,
+            bench_args: &args,
+            bench_json: j,
+        })
+        .await?;
+    }
     eprintln!("bench: reports landed in {}", reports_dir.display());
     Ok(())
 }