mlx-bun 0.4.0 → 1.0.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.
- package/README.md +1453 -88
- package/THIRD_PARTY_NOTICES.md +882 -0
- package/bin/mlx-bun.convert.mjs +4 -0
- package/bin/mlx-bun.fuse.mjs +4 -0
- package/bin/mlx-bun.generate.mjs +4 -0
- package/bin/mlx-bun.lora.mjs +4 -0
- package/bin/mlx-bun.mjs +13 -21
- package/bin/mlx-bun.server.mjs +4 -0
- package/bin/mlx-bun.upload.mjs +4 -0
- package/dist/web/app.js +9584 -0
- package/package.json +50 -53
- package/src/cli/ane-install.ts +76 -0
- package/src/cli/args.ts +179 -0
- package/src/cli/engine-entry.ts +68 -0
- package/src/cli/inference.ts +214 -0
- package/src/cli/job-entry.ts +97 -0
- package/src/cli/library-host.ts +117 -0
- package/src/cli/main.ts +57 -0
- package/src/cli/memory-engine.ts +163 -0
- package/src/cli/memory.ts +36 -0
- package/src/cli/mlx-lm-aliases.ts +309 -0
- package/src/cli/model-choice.ts +33 -0
- package/src/cli/model-selection.ts +84 -0
- package/src/cli/module-host.ts +11 -0
- package/src/cli/module-verbs.ts +50 -0
- package/src/cli/numerical-policy.ts +12 -0
- package/src/cli/perplexity.ts +89 -0
- package/src/cli/serve-host.ts +423 -0
- package/src/cli/serve-isolated.ts +217 -0
- package/src/cli/serve-options.ts +106 -0
- package/src/cli/serve-state.ts +205 -0
- package/src/cli/serve.ts +500 -0
- package/src/cli/served-model-host.ts +102 -0
- package/src/cli/server-entry.ts +148 -0
- package/src/cli/serving-unit.ts +177 -0
- package/src/{tui.ts → cli/terminal.ts} +13 -8
- package/src/cli/worker-adapters.ts +34 -0
- package/src/cli/worker-entry.ts +272 -0
- package/src/cli/worker-unit.ts +179 -0
- package/src/engine/adapter-operation.ts +26 -0
- package/src/engine/cache-services.ts +114 -0
- package/src/engine/completion.ts +39 -0
- package/src/engine/generation-gateway.ts +358 -0
- package/src/engine/index.ts +59 -0
- package/src/engine/kv-budget.ts +120 -0
- package/src/engine/media-preparation.ts +232 -0
- package/src/engine/model-binding.ts +24 -0
- package/src/engine/model-host.ts +513 -0
- package/src/engine/model-serving.ts +89 -0
- package/src/{serve → engine}/preparation.ts +10 -8
- package/src/{serve → engine}/session-completion-engine.ts +6 -6
- package/src/engine/telemetry.ts +109 -0
- package/src/hub/downloads.ts +116 -0
- package/src/jobs/db.ts +16 -7
- package/src/jobs/events.ts +29 -0
- package/src/jobs/executable.ts +5 -0
- package/src/jobs/host.ts +51 -0
- package/src/jobs/in-process.ts +55 -0
- package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
- package/src/jobs/runner.ts +150 -231
- package/src/jobs/service.ts +75 -0
- package/src/jobs/sse.ts +59 -23
- package/src/jobs/worker-memory.ts +46 -0
- package/src/jobs/worker-process.ts +163 -0
- package/src/jobs/worker-supervisor.ts +258 -0
- package/src/modules.ts +58 -0
- package/src/publishing/catalog-hub.ts +18 -0
- package/src/publishing/credentials.ts +31 -0
- package/src/publishing/upload.ts +37 -0
- package/src/residency/leased-adapters.ts +21 -0
- package/src/residency/local-records.ts +16 -0
- package/src/residency/model-residency.ts +405 -0
- package/src/residency/record-index.ts +28 -0
- package/src/residency/resident-estimate.ts +50 -0
- package/src/{anthropic.ts → server/anthropic.ts} +3 -81
- package/src/server/cache-routes.ts +36 -0
- package/src/{serve → server}/chat-request.ts +12 -10
- package/src/{serve → server}/chat-stage.ts +27 -22
- package/src/{client.ts → server/client.ts} +28 -2
- package/src/{serve → server}/completion-executor.ts +42 -42
- package/src/server/decision-body.ts +55 -0
- package/src/server/decision-routes.ts +134 -0
- package/src/server/decision-wire.ts +228 -0
- package/src/{serve → server}/discovery-routes.ts +42 -83
- package/src/server/generated-token-history.ts +57 -0
- package/src/{serve → server}/http.ts +25 -13
- package/src/{serve → server}/inference-request.ts +5 -5
- package/src/server/job-routes.ts +20 -0
- package/src/server/media-prompt.ts +63 -0
- package/src/server/memory-completion-client.ts +46 -0
- package/src/server/model-routes.ts +192 -0
- package/src/{serve → server}/openai-wire.ts +3 -2
- package/src/{serve → server}/pipeline.ts +1 -1
- package/src/server/prompt-builder.ts +13 -0
- package/src/server/prompt-contracts.ts +17 -0
- package/src/server/proxy-routes.ts +187 -0
- package/src/server/publishing-routes.ts +41 -0
- package/src/{serve → server}/request-plan.ts +8 -8
- package/src/{serve → server}/request-prep.ts +82 -68
- package/src/{serve → server}/responses-client.ts +30 -13
- package/src/{responses.ts → server/responses.ts} +12 -93
- package/src/server/routes.ts +205 -0
- package/src/server/start.ts +72 -0
- package/src/server/status-routes.ts +108 -0
- package/src/{serve → server}/text-completion-stage.ts +25 -4
- package/src/server/text-prompt.ts +12 -0
- package/src/{serve → server}/token-streams.ts +36 -38
- package/src/server/worker-routes.ts +311 -0
- package/src/storage/paths.ts +61 -0
- package/src/web/assets.ts +37 -0
- package/src/web/{src → browser}/api.ts +5 -23
- package/src/web/browser/chat-host.ts +17 -0
- package/src/web/browser/installed-panels.ts +6 -0
- package/src/web/browser/main.ts +55 -0
- package/src/web/browser/markdown.ts +279 -0
- package/src/web/browser/memory-panel.ts +9 -0
- package/src/web/browser/palette.ts +64 -0
- package/src/web/browser/protocol.ts +13 -0
- package/src/web/browser/shell.ts +467 -0
- package/src/web/{src → browser}/status.ts +32 -36
- package/src/web/build.ts +51 -0
- package/src/web/public/app.html +1054 -0
- package/src/web/{sw.js → public/sw.js} +4 -3
- package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
- package/src/web/{vendor → public/vendor}/hljs.js +2 -2
- package/THIRD_PARTY_LICENSES.md +0 -51
- package/docs/README.md +0 -94
- package/docs/archive/hlg-sampling.md +0 -350
- package/docs/archive/investigations/audio-input-plan.md +0 -356
- package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
- package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
- package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
- package/docs/archive/investigations/curve-bisector-routing.md +0 -123
- package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
- package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
- package/docs/archive/investigations/dspark-handoff.md +0 -224
- package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
- package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
- package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
- package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
- package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
- package/docs/archive/investigations/lab-build-journal.md +0 -157
- package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
- package/docs/archive/investigations/openjarvis-fit.md +0 -198
- package/docs/archive/investigations/openwiki-evaluation.md +0 -249
- package/docs/archive/investigations/optimization_plan.md +0 -346
- package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
- package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
- package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
- package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
- package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
- package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
- package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
- package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
- package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
- package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
- package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
- package/docs/archive/planning/chat-ui-vision.md +0 -50
- package/docs/archive/planning/chunk-task-roadmap.md +0 -77
- package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
- package/docs/archive/planning/journal.md +0 -316
- package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
- package/docs/archive/planning/pi-integration-review.md +0 -178
- package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
- package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
- package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
- package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
- package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
- package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
- package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
- package/docs/archive/planning/web-ui-pass-plan.md +0 -213
- package/docs/archive/planning/website-readme-pass-plan.md +0 -224
- package/docs/design/batching.md +0 -1841
- package/docs/design/decode-speed-program.md +0 -2349
- package/docs/design/dreaming-nightly-pipeline.md +0 -684
- package/docs/design/generic-model-support.md +0 -705
- package/docs/design/kv-cache.md +0 -824
- package/docs/design/orpo-training.md +0 -680
- package/docs/design/speculative-decoding.md +0 -1990
- package/docs/design/turboquant.md +0 -2212
- package/docs/design/unified-engine-frontier-plan.md +0 -1880
- package/docs/design/web-chat-redesign.md +0 -695
- package/docs/planning/PRODUCT_ROADMAP.md +0 -594
- package/docs/planning/ResearchTopics.md +0 -119
- package/docs/planning/release-notes-v0.4.0.md +0 -45
- package/docs/planning/video-series.md +0 -421
- package/docs/reference/benchmarks.md +0 -3613
- package/docs/reference/cli.md +0 -585
- package/docs/reference/distribution.md +0 -355
- package/docs/reference/environment.md +0 -398
- package/docs/reference/glossary.md +0 -39
- package/docs/reference/library-api.md +0 -674
- package/docs/reference/memory.md +0 -260
- package/docs/reference/models.md +0 -334
- package/docs/reference/server-api.md +0 -1775
- package/docs/reference/server-config.md +0 -846
- package/docs/reference/training.md +0 -462
- package/docs/reference/troubleshooting.md +0 -158
- package/src/admission-plan.ts +0 -18
- package/src/audio/conformer.ts +0 -647
- package/src/audio/decode.ts +0 -133
- package/src/audio/features.ts +0 -202
- package/src/audio/transcode.ts +0 -67
- package/src/backends/mlx/assistant-target.ts +0 -46
- package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
- package/src/backends/mlx/autoregressive.ts +0 -108
- package/src/backends/mlx/batch-group.ts +0 -1790
- package/src/backends/mlx/cache-attachment.ts +0 -67
- package/src/backends/mlx/cache-layout.ts +0 -31
- package/src/backends/mlx/checkpoint-state.ts +0 -53
- package/src/backends/mlx/continuation-persistence.ts +0 -106
- package/src/backends/mlx/continuation-request.ts +0 -43
- package/src/backends/mlx/continuation.ts +0 -77
- package/src/backends/mlx/diffusion.ts +0 -39
- package/src/backends/mlx/draft-target.ts +0 -32
- package/src/backends/mlx/evaluation.ts +0 -105
- package/src/backends/mlx/fill-append.ts +0 -45
- package/src/backends/mlx/full-kv-row-append.ts +0 -32
- package/src/backends/mlx/full-kv-row-donor.ts +0 -54
- package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
- package/src/backends/mlx/gateway-binding.ts +0 -130
- package/src/backends/mlx/graph.ts +0 -38
- package/src/backends/mlx/kv-codec.ts +0 -9
- package/src/backends/mlx/kv-maintenance.ts +0 -133
- package/src/backends/mlx/kv-tensor-rows.ts +0 -212
- package/src/backends/mlx/memory-client.ts +0 -189
- package/src/backends/mlx/methods.ts +0 -90
- package/src/backends/mlx/model-prompt.ts +0 -164
- package/src/backends/mlx/model-serving.ts +0 -79
- package/src/backends/mlx/prefill-cohort.ts +0 -89
- package/src/backends/mlx/prefill-rows.ts +0 -200
- package/src/backends/mlx/prefill.ts +0 -33
- package/src/backends/mlx/projected-context-rows.ts +0 -72
- package/src/backends/mlx/request-policy.ts +0 -20
- package/src/backends/mlx/request-state-policy.ts +0 -41
- package/src/backends/mlx/rollback.ts +0 -89
- package/src/backends/mlx/row-sampling.ts +0 -49
- package/src/backends/mlx/serial-executor.ts +0 -242
- package/src/backends/mlx/speculative-group.ts +0 -359
- package/src/backends/mlx/speculative-round.ts +0 -161
- package/src/backends/mlx/speculative.ts +0 -114
- package/src/backends/mlx/state-rows.ts +0 -104
- package/src/backends/mlx/state-views.ts +0 -46
- package/src/backends/mlx/target-layout-capability.ts +0 -35
- package/src/backends/mlx/text-engine.ts +0 -73
- package/src/backends/mlx/transitioning-kv-rows.ts +0 -165
- package/src/chat-template.ts +0 -382
- package/src/cli.ts +0 -3168
- package/src/config.ts +0 -399
- package/src/contracts/completion.ts +0 -16
- package/src/contracts/execution.ts +0 -60
- package/src/contracts/generation.ts +0 -103
- package/src/contracts/host.ts +0 -7
- package/src/contracts/pi-provider.ts +0 -30
- package/src/contracts/pi.ts +0 -259
- package/src/contracts/prefix-cache.ts +0 -23
- package/src/contracts/resources.ts +0 -25
- package/src/contracts/sampling.ts +0 -23
- package/src/contracts/scheduling.ts +0 -45
- package/src/contracts/tsconfig.json +0 -14
- package/src/dataset/generators.ts +0 -1087
- package/src/dataset/index.ts +0 -12
- package/src/dataset/job.ts +0 -81
- package/src/dataset/llm.ts +0 -71
- package/src/dataset/registry.ts +0 -528
- package/src/diffusion/diffusion-generate.ts +0 -507
- package/src/download.ts +0 -505
- package/src/embed.ts +0 -77
- package/src/engine/admission.ts +0 -59
- package/src/engine/cancellation.ts +0 -38
- package/src/engine/engine.ts +0 -56
- package/src/engine/execution-coordinator.ts +0 -70
- package/src/engine/execution-plan.ts +0 -53
- package/src/engine/resources.ts +0 -53
- package/src/engine/scheduler.ts +0 -72
- package/src/engine/session.ts +0 -247
- package/src/eval/README.md +0 -130
- package/src/eval/ifeval.ts +0 -81
- package/src/eval/kl-prompts.ts +0 -29
- package/src/eval/kl.ts +0 -590
- package/src/eval/perplexity.ts +0 -164
- package/src/eval/quality-db.ts +0 -92
- package/src/eval/reference-logits.ts +0 -207
- package/src/eval/runner.ts +0 -124
- package/src/eval/score.ts +0 -49
- package/src/eval/tasks/bfcl.ts +0 -535
- package/src/eval/tasks/gsm8k.ts +0 -98
- package/src/eval/tasks/hashhop.ts +0 -139
- package/src/eval/tasks/humaneval.ts +0 -275
- package/src/eval/tasks/ifeval.ts +0 -525
- package/src/eval/tasks/mmlu.ts +0 -157
- package/src/eval/ultrafeedback.ts +0 -60
- package/src/evaldb.ts +0 -199
- package/src/expert-io.ts +0 -393
- package/src/expert-offload-build.ts +0 -77
- package/src/expert-offload.ts +0 -76
- package/src/expert-residency.ts +0 -1134
- package/src/expert-usage.ts +0 -415
- package/src/fill/echo-index.ts +0 -188
- package/src/fill/fill-session.ts +0 -452
- package/src/fill/proposal.ts +0 -68
- package/src/fill/schema-rows.ts +0 -506
- package/src/fill/tool-boundary.ts +0 -103
- package/src/fit.ts +0 -249
- package/src/generate.ts +0 -1346
- package/src/grammar.ts +0 -591
- package/src/harness-pi.ts +0 -184
- package/src/hf-push.ts +0 -628
- package/src/hub-rest.ts +0 -242
- package/src/index.ts +0 -63
- package/src/inference/denoising.ts +0 -17
- package/src/inference/draft-acceptance.ts +0 -41
- package/src/inference/draft-output.ts +0 -49
- package/src/inference/graph.ts +0 -33
- package/src/inference/prefill.ts +0 -39
- package/src/inference/rollback.ts +0 -7
- package/src/jobs/index.ts +0 -31
- package/src/jobs/job-entry.ts +0 -107
- package/src/jobs/task-client.ts +0 -19
- package/src/jobs/types.ts +0 -2
- package/src/kv-scheme.ts +0 -257
- package/src/kv-store.ts +0 -1099
- package/src/lab/README.md +0 -18
- package/src/lab/curve/curve-designer.html +0 -303
- package/src/lab/curve/curve-sampler.ts +0 -122
- package/src/lab/expert-trace/expert-trace.ts +0 -69
- package/src/lab/paged-kv/paged-kv-rows.ts +0 -83
- package/src/lab/paged-kv/paged-kv.ts +0 -270
- package/src/library.ts +0 -40
- package/src/lora.ts +0 -408
- package/src/md-modules.d.ts +0 -49
- package/src/media-fetch.ts +0 -442
- package/src/memory/article.ts +0 -558
- package/src/memory/chunk-validation.ts +0 -150
- package/src/memory/chunk.ts +0 -318
- package/src/memory/cluster.ts +0 -351
- package/src/memory/coverage.ts +0 -134
- package/src/memory/crosslink.ts +0 -0
- package/src/memory/db.ts +0 -253
- package/src/memory/entity.ts +0 -203
- package/src/memory/gate.ts +0 -187
- package/src/memory/history.ts +0 -152
- package/src/memory/ingest.ts +0 -335
- package/src/memory/model.ts +0 -183
- package/src/memory/normalize.ts +0 -671
- package/src/memory/parse.ts +0 -22
- package/src/memory/pipeline.ts +0 -275
- package/src/memory/prompts.ts +0 -65
- package/src/memory/query.ts +0 -334
- package/src/memory/reconcile.ts +0 -734
- package/src/memory/redirect.ts +0 -108
- package/src/memory/reindex.ts +0 -325
- package/src/memory/resolve.ts +0 -307
- package/src/memory/rest.ts +0 -245
- package/src/memory/route.ts +0 -272
- package/src/memory/schedule.ts +0 -165
- package/src/memory/stages.ts +0 -777
- package/src/memory/synthesize.ts +0 -1638
- package/src/memory/tools.ts +0 -749
- package/src/memory/vault.ts +0 -1194
- package/src/memory/wikify.ts +0 -1064
- package/src/mlx/array.ts +0 -388
- package/src/mlx/autograd.ts +0 -304
- package/src/mlx/checkpoint.ts +0 -149
- package/src/mlx/compile.ts +0 -168
- package/src/mlx/custom-vjp.ts +0 -188
- package/src/mlx/ffi.ts +0 -512
- package/src/mlx/materialize.ts +0 -23
- package/src/mlx/metal-kernel.ts +0 -159
- package/src/mlx/ops.ts +0 -1021
- package/src/mlx/quantized-rows.ts +0 -36
- package/src/mlx/token-bitmask.ts +0 -52
- package/src/mlx/turboquant-kv-decode.ts +0 -82
- package/src/mlx/turboquant-kv-inverse.ts +0 -122
- package/src/mlx/turboquant-ops.ts +0 -861
- package/src/mlx/turboquant-tables.ts +0 -237
- package/src/mmap.ts +0 -90
- package/src/model/artifact-identity.ts +0 -73
- package/src/model/batched-kv.ts +0 -235
- package/src/model/batched-mask.ts +0 -279
- package/src/model/batched-quant.ts +0 -212
- package/src/model/batched-quantized-kv.ts +0 -144
- package/src/model/batched-rotating-quant.ts +0 -353
- package/src/model/batched-rotating-state.ts +0 -149
- package/src/model/batched-rotating.ts +0 -338
- package/src/model/batched-row-storage.ts +0 -179
- package/src/model/batched-ssm.ts +0 -52
- package/src/model/batched-turboquant-kv.ts +0 -93
- package/src/model/compiled-decode.ts +0 -712
- package/src/model/decoded-kv-donor.ts +0 -12
- package/src/model/delayed-quantized-kv.ts +0 -72
- package/src/model/delayed-rotating-quantized-kv.ts +0 -93
- package/src/model/delayed-turboquant-kv.ts +0 -55
- package/src/model/diffusion-gemma.ts +0 -1026
- package/src/model/factory.ts +0 -189
- package/src/model/fingerprint.ts +0 -33
- package/src/model/flash-attention.ts +0 -694
- package/src/model/full-prefill-padding.ts +0 -56
- package/src/model/full-prefill-row.ts +0 -105
- package/src/model/gemma4-base.ts +0 -2351
- package/src/model/gemma4.ts +0 -1315
- package/src/model/generated/gemma4-12b.ts +0 -429
- package/src/model/generated/gemma4-26b.ts +0 -448
- package/src/model/generated/gemma4-e4b.ts +0 -717
- package/src/model/generated/index.ts +0 -18
- package/src/model/glm52-atlas.ts +0 -511
- package/src/model/glm52-cache.ts +0 -792
- package/src/model/glm52-config.ts +0 -262
- package/src/model/glm52-container.ts +0 -305
- package/src/model/glm52-coupling.ts +0 -388
- package/src/model/glm52-dsa.ts +0 -606
- package/src/model/glm52-expert-layout.ts +0 -253
- package/src/model/glm52-layout.ts +0 -152
- package/src/model/glm52-memory.ts +0 -500
- package/src/model/glm52-mla.ts +0 -792
- package/src/model/glm52-moe.ts +0 -223
- package/src/model/glm52-pilot.ts +0 -537
- package/src/model/glm52-reference.ts +0 -445
- package/src/model/glm52-residency.ts +0 -557
- package/src/model/glm52-resident-weights.ts +0 -135
- package/src/model/glm52-streamed-experts.ts +0 -453
- package/src/model/glm52-streamed-metal.ts +0 -610
- package/src/model/glm52-weights.ts +0 -503
- package/src/model/glm52.ts +0 -1132
- package/src/model/implementation.ts +0 -69
- package/src/model/kv-attention-view.ts +0 -67
- package/src/model/minicpm5.ts +0 -376
- package/src/model/profile.ts +0 -443
- package/src/model/qwen-append.ts +0 -12
- package/src/model/qwen-conv.ts +0 -52
- package/src/model/qwen3-delta-state.ts +0 -74
- package/src/model/qwen3-delta.ts +0 -451
- package/src/model/qwen3-moe.ts +0 -404
- package/src/model/qwen3-mrope.ts +0 -252
- package/src/model/qwen3.ts +0 -277
- package/src/model/qwen3_5-checkpoint.ts +0 -164
- package/src/model/qwen3_5.ts +0 -819
- package/src/model/rotating-kv-donor.ts +0 -35
- package/src/model/rotating-kv-layout.ts +0 -262
- package/src/model/rotating-row-transaction.ts +0 -35
- package/src/model/speculative-rotating-kv.ts +0 -101
- package/src/model/ssm-prefill-padding.ts +0 -39
- package/src/model/support.ts +0 -102
- package/src/model/trellis-balanced-scatter.ts +0 -51
- package/src/model/trellis-linear.ts +0 -672
- package/src/model/trellis-shared-m.ts +0 -151
- package/src/model/trellis-shared-scatter.ts +0 -144
- package/src/model/trellis-splitk-prefill.ts +0 -158
- package/src/model/trellis-tiled-prefill.ts +0 -136
- package/src/model/trellis-vector-expand.ts +0 -62
- package/src/model/trellis-wide-prefill.ts +0 -94
- package/src/model/turboquant-codec.ts +0 -83
- package/src/model/universal/archs.ts +0 -332
- package/src/model/universal/dense.ts +0 -612
- package/src/model/universal/modules.ts +0 -170
- package/src/model/universal/rope.ts +0 -381
- package/src/native/expert_io.c +0 -523
- package/src/native/frame_extract.swift +0 -140
- package/src/native-pack.ts +0 -162
- package/src/pi-provider.ts +0 -53
- package/src/pi-session.ts +0 -81
- package/src/pi-terminal.ts +0 -274
- package/src/pi-web.ts +0 -1932
- package/src/preflight.ts +0 -158
- package/src/prompt-cache.ts +0 -460
- package/src/quantize/allocator.ts +0 -627
- package/src/quantize/atomic-output.ts +0 -38
- package/src/quantize/calibration.ts +0 -181
- package/src/quantize/config-writer.ts +0 -145
- package/src/quantize/index.ts +0 -84
- package/src/quantize/job.ts +0 -162
- package/src/quantize/quantizer.ts +0 -666
- package/src/quantize/rotate.ts +0 -603
- package/src/quantize/safetensors-writer.ts +0 -249
- package/src/quantize/sensitivity.ts +0 -216
- package/src/quantize/trellis.ts +0 -586
- package/src/quantize/weight-transform.ts +0 -292
- package/src/registry.ts +0 -602
- package/src/runtime-config.ts +0 -81
- package/src/safetensors.ts +0 -158
- package/src/sampler.ts +0 -1011
- package/src/serve/admin-routes.ts +0 -184
- package/src/serve/assets/curve-terrain.html +0 -105
- package/src/serve/assets/training-inference-map.html +0 -575
- package/src/serve/aux-routes.ts +0 -132
- package/src/serve/batch-scheduler.ts +0 -8
- package/src/serve/checkpoint-identity.ts +0 -64
- package/src/serve/generation-gateway.ts +0 -496
- package/src/serve/isolate.ts +0 -609
- package/src/serve/kv-budget.ts +0 -14
- package/src/serve/lab-routes.ts +0 -341
- package/src/serve/lane-registry.ts +0 -45
- package/src/serve/model-admin-routes.ts +0 -155
- package/src/serve/model-binding.ts +0 -43
- package/src/serve/model-host.ts +0 -511
- package/src/serve/parent-application.ts +0 -56
- package/src/serve/prompt-response-trace.ts +0 -147
- package/src/serve/response-lease.ts +0 -24
- package/src/serve/session-search.ts +0 -326
- package/src/serve/static-routes.ts +0 -101
- package/src/server.ts +0 -1314
- package/src/spec/assistant-rows.ts +0 -92
- package/src/spec/assistant-source.ts +0 -126
- package/src/spec/cache-identity.ts +0 -22
- package/src/spec/deepspec-rows.ts +0 -29
- package/src/spec/deepspec-source.ts +0 -145
- package/src/spec/dflash-source.ts +0 -149
- package/src/spec/drafter.ts +0 -304
- package/src/spec/dspark/ab-stats.ts +0 -136
- package/src/spec/dspark/calibration.ts +0 -112
- package/src/spec/dspark/data-dflash.ts +0 -156
- package/src/spec/dspark/data.ts +0 -201
- package/src/spec/dspark/deepspec-module.ts +0 -776
- package/src/spec/dspark/generate-dflash.ts +0 -245
- package/src/spec/dspark/generate.ts +0 -290
- package/src/spec/dspark/loader.ts +0 -23
- package/src/spec/dspark/loss.ts +0 -213
- package/src/spec/dspark/module-dflash.ts +0 -560
- package/src/spec/dspark/module.ts +0 -540
- package/src/spec/dspark/quantize-drafter.ts +0 -91
- package/src/spec/dspark/sample.ts +0 -112
- package/src/spec/generate.ts +0 -276
- package/src/spec/glm52-mtp-graph.ts +0 -29
- package/src/spec/glm52-mtp-rows.ts +0 -132
- package/src/spec/glm52-mtp-source.ts +0 -317
- package/src/spec/glm52-mtp-state.ts +0 -33
- package/src/spec/ngram-source.ts +0 -204
- package/src/spec/projected-draft-rows.ts +0 -73
- package/src/spec/qwen-mtp-module.ts +0 -171
- package/src/spec/qwen-mtp-rows.ts +0 -219
- package/src/spec/qwen-mtp-source.ts +0 -383
- package/src/spec/qwen-mtp-state.ts +0 -30
- package/src/spec/serve-loop.ts +0 -585
- package/src/spec/source.ts +0 -215
- package/src/spec/two-model-rows.ts +0 -61
- package/src/spec/two-model.ts +0 -113
- package/src/ssd-cache.ts +0 -372
- package/src/ssd-durability.ts +0 -211
- package/src/tokenizer.ts +0 -335
- package/src/tool-approvals.ts +0 -131
- package/src/tool-call.ts +0 -695
- package/src/train/dataset.ts +0 -484
- package/src/train/diffusion-lora.ts +0 -216
- package/src/train/export.ts +0 -32
- package/src/train/flash-cce.ts +0 -1234
- package/src/train/forward.ts +0 -266
- package/src/train/fuse.ts +0 -243
- package/src/train/index.ts +0 -46
- package/src/train/job.ts +0 -205
- package/src/train/lora-params.ts +0 -254
- package/src/train/loss.ts +0 -1591
- package/src/train/merge.ts +0 -195
- package/src/train/optimizer.ts +0 -183
- package/src/train/prefix-shared.ts +0 -490
- package/src/train/rank.ts +0 -137
- package/src/train/segmented.ts +0 -1828
- package/src/train/steel-qmm-header.ts +0 -1461
- package/src/train/trainer.ts +0 -1221
- package/src/train/watch.ts +0 -542
- package/src/vision/diffusion-vision.ts +0 -620
- package/src/vision/embedder.ts +0 -168
- package/src/vision/preprocess.ts +0 -247
- package/src/vision/prompt.ts +0 -373
- package/src/vision/qwen3vl-preprocess.ts +0 -409
- package/src/vision/qwen3vl-prompt.ts +0 -196
- package/src/vision/qwen3vl-tower.ts +0 -555
- package/src/vision/siglip.ts +0 -599
- package/src/vision/video-frames.ts +0 -148
- package/src/web/app.html +0 -2143
- package/src/web/app.js +0 -5703
- package/src/web/skills/memory/SKILL.md +0 -120
- package/src/web/skills/web-research/SKILL.md +0 -46
- package/src/web/skills.ts +0 -97
- package/src/web/src/adapters-panel.ts +0 -288
- package/src/web/src/assistant.ts +0 -451
- package/src/web/src/chat.ts +0 -1057
- package/src/web/src/composer.ts +0 -959
- package/src/web/src/dataset.ts +0 -132
- package/src/web/src/finetune.ts +0 -267
- package/src/web/src/hub.ts +0 -428
- package/src/web/src/main.ts +0 -98
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +0 -572
- package/src/web/src/model-picker.ts +0 -159
- package/src/web/src/palette.ts +0 -346
- package/src/web/src/protocol.ts +0 -26
- package/src/web/src/quantize.ts +0 -167
- package/src/web/src/rag.ts +0 -274
- package/src/web/src/sessions.ts +0 -469
- package/src/web/src/shell.ts +0 -804
- package/src/web/src/ui-catalog.ts +0 -78
- package/src/web/vendor/README.md +0 -61
- package/src/web-assets.ts +0 -47
- package/src/web-tools.ts +0 -478
- package/src/weights.ts +0 -255
- /package/src/{serve → server}/completion-sink.ts +0 -0
- /package/src/web/{icon.svg → public/icon.svg} +0 -0
- /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
- /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
|
@@ -1,489 +0,0 @@
|
|
|
1
|
-
# Steel flash-CCE — handoff
|
|
2
|
-
|
|
3
|
-
Porting MLX's quantized `steel` GEMM verbatim into our flash-CCE ORPO head, then
|
|
4
|
-
fusing the ORPO-specific epilogue (softcap + online-softmax logp / softmax−onehot
|
|
5
|
-
coeff + dh) on top — to get **MLX-GEMM speed AND the `[M,V]`-free memory property**
|
|
6
|
-
in one kernel. MLX ships no fused "quantized-matmul + softcap + response-logp" op, so
|
|
7
|
-
we build the composition; the heavy GEMM is theirs, verbatim.
|
|
8
|
-
|
|
9
|
-
## HANDOFF — current state (2026-06-19): SHIPPED in v0.0.5
|
|
10
|
-
|
|
11
|
-
The whole ORPO training stack is **merged (PR #16) and released as v0.0.5** — `npm
|
|
12
|
-
i mlx-bun` / `brew install joshuarossi/tap/mlx-bun` (tap formula at 0.0.5, sha verified).
|
|
13
|
-
What shipped: the flash-CCE head (fwd+bwd), prefix-sharing, segmented composition, warm-start,
|
|
14
|
-
the `scripts/train-orpo.ts` launcher, and the IFEval/UltraFeedback eval pieces. Release notes:
|
|
15
|
-
GitHub release v0.0.5. Supported scope = **OptiQ-quantized MiniCPM5 + Gemma-4 (e4b/12B/26B)**.
|
|
16
|
-
|
|
17
|
-
**Post-merge PR-review fixes (CodeRabbit, commits 890f380 / 63759fa) — read these, they
|
|
18
|
-
caught real bugs:**
|
|
19
|
-
- 🔴 **Prefix-shared head-primal UAF** (`branchLogpMeanGathered`/`orpoLossPrefixShared`): the
|
|
20
|
-
flash/fused-head CustomVjp PRIMAL (`hResp`, and `h`) was disposed *before* the lazy backward
|
|
21
|
-
recomputes from it → use-after-free (same class as the segmented `headSink` one). Fix: push
|
|
22
|
-
primals into the sink (freed post-eval) on the fused/flash path. **Tests passed before only
|
|
23
|
-
by lazy-eval timing luck** — this was latent. Watch for this pattern anywhere a CustomVjp's
|
|
24
|
-
primal is freed inline.
|
|
25
|
-
- **Segmented "flash implies fused"** (`trainer.ts` `segFusedChunk`): `orpoFlashCe` alone left
|
|
26
|
-
the segmented non-prefix fallback on the full `[M,vocab]` head → e4b memory blowup. Now
|
|
27
|
-
`orpoFusedCe || orpoFlashCe` routes through the bounded chunked head.
|
|
28
|
-
- Warm-start made atomic (validate all targets before disposing any), job payload exposes
|
|
29
|
-
`warm_start_adapter`/`mlp_split`, script GPU inputs use `fromBytesCopy` (page-align footgun),
|
|
30
|
-
env-precondition enforcement + flag validation in the probes.
|
|
31
|
-
|
|
32
|
-
**Warm-start** (`warmStartFromAdapter` / launcher `RESUME=<adapter-dir>`): continue from a
|
|
33
|
-
checkpoint's LoRA weights (optimizer + LR schedule restart). Insurance for interrupted runs.
|
|
34
|
-
|
|
35
|
-
**The training dress-rehearsal (honest):** a CPM5 UltraFeedback ORPO run (full stack, lr 5e-5)
|
|
36
|
-
reached ~step 4820, **val 1.66 → ~1.50, then plateaued** — expected: UF is open-ended, its loss
|
|
37
|
-
floor is ~1.2-1.5, NOT the 0.3-0.4 you get on a narrow task. **IFEval moved 22.5% → 22.5%
|
|
38
|
-
(flat)** — a real null result: general preference data + a partial run is the wrong lever for
|
|
39
|
-
IFEval. The pipeline learns (val dropped); the metric just isn't the right one. Checkpoints
|
|
40
|
-
every 200 under `./adapters/cpm5-uf-8h/checkpoints/` (best-val ~`step-04200-val1.5008`).
|
|
41
|
-
|
|
42
|
-
**Gotchas the runs taught us:**
|
|
43
|
-
- **Agent-spawned background runs get REAPED** (~47 min observed; not a crash/OOM — confirmed
|
|
44
|
-
via logs + `pmset` showed no sleep). **Run long training detached from your OWN shell**
|
|
45
|
-
(`nohup … &`), never as a session background task.
|
|
46
|
-
- e4b training **requires** `MLX_BUN_PERF_KERNEL=0` + `MLX_BUN_FUSED_GELU=0` (the launcher
|
|
47
|
-
auto-sets them; the e4b parity probe now enforces them).
|
|
48
|
-
- Adapters live in **`~/.cache/mlx-bun/mlx-bun-finetunes/`** (launcher default), never the repo.
|
|
49
|
-
|
|
50
|
-
**THE next goal — the chunk segmenter (load-bearing).** UF was the rehearsal; the real run is
|
|
51
|
-
**distilling Opus/GPT-5.5 conversation-segmentation into a local model** (data at
|
|
52
|
-
`~/Code/lucien/benchmark/finetune/chunk-v3/dpo/orpo-curated-*.fixed.jsonl`, `{prompt:[sys,user],
|
|
53
|
-
chosen, rejected}` — already supported by the loader). Score by **boundary/label accuracy vs
|
|
54
|
-
the gold (chunk-eval), NOT val loss** (loss is dominated by low-entropy JSON/UUID tokens). This
|
|
55
|
-
is what localizes the Lucien synthesis pipeline's `chunk-recent` stage (the whole "100% local
|
|
56
|
-
memory" promise). ORPO is ideal here: chosen/rejected share the conversation + are both
|
|
57
|
-
well-formed JSON, so the contrast isolates the segmentation decision, and the gold makes
|
|
58
|
-
pair-ranking + eval objective. The stack is built for it (prefix-share the shared 8k
|
|
59
|
-
conversation once, segment the long context, flash the big vocab). See memory
|
|
60
|
-
[[training-tracks-are-appliance-components]]. After that: the e4b overnight, and the welcome
|
|
61
|
-
assistant (a UF-tuned greeter — system prompt carries the mlx-bun knowledge, not training).
|
|
62
|
-
|
|
63
|
-
**Run commands:** see [orpo-quickstart](../reference/orpo-quickstart.md) +
|
|
64
|
-
[training.md](../reference/training.md). The full stack is `scripts/train-orpo.ts` (defaults on);
|
|
65
|
-
resume with `RESUME=<ckpt-dir>`; run it detached (`nohup`).
|
|
66
|
-
|
|
67
|
-
## TL;DR status
|
|
68
|
-
|
|
69
|
-
| Piece | State |
|
|
70
|
-
|---|---|
|
|
71
|
-
| **Steel GEMM port** (verbatim MLX BlockMMA/QuantizedBlockLoader/qmm_t) | ✅ done, compiles, matches `quantizedMatmul` 1e-5, **101ms == MLX 106ms** on e4b |
|
|
72
|
-
| **Forward** (steel GEMM + softcap + online-softmax → logp) | ✅ **in production** (`flashCceForward` default), parity PASS e4b/cpm/M=200, **180ms** (5× the old 848ms) |
|
|
73
|
-
| **Backward** (steel GEMM ×2 + softmax−onehot coeff + dh accumulate) | ✅ **IN PRODUCTION** (`flashCceBackward` default, `BWD_STEEL_SOURCE`/`bwdSteelKernel`). Parity PASS e4b (dh 0.40%) + cpm (dh 0.28%); **754ms** @ e4b M=512 — phase-2 W dequant now uses MLX's fused `QuantizedBlockLoader` (HTw=group_size, reduction_dim=0), **5× the old SG's 3687ms exact** (was 1851ms with the scalar dequant). Peak **0.928 GB flat @ M=8192** (`[M,V]`-free preserved). Old SG kept as `MLX_BUN_CCE_BWD_NOSTEEL=1` fallback. |
|
|
74
|
-
| Old shipping backward | the **OLD hand-rolled SG kernel** (`[M,V]`-free, correct, slow 3687ms) — now the fallback only |
|
|
75
|
-
|
|
76
|
-
**So: BOTH directions are now fast + live (steel fwd 180ms, steel bwd 754ms, both
|
|
77
|
-
`[M,V]`-free + exact). M1 + the phase-2 dequant optimization DONE.** Backward is now
|
|
78
|
-
~2.1× the ~360ms ideal (down from ~5×). Everything below (M2 prefix-share, M3 e4b probe,
|
|
79
|
-
M3-composition segmented+prefix, M4A integration tests) is also DONE — see sections.
|
|
80
|
-
|
|
81
|
-
## Why this exists (the journey, so you don't repeat it)
|
|
82
|
-
|
|
83
|
-
- Our hand-rolled simdgroup_matrix GEMM runs at **~8% of M1 Max peak**; MLX's `steel`
|
|
84
|
-
quantized GEMM runs at **~46%**. We spent a long time micro-optimizing the
|
|
85
|
-
hand-rolled kernel (token tiling, h-coalescing, dequant staging, bank-conflict
|
|
86
|
-
padding) — all marginal, because the gap is the **BlockMMA register-tiling +
|
|
87
|
-
K-pipeline**, not staging. The decisive move was: **stop hand-rolling, copy MLX
|
|
88
|
-
verbatim.** It works and hits their speed.
|
|
89
|
-
- **MLX's `quantizedMatmul` does the whole head ~3.8× faster than our old kernel AND
|
|
90
|
-
exact** (fwd 151 + bwd 330 = 481ms). That's the `orpoFusedCe` head, already in the
|
|
91
|
-
repo. The ONLY reason to keep flash-CCE: it's a **single kernel** → `[M,V]`-free,
|
|
92
|
-
no per-chunk host-loop allocator churn.
|
|
93
|
-
- **Memory caveat (important, was over-claimed then corrected):** the head is NOT the
|
|
94
|
-
memory wall at long seq — the layer activations are. Avoiding the full `[M,V]`
|
|
95
|
-
(8.6 GB at e4b/8192) IS essential, but BOTH flash-CCE (+0.17 GB) and a properly
|
|
96
|
-
streamed fused head (+0.27 GB) achieve it. flash-CCE backward peak is **0.93 GB flat
|
|
97
|
-
at M=8192** (weights-dominated; kernel scratch ~5 MB; linear in M, flat in V). So
|
|
98
|
-
option 2 (steel backward) is justified for **SPEED + single-kernel allocation
|
|
99
|
-
flatness**, not because the fused head "blows up" (it doesn't, if streamed right).
|
|
100
|
-
|
|
101
|
-
## Files
|
|
102
|
-
|
|
103
|
-
- `src/train/steel-qmm-header.ts` — **the verbatim MLX steel port** (auto-assembled
|
|
104
|
-
from MLX `quantized.h` + `steel/{gemm/mma.h,gemm/loader.h,gemm/transforms.h,
|
|
105
|
-
utils/integral_constant.h,utils/type_traits.h}`). Exports `STEEL_QMM_HEADER` (the
|
|
106
|
-
MSL header string). Contains: `BlockMMA`, `MMATile`, `BaseMMAFrag`, `tile_matmad`,
|
|
107
|
-
`BlockLoader`, `QuantizedBlockLoader`, `dequantize`, `get_pack_factor`, `qmm_t_impl`.
|
|
108
|
-
- `src/train/flash-cce.ts` — the head. `FWD_STEEL_SOURCE` + `fwdSteelKernel(gs,bits)`
|
|
109
|
-
(the **live forward**, dispatched by `useSteel` default). The old SG/scalar/lane
|
|
110
|
-
forward kernels + the current backward (`BWD_SG_SOURCE` / `bwdSgKernel`, the
|
|
111
|
-
hand-rolled persistent-acc[80] kernel) are still there.
|
|
112
|
-
- `src/train/loss.ts` — `makeFlashCceHeadVjp` (CustomVjp: fwd→Σlogp stash lse+blockMax,
|
|
113
|
-
bwd→flashCceBackward). `ChunkCtx.flash`. Routed via `orpoFlashCe` config flag.
|
|
114
|
-
- `src/train/trainer.ts` / `job.ts` — `orpoFlashCe` / `orpo_flash_ce` knob.
|
|
115
|
-
- `tests/train-orpo-fused-ce.test.ts` — flash-head fwd-parity + end-to-end training
|
|
116
|
-
tests (MLX_BUN_TEST_TRAIN=1, MiniCPM5).
|
|
117
|
-
- **Validated experiment scripts** (preserved, portable imports):
|
|
118
|
-
- `scripts/experiments/qmm-port-test.ts` — steel GEMM correctness vs quantizedMatmul.
|
|
119
|
-
- `scripts/experiments/qmm-port-speed.ts` — steel GEMM speed vs MLX (101 vs 106ms).
|
|
120
|
-
- `scripts/experiments/steel-fwd-test.ts` — forward epilogue (logp) vs reference.
|
|
121
|
-
- `scripts/experiments/steel-coeff-test.ts` — **backward phase-1** (logit→coeff) PASS.
|
|
122
|
-
- `scripts/experiments/steel-bwd-test.ts` — **full backward dh** (phase-1+2) PASS 1.6e-5.
|
|
123
|
-
- `scripts/experiments/bwd-peak.ts` — clean isolated backward peak (0.93 GB @ M=8192).
|
|
124
|
-
- `scripts/experiments/fwd-gemm-bench.ts` — MLX QM baseline (fwd 151 / bwd 330ms).
|
|
125
|
-
|
|
126
|
-
## The architecture (what's proven)
|
|
127
|
-
|
|
128
|
-
Tile constants: **BM=8 tokens, BN=32 vocab, BK=32 hidden, WM=1, WN=4** (4 simdgroups
|
|
129
|
-
along N), `BK_padded = BK + 16/sizeof(T)`. The `WM=1,WN=4` choice is THE unlock:
|
|
130
|
-
BlockMMA's output tile is then split so **each simdgroup owns a different N-slice** —
|
|
131
|
-
which for the dh GEMM means each simdgroup owns a different **H-slice**, i.e. exactly
|
|
132
|
-
the persistent `acc[80]` layout we already proved works (160 regs/lane). So steel's
|
|
133
|
-
BlockMMA and the `[M,V]`-free persistent accumulator ARE compatible.
|
|
134
|
-
|
|
135
|
-
**Forward** (`FWD_STEEL_SOURCE`, live): grid `[128, NBLK, ⌈M/32⌉]` (BM=32 there, not 8),
|
|
136
|
-
per (token-block z, vocab-block y) threadgroup loop BN vocab-tiles → steel K-loop →
|
|
137
|
-
`Ctile.store` to threadgroup `Ls` → softcap + online-softmax → `[M,NBLK]` partials →
|
|
138
|
-
MLX merge → logp. `load_safe` for the last token-block (M%BM); vocab aligned for e4b/cpm.
|
|
139
|
-
|
|
140
|
-
**Backward** (proven in `steel-bwd-test.ts`, BM=8/WM=1/WN=4): per (token-block, vocab-
|
|
141
|
-
block) threadgroup, persistent `dmma = BlockMMA<float,float,8,H,32,1,4,false,false>`
|
|
142
|
-
Ctile = the dh accumulator. Loop vocab-tiles: phase-1 `lmma` BlockMMA logit → `Ls` →
|
|
143
|
-
coeff epilogue (`g·(onehot−softmax(logit−lse))·sech²`) → threadgroup `coeffS[8,32]`;
|
|
144
|
-
dequant W non-transposed → `Wd[32,H]`; `dmma.mma(coeffS, Wd)` accumulates `coeff@W`.
|
|
145
|
-
After the loop `dmma.store_result(dh,...)`.
|
|
146
|
-
|
|
147
|
-
## Gotchas (hard-won — read before touching the header/kernels)
|
|
148
|
-
|
|
149
|
-
1. **String.raw escaping**: when writing the header to a `.ts` string, do NOT escape
|
|
150
|
-
backslashes (mangles macro `\` line-continuations). Only fails if content has a
|
|
151
|
-
backtick or `${` (the MLX code has neither).
|
|
152
|
-
2. **MLX preamble**: `mx.fast.metal_kernel` already provides `METAL_FUNC` + `using
|
|
153
|
-
namespace metal` (redef warning, harmless) but NOT `STEEL_CONST`/`MLX_MTL_CONST`/
|
|
154
|
-
`SIMD_SIZE`/`Int<>`/`pointer_element_t` — we add the macros + `type_traits.h` +
|
|
155
|
-
`integral_constant.h` ourselves.
|
|
156
|
-
3. **`#pragma METAL internals`**: `type_traits.h` and `integral_constant.h` need it
|
|
157
|
-
(struct inheritance / `is_integral`). Include them **verbatim with their own
|
|
158
|
-
self-managed enable/disable pragmas** — do NOT strip + wrap manually (type_traits'
|
|
159
|
-
trailing `disable` will turn it off before integral_constant compiles → "derived
|
|
160
|
-
classes not supported").
|
|
161
|
-
4. **W dequant convention** (in MANUAL dequant, e.g. phase-2 `Wd`): use
|
|
162
|
-
`perWord = 32/bits` (4 elems per uint32 at 8-bit), NOT `get_pack_factor<bits,8>=1`
|
|
163
|
-
(that's MLX's byte-based packing for the QuantizedBlockLoader's internal uint8
|
|
164
|
-
addressing). Mixing these gave a 100%-wrong dh.
|
|
165
|
-
5. **`BlockMMA.mma` reads `Bs[BK,BN]` full-width** from threadgroup — so you can't wrap
|
|
166
|
-
it for a full-H persistent accumulator (would need `W[32,2560]`=320KB tg). Either
|
|
167
|
-
keep H small (test) or tile H with manual `tile_matmad` (production).
|
|
168
|
-
6. Watchdog: per-threadgroup vocab slice must stay bounded (`VOCAB_BLOCK=8192`).
|
|
169
|
-
|
|
170
|
-
## NEXT STEPS — the plan (in order)
|
|
171
|
-
|
|
172
|
-
### 1. H-tiling in the steel backward phase-2 (the one real remaining piece)
|
|
173
|
-
The test stages the full `W[32,H]`; at e4b H=2560 that's 320 KB > 32 KB threadgroup.
|
|
174
|
-
Production must tile H:
|
|
175
|
-
- dh accumulator = `MMATile<float, 1, H/32>` per simdgroup (= its H-quarter; 80 frags
|
|
176
|
-
@ e4b = the proven `acc[80]` register budget).
|
|
177
|
-
- per vocab-tile: loop H in `BKh` chunks → dequant `W[32, BKh]` → threadgroup (small) →
|
|
178
|
-
load coeff A-frags `MMATile<1,4>` + W B-frags `MMATile<4, BKh/8>` → `tile_matmad(
|
|
179
|
-
D_sub, A, B_sub, D_sub)` into the right sub-frags of the persistent D.
|
|
180
|
-
- The intricate bit is the manual sub-frag indexing into D (BlockMMA does this
|
|
181
|
-
internally; here we do `tile_matmad` by hand because D persists across vocab-tiles).
|
|
182
|
-
- Validate against `steel-bwd-test.ts` (extend it to H=2560, compare to QM(coeff,W,t=F)).
|
|
183
|
-
|
|
184
|
-
### 2. Vocab-blocking grid + atomic dh
|
|
185
|
-
- Grid `[128, NBLK, ⌈M/BM⌉]`; each (token-block, vocab-block) computes its block's dh
|
|
186
|
-
contribution, **atomic-add** into device `dh` (across the NBLK blocks) — same pattern
|
|
187
|
-
the current `BWD_SG_SOURCE` already uses (`atomicOutputs`, `initValue:0`).
|
|
188
|
-
- Need `lse` (have it, forward returns it) + `blockMax` (optional, for the block-skip)
|
|
189
|
-
+ `gv` (cotangent) passed in — same inputs as the current backward.
|
|
190
|
-
|
|
191
|
-
### 3. Wire into `flashCceBackward`
|
|
192
|
-
- Add `BWD_STEEL_SOURCE` + `bwdSteelKernel(gs,bits)` (header = STEEL_QMM_HEADER + defines).
|
|
193
|
-
- Dispatch: `useSteel` default when H,V,blockV %32 (mirror the forward's gate).
|
|
194
|
-
- Keep the old `bwdSgKernel` as fallback (H%32!=0) + the float4 scalar as last resort.
|
|
195
|
-
- The CustomVjp (`makeFlashCceHeadVjp`) already calls `flashCceBackward` — no change there.
|
|
196
|
-
|
|
197
|
-
### 4. Validate + benchmark
|
|
198
|
-
- Parity: `E4B=1 M=512 bun scripts/experiments/flash-cce-parity.ts` (+ cpm, + M=200).
|
|
199
|
-
Expect dh ~0.4% (bf16-class) vs autograd.
|
|
200
|
-
- Bench vs baselines: fused head **481ms** (speed), current flash-CCE (memory parity).
|
|
201
|
-
Target: steel backward in the same class as the forward (~hundreds of ms, vs 3375).
|
|
202
|
-
- Memory: `scripts/experiments/bwd-peak.ts` should stay ~0.93 GB @ 8192 (flat).
|
|
203
|
-
- **CAP ANY MEMORY PROBE well under 32 GB** and eval+free per iteration — a naive
|
|
204
|
-
full-graph host-loop allocation swapped the machine to 23 GB once. Single-kernel
|
|
205
|
-
flash probes are safe by construction.
|
|
206
|
-
|
|
207
|
-
### 5. (optional) softcap + filter/block-skip parity in the steel backward
|
|
208
|
-
- Softcap sech² is in the coeff epilogue already (steel-bwd-test uses cap=0; cap>0 path
|
|
209
|
-
is written, validate it).
|
|
210
|
-
- The Apple-CCE coeff filter + blockMax skip are **opt-in, default-off** approximations
|
|
211
|
-
(data-dependent; flat-softmax probes showed dh sensitivity). They live in the OLD
|
|
212
|
-
backward; decide whether to port them to steel (probably not needed — steel is fast
|
|
213
|
-
enough exact).
|
|
214
|
-
|
|
215
|
-
## Decision context (for when you pick the shipping config)
|
|
216
|
-
|
|
217
|
-
- **Now**: `orpoFlashCe` = steel forward (fast) + old SG backward (slow but `[M,V]`-free).
|
|
218
|
-
Trains, memory-flat. `orpoFusedCe` = MLX QM both ways (481ms, exact, `[chunk,V]`
|
|
219
|
-
transient).
|
|
220
|
-
- **After option 2 lands**: `orpoFlashCe` = steel fwd + steel bwd = fast AND `[M,V]`-free
|
|
221
|
-
AND single-kernel — strictly best; removes the speed/memory tradeoff.
|
|
222
|
-
- The one genuinely-unanswered question: does the fused head's host-loop chunked backward
|
|
223
|
-
churn MLX's allocator at real e4b/8192 training? An end-to-end training-step peak
|
|
224
|
-
measurement (model + activations + head, with segmented/checkpointed backward) decides
|
|
225
|
-
whether the single-kernel property matters in practice. Worth measuring once.
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
# END-STATE ROADMAP — "CPM5 test run with everything → e4b overnight @ 8192"
|
|
230
|
-
|
|
231
|
-
**The actual goal.** Two deliverables Josh runs himself (we wire, we do NOT kick off
|
|
232
|
-
the overnight run — ground rule):
|
|
233
|
-
- **(A)** A short **MiniCPM5** test training session using ALL optimizations — proves
|
|
234
|
-
the whole stack composes and trains (loss decreases).
|
|
235
|
-
- **(B)** An **e4b overnight** ORPO run at seq **8192** — the real target.
|
|
236
|
-
|
|
237
|
-
"ALL of our stuff" = flash-CCE head (fwd+bwd at MLX speed, `[M,V]`-free) + prefix-sharing
|
|
238
|
-
(single fwd/bwd, prompt shared) + segmented/checkpointed backward (layer-activation
|
|
239
|
-
memory at long seq) + LoRA.
|
|
240
|
-
|
|
241
|
-
## What's already wired (so you don't redo it)
|
|
242
|
-
- flash-CCE **forward**: live + default (`flashCceForward`).
|
|
243
|
-
- flash-CCE head CustomVjp (`makeFlashCceHeadVjp`) ↔ `orpoFlashCe` flag ↔ trainer.
|
|
244
|
-
- flash threaded into BOTH non-segmented (`fusedLogpMeanB1`) and **segmented**
|
|
245
|
-
(`fusedLogpMeanFromHidden`) head paths.
|
|
246
|
-
- Segmented backward exists (`SegmentedBackwardOrpo` / `…Gemma4`), `segmentSize` flag.
|
|
247
|
-
- ORPO B=1 path (`branchLogpMean`→fused/flash) + tests (MiniCPM5 flash training PASSES).
|
|
248
|
-
- prefix-sharing math (`orpoLossPrefixShared`, MiniCPM5, bit-exact, parity script).
|
|
249
|
-
|
|
250
|
-
## Milestones (dependency order)
|
|
251
|
-
|
|
252
|
-
### M1 — flash-CCE backward → production (the steel backward) ✅ DONE (2026-06-18)
|
|
253
|
-
H-tiled phase-2 (Design C: persistent `MMATile<1,H/32>` accumulator + per-H-tile temp
|
|
254
|
-
BlockMMA over bounded `Wd[32,128]` + lane-local frag accumulation) → vocab-blocking grid
|
|
255
|
-
+ atomic dh → `BWD_STEEL_SOURCE`/`bwdSteelKernel` wired into `flashCceBackward` (`useSteel`
|
|
256
|
-
gate: H,V,blockV %32 + H%128). Parity PASS e4b (dh 0.40%) + cpm (dh 0.28%); 2.0× the old
|
|
257
|
-
SG (1851 vs 3687ms e4b M=512 exact); peak 0.928 GB flat @8192. Design validated first in
|
|
258
|
-
`scripts/experiments/steel-bwd-htile-test.ts` (H=2560, PASS 1.1e-4 rel). Both flash
|
|
259
|
-
directions now fast. KEY INSIGHT that avoided the "intricate manual tile_matmad": a TEMP
|
|
260
|
-
BlockMMA per H-tile whose Ctile is accumulated into the persistent D via `frag += frag`
|
|
261
|
-
(lane-local — the per-lane element layout is identical, so no get_coord math needed).
|
|
262
|
-
|
|
263
|
-
### M2 — prefix-sharing → trainer (single fwd/bwd) ✅ DONE (2026-06-18)
|
|
264
|
-
- `orpoPrefixShared` trainer flag (+ `orpo_prefix_shared` job field) dispatches to
|
|
265
|
-
`orpoLossPrefixShared` (MiniCPM5) / `orpoLossPrefixSharedGemma` (Gemma4 — the sibling
|
|
266
|
-
already existed) via `splitPrefixBatch`, falling back to two-forward `orpoLoss` when a
|
|
267
|
-
row's chosen/rejected prompts differ. Guarded against `segmentSize>0` (composition is
|
|
268
|
-
M3). End-to-end CPM5 training test PASSES (loss decreases).
|
|
269
|
-
- **Composed with the flash head**: new `branchLogpMeanGathered` gathers each branch's
|
|
270
|
-
`[M,H]` response hiddens → `fusedRespLogpMean(flash)` per branch (reuses the analytic
|
|
271
|
-
per-branch VJP — cleaner than splitting one call's non-uniform length-normalized
|
|
272
|
-
cotangent). Validated: flash-routed prefix-share matches whole-vocab prefix-share to
|
|
273
|
-
**0.018%** (bf16-class) in `prefix-shared-parity.ts`. So prefix-share is now `[M,V]`-free
|
|
274
|
-
end to end (one model fwd + per-branch flash fwd/bwd).
|
|
275
|
-
- **e4b caveat unchanged**: e4b's bf16 length-sensitivity (~2–14%) is a numerical-parity
|
|
276
|
-
nicety, not correctness. MiniCPM5 is bit-exact (forward 0%, grads ~1% at P=512). NOTE:
|
|
277
|
-
for the e4b OVERNIGHT at seq 8192, prefix-share can't be used until M3 composes it with
|
|
278
|
-
the segmented backward — the overnight uses **segmented + flash** (validated config shape
|
|
279
|
-
below), with prefix-share an M3 follow-on.
|
|
280
|
-
|
|
281
|
-
### M4A — CPM5 smoke test of the complete new system ✅ DONE (2026-06-18)
|
|
282
|
-
Automated end-to-end tests in `tests/train-orpo-fused-ce.test.ts` (run with
|
|
283
|
-
`MLX_BUN_TEST_TRAIN=1`), all PASS — each trains CPM5 20 iters, asserts finite +
|
|
284
|
-
decreasing loss + no OOM/NaN:
|
|
285
|
-
- **flash head** (steel fwd+bwd) + LoRA.
|
|
286
|
-
- **prefix-share + flash** (the single-concat-forward + `[M,V]`-free head).
|
|
287
|
-
- **segmented + flash** (the e4b-overnight config shape: gradient-checkpointed layer
|
|
288
|
-
activations + `[M,V]`-free head). These exercise every new piece composing in a real
|
|
289
|
-
ORPO step. (prefix-share + segmented together = M3, not yet composed.)
|
|
290
|
-
|
|
291
|
-
### M3 — long-sequence memory @ e4b/8192 (the layer activations, NOT the head)
|
|
292
|
-
- Compose segmented/checkpointed backward (`segmentSize>0`) + flash head + prefix-share.
|
|
293
|
-
The head is ~free in memory (0.93 GB flat); the wall is the transformer activations,
|
|
294
|
-
which segmented backward already handles (peak 10.9→3.3 GB @2048 per the notes).
|
|
295
|
-
- **THE measurement that actually decides "does e4b train at 8192"**: a real end-to-end
|
|
296
|
-
training-step peak (model + activations + head) with segmented backward on. Do this
|
|
297
|
-
EARLY — it tells us the segment size needed to fit 8192 in 32 GB, and whether the head
|
|
298
|
-
choice (flash vs fused) matters at all. (Cap probes; never swap the machine.)
|
|
299
|
-
|
|
300
|
-
### M3/M4B — e4b @ 8192 memory probe + overnight config ✅ PROBED (2026-06-18)
|
|
301
|
-
`scripts/bench-orpo.ts` sweeps the new-system configs (`flash head` / `segmented + flash`
|
|
302
|
-
/ `prefix + flash`); `ONLY_NEW=1` skips the legacy baselines, `CONFIG="<substr>"` runs one,
|
|
303
|
-
and it now prints peak GB + a finite-loss check. The **`segmented + flash` row IS the
|
|
304
|
-
overnight config shape**.
|
|
305
|
-
|
|
306
|
-
**MEASURED on the M1 Max 32 GB (e4b, segmented+flash, SEG=2, `MLX_BUN_PERF_KERNEL=0
|
|
307
|
-
MLX_BUN_FUSED_GELU=0`):**
|
|
308
|
-
| SEQ | peak GB | ms/step |
|
|
309
|
-
|---|---|---|
|
|
310
|
-
| 1024 | 8.66 | 20.7k |
|
|
311
|
-
| 2048 | 10.17 | 40.4k |
|
|
312
|
-
| 4096 | 11.68 | 80.8k |
|
|
313
|
-
| **8192** | **16.14** | **175k** (loss 0.093→0.091 finite, decreasing) |
|
|
314
|
-
|
|
315
|
-
Footprint is **linear** in seq (~+1.5 GB / 1024 tokens — segmenting + flash attention keep
|
|
316
|
-
it linear, not quadratic; the head is flat 0.93 GB). **e4b @ 8192 fits in 16.14 GB with
|
|
317
|
-
~16 GB headroom — the historical "e4b OOMs ≥2048" ceiling is BROKEN.** SEG=2 is the sweet
|
|
318
|
-
spot: SEG=8 @ 8192 hit **33.47 GB (swapped) and was slower** — bigger segments hold more
|
|
319
|
-
activations, so small segments win here. The run command:
|
|
320
|
-
```
|
|
321
|
-
MODEL=<e4b-snapshot> CONFIG="segmented + flash" SEQ=8192 SEG=2 ITERS=3 \
|
|
322
|
-
MLX_BUN_PERF_KERNEL=0 MLX_BUN_FUSED_GELU=0 bun scripts/bench-orpo.ts
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**VALIDATED overnight config (segmented + flash + LoRA):**
|
|
326
|
-
```
|
|
327
|
-
method:"orpo", orpoFlashCe:true (implies fused), segmentSize:2, orpoChunkSize:512,
|
|
328
|
-
maxSeqLen:8192, env MLX_BUN_PERF_KERNEL=0 + MLX_BUN_FUSED_GELU=0, rank/scale/lr + real
|
|
329
|
-
dpo data per the run, LoRA targets default. Peak ~16 GB, ~2.9 min/step on the M1 Max.
|
|
330
|
-
```
|
|
331
|
-
Prefix-share is NOT in the overnight (segmented + prefix-share = the M3-composition below);
|
|
332
|
-
the overnight uses segmented + flash. **Josh starts the overnight** (ground rule).
|
|
333
|
-
|
|
334
|
-
### M3-composition — segmented backward + prefix-share together ✅ LANDED MiniCPM5 (2026-06-18)
|
|
335
|
-
New `SegmentedBackwardOrpoPrefix` (`src/train/segmented.ts`): streams ONE concat
|
|
336
|
-
`[prompt; chosen; rejected]` through the segmented backward with `PrefixSharedCache`
|
|
337
|
-
(block-sparse mask) + `setMiniCpmPrefixPlan` active during the streaming forward AND every
|
|
338
|
-
segment's `mlx_vjp` recompute; the head VJP gathers chosen/rejected response positions
|
|
339
|
-
(`branchLogpMeanGathered`, the `[M,V]`-free per-branch flash head) and scatter-adds its dh
|
|
340
|
-
into the `[1,T,H]` boundary that seeds the segmented backward. Trainer composes it (old
|
|
341
|
-
guard removed) with a two-forward-segmented fallback on prompt mismatch. Validated
|
|
342
|
-
(`scripts/experiments/prefix-shared-segmented-parity.ts`): grads **2.27%** bf16-class
|
|
343
|
-
(single-segment diagnostic 1.16% → it's segment-boundary reassociation + flash-head 0.4%
|
|
344
|
-
stacking, not a bug), loss **0.052%**, peak **32% lower** (3.64→2.47 GB @ P=512; grows to
|
|
345
|
-
59% lower @ P=1024) — prompt-encode-once now holds at long seq with flat ~2.5 GB activation.
|
|
346
|
-
Test #6 in `tests/train-orpo-fused-ce.test.ts` (PASS). **e4b (Gemma4) DEFERRED** — trainer
|
|
347
|
-
throws a clear error; the logical-position sliding-window prefix mask + donor-KV threading
|
|
348
|
-
across segmented donor boundaries is the remaining follow-on (the overnight uses
|
|
349
|
-
segmented+flash without prefix-share, which works).
|
|
350
|
-
|
|
351
|
-
### M4 — runnable configs + the two runs
|
|
352
|
-
- **(A) MiniCPM5 test config**: short seq, small iters, `orpoFlashCe` (or prefix-share
|
|
353
|
-
mode) + segmented on, LoRA. Run `trainLora`; assert loss decreases. This is the
|
|
354
|
-
"everything composes" gate — basically the existing flash training test scaled up.
|
|
355
|
-
- **(B) e4b overnight config**: seq 8192, `segmentSize` tuned from M3, flash head,
|
|
356
|
-
prefix-share (or two-forward if e4b variance is a problem), LoRA, full dataset
|
|
357
|
-
(`scripts/curate-ultrafeedback.ts` / the dpo data). **Josh runs this** — we hand him a
|
|
358
|
-
validated config + command, we do not start it.
|
|
359
|
-
|
|
360
|
-
## THE POINT: the runs are INTEGRATION TESTS of the NEW system
|
|
361
|
-
Josh does NOT care about training quality/results. The CPM5 run and the e4b run exist to
|
|
362
|
-
**exercise everything we just built — steel backward + flash head + prefix-sharing — end
|
|
363
|
-
to end in a real ORPO training step** and confirm the new code path RUNS (loss is finite,
|
|
364
|
-
decreases a bit, no crash/NaN/OOM). So we FINISH all the new pieces, wire them ALL the
|
|
365
|
-
way through, then run. Do NOT ship the old slow backward as a crutch — the steel backward
|
|
366
|
-
is part of what's being tested.
|
|
367
|
-
|
|
368
|
-
## Order of execution (build the new system, then test it)
|
|
369
|
-
1. **M1 — steel backward → production** (H-tile phase-2, vocab-block + atomic dh, wire
|
|
370
|
-
`bwdSteelKernel` into `flashCceBackward`, parity e4b/cpm). The new backward IS under
|
|
371
|
-
test; it must be in the path.
|
|
372
|
-
2. **M2 — prefix-sharing → trainer + compose with flash head** (gather `[Rc+Rr]` → one
|
|
373
|
-
flash-head call → split by branch). MiniCPM5 first.
|
|
374
|
-
3. **M4(A) — CPM5 test run = the smoke test of the complete new system**: flash fwd+bwd
|
|
375
|
-
(steel) + prefix-share + segmented + LoRA, all on. Run `trainLora` a handful of steps;
|
|
376
|
-
assert finite + decreasing loss + no OOM. THIS is the test — it validates every new
|
|
377
|
-
piece composes in a real step. If it passes, the new system works.
|
|
378
|
-
4. **M3 — e4b @ 8192 dry-run**: same new system on e4b, seq 8192, segmented on. First a
|
|
379
|
-
memory/step-peak check (cap it; the head is flat 0.93 GB, the wall is activations →
|
|
380
|
-
tune `segmentSize`), then a few real steps to confirm it RUNS. (e4b prefix-share bf16
|
|
381
|
-
variance is fine — we're not checking quality; if it NaNs, fall back to two-forward.)
|
|
382
|
-
5. **M4(B) — e4b overnight**: hand Josh a validated config + command for the longer run
|
|
383
|
-
(we wire + validate a few steps; **Josh starts the overnight** — ground rule).
|
|
384
|
-
|
|
385
|
-
**Risk register**: M1 mechanical (scoped — architecture+correctness already proven). M2/e4b
|
|
386
|
-
bf16 variance = non-blocking for a RUN test (two-forward fallback; quality irrelevant). M3
|
|
387
|
-
e4b/8192 memory = the one real unknown, but it's an activations/segmentSize question, not
|
|
388
|
-
a head question. The runs test integration; the pieces are individually validated.
|
|
389
|
-
|
|
390
|
-
---
|
|
391
|
-
|
|
392
|
-
# GLOSSARY — every named piece, what it is, status, where
|
|
393
|
-
|
|
394
|
-
Status legend: ✅ done+live · 🟢 done, not production-wired · 🟡 partial · 🔬 proven in a
|
|
395
|
-
test only · 📦 pre-existing (not ours this arc) · 🪦 dead end.
|
|
396
|
-
|
|
397
|
-
## A. The "head" = how we turn response hiddens `[M,H]` into ORPO log-probs
|
|
398
|
-
(M = number of response tokens; V = vocab; H = hidden.) These are *alternative
|
|
399
|
-
implementations of the same math* (`logp_t = target_logit − logsumexp_v`).
|
|
400
|
-
- **Full-logits head** 📦 — the naive reference: materialize `[M,V]` logits, logsumexp.
|
|
401
|
-
Correct, huge memory. Only used as the parity oracle.
|
|
402
|
-
- **Chunked head** (`orpoChunkSize`) 📦 — token-chunked + per-chunk `Checkpoint`; bounds
|
|
403
|
-
`[M,V]`→`[chunk,V]`. Older, autograd through the head.
|
|
404
|
-
- **Fused linear-CE head** (`orpoFusedCe`, `fusedRespLogpMean`) 📦✅ — a `CustomVjp` with
|
|
405
|
-
an ANALYTIC softmax−onehot backward (no autograd through the head), using **MLX
|
|
406
|
-
`quantizedMatmul`** for both GEMMs, token-chunked. Fast (**481ms** e4b), exact,
|
|
407
|
-
`[chunk,V]` transient. The speed baseline we're trying to match.
|
|
408
|
-
- **Vocab-blocked head** (`makeVocabBlockedHeadVjp`) 📦 — pure-MLX online-softmax over
|
|
409
|
-
vocab blocks; `[chunk, vocabBlock]` only. Slow-ish; the MLX-only CCE.
|
|
410
|
-
- **flash-CCE head** (`orpoFlashCe`, `makeFlashCceHeadVjp`) — **OURS**, the Metal-kernel
|
|
411
|
-
head: the vocab loop lives INSIDE one Metal kernel, so neither `[M,V]` nor a
|
|
412
|
-
dequantized `[V,H]` ever touches HBM → `[M,V]`-free, single kernel. Forward ✅ live,
|
|
413
|
-
backward 🟡 (old slow kernel live; steel kernel 🔬 proven, not wired). `flashCceForward`
|
|
414
|
-
+ `flashCceBackward` in `src/train/flash-cce.ts`.
|
|
415
|
-
|
|
416
|
-
## B. flash-CCE kernel internals (`src/train/flash-cce.ts`) — OURS
|
|
417
|
-
The flash head dispatches to one of several kernel implementations of fwd/bwd:
|
|
418
|
-
- **`FWD_STEEL_SOURCE` / `fwdSteelKernel`** ✅ — the NEW steel-GEMM forward (default). 180ms.
|
|
419
|
-
- `FWD_SG_SOURCE` / `fwdSgKernel` 🪦-ish — old hand-rolled simdgroup_matrix forward (848ms).
|
|
420
|
-
- `FWD_SOURCE` / `fwdKernel` — scalar fallback (H%32≠0).
|
|
421
|
-
- `FWD_LANE_SOURCE` 🪦 — lane-sliced (2.6× slower, dead end, kept gated).
|
|
422
|
-
- **`BWD_SG_SOURCE` / `bwdSgKernel`** ✅(live) — CURRENT production backward: hand-rolled
|
|
423
|
-
simdgroup_matrix, persistent `acc[80]` dh accumulator, phase-1 (logit→coeff) +
|
|
424
|
-
phase-2 (dh=coeffᵀ@W). Correct, `[M,V]`-free, **slow (3375ms)**.
|
|
425
|
-
- `BWD_SOURCE` / `bwdKernel` — float4 scalar backward fallback.
|
|
426
|
-
- **STEEL BACKWARD** 🔬 — the NEW one: `scripts/experiments/steel-bwd-test.ts`, validated
|
|
427
|
-
dh 1.6e-5, NOT yet a production kernel (`BWD_STEEL_SOURCE` is M1's job).
|
|
428
|
-
|
|
429
|
-
## C. The steel port (`src/train/steel-qmm-header.ts`) — OURS (verbatim from MLX)
|
|
430
|
-
MLX's quantized `steel` GEMM, copied verbatim so we run at MLX speed (~46% peak vs our
|
|
431
|
-
hand-rolled 8%). The `STEEL_QMM_HEADER` string contains:
|
|
432
|
-
- **`BlockMMA`** — the tiled matmul (BM×BN output, BK contraction, WM×WN simdgroups, the
|
|
433
|
-
K-pipeline). The thing that makes MLX fast.
|
|
434
|
-
- **`MMATile` / `BaseMMAFrag` / `tile_matmad`** — the 8×8 simdgroup-matrix fragment
|
|
435
|
-
abstraction BlockMMA is built on (used directly for the persistent dh accumulator).
|
|
436
|
-
- **`QuantizedBlockLoader`** — loads packed quantized weights and dequantizes them
|
|
437
|
-
straight into the threadgroup matmul tile (fused dequant, no separate pass).
|
|
438
|
-
- **`BlockLoader`** — loads the dense input (X / coeff) into the tile.
|
|
439
|
-
- **`qmm_t_impl`** — MLX's full quantized-matmul orchestration (we use it for the
|
|
440
|
-
forward; the backward composes BlockMMA + tile_matmad ourselves).
|
|
441
|
-
- Tile params we use: **BM=8/32, BN=32, BK=32, WM=1, WN=4** (the `WM=1,WN=4` is the key
|
|
442
|
-
that makes BlockMMA's output tiling match our `[M,V]`-free per-simdgroup H-slice accum).
|
|
443
|
-
|
|
444
|
-
## D. The epilogue (what we FUSE on top of the steel GEMM) — OURS
|
|
445
|
-
MLX has no "quant-matmul + softcap + response-logp" op, so we add:
|
|
446
|
-
- **Softcap** — `cap·tanh(raw/cap)` (Gemma final-logit cap; e4b cap=30, cpm none) + its
|
|
447
|
-
`sech²` chain-rule term in the backward.
|
|
448
|
-
- **Online softmax** — running `(max, sumexp)` over vocab blocks → `lse` (forward).
|
|
449
|
-
- **Gather / target capture** — pick the target token's logit per row.
|
|
450
|
-
- **softmax−onehot coeff** — the backward gradient `coeff = g·(onehot − softmax)·sech²`.
|
|
451
|
-
- **MLX merge** — combine the `[M,NBLK]` per-vocab-block partials → `logp`/`lse` in MLX.
|
|
452
|
-
|
|
453
|
-
## E. Backward approximations (opt-in, default-off, data-dependent) — OURS
|
|
454
|
-
Both are Apple-CCE-style skips that proved unreliable on flat/synthetic softmax, so they
|
|
455
|
-
are OFF by default and live in the OLD backward; probably NOT needed once steel is fast.
|
|
456
|
-
- **Coeff filter** (`MLX_BUN_CCE_BWD_FILTER_EPS`) — skip phase-2 chunks whose whole coeff
|
|
457
|
-
block < eps.
|
|
458
|
-
- **blockMax vocab-block skip** (`MLX_BUN_CCE_BWD_BLOCK_EPS`) — skip whole cold
|
|
459
|
-
(token-block, vocab-block) programs using the forward's `blockMax`.
|
|
460
|
-
|
|
461
|
-
## F. Model-level optimizations (above the head)
|
|
462
|
-
- **Prefix-sharing** (`src/train/prefix-shared.ts`, `orpoLossPrefixShared`,
|
|
463
|
-
`blockSparseMask`, `PrefixSharedCache`) 🟢 — OURS (earlier this arc). One forward over
|
|
464
|
-
`[prompt ; chosen ; rejected]` with a block-sparse mask (chosen & rejected each attend
|
|
465
|
-
the shared prompt but NOT each other) → prompt encoded ONCE, single fwd/bwd for the
|
|
466
|
-
pair. Bit-exact for MiniCPM5; e4b has a bf16 length-sensitivity caveat. Built + parity
|
|
467
|
-
script, NOT wired into the trainer.
|
|
468
|
-
- **Segmented backward** (`src/train/segmented.ts`, `SegmentedBackwardOrpo*`,
|
|
469
|
-
`segmentSize`) 📦✅ — gradient checkpointing for the TRANSFORMER LAYER activations (the
|
|
470
|
-
real memory wall at long seq; orthogonal to the head). Composes with the flash head
|
|
471
|
-
(`fusedLogpMeanFromHidden` carries the `flash` flag).
|
|
472
|
-
|
|
473
|
-
## G. Wiring / config layer
|
|
474
|
-
- **`makeFlashCceHeadVjp`** (`loss.ts`) — wraps flashCceForward/Backward as a `CustomVjp`
|
|
475
|
-
(fwd→Σlogp, stash lse+blockMax; bwd→dh×cotangent). OURS.
|
|
476
|
-
- **`ChunkCtx`** (`loss.ts`) — the head config struct: `{fused, flash, chunkSize,
|
|
477
|
-
vocabBlock, sink}`.
|
|
478
|
-
- **`orpoLoss` / `branchLogpMean`** (`loss.ts`) — the ORPO loss entry; B=1 routes to the
|
|
479
|
-
fused/flash head, B>1 to full-logits.
|
|
480
|
-
- **Trainer flags** (`trainer.ts` / `job.ts`): `orpoFusedCe`, `orpoFlashCe`, `segmentSize`,
|
|
481
|
-
`orpoChunkSize`, `orpoLambda`. CLI: `--orpo-flash-ce` etc.
|
|
482
|
-
|
|
483
|
-
## H. Baselines / numbers to remember
|
|
484
|
-
- MLX `quantizedMatmul` raw GEMM (the speed reference): e4b fwd **151ms**, bwd **330ms**.
|
|
485
|
-
- Fused head total: **481ms** exact.
|
|
486
|
-
- Our steel forward: **180ms** (raw GEMM 101ms; +epilogue). Old SG forward: 848ms.
|
|
487
|
-
- Our backward: old SG **3375ms** (live); steel target ~hundreds of ms (M1).
|
|
488
|
-
- flash-CCE backward peak: **0.93 GB flat @ M=8192** (weights-dominated; kernel ~5MB;
|
|
489
|
-
linear in M, flat in V).
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# THE DREAMING — HANDOFF (2026-06-28)
|
|
2
|
-
|
|
3
|
-
Live handoff for the local personal-wiki memory system (`src/memory/`). A fresh
|
|
4
|
-
session can resume from this doc. **Companion docs:** `research-journal.md` (dated
|
|
5
|
-
findings), `docs/design/memory-inference-path.md` (the in-progress templating/batching
|
|
6
|
-
rework), and the per-phase `p*-judge.md` reports.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## TL;DR — where we are
|
|
11
|
-
|
|
12
|
-
The Dreaming turns conversations → chunks → entities → **subject articles** →
|
|
13
|
-
cross-linked, self-healing personal wiki. It **works end-to-end on real data.**
|
|
14
|
-
|
|
15
|
-
- **Full-corpus import RESUMED from cursor 720/2096** into `~/.mlx-bun/wiki-full`, on the
|
|
16
|
-
corrected templating, batching off (serial, ~50h).
|
|
17
|
-
- **Committed + merged to `main`** (the Dreaming pipeline + inference-path rework). tsc 0.
|
|
18
|
-
- Templating fix **VERIFIED live** on real convs (bare prompt + a 40-msg conv → valid chunks).
|
|
19
|
-
|
|
20
|
-
## Resume the import
|
|
21
|
-
```
|
|
22
|
-
# resumable driver; continues from cursor 720. Writes to ~/.mlx-bun/wiki-full (NOT the
|
|
23
|
-
# real vault ~/.mlx-bun/wiki). ~25 min / 20-conv batch, ~50h total, SERIAL.
|
|
24
|
-
bun scripts/memory/dreaming-full-run.ts # resume (clean-slate guarded by an init flag)
|
|
25
|
-
# state files: ~/.mlx-bun/full-run-cursor.txt, ~/.mlx-bun/full-run-initialized, ~/.mlx-bun/full-run.log
|
|
26
|
-
# after the import finishes: reindex, then connect the graph:
|
|
27
|
-
mlx-bun memory link
|
|
28
|
-
```
|
|
29
|
-
**Gotcha:** background bash + detached processes get **reaped across turns** in this
|
|
30
|
-
harness. Drive long GPU runs as foreground bounded batches, or `nohup … & disown` (still
|
|
31
|
-
iffy). The pipeline is resumable, so just re-launch to continue.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Architecture (as-built, after this session's corrections)
|
|
36
|
-
|
|
37
|
-
**Staged, chronological, resumable pipeline** (`src/memory/stages.ts`). Each stage is an
|
|
38
|
-
independent DB-state-keyed worker, ordered `updated_at ASC` (chronological), resumable
|
|
39
|
-
(skips done work). CLI: `mlx-bun memory segment|extract|route|synthesize-stage|link` (run
|
|
40
|
-
separately/concurrently) — and `mlx-bun memory synthesize` runs the full DAG.
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
ingest → SEGMENT (our e4b-chunk-300 chunker) → EXTRACT (entities) → ROUTE (subject-based,
|
|
44
|
-
surface-everything) → CREATE/PATCH (per-section bounded synthesis; self-healing) →
|
|
45
|
-
RECONCILE (infobox-ground-truth consistency) → LINK (cross-link) → WIKIFY (editorial) → commit
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
- **Vault = truth** (markdown files in `articles/`); **DB = derived cache** (`reindex`
|
|
49
|
-
rebuilds it). The article FILES are the real artifacts. The `entities.article_stem`
|
|
50
|
-
column being unset mid-run is cosmetic (file-presence is the source of truth).
|
|
51
|
-
- **Vaults:** `~/.mlx-bun/wiki` (the REAL vault — untouched), `~/.mlx-bun/wiki-full`
|
|
52
|
-
(import target), `wiki-smoke|slice|pattern|pattern2|link-test` (scratch).
|
|
53
|
-
- **Model:** ONE base **Gemma-4-e4b** (`SNAPSHOT_E4B`). **Only ONE adapter trained so far:
|
|
54
|
-
`e4b-chunk-300`** (the chunker), symlinked `~/.cache/mlx-bun/adapters/memory-chunk`.
|
|
55
|
-
`callLocal(stage,…)` picks `memory-<stage>` adapter iff it exists, else base.
|
|
56
|
-
- **Lucien is a READ-ONLY oracle/data-source** (`~/Code/lucien/.lucien/lucien.db` opened
|
|
57
|
-
readonly; `~/Dreaming`). We reuse NONE of its derived chunks/buckets — only the raw
|
|
58
|
-
conversation text (≡ a JSONL export / scraper). Never write there.
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## What we LEARNED / CORRECTED this session (load-bearing — don't re-derive)
|
|
63
|
-
|
|
64
|
-
1. **NO notability/ownership filter.** Surface everything; notable = "anything that recurs
|
|
65
|
-
in your thinking" (Lucien `Editorial_Guidelines.md`). The plan's "owned/decided/≥3
|
|
66
|
-
chunks → PARK as trivia" was **fabricated by a prior agent and ripped out.** ROUTE now:
|
|
67
|
-
surface everything, strongly prefer an existing article, mint a new one only for a
|
|
68
|
-
substantive/recurring subject, `_captured` bucket (searchable) for the rest — **nothing
|
|
69
|
-
dropped.**
|
|
70
|
-
2. **Subject-based articles = the one deliberate improvement over Lucien** (which drifted
|
|
71
|
-
into `X_and_Y` topic-bins). Verified: frameworks (Kaizen, TPS, LessWrong, Free energy
|
|
72
|
-
principle) get good articles; coverage resolves (`resolve("Kaizen")` → article).
|
|
73
|
-
3. **Our chunker must be used.** The pipeline's `segment` was a no-op reusing Lucien's
|
|
74
|
-
chunks; fixed — `e4b-chunk-300` segments the raw conversations (better, topic-coherent).
|
|
75
|
-
4. **Chronological ordering.** Was `ORDER BY id` (= conv UUID, random); fixed to
|
|
76
|
-
`updated_at ASC` everywhere. Load-bearing for self-healing.
|
|
77
|
-
5. **Self-healing.** A later-dated correction flips the LEAD + INFOBOX + every body section
|
|
78
|
-
to the latest value; KEEPS the trajectory in a `## History` section **only for the
|
|
79
|
-
USER's evolving positions** — an AI *factual error* is silently overwritten (no
|
|
80
|
-
history). Date-aware; `reconcile.ts` is the consistency authority (infobox = ground
|
|
81
|
-
truth). Proven via a timestamp-swap demo (`scripts/memory/dreaming-selfheal-demo.ts`).
|
|
82
|
-
6. **Parroting (recurred 5×).** The small model copies ANY concrete example value from
|
|
83
|
-
prompts/Meta pages into unrelated articles (phantom S5IIX, "Anamorphic Video", etc.).
|
|
84
|
-
**ALL prompts + Meta pages must be SCHEMATIC** (no real names/specs/dates). Purged;
|
|
85
|
-
defensive strips added. Keep this rule for any new prompt.
|
|
86
|
-
7. **Cross-linking is WIKIFY's job, NOT synthesis** (synthesis updates ONE article, can't
|
|
87
|
-
know others). Built a dedicated `link` stage (`crosslink.ts`): mention-based (prose
|
|
88
|
-
names another article → `[[link]]`) + co-occurrence (shared folded chunks → See also).
|
|
89
|
-
Result on a 587-article snapshot: See-also 18%→96%, resolved edges 309→**7026 (22.7×)**.
|
|
90
|
-
Idempotent; fence-fix handles malformed input.
|
|
91
|
-
8. **Metrics.** Do NOT measure articles-per-conversation (there is no conv→article link).
|
|
92
|
-
Measure **topic aggregation** (e.g. `El_Salvador` ← 30 conversations → 1 article).
|
|
93
|
-
Quality is judged by a **CLOUD JUDGE on real output**, never Lucien bucket-F1 (that's the
|
|
94
|
-
bin taxonomy we replace).
|
|
95
|
-
9. **Inference path (IN PROGRESS — see `docs/design/memory-inference-path.md`):**
|
|
96
|
-
- **Template mismatch (fixed in working tree):** the chunk adapter was SFT'd with a
|
|
97
|
-
**system role** (Gemma-4 renders `<|turn>system…<turn|>` distinctly), but inference
|
|
98
|
-
dropped it (one user message). `callLocal` now passes `{system, user}` matching
|
|
99
|
-
training; the chunk stage uses `CHUNK_SYSTEM` (its exact trained system prompt). Also
|
|
100
|
-
noted: the live `CHUNK_PROMPT` drifted from training (only 2 of 8 Meta pages; abstracted
|
|
101
|
-
examples) — adapter still generalizes, so quality delta is **modest**.
|
|
102
|
-
- **Batching = DEAD END.** Measured ~**1.7× SLOWER** (warm, uniform: 0.607 vs 0.357
|
|
103
|
-
s/chunk). The `BatchScheduler` pads heterogeneous prefills and doesn't amortize
|
|
104
|
-
weight-loads. Default OFF (`MLX_BUN_MEMORY_BATCH=1`). Import is genuinely ~50h serial;
|
|
105
|
-
batching is NOT the lever (a *better* batched-decode that amortizes weights could help
|
|
106
|
-
in principle, but that's a real perf project, not worth it for a one-time import).
|
|
107
|
-
- **Load-once / persistent server = the REAL efficiency win, for DAILY use.** Each CLI
|
|
108
|
-
invocation today reloads the model + pays warmup; routing memory generation through the
|
|
109
|
-
**resident server** (model loaded once) kills that. Within the single-process import
|
|
110
|
-
the model is already loaded once, so it doesn't speed the import.
|
|
111
|
-
|
|
112
|
-
## Product framing (from the user)
|
|
113
|
-
- **Daily local conversations (pi sessions) folding in is the product** — watermark-gated
|
|
114
|
-
ingest, minutes/day, self-healing. The 4-year Claude/ChatGPT import is a one-time
|
|
115
|
-
**onboarding feature + stress test**. Throughput only matters for the import.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## NEXT STEPS (prioritized)
|
|
120
|
-
|
|
121
|
-
1. **Finish the inference-path rework.** Templating fix is in the working tree (verify it
|
|
122
|
-
end-to-end). **Wire memory generation through the persistent server (load-once)** — the
|
|
123
|
-
user's actual ask — keeping a no-server fallback; default batching OFF. Verify the chunk
|
|
124
|
-
stage decodes on-distribution (system role present).
|
|
125
|
-
2. **Import is RUNNING** (resumed from 720, serial, corrected templating). Just let it finish.
|
|
126
|
-
Re-segmenting the first 720 is **low-urgency** (old chunks were valid).
|
|
127
|
-
3. **After import:** `reindex` → `mlx-bun memory link` → browse `wiki-full` in Obsidian;
|
|
128
|
-
cloud-judge a broad, diverse sample (not just frameworks/gear).
|
|
129
|
-
4. **Promote to the real vault** when satisfied: point `~/.mlx-bun/wiki` at the bootstrapped
|
|
130
|
-
content; wire the **nightly daily fold-in** from pi sessions (`schedule.ts` exists).
|
|
131
|
-
5. **Open quality items** (low priority): ~<1% articles leak a prompt fragment; some leads
|
|
132
|
-
run on; the `owned/used/chosen` framing in `Article_Conventions` lead spec can put
|
|
133
|
-
`owned: yes` on abstract concepts (reframe).
|
|
134
|
-
6. **Commit when ready** — everything is uncommitted; the user has not asked to commit.
|
|
135
|
-
|
|
136
|
-
## Gotchas / facts
|
|
137
|
-
- `bunx tsc` sometimes can't resolve typescript in this checkout; use global `tsc`. Repo = 0 errors.
|
|
138
|
-
- The `mlx-bun train-watch orpo-e4b-chunk` process is a **stale idle daemon, not training** — GPU is free.
|
|
139
|
-
- e4b training still OOMs on this 32GB M1 Max; P10 adapter training stays USER-ACTION (segmented-backward).
|
|
140
|
-
- The `Reference/` folder in vaults symlinks the mlx-bun repo docs (`setupVault`) — non-portable; fine for now, drop for the real personal vault.
|
|
141
|
-
- Methodology memories: cloud-judge not bucket-F1; Lucien read-only; surface-everything notability.
|