Repository navigation
Expand file tree
/
Copy pathrender-bench-table.py
More file actions
1071 lines (882 loc) · 37.5 KB
/
Copy pathrender-bench-table.py
File metadata and controls
1071 lines (882 loc) · 37.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env python3
"""Regenerate the "Models tested on AINode" table in README.md from bench/results/*.json.
Those numbers appear in prose in two repos (this README and the tested-models guide on
docs.ainode.dev), so the table is generated rather than typed. Add a result file, run
this, commit both:
python3 scripts/render-bench-table.py # rewrite README.md in place
python3 scripts/render-bench-table.py --print # emit the table, touch nothing
python3 scripts/render-bench-table.py --check # exit 1 if README.md is stale
Any file carrying the two markers can be the target, which is how the same table
lands in the tested-models guide on docs.ainode.dev (MDX needs JSX comments, not
HTML ones):
python3 scripts/render-bench-table.py \
--readme ../ainode-docs/guides/tested-models.mdx \
--begin '{/* BEGIN bench-table */}' --end '{/* END bench-table */}'
Nothing is computed or extrapolated. A measurement that is missing from the JSON
renders as "not measured" and a run with no rubric renders as "not run"; neither
ever becomes a zero or a guess. See bench/SCHEMA.md for the record format.
A second table, "Coding harness runs", renders the records that carry a `harness`
block instead of throughput. It sits between its own markers,
`--harness-begin` / `--harness-end`, right after the speed table. A third,
"Agentic rubric runs", does the same for records carrying an `agentic` block,
between `--agentic-begin` / `--agentic-end`. A fourth, "Decision runs", does it for
records carrying a `decide` block, between `--decide-begin` / `--decide-end`. That
table holds both decision measurements: a record with a `decide.jevals` block was
scored by the Jevals recipe over the public question sets and fills the Decision
Score, ECE and hand-off columns; a legacy 110-item record fills Brier and the
wrong-at-gate count instead, and each says "not measured" in the other's columns
rather than borrowing a number computed under a different definition. A
fifth, "Embedding runs", does it for records carrying an `embed` block, between
`--embed-begin` / `--embed-end`. A sixth, "Speech runs", does it for records carrying
a `speech` block, between `--speech-begin` / `--speech-end`. `--check` covers all six
tables.
# ponytail: stdlib only, so it runs in CI and in the slim image with nothing installed.
"""
import argparse
import json
import pathlib
import sys
BEGIN = "<!-- BEGIN bench-table (generated by scripts/render-bench-table.py) -->"
END = "<!-- END bench-table -->"
HARNESS_BEGIN = "<!-- BEGIN harness-bench-table (generated by scripts/render-bench-table.py) -->"
HARNESS_END = "<!-- END harness-bench-table -->"
AGENTIC_BEGIN = "<!-- BEGIN agentic-bench-table (generated by scripts/render-bench-table.py) -->"
AGENTIC_END = "<!-- END agentic-bench-table -->"
DECIDE_BEGIN = "<!-- BEGIN decide-bench-table (generated by scripts/render-bench-table.py) -->"
DECIDE_END = "<!-- END decide-bench-table -->"
EMBED_BEGIN = "<!-- BEGIN embed-bench-table (generated by scripts/render-bench-table.py) -->"
EMBED_END = "<!-- END embed-bench-table -->"
SPEECH_BEGIN = "<!-- BEGIN speech-bench-table (generated by scripts/render-bench-table.py) -->"
SPEECH_END = "<!-- END speech-bench-table -->"
BASE_URL = "https://github.com/getainode/ainode/blob/main/bench/results"
NOT_MEASURED = "not measured"
HEADERS = [
"Model",
"Params / active",
"Quant",
"Placement",
"Single-stream tok/s",
"16 streams tok/s",
"Rubric",
"Date",
"Run",
]
HARNESS_HEADERS = [
"Model",
"Harness",
"pass@1",
"pass@2",
"Mean s",
"Placement",
"Date",
"Run",
]
AGENTIC_HEADERS = [
"Model",
"Placement",
"Score",
"Tools (B+G)",
"Coding (C)",
"Reasoning (D)",
"Needle",
"Date",
"Run",
]
DECIDE_HEADERS = [
"Backend/Model",
"Placement",
"Items",
"Accuracy",
"Decision Score",
"Brier",
"ECE",
"Hand-off at 95%",
"Wrong at 0.9",
"p50 ms",
"Cost",
"Date",
"Run",
]
EMBED_HEADERS = [
"Model",
"Placement",
"Dims",
"p50 ms",
"Texts/s at 64",
"Tokens/s",
"Pairs ordered",
"Date",
"Run",
]
SPEECH_HEADERS = [
"Model",
"Placement",
"Clips",
"WER",
"Exact",
"p50 ms",
"RTF",
"Date",
"Run",
]
#: The batch size the embedding table reports throughput at. The record carries
#: every size the sweep ran; one column is enough in a README, and 64 is the one an
#: indexer uses and the engine's own --max-num-seqs in the proven recipe.
EMBED_BATCH = 64
#: Which groups make up the "Tools" column: B is one call at a time, G is the
#: agentic loop. They are the same skill measured shallow and deep, so the table
#: adds them and the record keeps them apart.
TOOL_GROUPS = ("B", "G")
#: The confidence gate the decision table reports errors at. The record carries 0.8
#: as well; one column is enough in a README, and 0.9 is the one people automate at.
DECIDE_THRESHOLD = "0.9"
def load_runs(results_dir):
"""Every result JSON, newest run first."""
runs = []
for path in sorted(results_dir.glob("*.json")):
with path.open() as fh:
run = json.load(fh)
run["_file"] = path.name
runs.append(run)
runs.sort(key=lambda r: r.get("stamp", ""), reverse=True)
return runs
def is_harness_run(run):
"""A harness-bench record: it measured a coding agent, not throughput.
Those runs carry a `harness` block and no `single_stream`, so every column of
this table would be "not measured" for them. They belong in their own table
(see bench/harness/README.md), not as a row of blanks in this one.
"""
return bool(run.get("harness")) and not (run.get("results") or {}).get("single_stream")
def is_agentic_run(run):
"""An agentic-rubric record: an `agentic` block and no throughput.
Same reasoning as `is_harness_run`: the run scored a capability rubric and took
no tok/s, so every column of the speed table would read "not measured".
"""
return bool(run.get("agentic")) and not (run.get("results") or {}).get("single_stream")
def is_decide_run(run):
"""A decision-bench record: a `decide` block and no throughput.
Same reasoning as the two above: the run measured typed decisions and took no
tok/s, so every column of the speed table would read "not measured".
"""
return bool(run.get("decide")) and not (run.get("results") or {}).get("single_stream")
def is_embed_run(run):
"""An embedding-bench record: an `embed` block and no throughput.
Same reasoning as the three above: the run measured an embedding model, which
generates no tokens at all, so every column of the speed table would read "not
measured" and the tok/s ones would be meaningless even if it did not.
"""
return bool(run.get("embed")) and not (run.get("results") or {}).get("single_stream")
def is_speech_run(run):
"""A speech-bench record: a `speech` block and no throughput.
Same reasoning as the four above: the run measured a transcription model, which
is scored against known words rather than timed writing tokens, so every column
of the speed table would read "not measured".
"""
return bool(run.get("speech")) and not (run.get("results") or {}).get("single_stream")
def throughput_runs(runs):
return [run for run in runs
if not is_harness_run(run) and not is_agentic_run(run)
and not is_decide_run(run) and not is_embed_run(run)
and not is_speech_run(run)]
def fmt_params(model):
params = model.get("params_b")
active = model.get("active_b")
if params is None:
return NOT_MEASURED
if model.get("arch") == "moe" and (active is None or active == params):
# MoE with no active count in the record is still not dense.
return f"{params:g}B MoE"
if model.get("arch") == "dense" or active is None or active == params:
return f"{params:g}B dense"
return f"{params:g}B / {active:g}B active"
def fmt_placement(placement):
bits = []
node = placement.get("node")
if node:
bits.append(node)
gpus = placement.get("gpus")
gpu = placement.get("gpu", "GPU")
if gpus:
bits.append(f"{gpus}× {gpu.replace('NVIDIA ', '')}")
tp = placement.get("tp")
if tp:
bits.append(f"TP={tp}")
line = ", ".join(bits) if bits else NOT_MEASURED
if placement.get("stacked_with"):
# Stacked runs share the node's memory with another engine, which caps
# gpu_memory_utilization and therefore the KV cache. Say so in the row.
line += " (stacked)"
return line
def fmt_tok_s(value):
return NOT_MEASURED if value is None else f"{value:.1f}"
def fmt_single_stream(results):
return fmt_tok_s((results.get("single_stream") or {}).get("decode_tok_s"))
def fmt_aggregate(results, streams=16):
for point in results.get("concurrency") or []:
if point.get("streams") == streams:
return fmt_tok_s(point.get("aggregate_tok_s"))
return NOT_MEASURED
def fmt_rubric(run):
rubric = run.get("rubric") or {}
passed, total = rubric.get("pass"), rubric.get("total")
if passed is None or total is None:
return "not run"
return f"{passed}/{total}"
def fmt_date(stamp):
if not stamp or len(stamp) < 8:
return "unknown"
return f"{stamp[0:4]}-{stamp[4:6]}-{stamp[6:8]}"
def row_for(run, base_url):
model = run.get("model") or {}
label = run.get("label") or "run"
return [
model.get("name") or model.get("id") or "unknown",
fmt_params(model),
model.get("quant") or NOT_MEASURED,
fmt_placement(run.get("placement") or {}),
fmt_single_stream(run.get("results") or {}),
fmt_aggregate(run.get("results") or {}),
fmt_rubric(run),
fmt_date(run.get("stamp")),
f"[{label}]({base_url}/{run['_file']})",
]
def render_table(runs, base_url=BASE_URL):
runs = throughput_runs(runs)
# Unpadded cells and a `|---|` rule, matching the other tables in README.md.
lines = [
"| " + " | ".join(HEADERS) + " |",
"|" + "---|" * len(HEADERS),
]
for run in runs:
lines.append("| " + " | ".join(row_for(run, base_url)) + " |")
return "\n".join(lines)
def note_marks_not_measured(run, hr):
"""A record's notes can flag one harness's rows as "not measured".
The notes are free text and name the offending harness before they say so,
either with its version string ("opencode 1.18.31") or its bare name
("claude"), so a note counts only when it carries both the name and the
words "not measured".
"""
version = hr.get("version")
name = hr.get("harness") or ""
candidates = []
if version:
candidates.append(version)
if name:
candidates.append(f"{name} {version}")
if name:
candidates.append(name)
if not candidates:
return False
wanted = [c.lower() for c in candidates]
for note in run.get("notes") or []:
lowered = note.lower()
if "not measured" in lowered and any(w in lowered for w in wanted):
return True
return False
def fmt_harness(hr):
"""The harness column: its name, and its version when the run knew one."""
name = hr.get("harness") or NOT_MEASURED
version = hr.get("version")
if version:
return f"{name} {version}"
return name
def fmt_pass(hr, key):
"""pass@1 / pass@2 rendered as a count over the tasks the run attempted."""
scores = hr.get("scores") or {}
passed = scores.get(key)
tasks = scores.get("tasks")
if passed is None or tasks is None:
return NOT_MEASURED
return f"{passed}/{tasks}"
def fmt_mean(hr):
value = (hr.get("scores") or {}).get("mean_wall_s")
return NOT_MEASURED if value is None else f"{value:.1f}"
def fmt_placement_tp(placement):
"""Placement narrowed to node and tensor-parallel size for the harness table."""
placement = placement or {}
bits = []
node = placement.get("node")
if node:
bits.append(node)
tp = placement.get("tp")
if tp:
bits.append(f"TP={tp}")
return ", ".join(bits) if bits else NOT_MEASURED
def row_for_harness(run, hr, base_url):
model = run.get("model") or {}
label = run.get("label") or "run"
if note_marks_not_measured(run, hr):
pass1 = pass2 = mean = NOT_MEASURED
else:
pass1 = fmt_pass(hr, "passed_at_1")
pass2 = fmt_pass(hr, "passed_at_2")
mean = fmt_mean(hr)
return [
model.get("name") or model.get("id") or "unknown",
fmt_harness(hr),
pass1,
pass2,
mean,
fmt_placement_tp(run.get("placement") or {}),
fmt_date(run.get("stamp")),
f"[{label}]({base_url}/{run['_file']})",
]
def dedup_harness_runs(runs):
"""One (run, harness-run) per (model, harness); the latest stamp wins.
`runs` arrive newest-first, so the first record seen for a pair is its
winner and every earlier-dated record for the same pair is skipped.
"""
chosen = {}
for run in runs:
model = run.get("model") or {}
label = model.get("name") or model.get("id") or "unknown"
for hr in (run.get("harness") or {}).get("runs") or []:
key = (label, hr.get("harness") or "")
if key not in chosen:
chosen[key] = (run, hr)
return list(chosen.values())
def render_harness_table(runs, base_url=BASE_URL):
"""One row per (model, harness), newest record winning, sorted by model then harness.
A run whose notes flag a harness as "not measured" renders that phrase in the
score cells instead of a number.
"""
chosen = dedup_harness_runs(runs)
def sort_key(pair):
run, hr = pair
model = run.get("model") or {}
return (model.get("name") or model.get("id") or "", hr.get("harness") or "")
chosen.sort(key=sort_key)
lines = [
"| " + " | ".join(HARNESS_HEADERS) + " |",
"|" + "---|" * len(HARNESS_HEADERS),
]
for run, hr in chosen:
lines.append("| " + " | ".join(row_for_harness(run, hr, base_url)) + " |")
return "\n".join(lines)
def fmt_group(agentic, groups):
"""`pass/total` summed over the named probe groups, or "not measured".
Summed rather than averaged: the cell is a count of probes, and a run that
skipped a group (`--groups`, `--quick`) contributes nothing to it instead of a
zero it never measured.
"""
blocks = agentic.get("groups") or {}
present = [blocks[g] for g in groups if isinstance(blocks.get(g), dict)]
if not present:
return NOT_MEASURED
passed = sum(b.get("pass") or 0 for b in present)
total = sum(b.get("total") or 0 for b in present)
if not total:
return NOT_MEASURED
return f"{passed}/{total}"
def fmt_score(agentic):
score = agentic.get("score") or {}
passed, total = score.get("pass"), score.get("total")
if passed is None or total is None:
return NOT_MEASURED
return f"{passed}/{total}"
def fmt_needle(agentic):
"""The largest prompt size whose needle probe passed.
A run where every size failed says so rather than naming the smallest one, and
a run that skipped group E reads "not measured".
"""
needle = agentic.get("needle") or {}
sizes = []
for size, ok in needle.items():
try:
sizes.append((int(size), bool(ok)))
except (TypeError, ValueError):
continue
if not sizes:
return NOT_MEASURED
passing = [size for size, ok in sizes if ok]
if not passing:
return "none"
return f"{max(passing) // 1000}k"
def row_for_agentic(run, base_url):
model = run.get("model") or {}
agentic = run.get("agentic") or {}
label = run.get("label") or "run"
return [
model.get("name") or model.get("id") or "unknown",
fmt_placement_tp(run.get("placement") or {}),
fmt_score(agentic),
fmt_group(agentic, TOOL_GROUPS),
fmt_group(agentic, ("C",)),
fmt_group(agentic, ("D",)),
fmt_needle(agentic),
fmt_date(run.get("stamp")),
f"[{label}]({base_url}/{run['_file']})",
]
def dedup_agentic_runs(runs):
"""One record per model; the latest stamp wins.
`runs` arrive newest-first, so the first record seen for a model is its winner.
The same rule the harness table uses, keyed on the model alone because an
agentic run has one score rather than one per harness.
"""
chosen = {}
for run in runs:
if not is_agentic_run(run) and not run.get("agentic"):
continue
model = run.get("model") or {}
key = model.get("name") or model.get("id") or "unknown"
if key not in chosen:
chosen[key] = run
return list(chosen.values())
def render_agentic_table(runs, base_url=BASE_URL):
"""One row per model, newest record winning, sorted by model name."""
chosen = dedup_agentic_runs(runs)
def sort_key(run):
model = run.get("model") or {}
return model.get("name") or model.get("id") or ""
chosen.sort(key=sort_key)
lines = [
"| " + " | ".join(AGENTIC_HEADERS) + " |",
"|" + "---|" * len(AGENTIC_HEADERS),
]
for run in chosen:
lines.append("| " + " | ".join(row_for_agentic(run, base_url)) + " |")
return "\n".join(lines)
def fmt_backend_model(run):
"""The first column: which backend answered, and as what model.
Both, because the same model id behind two backends is two different
measurements: `/v1/decide` and the lettered-options chat fallback ask a served
model in different shapes, and averaging their rows together would hide that.
"""
decide = run.get("decide") or {}
model = run.get("model") or {}
name = model.get("name") or model.get("id") or "unknown"
backend = decide.get("backend")
return f"{backend} / {name}" if backend else name
def fmt_ratio(value, places=3):
return NOT_MEASURED if value is None else f"{value:.{places}f}"
def fmt_items(decide):
overall = decide.get("overall") or {}
count = overall.get("n")
if count is None:
return NOT_MEASURED
errors = overall.get("errors") or 0
return f"{count}" if not errors else f"{count} ({errors} failed)"
def fmt_wrong_at(decide, threshold=DECIDE_THRESHOLD):
"""`wrong of kept` at the gate: the failure mode, over the answers it let through.
Two numbers rather than a rate, because "2 of 106" is the sentence a reader
needs: at 0.9 the backend answered 106 of the items and got 2 of those wrong.
"""
block = ((decide.get("overall") or {}).get("thresholds") or {}).get(threshold)
if not isinstance(block, dict):
return NOT_MEASURED
wrong, kept = block.get("wrong"), block.get("kept")
if wrong is None or kept is None:
return NOT_MEASURED
return f"{wrong} of {kept}"
def decide_set_blocks(decide):
"""The per-set metrics blocks of a Jevals-recipe record, or ``[]`` for a legacy one.
A record carrying a `decide.jevals` block was scored by the recipe recorded in
`bench/decide/JEVALS.md` over the public question sets; one with no such block is a
legacy 110-item run. The two are not the same measurement, so the three columns
below read from the first and say "not measured" for the second rather than
borrowing a number from a different definition.
"""
return list(((decide.get("jevals") or {}).get("sets") or {}).values())
def fmt_decision_score(decide):
"""The mean Decision Score over the sets this run scored, or "not measured".
100 is perfect, 0 is answering with the label base rates and negative is worse than
that, so this column is the one to read first on a Jevals-recipe row. The mean over
several sets is only shown when every set has a score, which is the recipe's rule.
"""
overall = (decide.get("jevals") or {}).get("overall") or {}
value = overall.get("mean_decision_score")
if value is None:
blocks = decide_set_blocks(decide)
scores = [b.get("decision_score") for b in blocks]
if not scores or any(s is None for s in scores):
return NOT_MEASURED
value = sum(scores) / len(scores)
return f"{value:.1f}"
def fmt_decide_ece(decide):
"""The calibration gap, in the units of whichever recipe produced it.
A Jevals-recipe row shows the ten-bin top-label ECE in POINTS with the unit in the
cell (`5.8 pt`, which is 0.058); a legacy row shows its own five-bin ratio
(`0.059`). The unit travels with the number because two definitions in one column
with no unit is how a comparison becomes a lie.
"""
blocks = decide_set_blocks(decide)
if blocks:
points = [b.get("ece_points") for b in blocks]
points = [p for p in points if p is not None]
if not points:
return NOT_MEASURED
return f"{sum(points) / len(points):.1f} pt"
value = (decide.get("overall") or {}).get("ece")
return NOT_MEASURED if value is None else f"{value:.3f}"
def fmt_handoff_share(decide):
"""`share @ threshold`: the largest share it can take alone while staying 95% right.
Averaged over the sets when there are several, and "not measured" as soon as one set
never reached 95 percent at any threshold, because a mean over the sets that did
would read as a hand-off the model does not have.
"""
blocks = decide_set_blocks(decide)
if not blocks:
return NOT_MEASURED
hands = [b.get("handoff_95") for b in blocks]
if not hands or any(not h for h in hands):
return NOT_MEASURED
shares = [h.get("share") for h in hands]
thresholds = [h.get("threshold") for h in hands]
if any(s is None for s in shares) or any(t is None for t in thresholds):
return NOT_MEASURED
return (f"{sum(shares) / len(shares):.2f} @ "
f"{sum(thresholds) / len(thresholds):.2f}")
def fmt_latency_ms(decide):
value = (decide.get("overall") or {}).get("p50_ms")
return NOT_MEASURED if value is None else f"{value:.0f}"
def fmt_usd(decide):
"""The run's bill. `$0` for a backend nobody charges per token for."""
value = (decide.get("overall") or {}).get("cost_usd")
if value is None:
return NOT_MEASURED
if not value:
return "$0"
return f"${value:.4f}" if value >= 0.0001 else f"${value:.6f}"
def fmt_placement_decide(run):
"""Placement for a decision row, or the hosted service's own name."""
placement = run.get("placement") or {}
if placement.get("node") and not placement.get("gpus") and not placement.get("tp"):
# A hosted backend has one honest placement string and no GPU of ours.
return placement["node"]
return fmt_placement_tp(placement)
def row_for_decide(run, base_url):
decide = run.get("decide") or {}
overall = decide.get("overall") or {}
label = run.get("label") or "run"
return [
fmt_backend_model(run),
fmt_placement_decide(run),
fmt_items(decide),
fmt_ratio(overall.get("accuracy")),
fmt_decision_score(decide),
fmt_ratio(overall.get("brier")),
fmt_decide_ece(decide),
fmt_handoff_share(decide),
fmt_wrong_at(decide),
fmt_latency_ms(decide),
fmt_usd(decide),
fmt_date(run.get("stamp")),
f"[{label}]({base_url}/{run['_file']})",
]
def dedup_decide_runs(runs):
"""One record per (backend, model); the latest stamp wins.
Keyed on the pair because a model measured through `/v1/decide` and through the
chat fallback are two backends' numbers, not one model's, and both belong in the
table.
"""
chosen = {}
for run in runs:
if not run.get("decide"):
continue
model = run.get("model") or {}
key = ((run["decide"].get("backend") or ""),
model.get("name") or model.get("id") or "unknown")
if key not in chosen:
chosen[key] = run
return list(chosen.values())
def render_decide_table(runs, base_url=BASE_URL):
"""One row per (backend, model), newest record winning, sorted by that pair."""
chosen = dedup_decide_runs(runs)
def sort_key(run):
model = run.get("model") or {}
return ((run.get("decide") or {}).get("backend") or "",
model.get("name") or model.get("id") or "")
chosen.sort(key=sort_key)
lines = [
"| " + " | ".join(DECIDE_HEADERS) + " |",
"|" + "---|" * len(DECIDE_HEADERS),
]
for run in chosen:
lines.append("| " + " | ".join(row_for_decide(run, base_url)) + " |")
return "\n".join(lines)
def fmt_dims(embed):
value = embed.get("dimensions")
return NOT_MEASURED if not value else str(value)
def fmt_embed_latency(embed):
"""p50 of a single-text request, end to end from wherever the bench ran.
The record also carries the measured transport floor; the column is the number a
caller waits, and the floor is in the record's notes where the sentence that
explains it fits.
"""
value = (embed.get("latency") or {}).get("p50_ms")
return NOT_MEASURED if value is None else f"{value:.0f}"
def embed_row_at(embed, batch=EMBED_BATCH):
for row in embed.get("throughput") or []:
if row.get("batch") == batch:
return row
return None
def fmt_texts_per_s(embed, batch=EMBED_BATCH):
row = embed_row_at(embed, batch)
if not row or row.get("texts_per_s") is None:
return NOT_MEASURED
return f"{row['texts_per_s']:.0f}"
def fmt_tokens_per_s(embed, batch=EMBED_BATCH):
"""Tokens per second at the same batch as the texts column, not the best of all.
Two rates from two different batch sizes side by side would read as one
measurement and be neither.
"""
row = embed_row_at(embed, batch)
if not row or row.get("tokens_per_s") is None:
return NOT_MEASURED
return f"{row['tokens_per_s']:.0f}"
def fmt_pairs_ordered(embed):
"""The quality verdict: every related pair above every unrelated one.
A run that could not score all six pairs reads "not measured" rather than "no",
because nothing failed: nothing was measured.
"""
quality = embed.get("quality") or {}
ordered = quality.get("ordered")
if ordered is None:
return NOT_MEASURED
margin = quality.get("margin")
if margin is None:
return "yes" if ordered else "NO"
return f"{'yes' if ordered else 'NO'} ({margin:+.2f})"
def row_for_embed(run, base_url):
model = run.get("model") or {}
embed = run.get("embed") or {}
label = run.get("label") or "run"
return [
model.get("name") or model.get("id") or "unknown",
fmt_placement_tp(run.get("placement") or {}),
fmt_dims(embed),
fmt_embed_latency(embed),
fmt_texts_per_s(embed),
fmt_tokens_per_s(embed),
fmt_pairs_ordered(embed),
fmt_date(run.get("stamp")),
f"[{label}]({base_url}/{run['_file']})",
]
def dedup_embed_runs(runs):
"""One record per (model, endpoint); the latest stamp wins.
Keyed on the pair because the same model measured through the fleet router and
straight at its engine port are two different measurements of the same instance,
and the difference between them is the routing hop this table exists to make
visible.
"""
chosen = {}
for run in runs:
if not run.get("embed"):
continue
model = run.get("model") or {}
key = (model.get("name") or model.get("id") or "unknown",
(run["embed"].get("endpoint") or ""))
if key not in chosen:
chosen[key] = run
return list(chosen.values())
def render_embed_table(runs, base_url=BASE_URL):
"""One row per (model, endpoint), newest record winning, sorted by that pair."""
chosen = dedup_embed_runs(runs)
def sort_key(run):
model = run.get("model") or {}
return (model.get("name") or model.get("id") or "",
(run.get("embed") or {}).get("endpoint") or "")
chosen.sort(key=sort_key)
lines = [
"| " + " | ".join(EMBED_HEADERS) + " |",
"|" + "---|" * len(EMBED_HEADERS),
]
for run in chosen:
lines.append("| " + " | ".join(row_for_embed(run, base_url)) + " |")
return "\n".join(lines)
def fmt_speech_clips(speech):
"""Clips scored out of clips sent, so a run that lost one does not read as ten."""
accuracy = speech.get("accuracy") or {}
sent = accuracy.get("clips")
scored = accuracy.get("scored")
if not sent:
return NOT_MEASURED
return str(sent) if scored == sent else f"{scored} of {sent}"
def fmt_wer(speech):
"""The pooled word error rate as a percentage, with the orthographic one beside it.
Both, because the difference between them is spelling rather than hearing and one
number alone invites the reader to pick which it is. A run that scored nothing
reads "not measured" rather than a rate nobody took.
"""
accuracy = speech.get("accuracy") or {}
wer = accuracy.get("wer")
if wer is None:
return NOT_MEASURED
strict = accuracy.get("wer_orthographic")
if strict is None:
return f"{wer * 100:.1f}%"
return f"{wer * 100:.1f}% ({strict * 100:.1f}% raw)"
def fmt_exact(speech):
"""Clips transcribed word for word, which is the number a user feels."""
accuracy = speech.get("accuracy") or {}
exact = accuracy.get("clips_exact")
scored = accuracy.get("scored")
if exact is None or not scored:
return NOT_MEASURED
return f"{exact} of {scored}"
def fmt_speech_latency(speech):
"""p50 of one clip uploaded on its own, end to end from wherever the bench ran.
The record also carries the measured transport floor; the column is the number a
caller waits, and the floor is in the record's notes where the sentence that
explains it fits.
"""
value = (speech.get("latency") or {}).get("p50_ms")
return NOT_MEASURED if value is None else f"{value:.0f}"
def fmt_rtf(speech):
"""Pooled real-time factor: wall seconds per second of audio.
Below 1 is faster than the clip plays, which is what decides whether a live
stream can be kept up with. The wire is in it, so the record's floor is part of
reading it.
"""
value = (speech.get("rtf") or {}).get("pooled")
return NOT_MEASURED if value is None else f"{value:.3f}"
def row_for_speech(run, base_url):
model = run.get("model") or {}
speech = run.get("speech") or {}
label = run.get("label") or "run"
return [
model.get("name") or model.get("id") or "unknown",
fmt_placement_tp(run.get("placement") or {}),
fmt_speech_clips(speech),
fmt_wer(speech),
fmt_exact(speech),
fmt_speech_latency(speech),
fmt_rtf(speech),
fmt_date(run.get("stamp")),
f"[{label}]({base_url}/{run['_file']})",
]
def dedup_speech_runs(runs):
"""One record per (model, endpoint, path); the latest stamp wins.
Keyed on all three because the same model measured through the fleet router and
straight at its engine port are two different measurements of the same instance,
and because transcription and translation are different tasks that must never
share a row.
"""
chosen = {}
for run in runs:
if not run.get("speech"):
continue
model = run.get("model") or {}
key = (model.get("name") or model.get("id") or "unknown",
(run["speech"].get("endpoint") or ""),
(run["speech"].get("path") or ""))
if key not in chosen:
chosen[key] = run
return list(chosen.values())
def render_speech_table(runs, base_url=BASE_URL):
"""One row per (model, endpoint, path), newest record winning, sorted by that."""
chosen = dedup_speech_runs(runs)
def sort_key(run):
model = run.get("model") or {}
speech = run.get("speech") or {}
return (model.get("name") or model.get("id") or "",
speech.get("endpoint") or "", speech.get("path") or "")
chosen.sort(key=sort_key)
lines = [
"| " + " | ".join(SPEECH_HEADERS) + " |",
"|" + "---|" * len(SPEECH_HEADERS),
]
for run in chosen:
lines.append("| " + " | ".join(row_for_speech(run, base_url)) + " |")
return "\n".join(lines)
def splice(text, table, begin=BEGIN, end=END):
"""Replace whatever sits between the markers. Both markers must already exist."""
start = text.find(begin)
stop = text.find(end)
if start == -1 or stop == -1:
raise SystemExit(f"markers not found in target file; expected\n {begin}\n {end}")
if stop < start:
raise SystemExit("end marker appears before begin marker")
head = text[: start + len(begin)]
tail = text[stop:]
return f"{head}\n\n{table}\n\n{tail}"
def main():
repo = pathlib.Path(__file__).resolve().parent.parent
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
ap.add_argument("--results", type=pathlib.Path, default=repo / "bench" / "results")
ap.add_argument("--readme", type=pathlib.Path, default=repo / "README.md",
help="file to rewrite; any file carrying the two markers works, which "
"is how the docs-site guide gets the same table")
ap.add_argument("--begin", default=BEGIN, help="opening marker (MDX needs {/* ... */})")
ap.add_argument("--end", default=END, help="closing marker")
ap.add_argument("--harness-begin", default=HARNESS_BEGIN,
help="opening marker for the Coding harness runs table")
ap.add_argument("--harness-end", default=HARNESS_END,
help="closing marker for the Coding harness runs table")
ap.add_argument("--agentic-begin", default=AGENTIC_BEGIN,
help="opening marker for the Agentic rubric runs table")
ap.add_argument("--agentic-end", default=AGENTIC_END,
help="closing marker for the Agentic rubric runs table")
ap.add_argument("--decide-begin", default=DECIDE_BEGIN,
help="opening marker for the Decision runs table")
ap.add_argument("--decide-end", default=DECIDE_END,
help="closing marker for the Decision runs table")
ap.add_argument("--embed-begin", default=EMBED_BEGIN,
help="opening marker for the Embedding runs table")