mlx-bun 0.0.13 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. package/README.md +71 -578
  2. package/bin/mlx-bun.mjs +1 -1
  3. package/docs/README.md +91 -0
  4. package/docs/{design → archive}/hlg-sampling.md +3 -3
  5. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  6. package/docs/{design → archive/investigations}/colibri-glm52-port.md +1 -1
  7. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  8. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  9. package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
  10. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  11. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  12. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
  13. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  14. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  15. package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
  16. package/docs/{planning → archive/planning}/chunk-task-roadmap.md +1 -1
  17. package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +4 -4
  18. package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +1 -1
  19. package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
  20. package/docs/archive/planning/release-notes-v0.2.0.md +49 -0
  21. package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
  22. package/docs/design/batching.md +569 -0
  23. package/docs/design/decode-speed-program.md +3178 -169
  24. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  25. package/docs/design/generic-model-support.md +579 -334
  26. package/docs/design/kv-cache.md +680 -0
  27. package/docs/design/orpo-training.md +673 -1239
  28. package/docs/design/speculative-decoding.md +1627 -0
  29. package/docs/design/turboquant.md +2102 -0
  30. package/docs/design/unified-engine-frontier-plan.md +1831 -727
  31. package/docs/design/web-chat-redesign.md +666 -1083
  32. package/docs/planning/PRODUCT_ROADMAP.md +34 -1
  33. package/docs/planning/release-notes-v0.3.0.md +35 -0
  34. package/docs/planning/video-series.md +421 -0
  35. package/docs/reference/benchmarks.md +1162 -0
  36. package/docs/reference/cli.md +395 -149
  37. package/docs/reference/distribution.md +321 -181
  38. package/docs/reference/environment.md +348 -0
  39. package/docs/reference/glossary.md +39 -0
  40. package/docs/reference/library-api.md +580 -142
  41. package/docs/reference/memory.md +227 -64
  42. package/docs/reference/models.md +137 -6
  43. package/docs/reference/server-api.md +938 -422
  44. package/docs/reference/server-config.md +652 -320
  45. package/docs/reference/training.md +393 -254
  46. package/docs/reference/troubleshooting.md +166 -0
  47. package/package.json +10 -5
  48. package/src/admission-plan.ts +18 -0
  49. package/src/anthropic.ts +92 -3
  50. package/src/audio/decode.ts +2 -2
  51. package/src/audio/features.ts +2 -2
  52. package/src/backends/mlx/autoregressive.ts +108 -0
  53. package/src/backends/mlx/batch-group.ts +1646 -0
  54. package/src/backends/mlx/diffusion.ts +39 -0
  55. package/src/backends/mlx/draft-target.ts +47 -0
  56. package/src/backends/mlx/evaluation.ts +105 -0
  57. package/src/backends/mlx/fill-append.ts +45 -0
  58. package/src/backends/mlx/gateway-binding.ts +71 -0
  59. package/src/backends/mlx/graph.ts +38 -0
  60. package/src/backends/mlx/memory-client.ts +189 -0
  61. package/src/backends/mlx/memory-guard.ts +40 -0
  62. package/src/backends/mlx/methods.ts +90 -0
  63. package/src/backends/mlx/model-prompt.ts +164 -0
  64. package/src/backends/mlx/model-serving.ts +79 -0
  65. package/src/backends/mlx/prefill.ts +33 -0
  66. package/src/backends/mlx/request-policy.ts +20 -0
  67. package/src/backends/mlx/rollback.ts +51 -0
  68. package/src/backends/mlx/serial-executor.ts +273 -0
  69. package/src/backends/mlx/speculative.ts +114 -0
  70. package/src/backends/mlx/state-views.ts +26 -0
  71. package/src/backends/mlx/text-engine.ts +73 -0
  72. package/src/cli.ts +189 -61
  73. package/src/client.ts +66 -0
  74. package/src/config.ts +21 -4
  75. package/src/contracts/completion.ts +16 -0
  76. package/src/contracts/execution.ts +49 -0
  77. package/src/contracts/generation.ts +103 -0
  78. package/src/contracts/host.ts +7 -0
  79. package/src/contracts/jobs.ts +66 -0
  80. package/src/contracts/pi-provider.ts +30 -0
  81. package/src/contracts/pi.ts +259 -0
  82. package/src/contracts/resources.ts +18 -0
  83. package/src/contracts/scheduling.ts +27 -0
  84. package/src/contracts/tsconfig.json +14 -0
  85. package/src/diffusion/diffusion-generate.ts +218 -153
  86. package/src/embed.ts +1 -1
  87. package/src/engine/admission.ts +59 -0
  88. package/src/engine/cancellation.ts +38 -0
  89. package/src/engine/engine.ts +56 -0
  90. package/src/engine/execution-coordinator.ts +70 -0
  91. package/src/engine/execution-plan.ts +51 -0
  92. package/src/engine/resources.ts +42 -0
  93. package/src/engine/scheduler.ts +67 -0
  94. package/src/engine/session.ts +247 -0
  95. package/src/eval/README.md +44 -1
  96. package/src/eval/kl.ts +263 -23
  97. package/src/eval/reference-logits.ts +207 -0
  98. package/src/eval/runner.ts +10 -79
  99. package/src/eval/tasks/bfcl.ts +2 -1
  100. package/src/eval/tasks/gsm8k.ts +2 -1
  101. package/src/eval/tasks/hashhop.ts +2 -1
  102. package/src/eval/tasks/humaneval.ts +5 -4
  103. package/src/eval/tasks/ifeval.ts +2 -1
  104. package/src/eval/tasks/mmlu.ts +2 -1
  105. package/src/expert-io.ts +3 -1
  106. package/src/expert-offload.ts +3 -1
  107. package/src/fill/echo-index.ts +188 -0
  108. package/src/fill/fill-session.ts +452 -0
  109. package/src/fill/proposal.ts +68 -0
  110. package/src/fill/schema-rows.ts +506 -0
  111. package/src/fill/tool-boundary.ts +103 -0
  112. package/src/fit.ts +24 -43
  113. package/src/generate.ts +740 -337
  114. package/src/grammar.ts +14 -8
  115. package/src/harness-pi.ts +15 -34
  116. package/src/hub-rest.ts +4 -4
  117. package/src/index.ts +27 -0
  118. package/src/inference/denoising.ts +17 -0
  119. package/src/inference/graph.ts +33 -0
  120. package/src/inference/prefill.ts +39 -0
  121. package/src/inference/rollback.ts +7 -0
  122. package/src/jobs/db.ts +4 -0
  123. package/src/jobs/index.ts +2 -0
  124. package/src/jobs/job-entry.ts +15 -14
  125. package/src/jobs/runner.ts +98 -13
  126. package/src/jobs/task-client.ts +19 -0
  127. package/src/jobs/types.ts +2 -58
  128. package/src/kv-scheme.ts +199 -0
  129. package/src/kv-store.ts +459 -234
  130. package/src/lab/README.md +18 -0
  131. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  132. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  133. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +7 -5
  134. package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
  135. package/src/library.ts +40 -0
  136. package/src/lora.ts +18 -0
  137. package/src/media-fetch.ts +20 -4
  138. package/src/memory/article.ts +1 -1
  139. package/src/memory/chunk.ts +1 -1
  140. package/src/memory/model.ts +32 -170
  141. package/src/memory/prompts.ts +1 -1
  142. package/src/memory/rest.ts +1 -1
  143. package/src/memory/schedule.ts +1 -1
  144. package/src/memory/stages.ts +4 -1
  145. package/src/memory/vault.ts +3 -4
  146. package/src/mlx/array.ts +9 -10
  147. package/src/mlx/compile.ts +12 -2
  148. package/src/mlx/ffi.ts +66 -22
  149. package/src/mlx/materialize.ts +23 -0
  150. package/src/mlx/metal-kernel.ts +10 -11
  151. package/src/mlx/ops.ts +64 -19
  152. package/src/mlx/quantized-rows.ts +36 -0
  153. package/src/mlx/token-bitmask.ts +52 -0
  154. package/src/mlx/turboquant-kv-decode.ts +82 -0
  155. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  156. package/src/mlx/turboquant-ops.ts +33 -3
  157. package/src/mlx/turboquant-tables.ts +2 -2
  158. package/src/model/batched-mask.ts +9 -3
  159. package/src/model/batched-quant.ts +2 -2
  160. package/src/model/batched-rotating-quant.ts +45 -99
  161. package/src/model/batched-rotating-state.ts +73 -0
  162. package/src/model/batched-rotating.ts +57 -106
  163. package/src/model/batched-row-storage.ts +127 -0
  164. package/src/model/compiled-decode.ts +4 -3
  165. package/src/model/diffusion-gemma.ts +8 -8
  166. package/src/model/factory.ts +87 -49
  167. package/src/model/fingerprint.ts +1 -1
  168. package/src/model/flash-attention.ts +3 -3
  169. package/src/model/gemma4-base.ts +187 -17
  170. package/src/model/gemma4.ts +6 -6
  171. package/src/model/generated/gemma4-12b.ts +52 -148
  172. package/src/model/generated/gemma4-26b.ts +34 -94
  173. package/src/model/generated/gemma4-e4b.ts +28 -76
  174. package/src/model/glm52-cache.ts +19 -9
  175. package/src/model/glm52-dsa.ts +13 -9
  176. package/src/model/glm52-memory.ts +28 -1
  177. package/src/model/implementation.ts +69 -0
  178. package/src/model/minicpm5.ts +7 -8
  179. package/src/model/profile.ts +443 -0
  180. package/src/model/qwen-append.ts +12 -0
  181. package/src/model/qwen-conv.ts +52 -0
  182. package/src/model/qwen3-delta.ts +98 -2
  183. package/src/model/qwen3-mrope.ts +252 -0
  184. package/src/model/qwen3_5-checkpoint.ts +164 -0
  185. package/src/model/qwen3_5.ts +336 -60
  186. package/src/model/support.ts +1 -1
  187. package/src/model/trellis-balanced-scatter.ts +51 -0
  188. package/src/model/trellis-linear.ts +672 -0
  189. package/src/model/trellis-shared-m.ts +151 -0
  190. package/src/model/trellis-shared-scatter.ts +144 -0
  191. package/src/model/trellis-splitk-prefill.ts +158 -0
  192. package/src/model/trellis-tiled-prefill.ts +136 -0
  193. package/src/model/trellis-vector-expand.ts +62 -0
  194. package/src/model/trellis-wide-prefill.ts +94 -0
  195. package/src/model/universal/dense.ts +1 -1
  196. package/src/model/universal/modules.ts +8 -1
  197. package/src/native/frame_extract.swift +140 -0
  198. package/src/native-pack.ts +15 -7
  199. package/src/pi-provider.ts +6 -64
  200. package/src/pi-web.ts +14 -320
  201. package/src/prompt-cache.ts +97 -54
  202. package/src/quantize/allocator.ts +1 -1
  203. package/src/quantize/atomic-output.ts +38 -0
  204. package/src/quantize/calibration.ts +2 -1
  205. package/src/quantize/config-writer.ts +16 -3
  206. package/src/quantize/index.ts +28 -1
  207. package/src/quantize/job.ts +11 -0
  208. package/src/quantize/quantizer.ts +265 -100
  209. package/src/quantize/rotate.ts +603 -0
  210. package/src/quantize/safetensors-writer.ts +79 -1
  211. package/src/quantize/sensitivity.ts +41 -59
  212. package/src/quantize/trellis.ts +586 -0
  213. package/src/quantize/weight-transform.ts +292 -0
  214. package/src/responses.ts +130 -3
  215. package/src/runtime-config.ts +81 -0
  216. package/src/sampler.ts +276 -4
  217. package/src/serve/admin-routes.ts +184 -0
  218. package/src/serve/aux-routes.ts +132 -0
  219. package/src/serve/batch-scheduler.ts +8 -1558
  220. package/src/serve/chat-request.ts +391 -0
  221. package/src/serve/chat-stage.ts +195 -0
  222. package/src/serve/checkpoint-identity.ts +64 -0
  223. package/src/serve/completion-executor.ts +354 -0
  224. package/src/serve/completion-sink.ts +157 -0
  225. package/src/serve/discovery-routes.ts +204 -0
  226. package/src/serve/generation-gateway.ts +211 -243
  227. package/src/serve/http.ts +159 -0
  228. package/src/serve/inference-request.ts +79 -0
  229. package/src/serve/isolate.ts +297 -105
  230. package/src/serve/kv-budget.ts +14 -0
  231. package/src/serve/lab-routes.ts +341 -0
  232. package/src/serve/lane-registry.ts +2 -1
  233. package/src/serve/model-admin-routes.ts +155 -0
  234. package/src/serve/model-binding.ts +43 -0
  235. package/src/serve/model-host.ts +512 -0
  236. package/src/serve/openai-wire.ts +103 -0
  237. package/src/serve/parent-application.ts +56 -0
  238. package/src/serve/pipeline.ts +33 -0
  239. package/src/serve/preparation.ts +33 -0
  240. package/src/serve/prompt-response-trace.ts +147 -0
  241. package/src/serve/request-plan.ts +162 -0
  242. package/src/serve/request-prep.ts +346 -0
  243. package/src/serve/response-lease.ts +24 -0
  244. package/src/serve/responses-client.ts +69 -0
  245. package/src/serve/session-completion-engine.ts +110 -0
  246. package/src/serve/session-search.ts +1 -1
  247. package/src/serve/static-routes.ts +101 -0
  248. package/src/serve/text-completion-stage.ts +104 -0
  249. package/src/serve/token-streams.ts +519 -0
  250. package/src/server.ts +523 -3551
  251. package/src/spec/assistant-source.ts +10 -44
  252. package/src/spec/deepspec-source.ts +6 -6
  253. package/src/spec/dflash-source.ts +9 -8
  254. package/src/spec/dspark/ab-stats.ts +3 -3
  255. package/src/spec/dspark/calibration.ts +2 -2
  256. package/src/spec/dspark/deepspec-module.ts +2 -2
  257. package/src/spec/dspark/generate-dflash.ts +2 -2
  258. package/src/spec/dspark/generate.ts +2 -2
  259. package/src/spec/dspark/loader.ts +1 -1
  260. package/src/spec/dspark/module-dflash.ts +5 -4
  261. package/src/spec/dspark/module.ts +3 -3
  262. package/src/spec/dspark/quantize-drafter.ts +1 -1
  263. package/src/spec/generate.ts +1 -1
  264. package/src/spec/glm52-mtp-source.ts +9 -1
  265. package/src/spec/ngram-source.ts +1 -1
  266. package/src/spec/prefix-state.ts +45 -0
  267. package/src/spec/qwen-mtp-source.ts +528 -0
  268. package/src/spec/serve-loop.ts +179 -213
  269. package/src/spec/source.ts +42 -10
  270. package/src/spec/two-model.ts +1 -1
  271. package/src/ssd-cache.ts +95 -24
  272. package/src/ssd-durability.ts +207 -0
  273. package/src/tool-call.ts +51 -14
  274. package/src/train/flash-cce.ts +14 -13
  275. package/src/train/forward.ts +38 -1
  276. package/src/train/loss.ts +3 -2
  277. package/src/train/prefix-shared.ts +5 -1
  278. package/src/train/segmented.ts +9 -6
  279. package/src/train/trainer.ts +9 -8
  280. package/src/vision/preprocess.ts +1 -1
  281. package/src/vision/prompt.ts +48 -2
  282. package/src/vision/qwen3vl-preprocess.ts +409 -0
  283. package/src/vision/qwen3vl-prompt.ts +196 -0
  284. package/src/vision/qwen3vl-tower.ts +555 -0
  285. package/src/vision/video-frames.ts +148 -0
  286. package/src/web/app.html +1 -1
  287. package/src/web/app.js +15 -6
  288. package/src/web/src/adapters-panel.ts +3 -3
  289. package/src/web/src/assistant.ts +2 -36
  290. package/src/web/src/chat.ts +16 -9
  291. package/src/web/src/composer.ts +4 -4
  292. package/src/web/src/hub.ts +1 -1
  293. package/src/web/src/markdown.ts +0 -0
  294. package/src/web/src/memory-panel.ts +1 -1
  295. package/src/web/src/model-picker.ts +1 -1
  296. package/src/web/src/palette.ts +1 -1
  297. package/src/web/src/protocol.ts +3 -39
  298. package/src/web/src/sessions.ts +1 -1
  299. package/src/web/src/ui-catalog.ts +4 -18
  300. package/src/web-assets.ts +47 -0
  301. package/src/weights.ts +134 -33
  302. package/docs/archive/mlx-bun-lab-report.html +0 -275
  303. package/docs/archive/wwdc-mlx-bun.html +0 -848
  304. package/docs/design/adapters-end-to-end.md +0 -205
  305. package/docs/design/batching-perf-path.md +0 -255
  306. package/docs/design/batching-v2-plan.md +0 -529
  307. package/docs/design/bucketing-stage.md +0 -197
  308. package/docs/design/compat-cli-surface-design.md +0 -230
  309. package/docs/design/docs-reorg-plan.md +0 -165
  310. package/docs/design/dspark-serving-program.md +0 -371
  311. package/docs/design/dspark-speculative-decoding.md +0 -268
  312. package/docs/design/grammar-spec-batching-integration.md +0 -301
  313. package/docs/design/memory-inference-path.md +0 -422
  314. package/docs/design/memory-synthesis.md +0 -287
  315. package/docs/design/memory-system.md +0 -237
  316. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  317. package/docs/design/omlx-adoption-map.md +0 -98
  318. package/docs/design/orpo-dynamic-lambda.md +0 -220
  319. package/docs/design/orpo-future-enhancements.md +0 -340
  320. package/docs/design/paged-kv-cache.md +0 -214
  321. package/docs/design/parallel-slots.md +0 -567
  322. package/docs/design/parity-tier-dag.md +0 -161
  323. package/docs/design/repo-cleanup-plan.md +0 -189
  324. package/docs/design/runtime-isolation.md +0 -263
  325. package/docs/design/segmented-backward-training.md +0 -543
  326. package/docs/design/spec-decode-larger-targets.md +0 -229
  327. package/docs/design/ssd-kv-cold-tier.md +0 -288
  328. package/docs/design/structured-output.md +0 -484
  329. package/docs/design/tauri-desktop-app.md +0 -127
  330. package/docs/design/the-dreaming-master-plan.md +0 -445
  331. package/docs/design/turboquant-kv.md +0 -235
  332. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  333. package/docs/design/web-chat-beat-matrix.md +0 -315
  334. package/docs/design/write-pipeline-entity.md +0 -468
  335. package/docs/investigations/curve-runs/bisector-route.json +0 -98
  336. package/docs/investigations/curve-runs/bisector-trace.json +0 -1393
  337. package/docs/investigations/curve-runs/curve-terrain.json +0 -1179
  338. package/docs/investigations/curve-runs/curve-terrain.svg +0 -42
  339. package/docs/investigations/hlg-ab.html +0 -34
  340. package/docs/investigations/hlg-explorer.html +0 -238
  341. package/docs/investigations/hlg-figs/cliff.svg +0 -1
  342. package/docs/investigations/hlg-figs/cross.svg +0 -1
  343. package/docs/investigations/hlg-figs/edges.svg +0 -1
  344. package/docs/investigations/hlg-figs/k20-grids.svg +0 -1
  345. package/docs/investigations/hlg-figs/k20-peaks.svg +0 -1
  346. package/docs/investigations/hlg-figs/lw-curve.svg +0 -1
  347. package/docs/investigations/hlg-figs/terrain.svg +0 -1
  348. package/docs/investigations/hlg-report.html +0 -262
  349. package/docs/investigations/hlg-runs/hlg-ab.json +0 -149
  350. package/docs/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  351. package/docs/investigations/hlg-runs/hlg-blind.json +0 -107
  352. package/docs/investigations/hlg-runs/hlg-cliff.json +0 -197
  353. package/docs/investigations/hlg-runs/hlg-cross.json +0 -505
  354. package/docs/investigations/hlg-runs/hlg-edge.json +0 -388
  355. package/docs/investigations/hlg-runs/hlg-eval1.json +0 -25
  356. package/docs/investigations/hlg-runs/hlg-frontier.json +0 -86
  357. package/docs/investigations/hlg-runs/hlg-grid.json +0 -242
  358. package/docs/investigations/hlg-runs/hlg-grid2.json +0 -343
  359. package/docs/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  360. package/docs/investigations/hlg-runs/hlg-map.json +0 -383
  361. package/docs/investigations/hlg-runs/run0-original.log +0 -159
  362. package/docs/investigations/hlg-runs/runA-recommended.log +0 -131
  363. package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  364. package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  365. package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  366. package/docs/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  367. package/docs/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  368. package/docs/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  369. package/docs/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  370. package/docs/investigations/hlg-runs/runB-gain-variants.log +0 -192
  371. package/docs/investigations/hlg-runs/runC-pivots.log +0 -162
  372. package/docs/investigations/hlg-runs/runD-oetf.log +0 -132
  373. package/docs/investigations/hlg-runs/runE-eotf.log +0 -162
  374. package/docs/investigations/hlg-runs/runF-shaper-working.log +0 -86
  375. package/docs/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  376. package/docs/investigations/hlg-runs/runH-wsweep.log +0 -176
  377. package/docs/investigations/hlg-runs/runI-asweep.log +0 -176
  378. package/docs/investigations/hlg-runs/runJ-knobmap.log +0 -49
  379. package/docs/investigations/hlg-runs/runK-frontier.log +0 -19
  380. package/docs/investigations/hlg-runs/runL-widemap.log +0 -65
  381. package/docs/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  382. package/docs/investigations/hlg-runs/runN-verify.log +0 -116
  383. package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  384. package/docs/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  385. package/docs/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  386. package/docs/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  387. package/docs/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  388. package/docs/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  389. package/docs/investigations/hlg-runs/runU-cross-12b.log +0 -33
  390. package/docs/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  391. package/docs/investigations/hlg-runs/runW-lw-12b.log +0 -22
  392. package/docs/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  393. package/docs/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  394. package/docs/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  395. package/docs/planning/IDEAS.md +0 -69
  396. package/docs/reference/embedding.md +0 -197
  397. package/docs/reference/features-matrix.md +0 -100
  398. package/docs/reference/orpo-quickstart.md +0 -135
  399. package/src/flags.ts +0 -13
  400. /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
  401. /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
  402. /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
  403. /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
  404. /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
  405. /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
  406. /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
  407. /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
  408. /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
  409. /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
  410. /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
  411. /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
  412. /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
  413. /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
  414. /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
  415. /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
  416. /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
  417. /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
  418. /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
  419. /package/docs/{planning → archive/planning}/journal.md +0 -0
  420. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  421. /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
  422. /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
  423. /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
  424. /package/docs/{planning → archive/planning}/release-notes-v0.0.13.md +0 -0
  425. /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
  426. /package/{docs/investigations → src/serve/assets}/curve-terrain.html +0 -0
  427. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -0,0 +1,51 @@
1
+ import type { ExecutionCapabilities, ExecutionFeatures, ExecutionRequirements, ResolvedExecution } from "../contracts/execution";
2
+
3
+ /** Preserve the shipped support matrix. A configured draft still forces serial
4
+ * placement even when this request must use the ordinary AR method. */
5
+ export function resolveExecution(
6
+ request: ExecutionRequirements, capabilities: ExecutionCapabilities,
7
+ features: ExecutionFeatures = { pagedKv: false, fill: false },
8
+ ): ResolvedExecution {
9
+ const reasons: string[] = [];
10
+ const continuousExclusions = [
11
+ [!capabilities.continuous, "continuous-unavailable"],
12
+ [capabilities.method !== "autoregressive", "method-requires-serial"],
13
+ [request.hasVision, "media-requires-serial"],
14
+ [request.hasAdapters, "adapters-require-serial"],
15
+ [request.wantsLogprobs, "logprobs-require-serial"],
16
+ [request.userSeed, "explicit-seed-requires-serial"],
17
+ [request.kvQuant && !capabilities.quantizedBatch, "kv-scheme-requires-serial"],
18
+ [request.turboQuant, "turbo-kv-requires-serial"],
19
+ [request.hasDraft, "configured-draft-requires-serial"],
20
+ [request.hasGrammar && !capabilities.grammarBatch, "grammar-batching-disabled"],
21
+ [features.pagedKv, "paged-kv-requires-serial"],
22
+ ] as const;
23
+ for (const [excluded, reason] of continuousExclusions) if (excluded) reasons.push(reason);
24
+ const mechanism = reasons.length ? "serial" : "continuous";
25
+ const speculative = capabilities.method === "autoregressive" && request.hasDraft &&
26
+ !request.hasVision && !request.hasAdapters && !request.wantsLogprobs &&
27
+ (!request.kvQuant || capabilities.speculativeKvQuant === true) &&
28
+ !request.turboQuant && !features.pagedKv;
29
+ if (request.hasDraft && !speculative) reasons.push("draft-incompatible-with-request");
30
+ const method = speculative ? "speculative" : capabilities.method;
31
+ const pagedKv = features.pagedKv && !request.hasVision && !request.hasAdapters;
32
+ if (features.pagedKv && !pagedKv) reasons.push("paged-kv-bypassed-for-media-or-adapters");
33
+ const promptCache = method !== "speculative" && !request.hasVision && !pagedKv;
34
+ const fill = features.fill && method === "autoregressive" && mechanism === "serial" &&
35
+ !request.hasDraft && !request.hasVision && !request.userSeed && !request.hasGrammar &&
36
+ !request.wantsLogprobs && !request.kvQuant && !request.turboQuant;
37
+ if (features.fill && !fill) reasons.push("fill-incompatible-with-request");
38
+ const checkpoint = capabilities.checkpoints && method === "autoregressive" &&
39
+ mechanism === "serial" && promptCache && !request.hasGrammar &&
40
+ !features.fill && !request.wantsLogprobs;
41
+ const compiledDecode = features.compiledDecode === true && capabilities.compiledDecode === true &&
42
+ method === "autoregressive" && !request.hasAdapters && !pagedKv;
43
+ if (features.compiledDecode && !compiledDecode) reasons.push("compiled-decode-unavailable-for-request");
44
+ const grammarJump = features.grammarJump === true && request.hasGrammar &&
45
+ method === "autoregressive" && mechanism === "serial" && !request.wantsLogprobs;
46
+ if (features.grammarJump && request.hasGrammar && !grammarJump)
47
+ reasons.push("grammar-jump-incompatible-with-request");
48
+ return Object.freeze({ method, mechanism, pagedKv, promptCache, checkpoint, fill,
49
+ compiledDecode, grammarJump,
50
+ reasons: Object.freeze(reasons) });
51
+ }
@@ -0,0 +1,42 @@
1
+ import type { DisposableResource, ResourceOwner } from "../contracts/resources";
2
+
3
+ export function ownResource<T>(value: T, release: (value: T) => void): ResourceOwner<T> {
4
+ let held: { value: T } | undefined = { value };
5
+ const borrow = () => {
6
+ if (!held) throw new Error("resource ownership has ended");
7
+ return held.value;
8
+ };
9
+ return {
10
+ borrow,
11
+ transfer() { const result = borrow(); held = undefined; return result; },
12
+ close() {
13
+ if (!held) return;
14
+ const result = held.value;
15
+ held = undefined;
16
+ release(result);
17
+ },
18
+ };
19
+ }
20
+
21
+ /** Attempt every release once. One failed destructor must not leak siblings. */
22
+ export function disposeResources(resources: Iterable<DisposableResource>): void {
23
+ const errors: unknown[] = [];
24
+ for (const resource of new Set(resources)) {
25
+ try { resource.dispose(); } catch (error) { errors.push(error); }
26
+ }
27
+ if (errors.length === 1) throw errors[0];
28
+ if (errors.length) throw new AggregateError(errors, "resource cleanup failed");
29
+ }
30
+
31
+ /** Used at failure boundaries to retain the execution error as well as cleanup. */
32
+ export function cleanupFailure(error: unknown, cleanup: () => void): never {
33
+ try { cleanup(); }
34
+ catch (cleanupError) { throw new AggregateError([error, cleanupError], "execution and cleanup failed"); }
35
+ throw error;
36
+ }
37
+
38
+ export function withResource<T, R>(owner: Pick<ResourceOwner<T>, "borrow" | "close">, use: (value: T) => R): R {
39
+ try { return use(owner.borrow()); }
40
+ catch (error) { cleanupFailure(error, () => owner.close()); }
41
+ finally { owner.close(); }
42
+ }
@@ -0,0 +1,67 @@
1
+ import type { ExecutionGroup, SchedulingClock } from "../contracts/scheduling";
2
+ import { disposeResources } from "./resources";
3
+
4
+ /** Continuous scheduling policy. Each advance is a backend-defined safe unit;
5
+ * this driver neither handles native state nor forces pending work to evaluate. */
6
+ export async function driveExecutionGroup(
7
+ group: ExecutionGroup, clock: SchedulingClock, yieldAfterPreparation = false,
8
+ ): Promise<void> {
9
+ let execution: (() => void) | undefined;
10
+ let residency: (() => void) | undefined;
11
+ let lastYield = 0;
12
+ let terminalError: unknown = new Error("scheduler closed");
13
+ const release = () => {
14
+ const releases = [execution, residency];
15
+ execution = residency = undefined;
16
+ disposeResources(releases.filter((fn): fn is () => void => !!fn).map((dispose) => ({ dispose })));
17
+ };
18
+ try {
19
+ while (!group.closed) {
20
+ group.pruneCancelled();
21
+ const held = group.admissionHeld;
22
+ if (!group.active && !group.preparing && (held || !group.queued)) {
23
+ release();
24
+ await group.waitForWork();
25
+ continue;
26
+ }
27
+ residency ??= group.reserveResidency();
28
+ if (!execution && group.acquireExecution) execution = await group.acquireExecution();
29
+ if (group.closed) break;
30
+
31
+ if (!group.preparing && !held && group.queued && group.active < group.maxActive)
32
+ group.admitNext();
33
+ if (group.preparing) {
34
+ const activeBefore = group.active;
35
+ await group.advancePreparation();
36
+ // A backend may emit its first output while preparing the first row.
37
+ // Flush a lone admission before decode; queued short admissions still
38
+ // group together. Re-enter policy after yielding to observe new work,
39
+ // cancellation, admission holds and shutdown.
40
+ if (yieldAfterPreparation && !activeBefore && !group.preparing &&
41
+ group.active === 1 && !group.queued) {
42
+ lastYield = clock.now();
43
+ await clock.yield();
44
+ continue;
45
+ }
46
+ }
47
+
48
+ // Finish short admissions before decode; long preparation interleaves
49
+ // with active work because the group still reports preparing=true.
50
+ if (!group.preparing && !held && group.queued && group.active < group.maxActive && group.canBurst())
51
+ continue;
52
+ if (group.active) {
53
+ try { await group.advance(); }
54
+ catch (error) { group.failActive(error); }
55
+ }
56
+ // Preserve the serial responsiveness budget for the single active run.
57
+ if (group.active === 1 && !group.queued && !group.preparing &&
58
+ !group.admissionHeld && clock.now() - lastYield < 25) continue;
59
+ lastYield = clock.now();
60
+ await clock.yield();
61
+ }
62
+ } catch (error) {
63
+ terminalError = error;
64
+ } finally {
65
+ disposeResources([{ dispose: () => group.failAll(terminalError) }, { dispose: release }]);
66
+ }
67
+ }
@@ -0,0 +1,247 @@
1
+ import type {
2
+ Cancellation, CancelReason, ExecutionPlan, GenerationEvent, GenerationOutcome,
3
+ GenerationOutput, GenerationSession, MethodResult, MethodRun, RunControl,
4
+ SessionState, Timer, TokenLogprobs,
5
+ } from "../contracts/generation";
6
+ import { CancellationSource, throwIfCancelled } from "./cancellation";
7
+
8
+ export interface SessionResources {
9
+ readonly timer: Timer;
10
+ readonly idleTimeoutMs: number;
11
+ readonly maxQueuedEvents: number;
12
+ readonly maxQueuedTokens: number;
13
+ readonly maxTopLogprobs: number;
14
+ reserveOutput(tokens: number): { buffer: Uint32Array; release(): void };
15
+ }
16
+
17
+ /** Lifecycle and bounded delivery only. No graph, cache, sampler, or method branches. */
18
+ export class EngineSession<Metrics> implements GenerationSession<Metrics> {
19
+ readonly result: Promise<GenerationOutcome<Metrics>>;
20
+ readonly events: AsyncIterable<GenerationEvent>;
21
+ #state: SessionState = "created";
22
+ #cancel = new CancellationSource();
23
+ #settle!: (outcome: GenerationOutcome<Metrics>) => void;
24
+ #started = false;
25
+ #readerClaimed = false;
26
+ #reading = false;
27
+ #publishing = false;
28
+ #queue: GenerationEvent[] = [];
29
+ #queuedTokens = 0;
30
+ #committed = 0;
31
+ #sequence = 0;
32
+ #wakeReader: (() => void) | undefined;
33
+ #wakeProducer: (() => void) | undefined;
34
+ #stopTimer: (() => void) | undefined;
35
+ #unsubscribe: (() => void) | undefined;
36
+ #buffer: Uint32Array | undefined;
37
+ #limit = 0;
38
+ #outputStopped = false;
39
+
40
+ constructor(
41
+ readonly id: string,
42
+ private readonly prepare: (cancellation: Cancellation) => Promise<ExecutionPlan<Metrics>>,
43
+ private readonly control: RunControl,
44
+ private readonly resources: SessionResources,
45
+ private readonly onTerminal: () => void,
46
+ ) {
47
+ this.result = new Promise((resolve) => { this.#settle = resolve; });
48
+ this.events = { [Symbol.asyncIterator]: () => this.#iterator() };
49
+ const unsubscribe = control.cancellation?.subscribe((reason) => { void this.cancel(reason); });
50
+ if (this.#state === "terminal") unsubscribe?.();
51
+ else this.#unsubscribe = unsubscribe;
52
+ if (this.#state !== "terminal") {
53
+ if (control.output !== "stream") this.#start();
54
+ else this.#armIdle();
55
+ }
56
+ }
57
+
58
+ get state(): SessionState { return this.#state; }
59
+
60
+ async cancel(reason: CancelReason = "requested"): Promise<void> {
61
+ if (this.#state !== "terminal") {
62
+ this.#cancel.cancel(reason);
63
+ this.#queue = [];
64
+ this.#queuedTokens = 0;
65
+ this.#wakeReader?.();
66
+ this.#wakeProducer?.();
67
+ this.#stopTimer?.();
68
+ if (!this.#started) this.#finish({ status: "cancelled", reason, committedTokens: 0 });
69
+ }
70
+ await this.result;
71
+ }
72
+
73
+ close(): Promise<void> { return this.cancel("consumer_closed"); }
74
+
75
+ #armIdle(): void {
76
+ this.#stopTimer?.();
77
+ this.#stopTimer = this.resources.timer.after(this.resources.idleTimeoutMs,
78
+ () => { void this.cancel("consumer_idle"); });
79
+ }
80
+
81
+ #iterator(): AsyncIterator<GenerationEvent> {
82
+ if (this.control.output !== "stream") throw new Error("collect sessions return output through result");
83
+ if (this.#readerClaimed) throw new Error("generation events have one consumer");
84
+ this.#readerClaimed = true;
85
+ return {
86
+ next: async () => {
87
+ if (this.#reading) throw new Error("concurrent next() is not supported");
88
+ this.#reading = true;
89
+ this.#stopTimer?.();
90
+ try {
91
+ this.#start();
92
+ while (!this.#queue.length && this.#state !== "terminal") {
93
+ await new Promise<void>((resolve) => { this.#wakeReader = resolve; });
94
+ this.#wakeReader = undefined;
95
+ }
96
+ const event = this.#queue.shift();
97
+ if (!event) return { done: true, value: undefined };
98
+ if (event.type === "committed") this.#queuedTokens -= event.tokenIds.length;
99
+ this.#wakeProducer?.();
100
+ if (this.#state !== "terminal") this.#armIdle();
101
+ return { done: false, value: event };
102
+ } finally { this.#reading = false; }
103
+ },
104
+ return: async () => { await this.close(); return { done: true, value: undefined }; },
105
+ throw: async (error) => { await this.close(); throw error; },
106
+ };
107
+ }
108
+
109
+ #start(): void {
110
+ if (this.#started || this.#state === "terminal") return;
111
+ this.#started = true;
112
+ void this.#execute();
113
+ }
114
+
115
+ async #execute(): Promise<void> {
116
+ let run: MethodRun<Metrics> | undefined;
117
+ let reservation: ReturnType<SessionResources["reserveOutput"]> | undefined;
118
+ let result: MethodResult<Metrics> | undefined;
119
+ let failure: unknown;
120
+ let failed = false;
121
+ try {
122
+ this.#state = "preparing";
123
+ throwIfCancelled(this.#cancel);
124
+ const plan = await this.prepare(this.#cancel);
125
+ throwIfCancelled(this.#cancel);
126
+ if (!Number.isSafeInteger(plan.outputTokenLimit) || plan.outputTokenLimit < 0)
127
+ throw new Error("invalid planned output token limit");
128
+ this.#limit = plan.outputTokenLimit;
129
+ if (this.control.output === "collect") {
130
+ reservation = this.resources.reserveOutput(this.#limit);
131
+ this.#buffer = reservation.buffer;
132
+ }
133
+ run = await plan.method.createRun(this.#cancel);
134
+ throwIfCancelled(this.#cancel);
135
+ this.#state = "running";
136
+ const output: GenerationOutput = {
137
+ commit: (ids, logprobs) => this.#publish(ids, logprobs),
138
+ progress: (completed, total) => this.#progress(completed, total),
139
+ };
140
+ result = await run.execute(output, this.#cancel);
141
+ } catch (error) { failure = error; failed = true; }
142
+ this.#state = "settling";
143
+ // Terminal means resources are safe to release, not merely that JS stopped reading.
144
+ let cleanupFailed = false;
145
+ let cleanupError: string | undefined;
146
+ try { await run?.close(); }
147
+ catch (error) {
148
+ cleanupError = error instanceof Error ? error.message : String(error);
149
+ if (!failed) failure = error;
150
+ failed = true;
151
+ cleanupFailed = true;
152
+ }
153
+ reservation?.release(); // Completed output ownership transfers to the caller.
154
+ const common = { committedTokens: this.#committed,
155
+ ...(this.#buffer ? { output: this.#buffer.subarray(0, this.#committed) } : {}) };
156
+ if (this.#cancel.reason && !cleanupFailed) {
157
+ this.#finish({ status: "cancelled", reason: this.#cancel.reason, ...common });
158
+ } else if (failed) {
159
+ this.#finish({ status: "failed", error: { code: cleanupFailed ? "cleanup_failed" : "execution_failed",
160
+ message: failure instanceof Error ? failure.message : String(failure),
161
+ ...(cleanupError === undefined ? {} : { cleanupError }) }, ...common });
162
+ } else {
163
+ this.#finish({ status: "completed", result: result!, ...common });
164
+ }
165
+ }
166
+
167
+ async #publish(ids: readonly number[], logprobs?: readonly (TokenLogprobs | undefined)[]): Promise<void | false> {
168
+ if (this.#publishing) throw new Error("method must await each publication");
169
+ this.#publishing = true;
170
+ try {
171
+ throwIfCancelled(this.#cancel);
172
+ if (this.#state !== "running") throw new Error("publication outside method execution");
173
+ if (this.#outputStopped) throw new Error("method published after the consumer requested a stop");
174
+ if (ids.length > this.#limit - this.#committed) throw new Error("method exceeded planned output limit");
175
+ if (logprobs && logprobs.length !== ids.length) throw new Error("logprobs must align with committed tokens");
176
+ if (logprobs?.some((item) => (item?.top?.length ?? 0) > this.resources.maxTopLogprobs))
177
+ throw new Error("top logprobs exceed session delivery capacity");
178
+ for (const id of ids)
179
+ if (!Number.isInteger(id) || id < 0 || id > 0xffffffff) throw new Error("invalid committed token id");
180
+ if (this.control.output === "callback") {
181
+ this.#committed += ids.length;
182
+ const result = await this.control.onTokens(ids, logprobs);
183
+ if (result === false) this.#outputStopped = true;
184
+ return result;
185
+ }
186
+ if (this.#buffer) {
187
+ if (logprobs) throw new Error("token logprobs require stream consumption");
188
+ this.#buffer.set(ids, this.#committed);
189
+ this.#committed += ids.length;
190
+ return;
191
+ }
192
+ for (let offset = 0; offset < ids.length;) {
193
+ const length = Math.min(ids.length - offset, this.resources.maxQueuedTokens);
194
+ await this.#space(length);
195
+ // Snapshot producer-owned arrays; later scratch-buffer reuse cannot alter events.
196
+ const event: GenerationEvent = { type: "committed", sequence: this.#sequence++,
197
+ tokenIds: ids.slice(offset, offset + length),
198
+ ...(logprobs ? { logprobs: logprobs.slice(offset, offset + length).map((item) => item && ({
199
+ ...(item.logprob === undefined ? {} : { logprob: item.logprob }),
200
+ ...(item.top ? { top: item.top.map((entry) => ({ id: entry.id, logprob: entry.logprob })) } : {}),
201
+ })) } : {}) };
202
+ this.#queue.push(event);
203
+ this.#queuedTokens += length;
204
+ this.#committed += length;
205
+ offset += length;
206
+ this.#wakeReader?.();
207
+ }
208
+ } finally { this.#publishing = false; }
209
+ }
210
+
211
+ async #progress(completed: number, total?: number): Promise<void> {
212
+ if (this.#publishing) throw new Error("method must await each publication");
213
+ this.#publishing = true;
214
+ try {
215
+ throwIfCancelled(this.#cancel);
216
+ if (this.#state !== "running") throw new Error("publication outside method execution");
217
+ if (!Number.isFinite(completed) || completed < 0 ||
218
+ (total !== undefined && (!Number.isFinite(total) || total < completed)))
219
+ throw new Error("invalid progress");
220
+ if (this.control.output !== "stream") return;
221
+ await this.#space(0);
222
+ this.#queue.push({ type: "progress", completed, ...(total === undefined ? {} : { total }) });
223
+ this.#wakeReader?.();
224
+ } finally { this.#publishing = false; }
225
+ }
226
+
227
+ async #space(tokens: number): Promise<void> {
228
+ while (this.#queue.length >= this.resources.maxQueuedEvents ||
229
+ this.#queuedTokens + tokens > this.resources.maxQueuedTokens) {
230
+ throwIfCancelled(this.#cancel);
231
+ this.#armIdle();
232
+ await new Promise<void>((resolve) => { this.#wakeProducer = resolve; });
233
+ this.#wakeProducer = undefined;
234
+ }
235
+ throwIfCancelled(this.#cancel);
236
+ }
237
+
238
+ #finish(outcome: GenerationOutcome<Metrics>): void {
239
+ if (this.#state === "terminal") return;
240
+ this.#state = "terminal";
241
+ this.#stopTimer?.();
242
+ this.#unsubscribe?.();
243
+ this.#settle(outcome);
244
+ this.#wakeReader?.();
245
+ this.onTerminal();
246
+ }
247
+ }
@@ -29,6 +29,45 @@ repo rule: free-running greedy "measures chaos").
29
29
  `KL(compat ‖ fused)` is literally "measure the output difference."
30
30
  - **two-model (optiq-style absolute quality):** a separate reference model
31
31
  (bf16 if it fits, else uniform-4bit), both resident.
32
+ - **saved-teacher (`--reference-logits <dir>`):** the reference is a
33
+ **dump on disk**, not a resident model — the only way to score against a
34
+ bf16 teacher on 32 GB. A Python-side script forwards the teacher once and
35
+ writes, per teacher-forced position, the top-2048 logits plus the
36
+ **full-vocab logsumexp**; every candidate is then scored through OUR
37
+ engine. Format (`format_version` 1, read by `reference-logits.ts`):
38
+
39
+ ```
40
+ runs/kl-teacher/<tag>/
41
+ manifest.json {format_version, model, corpus_sha256, ctx_len, n_seqs,
42
+ top_k, positions_per_seq, created, notes}
43
+ tokens.bin int32 LE [n_seqs][ctx_len]
44
+ seq-<i>.bin record r (r = 0…ctx_len-2, the distribution over token
45
+ r+1, i.e. candidate POSITION r):
46
+ int32[top_k] indices, descending by logit
47
+ float16[top_k] reference logits
48
+ float32 full-vocab logsumexp
49
+ ```
50
+
51
+ `KL = Σ_{j∈topK} p_j·(log p_j − log q_j)`, `p_j = exp(ref_j − ref_lse)`,
52
+ `log q_j = cand_j − logsumexp(cand, full vocab)`, float32 throughout.
53
+ The sum is truncated to top-k, so the run also reports **captured mass**
54
+ `Σ_j p_j` (how much of `p` the number covers — a low-mass run is not a
55
+ comparable KL) and **top-1 agreement** (argmax over the full vocab).
56
+ The forward is the SERVING path (`makeCache` + chunked `forwardHidden` +
57
+ `logitsFromHidden` per chunk, `--chunk` positions at a time so a 4k
58
+ context's full-vocab logits never exist at once), **not** `trainForward` —
59
+ which is why this works on qwen3_5, where `mlx-bun perplexity` cannot go
60
+ (docs/design/turboquant.md, "Known engine gaps"). KV stays bf16: this is a
61
+ weights-only instrument.
62
+
63
+ Noise floor (measured, M1 Max, Qwen3.5-0.8B-OptiQ-4bit, 2×128 ctx,
64
+ top-64): scoring a dump against the model that produced it gives KL
65
+ **exactly 0** at the same `--chunk`, and mean 9.3e-6 / p95 8.3e-7 across
66
+ chunk 64 → 40. float16 storage is lossless for a bf16 teacher (bf16's
67
+ 7 mantissa bits fit float16's 10, and logits sit far inside float16's
68
+ 65504 range), so the residual is only the engine's own L-dependent bf16
69
+ rounding — the same effect that makes prefill chunk size ulp-visible
70
+ (`generate.ts`, prefill-tail-split). Compare candidates at one `--chunk`.
32
71
 
33
72
  ## Run (on a cleared machine — loads models, not from an agent session)
34
73
 
@@ -42,6 +81,10 @@ bun scripts/eval.ts kl --candidate e4b --self MLX_BUN_NO_FUSED_SDPA --ref-value
42
81
  # optiq-style absolute drift vs a reference model:
43
82
  bun scripts/eval.ts kl --candidate e4b --reference <bf16-or-4bit-id>
44
83
 
84
+ # vs a saved bf16 teacher-logits dump (--n caps sequences, --chunk positions
85
+ # per forward; the dump brings its own corpus, so --prompts-file/--seq don't apply):
86
+ bun scripts/eval.ts kl --candidate <model> --reference-logits runs/kl-teacher/<tag>
87
+
45
88
  # higher-fidelity prompts (optiq's calibration mix):
46
89
  bun scripts/eval.ts kl --candidate e4b --prompts-file \
47
90
  /Users/joshrossi/Code/mlx-lm/.venv/.../optiq/calibration/data/optiq.jsonl
@@ -71,7 +114,7 @@ the throughput `runs` table). Each row records the active perf levers
71
114
  perf levers (NO_FUSED_SDPA) actually bite.
72
115
  - **M1 (done):** all six capability tasks ported + runtime-validated, plus
73
116
  `capability` aggregation and the `smoketest` (KL + GSM8K-50) gate. Datasets
74
- exported by `scripts/eval/export-datasets.py` → `~/.cache/mlx-bun/eval-data/`.
117
+ exported by `scripts/oracle/export-datasets.py` → `~/.cache/mlx-bun/eval-data/`.
75
118
  Tasks run through the real quantized-KV path (`runner.ts`). HumanEval executes
76
119
  in a sandbox-exec + venv-python subprocess; HashHop reconstructs Magic AI's
77
120
  generator (`MultiHopEval` isn't on PyPI). **Open quality checks** (need a real