0xSero brandonmusic commited on
Commit
6949f28
·
0 Parent(s):

Duplicate from brandonmusic/GLM-5.2-EXL3-TR3-3.0bpw

Browse files

Co-authored-by: Brandon Music <brandonmusic@users.noreply.huggingface.co>

This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +38 -0
  2. .manifest_verified +1 -0
  3. LICENSE +21 -0
  4. MANIFEST.sha256 +92 -0
  5. README.md +314 -0
  6. RELEASE_TEST_SUITE.md +0 -0
  7. benchmarks/2026-07-22/README.md +103 -0
  8. benchmarks/2026-07-22/decode-c1-c8.json +1469 -0
  9. benchmarks/2026-07-22/decode-c1-c8.log +104 -0
  10. benchmarks/2026-07-22/decode-c1-dedicated.json +342 -0
  11. benchmarks/2026-07-22/decode-c1-dedicated.log +99 -0
  12. benchmarks/2026-07-22/estonia-c5-r5.json +542 -0
  13. benchmarks/2026-07-22/estonia-c5-r5.log +70 -0
  14. benchmarks/2026-07-22/image-inspect.json +134 -0
  15. benchmarks/2026-07-22/kld-fp8-dcp4-summary.json +30 -0
  16. benchmarks/2026-07-22/kld-nvfp4-dcp4-summary.json +30 -0
  17. benchmarks/2026-07-22/lavd-c5-r10-pass2.json +0 -0
  18. benchmarks/2026-07-22/lavd-c5-r10-pass2.log +70 -0
  19. benchmarks/2026-07-22/lavd-c5-r10.json +0 -0
  20. benchmarks/2026-07-22/lavd-c5-r10.log +69 -0
  21. benchmarks/2026-07-22/prefill-8k-64k-128k.json +359 -0
  22. benchmarks/2026-07-22/prefill-8k-64k-128k.log +52 -0
  23. calibration_encoder/README.md +90 -0
  24. calibration_encoder/bootstrap_ext_b300.py +359 -0
  25. calibration_encoder/calibration/reap_recall_calib.jsonl +3 -0
  26. calibration_encoder/capture_b300.py +1167 -0
  27. calibration_encoder/convert_b300.sh +137 -0
  28. calibration_encoder/encode_b300.py +1093 -0
  29. calibration_encoder/encode_tr3_v31.py +0 -0
  30. calibration_encoder/preflight_b300.py +631 -0
  31. calibration_manifest.json +0 -0
  32. chat_template.jinja +119 -0
  33. config.json +507 -0
  34. docker-compose.yml +165 -0
  35. generation_config.json +12 -0
  36. independent-eval/ORIGINAL_REPORT.md +77 -0
  37. independent-eval/gpqa_bench.py +129 -0
  38. independent-eval/gpqa_diamond_summary.json +221 -0
  39. independent-eval/mathbench.py +187 -0
  40. independent-eval/rerun_errors.py +88 -0
  41. model-embed.safetensors +3 -0
  42. model-head.safetensors +3 -0
  43. model-layer-000.safetensors +3 -0
  44. model-layer-001.safetensors +3 -0
  45. model-layer-002.safetensors +3 -0
  46. model-layer-003.safetensors +3 -0
  47. model-layer-004.safetensors +3 -0
  48. model-layer-005.safetensors +3 -0
  49. model-layer-006.safetensors +3 -0
  50. model-layer-007.safetensors +3 -0
.gitattributes ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
37
+ model.safetensors.index.json filter=lfs diff=lfs merge=lfs -text
38
+ calibration_encoder/calibration/reap_recall_calib.jsonl filter=lfs diff=lfs merge=lfs -text
.manifest_verified ADDED
@@ -0,0 +1 @@
 
 
1
+ bfb6dc39f28da08c1cfc5b89603414046adf7003152d69e9ee350e11f7a1fa63
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zhipu AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
MANIFEST.sha256 ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 34448b82c17d60fec9b65b1f093c115ddbaadc04beb1b0140b6bfed2e012a930 .gitattributes
2
+ f4a18c6ae40b0a8e7d2b7667f52f6e1994e54a46430d2e172b73cb8c9b5eb0d7 LICENSE
3
+ ed5aca8ce3dc5f8de626c87e488444343e43b1dcbdeb0e643dc72fea63ab06e8 README.md
4
+ b14c763fbc8feca6539f1411139fbfae58a7a906df5cbd5b9d9e104ab0475699 calibration_manifest.json
5
+ 172dc74a35e1752df75ecfb2b2cf9326d2852bb1379868ebeec9571654489679 chat_template.jinja
6
+ fcde001350291a0048318d4a1136e0732e31f829f804a57cfbb558903e54171a config.json
7
+ ac76b43d8683d3b930126870fc8be73d8679308fe752fa1f381096d8354f6a55 generation_config.json
8
+ c83b92fcb91e1fe5c2ce10114685e91f768f4447b5c88b0fe8e2dee795001903 model-embed.safetensors
9
+ cd55f37f1aa08e1aa191da6a47594061ce340e75663cc770fdd26b57d0829a32 model-head.safetensors
10
+ 523923a15352a0706d2672ff5bcfa9a642813784aa5dd213087b10c1f1a7022c model-layer-000.safetensors
11
+ bf2ede0905c731348a618137db81be2db2e7d69d0f43f645636214e8f12ded06 model-layer-001.safetensors
12
+ bf91373c594ddc930ebcfef98235a5e1189b6cd7838bf92a3b36a708d4bef45c model-layer-002.safetensors
13
+ d2ebb2f2d5077ae997ac0b3dff777ad53aa578430569e8e7a1e7be2f6ab1f707 model-layer-003.safetensors
14
+ a0a558036106b6c2811309b217fd571b923cb7cd97f5713506090b143f261308 model-layer-004.safetensors
15
+ 7b9dd5f64a86b4cfddf2242350f7da5fa64f20a32def510b6192e88c43bc7c89 model-layer-005.safetensors
16
+ 7ac996885eb92fdca3cc2003a1f0852cfffc2efc32dfa9cfaac9e14b241dee04 model-layer-006.safetensors
17
+ 86d161e80133957b24de574c2159eefe72f68fef5729208aa21652b585517795 model-layer-007.safetensors
18
+ e47958158c21184f51e5a710d0f89b802269293c268c216843e871af2cd240da model-layer-008.safetensors
19
+ 5786b8e2c99baba5d8b1308aad1da7a1717611e60ce29733c1e0800f39485870 model-layer-009.safetensors
20
+ 8cc60cf9cf329049f02ef5f26e483c8e307b8afe250d73e7ddaba98487ef60e0 model-layer-010.safetensors
21
+ 80807c956832883d8a8bcbb6649f4d43b2c023f4212b3b9014593b4d5e1258c0 model-layer-011.safetensors
22
+ 7c3e78127440dc7219322a86d7fe99e0b61603eb938b4166dbc85403ad05b4e2 model-layer-012.safetensors
23
+ bef7e1ba1223951a1f168ca22f40713c77560a51dd56f3699a3b9a9f246a5fa8 model-layer-013.safetensors
24
+ 44e1d9a6880c65b97579ae1ffc0324ca68674af9902f5415f896cfced4934a2c model-layer-014.safetensors
25
+ 452196c9da2e62960fbe608eef090659f1262de47b196278aadb7de5394d737a model-layer-015.safetensors
26
+ 1ecc2bd54d02501d6b9e4ab21d0556d054ed116c5ccb7fd42f0a6686e867aca9 model-layer-016.safetensors
27
+ 85c6876bdf1cf1c5d4f596d79f7625fe63a4814935c331b4b362f4ed827fe14a model-layer-017.safetensors
28
+ 3e0caca28dad9b7616a4eb58cb10001a1455d9e49a193cb94b7b317ce22aaecb model-layer-018.safetensors
29
+ 01f1e20f426e47f33d27dabfa158bfb09c80acb30c2328a1417302c9810349a0 model-layer-019.safetensors
30
+ b0cd1da85d3af4c77c66e2f6a86c9ed07c7c1d3a12e3123f5bb039bfcfe3be94 model-layer-020.safetensors
31
+ 64be5c5d563f73473dc3216d6f77e5a53470cb421621140f1d84f4b3f3f1996d model-layer-021.safetensors
32
+ ef7d14b7e4e48a4460f6a24dd25ebe726c6ea1c407a183e54919d76ba3d2789b model-layer-022.safetensors
33
+ 4f0f6e24863a648b87c72d3bd571cca43e2a6fc79a74cb5152ef637200def3f2 model-layer-023.safetensors
34
+ d28a775166193ed6a2fb31b93a065ac0c6ce196a21570df3a3377d3f4021e76d model-layer-024.safetensors
35
+ e3aa5ae47ae074be6a02f825a4ed3b70f6fe5573f19a5650b49f153c248822ad model-layer-025.safetensors
36
+ ea07777d0c68751bb6e13690deac85413777e29ed6c1530d498bd1ab1526000b model-layer-026.safetensors
37
+ 0c99222d9022164a5ddcd64c422bbd76afb4e2abbbf3acb985d18bffc2048cfc model-layer-027.safetensors
38
+ 7022599423dd16d8fdfe673265d3281daeb506ddf8070b59661c7ba15d291b91 model-layer-028.safetensors
39
+ 05c9392e56954767de828f736fcbeee7f7b818b8fc3a65676a5734a2c0761433 model-layer-029.safetensors
40
+ a52473451a97970627f752da41dc40fd5bb24c5ff863db9bf185e3591da0a6f4 model-layer-030.safetensors
41
+ 5069636328af81fe4649daaccb0f402bc9c04e54ee54bb4afb2ec6b7b352cc8c model-layer-031.safetensors
42
+ 3f34d25eb7cb561f325646a82a74f600070a2e1a6f6142c6e978dbb339da0d29 model-layer-032.safetensors
43
+ 203229e06cfb11398345d99a3095dc5e1dbef3e4a932d7d7b408b760512482fc model-layer-033.safetensors
44
+ 941feb7d80b18eb1e7197686fe96e94faad37dc39d371c66f4d4b2f77656a725 model-layer-034.safetensors
45
+ 9417b1aa875c8633ab7569d5ba772d4bc4cddba910763cbfc35ae0c4c9a358c6 model-layer-035.safetensors
46
+ 26c86c37a0c561a8603177a509a3a2288352d316d23b1f9a5726ecc0932906d2 model-layer-036.safetensors
47
+ e52412112253e360cf3e5e43b91979ce6136ef008b63772580e97a3d7ce762e9 model-layer-037.safetensors
48
+ 2f67a05706fee1928d9a78d646bb142a25e27ee3ddee474d7d77957c3833ee8f model-layer-038.safetensors
49
+ 094d89de92d782f785ff88e615d63e8d77a58a00593c6726d065dd76d7c02da5 model-layer-039.safetensors
50
+ 8bea80bae6506ec0ecc7634ef647e485657f17a64648116b35e878dbc3750373 model-layer-040.safetensors
51
+ 42aa35c5472a18b6f136fadf75f70941efd7c521829b682407d8ec543ec3adbe model-layer-041.safetensors
52
+ fe887f998754bedf1ff76e508052615c21af3944ef82bd089691fbbbf542ee89 model-layer-042.safetensors
53
+ 4f3caa432c6183b97481aa3dcd2a8d1aa1b6c8f7132588c6cd0d7c23a0485f7f model-layer-043.safetensors
54
+ 31634aaaf0464d06e539ddd8ec5e8141bb4837f44a4781a5fae69446fba14027 model-layer-044.safetensors
55
+ 34ea3df0f3d97323c86df4f92193b0b870ee716eeefb0e388690df5a11c9ee2b model-layer-045.safetensors
56
+ 0e98220bd9c653b9e6fe8364fbefd7112b5edcde2f8cb8c1b0601e561cf1aab5 model-layer-046.safetensors
57
+ cd01aa23c4aa2deb11c7198459d0ea4c9821616f71171bc55f2b3e96fd57d291 model-layer-047.safetensors
58
+ bd97a89c83d8efa387bf50d794ccc5182a193502fd63afb13d0decce3e0c06a0 model-layer-048.safetensors
59
+ f25e484eb21468c3c7b601f6e7df3820574f4fd5329b36869a6c9ea7d0247ced model-layer-049.safetensors
60
+ 2ff5640492add5b873764e96a211966b51847f0799aba5a9376f5fb1254666d0 model-layer-050.safetensors
61
+ 21f0437e296a2eb720ce1806bf7c2efe160220bf447a5fe2cdfa403f0085be04 model-layer-051.safetensors
62
+ c62cdd2595d24d3f4591569a4b8ebcc5e85dfb24bc6c5cc7ce7e5e3f10510f57 model-layer-052.safetensors
63
+ 6d27e42e20a60f4287f772530756877d3d845db46b1fc9a1e74e3ba1c2ba8e27 model-layer-053.safetensors
64
+ 8d9b4f1949a17dc47541deaf6294202a0c470949a399c832cd1b889fe357b1b4 model-layer-054.safetensors
65
+ 7ad769b9c3b69f0d46427db8c2dd66bc9dcb3026237d1fd601f679aff3e5ed2a model-layer-055.safetensors
66
+ 1e1b05efa524d2ada858cd5cb253552ae25813dcc0cda00c52c93a49d639fcfe model-layer-056.safetensors
67
+ a074ea5342ea64445fc24beec85ba3e0f84fa0e29cf9bb2cb6cb04b5ac61500d model-layer-057.safetensors
68
+ 5eb065390c68b17f4fdcbdbb4652b917ddf5e4dcb8fb4dcbf48bdb85259944d4 model-layer-058.safetensors
69
+ b77c52eda46b3b04e46b15fac14dc8b9fb1726dfd16f147e33eb4b0c2f805d71 model-layer-059.safetensors
70
+ ff14e64b5fca5cb12cb174170414d7f925470713d57f5b15c85d906ddec4c8dd model-layer-060.safetensors
71
+ c6f73d57fc62bad0d569df8c1a2d24d14b3792544f7562dd9162521e00d7dcb3 model-layer-061.safetensors
72
+ 01c4ee90769f8f333c5c38b3a5aec63879d5f4f9fcbea2a7cdccfe0df7a61978 model-layer-062.safetensors
73
+ a5063ac082bac1a9178b17e22ac5a4297c6177182adf492e06fa58fb5bc77ec1 model-layer-063.safetensors
74
+ 27c4488dde59edd81446d8118f6b8c537ea75cef16e72cb13e2df86d99cca496 model-layer-064.safetensors
75
+ 5627ba5174368042c2c8f1f668ff950164fb5b5bf92fa489d33087b5fc722305 model-layer-065.safetensors
76
+ bfef774788d080261c5ffaccf6023ad29494d51f39b19c7485a4d4e33547c301 model-layer-066.safetensors
77
+ 48d5f2e00e557bb613f54ab5f7dcef49fb7113231d7a7f20b774fb9c22e05f91 model-layer-067.safetensors
78
+ d3ff469c724bbd23a35ef8dbe41c4d0d1dbe2fa463dbb6187f294793ac481b72 model-layer-068.safetensors
79
+ 67ba35cc2792210488cf863ca454d7f9dcc9f24d92885a87d8293fb7c9fd5f33 model-layer-069.safetensors
80
+ 8772ad177adebef697aeed0161cc2b03d2e534443597206c24ee87292b23f09f model-layer-070.safetensors
81
+ 3b79dd4313813570feb6827583b4dcd270f0befd343839885ac352ef98e6cc77 model-layer-071.safetensors
82
+ 872d5ba6788f14c415a4f7b04e8967b57638d7340dcd40fb61e04abdef79f38c model-layer-072.safetensors
83
+ c1bf842b788c0be1e00a7512a28093ee6936fca3d361ae9f3c8cf236142e4689 model-layer-073.safetensors
84
+ 78658d1192e76b9aad29a8c3075060e9e824d9f853483e6bb185ae2e063505ba model-layer-074.safetensors
85
+ 6007a4f45ba0145498ff52a15e92cd8ca62c876a18729bb7b5e44c88d72cd7cd model-layer-075.safetensors
86
+ 03e2a24e48a4b78e2f0c3808f99f76d48ac2fce865778fee0f7d87998d744222 model-layer-076.safetensors
87
+ 5d23706f97c9b5fbcdf551c808db585b8f391f78ecc343e943f2f2a085d0ac46 model-layer-077.safetensors
88
+ 5448b63a32e394e8cbff5a4737fb50b40fc53c6c3c41305f1a7ee540c4d9a6e3 model-layer-078.safetensors
89
+ 346227a4ea44b6063017739ee38a830319dc10305ccf714734095e27b28064c2 model.safetensors.index.json
90
+ e0b03bead848272a3ae1a335c24ebc55632dea4916bfa8b4bac742fc802e7a3f tier_bitmap.json
91
+ 19e773648cb4e65de8660ea6365e10acca112d42a854923df93db4a6f333a82d tokenizer.json
92
+ 98b1271574f41abf89427ae2dda030d94dc9478f0edc5a8bd240db213c6fd5fc tokenizer_config.json
README.md ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ - zh
5
+ license: mit
6
+ library_name: transformers
7
+ pipeline_tag: text-generation
8
+ base_model: zai-org/GLM-5.2
9
+ tags:
10
+ - glm
11
+ - exl3
12
+ - trellis
13
+ - vllm
14
+ - blackwell
15
+ - mixture-of-experts
16
+ inference: false
17
+ ---
18
+
19
+ # GLM-5.2 EXL3 TR3 3.0 bpw
20
+
21
+ This is a TP4, rank-sliced EXL3 build of
22
+ [zai-org/GLM-5.2](https://huggingface.co/zai-org/GLM-5.2), optimized for
23
+ four NVIDIA Blackwell workstation GPUs. Routed MoE experts in layers 3-78 use
24
+ EXL3 Trellis weights targeting 3.0 bits per weight — as of the **2026-07-25
25
+ update this includes the MTP (layer 78) routed experts**, which were previously
26
+ BF16. Accuracy-sensitive and dense components remain in BF16.
27
+
28
+ The repository payload is 316.5 GB (294.8 GiB) — 15.66 GB smaller than the
29
+ prior BF16-MTP build, because the layer-78 head is now EXL3 tr3. This format requires the
30
+ custom vLLM + Sparkinfer runtime below; it is not a drop-in Transformers model.
31
+ The `config.json` retains ModelOpt/NVFP4 compatibility metadata used by the
32
+ conversion pipeline, but the routed weights are EXL3 and the required launch
33
+ flag is `--quantization exl3`. NVFP4 in the supplied runtime refers to the KV
34
+ cache, not the routed-expert weight format.
35
+
36
+ ## Quantization layout
37
+
38
+ | Component | Storage |
39
+ | --- | --- |
40
+ | Routed MoE experts, layers 3-78 (includes MTP layer 78) | EXL3 Trellis, TP4 rank-sliced, 3.0 bpw target |
41
+ | Dense MLP layers 0-2 | BF16 |
42
+ | Shared-expert MLPs | BF16 |
43
+ | Attention and sparse indexer | BF16 |
44
+ | Embeddings and LM head | BF16 |
45
+ | Norms, router gates, and e-score correction bias | BF16/FP32 source precision |
46
+ | MTP layer 78 — routed experts | **EXL3 Trellis, TP4 rank-sliced, 3.0 bpw target** (2026-07-25) |
47
+ | MTP layer 78 — attention, shared experts, eh_proj, norms | BF16 |
48
+
49
+ The calibration manifest is included as `calibration_manifest.json`. It records
50
+ 12,228 owner-corpus samples across general, legal, coding/agentic, and
51
+ reasoning/termination axes. The model was calibrated at TP8 and packed for TP4.
52
+
53
+ ## Supported runtime
54
+
55
+ The tested runtime is published at
56
+ [verdictai/glm52-exl3-sparkinfer](https://hub.docker.com/r/verdictai/glm52-exl3-sparkinfer):
57
+
58
+ ```text
59
+ verdictai/glm52-exl3-sparkinfer:v26-gg-v20final-scopefix-archkey-vllm5517197-sibe0edca-cu132-sm120a
60
+ ```
61
+
62
+ The supplied scripts pin the immutable registry manifest:
63
+
64
+ ```text
65
+ verdictai/glm52-exl3-sparkinfer:v26-gg-v20final-scopefix-archkey-vllm5517197-sibe0edca-cu132-sm120a@sha256:2bb9e804a283d1da3b7e3425ff87375121285141d0d0a40d3dc09d41bf881a10
66
+ ```
67
+
68
+ It pins:
69
+
70
+ - Gilded Gnosis **v20 final** vLLM `5517197` + EXL3 Trellis (rebased PR #139)
71
+ - Sparkinfer **v20 final** `be0edca` + EXL3 Trellis fused arm (rebased PR #49)
72
+ - CUDA 13.2, PyTorch 2.12, CUTLASS DSL 4.6.0, FlashInfer 801d57a, NCCL 2.30.4, SM120a
73
+ - EXL3 Trellis MoE, B12X sparse MLA, DCP A2A, and MTP speculative decoding
74
+ - NVFP4 DeepSeek-MLA KV cache using calibrated outer scales
75
+
76
+ ### v21 changes (2026-07-25) — MTP layer-78 → EXL3 tr3
77
+
78
+ The MTP (layer 78) routed experts are now EXL3 Trellis rank-sliced (3.0 bpw),
79
+ matching layers 3-77; the BF16 head is retired. This frees ~3.9 GiB/rank of VRAM
80
+ (≈ +66% KV-cache headroom: ~1.13M tokens at util 0.96, **2.16× at 524K ctx**,
81
+ vs ~680K / ~1.3× with the BF16 head).
82
+
83
+ Loading a tr3 MTP layer required two vLLM loader fixes (both in PR #139):
84
+ - `get_draft_quant_config` now hydrates the draft `Exl3Config` with
85
+ `rank_sliced_metadata` (previously only the target model received this call),
86
+ so the MTP experts take the tr3 path instead of stock FusedMoE.
87
+ - `DeepSeekMTP.load_weights` normalizes rank-sliced weight names (strips
88
+ `.rank{r}`, as the target model already does) so experts map to the fused
89
+ `w2_mcg` / `w13_trellis` params instead of KeyError-ing on
90
+ `...routed_experts.w2_rank0.mcg`.
91
+
92
+ **Runtime requirement:** set `VLLM_EXL3_TRELLIS_MIN_M=1` (the compose / server.sh
93
+ default in this repo) so the MTP-N draft's small-m (m=1…N) GEMMs stay inside the
94
+ Trellis cudagraph decode window; the previous default of `4` raises
95
+ `EXL3 eager parity path entered during CUDA graph capture (m=3)`. The prior v20
96
+ image cannot load this checkpoint.
97
+
98
+ Validation (TP4/DCP4/MTP-3): loads clean, Estonia 10/10, LAVD EXACT 5 / NEAR 5 /
99
+ FAIL 0, decode C1/C8 89.7/293.5 tok/s. Full numbers in `RELEASE_TEST_SUITE.md`.
100
+
101
+ ### v20-final rebase (2026-07-25)
102
+
103
+ Rebased onto the **finalized Gilded Gnosis v20 common base**
104
+ `voipmonitor/vllm:gilded-gnosis-v20-vllm5517197-sibe0edca-fi801d57a-cu132-20260725`
105
+ (vLLM `5517197`, Sparkinfer `be0edca`). Per the v20 release note that base packages
106
+ no EXL3/Trellis loader, so EXL3 is enabled by rebasing the EXL3 **source layer**
107
+ onto the pinned stack rather than pointing the base tag at an EXL3 checkpoint.
108
+
109
+ Why this matters here: the finalized base carries the **DCP prefill auto-policy and
110
+ corrected workspace accounting** that resolve the >8k DCP prefill collapse seen in
111
+ earlier v20 candidates. For TP4/DCP4 the policy resolves to query-split 1, full-CKV
112
+ gather 1, top-k owner-merge 1, indexer shards 0, CKV prefetch depth 1, and
113
+ `DCP_PREFILL_WORKSPACE=1` (`VLLM_DCP_PROJECT_BEFORE_MERGE=1` +
114
+ `VLLM_B12X_MLA_DCP_GATHER_IN_WORKSPACE=1`). Those last two flags OOM'd on
115
+ large-context prefill on the pre-final base; the shipped `server.sh` /
116
+ `docker-compose.yml` now set the resolved values explicitly, because this preset
117
+ invokes `vllm serve` directly and therefore bypasses the base launcher that would
118
+ otherwise translate `DCP_*=auto`.
119
+
120
+ Of the 12 runtime overlay files, only `models/deepseek_v2.py` and
121
+ `v1/attention/backends/mla/indexer.py` changed in the finalized base; both were
122
+ re-derived from the v20-final versions with the EXL3 edits replayed on top, so the
123
+ new DCP/indexer work is preserved rather than overwritten.
124
+
125
+ Quality re-verified on this image (no regression): **Estonia c2 x5 = 5/5 pass,
126
+ 0 fail**; **LAVD c5 x5 = 3 EXACT / 2 NEAR / 0 FAIL**, correct rate 1.00 on both.
127
+ Runtime reports `nccl==2.30.4`, EXL3 planned Trellis `m=1..32 block_m=8 /
128
+ prefill block_m=64`, native CKV prefetch depth 1 with 2 workspace slots, and a
129
+ 998,656-token KV cache (1.90x at 524,288).
130
+
131
+ The KV figure is ~1 GiB below the earlier 1,115,904 tokens (2.13x) on purpose: the
132
+ rank-sliced runtime is now scoped per model, so the MTP draft layer allocates its own
133
+ Trellis/prefill arena instead of sharing the target's. Losing that capacity is the
134
+ intended cost of target/draft scratch isolation, and it is also why the scope is
135
+ per-model rather than per-layer -- the prefill arena is ~1054 MiB, so per-layer
136
+ ownership would need tens of GiB per rank across 75+ layers.
137
+
138
+ ### v20 changes (Gilded Gnosis v20 base)
139
+
140
+ This release rebases the EXL3 Trellis backend onto the Gilded Gnosis **v20**
141
+ canonical heads (vLLM `6722c1d`, Sparkinfer `1a88b389`). The v20 base supplies
142
+ the upstreamed MTP/DCP correctness fixes — head-major cross-rank BMM (vLLM #147),
143
+ MTP verifier-decode dispatch (vLLM #164), and graph-resource isolation (vLLM
144
+ #149). On top of that base this image adds (vLLM PR #139 / Sparkinfer PR #49,
145
+ both rebased onto v20):
146
+
147
+ - **EXL3 Trellis MoE backend** for rank-sliced GLM/DeepSeek routed experts.
148
+ - **MTP tool-call + DSA-crash fix** — the structured-output grammar advances
149
+ from the authoritative step delta so tool calling engages under speculative
150
+ decoding, and `has_indexer` is derived from `index_k` so MTP draft steps that
151
+ skip top-k no longer trip the fused-norm-rope assertion.
152
+ - **Dual-plan Trellis prefill** — prefill batches route through the planned
153
+ Trellis MoE.
154
+ - **SM120 + B12X flattening fix** — MTP `next_n>2` uses the native `(B, next_n)`
155
+ sparse-indexer path instead of the DeepGEMM `next_n<=2` flatten fallback, which
156
+ had corrupted MTP-3 code generation.
157
+
158
+ Validated on 4x RTX PRO 6000 Blackwell 96 GB (TP4/DCP4, MTP-3 greedy, NVFP4 KV,
159
+ FULL_AND_PIECEWISE cudagraphs):
160
+
161
+ - **Code generation** — the previously reported ~50% syntax-error rate under
162
+ MTP-3 is eliminated; generated Python/HTML is 94–100% syntactically valid
163
+ across runs. The rare remaining edge is fp8-KV/DCP floating-point
164
+ nondeterminism, not the prior systematic corruption.
165
+ - **LAVD** long-context retrieval (r10/c5, temp 0): **10/10 (6 exact, 4 near,
166
+ 0 fail)** — up from 8/10 (2 fails) on the prior base. The v20 canonical MTP
167
+ fixes plus the flattening fix drive the fail count from 2 to 0.
168
+
169
+ Asynchronous scheduling remains disabled as a correctness guard for this
170
+ DCP4/MTP path; do not enable it on this release.
171
+
172
+ ## Quick start
173
+
174
+ Install Docker Engine, Docker Compose v2, the NVIDIA Container Toolkit, and the
175
+ Hugging Face CLI. Then download the model and start the server:
176
+
177
+ ```bash
178
+ hf download brandonmusic/GLM-5.2-EXL3-TR3-3.0bpw \
179
+ --local-dir "$HOME/models/GLM-5.2-EXL3-TR3-3.0bpw"
180
+
181
+ cd "$HOME/models/GLM-5.2-EXL3-TR3-3.0bpw"
182
+ chmod +x server.sh
183
+ ./server.sh start
184
+ ./server.sh logs
185
+ ```
186
+
187
+ The OpenAI-compatible endpoint is available locally at
188
+ `http://localhost:8000/v1`. Here, `localhost` always means the machine on
189
+ which the downloader starts this model; it does not refer to the model
190
+ publisher's machine.
191
+
192
+ ```bash
193
+ curl http://localhost:8000/v1/chat/completions \
194
+ -H 'Content-Type: application/json' \
195
+ -d '{
196
+ "model": "GLM-5.2-EXL3-TR3-3.0bpw",
197
+ "messages": [{"role": "user", "content": "What is 2 + 2?"}],
198
+ "temperature": 0,
199
+ "max_tokens": 128
200
+ }'
201
+ ```
202
+
203
+ Useful controls:
204
+
205
+ ```bash
206
+ ./server.sh status
207
+ ./server.sh logs
208
+ ./server.sh restart
209
+ ./server.sh stop
210
+ ```
211
+
212
+ ## Direct Compose use
213
+
214
+ `server.sh` exports the defaults and invokes the included
215
+ `docker-compose.yml`. To run Compose directly, set the model and cache paths:
216
+
217
+ ```bash
218
+ export MODEL_DIR="$HOME/models/GLM-5.2-EXL3-TR3-3.0bpw"
219
+ export CACHE_DIR="$HOME/.cache/glm52-exl3-sparkinfer"
220
+ docker compose pull
221
+ docker compose up -d
222
+ docker compose logs --tail 100 -f glm52
223
+ ```
224
+
225
+ The defaults can be overridden without editing the files:
226
+
227
+ | Variable | Default | Purpose |
228
+ | --- | --- | --- |
229
+ | `MODEL_DIR` | Directory containing `server.sh` | Model mount |
230
+ | `CACHE_DIR` | `~/.cache/glm52-exl3-sparkinfer` | Persistent JIT cache |
231
+ | `PORT` | `8000` | Host API port |
232
+ | `BIND_ADDRESS` | `127.0.0.1` | Local-only host binding |
233
+ | `CUDA_VISIBLE_DEVICES` | `3,1,2,0` | Physical GPU to TP-rank order |
234
+ | `GPU_MEMORY_UTILIZATION` | `0.96` | vLLM memory reservation |
235
+ | `MAX_MODEL_LEN` | `262144` | Per-request context cap |
236
+ | `MTP_TOKENS` | `3` | Validated speculative-token count (MTP-3) |
237
+ | `ENABLE_ASYNC_SCHEDULING` | `0` | Required correctness guard |
238
+ | `NUM_GPU_BLOCKS_OVERRIDE` | `1024` | 262,144 logical KV tokens at DCP4 |
239
+
240
+ The tested GPU order intentionally keeps physical GPU 3 away from TP rank 3.
241
+ On another host, set `CUDA_VISIBLE_DEVICES=0,1,2,3` or use the order appropriate
242
+ for that machine.
243
+
244
+ The supplied Compose file binds only to loopback by default, so it does not
245
+ publish the API to the LAN or internet.
246
+
247
+ ## Runtime validation
248
+
249
+ The exact published image completed all 81 model-shard loads, EXL3
250
+ initialization, Sparkinfer PCIe collective initialization, NVFP4 KV allocation,
251
+ and full plus piecewise CUDA graph capture. The v20 base has a larger runtime
252
+ footprint, so the release preset allocates 262,144 logical KV-cache tokens:
253
+ 1,024 blocks x 64 tokens x DCP4, with 65,536 tokens local to each DCP rank. The
254
+ configured per-request context cap is also 262,144. A GPU 0 with no other
255
+ resident processes supports a larger KV pool and context (raise
256
+ `NUM_GPU_BLOCKS_OVERRIDE` / `MAX_MODEL_LEN` within the KV capacity reported at
257
+ startup).
258
+
259
+ Quality was validated with the release serving configuration (MTP-3, TP4/DCP4,
260
+ concurrency 5):
261
+
262
+ | Evaluation | v20 result | Prior base |
263
+ | --- | ---: | ---: |
264
+ | LAVD r10/c5 | 10/10 (6 exact, 4 near, 0 fail) | 8/10 (2 fail) |
265
+ | Code generation (Python/HTML, temp 0) | 94–100% valid | ~50% (reported bug) |
266
+
267
+ The LAVD fail count dropping 2 → 0 reflects the v20 canonical MTP fixes plus the
268
+ SM120+B12X flattening fix. Exact/near split varies run to run (fp8-KV/DCP
269
+ nondeterminism); the 0-fail result is the stable signal.
270
+
271
+ The following prefill, decode, and KLD tables are indicative reference measured
272
+ on the prior base; the v20 image is validated for correctness by the results
273
+ above.
274
+
275
+ Cold standalone prefill results:
276
+
277
+ | Requested context | Prompt tokens | TTFT | Client tok/s | Server tok/s |
278
+ | ---: | ---: | ---: | ---: | ---: |
279
+ | 8K | 8,201 | 5.46 s | 1,502 | 1,507 |
280
+ | 64K | 64,512 | 51.64 s | 1,249 | 1,252 |
281
+ | 128K | 128,881 | 109.00 s | 1,182 | 1,185 |
282
+
283
+ Sustained decode used 20-second steady-state cells after warmup, zero input
284
+ context, and continuous OpenAI stream usage:
285
+
286
+ | Concurrency | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
287
+ | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
288
+ | Aggregate tok/s | 48.9 | 112.9 | 154.0 | 188.2 | 218.2 | 239.4 | 253.9 | 266.8 |
289
+ | Per-request tok/s | 48.9 | 56.4 | 51.3 | 47.0 | 43.6 | 39.9 | 36.3 | 33.3 |
290
+
291
+ A separate 30-second C1 run measured 48.5 tok/s. No decode cell was underfilled,
292
+ capacity-limited, or errored.
293
+
294
+ Five-run, 2,047-position DCP4 KLD against the same verified BF16 reference:
295
+
296
+ | KV cache | Mean KLD | Sample SD | Min | Max |
297
+ | --- | ---: | ---: | ---: | ---: |
298
+ | NVFP4 DeepSeek MLA | 0.1124021 | 0.0025948 | 0.1086084 | 0.1156108 |
299
+ | FP8 | 0.1036666 | 0.0018374 | 0.1016535 | 0.1066077 |
300
+
301
+ Full methodology, raw JSON, and copyable Rich TUI logs are in
302
+ [benchmarks/2026-07-22](benchmarks/2026-07-22/README.md).
303
+
304
+ ## Source
305
+
306
+ - [vLLM EXL3 integration PR](https://github.com/local-inference-lab/vllm/pull/139)
307
+ - [Sparkinfer EXL3 Trellis PR](https://github.com/local-inference-lab/b12x/pull/49)
308
+ - [Upstream GLM-5.2 model](https://huggingface.co/zai-org/GLM-5.2)
309
+ - [GLM-5 technical report](https://arxiv.org/abs/2602.15763)
310
+
311
+ ## License
312
+
313
+ The model and this derivative are released under the MIT license. See
314
+ `LICENSE` and the upstream model card for attribution and usage terms.
RELEASE_TEST_SUITE.md ADDED
The diff for this file is too large to render. See raw diff
 
benchmarks/2026-07-22/README.md ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GLM-5.2 EXL3 release validation
2
+
3
+ These artifacts were collected on four RTX PRO 6000 Blackwell 96 GB GPUs with
4
+ the final release image, TP4 + DCP4 A2A, MTP1 greedy, asynchronous scheduling
5
+ disabled, and NVFP4 DeepSeek-MLA KV cache unless a row says otherwise.
6
+
7
+ Tested local image ID:
8
+
9
+ ```text
10
+ sha256:bfd6d6670db37b04e9cbef7375722e3f71d66745abf1714c05cc5b71fd126715
11
+ ```
12
+
13
+ Published immutable image:
14
+
15
+ ```text
16
+ verdictai/glm52-exl3-sparkinfer:v2-gg-1043999ab-spi879ca0ad-cu132-sm120a@sha256:bfd6d6670db37b04e9cbef7375722e3f71d66745abf1714c05cc5b71fd126715
17
+ ```
18
+
19
+ Source revisions:
20
+
21
+ - Gilded Gnosis vLLM: `1043999ab5f13350aaacc188e713d6c0928387e9`
22
+ - Sparkinfer: `879ca0ad878958a0fbb1d6a1393c1bb40ec54790`
23
+
24
+ The vLLM banner in the logs retains the base package's `g60c82d972` version
25
+ string. The `ai.verdict.vllm.revision` and `ai.verdict.sparkinfer.revision` OCI
26
+ labels in `image-inspect.json` identify the source actually installed in the
27
+ tested image.
28
+
29
+ ## Correctness
30
+
31
+ | Evaluation | Result | Concurrency | Max output | Cap hits |
32
+ | --- | ---: | ---: | ---: | ---: |
33
+ | LAVD pass 1 | 10/10 (5 exact, 5 near) | 5 | 20,000 | 0 |
34
+ | LAVD pass 2 | 10/10 (3 exact, 7 near) | 5 | 20,000 | 0 |
35
+ | Estonia | 5/5 pass | 5 | 5,000 | 0 |
36
+
37
+ The two LAVD passes are independent full runs, for a combined 20/20 scorer
38
+ pass. `near` is a passing LAVD score, not a failure.
39
+ LAVD used temperature 0 and repetition penalty 1.15; Estonia used temperature
40
+ 0 and repetition penalty 1.25.
41
+
42
+ ## KV-cache KLD
43
+
44
+ Each KLD figure is the mean of five independent runs against the same verified
45
+ BF16 reference-logit artifact. Every run evaluated all 2,047 positions from a
46
+ 2,048-token sample with TP4 + DCP4 A2A, the 78-layer sparse-index pattern,
47
+ asynchronous scheduling disabled, and eager execution. KLD isolates model and
48
+ KV-cache drift; the serving evaluations above validate MTP1 and CUDA graphs.
49
+ The reference artifact SHA256 is
50
+ `87f992a689c054a0548a4b3863da6c809f9239beacd5786d0401e45904fec063`.
51
+
52
+ | KV cache | Mean KLD | Sample SD | Min | Max | Runs |
53
+ | --- | ---: | ---: | ---: | ---: | ---: |
54
+ | NVFP4 DeepSeek MLA | 0.1124021 | 0.0025948 | 0.1086084 | 0.1156108 | 5 |
55
+ | FP8 | 0.1036666 | 0.0018374 | 0.1016535 | 0.1066077 | 5 |
56
+
57
+ ## Prefill
58
+
59
+ Cold standalone prefill uses `prompt_tokens / TTFT`; the client figure is the
60
+ headline and the uncontaminated vLLM Prometheus counter is shown as validation.
61
+
62
+ | Requested context | Prompt tokens | TTFT | Client tok/s | Server tok/s |
63
+ | ---: | ---: | ---: | ---: | ---: |
64
+ | 8K | 8,201 | 5.46 s | 1,502 | 1,507 |
65
+ | 64K | 64,512 | 51.64 s | 1,249 | 1,252 |
66
+ | 128K | 128,881 | 109.00 s | 1,182 | 1,185 |
67
+
68
+ ## Sustained decode
69
+
70
+ These are 20-second steady-state cells after warmup, at zero input context and
71
+ with EOS ignored. Aggregate throughput comes from continuous OpenAI stream
72
+ usage. There were no request errors, underfilled cells, or capacity-limited
73
+ cells. A separate 30-second C1 run measured 48.5 tok/s.
74
+
75
+ | Concurrency | Aggregate tok/s | Per-request tok/s |
76
+ | ---: | ---: | ---: |
77
+ | 1 | 48.9 | 48.9 |
78
+ | 2 | 112.9 | 56.4 |
79
+ | 3 | 154.0 | 51.3 |
80
+ | 4 | 188.2 | 47.0 |
81
+ | 5 | 218.2 | 43.6 |
82
+ | 6 | 239.4 | 39.9 |
83
+ | 7 | 253.9 | 36.3 |
84
+ | 8 | 266.8 | 33.3 |
85
+
86
+ The release preset allocates 524,288 logical KV-cache tokens: 2,048 blocks x
87
+ 64 tokens x DCP4, with 131,072 tokens local to each DCP rank. This is the
88
+ validated allocation and configured per-request context cap.
89
+
90
+ ## Raw artifacts
91
+
92
+ - [C1-C8 decode JSON](decode-c1-c8.json) and [Rich TUI log](decode-c1-c8.log)
93
+ - [Dedicated C1 JSON](decode-c1-dedicated.json) and [Rich TUI log](decode-c1-dedicated.log)
94
+ - [Prefill JSON](prefill-8k-64k-128k.json) and [Rich TUI log](prefill-8k-64k-128k.log)
95
+ - [LAVD pass 1 JSON](lavd-c5-r10.json) and [Rich TUI log](lavd-c5-r10.log)
96
+ - [LAVD pass 2 JSON](lavd-c5-r10-pass2.json) and [Rich TUI log](lavd-c5-r10-pass2.log)
97
+ - [Estonia JSON](estonia-c5-r5.json) and [Rich TUI log](estonia-c5-r5.log)
98
+ - [NVFP4 KLD summary](kld-nvfp4-dcp4-summary.json)
99
+ - [FP8 KLD summary](kld-fp8-dcp4-summary.json)
100
+ - [Exact tested-image inspection](image-inspect.json)
101
+
102
+ At C8, the hottest observed GPU reached 90 C. NVIDIA hardware and software
103
+ thermal-slowdown flags were inactive during the run.
benchmarks/2026-07-22/decode-c1-c8.json ADDED
@@ -0,0 +1,1469 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "metadata": {
3
+ "version": "0.4.29",
4
+ "engine": "vllm",
5
+ "model": "GLM-5.2-EXL3-TR3-3.0bpw",
6
+ "server": "127.0.0.1:8000",
7
+ "timestamp": "2026-07-22T05:40:20.743450",
8
+ "decode_mode": "duration",
9
+ "primary_decode_layer": "sustained_decode",
10
+ "duration_per_test": 20.0,
11
+ "request_count": 0,
12
+ "warmup_request_count": 0,
13
+ "run_burst": false,
14
+ "prefill_mode": "skipped",
15
+ "standalone_prefill": false,
16
+ "prefill_only": false,
17
+ "skip_prefill": true,
18
+ "burst_e2e_status": "not_run_use_--run-burst",
19
+ "burst_request_count": 0,
20
+ "burst_warmup_request_count": 0,
21
+ "burst_requests_per_concurrency": 5,
22
+ "decode_warmup_seconds": 3.0,
23
+ "decode_warmup_context": 0,
24
+ "decode_warmup_concurrency": 1,
25
+ "cell_warmup_timeout_seconds": 0.0,
26
+ "cell_warmup_timeout_policy": "<=32k:60s,64k:120s,>=128k:180s when override is 0",
27
+ "show_capacity_limited_values": false,
28
+ "max_tokens": 8192,
29
+ "temperature": 0.0,
30
+ "ignore_eos": true,
31
+ "max_total_tokens": 524288,
32
+ "dcp_size": 0,
33
+ "metrics_available": true,
34
+ "metrics_warning": "",
35
+ "concurrency_levels": [
36
+ 1,
37
+ 2,
38
+ 3,
39
+ 4,
40
+ 5,
41
+ 6,
42
+ 7,
43
+ 8
44
+ ],
45
+ "context_lengths": [
46
+ 0
47
+ ],
48
+ "startup_diagnostics_available": true,
49
+ "nvidia_p2p_override_effective": true,
50
+ "p2pmark_status": "not_run",
51
+ "amd_fabric_status": "not_run"
52
+ },
53
+ "startup_diagnostics": {
54
+ "version": "0.4.29",
55
+ "server_url": "http://127.0.0.1:8000",
56
+ "hostname": "pop-os",
57
+ "uname": "Linux pop-os 6.18.7-76061807-generic #202601231045~1769703228~24.04~cb87b5b SMP PREEMPT_DYNAMIC Thu J x86_64 x86_64 x86_64 GNU/Linux",
58
+ "env": {},
59
+ "args": {
60
+ "concurrency": "1,2,3,4,5,6,7,8",
61
+ "contexts": "0",
62
+ "max_tokens": 8192,
63
+ "duration": 20.0,
64
+ "request_count": 0,
65
+ "run_burst": false,
66
+ "standalone_prefill": false,
67
+ "prefill_only": false,
68
+ "skip_prefill": true,
69
+ "prefill_contexts": "8k,64k,128k",
70
+ "prefill_metric": "client",
71
+ "dcp_size": 0,
72
+ "kv_budget": 0
73
+ },
74
+ "nvidia_p2p_override": {
75
+ "effective": true,
76
+ "configured": true,
77
+ "params_path": "/proc/driver/nvidia/params",
78
+ "params_available": true,
79
+ "modprobe_path": "/etc/modprobe.d/nvidia-p2p-override.conf",
80
+ "modprobe_available": true,
81
+ "runtime": {
82
+ "ForceP2P": "0x11",
83
+ "RMForceP2PType": "1",
84
+ "RMPcieP2PType": "2",
85
+ "GrdmaPciTopoCheckOverride": "1",
86
+ "EnableResizableBar": "1",
87
+ "DmaRemapPeerMmio": "1"
88
+ },
89
+ "expected": {
90
+ "ForceP2P": "0x11",
91
+ "RMForceP2PType": "1",
92
+ "RMPcieP2PType": "2",
93
+ "GrdmaPciTopoCheckOverride": "1",
94
+ "EnableResizableBar": "1"
95
+ },
96
+ "missing": [],
97
+ "mismatched": {},
98
+ "registry_dwords": "ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1",
99
+ "suggested_modprobe_line": "options nvidia NVreg_RegistryDwords=\"ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1\"",
100
+ "suggested_reload": "stop GPU workloads, then reload NVIDIA modules or reboot; the modprobe file alone is not enough until the nvidia module is reloaded"
101
+ },
102
+ "p2pmark": {
103
+ "status": "not_run"
104
+ },
105
+ "amd_fabric": {
106
+ "status": "not_run"
107
+ },
108
+ "nvidia_smi_query": {
109
+ "cmd": [
110
+ "nvidia-smi",
111
+ "--query-gpu=index,name,driver_version,pci.bus_id,pcie.link.gen.current,pcie.link.width.current,power.limit",
112
+ "--format=csv,noheader,nounits"
113
+ ],
114
+ "returncode": 0,
115
+ "stdout": "0, NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition, 595.58.03, 00000000:01:00.0, 5, 16, 300.00\n1, NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 595.58.03, 00000000:21:00.0, 5, 16, 300.00\n2, NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition, 595.58.03, 00000000:81:00.0, 5, 16, 300.00\n3, NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 595.58.03, 00000000:C1:00.0, 5, 16, 300.00",
116
+ "stderr": ""
117
+ },
118
+ "nvidia_smi_topo": {
119
+ "cmd": [
120
+ "nvidia-smi",
121
+ "topo",
122
+ "-m"
123
+ ],
124
+ "returncode": 0,
125
+ "stdout": "\u001b[4mGPU0\tGPU1\tGPU2\tGPU3\tCPU Affinity\tNUMA Affinity\tGPU NUMA ID\u001b[0m\nGPU0\t X \tNODE\tNODE\tNODE\t0-47\t0\t\tN/A\nGPU1\tNODE\t X \tNODE\tNODE\t0-47\t0\t\tN/A\nGPU2\tNODE\tNODE\t X \tNODE\t0-47\t0\t\tN/A\nGPU3\tNODE\tNODE\tNODE\t X \t0-47\t0\t\tN/A\n\nLegend:\n\n X = Self\n SYS = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI)\n NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node\n PHB = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU)\n PXB = Connection traversing multiple PCIe bridges (without traversing the PCIe Host Bridge)\n PIX = Connection traversing at most a single PCIe bridge\n NV# = Connection traversing a bonded set of # NVLinks",
126
+ "stderr": ""
127
+ }
128
+ },
129
+ "nvidia_p2p_override": {
130
+ "effective": true,
131
+ "configured": true,
132
+ "params_path": "/proc/driver/nvidia/params",
133
+ "params_available": true,
134
+ "modprobe_path": "/etc/modprobe.d/nvidia-p2p-override.conf",
135
+ "modprobe_available": true,
136
+ "runtime": {
137
+ "ForceP2P": "0x11",
138
+ "RMForceP2PType": "1",
139
+ "RMPcieP2PType": "2",
140
+ "GrdmaPciTopoCheckOverride": "1",
141
+ "EnableResizableBar": "1",
142
+ "DmaRemapPeerMmio": "1"
143
+ },
144
+ "expected": {
145
+ "ForceP2P": "0x11",
146
+ "RMForceP2PType": "1",
147
+ "RMPcieP2PType": "2",
148
+ "GrdmaPciTopoCheckOverride": "1",
149
+ "EnableResizableBar": "1"
150
+ },
151
+ "missing": [],
152
+ "mismatched": {},
153
+ "registry_dwords": "ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1",
154
+ "suggested_modprobe_line": "options nvidia NVreg_RegistryDwords=\"ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1\"",
155
+ "suggested_reload": "stop GPU workloads, then reload NVIDIA modules or reboot; the modprobe file alone is not enough until the nvidia module is reloaded"
156
+ },
157
+ "p2pmark": {
158
+ "status": "not_run"
159
+ },
160
+ "amd_fabric": {
161
+ "status": "not_run"
162
+ },
163
+ "hardware_run_summary": {
164
+ "samples": 96,
165
+ "duration_seconds": 229.891,
166
+ "gpu_count": 4,
167
+ "cpu_util_avg_pct": 12.38,
168
+ "cpu_temp_max_c": 76.25,
169
+ "gpu_util_avg_pct": 92.52,
170
+ "gpu_util_max_pct": 100.0,
171
+ "mem_util_avg_pct": 39.27,
172
+ "mem_util_max_pct": 53.0,
173
+ "temp_avg_c": 72.92,
174
+ "temp_max_c": 90.0,
175
+ "power_total_avg_w": 1037.72,
176
+ "power_total_max_w": 1127.5,
177
+ "power_limit_total_w": 1200.0,
178
+ "vram_used_avg_mb": 381281.18,
179
+ "vram_used_max_mb": 381297.0,
180
+ "vram_total_mb": 391548.0,
181
+ "vram_used_avg_pct": 97.38,
182
+ "vram_used_max_pct": 97.38,
183
+ "pcie_rx_avg_mb_s": 15693.94,
184
+ "pcie_rx_max_mb_s": 52452.0,
185
+ "pcie_tx_avg_mb_s": 15608.96,
186
+ "pcie_tx_max_mb_s": 50328.0
187
+ },
188
+ "event_log": [
189
+ "05:36:28 benchmark start engine=vllm",
190
+ "05:36:28 startup server=http://127.0.0.1:8000 model=GLM-5.2-EXL3-TR3-3.0bpw",
191
+ "05:36:28 startup decode concurrency=1,2,3,4,5,6,7,8 contexts=0",
192
+ "05:36:28 startup NVIDIA P2P override: enabled: runtime NVIDIA P2P override matches expected RegistryDwords",
193
+ "05:36:28 startup engine vLLM 0.17.0rc1.dev4499+g60c82d972 models=['GLM-5.2-EXL3-TR3-3.0bpw']",
194
+ "05:36:28 startup KV cache budget from vLLM metrics: 524,288 tokens (2048 blocks x 64; local 131,072 \u00d7 CP 4; CP source: local process)",
195
+ "05:36:28 startup model context length: 524,288 tokens",
196
+ "05:36:28 startup prefill tests: skipped",
197
+ "05:36:28 startup startup preparation done",
198
+ "05:36:28 hardware monitor interval=2s",
199
+ "05:36:28 decode warmup start",
200
+ "05:36:29 decode warmup start C=1 ctx=0 3s",
201
+ "05:36:29 cell start C=1 ctx=0",
202
+ "05:36:35 ready C=1 ctx=0 running_reqs=1/1, queue_reqs=0, active_streams=1/1, stable=3.0s",
203
+ "05:36:38 cell done C=1 ctx=0 48.2 tok/s",
204
+ "05:36:38 decode warmup done C=1 ctx=0",
205
+ "05:36:40 cell start C=1 ctx=0",
206
+ "05:36:45 ready C=1 ctx=0 running_reqs=1/1, queue_reqs=0, active_streams=1/1, stable=3.0s",
207
+ "05:37:05 cell done C=1 ctx=0 48.9 tok/s",
208
+ "05:37:07 cell start C=2 ctx=0",
209
+ "05:37:13 ready C=2 ctx=0 running_reqs=2/2, queue_reqs=0, active_streams=2/2, stable=3.0s",
210
+ "05:37:33 cell done C=2 ctx=0 112.9 tok/s",
211
+ "05:37:35 cell start C=3 ctx=0",
212
+ "05:37:40 ready C=3 ctx=0 running_reqs=3/3, queue_reqs=0, active_streams=3/3, stable=3.0s",
213
+ "05:38:00 cell done C=3 ctx=0 154.0 tok/s",
214
+ "05:38:02 cell start C=4 ctx=0",
215
+ "05:38:08 ready C=4 ctx=0 running_reqs=4/4, queue_reqs=0, active_streams=4/4, stable=3.0s",
216
+ "05:38:28 cell done C=4 ctx=0 188.2 tok/s",
217
+ "05:38:30 cell start C=5 ctx=0",
218
+ "05:38:35 ready C=5 ctx=0 running_reqs=5/5, queue_reqs=0, active_streams=5/5, stable=3.0s",
219
+ "05:38:55 cell done C=5 ctx=0 218.2 tok/s",
220
+ "05:38:58 cell start C=6 ctx=0",
221
+ "05:39:03 ready C=6 ctx=0 running_reqs=6/6, queue_reqs=0, active_streams=6/6, stable=3.0s",
222
+ "05:39:23 cell done C=6 ctx=0 239.4 tok/s",
223
+ "05:39:25 cell start C=7 ctx=0",
224
+ "05:39:31 ready C=7 ctx=0 running_reqs=7/7, queue_reqs=0, active_streams=7/7, stable=3.0s",
225
+ "05:39:51 cell done C=7 ctx=0 253.9 tok/s",
226
+ "05:39:53 cell start C=8 ctx=0",
227
+ "05:39:58 ready C=8 ctx=0 running_reqs=8/8, queue_reqs=0, active_streams=8/8, stable=3.0s",
228
+ "05:40:18 cell done C=8 ctx=0 266.8 tok/s"
229
+ ],
230
+ "prefill": {},
231
+ "results": [
232
+ {
233
+ "concurrency": 1,
234
+ "context_tokens": 0,
235
+ "benchmark_mode": "duration",
236
+ "request_count_target": 0,
237
+ "warmup_request_count": 0,
238
+ "measurement_seconds": 19.976693,
239
+ "measurement_wall_seconds": 20.000807,
240
+ "client_output_tokens": 977,
241
+ "server_output_tokens": 977,
242
+ "aggregate_source": "openai_continuous_usage",
243
+ "aggregate_tps": 48.90699346650318,
244
+ "per_request_avg_tps": 48.90699346650318,
245
+ "ttft_avg": 0.17986271699919598,
246
+ "ttft_p50": 0.17986271699919598,
247
+ "ttft_p90": 0.17986271699919598,
248
+ "ttft_p99": 0.17986271699919598,
249
+ "time_to_second_token_avg": 0.038283893998595886,
250
+ "time_to_second_token_p50": 0.038283893998595886,
251
+ "time_to_second_token_p90": 0.038283893998595886,
252
+ "time_to_second_token_p99": 0.038283893998595886,
253
+ "request_latency_avg": 0.0,
254
+ "request_latency_p50": 0.0,
255
+ "request_latency_p90": 0.0,
256
+ "request_latency_p99": 0.0,
257
+ "inter_token_latency_avg": 0.020280784702959735,
258
+ "inter_token_latency_p50": 0.020280784702959735,
259
+ "inter_token_latency_p90": 0.020280784702959735,
260
+ "inter_token_latency_p99": 0.020280784702959735,
261
+ "output_tps_per_user_avg": 49.30775680755894,
262
+ "output_tps_per_user_p50": 49.30775680755894,
263
+ "output_tps_per_user_p90": 49.30775680755894,
264
+ "output_tps_per_user_p99": 49.30775680755894,
265
+ "e2e_output_tps_per_user_avg": 0.0,
266
+ "e2e_output_tps_per_user_p50": 0.0,
267
+ "e2e_output_tps_per_user_p90": 0.0,
268
+ "e2e_output_tps_per_user_p99": 0.0,
269
+ "chunk_inter_token_latency_avg": 0.03809127833683716,
270
+ "chunk_inter_token_latency_p50": 0.03809127833683716,
271
+ "chunk_inter_token_latency_p90": 0.03809127833683716,
272
+ "chunk_inter_token_latency_p99": 0.03809127833683716,
273
+ "input_seq_len_avg": 78.0,
274
+ "output_seq_len_avg": 1250.0,
275
+ "output_seq_len_p50": 1250.0,
276
+ "output_seq_len_p90": 1250.0,
277
+ "output_seq_len_p99": 1250.0,
278
+ "request_count": 1,
279
+ "completed_request_count": 0,
280
+ "request_samples": [
281
+ {
282
+ "ttft": 0.17986271699919598,
283
+ "time_to_second_token": 0.038283893998595886,
284
+ "latency": 0.0,
285
+ "inter_token_latency_avg": 0.020280784702959735,
286
+ "chunk_inter_token_latency_avg": 0.03809127833683716,
287
+ "input_tokens": 78,
288
+ "output_tokens": 1250,
289
+ "output_tps_per_user": 49.30775680755894,
290
+ "e2e_output_tps_per_user": 0.0,
291
+ "completed": false
292
+ }
293
+ ],
294
+ "total_tokens": 977,
295
+ "wall_time": 25.55021575799765,
296
+ "num_completed": 1,
297
+ "num_errors": 0,
298
+ "server_gen_throughput": 48.83638488717953,
299
+ "server_utilization": 0.002931118710307823,
300
+ "server_spec_accept_rate": 1.0,
301
+ "server_spec_accept_length": 0.0,
302
+ "avg_running_reqs": 1,
303
+ "max_running_reqs": 1,
304
+ "effective_concurrency": 1,
305
+ "avg_queue_reqs": 0,
306
+ "max_queue_reqs": 0,
307
+ "queue_fraction": 0.0,
308
+ "underfilled": false,
309
+ "warmup_timed_out": false,
310
+ "warmup_duration": 5.534,
311
+ "ready_reason": "running_reqs=1/1, queue_reqs=0, active_streams=1/1, stable=3.0s",
312
+ "timeout_reason": "",
313
+ "capacity_limited": false,
314
+ "hardware_summary": {
315
+ "samples": 8,
316
+ "duration_seconds": 16.895,
317
+ "gpu_count": 4,
318
+ "cpu_util_avg_pct": 12.64,
319
+ "cpu_temp_max_c": 76.0,
320
+ "gpu_util_avg_pct": 99.22,
321
+ "gpu_util_max_pct": 100.0,
322
+ "mem_util_avg_pct": 34.81,
323
+ "mem_util_max_pct": 39.0,
324
+ "temp_avg_c": 70.62,
325
+ "temp_max_c": 84.0,
326
+ "power_total_avg_w": 1025.82,
327
+ "power_total_max_w": 1032.7,
328
+ "power_limit_total_w": 1200.0,
329
+ "vram_used_avg_mb": 381281.5,
330
+ "vram_used_max_mb": 381282.0,
331
+ "vram_total_mb": 391548.0,
332
+ "vram_used_avg_pct": 97.38,
333
+ "vram_used_max_pct": 97.38,
334
+ "pcie_rx_avg_mb_s": 4783.38,
335
+ "pcie_rx_max_mb_s": 4887.0,
336
+ "pcie_tx_avg_mb_s": 4729.25,
337
+ "pcie_tx_max_mb_s": 4937.0
338
+ }
339
+ },
340
+ {
341
+ "concurrency": 2,
342
+ "context_tokens": 0,
343
+ "benchmark_mode": "duration",
344
+ "request_count_target": 0,
345
+ "warmup_request_count": 0,
346
+ "measurement_seconds": 19.982984,
347
+ "measurement_wall_seconds": 20.002096,
348
+ "client_output_tokens": 2256,
349
+ "server_output_tokens": 2256,
350
+ "aggregate_source": "openai_continuous_usage",
351
+ "aggregate_tps": 112.8960533960185,
352
+ "per_request_avg_tps": 56.44802669800925,
353
+ "ttft_avg": 0.2745096079997893,
354
+ "ttft_p50": 0.2745096079997893,
355
+ "ttft_p90": 0.3482390583980305,
356
+ "ttft_p99": 0.36482818473763473,
357
+ "time_to_second_token_avg": 0.10898957750032423,
358
+ "time_to_second_token_p50": 0.10898957750032423,
359
+ "time_to_second_token_p90": 0.1693450467006187,
360
+ "time_to_second_token_p99": 0.18292502727068494,
361
+ "request_latency_avg": 0.0,
362
+ "request_latency_p50": 0.0,
363
+ "request_latency_p90": 0.0,
364
+ "request_latency_p99": 0.0,
365
+ "inter_token_latency_avg": 0.017561321544739904,
366
+ "inter_token_latency_p50": 0.017561321544739904,
367
+ "inter_token_latency_p90": 0.017622366905861796,
368
+ "inter_token_latency_p99": 0.01763610211211422,
369
+ "output_tps_per_user_avg": 56.94439784609684,
370
+ "output_tps_per_user_p50": 56.94439784609684,
371
+ "output_tps_per_user_p90": 57.14234373083722,
372
+ "output_tps_per_user_p99": 57.1868815549038,
373
+ "e2e_output_tps_per_user_avg": 0.0,
374
+ "e2e_output_tps_per_user_p50": 0.0,
375
+ "e2e_output_tps_per_user_p90": 0.0,
376
+ "e2e_output_tps_per_user_p99": 0.0,
377
+ "chunk_inter_token_latency_avg": 0.0335908112100433,
378
+ "chunk_inter_token_latency_p50": 0.0335908112100433,
379
+ "chunk_inter_token_latency_p90": 0.033599633338025736,
380
+ "chunk_inter_token_latency_p99": 0.033601618316821784,
381
+ "input_seq_len_avg": 78.0,
382
+ "output_seq_len_avg": 1438.5,
383
+ "output_seq_len_p50": 1438.5,
384
+ "output_seq_len_p90": 1447.7,
385
+ "output_seq_len_p99": 1449.77,
386
+ "request_count": 2,
387
+ "completed_request_count": 0,
388
+ "request_samples": [
389
+ {
390
+ "ttft": 0.18234779500198783,
391
+ "time_to_second_token": 0.1844339140006923,
392
+ "latency": 0.0,
393
+ "inter_token_latency_avg": 0.017485014843337535,
394
+ "chunk_inter_token_latency_avg": 0.03360183887002134,
395
+ "input_tokens": 78,
396
+ "output_tokens": 1450,
397
+ "output_tps_per_user": 57.19183020202231,
398
+ "e2e_output_tps_per_user": 0.0,
399
+ "completed": false
400
+ },
401
+ {
402
+ "ttft": 0.36667142099759076,
403
+ "time_to_second_token": 0.03354524099995615,
404
+ "latency": 0.0,
405
+ "inter_token_latency_avg": 0.01763762824614227,
406
+ "chunk_inter_token_latency_avg": 0.03357978355006526,
407
+ "input_tokens": 78,
408
+ "output_tokens": 1427,
409
+ "output_tps_per_user": 56.69696549017137,
410
+ "e2e_output_tps_per_user": 0.0,
411
+ "completed": false
412
+ }
413
+ ],
414
+ "total_tokens": 2256,
415
+ "wall_time": 25.553373684997496,
416
+ "num_completed": 2,
417
+ "num_errors": 0,
418
+ "server_gen_throughput": 112.75972864662006,
419
+ "server_utilization": 0.005862237420615535,
420
+ "server_spec_accept_rate": 0.8620689655172413,
421
+ "server_spec_accept_length": 0.0,
422
+ "avg_running_reqs": 2,
423
+ "max_running_reqs": 2,
424
+ "effective_concurrency": 2,
425
+ "avg_queue_reqs": 0,
426
+ "max_queue_reqs": 0,
427
+ "queue_fraction": 0.0,
428
+ "underfilled": false,
429
+ "warmup_timed_out": false,
430
+ "warmup_duration": 5.535,
431
+ "ready_reason": "running_reqs=2/2, queue_reqs=0, active_streams=2/2, stable=3.0s",
432
+ "timeout_reason": "",
433
+ "capacity_limited": false,
434
+ "hardware_summary": {
435
+ "samples": 8,
436
+ "duration_seconds": 16.96,
437
+ "gpu_count": 4,
438
+ "cpu_util_avg_pct": 13.01,
439
+ "cpu_temp_max_c": 73.62,
440
+ "gpu_util_avg_pct": 99.44,
441
+ "gpu_util_max_pct": 100.0,
442
+ "mem_util_avg_pct": 43.22,
443
+ "mem_util_max_pct": 51.0,
444
+ "temp_avg_c": 71.81,
445
+ "temp_max_c": 87.0,
446
+ "power_total_avg_w": 1059.21,
447
+ "power_total_max_w": 1063.03,
448
+ "power_limit_total_w": 1200.0,
449
+ "vram_used_avg_mb": 381283.62,
450
+ "vram_used_max_mb": 381287.0,
451
+ "vram_total_mb": 391548.0,
452
+ "vram_used_avg_pct": 97.38,
453
+ "vram_used_max_pct": 97.38,
454
+ "pcie_rx_avg_mb_s": 10778.88,
455
+ "pcie_rx_max_mb_s": 11250.0,
456
+ "pcie_tx_avg_mb_s": 10734.62,
457
+ "pcie_tx_max_mb_s": 11220.0
458
+ }
459
+ },
460
+ {
461
+ "concurrency": 3,
462
+ "context_tokens": 0,
463
+ "benchmark_mode": "duration",
464
+ "request_count_target": 0,
465
+ "warmup_request_count": 0,
466
+ "measurement_seconds": 19.984512,
467
+ "measurement_wall_seconds": 20.000639,
468
+ "client_output_tokens": 3077,
469
+ "server_output_tokens": 3077,
470
+ "aggregate_source": "openai_continuous_usage",
471
+ "aggregate_tps": 153.96923383622084,
472
+ "per_request_avg_tps": 51.32307794540694,
473
+ "ttft_avg": 0.3553215866680451,
474
+ "ttft_p50": 0.4402429800029495,
475
+ "ttft_p90": 0.44052856799826257,
476
+ "ttft_p99": 0.44059282529720806,
477
+ "time_to_second_token_avg": 0.10680816499855912,
478
+ "time_to_second_token_p50": 0.03267732400126988,
479
+ "time_to_second_token_p90": 0.21077119199471783,
480
+ "time_to_second_token_p99": 0.2508423122932436,
481
+ "request_latency_avg": 0.0,
482
+ "request_latency_p50": 0.0,
483
+ "request_latency_p90": 0.0,
484
+ "request_latency_p99": 0.0,
485
+ "inter_token_latency_avg": 0.019251174242436025,
486
+ "inter_token_latency_p50": 0.01927742167102236,
487
+ "inter_token_latency_p90": 0.019397001418632293,
488
+ "inter_token_latency_p99": 0.019423906861844527,
489
+ "output_tps_per_user_avg": 51.948271083988274,
490
+ "output_tps_per_user_p50": 51.87415708726187,
491
+ "output_tps_per_user_p90": 52.37133534333349,
492
+ "output_tps_per_user_p99": 52.4832004509496,
493
+ "e2e_output_tps_per_user_avg": 0.0,
494
+ "e2e_output_tps_per_user_p50": 0.0,
495
+ "e2e_output_tps_per_user_p90": 0.0,
496
+ "e2e_output_tps_per_user_p99": 0.0,
497
+ "chunk_inter_token_latency_avg": 0.0365812899178145,
498
+ "chunk_inter_token_latency_p50": 0.03666655788596504,
499
+ "chunk_inter_token_latency_p90": 0.03700879298509785,
500
+ "chunk_inter_token_latency_p99": 0.03708579588240273,
501
+ "input_seq_len_avg": 78.0,
502
+ "output_seq_len_avg": 1308.3333333333333,
503
+ "output_seq_len_p50": 1302.0,
504
+ "output_seq_len_p90": 1325.2,
505
+ "output_seq_len_p99": 1330.42,
506
+ "request_count": 3,
507
+ "completed_request_count": 0,
508
+ "request_samples": [
509
+ {
510
+ "ttft": 0.18512181500409497,
511
+ "time_to_second_token": 0.2552946589930798,
512
+ "latency": 0.0,
513
+ "inter_token_latency_avg": 0.019049204700750944,
514
+ "chunk_inter_token_latency_avg": 0.03709435175988105,
515
+ "input_tokens": 78,
516
+ "output_tokens": 1331,
517
+ "output_tps_per_user": 52.49562990735139,
518
+ "e2e_output_tps_per_user": 0.0,
519
+ "completed": false
520
+ },
521
+ {
522
+ "ttft": 0.44059996499709086,
523
+ "time_to_second_token": 0.032452512001327705,
524
+ "latency": 0.0,
525
+ "inter_token_latency_avg": 0.01927742167102236,
526
+ "chunk_inter_token_latency_avg": 0.03666655788596504,
527
+ "input_tokens": 78,
528
+ "output_tokens": 1302,
529
+ "output_tps_per_user": 51.87415708726187,
530
+ "e2e_output_tps_per_user": 0.0,
531
+ "completed": false
532
+ },
533
+ {
534
+ "ttft": 0.4402429800029495,
535
+ "time_to_second_token": 0.03267732400126988,
536
+ "latency": 0.0,
537
+ "inter_token_latency_avg": 0.019426896355534774,
538
+ "chunk_inter_token_latency_avg": 0.03598296010759741,
539
+ "input_tokens": 78,
540
+ "output_tokens": 1292,
541
+ "output_tps_per_user": 51.475026257351566,
542
+ "e2e_output_tps_per_user": 0.0,
543
+ "completed": false
544
+ }
545
+ ],
546
+ "total_tokens": 3077,
547
+ "wall_time": 25.559213790002104,
548
+ "num_completed": 3,
549
+ "num_errors": 0,
550
+ "server_gen_throughput": 153.8065347116393,
551
+ "server_utilization": 0.008793356130923358,
552
+ "server_spec_accept_rate": 0.9135802469135802,
553
+ "server_spec_accept_length": 0.0,
554
+ "avg_running_reqs": 3,
555
+ "max_running_reqs": 3,
556
+ "effective_concurrency": 3,
557
+ "avg_queue_reqs": 0,
558
+ "max_queue_reqs": 0,
559
+ "queue_fraction": 0.0,
560
+ "underfilled": false,
561
+ "warmup_timed_out": false,
562
+ "warmup_duration": 5.536,
563
+ "ready_reason": "running_reqs=3/3, queue_reqs=0, active_streams=3/3, stable=3.0s",
564
+ "timeout_reason": "",
565
+ "capacity_limited": false,
566
+ "hardware_summary": {
567
+ "samples": 9,
568
+ "duration_seconds": 19.459,
569
+ "gpu_count": 4,
570
+ "cpu_util_avg_pct": 13.84,
571
+ "cpu_temp_max_c": 75.25,
572
+ "gpu_util_avg_pct": 99.28,
573
+ "gpu_util_max_pct": 100.0,
574
+ "mem_util_avg_pct": 45.69,
575
+ "mem_util_max_pct": 53.0,
576
+ "temp_avg_c": 73.11,
577
+ "temp_max_c": 89.0,
578
+ "power_total_avg_w": 1090.03,
579
+ "power_total_max_w": 1099.33,
580
+ "power_limit_total_w": 1200.0,
581
+ "vram_used_avg_mb": 381287.67,
582
+ "vram_used_max_mb": 381297.0,
583
+ "vram_total_mb": 391548.0,
584
+ "vram_used_avg_pct": 97.38,
585
+ "vram_used_max_pct": 97.38,
586
+ "pcie_rx_avg_mb_s": 14818.56,
587
+ "pcie_rx_max_mb_s": 15467.0,
588
+ "pcie_tx_avg_mb_s": 14798.89,
589
+ "pcie_tx_max_mb_s": 15468.0
590
+ }
591
+ },
592
+ {
593
+ "concurrency": 4,
594
+ "context_tokens": 0,
595
+ "benchmark_mode": "duration",
596
+ "request_count_target": 0,
597
+ "warmup_request_count": 0,
598
+ "measurement_seconds": 19.981895,
599
+ "measurement_wall_seconds": 20.000999,
600
+ "client_output_tokens": 3760,
601
+ "server_output_tokens": 3760,
602
+ "aggregate_source": "openai_continuous_usage",
603
+ "aggregate_tps": 188.17034108841304,
604
+ "per_request_avg_tps": 47.04258527210326,
605
+ "ttft_avg": 0.4259795034995477,
606
+ "ttft_p50": 0.5066995435008721,
607
+ "ttft_p90": 0.5067091596996761,
608
+ "ttft_p99": 0.5067112308692594,
609
+ "time_to_second_token_avg": 0.10913618475206022,
610
+ "time_to_second_token_p50": 0.03785586549929576,
611
+ "time_to_second_token_p90": 0.2374592877036776,
612
+ "time_to_second_token_p99": 0.3144445877741963,
613
+ "request_latency_avg": 0.0,
614
+ "request_latency_p50": 0.0,
615
+ "request_latency_p90": 0.0,
616
+ "request_latency_p99": 0.0,
617
+ "inter_token_latency_avg": 0.021038738767539554,
618
+ "inter_token_latency_p50": 0.021001472490651703,
619
+ "inter_token_latency_p90": 0.021209152859497836,
620
+ "inter_token_latency_p99": 0.021282474638977047,
621
+ "output_tps_per_user_avg": 47.53399241611042,
622
+ "output_tps_per_user_p50": 47.61574226297671,
623
+ "output_tps_per_user_p90": 47.85149820446787,
624
+ "output_tps_per_user_p99": 47.927052686200305,
625
+ "e2e_output_tps_per_user_avg": 0.0,
626
+ "e2e_output_tps_per_user_p50": 0.0,
627
+ "e2e_output_tps_per_user_p90": 0.0,
628
+ "e2e_output_tps_per_user_p99": 0.0,
629
+ "chunk_inter_token_latency_avg": 0.03989503016456929,
630
+ "chunk_inter_token_latency_p50": 0.03982961252260963,
631
+ "chunk_inter_token_latency_p90": 0.04022755274032715,
632
+ "chunk_inter_token_latency_p99": 0.0403320795257882,
633
+ "input_seq_len_avg": 78.0,
634
+ "output_seq_len_avg": 1193.75,
635
+ "output_seq_len_p50": 1192.0,
636
+ "output_seq_len_p90": 1197.9,
637
+ "output_seq_len_p99": 1199.79,
638
+ "request_count": 4,
639
+ "completed_request_count": 0,
640
+ "request_samples": [
641
+ {
642
+ "ttft": 0.18380746599723352,
643
+ "time_to_second_token": 0.32299851000425406,
644
+ "latency": 0.0,
645
+ "inter_token_latency_avg": 0.021290621503363628,
646
+ "chunk_inter_token_latency_avg": 0.04034369361306165,
647
+ "input_tokens": 78,
648
+ "output_tokens": 1191,
649
+ "output_tps_per_user": 46.96903750987324,
650
+ "e2e_output_tps_per_user": 0.0,
651
+ "completed": false
652
+ },
653
+ {
654
+ "ttft": 0.5066952970009879,
655
+ "time_to_second_token": 0.03786776900233235,
656
+ "latency": 0.0,
657
+ "inter_token_latency_avg": 0.02086138858549119,
658
+ "chunk_inter_token_latency_avg": 0.039956557370613315,
659
+ "input_tokens": 78,
660
+ "output_tokens": 1200,
661
+ "output_tps_per_user": 47.935447628615016,
662
+ "e2e_output_tps_per_user": 0.0,
663
+ "completed": false
664
+ },
665
+ {
666
+ "ttft": 0.5067037900007563,
667
+ "time_to_second_token": 0.03784396199625917,
668
+ "latency": 0.0,
669
+ "inter_token_latency_avg": 0.020983885624159086,
670
+ "chunk_inter_token_latency_avg": 0.03957720199999625,
671
+ "input_tokens": 78,
672
+ "output_tokens": 1193,
673
+ "output_tps_per_user": 47.655616214791216,
674
+ "e2e_output_tps_per_user": 0.0,
675
+ "completed": false
676
+ },
677
+ {
678
+ "ttft": 0.5067114609992132,
679
+ "time_to_second_token": 0.03783449800539529,
680
+ "latency": 0.0,
681
+ "inter_token_latency_avg": 0.02101905935714432,
682
+ "chunk_inter_token_latency_avg": 0.039702667674605945,
683
+ "input_tokens": 78,
684
+ "output_tokens": 1191,
685
+ "output_tps_per_user": 47.57586831116221,
686
+ "e2e_output_tps_per_user": 0.0,
687
+ "completed": false
688
+ }
689
+ ],
690
+ "total_tokens": 3760,
691
+ "wall_time": 25.562061192998954,
692
+ "num_completed": 4,
693
+ "num_errors": 0,
694
+ "server_gen_throughput": 187.93392297771373,
695
+ "server_utilization": 0.009770395701025891,
696
+ "server_spec_accept_rate": 0.8958333333333334,
697
+ "server_spec_accept_length": 0.0,
698
+ "avg_running_reqs": 4,
699
+ "max_running_reqs": 4,
700
+ "effective_concurrency": 4,
701
+ "avg_queue_reqs": 0,
702
+ "max_queue_reqs": 0,
703
+ "queue_fraction": 0.0,
704
+ "underfilled": false,
705
+ "warmup_timed_out": false,
706
+ "warmup_duration": 5.538,
707
+ "ready_reason": "running_reqs=4/4, queue_reqs=0, active_streams=4/4, stable=3.0s",
708
+ "timeout_reason": "",
709
+ "capacity_limited": false,
710
+ "hardware_summary": {
711
+ "samples": 8,
712
+ "duration_seconds": 16.929,
713
+ "gpu_count": 4,
714
+ "cpu_util_avg_pct": 12.57,
715
+ "cpu_temp_max_c": 74.0,
716
+ "gpu_util_avg_pct": 99.78,
717
+ "gpu_util_max_pct": 100.0,
718
+ "mem_util_avg_pct": 44.91,
719
+ "mem_util_max_pct": 50.0,
720
+ "temp_avg_c": 73.75,
721
+ "temp_max_c": 89.0,
722
+ "power_total_avg_w": 1099.79,
723
+ "power_total_max_w": 1106.77,
724
+ "power_limit_total_w": 1200.0,
725
+ "vram_used_avg_mb": 381278.0,
726
+ "vram_used_max_mb": 381278.0,
727
+ "vram_total_mb": 391548.0,
728
+ "vram_used_avg_pct": 97.38,
729
+ "vram_used_max_pct": 97.38,
730
+ "pcie_rx_avg_mb_s": 17081.0,
731
+ "pcie_rx_max_mb_s": 17786.0,
732
+ "pcie_tx_avg_mb_s": 17304.12,
733
+ "pcie_tx_max_mb_s": 18298.0
734
+ }
735
+ },
736
+ {
737
+ "concurrency": 5,
738
+ "context_tokens": 0,
739
+ "benchmark_mode": "duration",
740
+ "request_count_target": 0,
741
+ "warmup_request_count": 0,
742
+ "measurement_seconds": 19.993387,
743
+ "measurement_wall_seconds": 20.000507,
744
+ "client_output_tokens": 4363,
745
+ "server_output_tokens": 4362,
746
+ "aggregate_source": "openai_continuous_usage",
747
+ "aggregate_tps": 218.22215529749218,
748
+ "per_request_avg_tps": 43.64443105949844,
749
+ "ttft_avg": 0.50238033580099,
750
+ "ttft_p50": 0.5809674760021153,
751
+ "ttft_p90": 0.5811134215968196,
752
+ "ttft_p99": 0.5811735869580298,
753
+ "time_to_second_token_avg": 0.10931229779816931,
754
+ "time_to_second_token_p50": 0.03833671499887714,
755
+ "time_to_second_token_p90": 0.2513611791975564,
756
+ "time_to_second_token_p99": 0.379167114518641,
757
+ "request_latency_avg": 0.0,
758
+ "request_latency_p50": 0.0,
759
+ "request_latency_p90": 0.0,
760
+ "request_latency_p99": 0.0,
761
+ "inter_token_latency_avg": 0.022506907986658848,
762
+ "inter_token_latency_p50": 0.022497411690714515,
763
+ "inter_token_latency_p90": 0.022570362452308063,
764
+ "inter_token_latency_p99": 0.02260195477820478,
765
+ "output_tps_per_user_avg": 44.43107867028448,
766
+ "output_tps_per_user_p50": 44.44955774235734,
767
+ "output_tps_per_user_p90": 44.537662248183864,
768
+ "output_tps_per_user_p99": 44.566590628134485,
769
+ "e2e_output_tps_per_user_avg": 0.0,
770
+ "e2e_output_tps_per_user_p50": 0.0,
771
+ "e2e_output_tps_per_user_p90": 0.0,
772
+ "e2e_output_tps_per_user_p99": 0.0,
773
+ "chunk_inter_token_latency_avg": 0.043122730860543766,
774
+ "chunk_inter_token_latency_p50": 0.04316544434428346,
775
+ "chunk_inter_token_latency_p90": 0.043524573911415454,
776
+ "chunk_inter_token_latency_p99": 0.043739938080411225,
777
+ "input_seq_len_avg": 78.0,
778
+ "output_seq_len_avg": 1112.6,
779
+ "output_seq_len_p50": 1111.0,
780
+ "output_seq_len_p90": 1117.2,
781
+ "output_seq_len_p99": 1119.72,
782
+ "request_count": 5,
783
+ "completed_request_count": 0,
784
+ "request_samples": [
785
+ {
786
+ "ttft": 0.1879238180044922,
787
+ "time_to_second_token": 0.39336777399876155,
788
+ "latency": 0.0,
789
+ "inter_token_latency_avg": 0.022605465036637747,
790
+ "chunk_inter_token_latency_avg": 0.043763867432521864,
791
+ "input_tokens": 78,
792
+ "output_tokens": 1120,
793
+ "output_tps_per_user": 44.23709038408423,
794
+ "e2e_output_tps_per_user": 0.0,
795
+ "completed": false
796
+ },
797
+ {
798
+ "ttft": 0.5811802719981642,
799
+ "time_to_second_token": 0.03823754299810389,
800
+ "latency": 0.0,
801
+ "inter_token_latency_avg": 0.022497411690714515,
802
+ "chunk_inter_token_latency_avg": 0.042576159667239585,
803
+ "input_tokens": 78,
804
+ "output_tokens": 1110,
805
+ "output_tps_per_user": 44.44955774235734,
806
+ "e2e_output_tps_per_user": 0.0,
807
+ "completed": false
808
+ },
809
+ {
810
+ "ttft": 0.5808169670053758,
811
+ "time_to_second_token": 0.038351286995748524,
812
+ "latency": 0.0,
813
+ "inter_token_latency_avg": 0.022477239854053043,
814
+ "chunk_inter_token_latency_avg": 0.04316563362975584,
815
+ "input_tokens": 78,
816
+ "output_tokens": 1111,
817
+ "output_tps_per_user": 44.4894482815995,
818
+ "e2e_output_tps_per_user": 0.0,
819
+ "completed": false
820
+ },
821
+ {
822
+ "ttft": 0.5809674760021153,
823
+ "time_to_second_token": 0.03833671499887714,
824
+ "latency": 0.0,
825
+ "inter_token_latency_avg": 0.022436714776075395,
826
+ "chunk_inter_token_latency_avg": 0.04316544434428346,
827
+ "input_tokens": 78,
828
+ "output_tokens": 1113,
829
+ "output_tps_per_user": 44.569804892573444,
830
+ "e2e_output_tps_per_user": 0.0,
831
+ "completed": false
832
+ },
833
+ {
834
+ "ttft": 0.5810131459948025,
835
+ "time_to_second_token": 0.03826816999935545,
836
+ "latency": 0.0,
837
+ "inter_token_latency_avg": 0.02251770857581354,
838
+ "chunk_inter_token_latency_avg": 0.042942549228918075,
839
+ "input_tokens": 78,
840
+ "output_tokens": 1109,
841
+ "output_tps_per_user": 44.409492050807884,
842
+ "e2e_output_tps_per_user": 0.0,
843
+ "completed": false
844
+ }
845
+ ],
846
+ "total_tokens": 4363,
847
+ "wall_time": 25.578695286996663,
848
+ "num_completed": 5,
849
+ "num_errors": 0,
850
+ "server_gen_throughput": 218.04359264590255,
851
+ "server_utilization": 0.012212994626282336,
852
+ "server_spec_accept_rate": 0.8909090909090909,
853
+ "server_spec_accept_length": 0.0,
854
+ "avg_running_reqs": 5,
855
+ "max_running_reqs": 5,
856
+ "effective_concurrency": 5,
857
+ "avg_queue_reqs": 0,
858
+ "max_queue_reqs": 0,
859
+ "queue_fraction": 0.0,
860
+ "underfilled": false,
861
+ "warmup_timed_out": false,
862
+ "warmup_duration": 5.538,
863
+ "ready_reason": "running_reqs=5/5, queue_reqs=0, active_streams=5/5, stable=3.0s",
864
+ "timeout_reason": "",
865
+ "capacity_limited": false,
866
+ "hardware_summary": {
867
+ "samples": 8,
868
+ "duration_seconds": 16.944,
869
+ "gpu_count": 4,
870
+ "cpu_util_avg_pct": 12.53,
871
+ "cpu_temp_max_c": 75.5,
872
+ "gpu_util_avg_pct": 99.69,
873
+ "gpu_util_max_pct": 100.0,
874
+ "mem_util_avg_pct": 43.91,
875
+ "mem_util_max_pct": 48.0,
876
+ "temp_avg_c": 74.09,
877
+ "temp_max_c": 89.0,
878
+ "power_total_avg_w": 1103.33,
879
+ "power_total_max_w": 1109.64,
880
+ "power_limit_total_w": 1200.0,
881
+ "vram_used_avg_mb": 381279.0,
882
+ "vram_used_max_mb": 381282.0,
883
+ "vram_total_mb": 391548.0,
884
+ "vram_used_avg_pct": 97.38,
885
+ "vram_used_max_pct": 97.38,
886
+ "pcie_rx_avg_mb_s": 19600.5,
887
+ "pcie_rx_max_mb_s": 20488.0,
888
+ "pcie_tx_avg_mb_s": 19941.88,
889
+ "pcie_tx_max_mb_s": 21377.0
890
+ }
891
+ },
892
+ {
893
+ "concurrency": 6,
894
+ "context_tokens": 0,
895
+ "benchmark_mode": "duration",
896
+ "request_count_target": 0,
897
+ "warmup_request_count": 0,
898
+ "measurement_seconds": 19.974334,
899
+ "measurement_wall_seconds": 20.001453,
900
+ "client_output_tokens": 4782,
901
+ "server_output_tokens": 4782,
902
+ "aggregate_source": "openai_continuous_usage",
903
+ "aggregate_tps": 239.40723639392317,
904
+ "per_request_avg_tps": 39.90120606565386,
905
+ "ttft_avg": 0.549772203333608,
906
+ "ttft_p50": 0.6222461475008458,
907
+ "ttft_p90": 0.6223876490003022,
908
+ "ttft_p99": 0.6224695706016063,
909
+ "time_to_second_token_avg": 0.10726942716670844,
910
+ "time_to_second_token_p50": 0.041655773002275964,
911
+ "time_to_second_token_p90": 0.23858283699883032,
912
+ "time_to_second_token_p99": 0.41574188890263036,
913
+ "request_latency_avg": 0.0,
914
+ "request_latency_p50": 0.0,
915
+ "request_latency_p90": 0.0,
916
+ "request_latency_p99": 0.0,
917
+ "inter_token_latency_avg": 0.024716489034405417,
918
+ "inter_token_latency_p50": 0.024521605209357148,
919
+ "inter_token_latency_p90": 0.02530976165574415,
920
+ "inter_token_latency_p99": 0.025507327421623007,
921
+ "output_tps_per_user_avg": 40.47186197370677,
922
+ "output_tps_per_user_p50": 40.78052325608181,
923
+ "output_tps_per_user_p90": 41.12164312865083,
924
+ "output_tps_per_user_p99": 41.13975731076326,
925
+ "e2e_output_tps_per_user_avg": 0.0,
926
+ "e2e_output_tps_per_user_p50": 0.0,
927
+ "e2e_output_tps_per_user_p90": 0.0,
928
+ "e2e_output_tps_per_user_p99": 0.0,
929
+ "chunk_inter_token_latency_avg": 0.047295855643114615,
930
+ "chunk_inter_token_latency_p50": 0.04713935542163501,
931
+ "chunk_inter_token_latency_p90": 0.04787485548123559,
932
+ "chunk_inter_token_latency_p99": 0.048199485365566744,
933
+ "input_seq_len_avg": 78.0,
934
+ "output_seq_len_avg": 1011.1666666666666,
935
+ "output_seq_len_p50": 1016.0,
936
+ "output_seq_len_p90": 1024.5,
937
+ "output_seq_len_p99": 1024.95,
938
+ "request_count": 6,
939
+ "completed_request_count": 0,
940
+ "request_samples": [
941
+ {
942
+ "ttft": 0.1872373790029087,
943
+ "time_to_second_token": 0.43542622800305253,
944
+ "latency": 0.0,
945
+ "inter_token_latency_avg": 0.025529279173387324,
946
+ "chunk_inter_token_latency_avg": 0.04751415560975652,
947
+ "input_tokens": 78,
948
+ "output_tokens": 993,
949
+ "output_tps_per_user": 39.17071035215273,
950
+ "e2e_output_tps_per_user": 0.0,
951
+ "completed": false
952
+ },
953
+ {
954
+ "ttft": 0.6224786730017513,
955
+ "time_to_second_token": 0.041585910999856424,
956
+ "latency": 0.0,
957
+ "inter_token_latency_avg": 0.025090244138100976,
958
+ "chunk_inter_token_latency_avg": 0.04669703974670951,
959
+ "input_tokens": 78,
960
+ "output_tokens": 993,
961
+ "output_tps_per_user": 39.856128720622635,
962
+ "e2e_output_tps_per_user": 0.0,
963
+ "completed": false
964
+ },
965
+ {
966
+ "ttft": 0.622128247996443,
967
+ "time_to_second_token": 0.04165743000339717,
968
+ "latency": 0.0,
969
+ "inter_token_latency_avg": 0.024306197814453867,
970
+ "chunk_inter_token_latency_avg": 0.04823555535271465,
971
+ "input_tokens": 78,
972
+ "output_tokens": 1025,
973
+ "output_tps_per_user": 41.14176999766464,
974
+ "e2e_output_tps_per_user": 0.0,
975
+ "completed": false
976
+ },
977
+ {
978
+ "ttft": 0.6221973330029869,
979
+ "time_to_second_token": 0.041739445994608104,
980
+ "latency": 0.0,
981
+ "inter_token_latency_avg": 0.024330002661776047,
982
+ "chunk_inter_token_latency_avg": 0.0470502697977257,
983
+ "input_tokens": 78,
984
+ "output_tokens": 1024,
985
+ "output_tps_per_user": 41.101516259637016,
986
+ "e2e_output_tps_per_user": 0.0,
987
+ "completed": false
988
+ },
989
+ {
990
+ "ttft": 0.6222949619987048,
991
+ "time_to_second_token": 0.04165411600115476,
992
+ "latency": 0.0,
993
+ "inter_token_latency_avg": 0.024569978707800456,
994
+ "chunk_inter_token_latency_avg": 0.04722844104554433,
995
+ "input_tokens": 78,
996
+ "output_tokens": 1014,
997
+ "output_tps_per_user": 40.700075970457426,
998
+ "e2e_output_tps_per_user": 0.0,
999
+ "completed": false
1000
+ },
1001
+ {
1002
+ "ttft": 0.6222966249988531,
1003
+ "time_to_second_token": 0.04155343199818162,
1004
+ "latency": 0.0,
1005
+ "inter_token_latency_avg": 0.02447323171091384,
1006
+ "chunk_inter_token_latency_avg": 0.047049672306237,
1007
+ "input_tokens": 78,
1008
+ "output_tokens": 1018,
1009
+ "output_tps_per_user": 40.86097054170618,
1010
+ "e2e_output_tps_per_user": 0.0,
1011
+ "completed": false
1012
+ }
1013
+ ],
1014
+ "total_tokens": 4782,
1015
+ "wall_time": 25.56535250399611,
1016
+ "num_completed": 6,
1017
+ "num_errors": 0,
1018
+ "server_gen_throughput": 239.02226618249358,
1019
+ "server_utilization": 0.014655593551538892,
1020
+ "server_spec_accept_rate": 0.7894736842105263,
1021
+ "server_spec_accept_length": 0.0,
1022
+ "avg_running_reqs": 6,
1023
+ "max_running_reqs": 6,
1024
+ "effective_concurrency": 6,
1025
+ "avg_queue_reqs": 0,
1026
+ "max_queue_reqs": 0,
1027
+ "queue_fraction": 0.0,
1028
+ "underfilled": false,
1029
+ "warmup_timed_out": false,
1030
+ "warmup_duration": 5.538,
1031
+ "ready_reason": "running_reqs=6/6, queue_reqs=0, active_streams=6/6, stable=3.0s",
1032
+ "timeout_reason": "",
1033
+ "capacity_limited": false,
1034
+ "hardware_summary": {
1035
+ "samples": 8,
1036
+ "duration_seconds": 16.951,
1037
+ "gpu_count": 4,
1038
+ "cpu_util_avg_pct": 12.59,
1039
+ "cpu_temp_max_c": 74.5,
1040
+ "gpu_util_avg_pct": 99.91,
1041
+ "gpu_util_max_pct": 100.0,
1042
+ "mem_util_avg_pct": 43.28,
1043
+ "mem_util_max_pct": 47.0,
1044
+ "temp_avg_c": 74.66,
1045
+ "temp_max_c": 89.0,
1046
+ "power_total_avg_w": 1109.93,
1047
+ "power_total_max_w": 1113.83,
1048
+ "power_limit_total_w": 1200.0,
1049
+ "vram_used_avg_mb": 381279.0,
1050
+ "vram_used_max_mb": 381279.0,
1051
+ "vram_total_mb": 391548.0,
1052
+ "vram_used_avg_pct": 97.38,
1053
+ "vram_used_max_pct": 97.38,
1054
+ "pcie_rx_avg_mb_s": 21494.62,
1055
+ "pcie_rx_max_mb_s": 23366.0,
1056
+ "pcie_tx_avg_mb_s": 21025.0,
1057
+ "pcie_tx_max_mb_s": 22613.0
1058
+ }
1059
+ },
1060
+ {
1061
+ "concurrency": 7,
1062
+ "context_tokens": 0,
1063
+ "benchmark_mode": "duration",
1064
+ "request_count_target": 0,
1065
+ "warmup_request_count": 0,
1066
+ "measurement_seconds": 19.980163,
1067
+ "measurement_wall_seconds": 20.000297,
1068
+ "client_output_tokens": 5072,
1069
+ "server_output_tokens": 5072,
1070
+ "aggregate_source": "openai_continuous_usage",
1071
+ "aggregate_tps": 253.85178855739426,
1072
+ "per_request_avg_tps": 36.264541222484894,
1073
+ "ttft_avg": 0.6091304604280074,
1074
+ "ttft_p50": 0.6797027759967023,
1075
+ "ttft_p90": 0.6799549422008567,
1076
+ "ttft_p99": 0.6801378769153962,
1077
+ "time_to_second_token_avg": 0.10793581771369125,
1078
+ "time_to_second_token_p50": 0.04349551999621326,
1079
+ "time_to_second_token_p90": 0.22420424359879706,
1080
+ "time_to_second_token_p99": 0.4678210850646426,
1081
+ "request_latency_avg": 0.0,
1082
+ "request_latency_p50": 0.0,
1083
+ "request_latency_p90": 0.0,
1084
+ "request_latency_p99": 0.0,
1085
+ "inter_token_latency_avg": 0.026912070927078483,
1086
+ "inter_token_latency_p50": 0.02685170362270091,
1087
+ "inter_token_latency_p90": 0.02721208904703142,
1088
+ "inter_token_latency_p99": 0.02734247356075008,
1089
+ "output_tps_per_user_avg": 37.16072532128522,
1090
+ "output_tps_per_user_p50": 37.241584893503074,
1091
+ "output_tps_per_user_p90": 37.475494666525805,
1092
+ "output_tps_per_user_p99": 37.51911175310403,
1093
+ "e2e_output_tps_per_user_avg": 0.0,
1094
+ "e2e_output_tps_per_user_p50": 0.0,
1095
+ "e2e_output_tps_per_user_p90": 0.0,
1096
+ "e2e_output_tps_per_user_p99": 0.0,
1097
+ "chunk_inter_token_latency_avg": 0.05111701555098312,
1098
+ "chunk_inter_token_latency_p50": 0.0510016957926044,
1099
+ "chunk_inter_token_latency_p90": 0.05155462767216711,
1100
+ "chunk_inter_token_latency_p99": 0.05187532152028938,
1101
+ "input_seq_len_avg": 78.0,
1102
+ "output_seq_len_avg": 926.5714285714286,
1103
+ "output_seq_len_p50": 927.0,
1104
+ "output_seq_len_p90": 931.8,
1105
+ "output_seq_len_p99": 932.88,
1106
+ "request_count": 7,
1107
+ "completed_request_count": 0,
1108
+ "request_samples": [
1109
+ {
1110
+ "ttft": 0.18545529499533586,
1111
+ "time_to_second_token": 0.4948896230052924,
1112
+ "latency": 0.0,
1113
+ "inter_token_latency_avg": 0.027356960728941043,
1114
+ "chunk_inter_token_latency_avg": 0.05191095417008075,
1115
+ "input_tokens": 78,
1116
+ "output_tokens": 927,
1117
+ "output_tps_per_user": 36.55376815824778,
1118
+ "e2e_output_tps_per_user": 0.0,
1119
+ "completed": false
1120
+ },
1121
+ {
1122
+ "ttft": 0.6801582029947895,
1123
+ "time_to_second_token": 0.04320555600133957,
1124
+ "latency": 0.0,
1125
+ "inter_token_latency_avg": 0.026649640675967902,
1126
+ "chunk_inter_token_latency_avg": 0.051317076673558025,
1127
+ "input_tokens": 78,
1128
+ "output_tokens": 933,
1129
+ "output_tps_per_user": 37.523958096057164,
1130
+ "e2e_output_tps_per_user": 0.0,
1131
+ "completed": false
1132
+ },
1133
+ {
1134
+ "ttft": 0.679735507001169,
1135
+ "time_to_second_token": 0.04374732399446657,
1136
+ "latency": 0.0,
1137
+ "inter_token_latency_avg": 0.026909954437702797,
1138
+ "chunk_inter_token_latency_avg": 0.051106765320987,
1139
+ "input_tokens": 78,
1140
+ "output_tokens": 924,
1141
+ "output_tps_per_user": 37.160969644709894,
1142
+ "e2e_output_tps_per_user": 0.0,
1143
+ "completed": false
1144
+ },
1145
+ {
1146
+ "ttft": 0.6798194350049016,
1147
+ "time_to_second_token": 0.04349551999621326,
1148
+ "latency": 0.0,
1149
+ "inter_token_latency_avg": 0.02685170362270091,
1150
+ "chunk_inter_token_latency_avg": 0.0510016957926044,
1151
+ "input_tokens": 78,
1152
+ "output_tokens": 926,
1153
+ "output_tps_per_user": 37.241584893503074,
1154
+ "e2e_output_tps_per_user": 0.0,
1155
+ "completed": false
1156
+ },
1157
+ {
1158
+ "ttft": 0.6796896059968276,
1159
+ "time_to_second_token": 0.04351532000146108,
1160
+ "latency": 0.0,
1161
+ "inter_token_latency_avg": 0.026793599858689284,
1162
+ "chunk_inter_token_latency_avg": 0.050792775192239195,
1163
+ "input_tokens": 78,
1164
+ "output_tokens": 928,
1165
+ "output_tps_per_user": 37.32234583161827,
1166
+ "e2e_output_tps_per_user": 0.0,
1167
+ "completed": false
1168
+ },
1169
+ {
1170
+ "ttft": 0.6793524010063265,
1171
+ "time_to_second_token": 0.04345030099648284,
1172
+ "latency": 0.0,
1173
+ "inter_token_latency_avg": 0.02711550792575834,
1174
+ "chunk_inter_token_latency_avg": 0.05089714192621852,
1175
+ "input_tokens": 78,
1176
+ "output_tokens": 917,
1177
+ "output_tps_per_user": 36.87926491135545,
1178
+ "e2e_output_tps_per_user": 0.0,
1179
+ "completed": false
1180
+ },
1181
+ {
1182
+ "ttft": 0.6797027759967023,
1183
+ "time_to_second_token": 0.04324708000058308,
1184
+ "latency": 0.0,
1185
+ "inter_token_latency_avg": 0.026707129239789098,
1186
+ "chunk_inter_token_latency_avg": 0.05079269978119399,
1187
+ "input_tokens": 78,
1188
+ "output_tokens": 931,
1189
+ "output_tps_per_user": 37.443185713504896,
1190
+ "e2e_output_tps_per_user": 0.0,
1191
+ "completed": false
1192
+ }
1193
+ ],
1194
+ "total_tokens": 5072,
1195
+ "wall_time": 25.573439713996777,
1196
+ "num_completed": 7,
1197
+ "num_errors": 0,
1198
+ "server_gen_throughput": 253.5387425044205,
1199
+ "server_utilization": 0.013678553981436248,
1200
+ "server_spec_accept_rate": 0.8947368421052632,
1201
+ "server_spec_accept_length": 0.0,
1202
+ "avg_running_reqs": 7,
1203
+ "max_running_reqs": 7,
1204
+ "effective_concurrency": 7,
1205
+ "avg_queue_reqs": 0,
1206
+ "max_queue_reqs": 0,
1207
+ "queue_fraction": 0.0,
1208
+ "underfilled": false,
1209
+ "warmup_timed_out": false,
1210
+ "warmup_duration": 5.538,
1211
+ "ready_reason": "running_reqs=7/7, queue_reqs=0, active_streams=7/7, stable=3.0s",
1212
+ "timeout_reason": "",
1213
+ "capacity_limited": false,
1214
+ "hardware_summary": {
1215
+ "samples": 8,
1216
+ "duration_seconds": 17.005,
1217
+ "gpu_count": 4,
1218
+ "cpu_util_avg_pct": 12.69,
1219
+ "cpu_temp_max_c": 74.62,
1220
+ "gpu_util_avg_pct": 99.78,
1221
+ "gpu_util_max_pct": 100.0,
1222
+ "mem_util_avg_pct": 43.88,
1223
+ "mem_util_max_pct": 49.0,
1224
+ "temp_avg_c": 74.94,
1225
+ "temp_max_c": 89.0,
1226
+ "power_total_avg_w": 1117.96,
1227
+ "power_total_max_w": 1123.18,
1228
+ "power_limit_total_w": 1200.0,
1229
+ "vram_used_avg_mb": 381279.0,
1230
+ "vram_used_max_mb": 381279.0,
1231
+ "vram_total_mb": 391548.0,
1232
+ "vram_used_avg_pct": 97.38,
1233
+ "vram_used_max_pct": 97.38,
1234
+ "pcie_rx_avg_mb_s": 21867.88,
1235
+ "pcie_rx_max_mb_s": 22965.0,
1236
+ "pcie_tx_avg_mb_s": 21466.25,
1237
+ "pcie_tx_max_mb_s": 22328.0
1238
+ }
1239
+ },
1240
+ {
1241
+ "concurrency": 8,
1242
+ "context_tokens": 0,
1243
+ "benchmark_mode": "duration",
1244
+ "request_count_target": 0,
1245
+ "warmup_request_count": 0,
1246
+ "measurement_seconds": 19.94598,
1247
+ "measurement_wall_seconds": 20.001149,
1248
+ "client_output_tokens": 5321,
1249
+ "server_output_tokens": 5336,
1250
+ "aggregate_source": "openai_continuous_usage",
1251
+ "aggregate_tps": 266.7705425803283,
1252
+ "per_request_avg_tps": 33.34631782254104,
1253
+ "ttft_avg": 0.6750056610017054,
1254
+ "ttft_p50": 0.7443318575024023,
1255
+ "ttft_p90": 0.7446170434006489,
1256
+ "ttft_p99": 0.744826460442273,
1257
+ "time_to_second_token_avg": 0.10947240312361828,
1258
+ "time_to_second_token_p50": 0.04571369499899447,
1259
+ "time_to_second_token_p90": 0.19882177710023816,
1260
+ "time_to_second_token_p99": 0.5200262735081922,
1261
+ "request_latency_avg": 0.0,
1262
+ "request_latency_p50": 0.0,
1263
+ "request_latency_p90": 0.0,
1264
+ "request_latency_p99": 0.0,
1265
+ "inter_token_latency_avg": 0.029122754128254977,
1266
+ "inter_token_latency_p50": 0.028864435762547467,
1267
+ "inter_token_latency_p90": 0.02968891110728471,
1268
+ "inter_token_latency_p99": 0.029695202501238645,
1269
+ "output_tps_per_user_avg": 34.34314902522898,
1270
+ "output_tps_per_user_p50": 34.644709781862645,
1271
+ "output_tps_per_user_p90": 34.725839682868504,
1272
+ "output_tps_per_user_p99": 34.72609006181996,
1273
+ "e2e_output_tps_per_user_avg": 0.0,
1274
+ "e2e_output_tps_per_user_p50": 0.0,
1275
+ "e2e_output_tps_per_user_p90": 0.0,
1276
+ "e2e_output_tps_per_user_p99": 0.0,
1277
+ "chunk_inter_token_latency_avg": 0.05457970341557859,
1278
+ "chunk_inter_token_latency_p50": 0.05436626649120276,
1279
+ "chunk_inter_token_latency_p90": 0.0550703617236811,
1280
+ "chunk_inter_token_latency_p99": 0.055535958764680565,
1281
+ "input_seq_len_avg": 78.0,
1282
+ "output_seq_len_avg": 852.875,
1283
+ "output_seq_len_p50": 858.0,
1284
+ "output_seq_len_p90": 860.0,
1285
+ "output_seq_len_p99": 860.0,
1286
+ "request_count": 8,
1287
+ "completed_request_count": 0,
1288
+ "request_samples": [
1289
+ {
1290
+ "ttft": 0.18924397500086343,
1291
+ "time_to_second_token": 0.5557156619979651,
1292
+ "latency": 0.0,
1293
+ "inter_token_latency_avg": 0.029685915205401887,
1294
+ "chunk_inter_token_latency_avg": 0.05558769176923606,
1295
+ "input_tokens": 78,
1296
+ "output_tokens": 853,
1297
+ "output_tps_per_user": 33.68600877152785,
1298
+ "e2e_output_tps_per_user": 0.0,
1299
+ "completed": false
1300
+ },
1301
+ {
1302
+ "ttft": 0.7448497290024534,
1303
+ "time_to_second_token": 0.04580788399471203,
1304
+ "latency": 0.0,
1305
+ "inter_token_latency_avg": 0.02941328024613101,
1306
+ "chunk_inter_token_latency_avg": 0.05412815905250805,
1307
+ "input_tokens": 78,
1308
+ "output_tokens": 842,
1309
+ "output_tps_per_user": 33.99824812574377,
1310
+ "e2e_output_tps_per_user": 0.0,
1311
+ "completed": false
1312
+ },
1313
+ {
1314
+ "ttft": 0.7445173209998757,
1315
+ "time_to_second_token": 0.04565656199702062,
1316
+ "latency": 0.0,
1317
+ "inter_token_latency_avg": 0.0287970987182752,
1318
+ "chunk_inter_token_latency_avg": 0.05424716622587367,
1319
+ "input_tokens": 78,
1320
+ "output_tokens": 860,
1321
+ "output_tps_per_user": 34.72572045479639,
1322
+ "e2e_output_tps_per_user": 0.0,
1323
+ "completed": false
1324
+ },
1325
+ {
1326
+ "ttft": 0.7442418000064208,
1327
+ "time_to_second_token": 0.0457358639978338,
1328
+ "latency": 0.0,
1329
+ "inter_token_latency_avg": 0.029695901545011304,
1330
+ "chunk_inter_token_latency_avg": 0.05436634282855916,
1331
+ "input_tokens": 78,
1332
+ "output_tokens": 834,
1333
+ "output_tps_per_user": 33.67468061154024,
1334
+ "e2e_output_tps_per_user": 0.0,
1335
+ "completed": false
1336
+ },
1337
+ {
1338
+ "ttft": 0.7443080910015851,
1339
+ "time_to_second_token": 0.04586725500121247,
1340
+ "latency": 0.0,
1341
+ "inter_token_latency_avg": 0.028864530066514276,
1342
+ "chunk_inter_token_latency_avg": 0.05472765988274941,
1343
+ "input_tokens": 78,
1344
+ "output_tokens": 858,
1345
+ "output_tps_per_user": 34.64459659296859,
1346
+ "e2e_output_tps_per_user": 0.0,
1347
+ "completed": false
1348
+ },
1349
+ {
1350
+ "ttft": 0.7443556240032194,
1351
+ "time_to_second_token": 0.045691526000155136,
1352
+ "latency": 0.0,
1353
+ "inter_token_latency_avg": 0.02886419663944002,
1354
+ "chunk_inter_token_latency_avg": 0.05436619015384637,
1355
+ "input_tokens": 78,
1356
+ "output_tokens": 858,
1357
+ "output_tps_per_user": 34.64499679279487,
1358
+ "e2e_output_tps_per_user": 0.0,
1359
+ "completed": false
1360
+ },
1361
+ {
1362
+ "ttft": 0.7444347540003946,
1363
+ "time_to_second_token": 0.04566599700046936,
1364
+ "latency": 0.0,
1365
+ "inter_token_latency_avg": 0.028796769146685452,
1366
+ "chunk_inter_token_latency_avg": 0.05436576856484133,
1367
+ "input_tokens": 78,
1368
+ "output_tokens": 860,
1369
+ "output_tps_per_user": 34.72611788170345,
1370
+ "e2e_output_tps_per_user": 0.0,
1371
+ "completed": false
1372
+ },
1373
+ {
1374
+ "ttft": 0.7440939939988311,
1375
+ "time_to_second_token": 0.04563847499957774,
1376
+ "latency": 0.0,
1377
+ "inter_token_latency_avg": 0.028864341458580658,
1378
+ "chunk_inter_token_latency_avg": 0.05484864884701469,
1379
+ "input_tokens": 78,
1380
+ "output_tokens": 858,
1381
+ "output_tps_per_user": 34.64482297075669,
1382
+ "e2e_output_tps_per_user": 0.0,
1383
+ "completed": false
1384
+ }
1385
+ ],
1386
+ "total_tokens": 5321,
1387
+ "wall_time": 25.544834804000857,
1388
+ "num_completed": 8,
1389
+ "num_errors": 0,
1390
+ "server_gen_throughput": 266.680480555613,
1391
+ "server_utilization": 0.015632633121641426,
1392
+ "server_spec_accept_rate": 0.8819444444444444,
1393
+ "server_spec_accept_length": 0.0,
1394
+ "avg_running_reqs": 8,
1395
+ "max_running_reqs": 8,
1396
+ "effective_concurrency": 8,
1397
+ "avg_queue_reqs": 0,
1398
+ "max_queue_reqs": 0,
1399
+ "queue_fraction": 0.0,
1400
+ "underfilled": false,
1401
+ "warmup_timed_out": false,
1402
+ "warmup_duration": 5.536,
1403
+ "ready_reason": "running_reqs=8/8, queue_reqs=0, active_streams=8/8, stable=3.0s",
1404
+ "timeout_reason": "",
1405
+ "capacity_limited": false,
1406
+ "hardware_summary": {
1407
+ "samples": 9,
1408
+ "duration_seconds": 19.354,
1409
+ "gpu_count": 4,
1410
+ "cpu_util_avg_pct": 12.69,
1411
+ "cpu_temp_max_c": 76.25,
1412
+ "gpu_util_avg_pct": 99.97,
1413
+ "gpu_util_max_pct": 100.0,
1414
+ "mem_util_avg_pct": 44.5,
1415
+ "mem_util_max_pct": 49.0,
1416
+ "temp_avg_c": 75.19,
1417
+ "temp_max_c": 90.0,
1418
+ "power_total_avg_w": 1123.54,
1419
+ "power_total_max_w": 1127.5,
1420
+ "power_limit_total_w": 1200.0,
1421
+ "vram_used_avg_mb": 381280.78,
1422
+ "vram_used_max_mb": 381285.0,
1423
+ "vram_total_mb": 391548.0,
1424
+ "vram_used_avg_pct": 97.38,
1425
+ "vram_used_max_pct": 97.38,
1426
+ "pcie_rx_avg_mb_s": 23034.0,
1427
+ "pcie_rx_max_mb_s": 23340.0,
1428
+ "pcie_tx_avg_mb_s": 22772.89,
1429
+ "pcie_tx_max_mb_s": 23334.0
1430
+ }
1431
+ }
1432
+ ],
1433
+ "summary_table": {
1434
+ "0": {
1435
+ "1": 48.90699346650318,
1436
+ "2": 112.8960533960185,
1437
+ "3": 153.96923383622084,
1438
+ "4": 188.17034108841304,
1439
+ "5": 218.22215529749218,
1440
+ "6": 239.40723639392317,
1441
+ "7": 253.85178855739426,
1442
+ "8": 266.7705425803283
1443
+ }
1444
+ },
1445
+ "burst_results": [],
1446
+ "burst_summary_table": {},
1447
+ "methodology": {
1448
+ "prefill": {
1449
+ "name": "Prefill",
1450
+ "present": false,
1451
+ "mode": "skipped",
1452
+ "formula": "prompt_tokens / TTFT",
1453
+ "notes": "Default mode records the required decode scout request for each non-zero decode context, so normal runs do not pay for a separate prefill phase. Standalone mode repeats cold-prefill samples. Prometheus prefill counters, when available and uncontaminated, are stored as validation."
1454
+ },
1455
+ "sustained_decode": {
1456
+ "name": "Sustained Decode",
1457
+ "present": true,
1458
+ "formula": "OpenAI stream usage completion_tokens per measured window; client chunk fallback only when continuous usage is unavailable",
1459
+ "notes": "Duration-based steady-state cell after warmup. This is the main tuning/regression signal for kernels, NCCL, DCP, MTP, and scheduling. Prometheus metrics are stored as validation and scheduler state, not the default headline."
1460
+ },
1461
+ "burst_e2e_decode": {
1462
+ "name": "Burst / E2E Decode",
1463
+ "present": false,
1464
+ "status": "not run; use --run-burst",
1465
+ "formula": "sum(completion_tokens) / profiling_wall_time",
1466
+ "notes": "Finite client-facing request burst using OpenAI stream usage. It includes request admission, scheduling, prefill/cache behavior, and completion."
1467
+ }
1468
+ }
1469
+ }
benchmarks/2026-07-22/decode-c1-c8.log ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ╭──────────────────────────── NVIDIA P2P Override ─────────────────────────────╮
2
+ │ Effective: yes │
3
+ │ Configured file: yes (/etc/modprobe.d/nvidia-p2p-override.conf) │
4
+ │ Runtime: ForceP2P=0x11; RMForceP2PType=1; RMPcieP2PType=2; │
5
+ │ GrdmaPciTopoCheckOverride=1; EnableResizableBar=1; DmaRemapPeerMmio=1 │
6
+ ╰──────────────────────────────────────────────────────────────────────────────╯
7
+ ╭─────────────────────────────── Configuration ────────────────────────────────╮
8
+ │ LLM Inference Benchmark │
9
+ │ Model: GLM-5.2-EXL3-TR3-3.0bpw @ 127.0.0.1:8000 │
10
+ │ Decode concurrency: [1, 2, 3, 4, 5, 6, 7, 8] │
11
+ │ Decode contexts: ['0'] │
12
+ │ Duration: 20.0s per decode test | Max tokens: 8192 │
13
+ │ Pre-decode warmup: C=1 max-runnable context for 3s │
14
+ │ Prefill: skipped | Sustained decode: 8 cells │
15
+ ╰──────────────────────────────────────────────────────────────────────────────╯
16
+ Engine: vLLM 0.17.0rc1.dev4499+g60c82d972 Models: ['GLM-5.2-EXL3-TR3-3.0bpw']
17
+ KV cache budget (vLLM metrics): 524,288 tokens (2048 blocks × 64; local 131,072
18
+ × CP 4; CP source: local process)
19
+ Model context length: 524,288 tokens
20
+ Prefill tests: skipped
21
+ Done.
22
+
23
+
24
+
25
+ llm-decode-bench v0.4.29
26
+ ╭────────────────────────────────── Phase 2 ───────────────────────────────────╮
27
+ │ Sustained Decode │
28
+ │ Steady-state decode throughput after the engine has admitted the requested │
29
+ │ concurrency and passed warmup. Use this as the main tuning/regression signal │
30
+ │ for kernels, NCCL, DCP, MTP, and scheduler changes. │
31
+ ╰──────────────────────────────────────────────────────────────────────────────╯
32
+ Aggregate tok/s + TTFT/ITL
33
+ ╭────────┬────────┬────────┬────────┬────────┬────────┬───────┬────────┬───────╮
34
+ │ ctx \ │ │ │ │ │ │ │ │ │
35
+ │ conc │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │
36
+ ├────────┼────────┼────────┼────────┼────────┼────────┼───────┼────────┼───────┤
37
+ │ 0 │ 48.9 │ 112.9 │ 154.0 │ 188.2 │ 218.2 │ 239.4 │ 253.9 │ 266.8 │
38
+ │ │ 180/20 │ 275/18 │ 440/19 │ 507/21 │ 581/22 │ 622/… │ 680/27 │ 744/… │
39
+ ╰────────┴────────┴────────┴────────┴────────┴────────┴───────┴────────┴───────╯
40
+ Sustained Decode: aggregate tok/s uses OpenAI stream usage by default
41
+ (continuous completion_tokens when the server supports it). Prometheus is kept
42
+ as validation/scheduler data.
43
+ Aggregate source(s): openai_continuous_usage
44
+ Per-Request tok/s
45
+ ╭────────────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────╮
46
+ │ ctx \ conc │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │
47
+ ├────────────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┼──────┤
48
+ │ 0 │ 48.9 │ 56.4 │ 51.3 │ 47.0 │ 43.6 │ 39.9 │ 36.3 │ 33.3 │
49
+ ╰─────���──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────╯
50
+ Client request latency: p50 / p90 ms
51
+ ╭────────────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────╮
52
+ │ ctx \ conc │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │
53
+ ├────────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
54
+ │ 0 │ —/— │ —/— │ —/— │ —/— │ —/— │ —/— │ —/— │ —/— │
55
+ ╰────────────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────╯
56
+ Aggregate cells show dim detail as TTFT ms / ITL ms for the same ctx/conc
57
+ coordinate. ITL is computed from observed generated tokens, including streams
58
+ stopped at the measurement boundary; a missing ITL means no stream produced at
59
+ least two measured output tokens. Per-request tok/s and request latency are
60
+ shown in separate per-cell matrices. Completion/sample counts and full
61
+ request-level distributions remain in JSON under request_samples.
62
+ Sustained mode: client latency metrics explain request UX variance; aggregate
63
+ tok/s remains the primary throughput signal.
64
+ ITL=(last_token_time-first_token_time)/(output_tokens-1), user tok/s=1/ITL.
65
+ Hardware Summary
66
+ ╭───┬─┬───────┬───────────┬───────┬─────────┬─────┬──────┬─────┬───────────────╮
67
+ │ … │ │ mode │ GPU avg/… │ Mem … │ W avg/… │ T … │ CPU… │ VR… │ PCIe rx/tx a… │
68
+ ├───┼─┼───────┼───────────┼───────┼─────────┼─────┼──────┼─────┼───────────────┤
69
+ │ 0 │ │ sust… │ 99/100% │ 35% │ 1026/1… │ 84C │ 76C │ 97… │ 4783/4729 │
70
+ │ 0 │ │ sust… │ 99/100% │ 43% │ 1059/1… │ 87C │ 74C │ 97… │ 10779/10735 │
71
+ │ 0 │ │ sust… │ 99/100% │ 46% │ 1090/1… │ 89C │ 75C │ 97… │ 14819/14799 │
72
+ │ 0 │ │ sust… │ 100/100% │ 45% │ 1100/1… │ 89C │ 74C │ 97… │ 17081/17304 │
73
+ │ 0 │ │ sust… │ 100/100% │ 44% │ 1103/1… │ 89C │ 76C │ 97… │ 19600/19942 │
74
+ │ 0 │ │ sust… │ 100/100% │ 43% │ 1110/1… │ 89C │ 74C │ 97… │ 21495/21025 │
75
+ │ 0 │ │ sust… │ 100/100% │ 44% │ 1118/1… │ 89C │ 75C │ 97… │ 21868/21466 │
76
+ │ 0 │ │ sust… │ 100/100% │ 44% │ 1124/1… │ 90C │ 76C │ 97… │ 23034/22773 │
77
+ ╰───┴─┴───────┴───────────┴───────┴─────────┴─────┴──────┴─────┴───────────────╯
78
+ ╭──────────────────────── Whole-run GPU Power ─────────────────────────╮
79
+ │ avg 1,038 W | max 1,128 W | limit 1,200 W | over 3m 49s | 96 samples │
80
+ ╰──────────────────────────────────────────────────────────────────────╯
81
+ Hardware summary is sampled from nvidia-smi during the measured part of each
82
+ cell. Whole-run GPU power is the sampled sum of GPU power draw across the
83
+ complete benchmark run, not wall-outlet system power. PCIe rx/tx is MB/s and is
84
+ a coarse live diagnostic, not a per-kernel NCCL profiler.
85
+
86
+ ╭────────────────────────────────── Phase 3 ───────────────────────────────────╮
87
+ │ Burst / E2E Decode │
88
+ │ Not run. Re-run with --run-burst to append a finite client-facing request │
89
+ │ burst after Sustained Decode. This is intentionally disabled by default │
90
+ │ because it adds another full decode matrix. │
91
+ ╰──────────────────────────────────────────────────────────────────────────────╯
92
+
93
+ ╭───────────────��────────────── Primary Summary ───────────────────────────────╮
94
+ │ Primary matrices repeated last so the important numbers are visible without │
95
+ │ scrolling back through diagnostics. │
96
+ ╰──────────────────────────────────────────────────────────────────────────────╯
97
+ Aggregate decode tok/s
98
+ ╭────────────┬──────┬───────┬───────┬───────┬───────┬───────┬───────┬───────╮
99
+ │ ctx \ conc │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │
100
+ ├────────────┼──────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┤
101
+ │ 0 │ 48.9 │ 112.9 │ 154.0 │ 188.2 │ 218.2 │ 239.4 │ 253.9 │ 266.8 │
102
+ ╰────────────┴──────┴───────┴───────┴───────┴───────┴───────┴───────┴───────╯
103
+
104
+ Results saved to results/20260722T091010Z-mtp1-dcp4-async-off/decode-c1-c8.json
benchmarks/2026-07-22/decode-c1-dedicated.json ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "metadata": {
3
+ "version": "0.4.29",
4
+ "engine": "vllm",
5
+ "model": "GLM-5.2-EXL3-TR3-3.0bpw",
6
+ "server": "127.0.0.1:8000",
7
+ "timestamp": "2026-07-22T05:42:02.291644",
8
+ "decode_mode": "duration",
9
+ "primary_decode_layer": "sustained_decode",
10
+ "duration_per_test": 30.0,
11
+ "request_count": 0,
12
+ "warmup_request_count": 0,
13
+ "run_burst": false,
14
+ "prefill_mode": "skipped",
15
+ "standalone_prefill": false,
16
+ "prefill_only": false,
17
+ "skip_prefill": true,
18
+ "burst_e2e_status": "not_run_use_--run-burst",
19
+ "burst_request_count": 0,
20
+ "burst_warmup_request_count": 0,
21
+ "burst_requests_per_concurrency": 5,
22
+ "decode_warmup_seconds": 3.0,
23
+ "decode_warmup_context": 0,
24
+ "decode_warmup_concurrency": 1,
25
+ "cell_warmup_timeout_seconds": 0.0,
26
+ "cell_warmup_timeout_policy": "<=32k:60s,64k:120s,>=128k:180s when override is 0",
27
+ "show_capacity_limited_values": false,
28
+ "max_tokens": 8192,
29
+ "temperature": 0.0,
30
+ "ignore_eos": true,
31
+ "max_total_tokens": 524288,
32
+ "dcp_size": 0,
33
+ "metrics_available": true,
34
+ "metrics_warning": "",
35
+ "concurrency_levels": [
36
+ 1
37
+ ],
38
+ "context_lengths": [
39
+ 0
40
+ ],
41
+ "startup_diagnostics_available": true,
42
+ "nvidia_p2p_override_effective": true,
43
+ "p2pmark_status": "not_run",
44
+ "amd_fabric_status": "not_run"
45
+ },
46
+ "startup_diagnostics": {
47
+ "version": "0.4.29",
48
+ "server_url": "http://127.0.0.1:8000",
49
+ "hostname": "pop-os",
50
+ "uname": "Linux pop-os 6.18.7-76061807-generic #202601231045~1769703228~24.04~cb87b5b SMP PREEMPT_DYNAMIC Thu J x86_64 x86_64 x86_64 GNU/Linux",
51
+ "env": {},
52
+ "args": {
53
+ "concurrency": "1",
54
+ "contexts": "0",
55
+ "max_tokens": 8192,
56
+ "duration": 30.0,
57
+ "request_count": 0,
58
+ "run_burst": false,
59
+ "standalone_prefill": false,
60
+ "prefill_only": false,
61
+ "skip_prefill": true,
62
+ "prefill_contexts": "8k,64k,128k",
63
+ "prefill_metric": "client",
64
+ "dcp_size": 0,
65
+ "kv_budget": 0
66
+ },
67
+ "nvidia_p2p_override": {
68
+ "effective": true,
69
+ "configured": true,
70
+ "params_path": "/proc/driver/nvidia/params",
71
+ "params_available": true,
72
+ "modprobe_path": "/etc/modprobe.d/nvidia-p2p-override.conf",
73
+ "modprobe_available": true,
74
+ "runtime": {
75
+ "ForceP2P": "0x11",
76
+ "RMForceP2PType": "1",
77
+ "RMPcieP2PType": "2",
78
+ "GrdmaPciTopoCheckOverride": "1",
79
+ "EnableResizableBar": "1",
80
+ "DmaRemapPeerMmio": "1"
81
+ },
82
+ "expected": {
83
+ "ForceP2P": "0x11",
84
+ "RMForceP2PType": "1",
85
+ "RMPcieP2PType": "2",
86
+ "GrdmaPciTopoCheckOverride": "1",
87
+ "EnableResizableBar": "1"
88
+ },
89
+ "missing": [],
90
+ "mismatched": {},
91
+ "registry_dwords": "ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1",
92
+ "suggested_modprobe_line": "options nvidia NVreg_RegistryDwords=\"ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1\"",
93
+ "suggested_reload": "stop GPU workloads, then reload NVIDIA modules or reboot; the modprobe file alone is not enough until the nvidia module is reloaded"
94
+ },
95
+ "p2pmark": {
96
+ "status": "not_run"
97
+ },
98
+ "amd_fabric": {
99
+ "status": "not_run"
100
+ },
101
+ "nvidia_smi_query": {
102
+ "cmd": [
103
+ "nvidia-smi",
104
+ "--query-gpu=index,name,driver_version,pci.bus_id,pcie.link.gen.current,pcie.link.width.current,power.limit",
105
+ "--format=csv,noheader,nounits"
106
+ ],
107
+ "returncode": 0,
108
+ "stdout": "0, NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition, 595.58.03, 00000000:01:00.0, 1, 16, 300.00\n1, NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 595.58.03, 00000000:21:00.0, 5, 16, 300.00\n2, NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition, 595.58.03, 00000000:81:00.0, 1, 16, 300.00\n3, NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 595.58.03, 00000000:C1:00.0, 1, 16, 300.00",
109
+ "stderr": ""
110
+ },
111
+ "nvidia_smi_topo": {
112
+ "cmd": [
113
+ "nvidia-smi",
114
+ "topo",
115
+ "-m"
116
+ ],
117
+ "returncode": 0,
118
+ "stdout": "\u001b[4mGPU0\tGPU1\tGPU2\tGPU3\tCPU Affinity\tNUMA Affinity\tGPU NUMA ID\u001b[0m\nGPU0\t X \tNODE\tNODE\tNODE\t0-47\t0\t\tN/A\nGPU1\tNODE\t X \tNODE\tNODE\t0-47\t0\t\tN/A\nGPU2\tNODE\tNODE\t X \tNODE\t0-47\t0\t\tN/A\nGPU3\tNODE\tNODE\tNODE\t X \t0-47\t0\t\tN/A\n\nLegend:\n\n X = Self\n SYS = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI)\n NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node\n PHB = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU)\n PXB = Connection traversing multiple PCIe bridges (without traversing the PCIe Host Bridge)\n PIX = Connection traversing at most a single PCIe bridge\n NV# = Connection traversing a bonded set of # NVLinks",
119
+ "stderr": ""
120
+ }
121
+ },
122
+ "nvidia_p2p_override": {
123
+ "effective": true,
124
+ "configured": true,
125
+ "params_path": "/proc/driver/nvidia/params",
126
+ "params_available": true,
127
+ "modprobe_path": "/etc/modprobe.d/nvidia-p2p-override.conf",
128
+ "modprobe_available": true,
129
+ "runtime": {
130
+ "ForceP2P": "0x11",
131
+ "RMForceP2PType": "1",
132
+ "RMPcieP2PType": "2",
133
+ "GrdmaPciTopoCheckOverride": "1",
134
+ "EnableResizableBar": "1",
135
+ "DmaRemapPeerMmio": "1"
136
+ },
137
+ "expected": {
138
+ "ForceP2P": "0x11",
139
+ "RMForceP2PType": "1",
140
+ "RMPcieP2PType": "2",
141
+ "GrdmaPciTopoCheckOverride": "1",
142
+ "EnableResizableBar": "1"
143
+ },
144
+ "missing": [],
145
+ "mismatched": {},
146
+ "registry_dwords": "ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1",
147
+ "suggested_modprobe_line": "options nvidia NVreg_RegistryDwords=\"ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1\"",
148
+ "suggested_reload": "stop GPU workloads, then reload NVIDIA modules or reboot; the modprobe file alone is not enough until the nvidia module is reloaded"
149
+ },
150
+ "p2pmark": {
151
+ "status": "not_run"
152
+ },
153
+ "amd_fabric": {
154
+ "status": "not_run"
155
+ },
156
+ "hardware_run_summary": {
157
+ "samples": 21,
158
+ "duration_seconds": 48.435,
159
+ "gpu_count": 4,
160
+ "cpu_util_avg_pct": 15.24,
161
+ "cpu_temp_max_c": 73.5,
162
+ "gpu_util_avg_pct": 86.33,
163
+ "gpu_util_max_pct": 100.0,
164
+ "mem_util_avg_pct": 30.18,
165
+ "mem_util_max_pct": 41.0,
166
+ "temp_avg_c": 65.1,
167
+ "temp_max_c": 82.0,
168
+ "power_total_avg_w": 923.48,
169
+ "power_total_max_w": 1027.39,
170
+ "power_limit_total_w": 1200.0,
171
+ "vram_used_avg_mb": 381283.57,
172
+ "vram_used_max_mb": 381293.0,
173
+ "vram_total_mb": 391548.0,
174
+ "vram_used_avg_pct": 97.38,
175
+ "vram_used_max_pct": 97.38,
176
+ "pcie_rx_avg_mb_s": 4498.86,
177
+ "pcie_rx_max_mb_s": 5098.0,
178
+ "pcie_tx_avg_mb_s": 4404.48,
179
+ "pcie_tx_max_mb_s": 5004.0
180
+ },
181
+ "event_log": [
182
+ "05:41:12 benchmark start engine=vllm",
183
+ "05:41:12 startup server=http://127.0.0.1:8000 model=GLM-5.2-EXL3-TR3-3.0bpw",
184
+ "05:41:12 startup decode concurrency=1 contexts=0",
185
+ "05:41:12 startup NVIDIA P2P override: enabled: runtime NVIDIA P2P override matches expected RegistryDwords",
186
+ "05:41:12 startup engine vLLM 0.17.0rc1.dev4499+g60c82d972 models=['GLM-5.2-EXL3-TR3-3.0bpw']",
187
+ "05:41:12 startup KV cache budget from vLLM metrics: 524,288 tokens (2048 blocks x 64; local 131,072 \u00d7 CP 4; CP source: local process)",
188
+ "05:41:12 startup model context length: 524,288 tokens",
189
+ "05:41:12 startup prefill tests: skipped",
190
+ "05:41:12 startup startup preparation done",
191
+ "05:41:12 hardware monitor interval=2s",
192
+ "05:41:12 decode warmup start",
193
+ "05:41:14 decode warmup start C=1 ctx=0 3s",
194
+ "05:41:14 cell start C=1 ctx=0",
195
+ "05:41:19 ready C=1 ctx=0 running_reqs=1/1, queue_reqs=0, active_streams=1/1, stable=3.0s",
196
+ "05:41:22 cell done C=1 ctx=0 50.8 tok/s",
197
+ "05:41:22 decode warmup done C=1 ctx=0",
198
+ "05:41:24 cell start C=1 ctx=0",
199
+ "05:41:30 ready C=1 ctx=0 running_reqs=1/1, queue_reqs=0, active_streams=1/1, stable=3.0s",
200
+ "05:42:00 cell done C=1 ctx=0 48.5 tok/s"
201
+ ],
202
+ "prefill": {},
203
+ "results": [
204
+ {
205
+ "concurrency": 1,
206
+ "context_tokens": 0,
207
+ "benchmark_mode": "duration",
208
+ "request_count_target": 0,
209
+ "warmup_request_count": 0,
210
+ "measurement_seconds": 29.966859,
211
+ "measurement_wall_seconds": 30.001007,
212
+ "client_output_tokens": 1454,
213
+ "server_output_tokens": 1454,
214
+ "aggregate_source": "openai_continuous_usage",
215
+ "aggregate_tps": 48.52026671742388,
216
+ "per_request_avg_tps": 48.52026671742388,
217
+ "ttft_avg": 0.18306065399519866,
218
+ "ttft_p50": 0.18306065399519866,
219
+ "ttft_p90": 0.18306065399519866,
220
+ "ttft_p99": 0.18306065399519866,
221
+ "time_to_second_token_avg": 0.03935272800299572,
222
+ "time_to_second_token_p50": 0.03935272800299572,
223
+ "time_to_second_token_p90": 0.03935272800299572,
224
+ "time_to_second_token_p99": 0.03935272800299572,
225
+ "request_latency_avg": 0.0,
226
+ "request_latency_p50": 0.0,
227
+ "request_latency_p90": 0.0,
228
+ "request_latency_p99": 0.0,
229
+ "inter_token_latency_avg": 0.020438049012732842,
230
+ "inter_token_latency_p50": 0.020438049012732842,
231
+ "inter_token_latency_p90": 0.020438049012732842,
232
+ "inter_token_latency_p99": 0.020438049012732842,
233
+ "output_tps_per_user_avg": 48.92834924590909,
234
+ "output_tps_per_user_p50": 48.92834924590909,
235
+ "output_tps_per_user_p90": 48.92834924590909,
236
+ "output_tps_per_user_p99": 48.92834924590909,
237
+ "e2e_output_tps_per_user_avg": 0.0,
238
+ "e2e_output_tps_per_user_p50": 0.0,
239
+ "e2e_output_tps_per_user_p90": 0.0,
240
+ "e2e_output_tps_per_user_p99": 0.0,
241
+ "chunk_inter_token_latency_avg": 0.03893820142668396,
242
+ "chunk_inter_token_latency_p50": 0.03893820142668396,
243
+ "chunk_inter_token_latency_p90": 0.03893820142668396,
244
+ "chunk_inter_token_latency_p99": 0.03893820142668396,
245
+ "input_seq_len_avg": 78.0,
246
+ "output_seq_len_avg": 1729.0,
247
+ "output_seq_len_p50": 1729.0,
248
+ "output_seq_len_p90": 1729.0,
249
+ "output_seq_len_p99": 1729.0,
250
+ "request_count": 1,
251
+ "completed_request_count": 0,
252
+ "request_samples": [
253
+ {
254
+ "ttft": 0.18306065399519866,
255
+ "time_to_second_token": 0.03935272800299572,
256
+ "latency": 0.0,
257
+ "inter_token_latency_avg": 0.020438049012732842,
258
+ "chunk_inter_token_latency_avg": 0.03893820142668396,
259
+ "input_tokens": 78,
260
+ "output_tokens": 1729,
261
+ "output_tps_per_user": 48.92834924590909,
262
+ "e2e_output_tps_per_user": 0.0,
263
+ "completed": false
264
+ }
265
+ ],
266
+ "total_tokens": 1454,
267
+ "wall_time": 35.541310323998914,
268
+ "num_completed": 1,
269
+ "num_errors": 0,
270
+ "server_gen_throughput": 48.45453833744349,
271
+ "server_utilization": 0.0039081582804103565,
272
+ "server_spec_accept_rate": 0.92,
273
+ "server_spec_accept_length": 0.0,
274
+ "avg_running_reqs": 1,
275
+ "max_running_reqs": 1,
276
+ "effective_concurrency": 1,
277
+ "avg_queue_reqs": 0,
278
+ "max_queue_reqs": 0,
279
+ "queue_fraction": 0.0,
280
+ "underfilled": false,
281
+ "warmup_timed_out": false,
282
+ "warmup_duration": 5.533,
283
+ "ready_reason": "running_reqs=1/1, queue_reqs=0, active_streams=1/1, stable=3.0s",
284
+ "timeout_reason": "",
285
+ "capacity_limited": false,
286
+ "hardware_summary": {
287
+ "samples": 12,
288
+ "duration_seconds": 26.677,
289
+ "gpu_count": 4,
290
+ "cpu_util_avg_pct": 12.88,
291
+ "cpu_temp_max_c": 73.5,
292
+ "gpu_util_avg_pct": 99.4,
293
+ "gpu_util_max_pct": 100.0,
294
+ "mem_util_avg_pct": 34.5,
295
+ "mem_util_max_pct": 40.0,
296
+ "temp_avg_c": 66.85,
297
+ "temp_max_c": 82.0,
298
+ "power_total_avg_w": 1006.3,
299
+ "power_total_max_w": 1013.08,
300
+ "power_limit_total_w": 1200.0,
301
+ "vram_used_avg_mb": 381282.08,
302
+ "vram_used_max_mb": 381283.0,
303
+ "vram_total_mb": 391548.0,
304
+ "vram_used_avg_pct": 97.38,
305
+ "vram_used_max_pct": 97.38,
306
+ "pcie_rx_avg_mb_s": 4737.58,
307
+ "pcie_rx_max_mb_s": 5017.0,
308
+ "pcie_tx_avg_mb_s": 4647.08,
309
+ "pcie_tx_max_mb_s": 4899.0
310
+ }
311
+ }
312
+ ],
313
+ "summary_table": {
314
+ "0": {
315
+ "1": 48.52026671742388
316
+ }
317
+ },
318
+ "burst_results": [],
319
+ "burst_summary_table": {},
320
+ "methodology": {
321
+ "prefill": {
322
+ "name": "Prefill",
323
+ "present": false,
324
+ "mode": "skipped",
325
+ "formula": "prompt_tokens / TTFT",
326
+ "notes": "Default mode records the required decode scout request for each non-zero decode context, so normal runs do not pay for a separate prefill phase. Standalone mode repeats cold-prefill samples. Prometheus prefill counters, when available and uncontaminated, are stored as validation."
327
+ },
328
+ "sustained_decode": {
329
+ "name": "Sustained Decode",
330
+ "present": true,
331
+ "formula": "OpenAI stream usage completion_tokens per measured window; client chunk fallback only when continuous usage is unavailable",
332
+ "notes": "Duration-based steady-state cell after warmup. This is the main tuning/regression signal for kernels, NCCL, DCP, MTP, and scheduling. Prometheus metrics are stored as validation and scheduler state, not the default headline."
333
+ },
334
+ "burst_e2e_decode": {
335
+ "name": "Burst / E2E Decode",
336
+ "present": false,
337
+ "status": "not run; use --run-burst",
338
+ "formula": "sum(completion_tokens) / profiling_wall_time",
339
+ "notes": "Finite client-facing request burst using OpenAI stream usage. It includes request admission, scheduling, prefill/cache behavior, and completion."
340
+ }
341
+ }
342
+ }
benchmarks/2026-07-22/decode-c1-dedicated.log ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ╭──────────────────────────── NVIDIA P2P Override ─────────────────────────────╮
2
+ │ Effective: yes │
3
+ │ Configured file: yes (/etc/modprobe.d/nvidia-p2p-override.conf) │
4
+ │ Runtime: ForceP2P=0x11; RMForceP2PType=1; RMPcieP2PType=2; │
5
+ │ GrdmaPciTopoCheckOverride=1; EnableResizableBar=1; DmaRemapPeerMmio=1 │
6
+ ╰──────────────────────────────────────────────────────────────────────────────╯
7
+ ╭─────────────────────────────── Configuration ────────────────────────────────╮
8
+ │ LLM Inference Benchmark │
9
+ │ Model: GLM-5.2-EXL3-TR3-3.0bpw @ 127.0.0.1:8000 │
10
+ │ Decode concurrency: [1] │
11
+ │ Decode contexts: ['0'] │
12
+ │ Duration: 30.0s per decode test | Max tokens: 8192 │
13
+ │ Pre-decode warmup: C=1 max-runnable context for 3s │
14
+ │ Prefill: skipped | Sustained decode: 1 cells │
15
+ ╰──────────────────────────────────────────────────────────────────────────────╯
16
+ Engine: vLLM 0.17.0rc1.dev4499+g60c82d972 Models: ['GLM-5.2-EXL3-TR3-3.0bpw']
17
+ KV cache budget (vLLM metrics): 524,288 tokens (2048 blocks × 64; local 131,072
18
+ × CP 4; CP source: local process)
19
+ Model context length: 524,288 tokens
20
+ Prefill tests: skipped
21
+ Done.
22
+
23
+
24
+
25
+ llm-decode-bench v0.4.29
26
+ ╭────────────────────────────────── Phase 2 ───────────────────────────────────╮
27
+ │ Sustained Decode │
28
+ │ Steady-state decode throughput after the engine has admitted the requested │
29
+ │ concurrency and passed warmup. Use this as the main tuning/regression signal │
30
+ │ for kernels, NCCL, DCP, MTP, and scheduler changes. │
31
+ ╰──────────────────────────────────────────────────────────────────────────────╯
32
+ Aggregate tok/s + TTFT/ITL
33
+ ╭────────────┬─────────────╮
34
+ │ ctx \ conc │ 1 │
35
+ ├────────────┼─────────────┤
36
+ │ 0 │ 48.5 183/20 │
37
+ ╰────────────┴─────────────╯
38
+ Sustained Decode: aggregate tok/s uses OpenAI stream usage by default
39
+ (continuous completion_tokens when the server supports it). Prometheus is kept
40
+ as validation/scheduler data.
41
+ Aggregate source(s): openai_continuous_usage
42
+ Per-Request tok/s
43
+ ╭────────────┬──────╮
44
+ │ ctx \ conc │ 1 │
45
+ ├────────────┼──────┤
46
+ │ 0 │ 48.5 │
47
+ ╰────────────┴──────╯
48
+ Client request
49
+ latency: p50 / p90
50
+ ms
51
+ ╭────────────┬─────╮
52
+ │ ctx \ conc │ 1 │
53
+ ├────────────┼─────┤
54
+ │ 0 │ —/— │
55
+ ╰────────────┴─────╯
56
+ Aggregate cells show dim detail as TTFT ms / ITL ms for the same ctx/conc
57
+ coordinate. ITL is computed from observed generated tokens, including streams
58
+ stopped at the measurement boundary; a missing ITL means no stream produced at
59
+ least two measured output tokens. Per-request tok/s and request latency are
60
+ shown in separate per-cell matrices. Completion/sample counts and full
61
+ request-level distributions remain in JSON under request_samples.
62
+ Sustained mode: client latency metrics explain request UX variance; aggregate
63
+ tok/s remains the primary throughput signal.
64
+ ITL=(last_token_time-first_token_time)/(output_tokens-1), user tok/s=1/ITL.
65
+ Hardware Summary
66
+ ╭───┬─┬───────┬───────────┬───────┬─────────┬─────┬──────┬─────┬───────────────╮
67
+ │ … │ │ mode │ GPU avg/… │ Mem … │ W avg/… │ T … │ CPU… │ VR… │ PCIe rx/tx a… │
68
+ ├───┼─┼───────┼───────────┼───────┼─────────┼─────┼──────┼─────┼───────────────┤
69
+ │ 0 │ │ sust… │ 99/100% │ 34% │ 1006/1… │ 82C │ 74C │ 97… │ 4738/4647 │
70
+ ╰───┴─┴───────┴───────────┴───────┴─────────┴─────┴──────┴─────┴───────────────╯
71
+ ╭────────────────────── Whole-run GPU Power ──────────────────────╮
72
+ │ avg 923 W | max 1,027 W | limit 1,200 W | over 48s | 21 samples │
73
+ ╰─────────────────────────────────────────────────────────────────╯
74
+ Hardware summary is sampled from nvidia-smi during the measured part of each
75
+ cell. Whole-run GPU power is the sampled sum of GPU power draw across the
76
+ complete benchmark run, not wall-outlet system power. PCIe rx/tx is MB/s and is
77
+ a coarse live diagnostic, not a per-kernel NCCL profiler.
78
+
79
+ ╭────────────────────────────────── Phase 3 ───────────────────────────────────╮
80
+ │ Burst / E2E Decode │
81
+ │ Not run. Re-run with --run-burst to append a finite client-facing request │
82
+ │ burst after Sustained Decode. This is intentionally disabled by default │
83
+ │ because it adds another full decode matrix. │
84
+ ╰──────────────────────────────────────────────────────────────────────────────╯
85
+
86
+ ╭────────────────────────────── Primary Summary ───────────────────────────────╮
87
+ │ Primary matrices repeated last so the important numbers are visible without │
88
+ │ scrolling back through diagnostics. │
89
+ ╰──────────────────────────────────────────────────────────────────────────────╯
90
+ Aggregate decode
91
+ tok/s
92
+ ╭────────────┬──────╮
93
+ │ ctx \ conc │ 1 │
94
+ ├────────────┼──────┤
95
+ │ 0 │ 48.5 │
96
+ ╰────────────┴──────╯
97
+
98
+ Results saved to
99
+ results/20260722T091010Z-mtp1-dcp4-async-off/decode-c1-dedicated.json
benchmarks/2026-07-22/estonia-c5-r5.json ADDED
@@ -0,0 +1,542 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "metadata": {
3
+ "version": "0.4.29",
4
+ "mode": "completion_stats",
5
+ "interrupted": false,
6
+ "server": "http://127.0.0.1:8000",
7
+ "engine": "openai_proxy",
8
+ "server_version": "",
9
+ "kv_budget": 0,
10
+ "kv_source": "",
11
+ "max_running_requests": 0,
12
+ "model": "GLM-5.2-EXL3-TR3-3.0bpw",
13
+ "models": [
14
+ "GLM-5.2-EXL3-TR3-3.0bpw"
15
+ ],
16
+ "test_profile": "estonia",
17
+ "test_profile_description": "Long-context GLM dense-MLA vs NSA diagnostic task. The expected final answer is Estonia; completion-token statistics show how many decode tokens the engine needs to reach that answer.",
18
+ "prompt_source": "profile:estonia",
19
+ "prompt_chars": 707372,
20
+ "timestamp": "2026-07-22T05:30:46.949170",
21
+ "max_tokens": 5000,
22
+ "token_limit_field": "max_tokens",
23
+ "max_tokens_omitted": false,
24
+ "fixed_concurrency": 5,
25
+ "requested_runs": 5,
26
+ "concurrency_levels_requested": [
27
+ 5
28
+ ],
29
+ "min_results": 5,
30
+ "probe_waves": 1,
31
+ "auto_stop": true,
32
+ "min_improvement": 0.03,
33
+ "patience": 1,
34
+ "correct_regex": "\\bestonia\\b",
35
+ "score_source": "final_answer",
36
+ "profile_scorer": "regex",
37
+ "expected_answer": "",
38
+ "approx_tolerance": "",
39
+ "dataset_rows": "",
40
+ "dataset_sha256": "",
41
+ "dataset": "",
42
+ "dataset_path": "",
43
+ "dataset_source": "",
44
+ "dataset_items_total": 0,
45
+ "dataset_items_selected": 0,
46
+ "prompt_sha256": "",
47
+ "prefill_scout": true,
48
+ "temperature": 0.0,
49
+ "top_p": null,
50
+ "repetition_penalty": 1.25,
51
+ "request_overrides": {},
52
+ "system_prompt": false,
53
+ "nvidia_p2p_override_effective": true,
54
+ "p2pmark_status": "not_run",
55
+ "amd_fabric_status": "not_run"
56
+ },
57
+ "nvidia_p2p_override": {
58
+ "effective": true,
59
+ "configured": true,
60
+ "params_path": "/proc/driver/nvidia/params",
61
+ "params_available": true,
62
+ "modprobe_path": "/etc/modprobe.d/nvidia-p2p-override.conf",
63
+ "modprobe_available": true,
64
+ "runtime": {
65
+ "ForceP2P": "0x11",
66
+ "RMForceP2PType": "1",
67
+ "RMPcieP2PType": "2",
68
+ "GrdmaPciTopoCheckOverride": "1",
69
+ "EnableResizableBar": "1",
70
+ "DmaRemapPeerMmio": "1"
71
+ },
72
+ "expected": {
73
+ "ForceP2P": "0x11",
74
+ "RMForceP2PType": "1",
75
+ "RMPcieP2PType": "2",
76
+ "GrdmaPciTopoCheckOverride": "1",
77
+ "EnableResizableBar": "1"
78
+ },
79
+ "missing": [],
80
+ "mismatched": {},
81
+ "registry_dwords": "ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1",
82
+ "suggested_modprobe_line": "options nvidia NVreg_RegistryDwords=\"ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1\"",
83
+ "suggested_reload": "stop GPU workloads, then reload NVIDIA modules or reboot; the modprobe file alone is not enough until the nvidia module is reloaded"
84
+ },
85
+ "p2pmark": {
86
+ "status": "not_run"
87
+ },
88
+ "amd_fabric": {
89
+ "status": "not_run"
90
+ },
91
+ "prefill_scout": {
92
+ "run_index": 0,
93
+ "phase": "prefill_scout",
94
+ "concurrency": 1,
95
+ "ok": true,
96
+ "correct": null,
97
+ "completion_tokens": 1,
98
+ "prompt_tokens": 133186,
99
+ "elapsed": 115.87873174100241,
100
+ "gen_elapsed": 0.0,
101
+ "ttft": 115.87825518200407,
102
+ "time_to_second_token": 0.0,
103
+ "gen_tok_s": 0.0,
104
+ "e2e_tok_s": 0.008629711293657187,
105
+ "finish_reason": "length",
106
+ "final_answer": "We",
107
+ "score_label": "",
108
+ "score_detail": "",
109
+ "parsed_answer": "",
110
+ "output_excerpt": "We",
111
+ "output_text": "",
112
+ "reasoning_text": "",
113
+ "content_text": "",
114
+ "error": "",
115
+ "hit_max_tokens": true,
116
+ "estimated_tokens": false,
117
+ "cancelled": false,
118
+ "item_id": "",
119
+ "category": "",
120
+ "expected_answer": ""
121
+ },
122
+ "selected_concurrency": 5,
123
+ "selected_summary": {
124
+ "attempted": 5,
125
+ "completed": 5,
126
+ "errors": 0,
127
+ "correct": 5,
128
+ "wrong": 0,
129
+ "score_counts": {
130
+ "pass": 5
131
+ },
132
+ "exact": 0,
133
+ "near": 0,
134
+ "fail": 0,
135
+ "correct_rate": 1.0,
136
+ "score_available": true,
137
+ "hit_max_tokens": 0,
138
+ "estimated_token_runs": 0,
139
+ "completion_tokens": {
140
+ "avg": 1624.0,
141
+ "min": 1213.0,
142
+ "max": 2197.0,
143
+ "p50": 1641.0,
144
+ "p90": 2019.0,
145
+ "p99": 2179.2,
146
+ "std": 348.7612363781273
147
+ },
148
+ "ttft": {
149
+ "avg": 1.6172576304001267,
150
+ "min": 0.6980738370039035,
151
+ "max": 2.1988909380015684,
152
+ "p50": 1.4990805359993828,
153
+ "p90": 2.197183095198125,
154
+ "p99": 2.198720153721224,
155
+ "std": 0.5559327593769275
156
+ },
157
+ "elapsed": {
158
+ "avg": 45.48616596040083,
159
+ "min": 36.35532188900106,
160
+ "max": 57.899014128001,
161
+ "p50": 45.89715363700088,
162
+ "p90": 54.01391431080265,
163
+ "p99": 57.510504146281164,
164
+ "std": 7.560187317393756
165
+ },
166
+ "gen_elapsed": {
167
+ "avg": 43.84264659439941,
168
+ "min": 34.15622323400021,
169
+ "max": 56.356188883997675,
170
+ "p50": 45.19852735499444,
171
+ "p90": 52.47423511519882,
172
+ "p99": 55.96799350711779,
173
+ "std": 7.861625597858535
174
+ },
175
+ "gen_tok_s": {
176
+ "avg": 36.81954303524079,
177
+ "min": 35.51329406913293,
178
+ "max": 38.98418334359437,
179
+ "p50": 36.3064926233414,
180
+ "p90": 38.41259798594358,
181
+ "p99": 38.92702480782929,
182
+ "std": 1.293444614474703
183
+ },
184
+ "e2e_tok_s": {
185
+ "avg": 35.422419567782015,
186
+ "min": 33.365128871736964,
187
+ "max": 37.94537839872288,
188
+ "p50": 35.75385116424901,
189
+ "p90": 37.3107905637257,
190
+ "p99": 37.88191961522316,
191
+ "std": 1.7082128679103057
192
+ },
193
+ "aggregate_gen_tok_s": 37.04155944380088,
194
+ "aggregate_e2e_tok_s": 35.70316305431888
195
+ },
196
+ "all_summary": {
197
+ "attempted": 5,
198
+ "completed": 5,
199
+ "errors": 0,
200
+ "correct": 5,
201
+ "wrong": 0,
202
+ "score_counts": {
203
+ "pass": 5
204
+ },
205
+ "exact": 0,
206
+ "near": 0,
207
+ "fail": 0,
208
+ "correct_rate": 1.0,
209
+ "score_available": true,
210
+ "hit_max_tokens": 0,
211
+ "estimated_token_runs": 0,
212
+ "completion_tokens": {
213
+ "avg": 1624.0,
214
+ "min": 1213.0,
215
+ "max": 2197.0,
216
+ "p50": 1641.0,
217
+ "p90": 2019.0,
218
+ "p99": 2179.2,
219
+ "std": 348.7612363781273
220
+ },
221
+ "ttft": {
222
+ "avg": 1.6172576304001267,
223
+ "min": 0.6980738370039035,
224
+ "max": 2.1988909380015684,
225
+ "p50": 1.4990805359993828,
226
+ "p90": 2.197183095198125,
227
+ "p99": 2.198720153721224,
228
+ "std": 0.5559327593769275
229
+ },
230
+ "elapsed": {
231
+ "avg": 45.48616596040083,
232
+ "min": 36.35532188900106,
233
+ "max": 57.899014128001,
234
+ "p50": 45.89715363700088,
235
+ "p90": 54.01391431080265,
236
+ "p99": 57.510504146281164,
237
+ "std": 7.560187317393756
238
+ },
239
+ "gen_elapsed": {
240
+ "avg": 43.84264659439941,
241
+ "min": 34.15622323400021,
242
+ "max": 56.356188883997675,
243
+ "p50": 45.19852735499444,
244
+ "p90": 52.47423511519882,
245
+ "p99": 55.96799350711779,
246
+ "std": 7.861625597858535
247
+ },
248
+ "gen_tok_s": {
249
+ "avg": 36.81954303524079,
250
+ "min": 35.51329406913293,
251
+ "max": 38.98418334359437,
252
+ "p50": 36.3064926233414,
253
+ "p90": 38.41259798594358,
254
+ "p99": 38.92702480782929,
255
+ "std": 1.293444614474703
256
+ },
257
+ "e2e_tok_s": {
258
+ "avg": 35.422419567782015,
259
+ "min": 33.365128871736964,
260
+ "max": 37.94537839872288,
261
+ "p50": 35.75385116424901,
262
+ "p90": 37.3107905637257,
263
+ "p99": 37.88191961522316,
264
+ "std": 1.7082128679103057
265
+ },
266
+ "aggregate_gen_tok_s": 37.04155944380088,
267
+ "aggregate_e2e_tok_s": 35.70316305431888
268
+ },
269
+ "level_summaries": [
270
+ {
271
+ "concurrency": 5,
272
+ "phase": "profile",
273
+ "summary": {
274
+ "attempted": 5,
275
+ "completed": 5,
276
+ "errors": 0,
277
+ "correct": 5,
278
+ "wrong": 0,
279
+ "score_counts": {
280
+ "pass": 5
281
+ },
282
+ "exact": 0,
283
+ "near": 0,
284
+ "fail": 0,
285
+ "correct_rate": 1.0,
286
+ "score_available": true,
287
+ "hit_max_tokens": 0,
288
+ "estimated_token_runs": 0,
289
+ "completion_tokens": {
290
+ "avg": 1624.0,
291
+ "min": 1213.0,
292
+ "max": 2197.0,
293
+ "p50": 1641.0,
294
+ "p90": 2019.0,
295
+ "p99": 2179.2,
296
+ "std": 348.7612363781273
297
+ },
298
+ "ttft": {
299
+ "avg": 1.6172576304001267,
300
+ "min": 0.6980738370039035,
301
+ "max": 2.1988909380015684,
302
+ "p50": 1.4990805359993828,
303
+ "p90": 2.197183095198125,
304
+ "p99": 2.198720153721224,
305
+ "std": 0.5559327593769275
306
+ },
307
+ "elapsed": {
308
+ "avg": 45.48616596040083,
309
+ "min": 36.35532188900106,
310
+ "max": 57.899014128001,
311
+ "p50": 45.89715363700088,
312
+ "p90": 54.01391431080265,
313
+ "p99": 57.510504146281164,
314
+ "std": 7.560187317393756
315
+ },
316
+ "gen_elapsed": {
317
+ "avg": 43.84264659439941,
318
+ "min": 34.15622323400021,
319
+ "max": 56.356188883997675,
320
+ "p50": 45.19852735499444,
321
+ "p90": 52.47423511519882,
322
+ "p99": 55.96799350711779,
323
+ "std": 7.861625597858535
324
+ },
325
+ "gen_tok_s": {
326
+ "avg": 36.81954303524079,
327
+ "min": 35.51329406913293,
328
+ "max": 38.98418334359437,
329
+ "p50": 36.3064926233414,
330
+ "p90": 38.41259798594358,
331
+ "p99": 38.92702480782929,
332
+ "std": 1.293444614474703
333
+ },
334
+ "e2e_tok_s": {
335
+ "avg": 35.422419567782015,
336
+ "min": 33.365128871736964,
337
+ "max": 37.94537839872288,
338
+ "p50": 35.75385116424901,
339
+ "p90": 37.3107905637257,
340
+ "p99": 37.88191961522316,
341
+ "std": 1.7082128679103057
342
+ },
343
+ "aggregate_gen_tok_s": 37.04155944380088,
344
+ "aggregate_e2e_tok_s": 35.70316305431888
345
+ },
346
+ "selected": true,
347
+ "improved": true
348
+ }
349
+ ],
350
+ "accuracy": null,
351
+ "category_summaries": [],
352
+ "wrong_runs": [],
353
+ "hardware_run_summary": {
354
+ "samples": 72,
355
+ "duration_seconds": 172.026,
356
+ "gpu_count": 4,
357
+ "cpu_util_avg_pct": 13.25,
358
+ "cpu_temp_max_c": 81.38,
359
+ "gpu_util_avg_pct": 97.55,
360
+ "gpu_util_max_pct": 100.0,
361
+ "mem_util_avg_pct": 26.76,
362
+ "mem_util_max_pct": 47.0,
363
+ "temp_avg_c": 74.97,
364
+ "temp_max_c": 91.0,
365
+ "power_total_avg_w": 1092.0,
366
+ "power_total_max_w": 1130.89,
367
+ "power_limit_total_w": 1200.0,
368
+ "vram_used_avg_mb": 381180.78,
369
+ "vram_used_max_mb": 381192.0,
370
+ "vram_total_mb": 391548.0,
371
+ "vram_used_avg_pct": 97.35,
372
+ "vram_used_max_pct": 97.36,
373
+ "pcie_rx_avg_mb_s": 43663.96,
374
+ "pcie_rx_max_mb_s": 88780.0,
375
+ "pcie_tx_avg_mb_s": 44165.6,
376
+ "pcie_tx_max_mb_s": 88023.0
377
+ },
378
+ "runs": [
379
+ {
380
+ "run_index": 1,
381
+ "phase": "profile",
382
+ "concurrency": 5,
383
+ "ok": true,
384
+ "correct": true,
385
+ "completion_tokens": 1641,
386
+ "prompt_tokens": 133186,
387
+ "elapsed": 45.89715363700088,
388
+ "gen_elapsed": 45.19852735499444,
389
+ "ttft": 0.6980738370039035,
390
+ "time_to_second_token": 0.8058631329986383,
391
+ "gen_tok_s": 36.3064926233414,
392
+ "e2e_tok_s": 35.75385116424901,
393
+ "finish_reason": "stop",
394
+ "final_answer": "Estonia — the Glass Current bench’s current calibration cassette (MX‑88) mates with adapter collar N‑4, which is stocked under code AR‑12; AR‑12 is in procurement family K‑27, mapping to vendor account V‑441, i.e., **Mirel Instrument**, headquartered in Estonia.",
395
+ "score_label": "pass",
396
+ "score_detail": "",
397
+ "parsed_answer": "",
398
+ "output_excerpt": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\" Need parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters",
399
+ "output_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet... prior unexplained correction-factor drift ... wrong cassette...\"\nAlso \"Brackish Current salinity bench...\" Wait question says Glass Current salinity bench. Maybe \"Glass Current\"? Let's search.\n\nText snippets:\n\n- \"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\"\n\nThen later: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2...\"\n\nBut manufacturer/material?\n\nThere is \"adapter summary had a second page full of low-stakes component trivia ...\" ferrule set FR-31 tied to Holst Vane, seal carrier SC-8 to Arden Weir, bracket shim BS-14 to Ketter Line, guide pin GP-2 to Lexton Hale...\n\nCould relate to material used by bench? Hmm.\n\nAnother snippet: \"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87, a change made after the old cassette housing developed a hairline crack near the lower latch. The note matters only because staff kept conflating the two benches during a cleanup of retired service sheets.\"\n\nWait question says Glass Current salinity bench, not Brackish Current. Could be typo? Actually packet has \"instrument maintenance appendix for the Glass Current salinity bench\", and \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87\".\n\nQuestion: \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Which material? Calibration cassette? Manufacturer? Need find manufacturer HQ.\n\nLook for manufacturers/vendors associated with cassettes/MX-88/MX-86/N-4/N-2 etc.\n\nPacket includes lots of vendor names and countries:\n- Vendor registration correction: vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\n- Earlier: \"vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia and should not be merged with Mirel Instrument despite near-identical names\".\nSo Mirel Instrument = Estonia, Mirel Industrial=Latvia.\n\nWhich applies to Glass Current salinity bench material? Search associations.\n\nVendor accounts/family crosswalk:\n- Procurement family crosswalk: K-27 maps to vendor account V-441, K-27B maps to V-447.\n- Later: \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, headquartered in Latvia ...\"\n- \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia ...\"\n\nStock codes:\n- \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer...\"\n- \"same ledger notes that stock code AR-13 is booked under procurement family K-27B and should remain segregated from the AR-12 drawer...\"\n- \"reverse side of the same small-parts card warns that insert collar N-4B ships with stock code AR-12A...\"\n- \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447\"\n\nThus stock code AR-12 -> family K-27 -> V-441 -> Mirel Instrument (Estonia)\nAR-13/K-27B -> V-447 -> Mirel Industrial (Latvia)\n\nNow link to Glass Current salinity bench / cassette MX-88? \nCartridge fitment cross-ref: \"control cassette MX-88 seats against adapter collar N-4, while legacy MX-86 seats against N-2.\" Small-parts compat: \"insert collar N-4 is packed only with stock code AR-12\"; \"insert collar N-4B ships with stock code AR-12A\". Addendum: \"MX-89 seats against adapter collar N-4B, while pre-revision MX-87 seats against N-3.\" \n\nIf Glass Current bench uses cassette MX-88, which seats against adapter collar N-4. Collar N-4 packed with stock code AR-12. AR-12 procured under family K-27 => vendor account V-441 => Mirel Instrument, headquartered in Estonia. Thus answer Estonia.\n\nNeed ensure \"material used by Glass Current salinity bench\" refers to \"current calibration cassette remains MX-88\" manufactured by ? Does MX-88 correspond to AR-12? Let's examine.\n\nPotential clue: \"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\" Cartridge fitment cross-reference says MX-88 seats against adapter collar N-4. Compatibility card says insert collar N-4 packed only with stock code AR-12. Family crosswalk says K-27 maps to V-441. Vendor reg correction says V-441=Mirel Instrument, headquartered in Estonia. Therefore yes.\n\nHowever, \"material used\" could be \"calibration cassette\" material? Manufacturer of cassette? Are there vendor names for cassettes? Look for \"MX-88\" manufacturer/vendor. Packet doesn't give direct vendor for cassette, but links via collar/part codes. Question asks \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Might expect tracing through stock code/vend account.\n\nAlternative possibilities:\n- \"Material used by Glass Current salinity bench\" could be \"calibration cassette MX-88\" and \"seats against adapter collar N-4\" which is \"packed only with stock code AR-12\" and \"booked under procurement family K-27\" (?) Did article explicitly connect AR-12 to K-27? \"ledger notes that stock code AR-13 is booked under procurement family K-27B...\" It didn't explicitly say AR-12 booked under K-27? Wait \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\" \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Perhaps implies AR-12 under K-27? Need check exact texts.\n\nFrom packet:\n- Early: \"The reagent vendor ledger says stock code AR-12 is booked under procurement family K-27 and should be ordered against the updated family code rather than the deprecated reseller alias still visible in one archived spreadsheet.\"\nAh yes! Found. AR-12 booked under K-27. Great.\n\nChain:\nGlass Current salinity bench uses calibration cassette MX-88.\nMX-88 seats against adapter collar N-4.\nInsert collar N-4 packed only with stock code AR-12.\nAR-12 booked under procurement family K-27.\nK-27 maps to vendor account V-441.\nV-441 corresponds to Mirel Instrument, headquartered in Estonia.\n\nTherefore answer: Estonia.\n\nNeed concise but maybe include chain.Estonia — the Glass Current bench’s current calibration cassette (MX‑88) mates with adapter collar N‑4, which is stocked under code AR‑12; AR‑12 is in procurement family K‑27, mapping to vendor account V‑441, i.e., **Mirel Instrument**, headquartered in Estonia.",
400
+ "reasoning_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet... prior unexplained correction-factor drift ... wrong cassette...\"\nAlso \"Brackish Current salinity bench...\" Wait question says Glass Current salinity bench. Maybe \"Glass Current\"? Let's search.\n\nText snippets:\n\n- \"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\"\n\nThen later: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2...\"\n\nBut manufacturer/material?\n\nThere is \"adapter summary had a second page full of low-stakes component trivia ...\" ferrule set FR-31 tied to Holst Vane, seal carrier SC-8 to Arden Weir, bracket shim BS-14 to Ketter Line, guide pin GP-2 to Lexton Hale...\n\nCould relate to material used by bench? Hmm.\n\nAnother snippet: \"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87, a change made after the old cassette housing developed a hairline crack near the lower latch. The note matters only because staff kept conflating the two benches during a cleanup of retired service sheets.\"\n\nWait question says Glass Current salinity bench, not Brackish Current. Could be typo? Actually packet has \"instrument maintenance appendix for the Glass Current salinity bench\", and \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87\".\n\nQuestion: \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Which material? Calibration cassette? Manufacturer? Need find manufacturer HQ.\n\nLook for manufacturers/vendors associated with cassettes/MX-88/MX-86/N-4/N-2 etc.\n\nPacket includes lots of vendor names and countries:\n- Vendor registration correction: vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\n- Earlier: \"vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia and should not be merged with Mirel Instrument despite near-identical names\".\nSo Mirel Instrument = Estonia, Mirel Industrial=Latvia.\n\nWhich applies to Glass Current salinity bench material? Search associations.\n\nVendor accounts/family crosswalk:\n- Procurement family crosswalk: K-27 maps to vendor account V-441, K-27B maps to V-447.\n- Later: \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, headquartered in Latvia ...\"\n- \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia ...\"\n\nStock codes:\n- \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer...\"\n- \"same ledger notes that stock code AR-13 is booked under procurement family K-27B and should remain segregated from the AR-12 drawer...\"\n- \"reverse side of the same small-parts card warns that insert collar N-4B ships with stock code AR-12A...\"\n- \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447\"\n\nThus stock code AR-12 -> family K-27 -> V-441 -> Mirel Instrument (Estonia)\nAR-13/K-27B -> V-447 -> Mirel Industrial (Latvia)\n\nNow link to Glass Current salinity bench / cassette MX-88? \nCartridge fitment cross-ref: \"control cassette MX-88 seats against adapter collar N-4, while legacy MX-86 seats against N-2.\" Small-parts compat: \"insert collar N-4 is packed only with stock code AR-12\"; \"insert collar N-4B ships with stock code AR-12A\". Addendum: \"MX-89 seats against adapter collar N-4B, while pre-revision MX-87 seats against N-3.\" \n\nIf Glass Current bench uses cassette MX-88, which seats against adapter collar N-4. Collar N-4 packed with stock code AR-12. AR-12 procured under family K-27 => vendor account V-441 => Mirel Instrument, headquartered in Estonia. Thus answer Estonia.\n\nNeed ensure \"material used by Glass Current salinity bench\" refers to \"current calibration cassette remains MX-88\" manufactured by ? Does MX-88 correspond to AR-12? Let's examine.\n\nPotential clue: \"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\" Cartridge fitment cross-reference says MX-88 seats against adapter collar N-4. Compatibility card says insert collar N-4 packed only with stock code AR-12. Family crosswalk says K-27 maps to V-441. Vendor reg correction says V-441=Mirel Instrument, headquartered in Estonia. Therefore yes.\n\nHowever, \"material used\" could be \"calibration cassette\" material? Manufacturer of cassette? Are there vendor names for cassettes? Look for \"MX-88\" manufacturer/vendor. Packet doesn't give direct vendor for cassette, but links via collar/part codes. Question asks \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Might expect tracing through stock code/vend account.\n\nAlternative possibilities:\n- \"Material used by Glass Current salinity bench\" could be \"calibration cassette MX-88\" and \"seats against adapter collar N-4\" which is \"packed only with stock code AR-12\" and \"booked under procurement family K-27\" (?) Did article explicitly connect AR-12 to K-27? \"ledger notes that stock code AR-13 is booked under procurement family K-27B...\" It didn't explicitly say AR-12 booked under K-27? Wait \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\" \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Perhaps implies AR-12 under K-27? Need check exact texts.\n\nFrom packet:\n- Early: \"The reagent vendor ledger says stock code AR-12 is booked under procurement family K-27 and should be ordered against the updated family code rather than the deprecated reseller alias still visible in one archived spreadsheet.\"\nAh yes! Found. AR-12 booked under K-27. Great.\n\nChain:\nGlass Current salinity bench uses calibration cassette MX-88.\nMX-88 seats against adapter collar N-4.\nInsert collar N-4 packed only with stock code AR-12.\nAR-12 booked under procurement family K-27.\nK-27 maps to vendor account V-441.\nV-441 corresponds to Mirel Instrument, headquartered in Estonia.\n\nTherefore answer: Estonia.\n\nNeed concise but maybe include chain.",
401
+ "content_text": "Estonia — the Glass Current bench’s current calibration cassette (MX‑88) mates with adapter collar N‑4, which is stocked under code AR‑12; AR‑12 is in procurement family K‑27, mapping to vendor account V‑441, i.e., **Mirel Instrument**, headquartered in Estonia.",
402
+ "error": "",
403
+ "hit_max_tokens": false,
404
+ "estimated_tokens": false,
405
+ "cancelled": false,
406
+ "item_id": "",
407
+ "category": "",
408
+ "expected_answer": ""
409
+ },
410
+ {
411
+ "run_index": 2,
412
+ "phase": "profile",
413
+ "concurrency": 5,
414
+ "ok": true,
415
+ "correct": true,
416
+ "completion_tokens": 2197,
417
+ "prompt_tokens": 133186,
418
+ "elapsed": 57.899014128001,
419
+ "gen_elapsed": 56.356188883997675,
420
+ "ttft": 1.4990805359993828,
421
+ "time_to_second_token": 0.7064408669975819,
422
+ "gen_tok_s": 38.98418334359437,
423
+ "e2e_tok_s": 37.94537839872288,
424
+ "finish_reason": "stop",
425
+ "final_answer": "The Glass Current salinity bench uses calibration/control cassette **MX‑88**, which seats against adapter collar **N‑4**. Collar N‑4 is packed with stock code **AR‑12**, booked under procurement family **K‑27**, which maps to vendor account **V‑441**. According to the vendor registration correction, **V‑441 corresponds to Mirel Instrument, headquartered in Estonia** (not Latvia).",
426
+ "score_label": "pass",
427
+ "score_detail": "",
428
+ "parsed_answer": "",
429
+ "output_excerpt": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\" Need parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters",
430
+ "output_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. ... prior unexplained correction-factor drift ...\"\n\nThen later: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4...\" Hmm.\n\nAnother: \"instrument maintenance appendix... Glass Current salinity bench ...\" Does it give manufacturer/material?\n\nAlso \"Brackish Current salinity bench\"? Wait:\n\nEarlier: \"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"\n\nLater: \"Glass Current salivity bench says current calibration cassette remains MX-88 rather than older MX-86.\"\n\nBut question asks \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Maybe refers to \"material\" = calibration cassette? Manufacturer? Let's search thoroughly.\n\nThere is a sentence: \"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nDoes it mention manufacturer/headquartered? Later \"adapter summary had a second page full of low-stakes component trivia...\" Vendor accounts? Could relate to \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" \n\nCould the Glass Current salinity bench material manufacturer be Mirel Instrument/Estonia? Need connect.\n\nLook for \"MX-88\", \"MX-86\", \"control cassette\", \"calibration cassette\", \"seats against adapter collar N-4/N-2\".\n\nText snippets:\n- \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2...\"\n- \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 ...\"\n- \"reverse side of the same small-parts card warns that insert collar N-4B ships with stock code AR-12A...\"\n- \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\"\n- \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\"\n- \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\"\n- \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\"\n\nSo if Glass Current salinity bench uses MX-88 cassette, which seats against adapter collar N-4 / N-4B, which is packed/ships with stock code AR-12/A? Procurement family K-27 -> vendor account V-441 -> Mirel Instrument HQ Estonia. Alternatively MX-86 seats against N-2? Unknown. Question asks \"manufacturer of the material used by the Glass Current salinity bench\" — material maybe \"current calibration cassette MX-88\"; manufacturer determined by stock/family/vendor? Need establish link from MX-88 to AR-12/K-27/Mirel Instrument.\n\nLet's examine all fragments relating to Glass Current and manufacturers.\n\nFrom packet:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\n\"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2. Someone drew a margin arrow after a prior mix-up to make clear that the couplings are not interchangeable even though the outer housings are nearly the same size.\"\n\n\"The small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer just because both sets ship in the same pale gray sleeve. The warning reads like the residue of a mistake that annoyed enough people to become permanent paperwork.\"\n\n\"The reverse side of the same small-parts card warns that insert collar N-4B ships with stock code AR-12A and must not be dropped into the AR-12 bin during end-of-shift cleanup, even though the sleeve labels differ by only a single printed character near the lower edge.\"\n\nWait Glass Current uses MX-88 seats against adapter collar N-4. Insert collar N-4 packed with stock code AR-12. Procurement family crosswalk: K-27 maps to vendor account V-441. Which stock code AR-12? Probably book under procurement family K-27. Text: \"The procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447. The table was added after a buyer copied the family prefix correctly but carried the wrong trailing letter into a reorder request...\" \nWhere is AR-12 linked to K-27? Search snippet: \"The reagent vendor ledger says stock code AR-12 is booked under procurement family K-27 and should be ordered against the updated family code rather than the deprecated reseller alias still visible in one archived spreadsheet.\" Exactly! Thus AR-12 => K-27 => V-441 => Mirel Instrument HQ Estonia. However there is nuance: \"AR-12A\"/collar N-4B maybe K-27B? Reverse side says N-4B ships with stock code AR-12A. Same ledger notes AR-13 booked under K-27B? Actually \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Did AR-12A correspond to K-27B? Possibly yes? Need consider.\n\nQuestion: \"manufacturer of the material used by the Glass Current salinity bench\" Might be \"current calibration cassette remains MX-88\" manufactured by ??? Perhaps \"Mirel Instrument\" if material=insert collar/adaptor? But maybe \"calibration cassette MX-88\" itself has manufacturer? Look for \"MX-88\" vendor info anywhere? Maybe \"Tovik Glass\"? Wait there are lots of vendor/part associations sprinkled:\n- Consumables comparison sheet side column: \"Pipette rack PR-5 was noted as an Elsen Ward item, membrane clip MC-21 as coming from Tovik Glass, bottle sleeve BS-7 from Karden Elm, and cap insert CI-4 from Nollis West.\"\n- Adapter summary second page: ferrule set FR-31 tied to Holst Vane...\n- Quartermaster notes: \"central stores shelf card... Rack stop RS-6 marked to Varlan Labs, tray pin TP-4 to Edden Cross, sleeve card SC-11 to Polt Metric, bottle cradle BC-7 to Weller Fen\".\n- \"neighboring bench config note says Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87, change after old cassette housing developed hairline crack...\" Doesn't mention manufacturer.\n- Addendum for adjacent service bay: \"control cassette MX-89 seats against adapter collar N-4B, while pre-revision MX-87 cassette seats against N-3.\" Boxed after technician tried borrow parts by visual similarity.\n- Small-parts compat card: insert collar N-4 packed with stock code AR-12 ...\n- Reverse side: insert collar N-4B ships with stock code AR-12A...\n\nWhich bench is Glass Current? Uses MX-88 seats against N-4. Collar N-4 packed with AR-12. Family K-27->V-441=Mirel Instrument HQ Estonia. But if \"material used by Glass Current salinity bench\" could be \"calibration cassette MX-88\" not \"insert collar N-4\". Are cassettes stocked under AR-?? Maybe not. Need see if MX-88 relates to stock code AR-12? Through adapter collar N-4. The \"material\" maybe \"calibration cassette\" itself, not collar. Who manufactures cassette? Packet doesn't explicitly say. Unless \"Mirel Instrument\" manufactures \"control cassette MX-88\"? How derive? Control cassette MX-88 seats against adapter collar N-4. Insert collar N-4 packed with stock code AR-12. AR-12 booked under K-27=>V-441=>Mirel Instrument. But that identifies manufacturer of insert collar/adaptor material, not cassette. User asks \"manufacturer of the material used by the Glass Current salinity bench\" maybe purposely indirect: material used by bench = calibration cassette? Hmm.\n\nAlternative: \"Glass Current salinity bench\" uses \"calibration cassette MX-88\". The \"cartridge fitment cross-reference\" says \"control cassette MX-88 seats against adapter collar N-4\". The \"small-parts compatibility card\" says \"insert collar N-4 is packed only with stock code AR-12\". The \"reagent vendor ledger\" says \"stock code AR-12 is booked under procurement family K-27\". The \"procurement family crosswalk\" says \"K-27 maps to vendor account V-441\". The \"vendor registration correction\" says \"vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia\". Therefore answer Estonia. Likely.\n\nNeed formulate concise answer with citations maybe. Ensure not Latvia. Mention Mirel Instrument headquartered in Estonia.Estonia.\n\nThe Glass Current salinity bench uses calibration/control cassette **MX‑88**, which seats against adapter collar **N‑4**. Collar N‑4 is packed with stock code **AR‑12**, booked under procurement family **K‑27**, which maps to vendor account **V‑441**. According to the vendor registration correction, **V‑441 corresponds to Mirel Instrument, headquartered in Estonia** (not Latvia).",
431
+ "reasoning_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. ... prior unexplained correction-factor drift ...\"\n\nThen later: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4...\" Hmm.\n\nAnother: \"instrument maintenance appendix... Glass Current salinity bench ...\" Does it give manufacturer/material?\n\nAlso \"Brackish Current salinity bench\"? Wait:\n\nEarlier: \"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"\n\nLater: \"Glass Current salivity bench says current calibration cassette remains MX-88 rather than older MX-86.\"\n\nBut question asks \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Maybe refers to \"material\" = calibration cassette? Manufacturer? Let's search thoroughly.\n\nThere is a sentence: \"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nDoes it mention manufacturer/headquartered? Later \"adapter summary had a second page full of low-stakes component trivia...\" Vendor accounts? Could relate to \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" \n\nCould the Glass Current salinity bench material manufacturer be Mirel Instrument/Estonia? Need connect.\n\nLook for \"MX-88\", \"MX-86\", \"control cassette\", \"calibration cassette\", \"seats against adapter collar N-4/N-2\".\n\nText snippets:\n- \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2...\"\n- \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 ...\"\n- \"reverse side of the same small-parts card warns that insert collar N-4B ships with stock code AR-12A...\"\n- \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\"\n- \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\"\n- \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\"\n- \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\"\n\nSo if Glass Current salinity bench uses MX-88 cassette, which seats against adapter collar N-4 / N-4B, which is packed/ships with stock code AR-12/A? Procurement family K-27 -> vendor account V-441 -> Mirel Instrument HQ Estonia. Alternatively MX-86 seats against N-2? Unknown. Question asks \"manufacturer of the material used by the Glass Current salinity bench\" — material maybe \"current calibration cassette MX-88\"; manufacturer determined by stock/family/vendor? Need establish link from MX-88 to AR-12/K-27/Mirel Instrument.\n\nLet's examine all fragments relating to Glass Current and manufacturers.\n\nFrom packet:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\n\"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2. Someone drew a margin arrow after a prior mix-up to make clear that the couplings are not interchangeable even though the outer housings are nearly the same size.\"\n\n\"The small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer just because both sets ship in the same pale gray sleeve. The warning reads like the residue of a mistake that annoyed enough people to become permanent paperwork.\"\n\n\"The reverse side of the same small-parts card warns that insert collar N-4B ships with stock code AR-12A and must not be dropped into the AR-12 bin during end-of-shift cleanup, even though the sleeve labels differ by only a single printed character near the lower edge.\"\n\nWait Glass Current uses MX-88 seats against adapter collar N-4. Insert collar N-4 packed with stock code AR-12. Procurement family crosswalk: K-27 maps to vendor account V-441. Which stock code AR-12? Probably book under procurement family K-27. Text: \"The procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447. The table was added after a buyer copied the family prefix correctly but carried the wrong trailing letter into a reorder request...\" \nWhere is AR-12 linked to K-27? Search snippet: \"The reagent vendor ledger says stock code AR-12 is booked under procurement family K-27 and should be ordered against the updated family code rather than the deprecated reseller alias still visible in one archived spreadsheet.\" Exactly! Thus AR-12 => K-27 => V-441 => Mirel Instrument HQ Estonia. However there is nuance: \"AR-12A\"/collar N-4B maybe K-27B? Reverse side says N-4B ships with stock code AR-12A. Same ledger notes AR-13 booked under K-27B? Actually \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Did AR-12A correspond to K-27B? Possibly yes? Need consider.\n\nQuestion: \"manufacturer of the material used by the Glass Current salinity bench\" Might be \"current calibration cassette remains MX-88\" manufactured by ??? Perhaps \"Mirel Instrument\" if material=insert collar/adaptor? But maybe \"calibration cassette MX-88\" itself has manufacturer? Look for \"MX-88\" vendor info anywhere? Maybe \"Tovik Glass\"? Wait there are lots of vendor/part associations sprinkled:\n- Consumables comparison sheet side column: \"Pipette rack PR-5 was noted as an Elsen Ward item, membrane clip MC-21 as coming from Tovik Glass, bottle sleeve BS-7 from Karden Elm, and cap insert CI-4 from Nollis West.\"\n- Adapter summary second page: ferrule set FR-31 tied to Holst Vane...\n- Quartermaster notes: \"central stores shelf card... Rack stop RS-6 marked to Varlan Labs, tray pin TP-4 to Edden Cross, sleeve card SC-11 to Polt Metric, bottle cradle BC-7 to Weller Fen\".\n- \"neighboring bench config note says Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87, change after old cassette housing developed hairline crack...\" Doesn't mention manufacturer.\n- Addendum for adjacent service bay: \"control cassette MX-89 seats against adapter collar N-4B, while pre-revision MX-87 cassette seats against N-3.\" Boxed after technician tried borrow parts by visual similarity.\n- Small-parts compat card: insert collar N-4 packed with stock code AR-12 ...\n- Reverse side: insert collar N-4B ships with stock code AR-12A...\n\nWhich bench is Glass Current? Uses MX-88 seats against N-4. Collar N-4 packed with AR-12. Family K-27->V-441=Mirel Instrument HQ Estonia. But if \"material used by Glass Current salinity bench\" could be \"calibration cassette MX-88\" not \"insert collar N-4\". Are cassettes stocked under AR-?? Maybe not. Need see if MX-88 relates to stock code AR-12? Through adapter collar N-4. The \"material\" maybe \"calibration cassette\" itself, not collar. Who manufactures cassette? Packet doesn't explicitly say. Unless \"Mirel Instrument\" manufactures \"control cassette MX-88\"? How derive? Control cassette MX-88 seats against adapter collar N-4. Insert collar N-4 packed with stock code AR-12. AR-12 booked under K-27=>V-441=>Mirel Instrument. But that identifies manufacturer of insert collar/adaptor material, not cassette. User asks \"manufacturer of the material used by the Glass Current salinity bench\" maybe purposely indirect: material used by bench = calibration cassette? Hmm.\n\nAlternative: \"Glass Current salinity bench\" uses \"calibration cassette MX-88\". The \"cartridge fitment cross-reference\" says \"control cassette MX-88 seats against adapter collar N-4\". The \"small-parts compatibility card\" says \"insert collar N-4 is packed only with stock code AR-12\". The \"reagent vendor ledger\" says \"stock code AR-12 is booked under procurement family K-27\". The \"procurement family crosswalk\" says \"K-27 maps to vendor account V-441\". The \"vendor registration correction\" says \"vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia\". Therefore answer Estonia. Likely.\n\nNeed formulate concise answer with citations maybe. Ensure not Latvia. Mention Mirel Instrument headquartered in Estonia.",
432
+ "content_text": "Estonia.\n\nThe Glass Current salinity bench uses calibration/control cassette **MX‑88**, which seats against adapter collar **N‑4**. Collar N‑4 is packed with stock code **AR‑12**, booked under procurement family **K‑27**, which maps to vendor account **V‑441**. According to the vendor registration correction, **V‑441 corresponds to Mirel Instrument, headquartered in Estonia** (not Latvia).",
433
+ "error": "",
434
+ "hit_max_tokens": false,
435
+ "estimated_tokens": false,
436
+ "cancelled": false,
437
+ "item_id": "",
438
+ "category": "",
439
+ "expected_answer": ""
440
+ },
441
+ {
442
+ "run_index": 3,
443
+ "phase": "profile",
444
+ "concurrency": 5,
445
+ "ok": true,
446
+ "correct": true,
447
+ "completion_tokens": 1752,
448
+ "prompt_tokens": 133186,
449
+ "elapsed": 48.18626458500512,
450
+ "gen_elapsed": 46.65130446200055,
451
+ "ttft": 1.4956215100028203,
452
+ "time_to_second_token": 0.7066332800022792,
453
+ "gen_tok_s": 37.555219949467386,
454
+ "e2e_tok_s": 36.358908811229945,
455
+ "finish_reason": "stop",
456
+ "final_answer": "Estonia.",
457
+ "score_label": "pass",
458
+ "score_detail": "",
459
+ "parsed_answer": "",
460
+ "output_excerpt": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\" Need parse packet. Need find info about Glass Current salinity bench and material used / manufacturer h",
461
+ "output_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need find info about Glass Current salinity bench and material used / manufacturer headquarters.\n\nSearch in huge text. Mentions:\n\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nAlso earlier:\n\"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\" Wait question says Glass Current salinity bench. Maybe typo? Let's search.\n\nThere is \"Glass Current salinity bench\" sentence. Does it give manufacturer/headquarters? Hmm maybe \"material used by ... bench\" refers to calibration cassette? Manufacturer of material? Could be \"control cassette MX-88\"? Need identify manufacturer HQ country.\n\nLook for cassette manufacturers. Search \"MX-88\", \"MX-86\".\n\nText snippets:\n- \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86...\"\n- \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"; \n- \"adapter summary ...\" maybe \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 ...\"\n- \"addendum for the adjacent service bay says control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3...\"\n\nBut no manufacturer?\n\nCould be \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" Which relates to material used by Glass Current salinity bench? Need connect.\n\nQuestion: \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Perhaps material = \"fluorocarbon compound\"?? Actually Glass Current salinity bench uses calibration cassette MX-88. Who manufactured cassette/material? Need find in packet.\n\nLet's thoroughly examine relevant portions.\n\nPacket includes lots of vendor/part associations. Need link Glass Current salinity bench -> material -> manufacturer -> country.\n\nPotential clue: \"Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87, a change made after the old cassette housing developed a hairline crack near the lower latch.\" Question says Glass Current salinity bench, not Brackish. Similar structure. Might involve \"current calibration cassette remains MX-88 rather than older MX-86\". \n\nWhere are cassette/model manufacturers? Look for \"Holst Vane\", \"Edden Cross\", etc. Text has numerous vendor names paired with part codes. Need find pair for MX-88/MX-86 or Glass Current.\n\nSearch mentally for \"MX-\" occurrences:\n- \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\"\n- \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"\n- \"addendum for the adjacent service bay says control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3.\"\n- \"cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2.\"\nNo manufacturer names there.\n\nMaybe \"material used by the Glass Current salinity bench\" isn't cassette but \"salinity bench\" uses \"HEPES formulation\"/buffer? Salinity bench calibrations use artificial seawater salts? Packet mentions \"lab’s target salinity range per ASTM D1141\" and pH buffers from Meridian Systems in Phoenix/Tempe. But Glass Current salinity bench? Hmm.\n\nQuestion wording: \"manufacturer of the material used by the Glass Current salinity bench\" — maybe \"material\" = \"calibration cassette\" and manufacturer = ? Need derive from vendor accounts.\n\nLet's search for \"Glass Current\" in text. Occurs only once? Possibly yes. Sentence doesn't mention manufacturer. However preceding/following paragraphs may include vendor registrations. Since packet repeats many fragments. Need contextual connections.\n\nNearby around Glass Current:\nIt appears after \"system note ORBIT-LESS-719\" and before \"overnight security log...\" Let's scroll region:\n\n...\n\"The system note confirmed ORBIT-LESS-719 as drill-only and inactive...\n\nThe temporary staffer’s annex-versus-main-desk comparison ...\n\nThe coffee-run interruption ledger ...\n\nThe crossed-out labels appendix ...\n\nThe end-of-day key return sheet ...\n\nThe red binder handling guideline ...\n\nThe queue evolution summary ...\n\nThe chair movement register ...\n\nThe scanner calibration note ...\n\nThe annex clock synchronization record ...\n\nThe clerk’s memo on ordinary embarrassment ...\n\nThe dispatch spillover note ...\n\nThe shelf lane survey ...\n\nThe courtesy copies argument ...\n\nThe retention note ...\n\nThe portable fan borrowing sheet ...\n\nThe hallway pauses taxonomy ...\n\nThe folded page hazard memo ...\n\nThe directional shorthand caution ...\n\nThe copier heat plume note ...\n\nThe postponement transcript ...\n\nThe rubber band usage review ...\n\nThe ink smudge provenance note ...\n\nThe new rule against hanging sleeves/binders over chair backs ...\n\nThe pencil-vs.-pen comparison ...\n\nThe timed table-clearing proposal ...\n\nThe decipherment sheet ...\n\nThe squeak report ...\n\nThe side-door air-pressure instability memo ...\n\nThe habitual walking routes sketch ...\n\nThe side-margin crowding warning ...\n\nThe overheard certainty index ...\n\nThe rationale against photographing every intermediate state ...\"\n\nThen:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nImmediately after:\n\"The overnight security log for the main laboratory complex recorded...\" Security stuff.\n\nSo no manufacturer near.\n\nLater there are vendor registration corrections:\n- \"The vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia, and instructs purchasing staff to amend the older country field...\"\nEarlier: \"The adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia and should not be merged with Mirel Instrument despite the near-identical names...\"\nWhich vendor accounts relate to procurement families/parts? Procurement family crosswalk: \"K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\" Later \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" and \"AR-12 is booked under procurement family K-27...\" Small-parts compatibility: \"insert collar N-4 is packed only with stock code AR-12...\" Reverse side: \"insert collar N-4B ships with stock code AR-12A...\" Cartridge fitment: \"control cassette MX-88 seats against adapter collar N-4, while legacy MX-86 seats against N-2.\" Addendum: \"control cassette MX-89 seats against adapter collar N-4B, while pre-revision MX-87 seats against N-3.\" Thus Glass Current uses MX-88/N-4/AR-12/K-27/vendor account V-441=Mirel Instrument/Estonia. Ah! Great. Need answer Estonia.\n\nLet's validate linkage:\n- Glass Current salinity bench current calibration cassette MX-88.\n- cartridge fitment cross-ref: MX-88 seats against adapter collar N-4.\n- small-parts compat: insert collar N-4 packed only with stock code AR-12.\n- procurement family crosswalk: K-27 maps to vendor account V-441.\n- vendor reg correction: V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia.\nThus manufacturer of material used by Glass Current salinity bench is Mirel Instrument, headquartered in Estonia. Answer: Estonia.\n\nNeed concise.Estonia.",
462
+ "reasoning_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need find info about Glass Current salinity bench and material used / manufacturer headquarters.\n\nSearch in huge text. Mentions:\n\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nAlso earlier:\n\"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\" Wait question says Glass Current salinity bench. Maybe typo? Let's search.\n\nThere is \"Glass Current salinity bench\" sentence. Does it give manufacturer/headquarters? Hmm maybe \"material used by ... bench\" refers to calibration cassette? Manufacturer of material? Could be \"control cassette MX-88\"? Need identify manufacturer HQ country.\n\nLook for cassette manufacturers. Search \"MX-88\", \"MX-86\".\n\nText snippets:\n- \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86...\"\n- \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"; \n- \"adapter summary ...\" maybe \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12 ...\"\n- \"addendum for the adjacent service bay says control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3...\"\n\nBut no manufacturer?\n\nCould be \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" Which relates to material used by Glass Current salinity bench? Need connect.\n\nQuestion: \"manufacturer of the material used by the Glass Current salinity bench headquartered?\" Perhaps material = \"fluorocarbon compound\"?? Actually Glass Current salinity bench uses calibration cassette MX-88. Who manufactured cassette/material? Need find in packet.\n\nLet's thoroughly examine relevant portions.\n\nPacket includes lots of vendor/part associations. Need link Glass Current salinity bench -> material -> manufacturer -> country.\n\nPotential clue: \"Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87, a change made after the old cassette housing developed a hairline crack near the lower latch.\" Question says Glass Current salinity bench, not Brackish. Similar structure. Might involve \"current calibration cassette remains MX-88 rather than older MX-86\". \n\nWhere are cassette/model manufacturers? Look for \"Holst Vane\", \"Edden Cross\", etc. Text has numerous vendor names paired with part codes. Need find pair for MX-88/MX-86 or Glass Current.\n\nSearch mentally for \"MX-\" occurrences:\n- \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\"\n- \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"\n- \"addendum for the adjacent service bay says control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3.\"\n- \"cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2.\"\nNo manufacturer names there.\n\nMaybe \"material used by the Glass Current salinity bench\" isn't cassette but \"salinity bench\" uses \"HEPES formulation\"/buffer? Salinity bench calibrations use artificial seawater salts? Packet mentions \"lab’s target salinity range per ASTM D1141\" and pH buffers from Meridian Systems in Phoenix/Tempe. But Glass Current salinity bench? Hmm.\n\nQuestion wording: \"manufacturer of the material used by the Glass Current salinity bench\" — maybe \"material\" = \"calibration cassette\" and manufacturer = ? Need derive from vendor accounts.\n\nLet's search for \"Glass Current\" in text. Occurs only once? Possibly yes. Sentence doesn't mention manufacturer. However preceding/following paragraphs may include vendor registrations. Since packet repeats many fragments. Need contextual connections.\n\nNearby around Glass Current:\nIt appears after \"system note ORBIT-LESS-719\" and before \"overnight security log...\" Let's scroll region:\n\n...\n\"The system note confirmed ORBIT-LESS-719 as drill-only and inactive...\n\nThe temporary staffer’s annex-versus-main-desk comparison ...\n\nThe coffee-run interruption ledger ...\n\nThe crossed-out labels appendix ...\n\nThe end-of-day key return sheet ...\n\nThe red binder handling guideline ...\n\nThe queue evolution summary ...\n\nThe chair movement register ...\n\nThe scanner calibration note ...\n\nThe annex clock synchronization record ...\n\nThe clerk’s memo on ordinary embarrassment ...\n\nThe dispatch spillover note ...\n\nThe shelf lane survey ...\n\nThe courtesy copies argument ...\n\nThe retention note ...\n\nThe portable fan borrowing sheet ...\n\nThe hallway pauses taxonomy ...\n\nThe folded page hazard memo ...\n\nThe directional shorthand caution ...\n\nThe copier heat plume note ...\n\nThe postponement transcript ...\n\nThe rubber band usage review ...\n\nThe ink smudge provenance note ...\n\nThe new rule against hanging sleeves/binders over chair backs ...\n\nThe pencil-vs.-pen comparison ...\n\nThe timed table-clearing proposal ...\n\nThe decipherment sheet ...\n\nThe squeak report ...\n\nThe side-door air-pressure instability memo ...\n\nThe habitual walking routes sketch ...\n\nThe side-margin crowding warning ...\n\nThe overheard certainty index ...\n\nThe rationale against photographing every intermediate state ...\"\n\nThen:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nImmediately after:\n\"The overnight security log for the main laboratory complex recorded...\" Security stuff.\n\nSo no manufacturer near.\n\nLater there are vendor registration corrections:\n- \"The vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia, and instructs purchasing staff to amend the older country field...\"\nEarlier: \"The adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia and should not be merged with Mirel Instrument despite the near-identical names...\"\nWhich vendor accounts relate to procurement families/parts? Procurement family crosswalk: \"K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\" Later \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" and \"AR-12 is booked under procurement family K-27...\" Small-parts compatibility: \"insert collar N-4 is packed only with stock code AR-12...\" Reverse side: \"insert collar N-4B ships with stock code AR-12A...\" Cartridge fitment: \"control cassette MX-88 seats against adapter collar N-4, while legacy MX-86 seats against N-2.\" Addendum: \"control cassette MX-89 seats against adapter collar N-4B, while pre-revision MX-87 seats against N-3.\" Thus Glass Current uses MX-88/N-4/AR-12/K-27/vendor account V-441=Mirel Instrument/Estonia. Ah! Great. Need answer Estonia.\n\nLet's validate linkage:\n- Glass Current salinity bench current calibration cassette MX-88.\n- cartridge fitment cross-ref: MX-88 seats against adapter collar N-4.\n- small-parts compat: insert collar N-4 packed only with stock code AR-12.\n- procurement family crosswalk: K-27 maps to vendor account V-441.\n- vendor reg correction: V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia.\nThus manufacturer of material used by Glass Current salinity bench is Mirel Instrument, headquartered in Estonia. Answer: Estonia.\n\nNeed concise.",
463
+ "content_text": "Estonia.",
464
+ "error": "",
465
+ "hit_max_tokens": false,
466
+ "estimated_tokens": false,
467
+ "cancelled": false,
468
+ "item_id": "",
469
+ "category": "",
470
+ "expected_answer": ""
471
+ },
472
+ {
473
+ "run_index": 4,
474
+ "phase": "profile",
475
+ "concurrency": 5,
476
+ "ok": true,
477
+ "correct": true,
478
+ "completion_tokens": 1213,
479
+ "prompt_tokens": 133186,
480
+ "elapsed": 36.35532188900106,
481
+ "gen_elapsed": 34.15622323400021,
482
+ "ttft": 2.1988909380015684,
483
+ "time_to_second_token": 0.00010604199633235112,
484
+ "gen_tok_s": 35.51329406913293,
485
+ "e2e_tok_s": 33.365128871736964,
486
+ "finish_reason": "stop",
487
+ "final_answer": "Chain: the **Glass Current** salinity bench uses calibration cassette **MX‑88**, which seats against adapter collar **N‑4**. Collar N‑4 is stocked under **code AR‑12**, which is booked under procurement family **K‑27**. Family K‑27 maps to vendor account **V‑441**, corresponding to **Mirel Instrument**, which is headquartered in **Estonia** — not Latvia.",
488
+ "score_label": "pass",
489
+ "score_detail": "",
490
+ "parsed_answer": "",
491
+ "output_excerpt": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\" Need parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters",
492
+ "output_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nAlso \"Brackish Current salinity bench\"? Wait question says Glass Current salinity bench. Text: \n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88...\" Maybe material = calibration cassette? Manufacturer?\n\nLater: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2...\"\nBut doesn't give manufacturer.\n\nAnother snippet: \"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"; Hmm \"Glass Current\" maybe typo? Let's search thoroughly.\n\nThere is \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86...\"\n\nWhere is manufacturer of material used by Glass Current salinity bench headquartered? Could relate to \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia ...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia ... should not merge with Mirel Instrument\".\n\nWhich vendor accounts correspond to material used by Glass Current salinity bench? Need connect.\n\nText snippets:\n\n- Procurement family crosswalk: \"K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\"\n- Vendor registration correction: \"V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia\".\n- Adjacent vendor master update: \"V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia ...\"\n\nMaterial used by Glass Current salinity bench? Which stock/family/vendor? Search for \"AR-12\", \"MX-88\", \"adapter collar N-4\", \"control cassette MX-88 seats against adapter collar N-4\". Small-parts compatibility card: \"insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer...\" Reverse side: \"insert collar N-4B ships with stock code AR-12A...\" Addendum: \"control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3.\" \n\nWait Glass Current salinity bench uses MX-88 cassette seats against adapter collar N-4. Insert collar N-4 packed with stock code AR-12. Procurement family crosswalk says K-27 maps to V-441. Does AR-12 book under procurement family K-27? Text: \"The reagent vendor ledger says stock code AR-12 is booked under procurement family K-27 and should be ordered against the updated family code rather than the deprecated reseller alias still visible in one archived spreadsheet.\" Later \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Thus AR-12 -> K-27 -> V-441 -> Mirel Instrument HQ Estonia. Question asks manufacturer of material used by Glass Current salinity bench. Likely yes.\n\nNeed ensure \"material used by Glass Current salinity bench\" refers to \"current calibration cassette remains MX-88\" manufactured by ? Actually cassette maybe material? Who manufacturers cassette? Perhaps \"Tovik Glass\"? Let's examine all vendor/part associations.\n\nPotential traps: Packet includes lots of vendor names. Need pinpoint Glass Current salinity bench. It says \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than older MX-86...\" Calibration cassette is material used by bench. Cartridge fitment cross-ref says control cassette MX-88 seats against adapter collar N-4. Compatibility card says insert collar N-4 packed only with stock code AR-12. Reagent vendor ledger says AR-12 booked under procurement family K-27. Procurement family crosswalk says K-27 maps to vendor account V-441. Vendor registration correction says V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia. Therefore answer Estonia.\n\nCould there be competing info: \"Vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia, and instructs purchasing staff to amend older country field...\" Exactly.\n\nNeed formulate concise answer with citations? User didn't ask for derivation but likely helpful. Desired verbosity 5. Answer: Estonia. Include chain: Glass Current bench uses MX-88 cassette / N-4 collar / AR-12 stock / K-27 / V-441 / Mirel Instrument. Ensure no contradiction: \"Adjacent vendor master update says V-447 corresponds to Mirel Industrial, headquartered in Latvia...\" But AR-12/K-27/V-441/Mirel Instrument/Estonia.Estonia.\n\nChain: the **Glass Current** salinity bench uses calibration cassette **MX‑88**, which seats against adapter collar **N‑4**. Collar N‑4 is stocked under **code AR‑12**, which is booked under procurement family **K‑27**. Family K‑27 maps to vendor account **V‑441**, corresponding to **Mirel Instrument**, which is headquartered in **Estonia** — not Latvia.",
493
+ "reasoning_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nAlso \"Brackish Current salinity bench\"? Wait question says Glass Current salinity bench. Text: \n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88...\" Maybe material = calibration cassette? Manufacturer?\n\nLater: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4, while the legacy MX-86 cassette seats against N-2...\"\nBut doesn't give manufacturer.\n\nAnother snippet: \"The neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"; Hmm \"Glass Current\" maybe typo? Let's search thoroughly.\n\nThere is \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86...\"\n\nWhere is manufacturer of material used by Glass Current salinity bench headquartered? Could relate to \"vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia ...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia ... should not merge with Mirel Instrument\".\n\nWhich vendor accounts correspond to material used by Glass Current salinity bench? Need connect.\n\nText snippets:\n\n- Procurement family crosswalk: \"K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\"\n- Vendor registration correction: \"V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia\".\n- Adjacent vendor master update: \"V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia ...\"\n\nMaterial used by Glass Current salinity bench? Which stock/family/vendor? Search for \"AR-12\", \"MX-88\", \"adapter collar N-4\", \"control cassette MX-88 seats against adapter collar N-4\". Small-parts compatibility card: \"insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer...\" Reverse side: \"insert collar N-4B ships with stock code AR-12A...\" Addendum: \"control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3.\" \n\nWait Glass Current salinity bench uses MX-88 cassette seats against adapter collar N-4. Insert collar N-4 packed with stock code AR-12. Procurement family crosswalk says K-27 maps to V-441. Does AR-12 book under procurement family K-27? Text: \"The reagent vendor ledger says stock code AR-12 is booked under procurement family K-27 and should be ordered against the updated family code rather than the deprecated reseller alias still visible in one archived spreadsheet.\" Later \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Thus AR-12 -> K-27 -> V-441 -> Mirel Instrument HQ Estonia. Question asks manufacturer of material used by Glass Current salinity bench. Likely yes.\n\nNeed ensure \"material used by Glass Current salinity bench\" refers to \"current calibration cassette remains MX-88\" manufactured by ? Actually cassette maybe material? Who manufacturers cassette? Perhaps \"Tovik Glass\"? Let's examine all vendor/part associations.\n\nPotential traps: Packet includes lots of vendor names. Need pinpoint Glass Current salinity bench. It says \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than older MX-86...\" Calibration cassette is material used by bench. Cartridge fitment cross-ref says control cassette MX-88 seats against adapter collar N-4. Compatibility card says insert collar N-4 packed only with stock code AR-12. Reagent vendor ledger says AR-12 booked under procurement family K-27. Procurement family crosswalk says K-27 maps to vendor account V-441. Vendor registration correction says V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia. Therefore answer Estonia.\n\nCould there be competing info: \"Vendor registration correction states that vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia, and instructs purchasing staff to amend older country field...\" Exactly.\n\nNeed formulate concise answer with citations? User didn't ask for derivation but likely helpful. Desired verbosity 5. Answer: Estonia. Include chain: Glass Current bench uses MX-88 cassette / N-4 collar / AR-12 stock / K-27 / V-441 / Mirel Instrument. Ensure no contradiction: \"Adjacent vendor master update says V-447 corresponds to Mirel Industrial, headquartered in Latvia...\" But AR-12/K-27/V-441/Mirel Instrument/Estonia.",
494
+ "content_text": "Estonia.\n\nChain: the **Glass Current** salinity bench uses calibration cassette **MX‑88**, which seats against adapter collar **N‑4**. Collar N‑4 is stocked under **code AR‑12**, which is booked under procurement family **K‑27**. Family K‑27 maps to vendor account **V‑441**, corresponding to **Mirel Instrument**, which is headquartered in **Estonia** — not Latvia.",
495
+ "error": "",
496
+ "hit_max_tokens": false,
497
+ "estimated_tokens": false,
498
+ "cancelled": false,
499
+ "item_id": "",
500
+ "category": "",
501
+ "expected_answer": ""
502
+ },
503
+ {
504
+ "run_index": 5,
505
+ "phase": "profile",
506
+ "concurrency": 5,
507
+ "ok": true,
508
+ "correct": true,
509
+ "completion_tokens": 1317,
510
+ "prompt_tokens": 133186,
511
+ "elapsed": 39.09307556299609,
512
+ "gen_elapsed": 36.85098903700418,
513
+ "ttft": 2.194621330992959,
514
+ "time_to_second_token": 0.00014050500612938777,
515
+ "gen_tok_s": 35.738525190667886,
516
+ "e2e_tok_s": 33.688830592971264,
517
+ "finish_reason": "stop",
518
+ "final_answer": "Estonia.",
519
+ "score_label": "pass",
520
+ "score_detail": "",
521
+ "parsed_answer": "",
522
+ "output_excerpt": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\" Need parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters",
523
+ "output_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet... prior unexplained correction-factor drift ... wrong cassette...\"\nBut doesn't give manufacturer?\n\nLater: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4...\" Maybe manufacturers? Let's search.\n\nThere are lots of vendor/part snippets. Need connect Glass Current salinity bench material manufacturer HQ country.\n\nLook for \"Glass Current\" occurrences. First: \n\"Instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\"\n\nThen \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"\n\nWait question asks \"manufacturer of the material used by the Glass Current salinity bench headquartered\"? Could be \"material\" = calibration cassette? Manufacturer of cassette/material? Need find company manufacturing MX-88 / material? Search for MX-88/MX-86 associations.\n\nText: \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nAnother snippet: \"adapter summary had a second page full of low-stakes component trivia... ferrule set FR-31 ... Holst Vane ...\" Hmm.\n\nCould be \"control cassette MX-88 seats against adapter collar N-4\", \"MX-86 seats against N-2\".\n\nWhere is manufacturer of material used by Glass Current salinity bench headquartered? Perhaps in vendor registration correction: \"vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Wait Mirel Instrument/Estonia. Does Mirel manufacture material used by Glass Current salinity bench? Need link.\n\nAlso \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" Later correction: \"V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Which relates to material? \n\nQuestion wording: \"manufacturer of the material used by the Glass Current salinity bench\" — maybe \"material\" refers to \"current calibration cassette remains MX-88\"; manufacturer of cassette? Need identify from vendor info. Did any sentence associate MX-88 with a vendor/company/location? Search memory:\n\nNear \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12...\" Reverse side warns \"insert collar N-4B ships with stock code AR-12A...\" Addendum for adjacent service bay says \"control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3.\" Cartridge fitment cross-ref says \"control cassette MX-88 seats against adapter collar N-4, while legacy MX-86 seats against N-2.\" No manufacturer.\n\nVendor accounts: \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\" Later \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Vendor registration correction: \"vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" Thus V-441=Mirel Instrument(Estonia), V-447=Mirel Industrial(Latvia).\n\nWhich vendor account/family applies to Glass Current salinity bench material? Need find linkage between Glass Current salinity bench and stock/vendor. Maybe \"AR-12\"/\"AR-13\"?? Calibration cassette? Let's examine fragments.\n\nSmall-parts compatibility card: \"insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer...\" Reverse side: \"insert collar N-4B ships with stock code AR-12A...\" Adapter/service bay: \"control cassette MX-89 seats against adapter collar N-4B, while pre-revision MX-87 cassette seats against N-3.\" Since Glass Current uses MX-88 seats against N-4. Insert collar N-4 packed with stock code AR-12. Procurement family crosswalk: K-27 -> V-441; K-27B->V-447. Same ledger notes AR-13 booked under K-27B. Retention/reagent vendor ledger: \"stock code AR-12 is booked under procurement family K-27 and should be ordered against updated family code rather than deprecated reseller alias...\" Ah! AR-12 => K-27 => V-441 => Mirel Instrument, headquartered in Estonia. Likely answer Estonia.\n\nBut question says \"manufacturer of the material used by the Glass Current salinity bench\" not \"insert collar\" maybe material=calibration cassette MX-88? How relate to AR-12/K-27/V-441? Let's trace thoroughly.\n\nFrom packet:\n- Glass Current salinity bench current calibration cassette MX-88 (instead of MX-86)\n- cartridge fitment cross-reference: MX-88 seats against adapter collar N-4; legacy MX-86 seats against N-2.\n- Small-parts compatibility card: insert collar N-4 is packed only with stock code AR-12...\nThus material/component used by Glass Current bench (collar/cassette?) stocked under AR-12.\n- Reagent vendor ledger: stock code AR-12 booked under procurement family K-27 ...\n- Procurement family crosswalk: K-27 maps to vendor account V-441.\n- Vendor registration correction: V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\n\nSo answer: Estonia.Estonia.",
524
+ "reasoning_text": "We need answer question: \"In which country is the manufacturer of the material used by the Glass Current salinity bench headquartered?\"\n\nNeed parse packet. Need identify Glass Current salinity bench, material used, manufacturer headquarters.\n\nSearch text. Mentions:\n\"The instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet... prior unexplained correction-factor drift ... wrong cassette...\"\nBut doesn't give manufacturer?\n\nLater: \"The cartridge fitment cross-reference says control cassette MX-88 seats against adapter collar N-4...\" Maybe manufacturers? Let's search.\n\nThere are lots of vendor/part snippets. Need connect Glass Current salinity bench material manufacturer HQ country.\n\nLook for \"Glass Current\" occurrences. First: \n\"Instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet.\"\n\nThen \"neighboring bench configuration note says the Brackish Current salinity bench now runs calibration cassette MX-89 instead of MX-87...\"\n\nWait question asks \"manufacturer of the material used by the Glass Current salinity bench headquartered\"? Could be \"material\" = calibration cassette? Manufacturer of cassette/material? Need find company manufacturing MX-88 / material? Search for MX-88/MX-86 associations.\n\nText: \"instrument maintenance appendix for the Glass Current salinity bench says the current calibration cassette remains MX-88 rather than the older MX-86 still visible on one retired service sheet. The appendix was preserved because a prior unexplained correction-factor drift turned out to be nothing more glamorous than a bench running the wrong cassette while everyone argued about chemistry.\"\n\nAnother snippet: \"adapter summary had a second page full of low-stakes component trivia... ferrule set FR-31 ... Holst Vane ...\" Hmm.\n\nCould be \"control cassette MX-88 seats against adapter collar N-4\", \"MX-86 seats against N-2\".\n\nWhere is manufacturer of material used by Glass Current salinity bench headquartered? Perhaps in vendor registration correction: \"vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Wait Mirel Instrument/Estonia. Does Mirel manufacture material used by Glass Current salinity bench? Need link.\n\nAlso \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" Later correction: \"V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Which relates to material? \n\nQuestion wording: \"manufacturer of the material used by the Glass Current salinity bench\" — maybe \"material\" refers to \"current calibration cassette remains MX-88\"; manufacturer of cassette? Need identify from vendor info. Did any sentence associate MX-88 with a vendor/company/location? Search memory:\n\nNear \"small-parts compatibility card filed behind the quartermaster note says insert collar N-4 is packed only with stock code AR-12...\" Reverse side warns \"insert collar N-4B ships with stock code AR-12A...\" Addendum for adjacent service bay says \"control cassette MX-89 seats against adapter collar N-4B, while the pre-revision MX-87 cassette seats against N-3.\" Cartridge fitment cross-ref says \"control cassette MX-88 seats against adapter collar N-4, while legacy MX-86 seats against N-2.\" No manufacturer.\n\nVendor accounts: \"procurement family crosswalk says K-27 maps to vendor account V-441, while K-27B maps to vendor account V-447.\" Later \"same ledger notes that stock code AR-13 is booked under procurement family K-27B...\" Vendor registration correction: \"vendor account V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\" Earlier \"adjacent vendor master update says vendor account V-447 corresponds to Mirel Industrial, which remains headquartered in Latvia...\" Thus V-441=Mirel Instrument(Estonia), V-447=Mirel Industrial(Latvia).\n\nWhich vendor account/family applies to Glass Current salinity bench material? Need find linkage between Glass Current salinity bench and stock/vendor. Maybe \"AR-12\"/\"AR-13\"?? Calibration cassette? Let's examine fragments.\n\nSmall-parts compatibility card: \"insert collar N-4 is packed only with stock code AR-12 and should never be re-binned into the AR-11 drawer...\" Reverse side: \"insert collar N-4B ships with stock code AR-12A...\" Adapter/service bay: \"control cassette MX-89 seats against adapter collar N-4B, while pre-revision MX-87 cassette seats against N-3.\" Since Glass Current uses MX-88 seats against N-4. Insert collar N-4 packed with stock code AR-12. Procurement family crosswalk: K-27 -> V-441; K-27B->V-447. Same ledger notes AR-13 booked under K-27B. Retention/reagent vendor ledger: \"stock code AR-12 is booked under procurement family K-27 and should be ordered against updated family code rather than deprecated reseller alias...\" Ah! AR-12 => K-27 => V-441 => Mirel Instrument, headquartered in Estonia. Likely answer Estonia.\n\nBut question says \"manufacturer of the material used by the Glass Current salinity bench\" not \"insert collar\" maybe material=calibration cassette MX-88? How relate to AR-12/K-27/V-441? Let's trace thoroughly.\n\nFrom packet:\n- Glass Current salinity bench current calibration cassette MX-88 (instead of MX-86)\n- cartridge fitment cross-reference: MX-88 seats against adapter collar N-4; legacy MX-86 seats against N-2.\n- Small-parts compatibility card: insert collar N-4 is packed only with stock code AR-12...\nThus material/component used by Glass Current bench (collar/cassette?) stocked under AR-12.\n- Reagent vendor ledger: stock code AR-12 booked under procurement family K-27 ...\n- Procurement family crosswalk: K-27 maps to vendor account V-441.\n- Vendor registration correction: V-441 corresponds to Mirel Instrument, headquartered in Estonia, not Latvia...\n\nSo answer: Estonia.",
525
+ "content_text": "Estonia.",
526
+ "error": "",
527
+ "hit_max_tokens": false,
528
+ "estimated_tokens": false,
529
+ "cancelled": false,
530
+ "item_id": "",
531
+ "category": "",
532
+ "expected_answer": ""
533
+ }
534
+ ],
535
+ "methodology": {
536
+ "name": "Completion-token statistics",
537
+ "prefill": "A single max_tokens=1 scout request is sent first to populate the server prefix cache. Measured requests use the exact same prompt, so engines with prefix caching can reuse prefill while decode is sampled in parallel.",
538
+ "adaptive_concurrency": "If --profile-concurrency is set, the benchmark sends exactly the configured number of measured profile requests with that many concurrent workers. Otherwise it probes increasing concurrency levels and keeps the fastest aggregate generation-token throughput, then collects additional runs at the selected concurrency until min_results is reached.",
539
+ "token_need": "completion_tokens is taken from OpenAI stream usage. If usage is missing, streamed content chunks are used as an estimated fallback and the run is marked estimated_tokens=true.",
540
+ "correctness": "By default correctness is scored by applying the regex to the final non-empty answer line, matching the GLM dense-MLA vs NSA comparison."
541
+ }
542
+ }
benchmarks/2026-07-22/estonia-c5-r5.log ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ╭──────────────────────────── NVIDIA P2P Override ─────────────────────────────╮
2
+ │ Effective: yes │
3
+ │ Configured file: yes (/etc/modprobe.d/nvidia-p2p-override.conf) │
4
+ │ Runtime: ForceP2P=0x11; RMForceP2PType=1; RMPcieP2PType=2; │
5
+ │ GrdmaPciTopoCheckOverride=1; EnableResizableBar=1; DmaRemapPeerMmio=1 │
6
+ ╰──────────────────────────────────────────────────────────────────────────────╯
7
+ ╭─────────────────────────────── Configuration ────────────────────────────────╮
8
+ │ Completion Token Statistics Benchmark │
9
+ │ Model: GLM-5.2-EXL3-TR3-3.0bpw @ 127.0.0.1:8000 │
10
+ │ Prompt: profile:estonia │
11
+ │ Concurrency: 5 │
12
+ │ Measured runs: 5 | Max tokens: 5000 │
13
+ │ Scoring: \bestonia\b │
14
+ ╰──────────────────────────────────────────────────────────────────────────────╯
15
+
16
+ ╭────────────────────────────── Completion Stats ──────────────────────────────╮
17
+ │ Completion Token Statistics │
18
+ │ One optional prefix-cache scout request is used to populate prefill first. │
19
+ │ Built-in profile run at fixed concurrency C=5. │
20
+ ╰──────────────────────────────────────────────────────────────────────────────╯
21
+ Profile
22
+ ╭────────────────┬────────────────────────────────────────────╮
23
+ │ field │ value │
24
+ ├────────────────┼────────────────────────────────────────────┤
25
+ │ profile │ estonia │
26
+ │ prompt │ profile:estonia │
27
+ │ prompt chars │ 707,372 │
28
+ │ requested runs │ 5 │
29
+ │ concurrency │ 5 │
30
+ │ max tokens │ 5000 │
31
+ │ scoring │ regex │
32
+ │ prefill scout │ 133,186 prompt tok / 115.88s = 1,149 tok/s │
33
+ │ correct regex │ \bestonia\b │
34
+ ╰────────────────┴────────────────────────────────────────────╯
35
+ ╭──────────────────────── Whole-run GPU Power ─────────────────────────╮
36
+ │ avg 1,092 W | max 1,131 W | limit 1,200 W | over 2m 52s | 72 samples │
37
+ ╰──────────────────────────────────────────────────────────────────────╯
38
+ Concurrency Results
39
+ ╭────┬────────┬───────────┬──────┬─────────┬──────────┬──────────┬─────────┬───╮
40
+ │ p… │ done/… │ score │ sta… │ output… │ output … │ aggrega… │ avg re… │ … │
41
+ ├────┼────────┼───────────┼──────┼─────────┼──────────┼──────────┼─────────┼───┤
42
+ │ 5 │ 5/5 │ PASS 5 /… │ ★★★… │ 1,641 │ 2,019 │ 37.0 │ 45.5 │ … │
43
+ ╰────┴��───────┴───────────┴──────┴─────────┴──────────┴──────────┴─────────┴───╯
44
+ Selected C=5
45
+ ╭────────────────────────────┬─────────────────╮
46
+ │ metric │ value │
47
+ ├────────────────────────────┼─────────────────┤
48
+ │ completed │ 5/5 │
49
+ │ score │ PASS 5 / FAIL 0 │
50
+ │ stars │ ★★★★★★★★★★ 👍 │
51
+ │ hit max_tokens │ 0 │
52
+ │ completion tokens avg │ 1,624 │
53
+ │ completion tokens p50 │ 1,641 │
54
+ │ completion tokens p90 │ 2,019 │
55
+ │ completion tokens p99 │ 2,179 │
56
+ │ elapsed avg │ 45.5s │
57
+ │ TTFT avg │ 1.62s │
58
+ │ aggregate gen tok/s │ 37.0 │
59
+ │ mean per-request gen tok/s │ 36.8 │
60
+ ╰────────────────────────────┴─────────────────╯
61
+ Interpretation: completion-token p50/p90/p99 tells how many decode tokens the
62
+ model needed to reach its final answer under this engine/config. Correctness is
63
+ scored from the final non-empty answer line by default, matching the GLM
64
+ dense-MLA vs NSA benchmark methodology. The prefill scout is not a scored
65
+ answer; it is the max_tokens=1 prefix-cache warmup and its prompt_tokens/TTFT
66
+ value is reported as scout prefill speed. Concurrency Results groups completed
67
+ requests by parallelism; Completed Requests shows the latest individual finished
68
+ answers.
69
+
70
+ Results saved to results/20260722T091010Z-mtp1-dcp4-async-off/estonia-c5-r5.json
benchmarks/2026-07-22/image-inspect.json ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "Id": "sha256:bfd6d6670db37b04e9cbef7375722e3f71d66745abf1714c05cc5b71fd126715",
4
+ "RepoTags": [
5
+ "verdictai/glm52-exl3-sparkinfer:release-final-candidate"
6
+ ],
7
+ "RepoDigests": [
8
+ "verdictai/glm52-exl3-sparkinfer@sha256:bfd6d6670db37b04e9cbef7375722e3f71d66745abf1714c05cc5b71fd126715"
9
+ ],
10
+ "Comment": "buildkit.dockerfile.v0",
11
+ "Created": "2026-07-22T03:30:53.101796926-04:00",
12
+ "Config": {
13
+ "Env": [
14
+ "PATH=/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
15
+ "NVARCH=x86_64",
16
+ "NVIDIA_REQUIRE_CUDA=cuda>=13.2 brand=unknown,driver>=535,driver<536 brand=grid,driver>=535,driver<536 brand=tesla,driver>=535,driver<536 brand=nvidia,driver>=535,driver<536 brand=quadro,driver>=535,driver<536 brand=quadrortx,driver>=535,driver<536 brand=nvidiartx,driver>=535,driver<536 brand=vapps,driver>=535,driver<536 brand=vpc,driver>=535,driver<536 brand=vcs,driver>=535,driver<536 brand=vws,driver>=535,driver<536 brand=cloudgaming,driver>=535,driver<536 brand=unknown,driver>=570,driver<571 brand=grid,driver>=570,driver<571 brand=tesla,driver>=570,driver<571 brand=nvidia,driver>=570,driver<571 brand=quadro,driver>=570,driver<571 brand=quadrortx,driver>=570,driver<571 brand=nvidiartx,driver>=570,driver<571 brand=vapps,driver>=570,driver<571 brand=vpc,driver>=570,driver<571 brand=vcs,driver>=570,driver<571 brand=vws,driver>=570,driver<571 brand=cloudgaming,driver>=570,driver<571 brand=unknown,driver>=580,driver<581 brand=grid,driver>=580,driver<581 brand=tesla,driver>=580,driver<581 brand=nvidia,driver>=580,driver<581 brand=quadro,driver>=580,driver<581 brand=quadrortx,driver>=580,driver<581 brand=nvidiartx,driver>=580,driver<581 brand=vapps,driver>=580,driver<581 brand=vpc,driver>=580,driver<581 brand=vcs,driver>=580,driver<581 brand=vws,driver>=580,driver<581 brand=cloudgaming,driver>=580,driver<581 brand=unknown,driver>=590,driver<591 brand=grid,driver>=590,driver<591 brand=tesla,driver>=590,driver<591 brand=nvidia,driver>=590,driver<591 brand=quadro,driver>=590,driver<591 brand=quadrortx,driver>=590,driver<591 brand=nvidiartx,driver>=590,driver<591 brand=vapps,driver>=590,driver<591 brand=vpc,driver>=590,driver<591 brand=vcs,driver>=590,driver<591 brand=vws,driver>=590,driver<591 brand=cloudgaming,driver>=590,driver<591",
17
+ "NV_CUDA_CUDART_VERSION=13.2.75-1",
18
+ "CUDA_VERSION=13.2.1",
19
+ "LD_LIBRARY_PATH=/usr/local/nvidia/lib64:/usr/local/cuda/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64",
20
+ "NVIDIA_VISIBLE_DEVICES=all",
21
+ "NVIDIA_DRIVER_CAPABILITIES=compute,utility",
22
+ "DEBIAN_FRONTEND=noninteractive",
23
+ "UV_HTTP_TIMEOUT=500",
24
+ "UV_INDEX_STRATEGY=unsafe-best-match",
25
+ "UV_LINK_MODE=copy",
26
+ "UV_PYTHON_INSTALL_DIR=/opt/uv/python",
27
+ "UV_CACHE_DIR=/opt/uv/cache",
28
+ "VLLM_ENABLE_CUDA_COMPATIBILITY=0",
29
+ "TORCH_CUDA_ARCH_LIST=12.0a",
30
+ "VLLM_USAGE_SOURCE=production-docker-image",
31
+ "VLLM_BUILD_COMMIT=unknown",
32
+ "VLLM_BUILD_PIPELINE=local",
33
+ "VLLM_BUILD_URL=",
34
+ "VLLM_IMAGE_TAG=local/vllm-openai:dev",
35
+ "VLLM_EXL3_EXT_PATH=/opt/glm52/lib",
36
+ "VLLM_EXL3_ABI_SHIM=/opt/glm52/lib/libexl3_torch212_compat.so",
37
+ "VLLM_NVFP4_MLA_SCALES_FILE=/opt/glm52/kv-scale/glm52_nvfp4_mla_outer_scales.json",
38
+ "NCCL_LOCAL_INFERENCE_PATH=/opt/libnccl-local-inference.so.2.30.4",
39
+ "NCCL_PR2127_PATH=/opt/libnccl-local-inference.so.2.30.4",
40
+ "VLLM_NCCL_SO_PATH=/opt/libnccl-local-inference.so.2.30.4",
41
+ "LD_PRELOAD=/opt/libnccl-local-inference.so.2.30.4"
42
+ ],
43
+ "Entrypoint": [
44
+ "vllm",
45
+ "serve"
46
+ ],
47
+ "WorkingDir": "/vllm-workspace",
48
+ "Labels": {
49
+ "ai.verdict.model": "brandonmusic/GLM-5.2-EXL3-TR3-3.0bpw",
50
+ "ai.verdict.sparkinfer.revision": "879ca0ad878958a0fbb1d6a1393c1bb40ec54790",
51
+ "ai.verdict.vllm.revision": "1043999ab5f13350aaacc188e713d6c0928387e9",
52
+ "ai.vllm.build.commit": "unknown",
53
+ "ai.vllm.build.pipeline": "local",
54
+ "ai.vllm.build.url": "",
55
+ "ai.vllm.image.tag": "local/vllm-openai:dev",
56
+ "maintainer": "NVIDIA CORPORATION <cudatools@nvidia.com>",
57
+ "org.opencontainers.image.description": "Gilded Gnosis vLLM with Sparkinfer EXL3 Trellis, NVFP4 MLA KV cache, DCP A2A, and Blackwell kernels",
58
+ "org.opencontainers.image.revision": "unknown",
59
+ "org.opencontainers.image.source": "https://github.com/local-inference-lab/vllm",
60
+ "org.opencontainers.image.title": "GLM-5.2 EXL3 Trellis inference runtime",
61
+ "org.opencontainers.image.url": "",
62
+ "org.opencontainers.image.version": "local/vllm-openai:dev"
63
+ }
64
+ },
65
+ "Architecture": "amd64",
66
+ "Os": "linux",
67
+ "Size": 7799656676,
68
+ "RootFS": {
69
+ "Type": "layers",
70
+ "Layers": [
71
+ "sha256:538812a4b9bd45adaac2b5e5b967daa6999aa44eb110aa32ae7c69702b906475",
72
+ "sha256:033dd3ac1e3752546ffe96cf256b45766e15631c5876573d70f5f73069d4e7da",
73
+ "sha256:172292358808d705cbbe333223be62c856777357bf15a3b33483182c75b60a37",
74
+ "sha256:e3d44de88e7571b5dbe1e6448876231156b9bf77dfa63bdba78809955f43ef31",
75
+ "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
76
+ "sha256:25aa3793397fe126f13b0fa2fdb0239bfe6c55fca85dcbed58326e3401ecb9ec",
77
+ "sha256:b523221e8b19459a04938c97406126f5d989e7c05acc49d7f5afd4cdce3100cf",
78
+ "sha256:9d4b2275ee6cfb0ee7b9131407ada97f22f02465aa14a461153326af8b7b4ce3",
79
+ "sha256:e5cc1074644d6c3ee0049d1c7487159aae2cddd312ae4373a3454be2c4b05e8d",
80
+ "sha256:8fcf76843117f693aa4944ffdf9bb4decbc5c96cf0aa1d34f96afeb62b56b698",
81
+ "sha256:c7c177dcf75866f433696694f5edc715c6a2151b8e164542f6a134b71040a5c8",
82
+ "sha256:54e9458a33f87ea245fe10acdd96e8521821a1e9a839f6bc4468e7896287c551",
83
+ "sha256:e0d6e7d81417a44adec10fb1e99842bbac0409c9962f314702c86a236180702b",
84
+ "sha256:4d98db58920a1a826ea959938b37d49a70ea574a774221b03bf12cb9731916f7",
85
+ "sha256:bd6df3d183f34c11312c40686abd4c7d8a0781cae98639ecfdb5d9746ae4985f",
86
+ "sha256:9c0c15e180a5b725a928c856db1ba9b5c7e968c7525043b79ab38950ee00212e",
87
+ "sha256:6cd879145a53dcb9fb888c10ec61059883f49516ee4f6ff9bbb862ab86f5cf8d",
88
+ "sha256:d98d28d1d1365865086cdc28f0d3ef12c0980abe461ea18070061eee006c029c",
89
+ "sha256:a8d1d50b2a57d17bd32e1c012b62f640c2c57dc92fc0e714dd57bc57c17254f9",
90
+ "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
91
+ "sha256:da07325301e0ca814e9ce660ac38835ce42e079707a309549976ec10f1e7132d",
92
+ "sha256:3d58289a7b335e42df9fc308d024bfbbf039356a98fd5f40185daa77d97a221e",
93
+ "sha256:21b3f5a486cdafa1944b8357ff76620b135102e7ca4e3ba8e1f665f107ce37c9",
94
+ "sha256:6af10737e44a831e68f8f998c358319fb6d711f510a8f028a9c7e45adea8e6b5",
95
+ "sha256:c1eed26033b5582c8eda09a6906aacb6565767e3b312ad8e4fb7e45625b89b80",
96
+ "sha256:b8f1b6d65c0fe5accaa8bc6ce2e27bd929510bd533c4c4f968007a33e6c8a73a",
97
+ "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
98
+ "sha256:09034afe39a61a80029f7f991047dae70595166464e816831eaddd5ce07f81ae",
99
+ "sha256:4c036a9cda26e30321ab0b1a2eb85b3bb4107728473dc1d6affc0cb507be3fe4",
100
+ "sha256:2605e0c511b42f679d779c0ce83a43502203bc0f45b1ba6207e88971931b2dd0",
101
+ "sha256:155682c46b6df6a7e6aa7c25054bc9746c8cdb5e31eb1540a419c1524ef4bebe",
102
+ "sha256:94082dfd1ddd54c6539b4a2acbde31a67edde514a176c33634dbf3064d459b9d",
103
+ "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
104
+ "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
105
+ "sha256:819bd790e2e90b343222eed4b063c38539022b099a64960910a041f374cc9c4c",
106
+ "sha256:d308d34e7198cec7384b1f0faf37a0a1431e2b9bf424cd2dadf46f83951af6d3",
107
+ "sha256:e1e25bb5b4c22a20677a513822bcb105cafa8a9f3f2c83e95f6565ed3a505822",
108
+ "sha256:43784741481131e4fb6d6a6552d8e5c3271a5fe19b018a4c0d124fb013a92068",
109
+ "sha256:b6700e609a886917d55c491091ca8cdbac855c8451fbe78897eb4ea9233145e1",
110
+ "sha256:885ae60023499b5b32c1838c336867d10ef407a21e85976a2a552e2cac30de60",
111
+ "sha256:96a81d9233dbfada9c3af1e7aea9e4dd074bc8d45d8807b66d101b960c8b5f6d",
112
+ "sha256:8dcb2745c1ef5ffce728a0c70adb8a460baec96e53111a45807fbdc9357bcc82",
113
+ "sha256:8c74cee801c43a8f6bcf8c129697e5cd36d85ba0768a9da2369933b7096d4acc",
114
+ "sha256:c8621e95fd0ef0357a9214eb0365ad32753be2b28beed57c5f280dcf5e683889"
115
+ ]
116
+ },
117
+ "Metadata": {
118
+ "LastTagTime": "2026-07-22T07:31:04.486961734Z"
119
+ },
120
+ "Descriptor": {
121
+ "mediaType": "application/vnd.oci.image.index.v1+json",
122
+ "digest": "sha256:bfd6d6670db37b04e9cbef7375722e3f71d66745abf1714c05cc5b71fd126715",
123
+ "size": 856
124
+ },
125
+ "Identity": {
126
+ "Build": [
127
+ {
128
+ "Ref": "i5szxcpmvtmom471lcaimd17s",
129
+ "CreatedAt": "2026-07-22T03:31:05.944516135-04:00"
130
+ }
131
+ ]
132
+ }
133
+ }
134
+ ]
benchmarks/2026-07-22/kld-fp8-dcp4-summary.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kv_cache_dtype": "fp8",
3
+ "decode_context_parallel_size": 4,
4
+ "dcp_comm_backend": "a2a",
5
+ "dcp_kv_cache_interleave_size": 64,
6
+ "image": "verdictai/glm52-exl3-sparkinfer:release-final-candidate",
7
+ "reference_sha256": "87f992a689c054a0548a4b3863da6c809f9239beacd5786d0401e45904fec063",
8
+ "runs": 5,
9
+ "values": [
10
+ 0.10279403895168812,
11
+ 0.10165348871050081,
12
+ 0.10349890400264748,
13
+ 0.10377883960451506,
14
+ 0.1066076642818636
15
+ ],
16
+ "mean_kld": 0.10366658711024301,
17
+ "sample_sd_kld": 0.0018374274565621039,
18
+ "min_kld": 0.10165348871050081,
19
+ "max_kld": 0.1066076642818636,
20
+ "positions": [
21
+ 2047
22
+ ],
23
+ "elapsed_seconds": [
24
+ 54.33670258522034,
25
+ 54.51158666610718,
26
+ 53.775944232940674,
27
+ 53.915428161621094,
28
+ 54.98634886741638
29
+ ]
30
+ }
benchmarks/2026-07-22/kld-nvfp4-dcp4-summary.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kv_cache_dtype": "nvfp4_ds_mla",
3
+ "decode_context_parallel_size": 4,
4
+ "dcp_comm_backend": "a2a",
5
+ "dcp_kv_cache_interleave_size": 64,
6
+ "image": "verdictai/glm52-exl3-sparkinfer:release-final-candidate",
7
+ "reference_sha256": "87f992a689c054a0548a4b3863da6c809f9239beacd5786d0401e45904fec063",
8
+ "runs": 5,
9
+ "values": [
10
+ 0.10860844685877598,
11
+ 0.11193449965586706,
12
+ 0.11207043933152104,
13
+ 0.11378629573697746,
14
+ 0.11561076614221365
15
+ ],
16
+ "mean_kld": 0.11240208954507103,
17
+ "sample_sd_kld": 0.0025948019812057094,
18
+ "min_kld": 0.10860844685877598,
19
+ "max_kld": 0.11561076614221365,
20
+ "positions": [
21
+ 2047
22
+ ],
23
+ "elapsed_seconds": [
24
+ 53.81100344657898,
25
+ 53.41490030288696,
26
+ 54.5698766708374,
27
+ 53.741952657699585,
28
+ 54.79673457145691
29
+ ]
30
+ }
benchmarks/2026-07-22/lavd-c5-r10-pass2.json ADDED
The diff for this file is too large to render. See raw diff
 
benchmarks/2026-07-22/lavd-c5-r10-pass2.log ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ╭──────────────────────────── NVIDIA P2P Override ─────────────────────────────╮
2
+ │ Effective: yes │
3
+ │ Configured file: yes (/etc/modprobe.d/nvidia-p2p-override.conf) │
4
+ │ Runtime: ForceP2P=0x11; RMForceP2PType=1; RMPcieP2PType=2; │
5
+ │ GrdmaPciTopoCheckOverride=1; EnableResizableBar=1; DmaRemapPeerMmio=1 │
6
+ ╰──────────────────────────────────────────────────────────────────────────────╯
7
+ ╭─────────────────────────────── Configuration ────────────────────────────────╮
8
+ │ LAVD Context Consistency Test │
9
+ │ Model: GLM-5.2-EXL3-TR3-3.0bpw @ 127.0.0.1:8000 │
10
+ │ Prompt: profile:lavd-test │
11
+ │ Concurrency: 5 │
12
+ │ Measured runs: 10 | Max tokens: 20000 │
13
+ │ Scoring: EXACT / NEAR / FAIL numeric pair │
14
+ ╰──────────────────────────────────────────────────────────────────────────────╯
15
+
16
+ ╭────────────────────────────── Completion Stats ──────────────────────────────╮
17
+ │ LAVD Context Consistency Test │
18
+ │ Arithmetic is intentionally simple; the test checks whether the model keeps │
19
+ │ a long structured context consistent, finds human data-entry errors, applies │
20
+ │ the repair rule, and returns the final ticket count and hours. Built-in │
21
+ │ profile run at fixed concurrency C=5. │
22
+ ╰──────────────────────────────────────────────────────────────────────────────╯
23
+ Profile
24
+ ╭────────────────┬───────────────────╮
25
+ │ field │ value │
26
+ ├────────────────┼───────────────────┤
27
+ │ profile │ lavd-test │
28
+ │ prompt │ profile:lavd-test │
29
+ │ prompt chars │ 48,302 │
30
+ │ requested runs │ 10 │
31
+ │ concurrency │ 5 │
32
+ │ max tokens │ 20000 │
33
+ │ scoring │ ledger_lavd │
34
+ │ expected │ 72, 46 │
35
+ │ prompt sha256 │ 5c83674d5f0fd2a7 │
36
+ │ dataset sha256 │ 612f8041bbca048c │
37
+ ╰────────────────┴───────────────────╯
38
+ ╭───────────────────────── Whole-run GPU Power ─────────────────────────╮
39
+ │ avg 1,097 W | max 1,113 W | limit 1,200 W | over 8m 16s | 206 samples │
40
+ ╰───────────────────────────────────────────────────────────────────────╯
41
+ Concurrency Results
42
+ ╭───┬──────┬────────────────────┬────┬─────────┬────────┬──────────┬───────┬───╮
43
+ │ … │ don… │ score │ s… │ output… │ outpu… │ aggrega… │ avg … │ … │
44
+ ├───┼──────┼────────────────────┼────┼─────────┼────────┼──────────┼───────┼───┤
45
+ │ 5 │ 10/… │ EXACT 3 / NEAR 7 … │ ★… │ 8,783 │ 9,586 │ 38.1 │ 228.0 │ … │
46
+ ╰───┴──────┴────────────────────┴────┴─────────┴────────┴──────────┴───────┴───╯
47
+ Selected C=5
48
+ ╭────────────────────────────┬───────────────────────────╮
49
+ │ metric │ value │
50
+ ├────────────────────────────┼───────────────────────────┤
51
+ │ completed │ 10/10 │
52
+ │ score │ EXACT 3 / NEAR 7 / FAIL 0 │
53
+ │ stars │ ★★★☆☆☆☆☆☆☆ 👍 │
54
+ │ hit max_tokens │ 0 │
55
+ │ completion tokens avg │ 8,641 │
56
+ │ completion tokens p50 │ 8,783 │
57
+ │ completion tokens p90 │ 9,586 │
58
+ │ completion tokens p99 │ 9,995 │
59
+ │ elapsed avg │ 228.0s │
60
+ │ TTFT avg │ 1.02s │
61
+ │ aggregate gen tok/s │ 38.1 │
62
+ │ mean per-request gen tok/s │ 38.1 │
63
+ ╰────────────────────────────┴───────────────────────────╯
64
+ Interpretation: EXACT means the parsed final numeric pair is exactly 72, 46.0.
65
+ NEAR means both count and hours are within the configured tolerance; FAIL means
66
+ the answer was unparseable or outside tolerance. The 10-slot quality bar is a
67
+ rounded distribution: ★=EXACT, ☆=NEAR, ✕=FAIL.
68
+
69
+ Results saved to
70
+ results/20260722T091010Z-mtp1-dcp4-async-off/lavd-c5-r10-pass2.json
benchmarks/2026-07-22/lavd-c5-r10.json ADDED
The diff for this file is too large to render. See raw diff
 
benchmarks/2026-07-22/lavd-c5-r10.log ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ╭──────────────────────────── NVIDIA P2P Override ─────────────────────────────╮
2
+ │ Effective: yes │
3
+ │ Configured file: yes (/etc/modprobe.d/nvidia-p2p-override.conf) │
4
+ │ Runtime: ForceP2P=0x11; RMForceP2PType=1; RMPcieP2PType=2; │
5
+ │ GrdmaPciTopoCheckOverride=1; EnableResizableBar=1; DmaRemapPeerMmio=1 │
6
+ ╰──────────────────────────────────────────────────────────────────────────────╯
7
+ ╭─────────────────────────────── Configuration ────────────────────────────────╮
8
+ │ LAVD Context Consistency Test │
9
+ │ Model: GLM-5.2-EXL3-TR3-3.0bpw @ 127.0.0.1:8000 │
10
+ │ Prompt: profile:lavd-test │
11
+ │ Concurrency: 5 │
12
+ │ Measured runs: 10 | Max tokens: 20000 │
13
+ │ Scoring: EXACT / NEAR / FAIL numeric pair │
14
+ ╰──────────────────────────────────────────────────────────────────────────────╯
15
+
16
+ ╭────────────────────────────── Completion Stats ──────────────────────────────╮
17
+ │ LAVD Context Consistency Test │
18
+ │ Arithmetic is intentionally simple; the test checks whether the model keeps │
19
+ │ a long structured context consistent, finds human data-entry errors, applies │
20
+ │ the repair rule, and returns the final ticket count and hours. Built-in │
21
+ │ profile run at fixed concurrency C=5. │
22
+ ╰──────────────────────────────────────────────────────────────────────────────╯
23
+ Profile
24
+ ╭────────────────┬───────────────────╮
25
+ │ field │ value │
26
+ ├────────────────┼───────────────────┤
27
+ │ profile │ lavd-test │
28
+ │ prompt │ profile:lavd-test │
29
+ │ prompt chars │ 48,302 │
30
+ │ requested runs │ 10 │
31
+ │ concurrency │ 5 │
32
+ │ max tokens │ 20000 │
33
+ │ scoring │ ledger_lavd │
34
+ │ expected │ 72, 46 │
35
+ │ prompt sha256 │ 5c83674d5f0fd2a7 │
36
+ │ dataset sha256 │ 612f8041bbca048c │
37
+ ╰────────────────┴───────────────────╯
38
+ ╭───────────────────────── Whole-run GPU Power ─────────────────────────╮
39
+ │ avg 1,096 W | max 1,142 W | limit 1,200 W | over 9m 00s | 224 samples │
40
+ ╰───────────────────────────────────────────────────────────────────────╯
41
+ Concurrency Results
42
+ ╭───┬──────┬────────────────────┬────┬─────────┬────────┬──────────┬───────┬───╮
43
+ │ … │ don… │ score │ s… │ output… │ outpu… │ aggrega… │ avg … │ … │
44
+ ├───┼──────┼────────────────────┼────┼─────────┼────────┼──────────┼───────┼───┤
45
+ │ 5 │ 10/… │ EXACT 5 / NEAR 5 … │ ★… │ 9,322 │ 10,256 │ 38.1 │ 249.1 │ … │
46
+ ╰───┴──────┴────────────────────┴────┴─────────┴────────┴──────────┴───────┴───╯
47
+ Selected C=5
48
+ ╭────────────────────────────┬───────────────────────────╮
49
+ │ metric │ value │
50
+ ├────────────────────────────┼───────────────────────────┤
51
+ │ completed │ 10/10 │
52
+ │ score │ EXACT 5 / NEAR 5 / FAIL 0 │
53
+ │ stars │ ★★★★★☆☆☆☆☆ 👍 │
54
+ │ hit max_tokens │ 0 │
55
+ │ completion tokens avg │ 9,177 │
56
+ │ completion tokens p50 │ 9,322 │
57
+ │ completion tokens p90 │ 10,256 │
58
+ │ completion tokens p99 │ 10,882 │
59
+ │ elapsed avg │ 249.1s │
60
+ │ TTFT avg │ 7.91s │
61
+ │ aggregate gen tok/s │ 38.1 │
62
+ │ mean per-request gen tok/s │ 38.0 │
63
+ ╰────────────────────────────┴───────────────────────────╯
64
+ Interpretation: EXACT means the parsed final numeric pair is exactly 72, 46.0.
65
+ NEAR means both count and hours are within the configured tolerance; FAIL means
66
+ the answer was unparseable or outside tolerance. The 10-slot quality bar is a
67
+ rounded distribution: ★=EXACT, ☆=NEAR, ✕=FAIL.
68
+
69
+ Results saved to results/20260722T091010Z-mtp1-dcp4-async-off/lavd-c5-r10.json
benchmarks/2026-07-22/prefill-8k-64k-128k.json ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "metadata": {
3
+ "version": "0.4.29",
4
+ "engine": "vllm",
5
+ "model": "GLM-5.2-EXL3-TR3-3.0bpw",
6
+ "server": "127.0.0.1:8000",
7
+ "timestamp": "2026-07-22T05:36:14.936220",
8
+ "decode_mode": "duration",
9
+ "primary_decode_layer": "sustained_decode",
10
+ "duration_per_test": 30.0,
11
+ "request_count": 0,
12
+ "warmup_request_count": 0,
13
+ "run_burst": false,
14
+ "prefill_mode": "standalone_cold",
15
+ "standalone_prefill": true,
16
+ "prefill_only": true,
17
+ "skip_prefill": false,
18
+ "burst_e2e_status": "not_run_use_--run-burst",
19
+ "burst_request_count": 0,
20
+ "burst_warmup_request_count": 0,
21
+ "burst_requests_per_concurrency": 5,
22
+ "decode_warmup_seconds": 3.0,
23
+ "decode_warmup_context": 0,
24
+ "decode_warmup_concurrency": 1,
25
+ "cell_warmup_timeout_seconds": 0.0,
26
+ "cell_warmup_timeout_policy": "<=32k:60s,64k:120s,>=128k:180s when override is 0",
27
+ "show_capacity_limited_values": false,
28
+ "max_tokens": 8192,
29
+ "temperature": null,
30
+ "ignore_eos": true,
31
+ "max_total_tokens": 524288,
32
+ "dcp_size": 0,
33
+ "metrics_available": true,
34
+ "metrics_warning": "",
35
+ "concurrency_levels": [
36
+ 1,
37
+ 2,
38
+ 4,
39
+ 8,
40
+ 16,
41
+ 32,
42
+ 64,
43
+ 128
44
+ ],
45
+ "context_lengths": [
46
+ 0,
47
+ 16384,
48
+ 32768,
49
+ 65536,
50
+ 131072
51
+ ],
52
+ "startup_diagnostics_available": true,
53
+ "nvidia_p2p_override_effective": true,
54
+ "p2pmark_status": "not_run",
55
+ "amd_fabric_status": "not_run"
56
+ },
57
+ "startup_diagnostics": {
58
+ "version": "0.4.29",
59
+ "server_url": "http://127.0.0.1:8000",
60
+ "hostname": "pop-os",
61
+ "uname": "Linux pop-os 6.18.7-76061807-generic #202601231045~1769703228~24.04~cb87b5b SMP PREEMPT_DYNAMIC Thu J x86_64 x86_64 x86_64 GNU/Linux",
62
+ "env": {},
63
+ "args": {
64
+ "concurrency": "1,2,4,8,16,32,64,128",
65
+ "contexts": "0,16k,32k,64k,128k",
66
+ "max_tokens": 8192,
67
+ "duration": 30.0,
68
+ "request_count": 0,
69
+ "run_burst": false,
70
+ "standalone_prefill": true,
71
+ "prefill_only": true,
72
+ "skip_prefill": false,
73
+ "prefill_contexts": "8k,64k,128k",
74
+ "prefill_metric": "auto",
75
+ "dcp_size": 0,
76
+ "kv_budget": 0
77
+ },
78
+ "nvidia_p2p_override": {
79
+ "effective": true,
80
+ "configured": true,
81
+ "params_path": "/proc/driver/nvidia/params",
82
+ "params_available": true,
83
+ "modprobe_path": "/etc/modprobe.d/nvidia-p2p-override.conf",
84
+ "modprobe_available": true,
85
+ "runtime": {
86
+ "ForceP2P": "0x11",
87
+ "RMForceP2PType": "1",
88
+ "RMPcieP2PType": "2",
89
+ "GrdmaPciTopoCheckOverride": "1",
90
+ "EnableResizableBar": "1",
91
+ "DmaRemapPeerMmio": "1"
92
+ },
93
+ "expected": {
94
+ "ForceP2P": "0x11",
95
+ "RMForceP2PType": "1",
96
+ "RMPcieP2PType": "2",
97
+ "GrdmaPciTopoCheckOverride": "1",
98
+ "EnableResizableBar": "1"
99
+ },
100
+ "missing": [],
101
+ "mismatched": {},
102
+ "registry_dwords": "ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1",
103
+ "suggested_modprobe_line": "options nvidia NVreg_RegistryDwords=\"ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1\"",
104
+ "suggested_reload": "stop GPU workloads, then reload NVIDIA modules or reboot; the modprobe file alone is not enough until the nvidia module is reloaded"
105
+ },
106
+ "p2pmark": {
107
+ "status": "not_run"
108
+ },
109
+ "amd_fabric": {
110
+ "status": "not_run"
111
+ },
112
+ "nvidia_smi_query": {
113
+ "cmd": [
114
+ "nvidia-smi",
115
+ "--query-gpu=index,name,driver_version,pci.bus_id,pcie.link.gen.current,pcie.link.width.current,power.limit",
116
+ "--format=csv,noheader,nounits"
117
+ ],
118
+ "returncode": 0,
119
+ "stdout": "0, NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition, 595.58.03, 00000000:01:00.0, 5, 16, 300.00\n1, NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 595.58.03, 00000000:21:00.0, 5, 16, 300.00\n2, NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition, 595.58.03, 00000000:81:00.0, 5, 16, 300.00\n3, NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 595.58.03, 00000000:C1:00.0, 5, 16, 300.00",
120
+ "stderr": ""
121
+ },
122
+ "nvidia_smi_topo": {
123
+ "cmd": [
124
+ "nvidia-smi",
125
+ "topo",
126
+ "-m"
127
+ ],
128
+ "returncode": 0,
129
+ "stdout": "\u001b[4mGPU0\tGPU1\tGPU2\tGPU3\tCPU Affinity\tNUMA Affinity\tGPU NUMA ID\u001b[0m\nGPU0\t X \tNODE\tNODE\tNODE\t0-47\t0\t\tN/A\nGPU1\tNODE\t X \tNODE\tNODE\t0-47\t0\t\tN/A\nGPU2\tNODE\tNODE\t X \tNODE\t0-47\t0\t\tN/A\nGPU3\tNODE\tNODE\tNODE\t X \t0-47\t0\t\tN/A\n\nLegend:\n\n X = Self\n SYS = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI)\n NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node\n PHB = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU)\n PXB = Connection traversing multiple PCIe bridges (without traversing the PCIe Host Bridge)\n PIX = Connection traversing at most a single PCIe bridge\n NV# = Connection traversing a bonded set of # NVLinks",
130
+ "stderr": ""
131
+ }
132
+ },
133
+ "nvidia_p2p_override": {
134
+ "effective": true,
135
+ "configured": true,
136
+ "params_path": "/proc/driver/nvidia/params",
137
+ "params_available": true,
138
+ "modprobe_path": "/etc/modprobe.d/nvidia-p2p-override.conf",
139
+ "modprobe_available": true,
140
+ "runtime": {
141
+ "ForceP2P": "0x11",
142
+ "RMForceP2PType": "1",
143
+ "RMPcieP2PType": "2",
144
+ "GrdmaPciTopoCheckOverride": "1",
145
+ "EnableResizableBar": "1",
146
+ "DmaRemapPeerMmio": "1"
147
+ },
148
+ "expected": {
149
+ "ForceP2P": "0x11",
150
+ "RMForceP2PType": "1",
151
+ "RMPcieP2PType": "2",
152
+ "GrdmaPciTopoCheckOverride": "1",
153
+ "EnableResizableBar": "1"
154
+ },
155
+ "missing": [],
156
+ "mismatched": {},
157
+ "registry_dwords": "ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1",
158
+ "suggested_modprobe_line": "options nvidia NVreg_RegistryDwords=\"ForceP2P=0x11;RMForceP2PType=1;RMPcieP2PType=2;GrdmaPciTopoCheckOverride=1;EnableResizableBar=1\"",
159
+ "suggested_reload": "stop GPU workloads, then reload NVIDIA modules or reboot; the modprobe file alone is not enough until the nvidia module is reloaded"
160
+ },
161
+ "p2pmark": {
162
+ "status": "not_run"
163
+ },
164
+ "amd_fabric": {
165
+ "status": "not_run"
166
+ },
167
+ "hardware_run_summary": {
168
+ "samples": 79,
169
+ "duration_seconds": 188.739,
170
+ "gpu_count": 4,
171
+ "cpu_util_avg_pct": 13.14,
172
+ "cpu_temp_max_c": 81.88,
173
+ "gpu_util_avg_pct": 91.6,
174
+ "gpu_util_max_pct": 100.0,
175
+ "mem_util_avg_pct": 20.04,
176
+ "mem_util_max_pct": 36.0,
177
+ "temp_avg_c": 70.94,
178
+ "temp_max_c": 90.0,
179
+ "power_total_avg_w": 1068.71,
180
+ "power_total_max_w": 1162.61,
181
+ "power_limit_total_w": 1200.0,
182
+ "vram_used_avg_mb": 380759.81,
183
+ "vram_used_max_mb": 381263.0,
184
+ "vram_total_mb": 391548.0,
185
+ "vram_used_avg_pct": 97.24,
186
+ "vram_used_max_pct": 97.37,
187
+ "pcie_rx_avg_mb_s": 50640.37,
188
+ "pcie_rx_max_mb_s": 77266.0,
189
+ "pcie_tx_avg_mb_s": 49778.35,
190
+ "pcie_tx_max_mb_s": 98654.0
191
+ },
192
+ "event_log": [],
193
+ "prefill": {
194
+ "8192": {
195
+ "ttft_seconds": 5.46,
196
+ "prefill_seconds": 5.46,
197
+ "tok_per_sec": 1502.0,
198
+ "client_ttft_seconds": 5.46,
199
+ "client_tok_per_sec": 1502.0,
200
+ "prompt_tokens": 8201,
201
+ "samples": 2,
202
+ "method": "client",
203
+ "server_validation": {
204
+ "method": "prometheus",
205
+ "tok_per_sec": 1507.0,
206
+ "prefill_seconds": 5.443,
207
+ "prompt_tokens": 8201,
208
+ "request_prompt_tokens": 8201,
209
+ "cached_tokens": 0,
210
+ "token_source": "kv_computed",
211
+ "samples": 2,
212
+ "invalid_reason": ""
213
+ },
214
+ "hardware_summary": {
215
+ "samples": 7,
216
+ "duration_seconds": 14.434,
217
+ "gpu_count": 4,
218
+ "cpu_util_avg_pct": 12.59,
219
+ "cpu_temp_max_c": 79.38,
220
+ "gpu_util_avg_pct": 64.18,
221
+ "gpu_util_max_pct": 100.0,
222
+ "mem_util_avg_pct": 12.86,
223
+ "mem_util_max_pct": 24.0,
224
+ "temp_avg_c": 61.64,
225
+ "temp_max_c": 79.0,
226
+ "power_total_avg_w": 927.54,
227
+ "power_total_max_w": 1142.27,
228
+ "power_limit_total_w": 1200.0,
229
+ "vram_used_avg_mb": 379532.0,
230
+ "vram_used_max_mb": 379659.0,
231
+ "vram_total_mb": 391548.0,
232
+ "vram_used_avg_pct": 96.93,
233
+ "vram_used_max_pct": 96.96,
234
+ "pcie_rx_avg_mb_s": 15854.29,
235
+ "pcie_rx_max_mb_s": 37233.0,
236
+ "pcie_tx_avg_mb_s": 14198.71,
237
+ "pcie_tx_max_mb_s": 40655.0
238
+ }
239
+ },
240
+ "65536": {
241
+ "ttft_seconds": 51.64,
242
+ "prefill_seconds": 51.64,
243
+ "tok_per_sec": 1249.0,
244
+ "client_ttft_seconds": 51.64,
245
+ "client_tok_per_sec": 1249.0,
246
+ "prompt_tokens": 64512,
247
+ "samples": 1,
248
+ "method": "client",
249
+ "server_validation": {
250
+ "method": "prometheus",
251
+ "tok_per_sec": 1252.0,
252
+ "prefill_seconds": 51.523,
253
+ "prompt_tokens": 64512,
254
+ "request_prompt_tokens": 64512,
255
+ "cached_tokens": 0,
256
+ "token_source": "kv_computed",
257
+ "samples": 1,
258
+ "invalid_reason": ""
259
+ },
260
+ "hardware_summary": {
261
+ "samples": 22,
262
+ "duration_seconds": 50.859,
263
+ "gpu_count": 4,
264
+ "cpu_util_avg_pct": 13.5,
265
+ "cpu_temp_max_c": 80.38,
266
+ "gpu_util_avg_pct": 95.41,
267
+ "gpu_util_max_pct": 100.0,
268
+ "mem_util_avg_pct": 21.09,
269
+ "mem_util_max_pct": 27.0,
270
+ "temp_avg_c": 68.94,
271
+ "temp_max_c": 90.0,
272
+ "power_total_avg_w": 1086.17,
273
+ "power_total_max_w": 1144.61,
274
+ "power_limit_total_w": 1200.0,
275
+ "vram_used_avg_mb": 380781.5,
276
+ "vram_used_max_mb": 381109.0,
277
+ "vram_total_mb": 391548.0,
278
+ "vram_used_avg_pct": 97.25,
279
+ "vram_used_max_pct": 97.33,
280
+ "pcie_rx_avg_mb_s": 55074.05,
281
+ "pcie_rx_max_mb_s": 77266.0,
282
+ "pcie_tx_avg_mb_s": 54968.68,
283
+ "pcie_tx_max_mb_s": 90554.0
284
+ }
285
+ },
286
+ "131072": {
287
+ "ttft_seconds": 109.002,
288
+ "prefill_seconds": 109.002,
289
+ "tok_per_sec": 1182.0,
290
+ "client_ttft_seconds": 109.002,
291
+ "client_tok_per_sec": 1182.0,
292
+ "prompt_tokens": 128881,
293
+ "samples": 1,
294
+ "method": "client",
295
+ "server_validation": {
296
+ "method": "prometheus",
297
+ "tok_per_sec": 1185.0,
298
+ "prefill_seconds": 108.797,
299
+ "prompt_tokens": 128881,
300
+ "request_prompt_tokens": 128881,
301
+ "cached_tokens": 0,
302
+ "token_source": "kv_computed",
303
+ "samples": 1,
304
+ "invalid_reason": ""
305
+ },
306
+ "hardware_summary": {
307
+ "samples": 46,
308
+ "duration_seconds": 108.985,
309
+ "gpu_count": 4,
310
+ "cpu_util_avg_pct": 13.36,
311
+ "cpu_temp_max_c": 81.88,
312
+ "gpu_util_avg_pct": 97.01,
313
+ "gpu_util_max_pct": 100.0,
314
+ "mem_util_avg_pct": 21.29,
315
+ "mem_util_max_pct": 27.0,
316
+ "temp_avg_c": 74.17,
317
+ "temp_max_c": 90.0,
318
+ "power_total_avg_w": 1105.58,
319
+ "power_total_max_w": 1151.83,
320
+ "power_limit_total_w": 1200.0,
321
+ "vram_used_avg_mb": 381232.07,
322
+ "vram_used_max_mb": 381263.0,
323
+ "vram_total_mb": 391548.0,
324
+ "vram_used_avg_pct": 97.37,
325
+ "vram_used_max_pct": 97.37,
326
+ "pcie_rx_avg_mb_s": 57352.15,
327
+ "pcie_rx_max_mb_s": 76770.0,
328
+ "pcie_tx_avg_mb_s": 55909.09,
329
+ "pcie_tx_max_mb_s": 98654.0
330
+ }
331
+ }
332
+ },
333
+ "results": [],
334
+ "summary_table": {},
335
+ "burst_results": [],
336
+ "burst_summary_table": {},
337
+ "methodology": {
338
+ "prefill": {
339
+ "name": "Prefill",
340
+ "present": true,
341
+ "mode": "standalone_cold",
342
+ "formula": "prompt_tokens / TTFT",
343
+ "notes": "Default mode records the required decode scout request for each non-zero decode context, so normal runs do not pay for a separate prefill phase. Standalone mode repeats cold-prefill samples. Prometheus prefill counters, when available and uncontaminated, are stored as validation."
344
+ },
345
+ "sustained_decode": {
346
+ "name": "Sustained Decode",
347
+ "present": false,
348
+ "formula": "OpenAI stream usage completion_tokens per measured window; client chunk fallback only when continuous usage is unavailable",
349
+ "notes": "Duration-based steady-state cell after warmup. This is the main tuning/regression signal for kernels, NCCL, DCP, MTP, and scheduling. Prometheus metrics are stored as validation and scheduler state, not the default headline."
350
+ },
351
+ "burst_e2e_decode": {
352
+ "name": "Burst / E2E Decode",
353
+ "present": false,
354
+ "status": "not run; use --run-burst",
355
+ "formula": "sum(completion_tokens) / profiling_wall_time",
356
+ "notes": "Finite client-facing request burst using OpenAI stream usage. It includes request admission, scheduling, prefill/cache behavior, and completion."
357
+ }
358
+ }
359
+ }
benchmarks/2026-07-22/prefill-8k-64k-128k.log ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ╭──────────────────────────── NVIDIA P2P Override ─────────────────────────────╮
2
+ │ Effective: yes │
3
+ │ Configured file: yes (/etc/modprobe.d/nvidia-p2p-override.conf) │
4
+ │ Runtime: ForceP2P=0x11; RMForceP2PType=1; RMPcieP2PType=2; │
5
+ │ GrdmaPciTopoCheckOverride=1; EnableResizableBar=1; DmaRemapPeerMmio=1 │
6
+ ╰──────────────────────────────────────────────────────────────────────────────╯
7
+ ╭─────────────────────────────── Configuration ────────────────────────────────╮
8
+ │ LLM Inference Benchmark │
9
+ │ Model: GLM-5.2-EXL3-TR3-3.0bpw @ 127.0.0.1:8000 │
10
+ │ Decode concurrency: [1, 2, 4, 8, 16, 32, 64, 128] │
11
+ │ Decode contexts: ['0', '16k', '32k', '64k', '128k'] │
12
+ │ Decode: skipped (--prefill-only) | Max tokens: 8192 │
13
+ │ Pre-decode warmup: C=1 max-runnable context for 3s │
14
+ │ Prefill-only: standalone cold profile (auto) | Sustained decode: 0 cells │
15
+ ╰──────────────────────────────────────────────────────────────────────────────╯
16
+ Engine: vLLM 0.17.0rc1.dev4499+g60c82d972 Models: ['GLM-5.2-EXL3-TR3-3.0bpw']
17
+ KV cache budget (vLLM metrics): 524,288 tokens (2048 blocks × 64; local 131,072
18
+ × CP 4; CP source: local process)
19
+ Model context length: 524,288 tokens
20
+ Prefill tests: standalone cold profile ['8k', '64k', '128k']
21
+ Calibrating padding text (run=nhzlzwcrjyxl, up to 128k)...
22
+ Token targeting: single-point estimate from 8k (use --token-targeting exact
23
+ for /tokenize binary search)
24
+ Calibrated: 6.18 chars/token (cached, source=8k)
25
+ 8k: 50,598 chars (~8,191 tokens)
26
+ 16k: 101,196 chars (~16,383 tokens)
27
+ 32k: 202,393 chars (~32,767 tokens)
28
+ 64k: 404,786 chars (~65,535 tokens)
29
+ 128k: 809,572 chars (~131,071 tokens)
30
+ Done.
31
+
32
+
33
+
34
+ llm-decode-bench v0.4.29
35
+ Prefill Speed (C=1, client ISL / TTFT)
36
+
37
+ PCIe rx/tx
38
+ Context Tokens TTFT (s) Client tok/s Server tok/s avg N
39
+ ──────────────────────────────────────────────────────────────────────────────
40
+ 8k 8,201 5.46 1,502 1,507 (2) 15854/14199 2
41
+ 64k 64,512 51.64 1,249 1,252 (1) 55074/54969 1
42
+ 128k 128,881 109.00 1,182 1,185 (1) 57352/55909 1
43
+
44
+ Client tok/s = prompt_tokens / TTFT. Integrated scout rows come from the
45
+ prefix-cache scout request that decode needs anyway. Server tok/s is optional
46
+ Prometheus validation when the engine exports prefill counters and the exact
47
+ counter delta is uncontaminated; for vLLM this uses newly computed KV tokens,
48
+ not request prompt tokens.
49
+
50
+
51
+ Results saved to
52
+ results/20260722T091010Z-mtp1-dcp4-async-off/prefill-8k-64k-128k.json
calibration_encoder/README.md ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Calibration + EXL3-Trellis encoder (reproduction bundle)
2
+
3
+ These are the exact scripts and calibration corpus used to produce
4
+ **GLM-5.2-EXL3-TR3-3.0bpw** from the BF16 base
5
+ [`zai-org/GLM-5.2`](https://huggingface.co/zai-org/GLM-5.2).
6
+
7
+ The routed MoE experts (layers 3–77, all 256 experts) are quantized to a 3.0-bpw
8
+ EXL3 **Trellis** representation with a **calibrated LDLQ** pass (proxy Hessians
9
+ from the corpus below); attention, dense MLPs (0–2), shared experts, router/gates,
10
+ MTP layer 78, embeddings, and LM head stay BF16. Weights are pre-sliced for **TP4**
11
+ and packed with the **MCG** codebook. It is **not** NVIDIA ModelOpt — the
12
+ `quant_method: modelopt` field in the model `config.json` is only a loader-dispatch
13
+ shim; the actual encoder is the calibrated LDLQ/Trellis pipeline here.
14
+
15
+ ## Files
16
+
17
+ | File | Role |
18
+ | --- | --- |
19
+ | `encode_tr3_v31.py` | Production LDLQ/Trellis encoder (v3 cross-slice lockstep). SHA-256 `e9a85a47…75032`, pinned by `encode_b300.py`. |
20
+ | `encode_b300.py` | B300 adapter around `encode_tr3_v31.py`: source IO, RAM capture IO, all-256 tiering, resume, assembly, and the model `config.json` dispatch shim. |
21
+ | `capture_b300.py` | Builds the deterministic capture plan and captures per-layer proxy Hessians from the corpus. |
22
+ | `bootstrap_ext_b300.py` | Builds/loads exllamav3 0.0.43's six quantizer ops (`had_r_128`, `pack_trellis`, `quantize_tiles`, `reconstruct`, `reconstruct_slice`, `unpack_trellis`) as an `sm_100` extension. |
23
+ | `preflight_b300.py` | Environment/HBM/disk/corpus smoke checks. |
24
+ | `convert_b300.sh` | Orchestrator (stage runner). |
25
+ | `calibration/reap_recall_calib.jsonl` | The calibration corpus (12,228 samples). SHA-256 `cf247acc…44df4`, pinned by `capture_b300.py`. |
26
+
27
+ ## Requirements
28
+
29
+ - **exllamav3 == 0.0.43**, installed with its source package (the extension is built
30
+ from its sources; the package is never imported at runtime). `bootstrap_ext_b300.py`
31
+ locates the installed sources and refuses any other version.
32
+ - **NVIDIA Blackwell** GPUs. The reference run used a **B300 (SM 10.0 / `sm_100`)** node
33
+ with **8 GPUs** (`TORCH_CUDA_ARCH_LIST=10.0`, capture at TP8, packed for TP4).
34
+ - **CUDA 12.9** (`CUDA_HOME=/usr/local/cuda-12.9`), PyTorch with matching CUDA.
35
+ - The BF16 base model `zai-org/GLM-5.2`.
36
+ - Large tmpfs (`/dev/shm`) for the Hessian capture windows and ~0.5 TB scratch for
37
+ assembly. The orchestrator enforces disk/RAM guards.
38
+
39
+ ## Corpus schema
40
+
41
+ JSONL, one object per line:
42
+
43
+ ```json
44
+ {"axis": "axis2_legal", "source": "neo4j_headnote:text", "text": "{\"messages\":[...]}", "meta": {...}}
45
+ ```
46
+
47
+ `text` is a serialized chat/messages blob. 12,228 rows are balanced across four axes
48
+ (≈3,057 each): `axis1_general`, `axis2_legal`, `axis3_code_agentic`,
49
+ `axis4_reasoning_termination`. The legal axis is public-record material (case law,
50
+ headnotes, statutes) plus synthetic legal-reasoning items. To calibrate on your own
51
+ data, keep the same schema and re-point `--corpus`; the pinned SHA guard in
52
+ `capture_b300.py` is only there to reproduce *this* build byte-for-byte, so relax it
53
+ if you substitute a corpus.
54
+
55
+ ## Reproduce
56
+
57
+ Set the paths the orchestrator expects (or export overrides), then run the stages.
58
+ `encode_tr3_v31.py` and the corpus must sit where the scripts look, e.g.:
59
+
60
+ ```bash
61
+ export WORK_ROOT=/workspace/tr3
62
+ export BF16_SRC=/workspace/bf16 # zai-org/GLM-5.2 (BF16)
63
+ export OWNER_CORPUS=$WORK_ROOT/calib/reap_recall_calib.jsonl
64
+ export BASE_ENCODER_PY=$WORK_ROOT/encode_tr3_v31.py
65
+ export CUDA_HOME=/usr/local/cuda-12.9
66
+
67
+ ./convert_b300.sh preflight # env + corpus + HBM smoke checks
68
+ ./convert_b300.sh ext # build the sm_100 exllamav3 0.0.43 ops
69
+ ./convert_b300.sh plan # deterministic capture manifest
70
+
71
+ # Process the MoE tail (layers 3..77) in windows of <=8 layers:
72
+ for W in 3-10 11-18 19-26 27-34 35-42 43-50 51-58 59-66 67-74 75-77; do
73
+ LAYERS=$W ./convert_b300.sh capture-window # proxy Hessians -> /dev/shm
74
+ LAYERS=$W ./convert_b300.sh encode-window # calibrated LDLQ/Trellis encode
75
+ done
76
+
77
+ ./convert_b300.sh assemble # assemble the final TP4 checkpoint + config
78
+ ```
79
+
80
+ The output is a rank-sliced EXL3-Trellis checkpoint with the `hybrid_tr3_tail`
81
+ metadata block that vLLM + Sparkinfer use to take the pre-planned (CUDA-graph-safe)
82
+ kernel path. Serve it per the model card's runtime section with `-tp 4`.
83
+
84
+ ## Method summary
85
+
86
+ Per routed-expert projection, per TP4 slice: Hadamard incoherence rotation (su/sv)
87
+ → block LDL of the calibrated proxy Hessian → blocked LDLQ quantization with error
88
+ feedback → MCG trellis codebook at 3 bits. The 64 experts with the highest trellis
89
+ round-trip error can optionally be kept as an NVFP4 sidecar (disabled in this build,
90
+ `nvfp4_keep_per_layer: 0`).
calibration_encoder/bootstrap_ext_b300.py ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Build/load exllamav3 0.0.43's six quantizer ops without importing its package."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import importlib.metadata
8
+ import os
9
+ from pathlib import Path
10
+ import re
11
+ import shutil
12
+ import site
13
+ import subprocess
14
+ import sys
15
+ import sysconfig
16
+
17
+
18
+ # The owner requires an sm_100 build even though this driver's runtime reports
19
+ # the B300 devices as compute capability 10.3. Keep build target and runtime
20
+ # observation separate.
21
+ ARCH_LIST = "10.0"
22
+ REQUIRED_VERSION = "0.0.43"
23
+ REQUIRED_OPS = (
24
+ "had_r_128",
25
+ "pack_trellis",
26
+ "quantize_tiles",
27
+ "reconstruct",
28
+ "reconstruct_slice",
29
+ "unpack_trellis",
30
+ )
31
+ GIB = 1 << 30
32
+ DEFAULT_BUILD_DIR = Path("/workspace/tr3/torch_extensions/exllamav3_ext_sm100")
33
+ DEFAULT_DISK_RESERVE_BYTES = 256 * GIB
34
+ EXT_BUILD_ALLOWANCE_BYTES = 32 * GIB
35
+
36
+
37
+ def _existing_ancestor(path: Path) -> Path:
38
+ current = path.expanduser().resolve(strict=False)
39
+ while not current.exists():
40
+ if current.parent == current:
41
+ raise RuntimeError(f"no existing filesystem ancestor for {path}")
42
+ current = current.parent
43
+ return current
44
+
45
+
46
+ def assert_disk_free(path: Path, write_bytes: int, label: str) -> dict:
47
+ reserve = int(os.environ.get("B300_DISK_RESERVE_BYTES", DEFAULT_DISK_RESERVE_BYTES))
48
+ anchor = _existing_ancestor(path)
49
+ usage = shutil.disk_usage(anchor)
50
+ required = int(write_bytes) + reserve
51
+ if usage.free < required:
52
+ raise RuntimeError(
53
+ f"DISK GUARD {label}: {usage.free} bytes free at {anchor}; "
54
+ f"need {write_bytes} write bytes + {reserve} reserve = {required}"
55
+ )
56
+ result = {
57
+ "target": str(path),
58
+ "anchor": str(anchor),
59
+ "free_bytes": usage.free,
60
+ "write_allowance_bytes": int(write_bytes),
61
+ "reserve_bytes": reserve,
62
+ }
63
+ print(f"DISK GUARD PASS: {label}: {result}", flush=True)
64
+ return result
65
+
66
+
67
+ def _candidate_roots() -> list[Path]:
68
+ roots: list[Path] = []
69
+ try:
70
+ dist = importlib.metadata.distribution("exllamav3")
71
+ roots.append(Path(dist.locate_file("exllamav3/exllamav3_ext")))
72
+ except importlib.metadata.PackageNotFoundError:
73
+ pass
74
+ prefixes: list[str] = []
75
+ try:
76
+ prefixes.extend(site.getsitepackages())
77
+ except AttributeError:
78
+ pass
79
+ user_site = site.getusersitepackages()
80
+ if isinstance(user_site, str):
81
+ prefixes.append(user_site)
82
+ purelib = sysconfig.get_path("purelib")
83
+ if purelib:
84
+ prefixes.append(purelib)
85
+ prefixes.extend(path for path in sys.path if path)
86
+ roots.extend(Path(path) / "exllamav3" / "exllamav3_ext" for path in prefixes)
87
+ unique: list[Path] = []
88
+ seen: set[str] = set()
89
+ for root in roots:
90
+ key = str(root.resolve(strict=False))
91
+ if key not in seen:
92
+ seen.add(key)
93
+ unique.append(root)
94
+ return unique
95
+
96
+
97
+ def find_source_root() -> Path:
98
+ for root in _candidate_roots():
99
+ if (root / "bindings.cpp").is_file() and (root / "quant" / "quantize.cu").is_file():
100
+ return root.resolve()
101
+ searched = "\n ".join(str(path) for path in _candidate_roots())
102
+ raise FileNotFoundError(
103
+ "exllamav3 extension sources not found. Install exllamav3==0.0.43 "
104
+ f"with its source package. Searched:\n {searched}"
105
+ )
106
+
107
+
108
+ def _assert_version() -> str:
109
+ try:
110
+ version = importlib.metadata.version("exllamav3")
111
+ except importlib.metadata.PackageNotFoundError as exc:
112
+ raise RuntimeError("exllamav3 is not installed in this Python environment") from exc
113
+ if version.split("+", 1)[0] != REQUIRED_VERSION:
114
+ raise RuntimeError(f"encoder is pinned to exllamav3 {REQUIRED_VERSION}; found {version}")
115
+ return version
116
+
117
+
118
+ def observed_ops(ext: object) -> list[str]:
119
+ return sorted(
120
+ name
121
+ for name in dir(ext)
122
+ if not name.startswith("_") and callable(getattr(ext, name, None))
123
+ )
124
+
125
+
126
+ def _assert_ops(ext: object) -> list[str]:
127
+ actual = observed_ops(ext)
128
+ missing = [name for name in REQUIRED_OPS if name not in actual]
129
+ if missing:
130
+ raise RuntimeError(f"exllamav3_ext missing {missing}; actual callable ops={actual}")
131
+ return actual
132
+
133
+
134
+ def _nvcc_release(cuda_home: str) -> str:
135
+ output = subprocess.run(
136
+ [str(Path(cuda_home) / "bin" / "nvcc"), "--version"],
137
+ check=True,
138
+ text=True,
139
+ stdout=subprocess.PIPE,
140
+ stderr=subprocess.STDOUT,
141
+ ).stdout
142
+ match = re.search(r"release\s+(\d+\.\d+)", output)
143
+ if not match:
144
+ raise RuntimeError(f"could not parse nvcc release: {output}")
145
+ return match.group(1)
146
+
147
+
148
+ def build(*, verbose: bool | None = None):
149
+ """Return the guarded sm_100 module and register it as ``exllamav3_ext``."""
150
+ existing = sys.modules.get("exllamav3_ext")
151
+ if existing is not None:
152
+ actual = _assert_ops(existing)
153
+ metadata = getattr(existing, "_b300_bootstrap", {})
154
+ if metadata.get("arch_list") != ARCH_LIST:
155
+ raise RuntimeError(
156
+ f"refusing unverified/preloaded extension: metadata={metadata!r}, ops={actual}"
157
+ )
158
+ return existing
159
+
160
+ version = _assert_version()
161
+ source_root = find_source_root()
162
+ sources = sorted(
163
+ str(path.resolve())
164
+ for path in source_root.rglob("*")
165
+ if path.is_file() and path.suffix in {".c", ".cpp", ".cu"}
166
+ )
167
+ if not sources:
168
+ raise RuntimeError(f"no extension sources under {source_root}")
169
+
170
+ os.environ["TORCH_CUDA_ARCH_LIST"] = ARCH_LIST
171
+ os.environ.setdefault("MAX_JOBS", "32")
172
+ import torch
173
+ from torch.utils.cpp_extension import CUDA_HOME, load
174
+
175
+ if not CUDA_HOME:
176
+ raise RuntimeError("torch.utils.cpp_extension did not resolve CUDA_HOME")
177
+ nvcc_release = _nvcc_release(CUDA_HOME)
178
+ torch_cuda = str(torch.version.cuda)
179
+ if int(nvcc_release.split(".", 1)[0]) != int(torch_cuda.split(".", 1)[0]):
180
+ raise RuntimeError(
181
+ f"CUDA compiler/PyTorch major mismatch: CUDA_HOME={CUDA_HOME}, "
182
+ f"nvcc={nvcc_release}, torch CUDA={torch_cuda}"
183
+ )
184
+
185
+ build_path = Path(os.environ.get("EXL3_B300_BUILD_DIR", str(DEFAULT_BUILD_DIR)))
186
+ build_path = build_path.expanduser().resolve(strict=False)
187
+ assert_disk_free(build_path, EXT_BUILD_ALLOWANCE_BYTES, "extension build")
188
+ build_path.mkdir(parents=True, exist_ok=True)
189
+ assert_disk_free(build_path, EXT_BUILD_ALLOWANCE_BYTES, "extension build pre-load")
190
+
191
+ extra_cuda_cflags = [
192
+ "-lineinfo",
193
+ "-O3",
194
+ "--use_fast_math",
195
+ "-Xcudafe",
196
+ "--diag_suppress=177",
197
+ "-Xcudafe",
198
+ "--diag_suppress=20012",
199
+ ]
200
+ cuda_host_cxx = os.environ.get("CUDAHOSTCXX")
201
+ if cuda_host_cxx:
202
+ extra_cuda_cflags += ["-ccbin", cuda_host_cxx]
203
+ if verbose is None:
204
+ verbose = os.environ.get("EXL3_B300_EXT_VERBOSE", "0") == "1"
205
+ ext = load(
206
+ name="exllamav3_ext",
207
+ sources=sources,
208
+ extra_include_paths=[str(source_root)],
209
+ extra_cflags=["-Ofast"],
210
+ extra_cuda_cflags=extra_cuda_cflags,
211
+ extra_ldflags=[],
212
+ build_directory=str(build_path),
213
+ verbose=verbose,
214
+ )
215
+ actual = _assert_ops(ext)
216
+ sys.modules["exllamav3_ext"] = ext
217
+ ext.__dict__.setdefault("_b300_bootstrap", {})
218
+ ext.__dict__["_b300_bootstrap"].update(
219
+ {
220
+ "arch_list": ARCH_LIST,
221
+ "exllamav3": version,
222
+ "source_root": str(source_root),
223
+ "build_directory": str(build_path),
224
+ "nvcc_release": nvcc_release,
225
+ "torch_cuda": torch_cuda,
226
+ "observed_ops": actual,
227
+ }
228
+ )
229
+ return ext
230
+
231
+
232
+ def _functional_smoke(ext: object, torch) -> dict:
233
+ device = torch.device("cuda:0")
234
+ input_tiles = torch.stack(
235
+ (
236
+ torch.linspace(-1.0, 1.0, 256, device=device),
237
+ torch.linspace(0.75, -0.25, 256, device=device),
238
+ )
239
+ ).contiguous()
240
+ output_tiles = torch.zeros_like(input_tiles)
241
+ output_indices = torch.zeros((2, 256), device=device, dtype=torch.int16)
242
+ temp_costs = torch.zeros((2, 2, 8192), device=device, dtype=torch.float16)
243
+ temp_edges = torch.zeros((2, 256, 8192), device=device, dtype=torch.int16)
244
+ ext.quantize_tiles(
245
+ input_tiles, output_tiles, output_indices, temp_costs, temp_edges, 3, True, False
246
+ )
247
+
248
+ # pack_trellis stores the low K bits of cyclic 16-bit trellis states;
249
+ # quantize_tiles supplies a valid state path. Independent values such as
250
+ # arange(256) % 2**K are not a valid input contract for an identity test.
251
+ encoded = output_indices.view(1, 2, 256).contiguous()
252
+ packed_tiles = torch.zeros((1, 2, 48), device=device, dtype=torch.int16)
253
+ unpacked = torch.zeros_like(encoded)
254
+ ext.pack_trellis(packed_tiles, encoded, 3)
255
+ ext.unpack_trellis(unpacked, packed_tiles, 3)
256
+ torch.cuda.synchronize()
257
+ if not torch.equal(unpacked, encoded):
258
+ raise RuntimeError("valid trellis-state pack/unpack CUDA round-trip mismatch")
259
+ if torch.equal(packed_tiles[:, 0], packed_tiles[:, 1]):
260
+ raise RuntimeError("distinct quantized smoke tiles produced identical trellis data")
261
+
262
+ packed = torch.cat(
263
+ (packed_tiles[:, 0:1].repeat(1, 8, 1), packed_tiles[:, 1:2].repeat(1, 8, 1)),
264
+ dim=1,
265
+ ).contiguous()
266
+ reconstructed = torch.empty((16, 256), device=device, dtype=torch.float16)
267
+ ext.reconstruct(reconstructed, packed, 3, True, False)
268
+ reconstructed_slice = torch.empty((16, 128), device=device, dtype=torch.float16)
269
+ ext.reconstruct_slice(reconstructed_slice, packed, 3, True, False, 128)
270
+
271
+ had_out = torch.empty((1, 128), device=device, dtype=torch.float32)
272
+ ext.had_r_128(
273
+ torch.arange(128, device=device, dtype=torch.float32).view(1, 128),
274
+ had_out,
275
+ None,
276
+ None,
277
+ 1.0,
278
+ )
279
+ torch.cuda.synchronize()
280
+ if not torch.equal(reconstructed_slice, reconstructed[:, 128:]):
281
+ raise RuntimeError("reconstruct_slice differs from full reconstruct")
282
+ if not bool(torch.isfinite(reconstructed).all()):
283
+ raise RuntimeError("reconstruct produced non-finite output")
284
+ if not bool(torch.isfinite(output_tiles).all()) or not bool(torch.isfinite(had_out).all()):
285
+ raise RuntimeError("quantize_tiles/had_r_128 produced non-finite output")
286
+ return {
287
+ "pack_trellis_launched": True,
288
+ "unpack_trellis_launched": True,
289
+ "valid_trellis_pack_unpack_identity": True,
290
+ "reconstruct_launched": True,
291
+ "reconstruct_slice_launched": True,
292
+ "reconstruct_slice_matches_full": True,
293
+ "reconstruct_finite": True,
294
+ "quantize_tiles_launched": True,
295
+ "quantize_tiles_finite": True,
296
+ "had_r_128_launched": True,
297
+ "had_r_128_finite": True,
298
+ }
299
+
300
+
301
+ def _cubin_arches(module_path: str) -> list[str]:
302
+ tool = shutil.which("cuobjdump")
303
+ if not tool or not module_path:
304
+ return []
305
+ result = subprocess.run(
306
+ [tool, "--list-elf", module_path],
307
+ check=False,
308
+ text=True,
309
+ stdout=subprocess.PIPE,
310
+ stderr=subprocess.STDOUT,
311
+ )
312
+ return sorted(set(re.findall(r"sm_[0-9a-z]+", result.stdout)))
313
+
314
+
315
+ def hardware_check() -> None:
316
+ ext = build(verbose=True)
317
+ import torch
318
+
319
+ if not torch.cuda.is_available() or torch.cuda.device_count() != 8:
320
+ raise RuntimeError(
321
+ f"expected eight CUDA devices, available={torch.cuda.is_available()} "
322
+ f"count={torch.cuda.device_count()}"
323
+ )
324
+ cap = torch.cuda.get_device_capability(0)
325
+ name = torch.cuda.get_device_name(0)
326
+ if cap != (10, 3) or "B300" not in name:
327
+ raise RuntimeError(f"expected B300-class CC 10.3 hardware, got {name!r} {cap}")
328
+ actual = _assert_ops(ext)
329
+ smoke = _functional_smoke(ext, torch)
330
+ arches = _cubin_arches(str(getattr(ext, "__file__", "")))
331
+ print(
332
+ "EXL3 EXT OK: "
333
+ f"torch={torch.__version__} cuda={torch.version.cuda} "
334
+ f"gpu={name!r} capability={cap} build_arch={ARCH_LIST} "
335
+ f"module={getattr(ext, '__file__', None)} cubins={arches} "
336
+ f"source={find_source_root()}"
337
+ )
338
+ print(f"ACTUAL EXT OPS: {actual}")
339
+ print(f"CUDA OP SMOKE: {smoke}")
340
+
341
+
342
+ def main() -> None:
343
+ parser = argparse.ArgumentParser(
344
+ description="flash-attn-free exllamav3 0.0.43 extension loader for B300"
345
+ )
346
+ parser.add_argument("--check", action="store_true", help="build and launch CUDA/op smoke")
347
+ parser.add_argument("--print-source", action="store_true", help="print source root without torch")
348
+ args = parser.parse_args()
349
+ if args.print_source:
350
+ _assert_version()
351
+ print(find_source_root())
352
+ elif args.check:
353
+ hardware_check()
354
+ else:
355
+ build()
356
+
357
+
358
+ if __name__ == "__main__":
359
+ main()
calibration_encoder/calibration/reap_recall_calib.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cf247acc7c5da9f0600c7d6ab3b7c2fcfc54ec30b794e3b6047559285fa44df4
3
+ size 34002059
calibration_encoder/capture_b300.py ADDED
@@ -0,0 +1,1167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """TP8 BF16 calibration capture for the all-EXL3 GLM-5.2 B300 build.
3
+
4
+ The payload ABI intentionally matches the proven TR3 encoder (BF16 x rows plus
5
+ natural top-8 expert IDs), but the output directory MUST be a RAM-backed tmpfs.
6
+ At most eight capture-data layers are striped across TP ranks per window.
7
+ No CPU model offload, low-memory mode, forced expert activation, or transformers
8
+ model loading is used. Transformers is used only for tokenization in this
9
+ capture environment; the encoder has no transformers dependency.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import argparse
15
+ from collections import Counter
16
+ import faulthandler
17
+ import gc
18
+ import hashlib
19
+ import json
20
+ import math
21
+ import os
22
+ from pathlib import Path
23
+ import random
24
+ import re
25
+ import shutil
26
+ import signal
27
+ import sys
28
+ import time
29
+ import uuid
30
+
31
+
32
+ try:
33
+ faulthandler.register(signal.SIGUSR2, all_threads=True)
34
+ except (AttributeError, RuntimeError):
35
+ pass
36
+
37
+
38
+ CORPUS_SHA256 = "cf247acc7c5da9f0600c7d6ab3b7c2fcfc54ec30b794e3b6047559285fa44df4"
39
+ CORPUS_ROWS = 12_228
40
+ AXES = (
41
+ "axis1_general",
42
+ "axis2_legal",
43
+ "axis3_code_agentic",
44
+ "axis4_reasoning_termination",
45
+ )
46
+ AXIS_ROWS = 3_057
47
+
48
+ SEED = 20260711
49
+ TARGET_TOKENS = 1_048_576 # one GLOBAL budget across all passes
50
+ MAX_SAMPLE_TOKENS = 4_096
51
+ MIN_SAMPLE_TOKENS = 8
52
+
53
+ HIDDEN = 6_144
54
+ NUM_EXPERTS = 256
55
+ TOPK = 8
56
+ FIRST_MOE_LAYER = 3
57
+ NUM_LAYERS = 78
58
+ MOE_LAYERS = list(range(FIRST_MOE_LAYER, NUM_LAYERS))
59
+
60
+ CAPTURE_TP = 8 # BF16 model residency on 8x B300
61
+ OUTPUT_TP = 4 # manifest reminder; encoded format remains TP4
62
+ MAX_MODEL_LEN = 4_352
63
+ MAX_NUM_BATCHED_TOKENS = 8_192
64
+ DEFAULT_KV_CACHE_BYTES = 4 << 30
65
+ DEFAULT_MAX_NUM_SEQS = 8
66
+ DEFAULT_MIN_POST_LOAD_FREE_BYTES = 48 << 30
67
+ GIB = 1 << 30
68
+ DEFAULT_DISK_RESERVE_BYTES = 256 * GIB
69
+ DEFAULT_RAMFS_RESERVE_BYTES = 64 * GIB
70
+ DEFAULT_HOST_RAM_RESERVE_BYTES = 128 * GIB
71
+ DEFAULT_MAX_CAPTURE_WINDOW_LAYERS = 8
72
+ METADATA_WRITE_ALLOWANCE_BYTES = 1 * GIB
73
+ RAM_FILESYSTEMS = {"tmpfs", "ramfs"}
74
+
75
+
76
+ def _existing_ancestor(path: Path) -> Path:
77
+ current = path.expanduser().resolve(strict=False)
78
+ while not current.exists():
79
+ if current.parent == current:
80
+ raise RuntimeError(f"no existing filesystem ancestor for {path}")
81
+ current = current.parent
82
+ return current
83
+
84
+
85
+ def filesystem_type(path: Path) -> str:
86
+ anchor = _existing_ancestor(path)
87
+ best = (0, "unknown")
88
+ for line in Path("/proc/self/mountinfo").read_text().splitlines():
89
+ fields = line.split()
90
+ try:
91
+ separator = fields.index("-")
92
+ except ValueError:
93
+ continue
94
+ mountpoint = fields[4]
95
+ for escaped, plain in (("\\040", " "), ("\\011", "\t"), ("\\134", "\\")):
96
+ mountpoint = mountpoint.replace(escaped, plain)
97
+ mount = Path(mountpoint)
98
+ try:
99
+ anchor.relative_to(mount)
100
+ except ValueError:
101
+ continue
102
+ if len(mountpoint) >= best[0]:
103
+ best = (len(mountpoint), fields[separator + 1])
104
+ return best[1]
105
+
106
+
107
+ def assert_disk_free(
108
+ path: Path, write_bytes: int, label: str, *, quiet: bool = False
109
+ ) -> dict:
110
+ """Preserve overlay headroom before every metadata/log write."""
111
+ anchor = _existing_ancestor(path)
112
+ fs_type = filesystem_type(anchor)
113
+ reserve = int(os.environ.get("B300_DISK_RESERVE_BYTES", DEFAULT_DISK_RESERVE_BYTES))
114
+ usage = shutil.disk_usage(anchor)
115
+ required = int(write_bytes) + (0 if fs_type in RAM_FILESYSTEMS else reserve)
116
+ if usage.free < required:
117
+ raise RuntimeError(
118
+ f"DISK GUARD {label}: {usage.free} bytes free on {fs_type} at {anchor}; "
119
+ f"need {write_bytes} write bytes + {required - write_bytes} reserve"
120
+ )
121
+ result = {
122
+ "target": str(path),
123
+ "filesystem": fs_type,
124
+ "free_bytes": usage.free,
125
+ "write_allowance_bytes": int(write_bytes),
126
+ "reserve_bytes": required - int(write_bytes),
127
+ }
128
+ if not quiet:
129
+ print(f"DISK GUARD PASS: {label}: {result}", flush=True)
130
+ return result
131
+
132
+
133
+ def _meminfo_bytes(key: str) -> int:
134
+ for line in Path("/proc/meminfo").read_text().splitlines():
135
+ if line.startswith(key + ":"):
136
+ return int(line.split()[1]) * 1024
137
+ raise RuntimeError(f"{key} absent from /proc/meminfo")
138
+
139
+
140
+ def _cgroup_memory_headroom() -> int | None:
141
+ root = Path("/sys/fs/cgroup")
142
+ maximum, current = root / "memory.max", root / "memory.current"
143
+ if not maximum.is_file() or not current.is_file():
144
+ return None
145
+ raw = maximum.read_text().strip()
146
+ if raw == "max":
147
+ return None
148
+ return max(0, int(raw) - int(current.read_text().strip()))
149
+
150
+
151
+ def active_swap_bytes() -> int:
152
+ lines = Path("/proc/swaps").read_text().splitlines()[1:]
153
+ return sum(int(line.split()[3]) * 1024 for line in lines if line.split())
154
+
155
+
156
+ def assert_ram_capture_target(path: Path, write_bytes: int, label: str) -> dict:
157
+ anchor = _existing_ancestor(path)
158
+ fs_type = filesystem_type(anchor)
159
+ if fs_type not in RAM_FILESYSTEMS:
160
+ raise RuntimeError(
161
+ f"RAM CAPTURE GUARD {label}: {path} resolves to {fs_type}, not tmpfs/ramfs"
162
+ )
163
+ ramfs_reserve = int(
164
+ os.environ.get("B300_RAMFS_RESERVE_BYTES", DEFAULT_RAMFS_RESERVE_BYTES)
165
+ )
166
+ host_reserve = int(
167
+ os.environ.get("B300_HOST_RAM_RESERVE_BYTES", DEFAULT_HOST_RAM_RESERVE_BYTES)
168
+ )
169
+ fs_free = shutil.disk_usage(anchor).free
170
+ mem_available = _meminfo_bytes("MemAvailable")
171
+ required_fs = int(write_bytes) + ramfs_reserve
172
+ required_host = int(write_bytes) + host_reserve
173
+ if fs_free < required_fs:
174
+ raise RuntimeError(
175
+ f"RAM CAPTURE GUARD {label}: tmpfs free={fs_free}, "
176
+ f"need payload={write_bytes} + reserve={ramfs_reserve}"
177
+ )
178
+ if mem_available < required_host:
179
+ raise RuntimeError(
180
+ f"RAM CAPTURE GUARD {label}: MemAvailable={mem_available}, "
181
+ f"need payload={write_bytes} + reserve={host_reserve}"
182
+ )
183
+ cgroup_headroom = _cgroup_memory_headroom()
184
+ if cgroup_headroom is not None and cgroup_headroom < required_host:
185
+ raise RuntimeError(
186
+ f"RAM CAPTURE GUARD {label}: cgroup headroom={cgroup_headroom}, "
187
+ f"need payload={write_bytes} + reserve={host_reserve}"
188
+ )
189
+ swap_used = active_swap_bytes()
190
+ result = {
191
+ "target": str(path),
192
+ "filesystem": fs_type,
193
+ "tmpfs_free_bytes": fs_free,
194
+ "payload_write_bytes": int(write_bytes),
195
+ "tmpfs_reserve_bytes": ramfs_reserve,
196
+ "mem_available_bytes": mem_available,
197
+ "host_reserve_bytes": host_reserve,
198
+ "cgroup_headroom_bytes": cgroup_headroom,
199
+ "active_swap_bytes": swap_used,
200
+ "swap_policy": "small capture-data windows plus host-RAM reserve; no overlay capture",
201
+ }
202
+ print(f"RAM CAPTURE GUARD PASS: {label}: {result}", flush=True)
203
+ return result
204
+
205
+
206
+ def log(message: str, logfile: str | None = None) -> None:
207
+ line = f"{time.strftime('%Y-%m-%d %H:%M:%S')} | {message}"
208
+ print(line, flush=True)
209
+ if logfile:
210
+ assert_disk_free(Path(logfile), METADATA_WRITE_ALLOWANCE_BYTES, "capture log", quiet=True)
211
+ with open(logfile, "a", encoding="utf-8") as handle:
212
+ handle.write(line + "\n")
213
+
214
+
215
+ def sha256_file(path: str | Path, chunk: int = 64 << 20) -> str:
216
+ digest = hashlib.sha256()
217
+ with open(path, "rb") as handle:
218
+ while block := handle.read(chunk):
219
+ digest.update(block)
220
+ return digest.hexdigest()
221
+
222
+
223
+ def atomic_json(path: Path, payload: dict) -> None:
224
+ encoded_size = len(json.dumps(payload, sort_keys=True).encode()) + 1
225
+ assert_disk_free(path, max(encoded_size * 2, 1 << 20), "capture JSON", quiet=True)
226
+ path.parent.mkdir(parents=True, exist_ok=True)
227
+ tmp = path.with_name(path.name + ".tmp")
228
+ with tmp.open("w", encoding="utf-8") as handle:
229
+ json.dump(payload, handle, indent=2, sort_keys=True)
230
+ handle.write("\n")
231
+ os.replace(tmp, path)
232
+
233
+
234
+ def parse_layers(spec: str) -> list[int]:
235
+ layers: list[int] = []
236
+ for part in spec.split(","):
237
+ part = part.strip()
238
+ if not part:
239
+ continue
240
+ if "-" in part:
241
+ start, end = part.split("-", 1)
242
+ layers.extend(range(int(start), int(end) + 1))
243
+ else:
244
+ layers.append(int(part))
245
+ out = sorted(set(layers))
246
+ if not out or any(layer not in MOE_LAYERS for layer in out):
247
+ raise ValueError(f"capture layers must be a nonempty subset of 3..77, got {spec!r}")
248
+ return out
249
+
250
+
251
+ def canonical_hash(payload: dict) -> str:
252
+ return hashlib.sha256(
253
+ json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
254
+ ).hexdigest()
255
+
256
+
257
+ def _tokenizer_identity(src: Path, tokenizer: object) -> dict:
258
+ files = {}
259
+ for name in (
260
+ "tokenizer.json",
261
+ "tokenizer_config.json",
262
+ "special_tokens_map.json",
263
+ "added_tokens.json",
264
+ "chat_template.jinja",
265
+ ):
266
+ path = src / name
267
+ if path.is_file():
268
+ files[name] = sha256_file(path)
269
+ return {
270
+ "class": type(tokenizer).__name__,
271
+ "vocab_size": int(getattr(tokenizer, "vocab_size", -1)),
272
+ "files_sha256": files,
273
+ }
274
+
275
+
276
+ def _waterfill_quotas(capacities: dict[str, int], target: int) -> dict[str, int]:
277
+ """Equal-token quotas with no sample repetition; redistribute short-axis slack."""
278
+ if sum(capacities.values()) < target:
279
+ raise RuntimeError(
280
+ f"owner corpus has only {sum(capacities.values())} eligible truncated tokens, "
281
+ f"below target {target}"
282
+ )
283
+ quotas = {axis: 0 for axis in capacities}
284
+ remaining_axes = list(capacities)
285
+ remaining = target
286
+ while remaining_axes:
287
+ share = math.ceil(remaining / len(remaining_axes))
288
+ short = [axis for axis in remaining_axes if capacities[axis] < share]
289
+ if not short:
290
+ base, extra = divmod(remaining, len(remaining_axes))
291
+ for index, axis in enumerate(remaining_axes):
292
+ quotas[axis] = base + int(index < extra)
293
+ remaining = 0
294
+ break
295
+ for axis in short:
296
+ quotas[axis] = capacities[axis]
297
+ remaining -= quotas[axis]
298
+ remaining_axes.remove(axis)
299
+ if remaining != 0 or sum(quotas.values()) != target:
300
+ raise AssertionError((remaining, quotas, target))
301
+ return quotas
302
+
303
+
304
+ def build_capture_plan(src: Path, corpus: Path, target_tokens: int, logfile: str) -> dict:
305
+ """Build the owner-corpus-only deterministic Luke-style multi-pass manifest."""
306
+ from transformers import AutoTokenizer
307
+
308
+ corpus_digest = sha256_file(corpus)
309
+ if corpus_digest != CORPUS_SHA256:
310
+ raise RuntimeError(f"owner corpus sha256 mismatch: {corpus_digest}")
311
+
312
+ records: list[dict] = []
313
+ counts: Counter[str] = Counter()
314
+ with corpus.open("r", encoding="utf-8") as handle:
315
+ for line_no, line in enumerate(handle):
316
+ if not line.strip():
317
+ continue
318
+ record = json.loads(line)
319
+ axis = record.get("axis")
320
+ text = record.get("text")
321
+ if axis not in AXES or not isinstance(text, str):
322
+ raise RuntimeError(f"corpus line {line_no + 1}: invalid axis/text")
323
+ records.append({"line": line_no, "axis": axis, "text": text})
324
+ counts[axis] += 1
325
+ if len(records) != CORPUS_ROWS or counts != Counter({axis: AXIS_ROWS for axis in AXES}):
326
+ raise RuntimeError(f"owner corpus row/axis mismatch: rows={len(records)} axes={dict(counts)}")
327
+
328
+ tokenizer = AutoTokenizer.from_pretrained(str(src), trust_remote_code=False)
329
+ by_axis: dict[str, list[tuple[int, int]]] = {axis: [] for axis in AXES}
330
+ skipped_short = 0
331
+ t0 = time.time()
332
+ for record in records:
333
+ length = min(len(tokenizer.encode(record["text"])), MAX_SAMPLE_TOKENS)
334
+ if length < MIN_SAMPLE_TOKENS:
335
+ skipped_short += 1
336
+ continue
337
+ by_axis[record["axis"]].append((record["line"], length))
338
+ capacities = {axis: sum(length for _, length in rows) for axis, rows in by_axis.items()}
339
+ quotas = _waterfill_quotas(capacities, target_tokens)
340
+
341
+ passes = []
342
+ selected_lines: set[int] = set()
343
+ total_tokens = 0
344
+ for axis_index, axis in enumerate(AXES):
345
+ candidates = list(by_axis[axis])
346
+ random.Random(SEED + 1_000_003 * axis_index).shuffle(candidates)
347
+ chosen = []
348
+ pass_tokens = 0
349
+ for line_no, length in candidates:
350
+ if pass_tokens >= quotas[axis]:
351
+ break
352
+ if line_no in selected_lines:
353
+ raise AssertionError(f"line selected twice: {line_no}")
354
+ selected_lines.add(line_no)
355
+ chosen.append({"line": line_no, "ntok": length})
356
+ pass_tokens += length
357
+ if pass_tokens < quotas[axis]:
358
+ raise RuntimeError(f"axis {axis} exhausted at {pass_tokens} < quota {quotas[axis]}")
359
+ passes.append(
360
+ {
361
+ "name": axis,
362
+ "axis": axis,
363
+ "quota_tokens": quotas[axis],
364
+ "tokens": pass_tokens,
365
+ "samples": chosen,
366
+ }
367
+ )
368
+ total_tokens += pass_tokens
369
+
370
+ source_identity = {
371
+ "config_sha256": sha256_file(src / "config.json"),
372
+ "index_sha256": sha256_file(src / "model.safetensors.index.json"),
373
+ }
374
+ plan = {
375
+ "schema": "glm52-b300-capture-plan-v1",
376
+ "selection_policy": "owner-corpus-axis-separated-luke-multipass-no-repeat-v1",
377
+ "selection_note": (
378
+ "Only the owner-pinned 12,228-row corpus is eligible. One natural-routing pass "
379
+ "is sealed per owner axis; rows never repeat and no stock dataset is allowed."
380
+ ),
381
+ "owner_corpus_only": True,
382
+ "calibration_baseline": True,
383
+ "corpus_sha256": corpus_digest,
384
+ "corpus_rows": len(records),
385
+ "axis_rows": dict(sorted(counts.items())),
386
+ "seed": SEED,
387
+ "target_tokens": target_tokens,
388
+ "max_sample_tokens": MAX_SAMPLE_TOKENS,
389
+ "min_sample_tokens": MIN_SAMPLE_TOKENS,
390
+ "skipped_short": skipped_short,
391
+ "passes": passes,
392
+ "total_tokens": total_tokens,
393
+ "capture_bytes": total_tokens * len(MOE_LAYERS) * (HIDDEN * 2 + TOPK),
394
+ "source": source_identity,
395
+ "tokenizer": _tokenizer_identity(src, tokenizer),
396
+ "capture_tp": CAPTURE_TP,
397
+ "output_tp": OUTPUT_TP,
398
+ "routing": {
399
+ "natural": True,
400
+ "forced_expert_activation": False,
401
+ "scoring_func": "sigmoid",
402
+ "top_k": TOPK,
403
+ "n_group": 1,
404
+ "topk_group": 1,
405
+ },
406
+ }
407
+ plan["capture_fingerprint"] = canonical_hash(plan)
408
+ log(
409
+ f"capture plan: {len(passes)} axis passes, {sum(len(p['samples']) for p in passes)} "
410
+ f"samples, {total_tokens} tokens (global target {target_tokens}), "
411
+ f"{plan['capture_bytes']/2**30:.2f} GiB for all 75 layers; "
412
+ f"capacities={capacities}, quotas={quotas}, tokenize={time.time()-t0:.1f}s",
413
+ logfile,
414
+ )
415
+ return plan
416
+
417
+
418
+ def validate_plan(plan: dict, src: Path, corpus: Path) -> None:
419
+ if plan.get("schema") != "glm52-b300-capture-plan-v1":
420
+ raise RuntimeError(f"unexpected capture plan schema: {plan.get('schema')!r}")
421
+ claimed = plan.get("capture_fingerprint")
422
+ canonical = dict(plan)
423
+ canonical.pop("capture_fingerprint", None)
424
+ actual = canonical_hash(canonical)
425
+ if claimed != actual:
426
+ raise RuntimeError(f"capture plan fingerprint mismatch: {claimed} != {actual}")
427
+ if sha256_file(corpus) != plan.get("corpus_sha256") or claimed is None:
428
+ raise RuntimeError("capture plan does not match the supplied owner corpus")
429
+ current_source = {
430
+ "config_sha256": sha256_file(src / "config.json"),
431
+ "index_sha256": sha256_file(src / "model.safetensors.index.json"),
432
+ }
433
+ if current_source != plan.get("source"):
434
+ raise RuntimeError(f"capture plan source mismatch: {current_source} != {plan.get('source')}")
435
+ if int(plan.get("capture_tp", -1)) != CAPTURE_TP or int(plan.get("output_tp", -1)) != OUTPUT_TP:
436
+ raise RuntimeError("capture/output TP in plan does not match TP8 capture / TP4 format")
437
+ if plan.get("selection_policy") != "owner-corpus-axis-separated-luke-multipass-no-repeat-v1":
438
+ raise RuntimeError("capture plan is not the owner-corpus Luke-style baseline")
439
+ if plan.get("owner_corpus_only") is not True:
440
+ raise RuntimeError("capture plan does not declare owner-corpus-only calibration")
441
+ if plan.get("calibration_baseline") is not True:
442
+ raise RuntimeError("capture plan does not declare mandatory baseline calibration")
443
+ routing = plan.get("routing", {})
444
+ expected_routing = {
445
+ "natural": True,
446
+ "forced_expert_activation": False,
447
+ "scoring_func": "sigmoid",
448
+ "top_k": TOPK,
449
+ "n_group": 1,
450
+ "topk_group": 1,
451
+ }
452
+ if routing != expected_routing:
453
+ raise RuntimeError(f"capture plan routing {routing} != mandatory {expected_routing}")
454
+ passes = plan.get("passes", [])
455
+ if not passes:
456
+ raise RuntimeError("capture plan contains no passes")
457
+ if [item.get("axis") for item in passes] != list(AXES):
458
+ raise RuntimeError("Luke-style baseline must contain one ordered pass per owner axis")
459
+ lines = [sample["line"] for item in passes for sample in item["samples"]]
460
+ if len(lines) != len(set(lines)):
461
+ raise RuntimeError("capture plan repeats corpus rows")
462
+ if sum(int(item["tokens"]) for item in passes) != int(plan["total_tokens"]):
463
+ raise RuntimeError("capture plan per-pass token sum mismatch")
464
+
465
+
466
+ def load_plan_tokens(plan: dict, src: Path, corpus: Path, logfile: str) -> list[tuple[str, list[list[int]]]]:
467
+ from transformers import AutoTokenizer
468
+
469
+ tokenizer = AutoTokenizer.from_pretrained(str(src), trust_remote_code=False)
470
+ if _tokenizer_identity(src, tokenizer) != plan.get("tokenizer"):
471
+ raise RuntimeError("tokenizer identity changed since capture plan was built")
472
+ raw_lines = corpus.read_text(encoding="utf-8").splitlines()
473
+ out = []
474
+ for pass_info in plan["passes"]:
475
+ token_lists = []
476
+ for sample in pass_info["samples"]:
477
+ line_no = int(sample["line"])
478
+ record = json.loads(raw_lines[line_no])
479
+ ids = tokenizer.encode(record["text"])[:MAX_SAMPLE_TOKENS]
480
+ if len(ids) != int(sample["ntok"]):
481
+ raise RuntimeError(
482
+ f"tokenization drift at corpus line {line_no}: {len(ids)} != {sample['ntok']}"
483
+ )
484
+ token_lists.append(ids)
485
+ tokens = sum(map(len, token_lists))
486
+ if tokens != int(pass_info["tokens"]):
487
+ raise RuntimeError(f"pass {pass_info['name']}: token sum drift {tokens}")
488
+ log(f"prepared pass {pass_info['name']}: {len(token_lists)} samples, {tokens} tokens", logfile)
489
+ out.append((str(pass_info["name"]), token_lists))
490
+ return out
491
+
492
+
493
+ class CaptureWorkerExtension:
494
+ """vLLM worker extension. Every layer is owned by exactly one TP rank."""
495
+
496
+ def _tr3_rank(self) -> int:
497
+ try:
498
+ from vllm.distributed.parallel_state import get_tensor_model_parallel_rank
499
+
500
+ return int(get_tensor_model_parallel_rank())
501
+ except Exception:
502
+ return int(getattr(self, "rank", 0))
503
+
504
+ def _tr3_world(self) -> int:
505
+ try:
506
+ from vllm.distributed.parallel_state import get_tensor_model_parallel_world_size
507
+
508
+ return int(get_tensor_model_parallel_world_size())
509
+ except Exception:
510
+ return CAPTURE_TP
511
+
512
+ def _tr3_model(self):
513
+ runner = getattr(self, "model_runner", None)
514
+ if runner is None:
515
+ raise RuntimeError("vLLM worker has no model_runner")
516
+ return runner.get_model() if hasattr(runner, "get_model") else runner.model
517
+
518
+ def tr3_cuda_memory_status(self) -> dict:
519
+ import torch
520
+
521
+ free_bytes, total_bytes = torch.cuda.mem_get_info()
522
+ return {
523
+ "rank": self._tr3_rank(),
524
+ "device": torch.cuda.get_device_name(),
525
+ "capability": list(torch.cuda.get_device_capability()),
526
+ "free_bytes": int(free_bytes),
527
+ "total_bytes": int(total_bytes),
528
+ "allocated_bytes": int(torch.cuda.memory_allocated()),
529
+ "reserved_bytes": int(torch.cuda.memory_reserved()),
530
+ }
531
+
532
+ def tr3_capture_init(
533
+ self,
534
+ out_dir: str,
535
+ verify_mode: bool,
536
+ active_layers: list[int],
537
+ capture_fingerprint: str,
538
+ expected_tokens: int,
539
+ ) -> dict:
540
+ import torch
541
+ import torch.nn.functional as torch_f
542
+
543
+ rank = self._tr3_rank()
544
+ world = self._tr3_world()
545
+ if world != CAPTURE_TP:
546
+ raise RuntimeError(f"capture world size {world} != required TP{CAPTURE_TP}")
547
+ active_layers = sorted(int(layer) for layer in active_layers)
548
+ assigned = active_layers[rank::world]
549
+ assert_ram_capture_target(
550
+ Path(out_dir),
551
+ int(expected_tokens) * len(assigned) * (HIDDEN * 2 + TOPK),
552
+ f"rank {rank} assigned capture",
553
+ )
554
+ model = self._tr3_model()
555
+
556
+ experts_mods: dict[int, torch.nn.Module] = {}
557
+ mlp_mods: dict[int, torch.nn.Module] = {}
558
+ pat = re.compile(r"(?:^|\.)layers\.(\d+)\.mlp\.experts$")
559
+ for name, module in model.named_modules():
560
+ match = pat.search(name)
561
+ if match:
562
+ experts_mods[int(match.group(1))] = module
563
+ pat_mlp = re.compile(r"(?:^|\.)layers\.(\d+)\.mlp$")
564
+ for name, module in model.named_modules():
565
+ match = pat_mlp.search(name)
566
+ if match and int(match.group(1)) in experts_mods:
567
+ mlp_mods[int(match.group(1))] = module
568
+ missing = [layer for layer in active_layers if layer not in experts_mods or layer not in mlp_mods]
569
+ if missing:
570
+ raise RuntimeError(f"MoE modules missing for capture layers {missing}")
571
+
572
+ config_obj = getattr(model, "config", None) or getattr(model, "model_config", None)
573
+ hf_config = getattr(config_obj, "hf_config", config_obj)
574
+ routing = {
575
+ "n_group": getattr(hf_config, "n_group", None),
576
+ "topk_group": getattr(hf_config, "topk_group", None),
577
+ "scoring_func": getattr(hf_config, "scoring_func", None),
578
+ "top_k": getattr(
579
+ hf_config,
580
+ "num_experts_per_tok",
581
+ getattr(hf_config, "top_k", None),
582
+ ),
583
+ }
584
+ expected_routing = {"n_group": 1, "topk_group": 1, "scoring_func": "sigmoid", "top_k": TOPK}
585
+ if routing != expected_routing:
586
+ raise RuntimeError(f"routing config {routing} != {expected_routing}")
587
+
588
+ self._tr3_gate_w = {}
589
+ self._tr3_gate_b = {}
590
+ for layer in assigned:
591
+ mlp = mlp_mods[layer]
592
+ if bool(getattr(mlp, "is_sequence_parallel", False)):
593
+ raise RuntimeError(
594
+ f"layer {layer}: sequence-parallel MoE would expose only a token shard; disable it"
595
+ )
596
+ gate = getattr(mlp, "gate", None)
597
+ if gate is None or not hasattr(gate, "weight"):
598
+ raise RuntimeError(f"layer {layer}: mlp.gate.weight absent")
599
+ weight = gate.weight
600
+ bias = getattr(gate, "e_score_correction_bias", None)
601
+ if tuple(weight.shape) != (NUM_EXPERTS, HIDDEN) or bias is None:
602
+ raise RuntimeError(f"layer {layer}: unexpected router weight/bias shape")
603
+ self._tr3_gate_w[layer] = weight.detach().to(torch.float32)
604
+ self._tr3_gate_b[layer] = bias.detach().to(torch.float32).flatten()
605
+ if tuple(self._tr3_gate_b[layer].shape) != (NUM_EXPERTS,):
606
+ raise RuntimeError(f"layer {layer}: router correction bias shape mismatch")
607
+
608
+ self._tr3_files_x = {}
609
+ self._tr3_files_i = {}
610
+ self._tr3_hash_x = {}
611
+ self._tr3_hash_i = {}
612
+ self._tr3_counts = {layer: 0 for layer in assigned}
613
+ self._tr3_routed = {layer: [0] * NUM_EXPERTS for layer in assigned}
614
+ self._tr3_verify = bool(verify_mode)
615
+ self._tr3_verify_cmp = {"checked_tokens": 0, "mismatch_tokens": 0, "kwarg_logits_layers": 0}
616
+ self._tr3_capture_fingerprint = capture_fingerprint
617
+ for layer in assigned:
618
+ layer_dir = Path(out_dir) / f"layer_{layer:03d}"
619
+ layer_dir.mkdir(parents=True, exist_ok=True)
620
+ self._tr3_files_x[layer] = open(layer_dir / "x.bin.partial", "wb", buffering=16 << 20)
621
+ self._tr3_files_i[layer] = open(layer_dir / "ids.bin.partial", "wb", buffering=1 << 20)
622
+ self._tr3_hash_x[layer] = hashlib.sha256()
623
+ self._tr3_hash_i[layer] = hashlib.sha256()
624
+
625
+ self._tr3_handles = []
626
+
627
+ def make_hook(layer: int):
628
+ gate_w = self._tr3_gate_w[layer]
629
+ gate_b = self._tr3_gate_b[layer]
630
+
631
+ def hook(module, args, kwargs):
632
+ hidden = kwargs.get("hidden_states")
633
+ if hidden is None and args:
634
+ hidden = args[0]
635
+ if hidden is None or hidden.dim() != 2 or hidden.shape[1] != HIDDEN:
636
+ raise RuntimeError(
637
+ f"layer {layer}: unexpected MoE input "
638
+ f"{None if hidden is None else tuple(hidden.shape)}"
639
+ )
640
+ rows = int(hidden.shape[0])
641
+ logits = torch_f.linear(hidden.to(torch.float32), gate_w)
642
+ scores = torch.sigmoid(logits) + gate_b
643
+ ids = torch.topk(scores, TOPK, dim=-1, sorted=False).indices
644
+
645
+ if self._tr3_verify:
646
+ router_logits = kwargs.get("router_logits")
647
+ if router_logits is None and len(args) > 1:
648
+ router_logits = args[1]
649
+ if (
650
+ router_logits is not None
651
+ and router_logits.dim() == 2
652
+ and router_logits.shape[1] == NUM_EXPERTS
653
+ and router_logits.data_ptr() != hidden.data_ptr()
654
+ ):
655
+ scores_2 = torch.sigmoid(router_logits.to(torch.float32)) + gate_b
656
+ ids_2 = torch.topk(scores_2, TOPK, dim=-1, sorted=False).indices
657
+ bad = (ids.sort(dim=-1).values != ids_2.sort(dim=-1).values).any(dim=-1)
658
+ self._tr3_verify_cmp["checked_tokens"] += rows
659
+ self._tr3_verify_cmp["mismatch_tokens"] += int(bad.sum().item())
660
+ self._tr3_verify_cmp["kwarg_logits_layers"] += 1
661
+
662
+ ids_cpu = ids.to(torch.uint8).cpu().contiguous()
663
+ hidden_cpu = hidden.detach().to(torch.bfloat16).cpu().contiguous()
664
+ x_bytes = hidden_cpu.view(torch.int16).numpy().tobytes()
665
+ id_bytes = ids_cpu.numpy().tobytes()
666
+ self._tr3_hash_x[layer].update(x_bytes)
667
+ self._tr3_hash_i[layer].update(id_bytes)
668
+ self._tr3_files_x[layer].write(x_bytes)
669
+ self._tr3_files_i[layer].write(id_bytes)
670
+ self._tr3_counts[layer] += rows
671
+
672
+ bincount = torch.bincount(ids.flatten().to(torch.int64), minlength=NUM_EXPERTS)
673
+ routed = bincount.cpu().tolist()
674
+ for expert, value in enumerate(routed):
675
+ self._tr3_routed[layer][expert] += int(value)
676
+ return None
677
+
678
+ return hook
679
+
680
+ for layer in assigned:
681
+ self._tr3_handles.append(
682
+ experts_mods[layer].register_forward_pre_hook(make_hook(layer), with_kwargs=True)
683
+ )
684
+ return {
685
+ "rank": rank,
686
+ "world": world,
687
+ "hooks": len(self._tr3_handles),
688
+ "assigned_layers": assigned,
689
+ "routing": routing,
690
+ "gate_dtype": str(mlp_mods[assigned[0]].gate.weight.dtype) if assigned else None,
691
+ }
692
+
693
+ def tr3_capture_status(self) -> dict:
694
+ return {
695
+ "rank": self._tr3_rank(),
696
+ "counts": {str(layer): count for layer, count in getattr(self, "_tr3_counts", {}).items()},
697
+ }
698
+
699
+ def tr3_capture_finalize(self) -> dict:
700
+ if not hasattr(self, "_tr3_counts"):
701
+ return {"rank": self._tr3_rank(), "layers": {}}
702
+ for handle in self._tr3_handles:
703
+ handle.remove()
704
+ layers = {}
705
+ for layer in sorted(self._tr3_counts):
706
+ x_handle = self._tr3_files_x[layer]
707
+ i_handle = self._tr3_files_i[layer]
708
+ x_handle.flush()
709
+ i_handle.flush()
710
+ x_handle.close()
711
+ i_handle.close()
712
+ layer_dir = Path(x_handle.name).parent
713
+ os.replace(layer_dir / "x.bin.partial", layer_dir / "x.bin")
714
+ os.replace(layer_dir / "ids.bin.partial", layer_dir / "ids.bin")
715
+ layers[str(layer)] = {
716
+ "tokens": self._tr3_counts[layer],
717
+ "routed": self._tr3_routed[layer],
718
+ "sha256_x": self._tr3_hash_x[layer].hexdigest(),
719
+ "sha256_ids": self._tr3_hash_i[layer].hexdigest(),
720
+ }
721
+ return {
722
+ "rank": self._tr3_rank(),
723
+ "layers": layers,
724
+ "verify_cmp": self._tr3_verify_cmp,
725
+ "capture_fingerprint": self._tr3_capture_fingerprint,
726
+ }
727
+
728
+
729
+ def make_llm(args):
730
+ here = str(Path(__file__).resolve().parent)
731
+ os.environ["PYTHONPATH"] = here + os.pathsep + os.environ.get("PYTHONPATH", "")
732
+ os.environ.setdefault("VLLM_LOGGING_LEVEL", "INFO")
733
+ os.environ.setdefault("VLLM_WORKER_MULTIPROC_METHOD", "spawn")
734
+ os.environ.setdefault("TORCH_NCCL_ASYNC_ERROR_HANDLING", "1")
735
+ os.environ.setdefault("NCCL_DEBUG", "WARN")
736
+ from vllm import LLM
737
+
738
+ return LLM(
739
+ model=str(args.src),
740
+ tensor_parallel_size=CAPTURE_TP,
741
+ dtype="bfloat16",
742
+ enforce_eager=True,
743
+ enable_prefix_caching=False,
744
+ max_model_len=MAX_MODEL_LEN,
745
+ max_num_batched_tokens=MAX_NUM_BATCHED_TOKENS,
746
+ max_num_seqs=args.max_num_seqs,
747
+ kv_cache_memory_bytes=args.kv_cache_bytes,
748
+ # The B300 TP8 post-load profile deadlocks in vLLM's custom/SYMM_MEM
749
+ # dispatch path. PyNCCL is already used for EP and is reliable here.
750
+ disable_custom_all_reduce=True,
751
+ worker_extension_cls="capture_b300.CaptureWorkerExtension",
752
+ seed=SEED,
753
+ trust_remote_code=False,
754
+ )
755
+
756
+
757
+ def _merge_status(results: list[dict], active_layers: list[int]) -> dict[int, int]:
758
+ merged: dict[int, int] = {}
759
+ for result in results:
760
+ for layer, count in result.get("counts", {}).items():
761
+ layer_i = int(layer)
762
+ if layer_i in merged:
763
+ raise RuntimeError(f"layer {layer_i} captured by multiple TP ranks")
764
+ merged[layer_i] = int(count)
765
+ if set(merged) != set(active_layers):
766
+ raise RuntimeError(f"capture status layers {sorted(merged)} != active {active_layers}")
767
+ return merged
768
+
769
+
770
+ def verify_engine_outputs(llm, logfile: str) -> None:
771
+ from vllm import SamplingParams
772
+
773
+ prompts = [
774
+ "The capital of France is",
775
+ "Under Kentucky law, a claim for negligence requires proof of duty, breach,",
776
+ "def quicksort(arr):\n if len(arr) <= 1:\n return arr\n",
777
+ ]
778
+ outputs = llm.generate(
779
+ prompts,
780
+ SamplingParams(temperature=0.0, max_tokens=32, ignore_eos=True),
781
+ )
782
+ for prompt, output in zip(prompts, outputs):
783
+ text = output.outputs[0].text
784
+ if not text.strip():
785
+ raise RuntimeError(f"empty greedy continuation for {prompt!r}")
786
+ log(f"verify greedy: {prompt!r} -> {text!r}", logfile)
787
+
788
+
789
+ def check_post_load_memory(llm, minimum_free_bytes: int, logfile: str) -> list[dict]:
790
+ statuses = sorted(llm.collective_rpc("tr3_cuda_memory_status"), key=lambda item: item["rank"])
791
+ if len(statuses) != CAPTURE_TP:
792
+ raise RuntimeError(f"expected {CAPTURE_TP} CUDA memory reports, got {len(statuses)}")
793
+ for status in statuses:
794
+ log(
795
+ f"post-load GPU rank {status['rank']}: {status['device']} capability="
796
+ f"{tuple(status['capability'])} free={status['free_bytes']/2**30:.2f} GiB / "
797
+ f"{status['total_bytes']/2**30:.2f} GiB, allocated="
798
+ f"{status['allocated_bytes']/2**30:.2f} GiB reserved="
799
+ f"{status['reserved_bytes']/2**30:.2f} GiB",
800
+ logfile,
801
+ )
802
+ if tuple(status["capability"]) != (10, 3):
803
+ raise RuntimeError(
804
+ f"rank {status['rank']}: expected B300 capability (10, 3), "
805
+ f"got {tuple(status['capability'])}"
806
+ )
807
+ if int(status["free_bytes"]) < minimum_free_bytes:
808
+ raise RuntimeError(
809
+ f"rank {status['rank']}: only {status['free_bytes']/2**30:.2f} GiB free "
810
+ f"after BF16 load; gate is {minimum_free_bytes/2**30:.2f} GiB"
811
+ )
812
+ return statuses
813
+
814
+
815
+ def run_capture(llm, passes, out_dir: Path, plan: dict, active_layers: list[int], args, logfile: str):
816
+ from vllm import SamplingParams, TokensPrompt
817
+
818
+ init_results = llm.collective_rpc(
819
+ "tr3_capture_init",
820
+ args=(
821
+ str(out_dir),
822
+ bool(args.verify_engine),
823
+ active_layers,
824
+ plan["capture_fingerprint"],
825
+ int(plan["total_tokens"]),
826
+ ),
827
+ )
828
+ assignments = {}
829
+ for result in init_results:
830
+ for layer in result.get("assigned_layers", []):
831
+ if layer in assignments:
832
+ raise RuntimeError(f"layer {layer} assigned to two ranks")
833
+ assignments[layer] = int(result["rank"])
834
+ if set(assignments) != set(active_layers) or sum(int(r.get("hooks", 0)) for r in init_results) != len(active_layers):
835
+ raise RuntimeError(f"hook assignment invalid: {init_results}")
836
+ log(f"hooks installed: {len(active_layers)} layers striped TP8; assignment={assignments}", logfile)
837
+
838
+ sampling = SamplingParams(temperature=0.0, max_tokens=1, ignore_eos=True)
839
+ cumulative = 0
840
+ pass_audit = []
841
+ for pass_index, (pass_name, token_lists) in enumerate(passes):
842
+ prompts = [TokensPrompt(prompt_token_ids=ids) for ids in token_lists]
843
+ expected = sum(map(len, token_lists))
844
+ remaining_tokens = int(plan["total_tokens"]) - cumulative
845
+ assert_ram_capture_target(
846
+ out_dir,
847
+ remaining_tokens * len(active_layers) * (HIDDEN * 2 + TOPK),
848
+ f"before pass {pass_name}",
849
+ )
850
+ started = time.time()
851
+ outputs = llm.generate(prompts, sampling)
852
+ if len(outputs) != len(prompts):
853
+ raise RuntimeError(f"pass {pass_name}: output count {len(outputs)} != {len(prompts)}")
854
+ cumulative += expected
855
+ counts = _merge_status(llm.collective_rpc("tr3_capture_status"), active_layers)
856
+ bad = {layer: value for layer, value in counts.items() if value != cumulative}
857
+ if bad:
858
+ raise RuntimeError(
859
+ f"pass {pass_name}: token accounting expected cumulative {cumulative}: {bad}"
860
+ )
861
+ elapsed = time.time() - started
862
+ pass_audit.append(
863
+ {"index": pass_index, "name": pass_name, "samples": len(prompts), "tokens": expected}
864
+ )
865
+ log(
866
+ f"pass {pass_index + 1}/{len(passes)} {pass_name}: {expected} tokens, "
867
+ f"cumulative={cumulative}, {elapsed:.1f}s",
868
+ logfile,
869
+ )
870
+
871
+ if cumulative != int(plan["total_tokens"]):
872
+ raise RuntimeError(f"captured {cumulative} tokens != plan {plan['total_tokens']}")
873
+ final_results = llm.collective_rpc("tr3_capture_finalize")
874
+ merged_layers = {}
875
+ verify = {"checked_tokens": 0, "mismatch_tokens": 0, "kwarg_logits_layers": 0}
876
+ for result in final_results:
877
+ if result.get("capture_fingerprint") not in (None, plan["capture_fingerprint"]):
878
+ raise RuntimeError("worker returned wrong capture fingerprint")
879
+ for layer, info in result.get("layers", {}).items():
880
+ if layer in merged_layers:
881
+ raise RuntimeError(f"duplicate finalized layer {layer}")
882
+ merged_layers[layer] = info
883
+ for key, value in result.get("verify_cmp", {}).items():
884
+ verify[key] = verify.get(key, 0) + int(value)
885
+ if {int(layer) for layer in merged_layers} != set(active_layers):
886
+ raise RuntimeError("finalized layer set does not match requested capture")
887
+ return merged_layers, pass_audit, assignments, verify
888
+
889
+
890
+ def write_manifests(
891
+ out_dir: Path,
892
+ plan: dict,
893
+ layer_results: dict,
894
+ pass_audit: list[dict],
895
+ assignments: dict[int, int],
896
+ verify: dict,
897
+ args,
898
+ logfile: str,
899
+ ) -> dict:
900
+ tokens = int(plan["total_tokens"])
901
+ run_uuid = str(uuid.uuid4())
902
+ for layer_s, info in layer_results.items():
903
+ layer = int(layer_s)
904
+ layer_dir = out_dir / f"layer_{layer:03d}"
905
+ x_path = layer_dir / "x.bin"
906
+ ids_path = layer_dir / "ids.bin"
907
+ if int(info["tokens"]) != tokens:
908
+ raise RuntimeError(f"layer {layer}: finalized token count mismatch")
909
+ if x_path.stat().st_size != tokens * HIDDEN * 2:
910
+ raise RuntimeError(f"layer {layer}: x payload size mismatch")
911
+ if ids_path.stat().st_size != tokens * TOPK:
912
+ raise RuntimeError(f"layer {layer}: ids payload size mismatch")
913
+ routed = [int(value) for value in info["routed"]]
914
+ if len(routed) != NUM_EXPERTS or sum(routed) != tokens * TOPK:
915
+ raise RuntimeError(f"layer {layer}: routed count audit failed")
916
+ manifest = {
917
+ "schema": "glm52-b300-layer-capture-v1",
918
+ "layer": layer,
919
+ "capture_fingerprint": plan["capture_fingerprint"],
920
+ "capture_run_uuid": run_uuid,
921
+ "capture_tp": CAPTURE_TP,
922
+ "owner_rank": assignments[layer],
923
+ "tokens": tokens,
924
+ "hidden": HIDDEN,
925
+ "x_dtype": "bfloat16",
926
+ "x_bytes": tokens * HIDDEN * 2,
927
+ "ids_topk": TOPK,
928
+ "ids_bytes": tokens * TOPK,
929
+ "sha256_x": info["sha256_x"],
930
+ "sha256_ids": info["sha256_ids"],
931
+ "routed_counts": routed,
932
+ "routed_min": min(routed),
933
+ "routed_max": max(routed),
934
+ "cold_experts_lt1024": [expert for expert, count in enumerate(routed) if count < 1024],
935
+ "finished": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
936
+ }
937
+ atomic_json(layer_dir / "layer_manifest.json", manifest)
938
+
939
+ if verify["checked_tokens"]:
940
+ fraction = 1.0 - verify["mismatch_tokens"] / verify["checked_tokens"]
941
+ if fraction < 0.99:
942
+ raise RuntimeError(f"routing recompute vs router_logits agreement only {fraction:.6f}")
943
+ run_manifest = {
944
+ "schema": "glm52-b300-capture-run-v1",
945
+ "capture_fingerprint": plan["capture_fingerprint"],
946
+ "capture_run_uuid": run_uuid,
947
+ "active_layers": sorted(int(layer) for layer in layer_results),
948
+ "tokens_per_layer": tokens,
949
+ "capture_payload_bytes": tokens * len(layer_results) * (HIDDEN * 2 + TOPK),
950
+ "pass_audit": pass_audit,
951
+ "rank_assignment": {str(layer): rank for layer, rank in sorted(assignments.items())},
952
+ "verify_routing": verify,
953
+ "capture_tp": CAPTURE_TP,
954
+ "output_tp": OUTPUT_TP,
955
+ "enforce_eager": True,
956
+ "enable_prefix_caching": False,
957
+ "max_tokens": 1,
958
+ "cpu_offload_gb": 0,
959
+ "low_memory_mode": False,
960
+ "kv_cache_memory_bytes": args.kv_cache_bytes,
961
+ "max_num_seqs": args.max_num_seqs,
962
+ "vllm": vllm_version(),
963
+ "finished": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
964
+ }
965
+ atomic_json(out_dir / "capture_run_manifest.json", run_manifest)
966
+ log(
967
+ f"CAPTURE SEALED: {len(layer_results)} layer(s), {tokens} tokens/layer, "
968
+ f"{run_manifest['capture_payload_bytes']/2**30:.2f} GiB RAM payload, "
969
+ f"fingerprint={plan['capture_fingerprint']}",
970
+ logfile,
971
+ )
972
+ return run_manifest
973
+
974
+
975
+ def vllm_version() -> str:
976
+ try:
977
+ import vllm
978
+
979
+ return str(vllm.__version__)
980
+ except Exception:
981
+ return "unknown"
982
+
983
+
984
+ def clean_active_capture(out_dir: Path, layers: list[int]) -> None:
985
+ for layer in layers:
986
+ layer_dir = out_dir / f"layer_{layer:03d}"
987
+ for name in ("x.bin", "ids.bin", "x.bin.partial", "ids.bin.partial", "layer_manifest.json"):
988
+ path = layer_dir / name
989
+ if path.exists():
990
+ path.unlink()
991
+ try:
992
+ layer_dir.rmdir()
993
+ except OSError:
994
+ pass
995
+ for name in ("capture_run_manifest.json", "capture_run_manifest.json.tmp"):
996
+ path = out_dir / name
997
+ if path.exists():
998
+ path.unlink()
999
+
1000
+
1001
+ def capture_ready(out_dir: Path, plan: dict, layers: list[int]) -> tuple[bool, str]:
1002
+ tokens = int(plan["total_tokens"])
1003
+ for layer in layers:
1004
+ layer_dir = out_dir / f"layer_{layer:03d}"
1005
+ manifest_path = layer_dir / "layer_manifest.json"
1006
+ try:
1007
+ manifest = json.loads(manifest_path.read_text())
1008
+ except Exception as exc:
1009
+ return False, f"layer {layer}: manifest unavailable ({exc})"
1010
+ if manifest.get("capture_fingerprint") != plan["capture_fingerprint"]:
1011
+ return False, f"layer {layer}: capture fingerprint mismatch"
1012
+ if int(manifest.get("tokens", -1)) != tokens:
1013
+ return False, f"layer {layer}: token count mismatch"
1014
+ x_path, ids_path = layer_dir / "x.bin", layer_dir / "ids.bin"
1015
+ if not x_path.is_file() or x_path.stat().st_size != tokens * HIDDEN * 2:
1016
+ return False, f"layer {layer}: x RAM payload absent/incomplete"
1017
+ if not ids_path.is_file() or ids_path.stat().st_size != tokens * TOPK:
1018
+ return False, f"layer {layer}: ids RAM payload absent/incomplete"
1019
+ return True, "ready"
1020
+
1021
+
1022
+ def main() -> None:
1023
+ parser = argparse.ArgumentParser(description="GLM-5.2 TP8 BF16 RAM capture for B300")
1024
+ modes = parser.add_mutually_exclusive_group(required=True)
1025
+ modes.add_argument("--plan", action="store_true", help="build deterministic capture plan; no model load")
1026
+ modes.add_argument("--capture", action="store_true", help="run TP8 BF16 natural-routing capture")
1027
+ modes.add_argument("--status", action="store_true", help="validate RAM payloads for --layers")
1028
+ parser.add_argument("--src", default="/workspace/bf16", type=Path)
1029
+ parser.add_argument(
1030
+ "--corpus",
1031
+ default="/workspace/tr3/calib/reap_recall_calib.jsonl",
1032
+ type=Path,
1033
+ )
1034
+ parser.add_argument("--plan-file", default="/workspace/tr3/capture_plan.json", type=Path)
1035
+ parser.add_argument(
1036
+ "--capture-dir", default="/dev/shm/glm52-tr3-capture", type=Path
1037
+ )
1038
+ parser.add_argument("--layers", default="3-77")
1039
+ parser.add_argument("--target-tokens", type=int, default=TARGET_TOKENS)
1040
+ parser.add_argument("--kv-cache-bytes", type=int, default=DEFAULT_KV_CACHE_BYTES)
1041
+ parser.add_argument("--max-num-seqs", type=int, default=DEFAULT_MAX_NUM_SEQS)
1042
+ parser.add_argument(
1043
+ "--min-post-load-free-bytes",
1044
+ type=int,
1045
+ default=DEFAULT_MIN_POST_LOAD_FREE_BYTES,
1046
+ )
1047
+ parser.add_argument(
1048
+ "--max-window-layers",
1049
+ type=int,
1050
+ default=DEFAULT_MAX_CAPTURE_WINDOW_LAYERS,
1051
+ help="fail closed above this capture-data window size",
1052
+ )
1053
+ parser.add_argument("--fresh", action="store_true", help="replace incomplete RAM payloads for active layers")
1054
+ parser.add_argument(
1055
+ "--reuse-existing-plan",
1056
+ action="store_true",
1057
+ help="accept a pre-staged, fingerprint-valid owner plan instead of regenerating boundaries",
1058
+ )
1059
+ parser.add_argument("--verify-engine", action="store_true", help="run three greedy checks before hooks")
1060
+ parser.add_argument("--log", default=None)
1061
+ args = parser.parse_args()
1062
+
1063
+ args.src = args.src.resolve()
1064
+ args.corpus = args.corpus.resolve()
1065
+ args.plan_file = args.plan_file.resolve()
1066
+ logfile = args.log or str(args.plan_file.with_suffix(".capture.log"))
1067
+ assert_disk_free(
1068
+ args.plan_file,
1069
+ METADATA_WRITE_ALLOWANCE_BYTES,
1070
+ "capture plan/log root",
1071
+ )
1072
+
1073
+ if args.plan:
1074
+ if args.reuse_existing_plan and args.plan_file.exists():
1075
+ existing = json.loads(args.plan_file.read_text())
1076
+ validate_plan(existing, args.src, args.corpus)
1077
+ log(
1078
+ f"reusing sealed capture plan: {args.plan_file} "
1079
+ f"({len(existing['passes'])} passes, fingerprint={existing['capture_fingerprint']})",
1080
+ logfile,
1081
+ )
1082
+ return
1083
+ plan = build_capture_plan(args.src, args.corpus, args.target_tokens, logfile)
1084
+ if args.plan_file.exists():
1085
+ existing = json.loads(args.plan_file.read_text())
1086
+ validate_plan(existing, args.src, args.corpus)
1087
+ if existing["capture_fingerprint"] != plan["capture_fingerprint"]:
1088
+ raise SystemExit(
1089
+ f"existing plan {args.plan_file} has a different fingerprint; move it explicitly "
1090
+ "before changing calibration selection"
1091
+ )
1092
+ log(f"capture plan already exists and matches: {args.plan_file}", logfile)
1093
+ else:
1094
+ atomic_json(args.plan_file, plan)
1095
+ log(f"wrote capture plan: {args.plan_file}", logfile)
1096
+ return
1097
+
1098
+ plan = json.loads(args.plan_file.read_text())
1099
+ validate_plan(plan, args.src, args.corpus)
1100
+ layers = parse_layers(args.layers)
1101
+ args.capture_dir = args.capture_dir.resolve()
1102
+
1103
+ if args.status:
1104
+ ready, reason = capture_ready(args.capture_dir, plan, layers)
1105
+ print(f"{'READY' if ready else 'NOT READY'}: {reason}")
1106
+ raise SystemExit(0 if ready else 1)
1107
+
1108
+ if not (1 <= args.max_window_layers <= len(MOE_LAYERS)):
1109
+ raise SystemExit("--max-window-layers must be in 1..75")
1110
+ if len(layers) > args.max_window_layers:
1111
+ raise SystemExit(
1112
+ f"RAM streaming requires windows of at most {args.max_window_layers} layers; "
1113
+ f"requested {len(layers)} ({args.layers}). Capture, encode with "
1114
+ "--consume-capture, then advance the window."
1115
+ )
1116
+
1117
+ capture_bytes = int(plan["total_tokens"]) * len(layers) * (HIDDEN * 2 + TOPK)
1118
+ assert_ram_capture_target(args.capture_dir, capture_bytes, "capture-data window")
1119
+
1120
+ if args.fresh:
1121
+ clean_active_capture(args.capture_dir, layers)
1122
+ else:
1123
+ ready, reason = capture_ready(args.capture_dir, plan, layers)
1124
+ if ready:
1125
+ log(f"RAM capture already ready for layers {args.layers}; skipping", logfile)
1126
+ return
1127
+ active_dirs = [args.capture_dir / f"layer_{layer:03d}" for layer in layers]
1128
+ if any(path.exists() and any(path.iterdir()) for path in active_dirs):
1129
+ raise SystemExit(f"RAM capture incomplete ({reason}); rerun with --fresh")
1130
+ args.capture_dir.mkdir(parents=True, exist_ok=True)
1131
+
1132
+ passes = load_plan_tokens(plan, args.src, args.corpus, logfile)
1133
+ log(
1134
+ f"loading BF16 source TP{CAPTURE_TP}, no CPU offload/low-memory mode; "
1135
+ f"capture layers={args.layers}, RAM dir={args.capture_dir}",
1136
+ logfile,
1137
+ )
1138
+ llm = make_llm(args)
1139
+ check_post_load_memory(llm, args.min_post_load_free_bytes, logfile)
1140
+ if args.verify_engine:
1141
+ verify_engine_outputs(llm, logfile)
1142
+ layer_results, pass_audit, assignments, verify = run_capture(
1143
+ llm, passes, args.capture_dir, plan, layers, args, logfile
1144
+ )
1145
+ write_manifests(
1146
+ args.capture_dir,
1147
+ plan,
1148
+ layer_results,
1149
+ pass_audit,
1150
+ assignments,
1151
+ verify,
1152
+ args,
1153
+ logfile,
1154
+ )
1155
+ del llm
1156
+ gc.collect()
1157
+ log("vLLM object released; process exit returns all BF16 HBM before encode", logfile)
1158
+
1159
+
1160
+ if __name__ == "__main__":
1161
+ try:
1162
+ main()
1163
+ except Exception:
1164
+ import traceback
1165
+
1166
+ traceback.print_exc()
1167
+ sys.exit(1)
calibration_encoder/convert_b300.sh ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # Real-box helper for the owner-locked GLM-5.2 BF16 -> EXL3 conversion.
3
+ # Long capture/encode/assemble invocations must be launched in the foreground
4
+ # by a Vast supervisor program; this file never daemonizes a job.
5
+ set -Eeuo pipefail
6
+
7
+ SCRIPT_DIR="${SCRIPT_DIR:-$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)}"
8
+ PYTHON="${PYTHON:-/usr/bin/python3}"
9
+ BF16_SRC="${BF16_SRC:-/workspace/bf16}"
10
+ OWNER_CORPUS="${OWNER_CORPUS:-/workspace/tr3/calib/reap_recall_calib.jsonl}"
11
+ BASE_ENCODER_PY="${BASE_ENCODER_PY:-/workspace/tr3/encode_tr3_v31.py}"
12
+ WORK_ROOT="${WORK_ROOT:-/workspace/tr3}"
13
+ WORK_DIR="${WORK_DIR:-${WORK_ROOT}/encode-work}"
14
+ OUT_DIR="${OUT_DIR:-${WORK_ROOT}/output/GLM-5.2-EXL3-TR3}"
15
+ CAPTURE_PLAN="${CAPTURE_PLAN:-${WORK_ROOT}/capture_plan.json}"
16
+ CAPTURE_DIR="${CAPTURE_DIR:-/dev/shm/glm52-tr3-capture}"
17
+ LAYERS="${LAYERS:-3-10}"
18
+ MAX_WINDOW_LAYERS="${MAX_WINDOW_LAYERS:-8}"
19
+ DISK_RESERVE_BYTES="${B300_DISK_RESERVE_BYTES:-274877906944}"
20
+ RAMFS_RESERVE_BYTES="${B300_RAMFS_RESERVE_BYTES:-68719476736}"
21
+ CUDA_HOME="${CUDA_HOME:-/usr/local/cuda-12.9}"
22
+ EXL3_B300_BUILD_DIR="${EXL3_B300_BUILD_DIR:-${WORK_ROOT}/torch_extensions/exllamav3_ext_sm100}"
23
+ MAX_JOBS="${MAX_JOBS:-32}"
24
+
25
+ export CUDA_HOME EXL3_B300_BUILD_DIR MAX_JOBS
26
+ export PATH="${CUDA_HOME}/bin:${PATH}"
27
+ export TORCH_CUDA_ARCH_LIST="10.0"
28
+ export PYTHONPATH="${SCRIPT_DIR}${PYTHONPATH:+:${PYTHONPATH}}"
29
+
30
+ die() {
31
+ echo "FATAL: $*" >&2
32
+ exit 1
33
+ }
34
+
35
+ existing_ancestor() {
36
+ local target="$1"
37
+ while [[ ! -e "$target" ]]; do
38
+ [[ "$target" != "/" ]] || break
39
+ target="$(dirname -- "$target")"
40
+ done
41
+ printf '%s\n' "$target"
42
+ }
43
+
44
+ disk_guard() {
45
+ local target="$1" write_bytes="$2" label="$3"
46
+ local anchor free required
47
+ anchor="$(existing_ancestor "$target")"
48
+ free="$(df -B1 --output=avail "$anchor" | tail -n 1 | tr -d ' ')"
49
+ required=$((write_bytes + DISK_RESERVE_BYTES))
50
+ (( free >= required )) || \
51
+ die "DISK GUARD ${label}: free=${free}, need write=${write_bytes} + reserve=${DISK_RESERVE_BYTES}"
52
+ echo "DISK GUARD PASS ${label}: target=${target} free=${free} write=${write_bytes} reserve=${DISK_RESERVE_BYTES}"
53
+ }
54
+
55
+ ram_guard() {
56
+ local target="$1" write_bytes="$2" label="$3"
57
+ local anchor fs_type free required
58
+ anchor="$(existing_ancestor "$target")"
59
+ fs_type="$(findmnt -n -o FSTYPE --target "$anchor")"
60
+ [[ "$fs_type" == "tmpfs" || "$fs_type" == "ramfs" ]] || \
61
+ die "RAM GUARD ${label}: ${target} is backed by ${fs_type}"
62
+ free="$(df -B1 --output=avail "$anchor" | tail -n 1 | tr -d ' ')"
63
+ required=$((write_bytes + RAMFS_RESERVE_BYTES))
64
+ (( free >= required )) || \
65
+ die "RAM GUARD ${label}: free=${free}, need write=${write_bytes} + reserve=${RAMFS_RESERVE_BYTES}"
66
+ echo "RAM GUARD PASS ${label}: target=${target} fs=${fs_type} free=${free}"
67
+ }
68
+
69
+ compile_check() {
70
+ disk_guard "$WORK_ROOT" 1073741824 "compile metadata"
71
+ "$PYTHON" -m py_compile \
72
+ "$SCRIPT_DIR/bootstrap_ext_b300.py" \
73
+ "$SCRIPT_DIR/capture_b300.py" \
74
+ "$SCRIPT_DIR/encode_b300.py" \
75
+ "$SCRIPT_DIR/preflight_b300.py"
76
+ }
77
+
78
+ smoke_preflight() {
79
+ compile_check
80
+ "$PYTHON" "$SCRIPT_DIR/preflight_b300.py" --smoke \
81
+ --src "$BF16_SRC" --corpus "$OWNER_CORPUS" \
82
+ --plan "$CAPTURE_PLAN" --work-root "$WORK_ROOT"
83
+ }
84
+
85
+ build_ext() {
86
+ disk_guard "$EXL3_B300_BUILD_DIR" 34359738368 "extension build"
87
+ "$PYTHON" "$SCRIPT_DIR/bootstrap_ext_b300.py" --check
88
+ }
89
+
90
+ build_plan() {
91
+ disk_guard "$CAPTURE_PLAN" 1073741824 "capture plan"
92
+ "$PYTHON" "$SCRIPT_DIR/capture_b300.py" --plan \
93
+ --src "$BF16_SRC" --corpus "$OWNER_CORPUS" --plan-file "$CAPTURE_PLAN"
94
+ }
95
+
96
+ capture_window() {
97
+ [[ -f "$CAPTURE_PLAN" ]] || die "capture plan absent: $CAPTURE_PLAN"
98
+ local payload
99
+ payload="$($PYTHON -c 'import json,sys; p=json.load(open(sys.argv[1])); parts=[x.strip() for x in sys.argv[2].split(",") if x.strip()]; layers=set(sum(([int(x)] if "-" not in x else list(range(int(x.split("-",1)[0]),int(x.split("-",1)[1])+1)) for x in parts),[])); print(int(p["total_tokens"])*len(layers)*(6144*2+8))' "$CAPTURE_PLAN" "$LAYERS")"
100
+ ram_guard "$CAPTURE_DIR" "$payload" "capture window $LAYERS"
101
+ "$PYTHON" "$SCRIPT_DIR/capture_b300.py" --capture \
102
+ --src "$BF16_SRC" --corpus "$OWNER_CORPUS" --plan-file "$CAPTURE_PLAN" \
103
+ --capture-dir "$CAPTURE_DIR" --layers "$LAYERS" \
104
+ --max-window-layers "$MAX_WINDOW_LAYERS"
105
+ }
106
+
107
+ encode_window() {
108
+ disk_guard "$WORK_DIR" 34359738368 "encode window $LAYERS"
109
+ ram_guard "$CAPTURE_DIR" 0 "encoded capture source"
110
+ "$PYTHON" "$SCRIPT_DIR/encode_b300.py" --encode --consume-capture \
111
+ --base-encoder "$BASE_ENCODER_PY" --src "$BF16_SRC" --work "$WORK_DIR" \
112
+ --capture-manifest "$CAPTURE_PLAN" --capture-dir "$CAPTURE_DIR" \
113
+ --layers "$LAYERS" --workers 8 --gpus 8
114
+ }
115
+
116
+ assemble_output() {
117
+ disk_guard "$OUT_DIR" 549755813888 "assembled checkpoint"
118
+ "$PYTHON" "$SCRIPT_DIR/encode_b300.py" --assemble \
119
+ --base-encoder "$BASE_ENCODER_PY" --src "$BF16_SRC" --work "$WORK_DIR" \
120
+ --capture-manifest "$CAPTURE_PLAN" --out "$OUT_DIR" --io-workers 8
121
+ }
122
+
123
+ case "${1:-preflight}" in
124
+ preflight) smoke_preflight ;;
125
+ ext) build_ext ;;
126
+ plan) build_plan ;;
127
+ capture-window) capture_window ;;
128
+ encode-window) encode_window ;;
129
+ assemble) assemble_output ;;
130
+ status)
131
+ disk_guard "$WORK_ROOT" 1073741824 "status"
132
+ df -h /workspace /dev/shm
133
+ ;;
134
+ *)
135
+ die "usage: $0 {preflight|ext|plan|capture-window|encode-window|assemble|status}; set LAYERS to an <=8-layer comma list"
136
+ ;;
137
+ esac
calibration_encoder/encode_b300.py ADDED
@@ -0,0 +1,1093 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Strict BF16 -> all-routed-expert EXL3 adapter for encode_tr3_v31.py.
3
+
4
+ The calibrated LDLQ/trellis implementation is imported byte-for-byte from the
5
+ owner-designated production encoder and pinned by SHA-256. This adapter changes
6
+ only source IO, RAM capture IO, all-256 tiering, resume identity, and assembly.
7
+ It never imports transformers or the exllamav3 Python package.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import hashlib
14
+ import importlib.util
15
+ import json
16
+ import os
17
+ from pathlib import Path
18
+ import shutil
19
+ import struct
20
+ import subprocess
21
+ import sys
22
+ import time
23
+ import traceback
24
+
25
+
26
+ BASE_ENCODER_SHA256 = "e9a85a47e165c8d8644354cef611efbb81dfd9ba88544ca59f0c80ee6bc75032"
27
+ CORPUS_SHA256 = "cf247acc7c5da9f0600c7d6ab3b7c2fcfc54ec30b794e3b6047559285fa44df4"
28
+ EXPECTED_SHARDS = 282
29
+ EXPECTED_LAYER_TENSORS = 256 * 3 * 4 * 4
30
+ EXPECTED_TOTAL_TR3_TENSORS = 75 * EXPECTED_LAYER_TENSORS
31
+ EXPECTED_REPLACED_WEIGHTS = 75 * 256 * 3
32
+ CAPTURE_PLAN_SCHEMA = "glm52-b300-capture-plan-v1"
33
+ DONE_SCHEMA = "glm52-b300-exl3-layer-v1"
34
+ ADAPTER_VERSION = "1"
35
+ RAM_FILESYSTEMS = {"tmpfs", "ramfs"}
36
+ GIB = 1 << 30
37
+ DEFAULT_DISK_RESERVE_BYTES = 256 * GIB
38
+ ENCODE_LAYER_ALLOWANCE_BYTES = 4 * GIB
39
+ ASSEMBLY_ALLOWANCE_BYTES = 512 * GIB
40
+ METADATA_WRITE_ALLOWANCE_BYTES = 1 * GIB
41
+
42
+ BASE = None
43
+ ACTIVE_SOURCE_HASHER = None
44
+ ACTIVE_SOURCE_TENSORS = 0
45
+ CURRENT_EXPECTED_RECIPE = None
46
+
47
+
48
+ def _existing_ancestor(path: Path) -> Path:
49
+ current = path.expanduser().resolve(strict=False)
50
+ while not current.exists():
51
+ if current.parent == current:
52
+ raise RuntimeError(f"no existing filesystem ancestor for {path}")
53
+ current = current.parent
54
+ return current
55
+
56
+
57
+ def filesystem_type(path: Path) -> str:
58
+ anchor = _existing_ancestor(path)
59
+ best = (0, "unknown")
60
+ for line in Path("/proc/self/mountinfo").read_text().splitlines():
61
+ fields = line.split()
62
+ try:
63
+ separator = fields.index("-")
64
+ except ValueError:
65
+ continue
66
+ mountpoint = fields[4]
67
+ for escaped, plain in (("\\040", " "), ("\\011", "\t"), ("\\134", "\\")):
68
+ mountpoint = mountpoint.replace(escaped, plain)
69
+ mount = Path(mountpoint)
70
+ try:
71
+ anchor.relative_to(mount)
72
+ except ValueError:
73
+ continue
74
+ if len(mountpoint) >= best[0]:
75
+ best = (len(mountpoint), fields[separator + 1])
76
+ return best[1]
77
+
78
+
79
+ def assert_disk_free(
80
+ path: Path, write_bytes: int, label: str, *, quiet: bool = False
81
+ ) -> dict:
82
+ anchor = _existing_ancestor(path)
83
+ fs_type = filesystem_type(anchor)
84
+ reserve = int(os.environ.get("B300_DISK_RESERVE_BYTES", DEFAULT_DISK_RESERVE_BYTES))
85
+ usage = shutil.disk_usage(anchor)
86
+ required = int(write_bytes) + (0 if fs_type in RAM_FILESYSTEMS else reserve)
87
+ if usage.free < required:
88
+ raise RuntimeError(
89
+ f"DISK GUARD {label}: {usage.free} bytes free on {fs_type} at {anchor}; "
90
+ f"need {write_bytes} write bytes + {required - write_bytes} reserve"
91
+ )
92
+ result = {
93
+ "target": str(path),
94
+ "filesystem": fs_type,
95
+ "free_bytes": usage.free,
96
+ "write_allowance_bytes": int(write_bytes),
97
+ "reserve_bytes": required - int(write_bytes),
98
+ }
99
+ if not quiet:
100
+ print(f"DISK GUARD PASS: {label}: {result}", flush=True)
101
+ return result
102
+
103
+
104
+ def assert_ram_capture_target(path: Path) -> dict:
105
+ anchor = _existing_ancestor(path)
106
+ fs_type = filesystem_type(anchor)
107
+ if fs_type not in RAM_FILESYSTEMS:
108
+ raise RuntimeError(
109
+ f"RAM CAPTURE GUARD: {path} resolves to {fs_type}; refusing disk-backed capture"
110
+ )
111
+ result = {"target": str(path), "filesystem": fs_type}
112
+ print(f"RAM CAPTURE GUARD PASS: {result}", flush=True)
113
+ return result
114
+
115
+
116
+ def sha256_file(path: str | Path, chunk: int = 64 << 20) -> str:
117
+ digest = hashlib.sha256()
118
+ with open(path, "rb") as handle:
119
+ while block := handle.read(chunk):
120
+ digest.update(block)
121
+ return digest.hexdigest()
122
+
123
+
124
+ def canonical_hash(payload: dict) -> str:
125
+ return hashlib.sha256(
126
+ json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
127
+ ).hexdigest()
128
+
129
+
130
+ def atomic_json(path: str | Path, payload: dict) -> None:
131
+ path = Path(path)
132
+ encoded_size = len(json.dumps(payload, sort_keys=True).encode()) + 1
133
+ assert_disk_free(path, max(encoded_size * 2, 1 << 20), "encoder JSON", quiet=True)
134
+ tmp = path.with_name(path.name + ".tmp")
135
+ with tmp.open("w", encoding="utf-8") as handle:
136
+ json.dump(payload, handle, indent=2, sort_keys=True)
137
+ handle.write("\n")
138
+ os.replace(tmp, path)
139
+
140
+
141
+ def load_base_encoder(path: Path):
142
+ global BASE
143
+ path = path.resolve()
144
+ digest = sha256_file(path)
145
+ if digest != BASE_ENCODER_SHA256:
146
+ raise RuntimeError(
147
+ f"production encoder SHA mismatch: {path} is {digest}, expected {BASE_ENCODER_SHA256}"
148
+ )
149
+ module_name = "_b300_encode_tr3_v31"
150
+ spec = importlib.util.spec_from_file_location(module_name, path)
151
+ if spec is None or spec.loader is None:
152
+ raise RuntimeError(f"cannot import production encoder from {path}")
153
+ module = importlib.util.module_from_spec(spec)
154
+ sys.modules[module_name] = module
155
+ spec.loader.exec_module(module)
156
+ BASE = module
157
+
158
+ # Format constants stay owner-pinned. Only the tier count changes.
159
+ if not (
160
+ module.HIDDEN == 6144
161
+ and module.MOE_INTER == 2048
162
+ and module.NUM_LAYERS == 78
163
+ and module.FIRST_MOE_LAYER == 3
164
+ and module.NUM_EXPERTS == 256
165
+ and module.BITS == 3
166
+ and module.TP == 4
167
+ ):
168
+ raise RuntimeError("production encoder constants no longer match the owner-pinned recipe")
169
+ module.KEEP_NVFP4 = 0
170
+ module._lazy_torch = lazy_torch_b300
171
+ module.load_expert_bf16 = load_expert_bf16_direct
172
+ module.LayerCalib = LayerCalibRAM
173
+ module.layer_done = layer_done
174
+ return module
175
+
176
+
177
+ def lazy_torch_b300():
178
+ import torch
179
+
180
+ # Never accept the wheel's prebuilt top-level extension implicitly. Every
181
+ # spawned worker enters the sm_100 bootstrap so the cached JIT artifact is
182
+ # provenance-checked and registered in this process.
183
+ from bootstrap_ext_b300 import build
184
+
185
+ ext = build()
186
+ return torch, ext
187
+
188
+
189
+ def source_identity(src: Path) -> dict:
190
+ index_path = src / "model.safetensors.index.json"
191
+ config_path = src / "config.json"
192
+ index = json.loads(index_path.read_text())
193
+ shards = sorted(set(index["weight_map"].values()))
194
+ if len(shards) != EXPECTED_SHARDS:
195
+ raise RuntimeError(f"source has {len(shards)} indexed shards, expected {EXPECTED_SHARDS}")
196
+ missing = [name for name in shards if not (src / name).is_file() or (src / name).stat().st_size == 0]
197
+ if missing:
198
+ raise RuntimeError(f"source shards missing/empty: {missing[:8]}")
199
+ shard_stats = [
200
+ {
201
+ "name": name,
202
+ "bytes": (src / name).stat().st_size,
203
+ "mtime_ns": (src / name).stat().st_mtime_ns,
204
+ }
205
+ for name in shards
206
+ ]
207
+ return {
208
+ "config_sha256": sha256_file(config_path),
209
+ "index_sha256": sha256_file(index_path),
210
+ "unique_shards": len(shards),
211
+ "shard_bytes": sum((src / name).stat().st_size for name in shards),
212
+ # Fast fail-closed resume identity. Final assembly additionally
213
+ # re-hashes every routed BF16 tensor against the digest recorded at
214
+ # encode time, so metadata alone is never the final integrity check.
215
+ "shard_stat_fingerprint": canonical_hash({"shards": shard_stats}),
216
+ }
217
+
218
+
219
+ def read_capture_plan(path: Path, src: Path) -> dict:
220
+ plan = json.loads(path.read_text())
221
+ if plan.get("schema") != CAPTURE_PLAN_SCHEMA:
222
+ raise RuntimeError(f"unexpected capture plan schema: {plan.get('schema')!r}")
223
+ canonical = dict(plan)
224
+ claimed = canonical.pop("capture_fingerprint", None)
225
+ if claimed != canonical_hash(canonical):
226
+ raise RuntimeError("capture plan fingerprint is invalid")
227
+ if plan.get("corpus_sha256") != CORPUS_SHA256:
228
+ raise RuntimeError("capture plan does not use the owner-pinned corpus")
229
+ current = source_identity(src)
230
+ planned = plan.get("source", {})
231
+ if current["config_sha256"] != planned.get("config_sha256") or current["index_sha256"] != planned.get("index_sha256"):
232
+ raise RuntimeError("capture plan and BF16 source config/index do not match")
233
+ if int(plan.get("capture_tp", -1)) != 8 or int(plan.get("output_tp", -1)) != 4:
234
+ raise RuntimeError("capture plan must declare TP8 capture and TP4 output")
235
+ if plan.get("selection_policy") != "owner-corpus-axis-separated-luke-multipass-no-repeat-v1":
236
+ raise RuntimeError("capture plan is not the owner-corpus Luke-style baseline")
237
+ if plan.get("owner_corpus_only") is not True:
238
+ raise RuntimeError("capture plan does not declare owner-corpus-only calibration")
239
+ if plan.get("calibration_baseline") is not True:
240
+ raise RuntimeError("capture plan does not declare mandatory baseline calibration")
241
+ expected_routing = {
242
+ "natural": True,
243
+ "forced_expert_activation": False,
244
+ "scoring_func": "sigmoid",
245
+ "top_k": 8,
246
+ "n_group": 1,
247
+ "topk_group": 1,
248
+ }
249
+ if plan.get("routing") != expected_routing:
250
+ raise RuntimeError("capture plan routing is not natural sigmoid top-8")
251
+ return plan
252
+
253
+
254
+ def recipe_material(args, plan: dict) -> dict:
255
+ base = BASE
256
+ assert base is not None
257
+ bootstrap_path = Path(__file__).resolve().with_name("bootstrap_ext_b300.py")
258
+ return {
259
+ "schema": "glm52-b300-exl3-recipe-v1",
260
+ "capture_fingerprint": plan["capture_fingerprint"],
261
+ "corpus_sha256": plan["corpus_sha256"],
262
+ "selection_policy": plan["selection_policy"],
263
+ "tokens_per_layer": int(plan["total_tokens"]),
264
+ "source": source_identity(Path(args.src).resolve()),
265
+ "production_encoder_sha256": BASE_ENCODER_SHA256,
266
+ "adapter_sha256": sha256_file(Path(__file__).resolve()),
267
+ "bootstrap_sha256": sha256_file(bootstrap_path),
268
+ "adapter_version": ADAPTER_VERSION,
269
+ "exllamav3": "0.0.43",
270
+ "scope": {
271
+ "layers": [3, 77],
272
+ "experts_per_layer": 256,
273
+ "projections": ["gate_proj", "up_proj", "down_proj"],
274
+ "keep_nvfp4": 0,
275
+ "tr3_experts": 256,
276
+ },
277
+ "format": {
278
+ "bits": 3,
279
+ "codebook": "mcg",
280
+ "mcg_multiplier": base.MCG_MULT,
281
+ "tp": 4,
282
+ "hidden": 6144,
283
+ "moe_intermediate": 2048,
284
+ },
285
+ "calibration_math": {
286
+ "hessian": "ldlq-calibrated",
287
+ "sigma_reg": base.SIGMA_REG,
288
+ "min_routed": int(args.min_routed),
289
+ "seed_base": base.SEED_BASE,
290
+ "out_scales": args.out_scales,
291
+ "lockstep": base.resolve_lockstep(args.lockstep),
292
+ "gss_lockstep": True,
293
+ },
294
+ }
295
+
296
+
297
+ def recipe_fingerprint(args, plan: dict) -> str:
298
+ return canonical_hash(recipe_material(args, plan))
299
+
300
+
301
+ def _expected_layer_entries(layer: int) -> dict[str, tuple[str, tuple[int, ...]]]:
302
+ base = BASE
303
+ assert base is not None
304
+ expected = {}
305
+ for expert in range(base.NUM_EXPERTS):
306
+ for proj in base.PROJS:
307
+ for rank in range(base.TP):
308
+ prefix = f"model.layers.{layer}.mlp.experts.{expert}.{proj}.rank{rank}"
309
+ if proj == "down_proj":
310
+ k, n = base.SLICE, base.HIDDEN
311
+ else:
312
+ k, n = base.HIDDEN, base.SLICE
313
+ expected[f"{prefix}.suh"] = ("F16", (k,))
314
+ expected[f"{prefix}.svh"] = ("F16", (n,))
315
+ expected[f"{prefix}.trellis"] = ("I16", (k // 16, n // 16, 48))
316
+ expected[f"{prefix}.mcg"] = ("I32", ())
317
+ return expected
318
+
319
+
320
+ def validate_layer_schema(path: Path, layer: int) -> None:
321
+ base = BASE
322
+ assert base is not None
323
+ reader = base.STReader(str(path))
324
+ expected = _expected_layer_entries(layer)
325
+ if len(reader.tensors) != EXPECTED_LAYER_TENSORS or set(reader.tensors) != set(expected):
326
+ missing = sorted(set(expected) - set(reader.tensors))[:4]
327
+ extra = sorted(set(reader.tensors) - set(expected))[:4]
328
+ raise RuntimeError(
329
+ f"layer {layer} EXL3 schema mismatch: count={len(reader.tensors)} "
330
+ f"missing={missing} extra={extra}"
331
+ )
332
+ for name, (dtype, shape) in expected.items():
333
+ actual_dtype, actual_shape, _, _ = reader.tensors[name]
334
+ if actual_dtype != dtype or tuple(actual_shape) != shape:
335
+ raise RuntimeError(
336
+ f"layer {layer} tensor {name}: {actual_dtype}{actual_shape} != {dtype}{shape}"
337
+ )
338
+
339
+
340
+ def layer_done(work: str, layer: int, expected_recipe: str | None = None) -> bool:
341
+ base = BASE
342
+ assert base is not None
343
+ expected_recipe = expected_recipe or CURRENT_EXPECTED_RECIPE
344
+ st_path_s, done_path_s = base.layer_paths(work, layer)
345
+ st_path, done_path = Path(st_path_s), Path(done_path_s)
346
+ if not st_path.is_file() or not done_path.is_file():
347
+ return False
348
+ try:
349
+ done = json.loads(done_path.read_text())
350
+ checks = (
351
+ done.get("schema") == DONE_SCHEMA,
352
+ int(done.get("layer", -1)) == layer,
353
+ int(done.get("bits", -1)) == 3,
354
+ int(done.get("tp", -1)) == 4,
355
+ done.get("keep_nvfp4") == [],
356
+ done.get("tail_tr3") == list(range(256)),
357
+ int(done.get("tensor_count", -1)) == EXPECTED_LAYER_TENSORS,
358
+ expected_recipe is None or done.get("recipe_fingerprint") == expected_recipe,
359
+ done.get("file_sha256") == sha256_file(st_path),
360
+ )
361
+ if not all(checks):
362
+ return False
363
+ validate_layer_schema(st_path, layer)
364
+ return True
365
+ except Exception:
366
+ return False
367
+
368
+
369
+ class LayerCalibRAM:
370
+ """Read-only mmap view over one sealed tmpfs capture layer."""
371
+
372
+ def __init__(self, capture_dir: str, layer: int, logfile: str | None = None):
373
+ base = BASE
374
+ assert base is not None
375
+ torch, _ = lazy_torch_b300()
376
+ import numpy as np
377
+
378
+ layer_dir = Path(capture_dir) / f"layer_{layer:03d}"
379
+ manifest = json.loads((layer_dir / "layer_manifest.json").read_text())
380
+ if manifest.get("capture_fingerprint") != getattr(self.__class__, "expected_fingerprint", None):
381
+ raise RuntimeError(f"layer {layer}: RAM capture fingerprint mismatch")
382
+ self.manifest = manifest
383
+ self.L = layer
384
+ self.tokens = int(manifest["tokens"])
385
+ if manifest.get("hidden") != base.HIDDEN or manifest.get("x_dtype") != "bfloat16":
386
+ raise RuntimeError(f"layer {layer}: capture geometry/dtype mismatch")
387
+ x_path, ids_path = layer_dir / "x.bin", layer_dir / "ids.bin"
388
+ if x_path.stat().st_size != self.tokens * base.HIDDEN * 2:
389
+ raise RuntimeError(f"layer {layer}: x RAM payload size mismatch")
390
+ if ids_path.stat().st_size != self.tokens * 8:
391
+ raise RuntimeError(f"layer {layer}: ids RAM payload size mismatch")
392
+
393
+ started = time.time()
394
+ if sha256_file(x_path) != manifest.get("sha256_x"):
395
+ raise RuntimeError(f"layer {layer}: x RAM payload SHA mismatch")
396
+ if sha256_file(ids_path) != manifest.get("sha256_ids"):
397
+ raise RuntimeError(f"layer {layer}: ids RAM payload SHA mismatch")
398
+ self._x_np = np.memmap(x_path, dtype=np.int16, mode="c", shape=(self.tokens, base.HIDDEN))
399
+ self.x = torch.from_numpy(self._x_np).view(torch.bfloat16)
400
+ self._ids_np = np.memmap(ids_path, dtype=np.uint8, mode="r", shape=(self.tokens, 8))
401
+ if self._ids_np.min() < 0 or self._ids_np.max() >= base.NUM_EXPERTS:
402
+ raise RuntimeError(f"layer {layer}: routed id out of range")
403
+ sorted_ids = np.sort(self._ids_np, axis=1)
404
+ if not (sorted_ids[:, 1:] != sorted_ids[:, :-1]).all():
405
+ raise RuntimeError(f"layer {layer}: duplicate routed expert within a token")
406
+ flat = self._ids_np.reshape(-1)
407
+ order = np.argsort(flat, kind="stable")
408
+ counts = np.bincount(flat, minlength=base.NUM_EXPERTS)
409
+ if counts.tolist() != manifest.get("routed_counts") or int(counts.sum()) != self.tokens * 8:
410
+ raise RuntimeError(f"layer {layer}: routed-count manifest mismatch")
411
+ self._starts = np.concatenate([[0], np.cumsum(counts)])
412
+ self._token_of = (order // 8).astype(np.int64)
413
+ self.routed_counts = counts.tolist()
414
+ self._H_layer_cpu = None
415
+ self._fallback_rows = None
416
+ if logfile:
417
+ base.log(
418
+ f"layer {layer}: RAM mmap verified — {self.tokens} tokens, "
419
+ f"routed min/max={counts.min()}/{counts.max()}, "
420
+ f"cold(<{base.MIN_ROUTED})={(counts < base.MIN_ROUTED).sum()}, "
421
+ f"sha+mmap={time.time()-started:.1f}s",
422
+ logfile,
423
+ )
424
+
425
+ def expert_rows(self, expert: int):
426
+ torch, _ = lazy_torch_b300()
427
+ return torch.from_numpy(
428
+ self._token_of[self._starts[expert] : self._starts[expert + 1]].copy()
429
+ )
430
+
431
+ def gather_chunks(self, rows, device, chunk=None):
432
+ torch, _ = lazy_torch_b300()
433
+ chunk = chunk or BASE.HCHUNK
434
+ for start in range(0, rows.numel(), chunk):
435
+ selection = rows[start : start + chunk]
436
+ yield torch.index_select(self.x, 0, selection).to(device).float()
437
+
438
+ def all_rows(self):
439
+ torch, _ = lazy_torch_b300()
440
+ return torch.arange(self.tokens, dtype=torch.int64)
441
+
442
+ def fallback_rows(self):
443
+ torch, _ = lazy_torch_b300()
444
+ if self._fallback_rows is None:
445
+ generator = torch.Generator().manual_seed(
446
+ BASE.SEED_BASE ^ (self.L * 2654435761 & 0x7FFFFFFF)
447
+ )
448
+ count = min(self.tokens, BASE.FALLBACK_ROWS)
449
+ self._fallback_rows = torch.randperm(self.tokens, generator=generator)[:count].sort().values
450
+ return self._fallback_rows
451
+
452
+ def layer_H(self, device):
453
+ torch, _ = lazy_torch_b300()
454
+ if self._H_layer_cpu is None:
455
+ hessian = torch.zeros(BASE.HIDDEN, BASE.HIDDEN, dtype=torch.float32, device=device)
456
+ for chunk in self.gather_chunks(self.all_rows(), device):
457
+ hessian.addmm_(chunk.T, chunk)
458
+ if not torch.isfinite(hessian).all():
459
+ raise RuntimeError(f"layer {self.L}: non-finite layer Hessian")
460
+ self._H_layer_cpu = hessian.cpu()
461
+ del hessian
462
+ return self._H_layer_cpu.to(device), self.tokens
463
+
464
+
465
+ def load_expert_bf16_direct(src, layer: int, expert: int, proj: str, device, logfile):
466
+ global ACTIVE_SOURCE_HASHER, ACTIVE_SOURCE_TENSORS
467
+ torch, _ = lazy_torch_b300()
468
+ key = src_key = BASE.expert_key(layer, expert, proj, "weight")
469
+ reader = src.reader_for(src_key, logfile)
470
+ dtype, shape, _, _ = reader.tensors[src_key]
471
+ expected_shape = (
472
+ (BASE.MOE_INTER, BASE.HIDDEN) if proj != "down_proj" else (BASE.HIDDEN, BASE.MOE_INTER)
473
+ )
474
+ if dtype != "BF16" or tuple(shape) != expected_shape:
475
+ raise RuntimeError(f"{key}: expected BF16 {expected_shape}, got {dtype} {shape}")
476
+ raw = reader.read_bytes(src_key)
477
+ if len(raw) != BASE.MOE_INTER * BASE.HIDDEN * 2:
478
+ raise RuntimeError(f"{key}: BF16 payload length mismatch")
479
+ if ACTIVE_SOURCE_HASHER is not None:
480
+ ACTIVE_SOURCE_HASHER.update(key.encode())
481
+ ACTIVE_SOURCE_HASHER.update(b"\0")
482
+ ACTIVE_SOURCE_HASHER.update(raw)
483
+ ACTIVE_SOURCE_TENSORS += 1
484
+ tensor = torch.frombuffer(bytearray(raw), dtype=torch.bfloat16).view(*shape)
485
+ return tensor.to(device)
486
+
487
+
488
+ def check_capture(capture_dir: str, layers: list[int], plan: dict) -> None:
489
+ assert_ram_capture_target(Path(capture_dir))
490
+ tokens = int(plan["total_tokens"])
491
+ for layer in layers:
492
+ layer_dir = Path(capture_dir) / f"layer_{layer:03d}"
493
+ try:
494
+ manifest = json.loads((layer_dir / "layer_manifest.json").read_text())
495
+ except Exception as exc:
496
+ raise RuntimeError(f"layer {layer}: RAM capture manifest missing ({exc})") from exc
497
+ if manifest.get("capture_fingerprint") != plan["capture_fingerprint"]:
498
+ raise RuntimeError(f"layer {layer}: RAM capture belongs to a different plan")
499
+ if int(manifest.get("tokens", -1)) != tokens:
500
+ raise RuntimeError(f"layer {layer}: RAM capture token count mismatch")
501
+ if (layer_dir / "x.bin").stat().st_size != tokens * BASE.HIDDEN * 2:
502
+ raise RuntimeError(f"layer {layer}: x RAM payload incomplete")
503
+ if (layer_dir / "ids.bin").stat().st_size != tokens * 8:
504
+ raise RuntimeError(f"layer {layer}: ids RAM payload incomplete")
505
+
506
+
507
+ def consume_capture(capture_dir: str, layer: int, logfile: str) -> None:
508
+ layer_dir = Path(capture_dir) / f"layer_{layer:03d}"
509
+ removed = 0
510
+ for name in ("x.bin", "ids.bin"):
511
+ path = layer_dir / name
512
+ if path.exists():
513
+ removed += path.stat().st_size
514
+ path.unlink()
515
+ BASE.log(f"layer {layer}: released {removed/2**30:.2f} GiB RAM capture payload", logfile)
516
+
517
+
518
+ def prune_completed_capture(args, layers: list[int]) -> None:
519
+ """Release only payloads whose matching EXL3 layer passes every done check."""
520
+ logfile = str(Path(args.work) / "logs" / "capture-prune.log")
521
+ assert_disk_free(Path(args.work), METADATA_WRITE_ALLOWANCE_BYTES, "capture prune log")
522
+ Path(logfile).parent.mkdir(parents=True, exist_ok=True)
523
+ pruned = 0
524
+ for layer in layers:
525
+ if layer_done(args.work, layer, args.expected_recipe):
526
+ consume_capture(args.capture_dir, layer, logfile)
527
+ pruned += 1
528
+ BASE.log(f"capture prune: {pruned} validated completed layer(s) inspected", logfile)
529
+
530
+
531
+ def process_layer_b300(args, src, layer: int, logfile: str, expected_recipe: str) -> None:
532
+ global ACTIVE_SOURCE_HASHER, ACTIVE_SOURCE_TENSORS
533
+ assert_disk_free(Path(args.work), ENCODE_LAYER_ALLOWANCE_BYTES, f"encode layer {layer}")
534
+ ACTIVE_SOURCE_HASHER = hashlib.sha256()
535
+ ACTIVE_SOURCE_TENSORS = 0
536
+ LayerCalibRAM.expected_fingerprint = args.capture_plan["capture_fingerprint"]
537
+ BASE.process_layer(
538
+ src,
539
+ args.work,
540
+ layer,
541
+ {"auto": None, "always": True, "never": False}[args.out_scales],
542
+ args.capture_dir,
543
+ args.min_routed,
544
+ logfile,
545
+ BASE.resolve_lockstep(args.lockstep),
546
+ )
547
+ if ACTIVE_SOURCE_TENSORS != 256 * 3:
548
+ raise RuntimeError(
549
+ f"layer {layer}: read {ACTIVE_SOURCE_TENSORS} BF16 expert tensors, expected 768"
550
+ )
551
+ st_path, done_path = BASE.layer_paths(args.work, layer)
552
+ done = json.loads(Path(done_path).read_text())
553
+ layer_manifest = json.loads(
554
+ (Path(args.capture_dir) / f"layer_{layer:03d}" / "layer_manifest.json").read_text()
555
+ )
556
+ if done.get("keep_nvfp4") != [] or done.get("tail_tr3") != list(range(256)):
557
+ raise RuntimeError(f"layer {layer}: encoder tier drifted from all-256 EXL3")
558
+ done.update(
559
+ {
560
+ "schema": DONE_SCHEMA,
561
+ "recipe_fingerprint": expected_recipe,
562
+ "recipe": recipe_material(args, args.capture_plan),
563
+ "source_expert_payload_sha256": ACTIVE_SOURCE_HASHER.hexdigest(),
564
+ "source_expert_tensor_count": ACTIVE_SOURCE_TENSORS,
565
+ "tensor_count": EXPECTED_LAYER_TENSORS,
566
+ "capture": {
567
+ "fingerprint": args.capture_plan["capture_fingerprint"],
568
+ "tokens": int(args.capture_plan["total_tokens"]),
569
+ "sha256_x": layer_manifest["sha256_x"],
570
+ "sha256_ids": layer_manifest["sha256_ids"],
571
+ },
572
+ "source_format": "BF16-direct",
573
+ "keep_nvfp4": [],
574
+ "tail_tr3": list(range(256)),
575
+ }
576
+ )
577
+ atomic_json(done_path, done)
578
+ if not layer_done(args.work, layer, expected_recipe):
579
+ raise RuntimeError(f"layer {layer}: post-write done/schema verification failed")
580
+ if args.consume_capture:
581
+ consume_capture(args.capture_dir, layer, logfile)
582
+ ACTIVE_SOURCE_HASHER = None
583
+
584
+
585
+ def worker_main(args) -> None:
586
+ logfile = str(Path(args.work) / "logs" / f"worker{args.worker_rank}.log")
587
+ assert_disk_free(
588
+ Path(args.work), ENCODE_LAYER_ALLOWANCE_BYTES, f"worker {args.worker_rank} startup"
589
+ )
590
+ Path(logfile).parent.mkdir(parents=True, exist_ok=True)
591
+ torch, _ = lazy_torch_b300()
592
+ BASE.log(
593
+ f"B300 worker {args.worker_rank} on {torch.cuda.get_device_name(0)}; "
594
+ f"CUDA_VISIBLE_DEVICES={os.environ.get('CUDA_VISIBLE_DEVICES')}",
595
+ logfile,
596
+ )
597
+ src = BASE.SourceModel(args.src)
598
+ layers = BASE.parse_layers(args.layers)
599
+ mine = layers[args.worker_rank :: args.workers]
600
+ todo = [layer for layer in mine if not layer_done(args.work, layer, args.expected_recipe)]
601
+ check_capture(args.capture_dir, todo, args.capture_plan)
602
+ for layer in todo:
603
+ process_layer_b300(args, src, layer, logfile, args.expected_recipe)
604
+ BASE.log(f"worker {args.worker_rank}: {len(todo)} layer(s) encoded", logfile)
605
+
606
+
607
+ def orchestrate_encode(args) -> None:
608
+ if not (1 <= args.workers <= args.gpus):
609
+ raise RuntimeError(f"workers must be in [1,gpus], got {args.workers}/{args.gpus}")
610
+ layers = BASE.parse_layers(args.layers)
611
+ todo = [layer for layer in layers if not layer_done(args.work, layer, args.expected_recipe)]
612
+ assert_disk_free(
613
+ Path(args.work),
614
+ len(todo) * ENCODE_LAYER_ALLOWANCE_BYTES + METADATA_WRITE_ALLOWANCE_BYTES,
615
+ f"aggregate encode work for {len(todo)} pending layers",
616
+ )
617
+ Path(args.work, "logs").mkdir(parents=True, exist_ok=True)
618
+ logfile = str(Path(args.work) / "logs" / "driver.log")
619
+ check_capture(args.capture_dir, todo, args.capture_plan)
620
+ BASE.log(
621
+ f"BF16-direct all-EXL3 encode: {len(layers)} requested, {len(todo)} pending, "
622
+ f"workers={args.workers}, GPUs={args.gpus}, bits=3, keep=0, tail=256, "
623
+ f"encoded_tp=4, recipe={args.expected_recipe}",
624
+ logfile,
625
+ )
626
+ if not todo:
627
+ BASE.log("nothing to encode", logfile)
628
+ return
629
+ processes = []
630
+ for rank in range(args.workers):
631
+ env = dict(os.environ)
632
+ env["CUDA_VISIBLE_DEVICES"] = str(rank % args.gpus)
633
+ command = [
634
+ sys.executable,
635
+ str(Path(__file__).resolve()),
636
+ "--worker-rank",
637
+ str(rank),
638
+ "--base-encoder",
639
+ args.base_encoder,
640
+ "--src",
641
+ args.src,
642
+ "--work",
643
+ args.work,
644
+ "--layers",
645
+ args.layers,
646
+ "--workers",
647
+ str(args.workers),
648
+ "--gpus",
649
+ str(args.gpus),
650
+ "--capture-dir",
651
+ args.capture_dir,
652
+ "--capture-manifest",
653
+ args.capture_manifest,
654
+ "--min-routed",
655
+ str(args.min_routed),
656
+ "--out-scales",
657
+ args.out_scales,
658
+ "--lockstep",
659
+ str(args.lockstep),
660
+ ]
661
+ if args.consume_capture:
662
+ command.append("--consume-capture")
663
+ process = subprocess.Popen(command, env=env)
664
+ processes.append(process)
665
+ BASE.log(f"spawned worker {rank} pid {process.pid} on GPU {rank % args.gpus}", logfile)
666
+ rc = 0
667
+ try:
668
+ for rank, process in enumerate(processes):
669
+ code = process.wait()
670
+ rc |= code
671
+ BASE.log(f"worker {rank} exited {code}", logfile)
672
+ except KeyboardInterrupt:
673
+ for process in processes:
674
+ process.terminate()
675
+ raise
676
+ complete = [layer for layer in layers if layer_done(args.work, layer, args.expected_recipe)]
677
+ BASE.log(f"encode pass: {len(complete)}/{len(layers)} valid layers", logfile)
678
+ if rc or len(complete) != len(layers):
679
+ raise SystemExit(1)
680
+
681
+
682
+ def modelopt_dispatch_config() -> dict:
683
+ """Compatibility metadata that selects the b12x ModelOpt interception.
684
+
685
+ There are zero NVFP4 payload tensors. The ignore list leaves only routed
686
+ experts in layers 3..77 on the intercepted path; MTP layer 78 is wholly
687
+ ignored so its BF16 experts are loaded normally.
688
+ """
689
+ return {
690
+ "config_groups": {
691
+ "group_0": {
692
+ "input_activations": {
693
+ "dynamic": False,
694
+ "num_bits": 4,
695
+ "type": "float",
696
+ "group_size": 16,
697
+ },
698
+ "weights": {
699
+ "dynamic": False,
700
+ "num_bits": 4,
701
+ "type": "float",
702
+ "group_size": 16,
703
+ },
704
+ "targets": ["Linear"],
705
+ }
706
+ },
707
+ "ignore": [
708
+ "lm_head",
709
+ "*embed_tokens*",
710
+ "model.norm*",
711
+ "*self_attn*",
712
+ "model.layers.0.mlp*",
713
+ "model.layers.1.mlp*",
714
+ "model.layers.2.mlp*",
715
+ "*shared_experts*",
716
+ "*mlp.gate*",
717
+ "model.layers.78*",
718
+ ],
719
+ "quant_algo": "NVFP4",
720
+ "producer": {"name": "b300-exl3-modelopt-dispatch-shim", "version": ADAPTER_VERSION},
721
+ "quant_method": "modelopt",
722
+ }
723
+
724
+
725
+ def audit_output(out: Path, source_keys: set[str], dropped: set[str], logfile: str) -> None:
726
+ index = json.loads((out / "model.safetensors.index.json").read_text())
727
+ weight_map = index["weight_map"]
728
+ indexed_files = set(weight_map.values())
729
+ actual_files = {path.name for path in out.glob("*.safetensors")}
730
+ if indexed_files != actual_files:
731
+ raise RuntimeError(
732
+ f"output shard/index file set mismatch: missing={indexed_files-actual_files}, "
733
+ f"stale={actual_files-indexed_files}"
734
+ )
735
+ if dropped & set(weight_map):
736
+ raise RuntimeError("BF16 routed expert weights survived output assembly")
737
+ tr3_keys = [key for key in weight_map if ".rank" in key and key.rsplit(".", 1)[-1] in {"trellis", "suh", "svh", "mcg"}]
738
+ if len(tr3_keys) != EXPECTED_TOTAL_TR3_TENSORS:
739
+ raise RuntimeError(f"output has {len(tr3_keys)} EXL3 tensors, expected {EXPECTED_TOTAL_TR3_TENSORS}")
740
+ carried_expected = source_keys - dropped
741
+ carried_actual = set(weight_map) & source_keys
742
+ if carried_actual != carried_expected:
743
+ raise RuntimeError(
744
+ f"carried source scope mismatch: missing={list(carried_expected-carried_actual)[:4]} "
745
+ f"unexpected={list(carried_actual-carried_expected)[:4]}"
746
+ )
747
+ BASE.audit_index(str(out), logfile)
748
+
749
+
750
+ def _hash_source_expert_layer(job: tuple[str, int]) -> tuple[int, str, int]:
751
+ """Recreate the exact per-layer source digest recorded during encode."""
752
+ src_path, layer = job
753
+ src = BASE.SourceModel(src_path)
754
+ digest = hashlib.sha256()
755
+ count = 0
756
+ for expert in range(BASE.NUM_EXPERTS):
757
+ for proj in BASE.PROJS:
758
+ key = BASE.expert_key(layer, expert, proj, "weight")
759
+ reader = src.reader_for(key)
760
+ dtype, shape, _, _ = reader.tensors[key]
761
+ expected_shape = (
762
+ (BASE.MOE_INTER, BASE.HIDDEN)
763
+ if proj != "down_proj"
764
+ else (BASE.HIDDEN, BASE.MOE_INTER)
765
+ )
766
+ if dtype != "BF16" or tuple(shape) != expected_shape:
767
+ raise RuntimeError(
768
+ f"{key}: final source audit expected BF16 {expected_shape}, got {dtype} {shape}"
769
+ )
770
+ raw = reader.read_bytes(key)
771
+ digest.update(key.encode())
772
+ digest.update(b"\0")
773
+ digest.update(raw)
774
+ count += 1
775
+ return layer, digest.hexdigest(), count
776
+
777
+
778
+ def verify_encoded_source_payloads(
779
+ src_path: str, dones: dict[int, dict], layers: list[int], workers: int, logfile: str
780
+ ) -> None:
781
+ """Fail if any BF16 expert payload changed after it was encoded."""
782
+ from multiprocessing import get_context
783
+
784
+ BASE.log(
785
+ "assemble: re-hashing all 57,600 routed BF16 source tensors against encode-time digests",
786
+ logfile,
787
+ )
788
+ jobs = [(src_path, layer) for layer in layers]
789
+ with get_context("fork").Pool(processes=min(workers, len(jobs))) as pool:
790
+ results = pool.map(_hash_source_expert_layer, jobs)
791
+ for layer, digest, count in results:
792
+ done = dones[layer]
793
+ if count != 256 * 3 or int(done.get("source_expert_tensor_count", -1)) != count:
794
+ raise RuntimeError(f"layer {layer}: source expert tensor-count audit failed")
795
+ if digest != done.get("source_expert_payload_sha256"):
796
+ raise RuntimeError(f"layer {layer}: BF16 expert payload changed since encode")
797
+ BASE.log("assemble: routed BF16 source payload audit PASSED", logfile)
798
+
799
+
800
+ def assemble(args) -> None:
801
+ out = Path(args.out)
802
+ assert_disk_free(out, ASSEMBLY_ALLOWANCE_BYTES, "assembled checkpoint")
803
+ if out.exists():
804
+ if not out.is_dir() or any(out.iterdir()):
805
+ raise RuntimeError(f"assembly output must be absent/empty (fail closed): {out}")
806
+ out.mkdir(parents=True, exist_ok=True)
807
+ Path(args.work, "logs").mkdir(parents=True, exist_ok=True)
808
+ logfile = str(Path(args.work) / "logs" / "assemble.log")
809
+ src = BASE.SourceModel(args.src)
810
+ layers = src.moe_layers()
811
+ dones = {}
812
+ for layer in layers:
813
+ if not layer_done(args.work, layer, args.expected_recipe):
814
+ raise RuntimeError(f"layer {layer}: missing/stale/invalid done artifact")
815
+ _, done_path = BASE.layer_paths(args.work, layer)
816
+ dones[layer] = json.loads(Path(done_path).read_text())
817
+ BASE.log(f"assemble: all {len(layers)} all-EXL3 layers validated", logfile)
818
+ verify_encoded_source_payloads(args.src, dones, layers, args.io_workers, logfile)
819
+
820
+ all_src = sorted(src.weight_map)
821
+ source_keys = set(all_src)
822
+ dropped = {
823
+ BASE.expert_key(layer, expert, proj, "weight")
824
+ for layer in layers
825
+ for expert in range(BASE.NUM_EXPERTS)
826
+ for proj in BASE.PROJS
827
+ }
828
+ if len(dropped) != EXPECTED_REPLACED_WEIGHTS or not dropped <= source_keys:
829
+ raise RuntimeError(
830
+ f"BF16 replacement scope invalid: {len(dropped)} planned, "
831
+ f"{len(dropped & source_keys)} present"
832
+ )
833
+
834
+ def carried_for_prefix(prefix: str) -> list[str]:
835
+ return [key for key in all_src if key.startswith(prefix) and key not in dropped]
836
+
837
+ shard_jobs = [("model-embed.safetensors", [("src", "model.embed_tokens.weight")])]
838
+ head = [key for key in ("lm_head.weight", "model.norm.weight") if key in src.weight_map]
839
+ shard_jobs.append(("model-head.safetensors", [("src", key) for key in head]))
840
+ for layer in range(BASE.NUM_LAYERS + 1):
841
+ items = [("src", key) for key in carried_for_prefix(f"model.layers.{layer}.")]
842
+ if layer in dones:
843
+ st_path, _ = BASE.layer_paths(args.work, layer)
844
+ reader = BASE.STReader(st_path)
845
+ if len(reader.tensors) != EXPECTED_LAYER_TENSORS:
846
+ raise RuntimeError(f"layer {layer}: unexpected work tensor count")
847
+ items += [("tr3", layer, key) for key in sorted(reader.tensors)]
848
+ shard_jobs.append((f"model-layer-{layer:03d}.safetensors", items))
849
+
850
+ accounted = {item[1] for _, items in shard_jobs for item in items if item[0] == "src"}
851
+ if accounted != source_keys - dropped:
852
+ raise RuntimeError("source tensor accounting is not bijective before assembly")
853
+
854
+ from multiprocessing import get_context
855
+
856
+ jobs = [(args.src, args.work, str(out), name, items) for name, items in shard_jobs]
857
+ with get_context("fork").Pool(processes=min(args.io_workers, len(jobs))) as pool:
858
+ results = pool.map(BASE._assemble_shard, jobs)
859
+ weight_map = {}
860
+ total_size = 0
861
+ for (name, _), (keys, nbytes) in zip(shard_jobs, results):
862
+ for key in keys:
863
+ if key in weight_map:
864
+ raise RuntimeError(f"duplicate output tensor key: {key}")
865
+ weight_map[key] = name
866
+ total_size += nbytes
867
+ BASE.log(
868
+ f"assemble: {len(shard_jobs)} shards, {total_size/2**30:.2f} GiB payload; "
869
+ "all carried tensors re-read and byte-verified",
870
+ logfile,
871
+ )
872
+
873
+ plan = args.capture_plan
874
+ per_x = {str(layer): dones[layer]["capture"]["sha256_x"] for layer in layers}
875
+ per_ids = {str(layer): dones[layer]["capture"]["sha256_ids"] for layer in layers}
876
+ if {done["recipe_fingerprint"] for done in dones.values()} != {args.expected_recipe}:
877
+ raise RuntimeError("mixed recipe fingerprints in layer done files")
878
+ config = dict(src.config)
879
+ config["quantization_config"] = modelopt_dispatch_config()
880
+ config["hybrid_tr3_tail"] = {
881
+ "producer": "encode_b300.py",
882
+ "producer_version": ADAPTER_VERSION,
883
+ "source_format": "BF16",
884
+ "source_config_sha256": plan["source"]["config_sha256"],
885
+ "source_index_sha256": plan["source"]["index_sha256"],
886
+ "format": "exl3-trellis",
887
+ "bits": 3.0,
888
+ "codebook": "mcg",
889
+ "mcg_multiplier": BASE.MCG_MULT,
890
+ "hessian": "ldlq-calibrated",
891
+ "exllamav3_version": "0.0.43",
892
+ "moe_layers": [3, 77],
893
+ "experts_per_layer": 256,
894
+ "nvfp4_keep_per_layer": 0,
895
+ "tr3_tail_per_layer": 256,
896
+ "tp": 4,
897
+ "recipe_fingerprint": args.expected_recipe,
898
+ "calibration": {
899
+ "corpus_sha256": plan["corpus_sha256"],
900
+ "corpus_rows": plan["corpus_rows"],
901
+ "axis_rows": plan["axis_rows"],
902
+ "selection_policy": plan["selection_policy"],
903
+ "capture_fingerprint": plan["capture_fingerprint"],
904
+ "passes": [
905
+ {
906
+ "name": item["name"],
907
+ "axis": item.get("axis"),
908
+ "samples": len(item["samples"]),
909
+ "tokens": item["tokens"],
910
+ }
911
+ for item in plan["passes"]
912
+ ],
913
+ "tokens_per_layer": plan["total_tokens"],
914
+ "min_routed_floor": args.min_routed,
915
+ "sigma_reg": BASE.SIGMA_REG,
916
+ "layer_h_fallback_experts_total": sum(
917
+ len(done["experts_layer_h_fallback"]) for done in dones.values()
918
+ ),
919
+ "q_fallback_slices_total": sum(len(done["q_fallback_slices"]) for done in dones.values()),
920
+ "per_layer_x_sha256": per_x,
921
+ "per_layer_ids_sha256": per_ids,
922
+ },
923
+ "scope": {
924
+ "quantized": "routed MoE expert gate/up/down projections, all 256 experts, layers 3..77",
925
+ "bf16_byte_exact": [
926
+ "attention",
927
+ "dense MLPs layers 0..2",
928
+ "shared experts",
929
+ "router/gates",
930
+ "MTP layer 78",
931
+ "embeddings",
932
+ "lm_head",
933
+ ],
934
+ },
935
+ "slicing": {
936
+ "gate_proj": "TP4 N-slice: rank r owns output rows [512r,512r+512)",
937
+ "up_proj": "TP4 N-slice: rank r owns output rows [512r,512r+512)",
938
+ "down_proj": "TP4 K-slice: rank r owns input columns [512r,512r+512)",
939
+ },
940
+ "tensor_schema": "model.layers.{L}.mlp.experts.{E}.{proj}.rank{r}.{trellis|suh|svh|mcg}",
941
+ "tier_bitmap": "tier_bitmap.json",
942
+ "modelopt_dispatch_note": (
943
+ "quantization_config selects the b12x ModelOpt interception only; this artifact "
944
+ "contains zero NVFP4 expert payloads. Layer 78 is ignored and remains BF16."
945
+ ),
946
+ }
947
+ atomic_json(out / "config.json", config)
948
+ atomic_json(
949
+ out / "model.safetensors.index.json",
950
+ {"metadata": {"total_size": total_size}, "weight_map": weight_map},
951
+ )
952
+ tier_bitmap = {
953
+ str(layer): {
954
+ "keep_nvfp4": [],
955
+ "tail_tr3": list(range(256)),
956
+ "expert_rel_rt_mse": dones[layer]["expert_rel_rt_mse"],
957
+ }
958
+ for layer in layers
959
+ }
960
+ atomic_json(out / "tier_bitmap.json", tier_bitmap)
961
+ atomic_json(out / "calibration_manifest.json", plan)
962
+
963
+ generated_names = {
964
+ "calibration_manifest.json",
965
+ "tier_bitmap.json",
966
+ "model.safetensors.index.json",
967
+ "config.json",
968
+ "MANIFEST.sha256",
969
+ }
970
+ for filename in BASE.aux_files(args.src):
971
+ if filename in generated_names:
972
+ raise RuntimeError(f"source auxiliary name collides with generated output: {filename}")
973
+ source = Path(args.src) / filename
974
+ destination = out / filename
975
+ with source.open("rb") as src_handle, destination.open("wb") as dst_handle:
976
+ while block := src_handle.read(BASE.CHUNK):
977
+ dst_handle.write(block)
978
+ if sha256_file(source) != sha256_file(destination):
979
+ raise RuntimeError(f"auxiliary byte-copy mismatch: {filename}")
980
+
981
+ audit_output(out, source_keys, dropped, logfile)
982
+ names = sorted(path.name for path in out.iterdir() if path.is_file() and path.name != "MANIFEST.sha256")
983
+ with (out / "MANIFEST.sha256").open("w", encoding="utf-8") as handle:
984
+ for name in names:
985
+ handle.write(f"{sha256_file(out / name)} {name}\n")
986
+ BASE.log(
987
+ f"assemble COMPLETE: {out}, {len(names)} files + MANIFEST, "
988
+ f"replaced={len(dropped)} BF16 weights, EXL3 tensors={EXPECTED_TOTAL_TR3_TENSORS}",
989
+ logfile,
990
+ )
991
+
992
+
993
+ def configure_args(args) -> None:
994
+ global CURRENT_EXPECTED_RECIPE
995
+ args.base_encoder = str(Path(args.base_encoder).resolve())
996
+ args.src = str(Path(args.src).resolve())
997
+ args.work = str(Path(args.work).resolve())
998
+ args.capture_manifest = str(Path(args.capture_manifest).resolve())
999
+ if args.capture_dir:
1000
+ args.capture_dir = str(Path(args.capture_dir).resolve())
1001
+ load_base_encoder(Path(args.base_encoder))
1002
+ args.capture_plan = read_capture_plan(Path(args.capture_manifest), Path(args.src))
1003
+ args.expected_recipe = recipe_fingerprint(args, args.capture_plan)
1004
+ CURRENT_EXPECTED_RECIPE = args.expected_recipe
1005
+
1006
+
1007
+ def main() -> None:
1008
+ parser = argparse.ArgumentParser(description="GLM-5.2 BF16 -> all-EXL3 B300 encoder")
1009
+ actions = parser.add_mutually_exclusive_group()
1010
+ actions.add_argument("--encode", action="store_true")
1011
+ actions.add_argument("--assemble", action="store_true")
1012
+ actions.add_argument("--smoke", action="store_true")
1013
+ actions.add_argument("--oracle", action="store_true")
1014
+ actions.add_argument("--pending", action="store_true", help="print comma-separated invalid/pending layers")
1015
+ actions.add_argument(
1016
+ "--prune-completed-capture",
1017
+ action="store_true",
1018
+ help="delete tmpfs x/ids only for layers with fully validated done artifacts",
1019
+ )
1020
+ parser.add_argument("--base-encoder", default="/workspace/tr3/encode_tr3_v31.py")
1021
+ parser.add_argument("--src", default="/workspace/bf16")
1022
+ parser.add_argument("--work", default="/workspace/tr3/encode-work")
1023
+ parser.add_argument("--out", default="")
1024
+ parser.add_argument("--capture-dir", default="/dev/shm/glm52-tr3-capture")
1025
+ parser.add_argument("--capture-manifest", default="/workspace/tr3/capture_plan.json")
1026
+ parser.add_argument("--layers", default="3-77")
1027
+ parser.add_argument("--workers", type=int, default=8)
1028
+ parser.add_argument("--gpus", type=int, default=8)
1029
+ parser.add_argument("--io-workers", type=int, default=8)
1030
+ parser.add_argument("--min-routed", type=int, default=1024)
1031
+ parser.add_argument("--out-scales", choices=["auto", "always", "never"], default="auto")
1032
+ parser.add_argument("--lockstep", default="auto")
1033
+ parser.add_argument("--consume-capture", action="store_true")
1034
+ parser.add_argument("--oracle-experts", default="0,1")
1035
+ parser.add_argument("--oracle-log", default="/tmp/b300_oracle.log")
1036
+ parser.add_argument("--worker-rank", type=int, default=None, help=argparse.SUPPRESS)
1037
+ args = parser.parse_args()
1038
+ configure_args(args)
1039
+ assert_disk_free(Path(args.work), METADATA_WRITE_ALLOWANCE_BYTES, "encoder startup")
1040
+
1041
+ if args.worker_rank is not None:
1042
+ worker_main(args)
1043
+ return
1044
+ layers = BASE.parse_layers(args.layers)
1045
+ if args.pending:
1046
+ pending = [layer for layer in layers if not layer_done(args.work, layer, args.expected_recipe)]
1047
+ print(",".join(map(str, pending)) if pending else "NONE")
1048
+ return
1049
+ if args.prune_completed_capture:
1050
+ if not args.capture_dir:
1051
+ raise RuntimeError("--prune-completed-capture requires --capture-dir")
1052
+ prune_completed_capture(args, layers)
1053
+ return
1054
+ if args.smoke:
1055
+ smoke_args = argparse.Namespace()
1056
+ BASE.smoke(smoke_args)
1057
+ return
1058
+ if args.oracle:
1059
+ if not args.capture_dir:
1060
+ raise RuntimeError("--oracle requires --capture-dir")
1061
+ LayerCalibRAM.expected_fingerprint = args.capture_plan["capture_fingerprint"]
1062
+ assert_disk_free(Path(args.oracle_log), METADATA_WRITE_ALLOWANCE_BYTES, "oracle log")
1063
+ oracle_args = argparse.Namespace(
1064
+ src=args.src,
1065
+ layers=args.layers,
1066
+ capture_dir=args.capture_dir,
1067
+ lockstep=args.lockstep,
1068
+ out_scales=args.out_scales,
1069
+ oracle_experts=args.oracle_experts,
1070
+ oracle_log=args.oracle_log,
1071
+ min_routed=args.min_routed,
1072
+ )
1073
+ BASE.check_capture = lambda capture_dir, requested: check_capture(
1074
+ capture_dir, requested, args.capture_plan
1075
+ )
1076
+ BASE.oracle(oracle_args)
1077
+ return
1078
+ if args.assemble:
1079
+ if not args.out:
1080
+ raise RuntimeError("--assemble requires --out")
1081
+ assemble(args)
1082
+ return
1083
+ if not args.capture_dir:
1084
+ raise RuntimeError("--encode requires --capture-dir")
1085
+ orchestrate_encode(args)
1086
+
1087
+
1088
+ if __name__ == "__main__":
1089
+ try:
1090
+ main()
1091
+ except Exception:
1092
+ traceback.print_exc()
1093
+ sys.exit(1)
calibration_encoder/encode_tr3_v31.py ADDED
The diff for this file is too large to render. See raw diff
 
calibration_encoder/preflight_b300.py ADDED
@@ -0,0 +1,631 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Measured-host preflight for the GLM-5.2 BF16 -> EXL3 B300 conversion.
3
+
4
+ ``--smoke`` never hides a contradiction, but it treats an absent/in-flight BF16
5
+ download and a not-yet-created capture plan as PENDING so every independent box
6
+ check still runs.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ from collections import Counter
13
+ import hashlib
14
+ import json
15
+ import os
16
+ from pathlib import Path
17
+ import platform
18
+ import re
19
+ import shutil
20
+ import struct
21
+ import subprocess
22
+ import sys
23
+
24
+
25
+ CORPUS_SHA256 = "cf247acc7c5da9f0600c7d6ab3b7c2fcfc54ec30b794e3b6047559285fa44df4"
26
+ CORPUS_ROWS = 12_228
27
+ AXIS_COUNTS = {
28
+ "axis1_general": 3_057,
29
+ "axis2_legal": 3_057,
30
+ "axis3_code_agentic": 3_057,
31
+ "axis4_reasoning_termination": 3_057,
32
+ }
33
+ AXES = tuple(AXIS_COUNTS)
34
+ EXPECTED_SHARDS = 282
35
+ FIRST_MOE_LAYER = 3
36
+ NUM_LAYERS = 78
37
+ NUM_EXPERTS = 256
38
+ HIDDEN = 6144
39
+ MOE_INTER = 2048
40
+ PROJS = ("gate_proj", "up_proj", "down_proj")
41
+
42
+ EXPECTED_GPUS = 8
43
+ EXPECTED_GPU_MIB = 275_040
44
+ EXPECTED_GPU_NAME = "NVIDIA B300 SXM6 AC"
45
+ EXPECTED_NVLINK_LINES = 144
46
+ OWNER_BUILD_ARCH = "10.0"
47
+ GIB = 1 << 30
48
+ DEFAULT_DISK_RESERVE_BYTES = 256 * GIB
49
+ SOURCE_EXPECTED_BYTES = 1_507_000_000_000
50
+ ENCODE_WORK_ALLOWANCE_BYTES = 320_000_000_000
51
+ ASSEMBLED_OUTPUT_ALLOWANCE_BYTES = 400_000_000_000
52
+ PREFLIGHT_WRITE_ALLOWANCE_BYTES = 1 * GIB
53
+ NOMINAL_CAPTURE_BYTES = 1_048_576 * 75 * (HIDDEN * 2 + 8)
54
+
55
+
56
+ class Report:
57
+ def __init__(self) -> None:
58
+ self.items: list[dict] = []
59
+
60
+ def add(self, status: str, check: str, evidence) -> None:
61
+ item = {"status": status, "check": check, "evidence": evidence}
62
+ self.items.append(item)
63
+ rendered = evidence if isinstance(evidence, str) else json.dumps(evidence, sort_keys=True)
64
+ print(f"{status:7s} {check}: {rendered}", flush=True)
65
+
66
+ def passed(self, check: str, evidence) -> None:
67
+ self.add("PASS", check, evidence)
68
+
69
+ def pending(self, check: str, evidence) -> None:
70
+ self.add("PENDING", check, evidence)
71
+
72
+ def failed(self, check: str, evidence) -> None:
73
+ self.add("FAIL", check, evidence)
74
+
75
+ def counts(self) -> Counter[str]:
76
+ return Counter(item["status"] for item in self.items)
77
+
78
+
79
+ def _existing_ancestor(path: Path) -> Path:
80
+ current = path.expanduser().resolve(strict=False)
81
+ while not current.exists():
82
+ if current.parent == current:
83
+ raise RuntimeError(f"no existing filesystem ancestor for {path}")
84
+ current = current.parent
85
+ return current
86
+
87
+
88
+ def assert_disk_free(path: Path, write_bytes: int = PREFLIGHT_WRITE_ALLOWANCE_BYTES) -> dict:
89
+ """The preflight itself writes nothing, but it must exercise the disk gate."""
90
+ anchor = _existing_ancestor(path)
91
+ reserve = int(os.environ.get("B300_DISK_RESERVE_BYTES", DEFAULT_DISK_RESERVE_BYTES))
92
+ usage = shutil.disk_usage(anchor)
93
+ required = int(write_bytes) + reserve
94
+ if usage.free < required:
95
+ raise AssertionError(
96
+ f"{usage.free} bytes free at {anchor}; need {write_bytes} + {reserve} reserve"
97
+ )
98
+ return {
99
+ "target": str(path),
100
+ "anchor": str(anchor),
101
+ "total_bytes": usage.total,
102
+ "free_bytes": usage.free,
103
+ "write_allowance_bytes": int(write_bytes),
104
+ "reserve_bytes": reserve,
105
+ }
106
+
107
+
108
+ def run(command: list[str], timeout: int = 30) -> str:
109
+ result = subprocess.run(
110
+ command,
111
+ check=False,
112
+ text=True,
113
+ stdout=subprocess.PIPE,
114
+ stderr=subprocess.STDOUT,
115
+ timeout=timeout,
116
+ )
117
+ if result.returncode:
118
+ raise AssertionError(
119
+ f"command {command!r} exited {result.returncode}: {result.stdout[-2000:]}"
120
+ )
121
+ return result.stdout
122
+
123
+
124
+ def sha256_file(path: Path, chunk: int = 64 << 20) -> str:
125
+ digest = hashlib.sha256()
126
+ with path.open("rb") as handle:
127
+ while block := handle.read(chunk):
128
+ digest.update(block)
129
+ return digest.hexdigest()
130
+
131
+
132
+ def read_safetensors_header(path: Path) -> dict:
133
+ size = path.stat().st_size
134
+ if size < 16:
135
+ raise AssertionError(f"zero/truncated shard: {path} ({size} bytes)")
136
+ with path.open("rb") as handle:
137
+ raw = handle.read(8)
138
+ if len(raw) != 8:
139
+ raise AssertionError(f"short safetensors length header: {path}")
140
+ header_len = struct.unpack("<Q", raw)[0]
141
+ if not (2 <= header_len <= 512 << 20):
142
+ raise AssertionError(f"implausible safetensors header length {header_len}: {path}")
143
+ payload = handle.read(header_len)
144
+ if len(payload) != header_len:
145
+ raise AssertionError(f"short safetensors JSON header: {path}")
146
+ header = json.loads(payload)
147
+ max_end = max(
148
+ (entry["data_offsets"][1] for name, entry in header.items() if name != "__metadata__"),
149
+ default=0,
150
+ )
151
+ if size < 8 + header_len + max_end:
152
+ raise AssertionError(f"incomplete shard {path}: {size} < {8 + header_len + max_end}")
153
+ return header
154
+
155
+
156
+ def expert_key(layer: int, expert: int, proj: str) -> str:
157
+ return f"model.layers.{layer}.mlp.experts.{expert}.{proj}.weight"
158
+
159
+
160
+ def validate_config(config: dict) -> None:
161
+ expected_cfg = {
162
+ "num_hidden_layers": NUM_LAYERS,
163
+ "first_k_dense_replace": FIRST_MOE_LAYER,
164
+ "n_routed_experts": NUM_EXPERTS,
165
+ "hidden_size": HIDDEN,
166
+ "moe_intermediate_size": MOE_INTER,
167
+ "n_group": 1,
168
+ "topk_group": 1,
169
+ "scoring_func": "sigmoid",
170
+ }
171
+ for key, expected in expected_cfg.items():
172
+ if config.get(key) != expected:
173
+ raise AssertionError(f"config {key}={config.get(key)!r}; expected {expected!r}")
174
+ topk = config.get("num_experts_per_tok", config.get("top_k"))
175
+ if topk != 8:
176
+ raise AssertionError(f"config natural routing top-k is {topk!r}; expected 8")
177
+ if config.get("quantization_config"):
178
+ raise AssertionError("source has quantization_config; expected straight BF16")
179
+
180
+
181
+ def validate_source(src: Path) -> dict:
182
+ config_path = src / "config.json"
183
+ index_path = src / "model.safetensors.index.json"
184
+ if not config_path.is_file() or not index_path.is_file():
185
+ raise AssertionError(f"BF16 source lacks config/index: {src}")
186
+ config = json.loads(config_path.read_text())
187
+ validate_config(config)
188
+ index = json.loads(index_path.read_text())
189
+ weight_map = index.get("weight_map")
190
+ if not isinstance(weight_map, dict) or not weight_map:
191
+ raise AssertionError("invalid or empty safetensors weight_map")
192
+ shard_names = sorted(set(weight_map.values()))
193
+ if len(shard_names) != EXPECTED_SHARDS:
194
+ raise AssertionError(
195
+ f"source index references {len(shard_names)} unique shards; expected {EXPECTED_SHARDS}"
196
+ )
197
+
198
+ headers: dict[str, dict] = {}
199
+ shard_bytes = 0
200
+ for name in shard_names:
201
+ path = src / name
202
+ if not path.is_file():
203
+ raise AssertionError(f"missing source shard: {path}")
204
+ headers[name] = read_safetensors_header(path)
205
+ shard_bytes += path.stat().st_size
206
+ for tensor_name, shard_name in weight_map.items():
207
+ if tensor_name not in headers[shard_name]:
208
+ raise AssertionError(f"index maps absent tensor {tensor_name} -> {shard_name}")
209
+
210
+ routed_count = 0
211
+ routed_bytes = 0
212
+ for layer in range(FIRST_MOE_LAYER, NUM_LAYERS):
213
+ for expert in range(NUM_EXPERTS):
214
+ for proj in PROJS:
215
+ key = expert_key(layer, expert, proj)
216
+ shard_name = weight_map.get(key)
217
+ if shard_name is None:
218
+ raise AssertionError(f"missing BF16 routed expert tensor: {key}")
219
+ entry = headers[shard_name][key]
220
+ expected_shape = (
221
+ [MOE_INTER, HIDDEN] if proj != "down_proj" else [HIDDEN, MOE_INTER]
222
+ )
223
+ if entry["dtype"] != "BF16" or entry["shape"] != expected_shape:
224
+ raise AssertionError(
225
+ f"{key}: {entry['dtype']} {entry['shape']} != BF16 {expected_shape}"
226
+ )
227
+ start, end = entry["data_offsets"]
228
+ if end - start != MOE_INTER * HIDDEN * 2:
229
+ raise AssertionError(f"{key}: BF16 payload size mismatch")
230
+ routed_count += 1
231
+ routed_bytes += end - start
232
+ for forbidden in (f"{key}_scale", f"{key}_scale_2"):
233
+ if forbidden in weight_map:
234
+ raise AssertionError(f"quantized side tensor found: {forbidden}")
235
+
236
+ expected_routed = (NUM_LAYERS - FIRST_MOE_LAYER) * NUM_EXPERTS * len(PROJS)
237
+ if routed_count != expected_routed:
238
+ raise AssertionError(f"routed tensor count {routed_count} != {expected_routed}")
239
+ keys = tuple(weight_map)
240
+ if not any(key.startswith("model.layers.78.") for key in keys):
241
+ raise AssertionError("MTP layer 78 tensors absent")
242
+ for layer in range(FIRST_MOE_LAYER, NUM_LAYERS):
243
+ if not any(key.startswith(f"model.layers.{layer}.mlp.shared_experts.") for key in keys):
244
+ raise AssertionError(f"layer {layer}: shared expert tensors absent")
245
+ if f"model.layers.{layer}.mlp.gate.weight" not in weight_map:
246
+ raise AssertionError(f"layer {layer}: router/gate weight absent")
247
+ return {
248
+ "config_sha256": sha256_file(config_path),
249
+ "index_sha256": sha256_file(index_path),
250
+ "unique_shards": len(shard_names),
251
+ "shard_bytes": shard_bytes,
252
+ "indexed_tensors": len(weight_map),
253
+ "routed_bf16_tensors": routed_count,
254
+ "routed_bf16_bytes": routed_bytes,
255
+ }
256
+
257
+
258
+ def inspect_source_progress(src: Path, *, smoke: bool = False) -> tuple[str, dict]:
259
+ config_path = src / "config.json"
260
+ index_path = src / "model.safetensors.index.json"
261
+ present_files = list(src.glob("*.safetensors")) if src.is_dir() else []
262
+ present_bytes = sum(path.stat().st_size for path in present_files)
263
+ if not config_path.is_file() or not index_path.is_file():
264
+ return "PENDING", {
265
+ "path": str(src),
266
+ "directory_exists": src.is_dir(),
267
+ "config_present": config_path.is_file(),
268
+ "index_present": index_path.is_file(),
269
+ "present_safetensors": len(present_files),
270
+ "present_safetensors_bytes": present_bytes,
271
+ "strict_checks_skipped": "config/index not both available",
272
+ }
273
+ config = json.loads(config_path.read_text())
274
+ validate_config(config)
275
+ index = json.loads(index_path.read_text())
276
+ weight_map = index.get("weight_map")
277
+ if not isinstance(weight_map, dict) or not weight_map:
278
+ raise AssertionError("invalid or empty safetensors weight_map")
279
+ names = sorted(set(weight_map.values()))
280
+ if len(names) != EXPECTED_SHARDS:
281
+ raise AssertionError(f"index has {len(names)} shards; expected {EXPECTED_SHARDS}")
282
+ missing = [name for name in names if not (src / name).is_file()]
283
+ zero = [name for name in names if (src / name).is_file() and (src / name).stat().st_size == 0]
284
+ if missing or zero:
285
+ complete = [name for name in names if name not in set(missing) and name not in set(zero)]
286
+ unreadable: list[dict[str, str]] = []
287
+ for name in complete:
288
+ try:
289
+ read_safetensors_header(src / name)
290
+ except Exception as exc:
291
+ unreadable.append({"name": name, "error": str(exc)})
292
+ if unreadable and not (smoke and present_bytes < SOURCE_EXPECTED_BYTES):
293
+ raise AssertionError(f"present source shard header invalid: {unreadable[:3]}")
294
+ return "PENDING", {
295
+ "path": str(src),
296
+ "indexed_shards": len(names),
297
+ "complete_shards": len(complete),
298
+ "missing_shards": len(missing),
299
+ "zero_shards": len(zero),
300
+ "unreadable_present_shards": unreadable[:8],
301
+ "complete_bytes": sum((src / name).stat().st_size for name in complete),
302
+ "strict_checks_skipped": "download incomplete",
303
+ }
304
+ try:
305
+ return "PASS", validate_source(src)
306
+ except Exception as exc:
307
+ if smoke and present_bytes < SOURCE_EXPECTED_BYTES:
308
+ return "PENDING", {
309
+ "path": str(src),
310
+ "indexed_shards": len(names),
311
+ "present_safetensors_bytes": present_bytes,
312
+ "expected_source_bytes": SOURCE_EXPECTED_BYTES,
313
+ "strict_checks_skipped": "download appears in flight",
314
+ "deferred_validation_error": str(exc),
315
+ }
316
+ raise
317
+
318
+
319
+ def validate_corpus(path: Path) -> dict:
320
+ if not path.is_file():
321
+ raise AssertionError(f"owner corpus absent: {path}")
322
+ digest = sha256_file(path)
323
+ if digest != CORPUS_SHA256:
324
+ raise AssertionError(f"corpus sha256 {digest} != owner-pinned {CORPUS_SHA256}")
325
+ axes: Counter[str] = Counter()
326
+ rows = 0
327
+ meta_tokens = 0
328
+ with path.open("r", encoding="utf-8") as handle:
329
+ for line_no, line in enumerate(handle, 1):
330
+ if not line.strip():
331
+ continue
332
+ record = json.loads(line)
333
+ if not isinstance(record.get("text"), str):
334
+ raise AssertionError(f"corpus line {line_no}: missing string text")
335
+ axes[record.get("axis")] += 1
336
+ meta_tokens += int(record.get("meta", {}).get("calib_tokens", 0))
337
+ rows += 1
338
+ if rows != CORPUS_ROWS:
339
+ raise AssertionError(f"corpus has {rows} rows; expected {CORPUS_ROWS}")
340
+ if dict(axes) != AXIS_COUNTS:
341
+ raise AssertionError(f"corpus axes {dict(axes)} != {AXIS_COUNTS}")
342
+ return {
343
+ "path": str(path),
344
+ "sha256": digest,
345
+ "rows": rows,
346
+ "axes": dict(sorted(axes.items())),
347
+ "metadata_calib_tokens": meta_tokens,
348
+ }
349
+
350
+
351
+ def validate_plan(path: Path, src: Path) -> dict:
352
+ plan = json.loads(path.read_text())
353
+ if plan.get("schema") != "glm52-b300-capture-plan-v1":
354
+ raise AssertionError(f"unexpected capture plan schema: {plan.get('schema')!r}")
355
+ if plan.get("corpus_sha256") != CORPUS_SHA256 or plan.get("calibration_baseline") is not True:
356
+ raise AssertionError("capture plan is not the mandatory owner calibration baseline")
357
+ if plan.get("owner_corpus_only") is not True:
358
+ raise AssertionError("capture plan does not declare owner-corpus-only calibration")
359
+ if int(plan.get("corpus_rows", -1)) != CORPUS_ROWS or plan.get("axis_rows") != AXIS_COUNTS:
360
+ raise AssertionError("capture plan corpus row/axis counts do not match the owner baseline")
361
+ if plan.get("selection_policy") != "owner-corpus-axis-separated-luke-multipass-no-repeat-v1":
362
+ raise AssertionError("capture plan selection policy is not the Luke-style owner baseline")
363
+ routing = plan.get("routing")
364
+ expected_routing = {
365
+ "natural": True,
366
+ "forced_expert_activation": False,
367
+ "scoring_func": "sigmoid",
368
+ "top_k": 8,
369
+ "n_group": 1,
370
+ "topk_group": 1,
371
+ }
372
+ if routing != expected_routing:
373
+ raise AssertionError(f"capture routing {routing} != {expected_routing}")
374
+ if int(plan.get("capture_tp", -1)) != 8 or int(plan.get("output_tp", -1)) != 4:
375
+ raise AssertionError("capture/output TP must be TP8/TP4")
376
+ if [item.get("axis") for item in plan.get("passes", [])] != list(AXES):
377
+ raise AssertionError("plan must contain one ordered pass per owner axis")
378
+ canonical = dict(plan)
379
+ fingerprint = canonical.pop("capture_fingerprint", None)
380
+ got = hashlib.sha256(
381
+ json.dumps(canonical, sort_keys=True, separators=(",", ":")).encode()
382
+ ).hexdigest()
383
+ if fingerprint != got:
384
+ raise AssertionError(f"capture plan fingerprint {fingerprint} != {got}")
385
+ config_path = src / "config.json"
386
+ index_path = src / "model.safetensors.index.json"
387
+ if not config_path.is_file() or not index_path.is_file():
388
+ raise AssertionError("cannot bind capture plan to source: config/index absent")
389
+ current_source = {
390
+ "config_sha256": sha256_file(config_path),
391
+ "index_sha256": sha256_file(index_path),
392
+ }
393
+ if plan.get("source") != current_source:
394
+ raise AssertionError(
395
+ f"capture plan source mismatch: {plan.get('source')} != {current_source}"
396
+ )
397
+ total_tokens = int(plan["total_tokens"])
398
+ capture_bytes = total_tokens * 75 * (HIDDEN * 2 + 8)
399
+ if int(plan.get("capture_bytes", -1)) != capture_bytes:
400
+ raise AssertionError("capture plan byte arithmetic mismatch")
401
+ return {
402
+ "path": str(path),
403
+ "capture_fingerprint": fingerprint,
404
+ "passes": len(plan["passes"]),
405
+ "samples": sum(len(item["samples"]) for item in plan["passes"]),
406
+ "tokens_per_layer": total_tokens,
407
+ "capture_bytes": capture_bytes,
408
+ "capture_gib": capture_bytes / GIB,
409
+ "source": current_source,
410
+ }
411
+
412
+
413
+ def check_hardware() -> dict:
414
+ output = run(
415
+ [
416
+ "nvidia-smi",
417
+ "--query-gpu=index,name,memory.total,compute_cap",
418
+ "--format=csv,noheader,nounits",
419
+ ]
420
+ )
421
+ rows = []
422
+ for line in output.splitlines():
423
+ fields = [field.strip() for field in line.split(",")]
424
+ if len(fields) != 4:
425
+ raise AssertionError(f"unexpected nvidia-smi row: {line!r}")
426
+ rows.append(
427
+ {"index": int(fields[0]), "name": fields[1], "memory_mib": int(fields[2]), "cc": fields[3]}
428
+ )
429
+ if len(rows) != EXPECTED_GPUS:
430
+ raise AssertionError(f"found {len(rows)} GPUs; expected {EXPECTED_GPUS}")
431
+ for expected_index, row in enumerate(rows):
432
+ if row["index"] != expected_index:
433
+ raise AssertionError(f"GPU indices are not 0..7: {rows}")
434
+ if row["name"] != EXPECTED_GPU_NAME or row["memory_mib"] != EXPECTED_GPU_MIB:
435
+ raise AssertionError(f"unexpected GPU identity/capacity: {row}")
436
+ if not row["cc"].startswith("10."):
437
+ raise AssertionError(f"unexpected B300 compute capability: {row}")
438
+ return {
439
+ "gpus": rows,
440
+ "aggregate_mib": sum(row["memory_mib"] for row in rows),
441
+ "aggregate_gib": sum(row["memory_mib"] for row in rows) / 1024,
442
+ "aggregate_tib": sum(row["memory_mib"] for row in rows) / 1024 / 1024,
443
+ "owner_build_arch": OWNER_BUILD_ARCH,
444
+ }
445
+
446
+
447
+ def check_nvlink() -> dict:
448
+ output = run(["nvidia-smi", "nvlink", "-s"])
449
+ lines = [line for line in output.splitlines() if re.match(r"^\s*Link \d+:.*GB/s", line)]
450
+ if len(lines) != EXPECTED_NVLINK_LINES:
451
+ raise AssertionError(f"active NVLink speed lines={len(lines)}; expected 144")
452
+ return {"active_speed_lines": len(lines), "sample": lines[:2]}
453
+
454
+
455
+ def meminfo() -> dict:
456
+ values = {}
457
+ for line in Path("/proc/meminfo").read_text().splitlines():
458
+ if ":" in line:
459
+ key, value = line.split(":", 1)
460
+ fields = value.split()
461
+ if fields and fields[0].isdigit():
462
+ values[key] = int(fields[0]) * 1024
463
+ total = values.get("MemTotal", 0)
464
+ available = values.get("MemAvailable", 0)
465
+ if total < 2_000 * GIB:
466
+ raise AssertionError(f"host RAM {total / GIB:.2f} GiB; expected at least 2000 GiB")
467
+ return {"total_bytes": total, "total_gib": total / GIB, "available_bytes": available, "available_gib": available / GIB}
468
+
469
+
470
+ def check_shm() -> dict:
471
+ path = Path("/dev/shm")
472
+ usage = shutil.disk_usage(path)
473
+ stat = os.statvfs(path)
474
+ swap_lines = Path("/proc/swaps").read_text().splitlines()[1:]
475
+ swap_used = sum(int(line.split()[3]) * 1024 for line in swap_lines if line.split())
476
+ window_bytes = 8 * 1_048_576 * (HIDDEN * 2 + 8)
477
+ if usage.free < window_bytes + 64 * GIB:
478
+ raise AssertionError("/dev/shm cannot hold an eight-layer window plus 64 GiB reserve")
479
+ return {
480
+ "path": str(path),
481
+ "capacity_bytes": usage.total,
482
+ "capacity_gib": usage.total / GIB,
483
+ "free_bytes": usage.free,
484
+ "nominal_full_capture_bytes": NOMINAL_CAPTURE_BYTES,
485
+ "nominal_full_capture_gib": NOMINAL_CAPTURE_BYTES / GIB,
486
+ "eight_layer_window_bytes": window_bytes,
487
+ "swap_entries": len(swap_lines),
488
+ "swap_used_bytes": swap_used,
489
+ "block_size": stat.f_frsize,
490
+ "policy": "capture-data windows required; overlay forbidden",
491
+ }
492
+
493
+
494
+ def check_python_cuda() -> tuple[dict, str]:
495
+ if sys.version_info[:2] != (3, 12):
496
+ raise AssertionError(f"Python {platform.python_version()}; expected 3.12.x")
497
+ nvcc = run(["nvcc", "--version"])
498
+ match = re.search(r"release\s+(\d+\.\d+)", nvcc)
499
+ if not match:
500
+ raise AssertionError("could not parse nvcc release")
501
+ return ({"executable": sys.executable, "python": platform.python_version(), "nvcc_release": match.group(1)}, match.group(1))
502
+
503
+
504
+ def check_torch(nvcc_release: str) -> tuple[str, dict]:
505
+ try:
506
+ import torch
507
+ except Exception as exc:
508
+ return "PENDING", {"reason": f"torch not importable in {sys.executable}: {exc}"}
509
+ evidence = {
510
+ "torch": torch.__version__,
511
+ "torch_cuda": torch.version.cuda,
512
+ "cuda_available": torch.cuda.is_available(),
513
+ "device_count": torch.cuda.device_count() if torch.cuda.is_available() else 0,
514
+ "nvcc_release": nvcc_release,
515
+ "CUDA_HOME": os.environ.get("CUDA_HOME"),
516
+ }
517
+ if not torch.cuda.is_available() or torch.cuda.device_count() != EXPECTED_GPUS:
518
+ raise AssertionError(f"Torch CUDA visibility mismatch: {evidence}")
519
+ evidence["gpu0"] = torch.cuda.get_device_name(0)
520
+ evidence["capability0"] = list(torch.cuda.get_device_capability(0))
521
+ torch_major = int(str(torch.version.cuda).split(".", 1)[0])
522
+ nvcc_major = int(nvcc_release.split(".", 1)[0])
523
+ if torch_major != nvcc_major:
524
+ raise AssertionError(f"Torch/nvcc CUDA major mismatch: {evidence}")
525
+ return "PASS", evidence
526
+
527
+
528
+ def projected_disk_need(src: Path) -> int:
529
+ source_bytes = sum(path.stat().st_size for path in src.glob("*.safetensors")) if src.is_dir() else 0
530
+ remaining_source = max(0, SOURCE_EXPECTED_BYTES - source_bytes)
531
+ return (
532
+ remaining_source
533
+ + ENCODE_WORK_ALLOWANCE_BYTES
534
+ + ASSEMBLED_OUTPUT_ALLOWANCE_BYTES
535
+ + DEFAULT_DISK_RESERVE_BYTES
536
+ )
537
+
538
+
539
+ def main() -> None:
540
+ parser = argparse.ArgumentParser(description="GLM-5.2 B300 measured-host preflight")
541
+ parser.add_argument("--smoke", action="store_true", help="allow only expected source/plan pending state")
542
+ parser.add_argument("--src", default="/workspace/bf16", type=Path)
543
+ parser.add_argument(
544
+ "--corpus", default="/workspace/tr3/calib/reap_recall_calib.jsonl", type=Path
545
+ )
546
+ parser.add_argument("--plan", default="/workspace/tr3/capture_plan.json", type=Path)
547
+ parser.add_argument("--work-root", default="/workspace/tr3", type=Path)
548
+ args = parser.parse_args()
549
+ src = args.src.resolve()
550
+ corpus = args.corpus.resolve()
551
+ plan = args.plan.resolve()
552
+ work_root = args.work_root.resolve()
553
+ report = Report()
554
+
555
+ checks = [
556
+ ("disk guard", lambda: assert_disk_free(work_root)),
557
+ ("B300 hardware", check_hardware),
558
+ ("NVLink", check_nvlink),
559
+ ("host RAM", meminfo),
560
+ ("host-RAM capture", check_shm),
561
+ ("owner calibration corpus", lambda: validate_corpus(corpus)),
562
+ ]
563
+ for name, function in checks:
564
+ try:
565
+ report.passed(name, function())
566
+ except Exception as exc:
567
+ report.failed(name, str(exc))
568
+
569
+ try:
570
+ disk = shutil.disk_usage(_existing_ancestor(work_root))
571
+ needed = projected_disk_need(src)
572
+ if disk.free < needed:
573
+ raise AssertionError(f"projected free need={needed}, actual free={disk.free}")
574
+ report.passed("projected conversion disk", {"free_bytes": disk.free, "required_bytes": needed})
575
+ except Exception as exc:
576
+ report.failed("projected conversion disk", str(exc))
577
+
578
+ nvcc_release = "unknown"
579
+ try:
580
+ evidence, nvcc_release = check_python_cuda()
581
+ report.passed("Python/CUDA toolkit", evidence)
582
+ except Exception as exc:
583
+ report.failed("Python/CUDA toolkit", str(exc))
584
+ if nvcc_release != "unknown":
585
+ try:
586
+ status, evidence = check_torch(nvcc_release)
587
+ report.add(status, "Torch CUDA runtime/build pairing", evidence)
588
+ except Exception as exc:
589
+ report.failed("Torch CUDA runtime/build pairing", str(exc))
590
+
591
+ guide = Path("/etc/vast-agents-guide.md")
592
+ base_guide = Path("/etc/vast_agents/base.md")
593
+ if guide.is_file() and base_guide.is_file():
594
+ report.passed("Vast supervisor guide", {"guide": str(guide), "base": str(base_guide)})
595
+ else:
596
+ report.failed("Vast supervisor guide", "required operating guide missing")
597
+
598
+ try:
599
+ status, evidence = inspect_source_progress(src, smoke=args.smoke)
600
+ if status == "PENDING" and not args.smoke:
601
+ report.failed("BF16 source", evidence)
602
+ else:
603
+ report.add(status, "BF16 source", evidence)
604
+ except Exception as exc:
605
+ report.failed("BF16 source", str(exc))
606
+
607
+ if plan.is_file():
608
+ try:
609
+ report.passed("capture plan", validate_plan(plan, src))
610
+ except Exception as exc:
611
+ report.failed("capture plan", str(exc))
612
+ elif args.smoke:
613
+ report.pending("capture plan", {"path": str(plan), "reason": "build after tokenizer/source arrives"})
614
+ else:
615
+ report.failed("capture plan", f"absent: {plan}")
616
+
617
+ counts = report.counts()
618
+ summary = {"counts": dict(counts), "smoke": args.smoke, "checks": report.items}
619
+ print(json.dumps(summary, indent=2, sort_keys=True))
620
+ if counts["FAIL"]:
621
+ print(f"PREFLIGHT FAILED: {counts['FAIL']} contradiction(s)")
622
+ raise SystemExit(1)
623
+ if not args.smoke and counts["PENDING"]:
624
+ print(f"STRICT PREFLIGHT FAILED: {counts['PENDING']} pending check(s)")
625
+ raise SystemExit(1)
626
+ mode = "SMOKE" if args.smoke else "STRICT"
627
+ print(f"{mode} PREFLIGHT PASSED: {counts['PASS']} pass, {counts['PENDING']} pending")
628
+
629
+
630
+ if __name__ == "__main__":
631
+ main()
calibration_manifest.json ADDED
The diff for this file is too large to render. See raw diff
 
chat_template.jinja ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [gMASK]<sop>
2
+ {%- set effective_reasoning_effort = 'high' if reasoning_effort is defined and reasoning_effort == 'high' else 'max' -%}
3
+ {%- if (enable_thinking is not defined or enable_thinking) and effective_reasoning_effort is not none -%}<|system|>Reasoning Effort: {{ effective_reasoning_effort | capitalize }}{%- endif -%}
4
+ {%- if tools -%}
5
+ {%- macro tool_to_json(tool) -%}
6
+ {%- set ns_tool = namespace(first=true) -%}
7
+ {{ '{' -}}
8
+ {%- for k, v in tool.items() -%}
9
+ {%- if k != 'defer_loading' and k != 'strict' -%}
10
+ {%- if not ns_tool.first -%}{{- ', ' -}}{%- endif -%}
11
+ {%- set ns_tool.first = false -%}
12
+ "{{ k }}": {{ v | tojson(ensure_ascii=False) }}
13
+ {%- endif -%}
14
+ {%- endfor -%}
15
+ {{- '}' -}}
16
+ {%- endmacro -%}
17
+ <|system|>
18
+ # Tools
19
+
20
+ You may call one or more functions to assist with the user query.
21
+
22
+ You are provided with function signatures within <tools></tools> XML tags:
23
+ <tools>
24
+ {% for tool in tools %}
25
+ {%- if 'function' in tool -%}
26
+ {%- set tool = tool['function'] -%}
27
+ {%- endif -%}
28
+ {% if tool.defer_loading is not defined or not tool.defer_loading %}
29
+ {{ tool_to_json(tool) }}
30
+ {% endif %}
31
+ {% endfor %}
32
+ </tools>
33
+
34
+ For each function call, output the function name and arguments within the following XML format:
35
+ <tool_call>{function-name}<arg_key>{arg-key-1}</arg_key><arg_value>{arg-value-1}</arg_value><arg_key>{arg-key-2}</arg_key><arg_value>{arg-value-2}</arg_value>...</tool_call>{%- endif -%}
36
+ {%- macro visible_text(content) -%}
37
+ {%- if content is string -%}
38
+ {{- content }}
39
+ {%- elif content is iterable and content is not mapping -%}
40
+ {%- for item in content -%}
41
+ {%- if item is mapping and item.type == 'text' -%}
42
+ {{- item.text }}
43
+ {%- elif item is string -%}
44
+ {{- item }}
45
+ {%- elif item is mapping and item.type in ['image', 'image_url', 'video', 'video_url', 'audio', 'audio_url', 'input_audio'] -%}
46
+ {%- set media_type = item.type | replace('_url', '') | replace('input_', '') -%}
47
+ {{- "<reminder>You are unable to process this " ~ media_type ~ " because you don't have multi-modal input ability. Try different methods.</reminder>" }}
48
+ {%- endif -%}
49
+ {%- endfor -%}
50
+ {%- else -%}
51
+ {{- content }}
52
+ {%- endif -%}
53
+ {%- endmacro -%}
54
+ {%- set ns = namespace(last_user_index=-1) -%}
55
+ {%- for m in messages %}
56
+ {%- if m.role == 'user' %}
57
+ {%- set ns.last_user_index = loop.index0 -%}
58
+ {%- endif %}
59
+ {%- endfor %}
60
+ {%- for m in messages -%}
61
+ {%- if m.role == 'user' -%}<|user|>{{ visible_text(m.content) }}
62
+ {%- elif m.role == 'assistant' -%}
63
+ <|assistant|>
64
+ {%- set content = visible_text(m.content) %}
65
+ {%- if m.reasoning_content is string %}
66
+ {%- set reasoning_content = m.reasoning_content %}
67
+ {%- elif '</think>' in content %}
68
+ {%- set reasoning_content = content.split('</think>')[0].split('<think>')[-1] %}
69
+ {%- set content = content.split('</think>')[-1] %}
70
+ {%- endif %}
71
+ {%- if ((clear_thinking is defined and not clear_thinking) or loop.index0 > ns.last_user_index) and reasoning_content is defined -%}
72
+ {{ '<think>' + reasoning_content + '</think>'}}
73
+ {%- else -%}
74
+ {{ '<think></think>' }}
75
+ {%- endif -%}
76
+ {%- if content.strip() -%}
77
+ {{ content.strip() }}
78
+ {%- endif -%}
79
+ {% if m.tool_calls %}
80
+ {% for tc in m.tool_calls %}
81
+ {%- if tc.function %}
82
+ {%- set tc = tc.function %}
83
+ {%- endif %}
84
+ {{- '<tool_call>' + tc.name -}}
85
+ {% set _args = tc.arguments %}{% for k, v in _args.items() %}<arg_key>{{ k }}</arg_key><arg_value>{{ v | tojson(ensure_ascii=False) if v is not string else v }}</arg_value>{% endfor %}</tool_call>{% endfor %}
86
+ {% endif %}
87
+ {%- elif m.role == 'tool' -%}
88
+ {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
89
+ {{- '<|observation|>' -}}
90
+ {%- endif %}
91
+ {%- if m.content is string -%}
92
+ {{- '<tool_response>' + m.content + '</tool_response>' -}}
93
+ {%- elif m.content is iterable and m.content is not mapping and m.content and m.content.0.type == "tool_reference" -%}
94
+ {{- '<tool_response><tools>\n' -}}
95
+ {% for tr in m.content %}
96
+ {%- for tool in tools -%}
97
+ {%- if 'function' in tool -%}
98
+ {%- set tool = tool['function'] -%}
99
+ {%- endif -%}
100
+ {%- if tool.name == tr.name -%}
101
+ {{- tool_to_json(tool) + '\n' -}}
102
+ {%- endif -%}
103
+ {%- endfor -%}
104
+ {%- endfor -%}
105
+ {{- '</tools></tool_response>' -}}
106
+ {%- elif m.content is iterable and m.content is not mapping and m.content and m.content.0 is mapping and m.content.0.output is defined -%}
107
+ {%- for tr in m.content -%}
108
+ {{- '<tool_response>' + tr.output + '</tool_response>' -}}
109
+ {%- endfor -%}
110
+ {%- else -%}
111
+ {{- '<tool_response>' + visible_text(m.content) + '</tool_response>' -}}
112
+ {% endif -%}
113
+ {%- elif m.role == 'system' -%}
114
+ <|system|>{{ visible_text(m.content) }}
115
+ {%- endif -%}
116
+ {%- endfor -%}
117
+ {%- if add_generation_prompt -%}
118
+ <|assistant|>{{- '<think></think>' if (enable_thinking is defined and not enable_thinking) else '<think>' -}}
119
+ {%- endif -%}
config.json ADDED
@@ -0,0 +1,507 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "GlmMoeDsaForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "dtype": "bfloat16",
8
+ "eos_token_id": [
9
+ 154820,
10
+ 154827,
11
+ 154829
12
+ ],
13
+ "ep_size": 1,
14
+ "first_k_dense_replace": 3,
15
+ "head_dim": 192,
16
+ "hidden_act": "silu",
17
+ "hidden_size": 6144,
18
+ "hybrid_tr3_tail": {
19
+ "bits": 3.0,
20
+ "calibration": {
21
+ "axis_rows": {
22
+ "axis1_general": 3057,
23
+ "axis2_legal": 3057,
24
+ "axis3_code_agentic": 3057,
25
+ "axis4_reasoning_termination": 3057
26
+ },
27
+ "capture_fingerprint": "2efd10279b8c953e3e46a469d9ec9970593795859c7a2cebc98c9ea707115b51",
28
+ "corpus_rows": 12228,
29
+ "corpus_sha256": "cf247acc7c5da9f0600c7d6ab3b7c2fcfc54ec30b794e3b6047559285fa44df4",
30
+ "layer_h_fallback_experts_total": 0,
31
+ "min_routed_floor": 1024,
32
+ "passes": [
33
+ {
34
+ "axis": "axis1_general",
35
+ "name": "axis1_general",
36
+ "samples": 247,
37
+ "tokens": 294790
38
+ },
39
+ {
40
+ "axis": "axis2_legal",
41
+ "name": "axis2_legal",
42
+ "samples": 832,
43
+ "tokens": 294681
44
+ },
45
+ {
46
+ "axis": "axis3_code_agentic",
47
+ "name": "axis3_code_agentic",
48
+ "samples": 361,
49
+ "tokens": 295687
50
+ },
51
+ {
52
+ "axis": "axis4_reasoning_termination",
53
+ "name": "axis4_reasoning_termination",
54
+ "samples": 3057,
55
+ "tokens": 165310
56
+ }
57
+ ],
58
+ "per_layer_ids_sha256": {
59
+ "10": "944172cb95fd0d5e04f6530c576fdbd3655017dd2f84df4a6026327bb3bd8b29",
60
+ "11": "96c038deadb3a6246e43c3721baec2e38c74da892c4cc4bf4eafc752924b3a62",
61
+ "12": "b534b4fabfdf4106f29fb2c6da9ba02f922c5e0de8b540214093b6d9a4ab83d4",
62
+ "13": "9281ba7da8317e3698d99b3d8a0bb49451381ed307b6bca7aa1728976cea048f",
63
+ "14": "e30587c05ac7a057ed3baee76c8d52137351bc60ad310cc7a936b504b5c1b6a2",
64
+ "15": "bb0a47a86f174c2c2ea1850ac5b306e603f0c2c4d073f51229e4b08577ded702",
65
+ "16": "297126f807808607f099f8d22bd42ee568a370219c23a3a32bd8f8b938c5ce9b",
66
+ "17": "7fe9c08f797dfe88e7be5a93f9f367c5dd6dbc2b0dad6ba10962c9df0803d51f",
67
+ "18": "b4bd0335dba1bc416210505a2e51c42d2f395b1d14e7136bce854367cbe3de47",
68
+ "19": "f3013f105748cef65cf9635515e6fe126f9dc67640ea28b4512d4030f5c40a87",
69
+ "20": "6def65ec244e56203184ec5d941c96fc16a642c917d21c24d18f649f4d073a23",
70
+ "21": "f183d6273accde7f8e1d3818d584121b155c70dc697c27fb1eead713f09bf1ea",
71
+ "22": "313bdcc88cee8693f86d74c7179720374d0f1dae6ce8499533bc1761f4acb7e1",
72
+ "23": "f7005e9ce1ba7fd0ec2b35eba18611156ac9104f86bc94574b02ba5766e6e36e",
73
+ "24": "d60b184183f7ed719a634f64dbf80e40a7e055537da33ae0ddaa4810b7592e43",
74
+ "25": "1937356771d8de5d112e0bf047261e820294199f30b477a20f00fa161a7dcc12",
75
+ "26": "2233b8fe22d5b26e570b349d56608300bd23774a2813d1570d5768221d57187c",
76
+ "27": "6fecbaa85d3903b3c6ff754fa4fc87c60c1015acdf20223f0be472ed207ac56f",
77
+ "28": "252eb337da398832349416b6a6bbc0035b6459326890ed7cbb206cc95c45a450",
78
+ "29": "cd19bdf2ccd19d5cbbd2c122f0ebbaba027730fc37a5025c6458fea4159382ba",
79
+ "3": "160c5353b4ce34cb74fa06e31e5bb67d3ab483b2720c676aec2130624fdad26f",
80
+ "30": "cbf67bf960f554666cd79b150db925f5b084c0febafcd5506162586daaeb1ab6",
81
+ "31": "9547132cf221eac0cb626ada87b51de8a89530c22dee8d2af79397e2d8d27a02",
82
+ "32": "9b8535a00a5fc4751b90975cd61ebcf9c01cf029d9184ac2e46ec54df96dbc35",
83
+ "33": "02c9f4c12120ad5dfdd94c8016b8071094e57b850494f4c5a0de96e83fdbc150",
84
+ "34": "6ad1e3337ea2b7028174cbf8efd11ee7fb7561c188ec77ce5f0875582ec0b523",
85
+ "35": "f7333c478ca20eabbbd1a83eb0d31bdce456ce4f996611cc0171aada6cb5a9a4",
86
+ "36": "e4d3a0a2f39816f28c12c13a09c9ef53d3309e67e9ccbca0853a53806e5487f5",
87
+ "37": "802c36092a22bd973c8d03f15491ef8fc2b2a076bd45f94426ff21a76b46c747",
88
+ "38": "f96d105a5d266870b7d789dac882c9c6d9e7f9097165ed11a66bc1823e434caf",
89
+ "39": "5badf1a5c79952b3e0f664f8cc3c041d58637a1825bbcce3fd248cabb6a0f276",
90
+ "4": "d461d0a2725c9e38d8016531d9a0433f932c7934fc8b41fbab5d7a2d8fbcf982",
91
+ "40": "52fe99f4b029272b57c443b33dfdbf684ea94ed190146d6bce0563f924fd48a9",
92
+ "41": "6eb3a5c47cfa1a4aa1b20c7ce75f964bb8086238ca24ad527e08af3f5521dcee",
93
+ "42": "cfbc83865cd9e7e9c751447469a2ae288a0d9010d6f6c8ed1ad2fdd283c3bc57",
94
+ "43": "c5779321bfdbcd6e672682907cd894bc893c2d9d4983e8050afd4f2f17978016",
95
+ "44": "9cd7861ebf2d971c39f67ab00f7bea361b7f64f861c61bd2e6639ac995a71d62",
96
+ "45": "7d2cd2026f6a23517a9cb88c803bc2792dea4060b16d09ef340a9eb9f302c2ab",
97
+ "46": "e9a6a0248c7cb6f1be4d59c077c8741e6264d20f4003b2f050ad0dfc9c1152d8",
98
+ "47": "2c6512673c31c775c5d603581db34d4bd62634e712f6ddaca24cc3f40bbf8b42",
99
+ "48": "c37925833ae9e0f87a92aeb89237908d21048d0fe812072952eaeaa9937dec27",
100
+ "49": "f682b58165c1ad8c225e1f28677127442baa2e25b3cb906d5df010e236428d38",
101
+ "5": "59515e224e0ca8a066f168c207f8917782f752dff8255c0e8b40007608a4e363",
102
+ "50": "a382c0b7c24d8437b44314b5f1020c75401461e73f0d036d10f0df37b47a01fa",
103
+ "51": "e7368340cc69dd39c1a9d7618ed5624e366c938dcc144ab8830aa72491af5dae",
104
+ "52": "186dca03622be49f93de41a32da2e4557e96c1d6274c64f49e5e931ffef53810",
105
+ "53": "4c14e704cc39f92a35ec5ebd50ae4467595546a02029f5a56a42a3cfa8056247",
106
+ "54": "99810633dd399fae9bda0db56f35d2e30e86e2a6bf92c41d24b82dc951578f8f",
107
+ "55": "be1b9ff06a176ff0d84e9879426ec207933ffb1d6d61819afff76afe4d77d640",
108
+ "56": "458fb45785a2d8cce6f781b2dc8f1995f98ef0cb9ea6714d0a16fecbd047913e",
109
+ "57": "7cf63b0ff0a929c1996e1b00ec958b4682ae635ef551a87c25305ae068a0e4ce",
110
+ "58": "e09af62bd0f15531b9d7c911c255544f90b9808904ca461a4639379a96f44760",
111
+ "59": "3a2edee2590ad7cee5c051c52ecae5a89ee14a5c252efabf7997e338d230d834",
112
+ "6": "c7ad2fbfacd9a5c442634bf4ddd24188f8662271d30be979a01ce301da0860a3",
113
+ "60": "62a5b98c3805af186ad8296b82b46be09de73adea2cb6c54df67ecb954fc4dd3",
114
+ "61": "5bf327d957ed3f9b7ee2df33b883073d054599fae1c2844036143f57f6b6e27f",
115
+ "62": "4f9dcd6e578a281dc9ad2a7038c183dd4b724b87b5d9570139de4e860a83a1ed",
116
+ "63": "78bc32a22b0f3237aa3a2e3f4487f8678f4d5b735441e4a4893738247fdb4af5",
117
+ "64": "41247f7196e88c95462bcc8484210b742b13faeec674a70e9a6867704f9ffeb4",
118
+ "65": "dde15bb42ee0b54f41e7cffdef083a325220f5ce74877ebebd7c8b64844df5e2",
119
+ "66": "e5460abb6dd4de3699c2d29d9de833dd52129e9f10d778e892baad655a5ab5f4",
120
+ "67": "e06e0cd4d64492853a0c25085e5d796af0e388b9545187d06d11c8a70cf3d045",
121
+ "68": "5965fc8d1eb4adda502449a6483c0f3dfca084f7f75e9ad09146d0093c207ded",
122
+ "69": "45fc01960dbc7f7d36b2f05a17a3bf21a96b2589385a9d8dda646cd33a353e3a",
123
+ "7": "0b3387dc099d979559dfa043190202198d1743aef89d7f0d059fb635fc75e674",
124
+ "70": "7118c4343021dc4432fc0165ee055262b9792574a6cd94937da1151a0ac3d8dd",
125
+ "71": "0c37b81467e03903d414029bea5b6f2bcee196f802c0bac19ce9419ada0d0e24",
126
+ "72": "1fd11098af6ca9232edfc93538e53939d0e2f00adcc3846a782b7dd0aaaf6230",
127
+ "73": "413c33b7509fbc9e0a6b2e1ac4cff3d47ccd66fd77580289920197c96e526612",
128
+ "74": "e2a92bcf38b4a8fbe4188375c87793a3a03cba9db5f3f97bdc81cd55a68268be",
129
+ "75": "0ab6352069bccc138ed7a70aa755187308ba538747590136c8a4b436a207ec45",
130
+ "76": "666662199d3778752d69bff59c13ee163023d857a9d1d0cbc3f35d059922728f",
131
+ "77": "f4d604947ce189ae14e6d6ac54ab188f2d9339fc37ffdb6c32117e08d93fd4f8",
132
+ "8": "75469d18e1cb717a712e6c13a1f11e927eac38e4ea1a585e07d1e9b820045861",
133
+ "9": "10adf8399353453e4f8ec61345f958d2ffb3fc61532d5245f46729eba1889861"
134
+ },
135
+ "per_layer_x_sha256": {
136
+ "10": "630795bba68861abf750e67f5594b8312917ae716c421d8e14dccae26ae3dcdb",
137
+ "11": "2b888bfb5fdd4a4de1a1e1039ef8ab8bad7c603d3b14f7e17d8fb15e956bee81",
138
+ "12": "5712b76ef3252481e9218f5faaa06809ad824d7ba40e9bf824f1b19f3d047f38",
139
+ "13": "fad146e05a179f166ab98320e6c04b700b1899f9e10c7eff9bd3fc541243e1b0",
140
+ "14": "eecf2af2b26627a305930a869712f7eb9056e2b1b6c9b069c4054b7c2948c8e5",
141
+ "15": "8cc3d0efa9092a2b5890e8d5b65a2432152110ad1b083527cdb01d095c6e028e",
142
+ "16": "836579943de48a3c7ba9bb868f7d506ffa608ecdac8f5200ec43db094c20607f",
143
+ "17": "302c72af994b580b4b102323963331856d61bd18d8d9cdbd7ec4a617a5c4eed5",
144
+ "18": "fe598ec588ca35ab05ee3c40752a23d9f3a3f7a59486696971103d125792569e",
145
+ "19": "157255508ae292a65f8cd8876ec93b9641efcd038fff4913ff5422b1b18cd78b",
146
+ "20": "df15c4fbd286647dce38818b821cddb60c2baf744138dfc0ab4b13c8d06eaf8d",
147
+ "21": "a3dba41861914213faecb88b761be90f7f5240c9d6ef939719c72c667962fa7a",
148
+ "22": "749d9923d1ce4e8d4c9d48808f90dbf71ea399eea9e6a308e58bca7be0c3aa25",
149
+ "23": "001c6acf96a90dc26297b5bf9d23862e8c15a08f1dfe57dfdd4368d07b70a383",
150
+ "24": "52001d2a5d1b209cd05ed26750a410db774a0880588f15bdb225828febf7e104",
151
+ "25": "7290fd2d3e78a3ef509246dbcc3b4516fa6cc0d717859db5fa74dea7c8806b80",
152
+ "26": "5cbe9137b601650881126e7075dd32cc11134fa89734b8e096fbdd70e1ee2103",
153
+ "27": "136f8234f84234cbef5e5f35d4aba2d9ef9db15f9886d5c76998e4b2a8755c2f",
154
+ "28": "29e04c8c651296725b95ced18e119ab84f0f7bf107336af9b6f3e520550a7e09",
155
+ "29": "943412684ba07bdbb16e01bc232d8771b51366ecbce01b57e25e2c9ea4e017e7",
156
+ "3": "0d355318242b05301c317ec77657c65a51263c5de9a84a6a4ad5130328ae70f3",
157
+ "30": "52951f087a1508cf3aa474cc735009be7085c3eae9a88499c8c0d6c3b6736f4a",
158
+ "31": "dc7be9c6a09af6aeaba79ef884d831ffd0113e7e663d1ec2e49d997840224e9e",
159
+ "32": "163c140020e201e288921e0a1617384eba8975567422b201dcabfcb7e792427b",
160
+ "33": "c182636e040e3b28b08f3f34b0b4802ba4d0b31c46e6df2a58b2bd96c030cde3",
161
+ "34": "e4c74876aa00085294c523229dc4ef6b44dcbc2a8d4d25d189b973126f0d7f66",
162
+ "35": "214643ceb1d9a17139c4827fa5b03454fa4e4c62510a889d2649822f65d79a37",
163
+ "36": "88ce87b5b5a782cadbce1326cc9b31c8f22edf1d5bd09e25fc0711ddc6386b3a",
164
+ "37": "77b8130e6a17621f6d1246e8a1c403bc1b7e0b897a0643dda857b8ae3f130924",
165
+ "38": "018ac2a9b0fcaeb359a5da57babf8b0ca82d9aef13380693b002d3c790bf0d7e",
166
+ "39": "27f291b8f64e6ae1584f84a3c8adb641f37128152eb4be7f2c5b2a236c09b254",
167
+ "4": "37baf4eefc878b6a24a36591dc7e8940c6b4c024ec65c656fc57f55fe3da41e6",
168
+ "40": "cd2981874a400416187547a16091c9eee09a36d33d61d46ef69f1b4b6cd5800f",
169
+ "41": "92b2acd32f78d95527fc43c97e9aa9e83731796cebbec296b0ff0f9a19ccc90c",
170
+ "42": "1a7565a32dc1fe7dda07756c865779bdaa64b22a1d110933d2ea2e44c290f0ca",
171
+ "43": "68b2a4db375e8f15865674630c700dea7d1d606d47693fb0ea65593df88c6a65",
172
+ "44": "3f254dc62e45155fddf83b640aa50f59c5ef9b2e8d80d25dd593c708effdba5f",
173
+ "45": "9a1ec43bd81d4a3a2dca73661307defc55d5ec06265d4c704129e36a3e512528",
174
+ "46": "9dad9939c7dd222cce110b08b57026724b7b26767c08fbdbbb27ed44303bbe84",
175
+ "47": "d40758d70e4f2e7647a3809cd2f10a2f58f87e4003da9bc98f07c6d1ecd261a0",
176
+ "48": "acbe3f79ecec5d42266f4581ec799d0ff7ddfdde30df31b447036d162eb4022e",
177
+ "49": "df6668d6934376d6eea3386e640b8fd479767baa4d235595a9d3296a1b4a56b7",
178
+ "5": "71d5355a424386c8da2e68f5f003e03476610f5affc6fe4d90b9bfd155e43766",
179
+ "50": "829c06ea3e13f1d304d2c48bb5021fabd501bd5b723976a95eb21b0496103e85",
180
+ "51": "ef4762f7a9fd2a76ee0898083283d598da6cf5bd1d753a7c54cfe3fcf180e3fc",
181
+ "52": "84974f752e28ece7c3300dddc0edd3f977ef0068d291f6ca2292fb417b10d8d5",
182
+ "53": "a75256eb1541825ec96ffb2af2fa51647c62f97fd2922a648e368e64f011e797",
183
+ "54": "f15bd7e990817708cb9672f270da69a6c749044a75636223a6be9a8e2d3e1b36",
184
+ "55": "ee91530bcde2ba90c23574b1b7c9fa57aed6a39724156c77304a1dcba80ae983",
185
+ "56": "32509d298e8136f131b6dedcfd894e47bc40fa1dcebeff3672ce0cb4b97a31af",
186
+ "57": "8581236d84a23c08bebadbfb5f311e752c34ab583c5f9e2c45a146282ff7dbd6",
187
+ "58": "d747b80f367c74c19cdf85b16d30dfb78852094421a60e36b13685ff34a56a71",
188
+ "59": "897f8ba2318aad388a02d007703c033ac1658f8fc554d8d60ebbfbe569037461",
189
+ "6": "62dab46cbe4a8b99701343421be579eadfdbaef9099758393b0aa98f3393c024",
190
+ "60": "3187b62f18530096342f2faa72bf36b967e4768aba50bc9115c9902229fff0f6",
191
+ "61": "27bd21e3d10c1764238341e89ee63fa0a3068a27a9f1c2084ff29114a4b6cf96",
192
+ "62": "5e6489ce16a50af7fc3be6f8ffda9414aadc50673492dd9cfdceddce7094e6b1",
193
+ "63": "ccd2173bab0009596732462726a950e89dc387370a5054b138af9c6368caab83",
194
+ "64": "4e6864cee05926986fda8d8715af580b0343b21236a9999a2c544f433e4eabb1",
195
+ "65": "6948dd47c19f10cf02f996c07fbe9cacf8a2919fc4fc94ff05a707ed2d6df4bb",
196
+ "66": "db3b5a5a42cfdc9c60d8e0307e6d46a87fc5987a534fca070890b5758e39a59d",
197
+ "67": "fe52111f18cc6b9ea412698ab544037cfc9c6db462ec82d94c9eaf5f392c493c",
198
+ "68": "a7c85dcea4160b582fd0f320542ec5ec7a2c4680e4d1fb02f6efa149245979c2",
199
+ "69": "5edb0b2f3eb115616e97e99eb8c08c27efd683321445d9c440d5ca279a1e3091",
200
+ "7": "8f5a093166f9a319cec7125a3ee0e93d37c870a336973b882124a665d5b7873d",
201
+ "70": "0f4304523d6d706f18223769f192d051185498d77da38763cc1df8352da8d122",
202
+ "71": "e3c7ca04ff5a93926e02678e05f3de52d376a879bfa5ed562dff569ca4a9f8d6",
203
+ "72": "a6af9992479ebd42005c0698e836068e8a6d17a52427e348992a94947162a32c",
204
+ "73": "315f8eade152cb1fc45504cbd4b32f9b40bc4417163d548dbc50c4b64709ae45",
205
+ "74": "98398c3cfb5d1ce79dd7473fc5b4ccbda4eca571f2ea5b401410f74d3e773888",
206
+ "75": "b9d8903d95d798959dc2aaa2fb711c5e58e3622166a75b150f4085c08195090c",
207
+ "76": "f0b300212791b3b2be25b504cd69bd52d68464b3906c822a4956305077a5bd50",
208
+ "77": "82fe852e9e12ecec67b8e3385cf4e21b8ae82c6e4b9a26e9adebaf72540da039",
209
+ "8": "06184a67d58fe6e3cda7494c01a51cbcbe02559834f151f107dba7609b4c9169",
210
+ "9": "bba3bbbdcdfb72b1c37305068c8399b3de5a7e27399703aaedb798a2a3041010"
211
+ },
212
+ "q_fallback_slices_total": 0,
213
+ "selection_policy": "owner-corpus-axis-separated-luke-multipass-no-repeat-v1",
214
+ "sigma_reg": 0.025,
215
+ "tokens_per_layer": 1050468
216
+ },
217
+ "codebook": "mcg",
218
+ "exllamav3_version": "0.0.43",
219
+ "experts_per_layer": 256,
220
+ "format": "exl3-trellis",
221
+ "hessian": "ldlq-calibrated",
222
+ "mcg_multiplier": 3417055213,
223
+ "modelopt_dispatch_note": "quantization_config selects the b12x ModelOpt interception only; this artifact contains zero NVFP4 expert payloads. Layer 78 is ignored and remains BF16.",
224
+ "moe_layers": [
225
+ 3,
226
+ 78
227
+ ],
228
+ "nvfp4_keep_per_layer": 0,
229
+ "producer": "encode_b300.py",
230
+ "producer_version": "1",
231
+ "recipe_fingerprint": "db7e6a6d4191e93de86833261e693658abd6b0acc161ef8e6a1f91ed84179a7f",
232
+ "scope": {
233
+ "bf16_byte_exact": [
234
+ "attention",
235
+ "dense MLPs layers 0..2",
236
+ "shared experts",
237
+ "router/gates",
238
+ "MTP layer 78 non-expert (attention, router, shared experts, eh_proj, norms)",
239
+ "embeddings",
240
+ "lm_head"
241
+ ],
242
+ "quantized": "routed MoE expert gate/up/down projections, all 256 experts, layers 3..78"
243
+ },
244
+ "slicing": {
245
+ "down_proj": "TP4 K-slice: rank r owns input columns [512r,512r+512)",
246
+ "gate_proj": "TP4 N-slice: rank r owns output rows [512r,512r+512)",
247
+ "up_proj": "TP4 N-slice: rank r owns output rows [512r,512r+512)"
248
+ },
249
+ "source_config_sha256": "185f93ee6d12548e16a847e279dc0c3c90b1524c970b0866b42fb545747d859a",
250
+ "source_format": "BF16",
251
+ "source_index_sha256": "5fd47a926aefce0f2c917f42523e5e0f3c87e23e389e767c3681536a62f5cf5e",
252
+ "tensor_schema": "model.layers.{L}.mlp.experts.{E}.{proj}.rank{r}.{trellis|suh|svh|mcg}",
253
+ "tier_bitmap": "tier_bitmap.json",
254
+ "tp": 4,
255
+ "tr3_tail_per_layer": 256,
256
+ "mtp78_overlay": {
257
+ "source": "malaiwah/GLM-5.2-EXL3-TR3-MTP78/3bpw-keep0",
258
+ "file_sha256": "a63c64a8356d326b6078475071cec359a6c07e161aa22759a216305986e4b7ff",
259
+ "merged_layer078_sha256": "5448b63a32e394e8cbff5a4737fb50b40fc53c6c3c41305f1a7ee540c4d9a6e3"
260
+ }
261
+ },
262
+ "index_head_dim": 128,
263
+ "index_n_heads": 32,
264
+ "index_share_for_mtp_iteration": true,
265
+ "index_skip_topk_offset": 3,
266
+ "index_topk": 2048,
267
+ "index_topk_freq": 4,
268
+ "index_topk_pattern": null,
269
+ "indexer_rope_interleave": true,
270
+ "indexer_types": [
271
+ "full",
272
+ "full",
273
+ "full",
274
+ "shared",
275
+ "shared",
276
+ "shared",
277
+ "full",
278
+ "shared",
279
+ "shared",
280
+ "shared",
281
+ "full",
282
+ "shared",
283
+ "shared",
284
+ "shared",
285
+ "full",
286
+ "shared",
287
+ "shared",
288
+ "shared",
289
+ "full",
290
+ "shared",
291
+ "shared",
292
+ "shared",
293
+ "full",
294
+ "shared",
295
+ "shared",
296
+ "shared",
297
+ "full",
298
+ "shared",
299
+ "shared",
300
+ "shared",
301
+ "full",
302
+ "shared",
303
+ "shared",
304
+ "shared",
305
+ "full",
306
+ "shared",
307
+ "shared",
308
+ "shared",
309
+ "full",
310
+ "shared",
311
+ "shared",
312
+ "shared",
313
+ "full",
314
+ "shared",
315
+ "shared",
316
+ "shared",
317
+ "full",
318
+ "shared",
319
+ "shared",
320
+ "shared",
321
+ "full",
322
+ "shared",
323
+ "shared",
324
+ "shared",
325
+ "full",
326
+ "shared",
327
+ "shared",
328
+ "shared",
329
+ "full",
330
+ "shared",
331
+ "shared",
332
+ "shared",
333
+ "full",
334
+ "shared",
335
+ "shared",
336
+ "shared",
337
+ "full",
338
+ "shared",
339
+ "shared",
340
+ "shared",
341
+ "full",
342
+ "shared",
343
+ "shared",
344
+ "shared",
345
+ "full",
346
+ "shared",
347
+ "shared",
348
+ "shared"
349
+ ],
350
+ "initializer_range": 0.02,
351
+ "intermediate_size": 12288,
352
+ "kv_lora_rank": 512,
353
+ "max_position_embeddings": 1048576,
354
+ "mlp_layer_types": [
355
+ "dense",
356
+ "dense",
357
+ "dense",
358
+ "sparse",
359
+ "sparse",
360
+ "sparse",
361
+ "sparse",
362
+ "sparse",
363
+ "sparse",
364
+ "sparse",
365
+ "sparse",
366
+ "sparse",
367
+ "sparse",
368
+ "sparse",
369
+ "sparse",
370
+ "sparse",
371
+ "sparse",
372
+ "sparse",
373
+ "sparse",
374
+ "sparse",
375
+ "sparse",
376
+ "sparse",
377
+ "sparse",
378
+ "sparse",
379
+ "sparse",
380
+ "sparse",
381
+ "sparse",
382
+ "sparse",
383
+ "sparse",
384
+ "sparse",
385
+ "sparse",
386
+ "sparse",
387
+ "sparse",
388
+ "sparse",
389
+ "sparse",
390
+ "sparse",
391
+ "sparse",
392
+ "sparse",
393
+ "sparse",
394
+ "sparse",
395
+ "sparse",
396
+ "sparse",
397
+ "sparse",
398
+ "sparse",
399
+ "sparse",
400
+ "sparse",
401
+ "sparse",
402
+ "sparse",
403
+ "sparse",
404
+ "sparse",
405
+ "sparse",
406
+ "sparse",
407
+ "sparse",
408
+ "sparse",
409
+ "sparse",
410
+ "sparse",
411
+ "sparse",
412
+ "sparse",
413
+ "sparse",
414
+ "sparse",
415
+ "sparse",
416
+ "sparse",
417
+ "sparse",
418
+ "sparse",
419
+ "sparse",
420
+ "sparse",
421
+ "sparse",
422
+ "sparse",
423
+ "sparse",
424
+ "sparse",
425
+ "sparse",
426
+ "sparse",
427
+ "sparse",
428
+ "sparse",
429
+ "sparse",
430
+ "sparse",
431
+ "sparse",
432
+ "sparse"
433
+ ],
434
+ "model_type": "glm_moe_dsa",
435
+ "moe_intermediate_size": 2048,
436
+ "moe_layer_freq": 1,
437
+ "moe_router_dtype": "float32",
438
+ "n_group": 1,
439
+ "n_routed_experts": 256,
440
+ "n_shared_experts": 1,
441
+ "norm_topk_prob": true,
442
+ "num_attention_heads": 64,
443
+ "num_experts_per_tok": 8,
444
+ "num_hidden_layers": 78,
445
+ "num_key_value_heads": 64,
446
+ "num_nextn_predict_layers": 1,
447
+ "pad_token_id": 154820,
448
+ "pretraining_tp": 1,
449
+ "q_lora_rank": 2048,
450
+ "qk_head_dim": 256,
451
+ "qk_nope_head_dim": 192,
452
+ "qk_rope_head_dim": 64,
453
+ "quantization_config": {
454
+ "config_groups": {
455
+ "group_0": {
456
+ "input_activations": {
457
+ "dynamic": false,
458
+ "group_size": 16,
459
+ "num_bits": 4,
460
+ "type": "float"
461
+ },
462
+ "targets": [
463
+ "Linear"
464
+ ],
465
+ "weights": {
466
+ "dynamic": false,
467
+ "group_size": 16,
468
+ "num_bits": 4,
469
+ "type": "float"
470
+ }
471
+ }
472
+ },
473
+ "ignore": [
474
+ "lm_head",
475
+ "*embed_tokens*",
476
+ "model.norm*",
477
+ "*self_attn*",
478
+ "model.layers.0.mlp*",
479
+ "model.layers.1.mlp*",
480
+ "model.layers.2.mlp*",
481
+ "*shared_experts*",
482
+ "*mlp.gate*",
483
+ "model.layers.78.eh_proj*"
484
+ ],
485
+ "producer": {
486
+ "name": "b300-exl3-modelopt-dispatch-shim",
487
+ "version": "1"
488
+ },
489
+ "quant_algo": "NVFP4",
490
+ "quant_method": "modelopt"
491
+ },
492
+ "rms_norm_eps": 1e-05,
493
+ "rope_interleave": true,
494
+ "rope_parameters": {
495
+ "rope_theta": 8000000,
496
+ "rope_type": "default"
497
+ },
498
+ "routed_scaling_factor": 2.5,
499
+ "scoring_func": "sigmoid",
500
+ "tie_word_embeddings": false,
501
+ "topk_group": 1,
502
+ "topk_method": "noaux_tc",
503
+ "transformers_version": "5.12.0",
504
+ "use_cache": true,
505
+ "v_head_dim": 256,
506
+ "vocab_size": 154880
507
+ }
docker-compose.yml ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ services:
2
+ glm52:
3
+ image: ${IMAGE:-verdictai/glm52-exl3-sparkinfer:v26-gg-v20final-scopefix-archkey-vllm5517197-sibe0edca-cu132-sm120a@sha256:2bb9e804a283d1da3b7e3425ff87375121285141d0d0a40d3dc09d41bf881a10}
4
+ container_name: glm52-exl3-sparkinfer
5
+ ports:
6
+ - "${BIND_ADDRESS:-127.0.0.1}:${PORT:-8000}:8000"
7
+ gpus: all
8
+ shm_size: "32g"
9
+ ipc: host
10
+ ulimits:
11
+ memlock: -1
12
+ nofile: 1048576
13
+ environment:
14
+ CUDA_VISIBLE_DEVICES: "${CUDA_VISIBLE_DEVICES:-3,1,2,0}"
15
+ CUDA_DEVICE_ORDER: PCI_BUS_ID
16
+ CUDA_DEVICE_MAX_CONNECTIONS: "32"
17
+ CUTE_DSL_ARCH: sm_120a
18
+ TORCH_CUDA_ARCH_LIST: 12.0a
19
+ FLASHINFER_CUDA_ARCH_LIST: 12.0f
20
+ FLASHINFER_DISABLE_VERSION_CHECK: "1"
21
+ OMP_NUM_THREADS: "16"
22
+ PYTORCH_CUDA_ALLOC_CONF: expandable_segments:True
23
+ SAFETENSORS_FAST_GPU: "1"
24
+ NCCL_IB_DISABLE: "1"
25
+ NCCL_P2P_LEVEL: SYS
26
+ NCCL_PROTO: LL,LL128,Simple
27
+ VLLM_USE_FLASHINFER_SAMPLER: "1"
28
+ VLLM_USE_B12X_FP8_GEMM: "1"
29
+ VLLM_USE_B12X_SPARSE_INDEXER: "1"
30
+ VLLM_USE_B12X_MOE: "1"
31
+ VLLM_USE_V2_MODEL_RUNNER: "1"
32
+ VLLM_ENABLE_PCIE_ALLREDUCE: "1"
33
+ VLLM_PCIE_ALLREDUCE_BACKEND: b12x
34
+ VLLM_PCIE_ONESHOT_ALLREDUCE_MAX_SIZE: "${VLLM_PCIE_ONESHOT_ALLREDUCE_MAX_SIZE:-64KB}"
35
+ VLLM_PCIE_ONESHOT_FUSED_ADD_RMS_NORM_MAX_SIZE: "${VLLM_PCIE_ONESHOT_FUSED_ADD_RMS_NORM_MAX_SIZE:-84KB}"
36
+ VLLM_PCIE_DMA_FP8: ag
37
+ B12X_PCIE_DMA_FP8: ag
38
+ VLLM_CPP_AR_1STAGE_NCCL_CUTOFF: 56KB
39
+ VLLM_CPP_AR_IGNORE_CUTOFF_MAX_ROWS: "0"
40
+ VLLM_RTX6K_FUSED_ALLREDUCE_ADD: "0"
41
+ VLLM_RTX6K_FUSED_ALLREDUCE_ADD_END_BARRIER: "0"
42
+ VLLM_USE_AOT_COMPILE: "1"
43
+ VLLM_USE_BREAKABLE_CUDAGRAPH: "0"
44
+ VLLM_USE_FUSED_MOE_GROUPED_TOPK: "1"
45
+ VLLM_USE_B12X_MHC: "1"
46
+ B12X_MHC_MAX_TOKENS: "16384"
47
+ VLLM_USE_B12X_WO_PROJECTION: "1"
48
+ B12X_MLA_SM120_UNIFIED: "1"
49
+ B12X_DENSE_SPLITK_TURBO: "1"
50
+ B12X_W4A16_TC_DECODE: "1"
51
+ B12X_MOE_FORCE_A16: "1"
52
+ VLLM_DISABLE_SHARED_EXPERTS_STREAM: "${VLLM_DISABLE_SHARED_EXPERTS_STREAM:-1}"
53
+ VLLM_DISABLED_KERNELS: MarlinFP8ScaledMMLinearKernel
54
+ VLLM_B12X_MLA_SPEC_EXTEND_AS_DECODE: "${VLLM_B12X_MLA_SPEC_EXTEND_AS_DECODE:-0}"
55
+ VLLM_B12X_MLA_SPEC_DECODE_MAX_Q: "8"
56
+ VLLM_USE_B12X_DCP_A2A: "1"
57
+ VLLM_DCP_A2A_MAX_TOKENS: "16"
58
+ VLLM_DCP_A2A_LARGE_BACKEND: ag_rs
59
+ VLLM_DCP_GLOBAL_TOPK: "${VLLM_DCP_GLOBAL_TOPK:-1}"
60
+ VLLM_DCP_SHARD_DRAFT: "${VLLM_DCP_SHARD_DRAFT:-1}"
61
+ # --- Gilded Gnosis v20 FINAL DCP prefill auto-policy (TP4/DCP4) ----------
62
+ # These are exactly what the v20 base image's own launcher resolves from
63
+ # DCP_*=auto for TP=4/DCP=4 (verify with:
64
+ # docker run -e TP=4 -e DCP=4 -e DRY_RUN=1 \
65
+ # --entrypoint /usr/local/bin/serve-glm52-v19.sh <base-image>)
66
+ # They are set explicitly because this preset calls `vllm serve` directly
67
+ # for the EXL3 flags and so bypasses /usr/local/bin/serve-gilded-gnosis.sh,
68
+ # which is what normally translates DCP_* -> VLLM_*.
69
+ VLLM_DCP_QUERY_SPLIT: "${VLLM_DCP_QUERY_SPLIT:-1}"
70
+ VLLM_B12X_MLA_CKV_GATHER: "${VLLM_B12X_MLA_CKV_GATHER:-1}"
71
+ VLLM_DCP_TOPK_OWNER_MERGE: "${VLLM_DCP_TOPK_OWNER_MERGE:-1}"
72
+ VLLM_DCP_INDEXER_SHARDS: "${VLLM_DCP_INDEXER_SHARDS:-0}"
73
+ VLLM_B12X_MLA_CKV_PREFETCH_DEPTH: "${VLLM_B12X_MLA_CKV_PREFETCH_DEPTH:-1}"
74
+ VLLM_B12X_MLA_CKV_PREFETCH_WORKSPACE_MIB: "${VLLM_B12X_MLA_CKV_PREFETCH_WORKSPACE_MIB:-1024}"
75
+ # DCP_PREFILL_WORKSPACE=auto -> 1 for TP4/DCP4: the corrected workspace
76
+ # accounting that resolves the >8k DCP prefill collapse.
77
+ VLLM_DCP_PROJECT_BEFORE_MERGE: "${VLLM_DCP_PROJECT_BEFORE_MERGE:-1}"
78
+ VLLM_DCP_PROJECT_BEFORE_MERGE_MIN_PREFILL_TOKENS: "${VLLM_DCP_PROJECT_BEFORE_MERGE_MIN_PREFILL_TOKENS:-1024}"
79
+ VLLM_B12X_MLA_DCP_GATHER_IN_WORKSPACE: "${VLLM_B12X_MLA_DCP_GATHER_IN_WORKSPACE:-1}"
80
+ VLLM_B12X_MLA_CKV_GATHER_MIN_TOKENS: "${VLLM_B12X_MLA_CKV_GATHER_MIN_TOKENS:-512}"
81
+ VLLM_B12X_MLA_CKV_GATHER_MAX_TOKENS: "${VLLM_B12X_MLA_CKV_GATHER_MAX_TOKENS:-16384}"
82
+ ENABLE_MTP: "${ENABLE_MTP:-1}"
83
+ MTP_TOKENS: "${MTP_TOKENS:-3}"
84
+ MTP_DRAFT_SAMPLE_METHOD: "${MTP_DRAFT_SAMPLE_METHOD:-greedy}"
85
+ ENABLE_ASYNC_SCHEDULING: "${ENABLE_ASYNC_SCHEDULING:-0}"
86
+ GLM52_INDEX_TOPK_PATTERN: "${GLM52_INDEX_TOPK_PATTERN:-FFFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSSFSSS}"
87
+ # Empty = auto-profile max KV at GPU_MEMORY_UTILIZATION (~1.13M tokens with
88
+ # the tr3 MTP head on 4x RTX PRO 6000 @ 0.96). Set an integer to pin.
89
+ NUM_GPU_BLOCKS_OVERRIDE: "${NUM_GPU_BLOCKS_OVERRIDE:-}"
90
+ MAX_NUM_BATCHED_TOKENS: "${MAX_NUM_BATCHED_TOKENS:-3072}"
91
+ # REQUIRED for the tr3 MTP layer-78: MTP-N draft small-m (m=1..N) GEMMs must
92
+ # stay inside the Trellis cudagraph window (default 4 -> capture error m=3).
93
+ VLLM_EXL3_TRELLIS_MIN_M: "${VLLM_EXL3_TRELLIS_MIN_M:-1}"
94
+ VLLM_EXL3_TRELLIS_MAX_M: "32"
95
+ VLLM_EXL3_TRELLIS_BLOCK_M: "8"
96
+ VLLM_EXL3_PREFILL_CHUNK: "128"
97
+ VLLM_CACHE_DIR: /cache/jit/vllm
98
+ TRITON_CACHE_DIR: /cache/jit/triton
99
+ TORCH_EXTENSIONS_DIR: /cache/jit/torch_extensions
100
+ TORCHINDUCTOR_CACHE_DIR: /cache/jit/torchinductor
101
+ FLASHINFER_WORKSPACE_BASE: /cache/jit/flashinfer
102
+ XDG_CACHE_HOME: /cache/jit
103
+ TVM_FFI_CACHE_DIR: /cache/jit/tvm-ffi
104
+ VLLM_MEMORY_PROFILE_INCLUDE_ATTN: "1"
105
+ VLLM_MEMORY_PROFILER_ESTIMATE_CUDAGRAPHS: "1"
106
+ VLLM_DEBUG_WORKSPACE: "${VLLM_DEBUG_WORKSPACE:-0}"
107
+ volumes:
108
+ - ${MODEL_DIR:-/home/brandonmusic/models/GLM-5.2-EXL3-TR3-3.0bpw}:/model:ro
109
+ - ${CACHE_DIR:-/home/brandonmusic/.cache/glm52-tr3-release}:/cache:rw
110
+ entrypoint:
111
+ - /bin/bash
112
+ - -lc
113
+ command:
114
+ - |
115
+ unset NCCL_GRAPH_FILE NCCL_GRAPH_DUMP_FILE VLLM_B12X_MLA_EXTEND_MAX_CHUNKS
116
+ spec_args=()
117
+ if [[ "$${ENABLE_MTP:-1}" == "1" ]]; then
118
+ printf -v spec_config '{"method":"mtp","num_speculative_tokens":%s,"moe_backend":"triton","draft_sample_method":"%s"}' \
119
+ "$${MTP_TOKENS:-3}" "$${MTP_DRAFT_SAMPLE_METHOD:-greedy}"
120
+ spec_args=(--speculative-config "$$spec_config")
121
+ fi
122
+ if [[ "$${ENABLE_ASYNC_SCHEDULING:-0}" == "1" ]]; then
123
+ async_args=(--async-scheduling)
124
+ else
125
+ async_args=(--no-async-scheduling)
126
+ fi
127
+ index_pattern="$${GLM52_INDEX_TOPK_PATTERN}"
128
+ if [[ "$${#index_pattern}" -ne 78 ]]; then
129
+ printf 'GLM-5.2 index_topk_pattern must cover all 78 layers (got %s)\n' "$${#index_pattern}" >&2
130
+ exit 2
131
+ fi
132
+ printf -v hf_overrides '{"use_index_cache":true,"index_topk_pattern":"%s"}' "$${index_pattern}"
133
+ block_args=()
134
+ if [[ -n "$${NUM_GPU_BLOCKS_OVERRIDE:-}" ]]; then
135
+ block_args=(--num-gpu-blocks-override "$${NUM_GPU_BLOCKS_OVERRIDE}")
136
+ fi
137
+ exec vllm serve /model \
138
+ --served-model-name GLM-5.2-EXL3-TR3-3.0bpw \
139
+ --host 0.0.0.0 --port 8000 --trust-remote-code \
140
+ --tensor-parallel-size 4 \
141
+ --decode-context-parallel-size 4 \
142
+ --dcp-comm-backend a2a \
143
+ --dcp-kv-cache-interleave-size ${DCP_KV_CACHE_INTERLEAVE_SIZE:-64} \
144
+ --seed 0 \
145
+ --quantization exl3 \
146
+ --kv-cache-dtype nvfp4_ds_mla \
147
+ --attention-backend B12X_MLA_SPARSE \
148
+ --moe-backend b12x \
149
+ --load-format safetensors \
150
+ --compilation-config '{"cudagraph_mode":"FULL_AND_PIECEWISE","cudagraph_capture_sizes":[4,8,12,16,20,24,28,32],"custom_ops":["all"],"pass_config":{"fuse_allreduce_rms":true}}' \
151
+ --gpu-memory-utilization ${GPU_MEMORY_UTILIZATION:-0.96} \
152
+ --max-model-len ${MAX_MODEL_LEN:-524288} \
153
+ --max-num-seqs 8 \
154
+ --max-num-batched-tokens $${MAX_NUM_BATCHED_TOKENS:-3072} \
155
+ --max-cudagraph-capture-size 32 \
156
+ --enable-chunked-prefill \
157
+ --enable-prefix-caching \
158
+ --enable-auto-tool-choice \
159
+ --tool-call-parser glm47 \
160
+ --reasoning-parser glm45 \
161
+ --default-chat-template-kwargs '{"reasoning_effort":"high"}' \
162
+ --hf-overrides "$${hf_overrides}" \
163
+ "$${block_args[@]}" \
164
+ "$${async_args[@]}" \
165
+ "$${spec_args[@]}"
generation_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "eos_token_id": [
4
+ 154820,
5
+ 154827,
6
+ 154829
7
+ ],
8
+ "pad_token_id": 154820,
9
+ "temperature": 1.0,
10
+ "top_p": 0.95,
11
+ "transformers_version": "5.12.0"
12
+ }
independent-eval/ORIGINAL_REPORT.md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GLM-5.2-EXL3-TR3-3.0bpw — independent benchmark results
2
+
3
+ Independent evaluation of `GLM-5.2-EXL3-TR3-3.0bpw` against the original
4
+ `zai-org/GLM-5.2` (753B-A40B, BF16) published scores. Run 2026-07-23/24 on a
5
+ self-hosted server; client harness scripts included for reproduction. A sibling
6
+ run of `madeby561/GLM-5.2-MXFP8-NVFP4-NF3-Hybrid` used the identical harness,
7
+ prompts, and deterministic GPQA choice shuffles, so all three columns are
8
+ directly comparable.
9
+
10
+ ## Results (pass@1, aggregated across repeats)
11
+
12
+ | Benchmark | n (questions × repeats) | EXL3 3.0bpw | Hybrid MXFP8/NVFP4/NF3 | Original (Z.ai published) | ~95% CI (EXL3) |
13
+ |----------------|-------------------------|-------------|------------------------|---------------------------|----------------|
14
+ | AIME 2026 | 30 × 4 = 120 | 99.2 | 97.5 | 99.2 | ±1.6 |
15
+ | HMMT Feb 2026 | 33 × 4 = 132 | 95.5 | 97.0 | 92.5 | ±3.6 |
16
+ | GPQA Diamond | 198 × 2 = 396 | 91.4 | 89.4 | 91.2 | ±2.8 |
17
+
18
+ All deltas versus BF16 are within sampling noise: no measurable reasoning
19
+ degradation was detected at 3.0 bits per weight. CI is a simple binomial
20
+ approximation; repeats of the same question are correlated, so true intervals
21
+ are somewhat wider.
22
+
23
+ ## Environment
24
+
25
+ - Quant: EXL3 TR3, 3.0 bpw
26
+ - Hardware: 4× RTX PRO 6000, fp8 KV cache, MTP-3 (multi-token prediction /
27
+ speculative decoding — affects throughput only, not output distribution)
28
+ - Engine: vLLM-compatible server reporting version `0.17.0rc1.dev4499+g60c82d972`,
29
+ `max_model_len` 524288, OpenAI-compatible chat completions
30
+ - Reasoning arrives in `message.reasoning`; answers extracted from `message.content` only
31
+ - Client: async Python harness (scripts in this bundle), 32 concurrent
32
+ requests total (16 GPQA + 8 AIME + 8 HMMT), all three benchmarks run simultaneously
33
+ - Aggregate throughput ~65 tok/s under mixed long-reasoning load; 8.63M
34
+ completion tokens total over ~16 h
35
+
36
+ ## Methodology
37
+
38
+ Matched to Z.ai's published eval settings from the zai-org/GLM-5.2 model card:
39
+
40
+ - Sampling: `temperature=1.0`, `top_p=0.95`
41
+ - Max generation: 163,840 tokens (math), 131,072 (GPQA); zero truncations occurred
42
+ - No thinking-effort override (server default thinking mode)
43
+ - Math prompts: Z.ai's system prompt (`Explanation: ... / Exact Answer: ... / Confidence: ...`)
44
+ - Math datasets: `MathArena/aime_2026`, `MathArena/hmmt_feb_2026`
45
+ - Math grading: `math-verify` symbolic equivalence (instead of Z.ai's GPT-5.5 judge);
46
+ fallback chain: "Exact Answer:" line → last `\boxed{}` → none
47
+ - GPQA: `Idavidrein/gpqa` (gpqa_diamond), simple-evals/Artificial-Analysis MCQ
48
+ template, answer options deterministically shuffled per (question, repeat) with
49
+ the same seeds as the hybrid run, regex letter extraction
50
+ - pass@1 computed over all repeats pooled
51
+
52
+ ## Incident note
53
+
54
+ Three requests stalled mid-run on dropped server connections (sockets stayed
55
+ ESTABLISHED client-side while the server no longer tracked the request). All
56
+ three hit the client's read timeout, auto-retried, and completed successfully —
57
+ zero lost or errored samples in the final data. Harness improvement for future
58
+ runs: TCP keepalives plus a tighter per-request timeout would surface this in
59
+ minutes instead of hours.
60
+
61
+ ## Reproducible quirks (both quants, likely model-level)
62
+
63
+ - HMMT Q20: a common reasoning path converges to the wrong answer `1100`
64
+ (gold `20460`) — both quants produced this identical wrong answer on some
65
+ repeats. EXL3 went 2-of-4 on this question.
66
+ - GPQA idx 79 (dataset order): triggers extreme reasoning chains (121k tokens
67
+ with format drift on the hybrid; clean 8.5k-token answer on EXL3 retry).
68
+
69
+ ## Files
70
+
71
+ - `*_summary.json` — per-benchmark settings, aggregate scores, per-question rates
72
+ - `*_samples.jsonl` — per-sample records: gold, prediction, correctness, finish
73
+ reason, completion tokens, wall seconds, final answer text (GPQA records carry
74
+ only the model's answer tail — no question text is reproduced, per the gated
75
+ dataset's terms)
76
+ - `mathbench.py`, `gpqa_bench.py`, `rerun_errors.py` — the harness (point
77
+ `--base-url` at any OpenAI-compatible endpoint; `--api-key` for bearer auth)
independent-eval/gpqa_bench.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """GPQA Diamond against an OpenAI-compatible endpoint, following AA's published
3
+ MCQ methodology (simple-evals style prompt, 'Answer: $LETTER' extraction,
4
+ deterministically shuffled choices). Reference: GLM-5.2 original = 91.2."""
5
+ import argparse
6
+ import asyncio
7
+ import json
8
+ import random
9
+ import re
10
+ import time
11
+ from pathlib import Path
12
+
13
+ from datasets import load_dataset
14
+ from openai import AsyncOpenAI
15
+
16
+ PROMPT_TMPL = (
17
+ "Answer the following multiple choice question. The last line of your response "
18
+ "should be of the following format: 'Answer: $LETTER' (without quotes) where "
19
+ "LETTER is one of ABCD. Think step by step before answering.\n\n"
20
+ "{question}\n\nA) {a}\nB) {b}\nC) {c}\nD) {d}"
21
+ )
22
+ ANSWER_RE = re.compile(r"(?i)answer\s*:\s*\*{0,2}\$?\(?\s*([A-D])\s*\)?")
23
+
24
+
25
+ def extract_letter(content: str):
26
+ hits = ANSWER_RE.findall(content)
27
+ return hits[-1].upper() if hits else None
28
+
29
+
30
+ async def run_one(client, sem, model, q, idx, rep, max_tokens, results, t0, total):
31
+ rng = random.Random(idx * 1000 + rep)
32
+ choices = [(q["Correct Answer"], True), (q["Incorrect Answer 1"], False),
33
+ (q["Incorrect Answer 2"], False), (q["Incorrect Answer 3"], False)]
34
+ rng.shuffle(choices)
35
+ gold_letter = "ABCD"[[c[1] for c in choices].index(True)]
36
+ prompt = PROMPT_TMPL.format(question=q["Question"], a=choices[0][0].strip(),
37
+ b=choices[1][0].strip(), c=choices[2][0].strip(), d=choices[3][0].strip())
38
+ async with sem:
39
+ last_err = None
40
+ for attempt in range(4):
41
+ try:
42
+ start = time.monotonic()
43
+ resp = await client.chat.completions.create(
44
+ model=model,
45
+ messages=[{"role": "user", "content": prompt}],
46
+ temperature=1.0, top_p=0.95, max_tokens=max_tokens,
47
+ )
48
+ secs = time.monotonic() - start
49
+ content = resp.choices[0].message.content or ""
50
+ pred = extract_letter(content)
51
+ ok = pred == gold_letter
52
+ rec = {"idx": idx, "repeat": rep, "gold": gold_letter, "pred": pred, "correct": ok,
53
+ "finish_reason": resp.choices[0].finish_reason,
54
+ "completion_tokens": resp.usage.completion_tokens if resp.usage else None,
55
+ "secs": round(secs, 1), "content_tail": content[-300:]}
56
+ results.append(rec)
57
+ done = len(results)
58
+ acc = sum(r["correct"] for r in results) / done
59
+ print(f"[{done}/{total}] idx={idx} rep={rep} {'OK ' if ok else 'MISS'} "
60
+ f"pred={pred} gold={gold_letter} tok={rec['completion_tokens']} {rec['secs']}s "
61
+ f"| acc={acc:.3f} | {(time.monotonic()-t0)/60:.1f}m", flush=True)
62
+ return
63
+ except Exception as e:
64
+ last_err = e
65
+ wait = 15 * (attempt + 1)
66
+ print(f"RETRY idx={idx} rep={rep} attempt={attempt+1}: {type(e).__name__}: {e}", flush=True)
67
+ await asyncio.sleep(wait)
68
+ results.append({"idx": idx, "repeat": rep, "gold": gold_letter, "pred": None, "correct": False,
69
+ "finish_reason": f"error:{last_err}", "completion_tokens": None, "secs": None,
70
+ "content_tail": ""})
71
+
72
+
73
+ async def main():
74
+ ap = argparse.ArgumentParser()
75
+ ap.add_argument("--base-url", default="http://localhost:8000/v1")
76
+ ap.add_argument("--api-key", default="dummy")
77
+ ap.add_argument("--served-root", default="madeby561/GLM-5.2-MXFP8-NVFP4-NF3-Hybrid")
78
+ ap.add_argument("--model", default="GLM-5.2")
79
+ ap.add_argument("--repeats", type=int, default=2)
80
+ ap.add_argument("--concurrency", type=int, default=6)
81
+ ap.add_argument("--max-tokens", type=int, default=131072)
82
+ ap.add_argument("--limit", type=int, default=0)
83
+ ap.add_argument("--out-dir", default="results")
84
+ args = ap.parse_args()
85
+
86
+ ds = load_dataset("Idavidrein/gpqa", "gpqa_diamond")
87
+ items = list(ds[list(ds.keys())[0]])
88
+ if args.limit:
89
+ items = items[: args.limit]
90
+
91
+ out_dir = Path(args.out_dir)
92
+ out_dir.mkdir(parents=True, exist_ok=True)
93
+ client = AsyncOpenAI(base_url=args.base_url, api_key=args.api_key, timeout=14400.0, max_retries=0)
94
+ sem = asyncio.Semaphore(args.concurrency)
95
+ results = []
96
+ total = len(items) * args.repeats
97
+ t0 = time.monotonic()
98
+ print(f"=== GPQA Diamond: {len(items)} questions x {args.repeats} repeats = {total} generations ===", flush=True)
99
+
100
+ await asyncio.gather(*[
101
+ run_one(client, sem, args.model, q, i, rep, args.max_tokens, results, t0, total)
102
+ for rep in range(args.repeats) for i, q in enumerate(items)
103
+ ])
104
+
105
+ with (out_dir / "gpqa_diamond_samples.jsonl").open("w") as f:
106
+ for r in sorted(results, key=lambda r: (r["repeat"], r["idx"])):
107
+ f.write(json.dumps(r) + "\n")
108
+ n = len(results)
109
+ toks = [r["completion_tokens"] for r in results if r["completion_tokens"]]
110
+ summary = {
111
+ "dataset": "Idavidrein/gpqa:gpqa_diamond", "model": args.model,
112
+ "served_root": args.served_root,
113
+ "settings": {"temperature": 1.0, "top_p": 0.95, "max_tokens": args.max_tokens,
114
+ "prompt": "AA/simple-evals MCQ template", "grader": "regex letter match"},
115
+ "n_questions": len(items), "repeats": args.repeats,
116
+ "accuracy_pass_at_1": round(sum(r["correct"] for r in results) / n, 4),
117
+ "no_answer_extracted": sum(1 for r in results if r["pred"] is None),
118
+ "truncated": sum(1 for r in results if r["finish_reason"] == "length"),
119
+ "errors": sum(1 for r in results if str(r["finish_reason"]).startswith("error")),
120
+ "avg_completion_tokens": round(sum(toks) / len(toks)) if toks else None,
121
+ "wall_minutes": round((time.monotonic() - t0) / 60, 1),
122
+ "reference_original_model": 91.2,
123
+ }
124
+ (out_dir / "gpqa_diamond_summary.json").write_text(json.dumps(summary, indent=2))
125
+ print(json.dumps(summary, indent=2), flush=True)
126
+
127
+
128
+ if __name__ == "__main__":
129
+ asyncio.run(main())
independent-eval/gpqa_diamond_summary.json ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "dataset": "Idavidrein/gpqa:gpqa_diamond",
3
+ "model": "GLM-5.2",
4
+ "served_root": "GLM-5.2-EXL3-TR3-3.0bpw",
5
+ "settings": {
6
+ "temperature": 1.0,
7
+ "top_p": 0.95,
8
+ "max_tokens": 131072,
9
+ "prompt": "AA/simple-evals MCQ template",
10
+ "grader": "regex letter match"
11
+ },
12
+ "n_questions": 198,
13
+ "repeats": 2,
14
+ "accuracy_pass_at_1": 0.9141,
15
+ "no_answer_extracted": 1,
16
+ "truncated": 0,
17
+ "errors": 0,
18
+ "avg_completion_tokens": 10561,
19
+ "wall_minutes": 955.6,
20
+ "reference_original_model": 91.2,
21
+ "per_question_correct_rate": {
22
+ "0": 1.0,
23
+ "1": 1.0,
24
+ "2": 1.0,
25
+ "3": 1.0,
26
+ "4": 1.0,
27
+ "5": 1.0,
28
+ "6": 1.0,
29
+ "7": 1.0,
30
+ "8": 1.0,
31
+ "9": 1.0,
32
+ "10": 1.0,
33
+ "11": 1.0,
34
+ "12": 1.0,
35
+ "13": 1.0,
36
+ "14": 1.0,
37
+ "15": 1.0,
38
+ "16": 1.0,
39
+ "17": 0.0,
40
+ "18": 1.0,
41
+ "19": 1.0,
42
+ "20": 1.0,
43
+ "21": 1.0,
44
+ "22": 1.0,
45
+ "23": 0.5,
46
+ "24": 1.0,
47
+ "25": 1.0,
48
+ "26": 1.0,
49
+ "27": 1.0,
50
+ "28": 1.0,
51
+ "29": 0.5,
52
+ "30": 0.0,
53
+ "31": 1.0,
54
+ "32": 0.5,
55
+ "33": 1.0,
56
+ "34": 1.0,
57
+ "35": 1.0,
58
+ "36": 1.0,
59
+ "37": 1.0,
60
+ "38": 0.5,
61
+ "39": 1.0,
62
+ "40": 1.0,
63
+ "41": 1.0,
64
+ "42": 1.0,
65
+ "43": 1.0,
66
+ "44": 1.0,
67
+ "45": 1.0,
68
+ "46": 1.0,
69
+ "47": 1.0,
70
+ "48": 1.0,
71
+ "49": 1.0,
72
+ "50": 1.0,
73
+ "51": 1.0,
74
+ "52": 1.0,
75
+ "53": 1.0,
76
+ "54": 1.0,
77
+ "55": 1.0,
78
+ "56": 1.0,
79
+ "57": 1.0,
80
+ "58": 1.0,
81
+ "59": 1.0,
82
+ "60": 1.0,
83
+ "61": 1.0,
84
+ "62": 1.0,
85
+ "63": 1.0,
86
+ "64": 1.0,
87
+ "65": 1.0,
88
+ "66": 1.0,
89
+ "67": 1.0,
90
+ "68": 1.0,
91
+ "69": 0.0,
92
+ "70": 1.0,
93
+ "71": 1.0,
94
+ "72": 1.0,
95
+ "73": 1.0,
96
+ "74": 1.0,
97
+ "75": 1.0,
98
+ "76": 0.0,
99
+ "77": 1.0,
100
+ "78": 1.0,
101
+ "79": 1.0,
102
+ "80": 1.0,
103
+ "81": 1.0,
104
+ "82": 1.0,
105
+ "83": 1.0,
106
+ "84": 1.0,
107
+ "85": 1.0,
108
+ "86": 1.0,
109
+ "87": 1.0,
110
+ "88": 0.5,
111
+ "89": 1.0,
112
+ "90": 0.5,
113
+ "91": 0.5,
114
+ "92": 1.0,
115
+ "93": 1.0,
116
+ "94": 1.0,
117
+ "95": 1.0,
118
+ "96": 1.0,
119
+ "97": 1.0,
120
+ "98": 1.0,
121
+ "99": 1.0,
122
+ "100": 1.0,
123
+ "101": 0.5,
124
+ "102": 1.0,
125
+ "103": 1.0,
126
+ "104": 1.0,
127
+ "105": 1.0,
128
+ "106": 0.0,
129
+ "107": 1.0,
130
+ "108": 1.0,
131
+ "109": 1.0,
132
+ "110": 1.0,
133
+ "111": 1.0,
134
+ "112": 1.0,
135
+ "113": 1.0,
136
+ "114": 1.0,
137
+ "115": 1.0,
138
+ "116": 1.0,
139
+ "117": 1.0,
140
+ "118": 1.0,
141
+ "119": 1.0,
142
+ "120": 1.0,
143
+ "121": 0.5,
144
+ "122": 1.0,
145
+ "123": 1.0,
146
+ "124": 1.0,
147
+ "125": 1.0,
148
+ "126": 1.0,
149
+ "127": 0.5,
150
+ "128": 1.0,
151
+ "129": 1.0,
152
+ "130": 0.5,
153
+ "131": 1.0,
154
+ "132": 1.0,
155
+ "133": 1.0,
156
+ "134": 1.0,
157
+ "135": 1.0,
158
+ "136": 1.0,
159
+ "137": 1.0,
160
+ "138": 1.0,
161
+ "139": 1.0,
162
+ "140": 0.5,
163
+ "141": 1.0,
164
+ "142": 0.5,
165
+ "143": 1.0,
166
+ "144": 1.0,
167
+ "145": 0.0,
168
+ "146": 1.0,
169
+ "147": 0.0,
170
+ "148": 1.0,
171
+ "149": 1.0,
172
+ "150": 1.0,
173
+ "151": 1.0,
174
+ "152": 1.0,
175
+ "153": 1.0,
176
+ "154": 1.0,
177
+ "155": 1.0,
178
+ "156": 1.0,
179
+ "157": 0.5,
180
+ "158": 1.0,
181
+ "159": 1.0,
182
+ "160": 0.0,
183
+ "161": 1.0,
184
+ "162": 1.0,
185
+ "163": 1.0,
186
+ "164": 1.0,
187
+ "165": 1.0,
188
+ "166": 1.0,
189
+ "167": 0.0,
190
+ "168": 1.0,
191
+ "169": 1.0,
192
+ "170": 1.0,
193
+ "171": 1.0,
194
+ "172": 1.0,
195
+ "173": 1.0,
196
+ "174": 1.0,
197
+ "175": 1.0,
198
+ "176": 1.0,
199
+ "177": 1.0,
200
+ "178": 1.0,
201
+ "179": 1.0,
202
+ "180": 1.0,
203
+ "181": 1.0,
204
+ "182": 1.0,
205
+ "183": 1.0,
206
+ "184": 1.0,
207
+ "185": 0.5,
208
+ "186": 0.5,
209
+ "187": 1.0,
210
+ "188": 1.0,
211
+ "189": 1.0,
212
+ "190": 1.0,
213
+ "191": 1.0,
214
+ "192": 1.0,
215
+ "193": 1.0,
216
+ "194": 1.0,
217
+ "195": 1.0,
218
+ "196": 1.0,
219
+ "197": 1.0
220
+ }
221
+ }
independent-eval/mathbench.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Replicate Z.ai's AIME/HMMT eval methodology against an OpenAI-compatible endpoint.
3
+
4
+ Methodology per zai-org/GLM-5.2 model card: temperature=1.0, top_p=0.95,
5
+ max generation 163840 tokens, Explanation/Exact Answer/Confidence system prompt.
6
+ Grading: math-verify symbolic match instead of an LLM judge.
7
+ """
8
+ import argparse
9
+ import asyncio
10
+ import json
11
+ import re
12
+ import time
13
+ from pathlib import Path
14
+
15
+ from datasets import load_dataset
16
+ from math_verify import parse as mv_parse, verify as mv_verify
17
+ from openai import AsyncOpenAI
18
+
19
+ SYSTEM_PROMPT = (
20
+ "Your response should be in the following format:\n"
21
+ "Explanation: {your explanation for your final answer}\n"
22
+ "Exact Answer: {your succinct, final answer}\n"
23
+ "Confidence: {your confidence score between 0% and 100% for your answer}."
24
+ )
25
+
26
+ BOXED_RE = re.compile(r"\\boxed\{([^{}]+(?:\{[^{}]*\}[^{}]*)*)\}")
27
+ EXACT_RE = re.compile(r"Exact Answer:\s*(.+?)(?:\n|Confidence:|$)", re.IGNORECASE | re.DOTALL)
28
+
29
+
30
+ def extract_answer(content: str):
31
+ m = EXACT_RE.search(content)
32
+ if m:
33
+ ans = m.group(1).strip().rstrip(".").strip("$ ").strip()
34
+ if ans:
35
+ return ans
36
+ boxed = BOXED_RE.findall(content)
37
+ if boxed:
38
+ return boxed[-1].strip()
39
+ return None
40
+
41
+
42
+ def grade(pred, gold) -> bool:
43
+ if pred is None:
44
+ return False
45
+ gold_s, pred_s = str(gold).strip(), str(pred).strip()
46
+ if pred_s == gold_s:
47
+ return True
48
+ try:
49
+ g = mv_parse(f"${gold_s}$")
50
+ p = mv_parse(f"${pred_s}$")
51
+ if g and p and mv_verify(g, p):
52
+ return True
53
+ except Exception:
54
+ pass
55
+ return False
56
+
57
+
58
+ async def run_one(client, sem, model, item, rep, max_tokens, results, t0, total):
59
+ async with sem:
60
+ last_err = None
61
+ for attempt in range(4):
62
+ try:
63
+ start = time.monotonic()
64
+ resp = await client.chat.completions.create(
65
+ model=model,
66
+ messages=[
67
+ {"role": "system", "content": SYSTEM_PROMPT},
68
+ {"role": "user", "content": item["problem"]},
69
+ ],
70
+ temperature=1.0,
71
+ top_p=0.95,
72
+ max_tokens=max_tokens,
73
+ )
74
+ secs = time.monotonic() - start
75
+ msg = resp.choices[0].message
76
+ content = msg.content or ""
77
+ reasoning = getattr(msg, "reasoning", None) or getattr(msg, "reasoning_content", None) or ""
78
+ pred = extract_answer(content)
79
+ ok = grade(pred, item["answer"])
80
+ rec = {
81
+ "problem_idx": item["problem_idx"],
82
+ "repeat": rep,
83
+ "gold": str(item["answer"]),
84
+ "pred": pred,
85
+ "correct": ok,
86
+ "finish_reason": resp.choices[0].finish_reason,
87
+ "completion_tokens": resp.usage.completion_tokens if resp.usage else None,
88
+ "secs": round(secs, 1),
89
+ "content": content,
90
+ "reasoning_head": reasoning[:500],
91
+ }
92
+ results.append(rec)
93
+ done = len(results)
94
+ acc = sum(r["correct"] for r in results) / done
95
+ elapsed = time.monotonic() - t0
96
+ print(
97
+ f"[{done}/{total}] idx={item['problem_idx']} rep={rep} "
98
+ f"{'OK ' if ok else 'MISS'} pred={pred!r} gold={item['answer']!r} "
99
+ f"tok={rec['completion_tokens']} {rec['secs']}s | running acc={acc:.3f} | elapsed={elapsed/60:.1f}m",
100
+ flush=True,
101
+ )
102
+ return rec
103
+ except Exception as e:
104
+ last_err = e
105
+ wait = 15 * (attempt + 1)
106
+ print(f"RETRY idx={item['problem_idx']} rep={rep} attempt={attempt+1}: {type(e).__name__}: {e} (sleep {wait}s)", flush=True)
107
+ await asyncio.sleep(wait)
108
+ rec = {"problem_idx": item["problem_idx"], "repeat": rep, "gold": str(item["answer"]),
109
+ "pred": None, "correct": False, "finish_reason": f"error:{last_err}",
110
+ "completion_tokens": None, "secs": None, "content": "", "reasoning_head": ""}
111
+ results.append(rec)
112
+ return rec
113
+
114
+
115
+ async def main():
116
+ ap = argparse.ArgumentParser()
117
+ ap.add_argument("--dataset", required=True)
118
+ ap.add_argument("--base-url", default="http://localhost:8000/v1")
119
+ ap.add_argument("--api-key", default="dummy")
120
+ ap.add_argument("--served-root", default="madeby561/GLM-5.2-MXFP8-NVFP4-NF3-Hybrid")
121
+ ap.add_argument("--model", default="GLM-5.2")
122
+ ap.add_argument("--repeats", type=int, default=4)
123
+ ap.add_argument("--concurrency", type=int, default=8)
124
+ ap.add_argument("--max-tokens", type=int, default=163840)
125
+ ap.add_argument("--limit", type=int, default=0)
126
+ ap.add_argument("--out-dir", default=".")
127
+ args = ap.parse_args()
128
+
129
+ ds = load_dataset(args.dataset)
130
+ split = list(ds.keys())[0]
131
+ items = list(ds[split])
132
+ if args.limit:
133
+ items = items[: args.limit]
134
+
135
+ tag = args.dataset.split("/")[-1]
136
+ out_dir = Path(args.out_dir)
137
+ out_dir.mkdir(parents=True, exist_ok=True)
138
+ samples_path = out_dir / f"{tag}_samples.jsonl"
139
+ summary_path = out_dir / f"{tag}_summary.json"
140
+
141
+ client = AsyncOpenAI(base_url=args.base_url, api_key=args.api_key, timeout=14400.0, max_retries=0)
142
+ sem = asyncio.Semaphore(args.concurrency)
143
+ results = []
144
+ total = len(items) * args.repeats
145
+ t0 = time.monotonic()
146
+ print(f"=== {args.dataset}: {len(items)} problems x {args.repeats} repeats = {total} generations ===", flush=True)
147
+
148
+ tasks = [
149
+ run_one(client, sem, args.model, item, rep, args.max_tokens, results, t0, total)
150
+ for rep in range(args.repeats)
151
+ for item in items
152
+ ]
153
+ await asyncio.gather(*tasks)
154
+
155
+ with samples_path.open("w") as f:
156
+ for r in sorted(results, key=lambda r: (r["repeat"], str(r["problem_idx"]))):
157
+ f.write(json.dumps(r) + "\n")
158
+
159
+ n = len(results)
160
+ acc = sum(r["correct"] for r in results) / n
161
+ toks = [r["completion_tokens"] for r in results if r["completion_tokens"]]
162
+ truncated = sum(1 for r in results if r["finish_reason"] == "length")
163
+ errors = sum(1 for r in results if str(r["finish_reason"]).startswith("error"))
164
+ per_q = {}
165
+ for r in results:
166
+ per_q.setdefault(str(r["problem_idx"]), []).append(r["correct"])
167
+ summary = {
168
+ "dataset": args.dataset,
169
+ "model": args.model,
170
+ "served_root": args.served_root,
171
+ "settings": {"temperature": 1.0, "top_p": 0.95, "max_tokens": args.max_tokens,
172
+ "system_prompt": "zai-explanation-exact-answer-confidence", "grader": "math-verify"},
173
+ "n_problems": len(items),
174
+ "repeats": args.repeats,
175
+ "accuracy_pass_at_1": round(acc, 4),
176
+ "truncated": truncated,
177
+ "errors": errors,
178
+ "avg_completion_tokens": round(sum(toks) / len(toks)) if toks else None,
179
+ "wall_minutes": round((time.monotonic() - t0) / 60, 1),
180
+ "per_question_correct_rate": {k: round(sum(v) / len(v), 3) for k, v in sorted(per_q.items(), key=lambda kv: kv[0])},
181
+ }
182
+ summary_path.write_text(json.dumps(summary, indent=2))
183
+ print(json.dumps(summary, indent=2), flush=True)
184
+
185
+
186
+ if __name__ == "__main__":
187
+ asyncio.run(main())
independent-eval/rerun_errors.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Re-run samples that died with exhausted retries (vLLM crash window) and merge
3
+ corrected records + summary. Works for both mathbench and gpqa samples files."""
4
+ import argparse
5
+ import asyncio
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ sys.path.insert(0, str(Path(__file__).parent))
11
+
12
+
13
+ async def main():
14
+ ap = argparse.ArgumentParser()
15
+ ap.add_argument("--samples", required=True, help="path to *_samples.jsonl")
16
+ ap.add_argument("--kind", choices=["math", "gpqa"], required=True)
17
+ ap.add_argument("--dataset", help="HF dataset name (math kind)", default=None)
18
+ ap.add_argument("--concurrency", type=int, default=6)
19
+ args = ap.parse_args()
20
+
21
+ path = Path(args.samples)
22
+ records = [json.loads(l) for l in path.open()]
23
+ bad = [r for r in records if str(r.get("finish_reason", "")).startswith("error")]
24
+ print(f"{path.name}: {len(records)} records, {len(bad)} error records to re-run")
25
+ if not bad:
26
+ return
27
+
28
+ import time
29
+ from openai import AsyncOpenAI
30
+ client = AsyncOpenAI(base_url="http://localhost:8000/v1", api_key="dummy", timeout=10800.0, max_retries=0)
31
+ sem = asyncio.Semaphore(args.concurrency)
32
+ results = []
33
+ t0 = time.monotonic()
34
+
35
+ if args.kind == "math":
36
+ from datasets import load_dataset
37
+ import mathbench as mb
38
+ ds = load_dataset(args.dataset)
39
+ items = {str(i["problem_idx"]): i for i in ds[list(ds.keys())[0]]}
40
+ total = len(bad)
41
+ await asyncio.gather(*[
42
+ mb.run_one(client, sem, "GLM-5.2", items[str(r["problem_idx"])], r["repeat"], 163840, results, t0, total)
43
+ for r in bad
44
+ ])
45
+ key = lambda r: (str(r["problem_idx"]), r["repeat"])
46
+ else:
47
+ from datasets import load_dataset
48
+ import gpqa_bench as gb
49
+ ds = load_dataset("Idavidrein/gpqa", "gpqa_diamond")
50
+ items = list(ds[list(ds.keys())[0]])
51
+ total = len(bad)
52
+ await asyncio.gather(*[
53
+ gb.run_one(client, sem, "GLM-5.2", items[r["idx"]], r["idx"], r["repeat"], 131072, results, t0, total)
54
+ for r in bad
55
+ ])
56
+ key = lambda r: (r["idx"], r["repeat"])
57
+
58
+ fixed = {key(r): r for r in results}
59
+ merged = [fixed.get(key(r), r) for r in records]
60
+ still_bad = sum(1 for r in merged if str(r.get("finish_reason", "")).startswith("error"))
61
+
62
+ backup = path.with_suffix(".jsonl.pre-fixup")
63
+ path.rename(backup)
64
+ with path.open("w") as f:
65
+ for r in merged:
66
+ f.write(json.dumps(r) + "\n")
67
+
68
+ n = len(merged)
69
+ acc = sum(r["correct"] for r in merged) / n
70
+ print(f"MERGED: {n} records, accuracy_pass_at_1={acc:.4f}, still_errored={still_bad}")
71
+ # patch summary file if present
72
+ sp = path.parent / path.name.replace("_samples.jsonl", "_summary.json")
73
+ if sp.exists():
74
+ s = json.loads(sp.read_text())
75
+ s["accuracy_pass_at_1"] = round(acc, 4)
76
+ s["errors"] = still_bad
77
+ s["crash_fixup"] = f"re-ran {len(bad)} samples killed by vLLM crash"
78
+ per_q = {}
79
+ idx_field = "problem_idx" if args.kind == "math" else "idx"
80
+ for r in merged:
81
+ per_q.setdefault(str(r[idx_field]), []).append(r["correct"])
82
+ s["per_question_correct_rate"] = {k: round(sum(v) / len(v), 3) for k, v in sorted(per_q.items())}
83
+ sp.write_text(json.dumps(s, indent=2))
84
+ print(f"summary updated: {sp}")
85
+
86
+
87
+ if __name__ == "__main__":
88
+ asyncio.run(main())
model-embed.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c83b92fcb91e1fe5c2ce10114685e91f768f4447b5c88b0fe8e2dee795001903
3
+ size 1903165584
model-head.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cd55f37f1aa08e1aa191da6a47594061ce340e75663cc770fdd26b57d0829a32
3
+ size 1903177952
model-layer-000.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:523923a15352a0706d2672ff5bcfa9a642813784aa5dd213087b10c1f1a7022c
3
+ size 801799648
model-layer-001.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bf2ede0905c731348a618137db81be2db2e7d69d0f43f645636214e8f12ded06
3
+ size 801799648
model-layer-002.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bf91373c594ddc930ebcfef98235a5e1189b6cd7838bf92a3b36a708d4bef45c
3
+ size 801799648
model-layer-003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d2ebb2f2d5077ae997ac0b3dff777ad53aa578430569e8e7a1e7be2f6ab1f707
3
+ size 4075006560
model-layer-004.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a0a558036106b6c2811309b217fd571b923cb7cd97f5713506090b143f261308
3
+ size 4075006560
model-layer-005.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7b9dd5f64a86b4cfddf2242350f7da5fa64f20a32def510b6192e88c43bc7c89
3
+ size 4075006560
model-layer-006.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ac996885eb92fdca3cc2003a1f0852cfffc2efc32dfa9cfaac9e14b241dee04
3
+ size 4093751088
model-layer-007.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:86d161e80133957b24de574c2159eefe72f68fef5729208aa21652b585517795
3
+ size 4075006560