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.
- package/README.md +71 -578
- package/bin/mlx-bun.mjs +1 -1
- package/docs/README.md +91 -0
- package/docs/{design → archive}/hlg-sampling.md +3 -3
- package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
- package/docs/{design → archive/investigations}/colibri-glm52-port.md +1 -1
- package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
- package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
- package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
- package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
- package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
- package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
- package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
- package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
- package/docs/{planning → archive/planning}/chunk-task-roadmap.md +1 -1
- package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +4 -4
- package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +1 -1
- package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
- package/docs/archive/planning/release-notes-v0.2.0.md +49 -0
- package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
- package/docs/design/batching.md +569 -0
- package/docs/design/decode-speed-program.md +3178 -169
- package/docs/design/dreaming-nightly-pipeline.md +675 -282
- package/docs/design/generic-model-support.md +579 -334
- package/docs/design/kv-cache.md +680 -0
- package/docs/design/orpo-training.md +673 -1239
- package/docs/design/speculative-decoding.md +1627 -0
- package/docs/design/turboquant.md +2102 -0
- package/docs/design/unified-engine-frontier-plan.md +1831 -727
- package/docs/design/web-chat-redesign.md +666 -1083
- package/docs/planning/PRODUCT_ROADMAP.md +34 -1
- package/docs/planning/release-notes-v0.3.0.md +35 -0
- package/docs/planning/video-series.md +421 -0
- package/docs/reference/benchmarks.md +1162 -0
- package/docs/reference/cli.md +395 -149
- package/docs/reference/distribution.md +321 -181
- package/docs/reference/environment.md +348 -0
- package/docs/reference/glossary.md +39 -0
- package/docs/reference/library-api.md +580 -142
- package/docs/reference/memory.md +227 -64
- package/docs/reference/models.md +137 -6
- package/docs/reference/server-api.md +938 -422
- package/docs/reference/server-config.md +652 -320
- package/docs/reference/training.md +393 -254
- package/docs/reference/troubleshooting.md +166 -0
- package/package.json +10 -5
- package/src/admission-plan.ts +18 -0
- package/src/anthropic.ts +92 -3
- package/src/audio/decode.ts +2 -2
- package/src/audio/features.ts +2 -2
- package/src/backends/mlx/autoregressive.ts +108 -0
- package/src/backends/mlx/batch-group.ts +1646 -0
- package/src/backends/mlx/diffusion.ts +39 -0
- package/src/backends/mlx/draft-target.ts +47 -0
- package/src/backends/mlx/evaluation.ts +105 -0
- package/src/backends/mlx/fill-append.ts +45 -0
- package/src/backends/mlx/gateway-binding.ts +71 -0
- package/src/backends/mlx/graph.ts +38 -0
- package/src/backends/mlx/memory-client.ts +189 -0
- package/src/backends/mlx/memory-guard.ts +40 -0
- package/src/backends/mlx/methods.ts +90 -0
- package/src/backends/mlx/model-prompt.ts +164 -0
- package/src/backends/mlx/model-serving.ts +79 -0
- package/src/backends/mlx/prefill.ts +33 -0
- package/src/backends/mlx/request-policy.ts +20 -0
- package/src/backends/mlx/rollback.ts +51 -0
- package/src/backends/mlx/serial-executor.ts +273 -0
- package/src/backends/mlx/speculative.ts +114 -0
- package/src/backends/mlx/state-views.ts +26 -0
- package/src/backends/mlx/text-engine.ts +73 -0
- package/src/cli.ts +189 -61
- package/src/client.ts +66 -0
- package/src/config.ts +21 -4
- package/src/contracts/completion.ts +16 -0
- package/src/contracts/execution.ts +49 -0
- package/src/contracts/generation.ts +103 -0
- package/src/contracts/host.ts +7 -0
- package/src/contracts/jobs.ts +66 -0
- package/src/contracts/pi-provider.ts +30 -0
- package/src/contracts/pi.ts +259 -0
- package/src/contracts/resources.ts +18 -0
- package/src/contracts/scheduling.ts +27 -0
- package/src/contracts/tsconfig.json +14 -0
- package/src/diffusion/diffusion-generate.ts +218 -153
- package/src/embed.ts +1 -1
- package/src/engine/admission.ts +59 -0
- package/src/engine/cancellation.ts +38 -0
- package/src/engine/engine.ts +56 -0
- package/src/engine/execution-coordinator.ts +70 -0
- package/src/engine/execution-plan.ts +51 -0
- package/src/engine/resources.ts +42 -0
- package/src/engine/scheduler.ts +67 -0
- package/src/engine/session.ts +247 -0
- package/src/eval/README.md +44 -1
- package/src/eval/kl.ts +263 -23
- package/src/eval/reference-logits.ts +207 -0
- package/src/eval/runner.ts +10 -79
- package/src/eval/tasks/bfcl.ts +2 -1
- package/src/eval/tasks/gsm8k.ts +2 -1
- package/src/eval/tasks/hashhop.ts +2 -1
- package/src/eval/tasks/humaneval.ts +5 -4
- package/src/eval/tasks/ifeval.ts +2 -1
- package/src/eval/tasks/mmlu.ts +2 -1
- package/src/expert-io.ts +3 -1
- package/src/expert-offload.ts +3 -1
- package/src/fill/echo-index.ts +188 -0
- package/src/fill/fill-session.ts +452 -0
- package/src/fill/proposal.ts +68 -0
- package/src/fill/schema-rows.ts +506 -0
- package/src/fill/tool-boundary.ts +103 -0
- package/src/fit.ts +24 -43
- package/src/generate.ts +740 -337
- package/src/grammar.ts +14 -8
- package/src/harness-pi.ts +15 -34
- package/src/hub-rest.ts +4 -4
- package/src/index.ts +27 -0
- package/src/inference/denoising.ts +17 -0
- package/src/inference/graph.ts +33 -0
- package/src/inference/prefill.ts +39 -0
- package/src/inference/rollback.ts +7 -0
- package/src/jobs/db.ts +4 -0
- package/src/jobs/index.ts +2 -0
- package/src/jobs/job-entry.ts +15 -14
- package/src/jobs/runner.ts +98 -13
- package/src/jobs/task-client.ts +19 -0
- package/src/jobs/types.ts +2 -58
- package/src/kv-scheme.ts +199 -0
- package/src/kv-store.ts +459 -234
- package/src/lab/README.md +18 -0
- package/src/{assets → lab/curve}/curve-designer.html +2 -2
- package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
- package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +7 -5
- package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
- package/src/library.ts +40 -0
- package/src/lora.ts +18 -0
- package/src/media-fetch.ts +20 -4
- package/src/memory/article.ts +1 -1
- package/src/memory/chunk.ts +1 -1
- package/src/memory/model.ts +32 -170
- package/src/memory/prompts.ts +1 -1
- package/src/memory/rest.ts +1 -1
- package/src/memory/schedule.ts +1 -1
- package/src/memory/stages.ts +4 -1
- package/src/memory/vault.ts +3 -4
- package/src/mlx/array.ts +9 -10
- package/src/mlx/compile.ts +12 -2
- package/src/mlx/ffi.ts +66 -22
- package/src/mlx/materialize.ts +23 -0
- package/src/mlx/metal-kernel.ts +10 -11
- package/src/mlx/ops.ts +64 -19
- package/src/mlx/quantized-rows.ts +36 -0
- package/src/mlx/token-bitmask.ts +52 -0
- package/src/mlx/turboquant-kv-decode.ts +82 -0
- package/src/mlx/turboquant-kv-inverse.ts +122 -0
- package/src/mlx/turboquant-ops.ts +33 -3
- package/src/mlx/turboquant-tables.ts +2 -2
- package/src/model/batched-mask.ts +9 -3
- package/src/model/batched-quant.ts +2 -2
- package/src/model/batched-rotating-quant.ts +45 -99
- package/src/model/batched-rotating-state.ts +73 -0
- package/src/model/batched-rotating.ts +57 -106
- package/src/model/batched-row-storage.ts +127 -0
- package/src/model/compiled-decode.ts +4 -3
- package/src/model/diffusion-gemma.ts +8 -8
- package/src/model/factory.ts +87 -49
- package/src/model/fingerprint.ts +1 -1
- package/src/model/flash-attention.ts +3 -3
- package/src/model/gemma4-base.ts +187 -17
- package/src/model/gemma4.ts +6 -6
- package/src/model/generated/gemma4-12b.ts +52 -148
- package/src/model/generated/gemma4-26b.ts +34 -94
- package/src/model/generated/gemma4-e4b.ts +28 -76
- package/src/model/glm52-cache.ts +19 -9
- package/src/model/glm52-dsa.ts +13 -9
- package/src/model/glm52-memory.ts +28 -1
- package/src/model/implementation.ts +69 -0
- package/src/model/minicpm5.ts +7 -8
- package/src/model/profile.ts +443 -0
- package/src/model/qwen-append.ts +12 -0
- package/src/model/qwen-conv.ts +52 -0
- package/src/model/qwen3-delta.ts +98 -2
- package/src/model/qwen3-mrope.ts +252 -0
- package/src/model/qwen3_5-checkpoint.ts +164 -0
- package/src/model/qwen3_5.ts +336 -60
- package/src/model/support.ts +1 -1
- package/src/model/trellis-balanced-scatter.ts +51 -0
- package/src/model/trellis-linear.ts +672 -0
- package/src/model/trellis-shared-m.ts +151 -0
- package/src/model/trellis-shared-scatter.ts +144 -0
- package/src/model/trellis-splitk-prefill.ts +158 -0
- package/src/model/trellis-tiled-prefill.ts +136 -0
- package/src/model/trellis-vector-expand.ts +62 -0
- package/src/model/trellis-wide-prefill.ts +94 -0
- package/src/model/universal/dense.ts +1 -1
- package/src/model/universal/modules.ts +8 -1
- package/src/native/frame_extract.swift +140 -0
- package/src/native-pack.ts +15 -7
- package/src/pi-provider.ts +6 -64
- package/src/pi-web.ts +14 -320
- package/src/prompt-cache.ts +97 -54
- package/src/quantize/allocator.ts +1 -1
- package/src/quantize/atomic-output.ts +38 -0
- package/src/quantize/calibration.ts +2 -1
- package/src/quantize/config-writer.ts +16 -3
- package/src/quantize/index.ts +28 -1
- package/src/quantize/job.ts +11 -0
- package/src/quantize/quantizer.ts +265 -100
- package/src/quantize/rotate.ts +603 -0
- package/src/quantize/safetensors-writer.ts +79 -1
- package/src/quantize/sensitivity.ts +41 -59
- package/src/quantize/trellis.ts +586 -0
- package/src/quantize/weight-transform.ts +292 -0
- package/src/responses.ts +130 -3
- package/src/runtime-config.ts +81 -0
- package/src/sampler.ts +276 -4
- package/src/serve/admin-routes.ts +184 -0
- package/src/serve/aux-routes.ts +132 -0
- package/src/serve/batch-scheduler.ts +8 -1558
- package/src/serve/chat-request.ts +391 -0
- package/src/serve/chat-stage.ts +195 -0
- package/src/serve/checkpoint-identity.ts +64 -0
- package/src/serve/completion-executor.ts +354 -0
- package/src/serve/completion-sink.ts +157 -0
- package/src/serve/discovery-routes.ts +204 -0
- package/src/serve/generation-gateway.ts +211 -243
- package/src/serve/http.ts +159 -0
- package/src/serve/inference-request.ts +79 -0
- package/src/serve/isolate.ts +297 -105
- package/src/serve/kv-budget.ts +14 -0
- package/src/serve/lab-routes.ts +341 -0
- package/src/serve/lane-registry.ts +2 -1
- package/src/serve/model-admin-routes.ts +155 -0
- package/src/serve/model-binding.ts +43 -0
- package/src/serve/model-host.ts +512 -0
- package/src/serve/openai-wire.ts +103 -0
- package/src/serve/parent-application.ts +56 -0
- package/src/serve/pipeline.ts +33 -0
- package/src/serve/preparation.ts +33 -0
- package/src/serve/prompt-response-trace.ts +147 -0
- package/src/serve/request-plan.ts +162 -0
- package/src/serve/request-prep.ts +346 -0
- package/src/serve/response-lease.ts +24 -0
- package/src/serve/responses-client.ts +69 -0
- package/src/serve/session-completion-engine.ts +110 -0
- package/src/serve/session-search.ts +1 -1
- package/src/serve/static-routes.ts +101 -0
- package/src/serve/text-completion-stage.ts +104 -0
- package/src/serve/token-streams.ts +519 -0
- package/src/server.ts +523 -3551
- package/src/spec/assistant-source.ts +10 -44
- package/src/spec/deepspec-source.ts +6 -6
- package/src/spec/dflash-source.ts +9 -8
- package/src/spec/dspark/ab-stats.ts +3 -3
- package/src/spec/dspark/calibration.ts +2 -2
- package/src/spec/dspark/deepspec-module.ts +2 -2
- package/src/spec/dspark/generate-dflash.ts +2 -2
- package/src/spec/dspark/generate.ts +2 -2
- package/src/spec/dspark/loader.ts +1 -1
- package/src/spec/dspark/module-dflash.ts +5 -4
- package/src/spec/dspark/module.ts +3 -3
- package/src/spec/dspark/quantize-drafter.ts +1 -1
- package/src/spec/generate.ts +1 -1
- package/src/spec/glm52-mtp-source.ts +9 -1
- package/src/spec/ngram-source.ts +1 -1
- package/src/spec/prefix-state.ts +45 -0
- package/src/spec/qwen-mtp-source.ts +528 -0
- package/src/spec/serve-loop.ts +179 -213
- package/src/spec/source.ts +42 -10
- package/src/spec/two-model.ts +1 -1
- package/src/ssd-cache.ts +95 -24
- package/src/ssd-durability.ts +207 -0
- package/src/tool-call.ts +51 -14
- package/src/train/flash-cce.ts +14 -13
- package/src/train/forward.ts +38 -1
- package/src/train/loss.ts +3 -2
- package/src/train/prefix-shared.ts +5 -1
- package/src/train/segmented.ts +9 -6
- package/src/train/trainer.ts +9 -8
- package/src/vision/preprocess.ts +1 -1
- package/src/vision/prompt.ts +48 -2
- package/src/vision/qwen3vl-preprocess.ts +409 -0
- package/src/vision/qwen3vl-prompt.ts +196 -0
- package/src/vision/qwen3vl-tower.ts +555 -0
- package/src/vision/video-frames.ts +148 -0
- package/src/web/app.html +1 -1
- package/src/web/app.js +15 -6
- package/src/web/src/adapters-panel.ts +3 -3
- package/src/web/src/assistant.ts +2 -36
- package/src/web/src/chat.ts +16 -9
- package/src/web/src/composer.ts +4 -4
- package/src/web/src/hub.ts +1 -1
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +1 -1
- package/src/web/src/model-picker.ts +1 -1
- package/src/web/src/palette.ts +1 -1
- package/src/web/src/protocol.ts +3 -39
- package/src/web/src/sessions.ts +1 -1
- package/src/web/src/ui-catalog.ts +4 -18
- package/src/web-assets.ts +47 -0
- package/src/weights.ts +134 -33
- package/docs/archive/mlx-bun-lab-report.html +0 -275
- package/docs/archive/wwdc-mlx-bun.html +0 -848
- package/docs/design/adapters-end-to-end.md +0 -205
- package/docs/design/batching-perf-path.md +0 -255
- package/docs/design/batching-v2-plan.md +0 -529
- package/docs/design/bucketing-stage.md +0 -197
- package/docs/design/compat-cli-surface-design.md +0 -230
- package/docs/design/docs-reorg-plan.md +0 -165
- package/docs/design/dspark-serving-program.md +0 -371
- package/docs/design/dspark-speculative-decoding.md +0 -268
- package/docs/design/grammar-spec-batching-integration.md +0 -301
- package/docs/design/memory-inference-path.md +0 -422
- package/docs/design/memory-synthesis.md +0 -287
- package/docs/design/memory-system.md +0 -237
- package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
- package/docs/design/omlx-adoption-map.md +0 -98
- package/docs/design/orpo-dynamic-lambda.md +0 -220
- package/docs/design/orpo-future-enhancements.md +0 -340
- package/docs/design/paged-kv-cache.md +0 -214
- package/docs/design/parallel-slots.md +0 -567
- package/docs/design/parity-tier-dag.md +0 -161
- package/docs/design/repo-cleanup-plan.md +0 -189
- package/docs/design/runtime-isolation.md +0 -263
- package/docs/design/segmented-backward-training.md +0 -543
- package/docs/design/spec-decode-larger-targets.md +0 -229
- package/docs/design/ssd-kv-cold-tier.md +0 -288
- package/docs/design/structured-output.md +0 -484
- package/docs/design/tauri-desktop-app.md +0 -127
- package/docs/design/the-dreaming-master-plan.md +0 -445
- package/docs/design/turboquant-kv.md +0 -235
- package/docs/design/w4a16-compute-precision-spike.md +0 -232
- package/docs/design/web-chat-beat-matrix.md +0 -315
- package/docs/design/write-pipeline-entity.md +0 -468
- package/docs/investigations/curve-runs/bisector-route.json +0 -98
- package/docs/investigations/curve-runs/bisector-trace.json +0 -1393
- package/docs/investigations/curve-runs/curve-terrain.json +0 -1179
- package/docs/investigations/curve-runs/curve-terrain.svg +0 -42
- package/docs/investigations/hlg-ab.html +0 -34
- package/docs/investigations/hlg-explorer.html +0 -238
- package/docs/investigations/hlg-figs/cliff.svg +0 -1
- package/docs/investigations/hlg-figs/cross.svg +0 -1
- package/docs/investigations/hlg-figs/edges.svg +0 -1
- package/docs/investigations/hlg-figs/k20-grids.svg +0 -1
- package/docs/investigations/hlg-figs/k20-peaks.svg +0 -1
- package/docs/investigations/hlg-figs/lw-curve.svg +0 -1
- package/docs/investigations/hlg-figs/terrain.svg +0 -1
- package/docs/investigations/hlg-report.html +0 -262
- package/docs/investigations/hlg-runs/hlg-ab.json +0 -149
- package/docs/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
- package/docs/investigations/hlg-runs/hlg-blind.json +0 -107
- package/docs/investigations/hlg-runs/hlg-cliff.json +0 -197
- package/docs/investigations/hlg-runs/hlg-cross.json +0 -505
- package/docs/investigations/hlg-runs/hlg-edge.json +0 -388
- package/docs/investigations/hlg-runs/hlg-eval1.json +0 -25
- package/docs/investigations/hlg-runs/hlg-frontier.json +0 -86
- package/docs/investigations/hlg-runs/hlg-grid.json +0 -242
- package/docs/investigations/hlg-runs/hlg-grid2.json +0 -343
- package/docs/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
- package/docs/investigations/hlg-runs/hlg-map.json +0 -383
- package/docs/investigations/hlg-runs/run0-original.log +0 -159
- package/docs/investigations/hlg-runs/runA-recommended.log +0 -131
- package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
- package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
- package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
- package/docs/investigations/hlg-runs/runAD-ab-samples.log +0 -8
- package/docs/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
- package/docs/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
- package/docs/investigations/hlg-runs/runAG-eval-config2.log +0 -16
- package/docs/investigations/hlg-runs/runB-gain-variants.log +0 -192
- package/docs/investigations/hlg-runs/runC-pivots.log +0 -162
- package/docs/investigations/hlg-runs/runD-oetf.log +0 -132
- package/docs/investigations/hlg-runs/runE-eotf.log +0 -162
- package/docs/investigations/hlg-runs/runF-shaper-working.log +0 -86
- package/docs/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
- package/docs/investigations/hlg-runs/runH-wsweep.log +0 -176
- package/docs/investigations/hlg-runs/runI-asweep.log +0 -176
- package/docs/investigations/hlg-runs/runJ-knobmap.log +0 -49
- package/docs/investigations/hlg-runs/runK-frontier.log +0 -19
- package/docs/investigations/hlg-runs/runL-widemap.log +0 -65
- package/docs/investigations/hlg-runs/runM-frontier-emb.log +0 -15
- package/docs/investigations/hlg-runs/runN-verify.log +0 -116
- package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
- package/docs/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
- package/docs/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
- package/docs/investigations/hlg-runs/runR-blind-transcript.log +0 -79
- package/docs/investigations/hlg-runs/runS-cross-coherence.log +0 -33
- package/docs/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
- package/docs/investigations/hlg-runs/runU-cross-12b.log +0 -33
- package/docs/investigations/hlg-runs/runV-lw-e4b.log +0 -22
- package/docs/investigations/hlg-runs/runW-lw-12b.log +0 -22
- package/docs/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
- package/docs/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
- package/docs/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
- package/docs/planning/IDEAS.md +0 -69
- package/docs/reference/embedding.md +0 -197
- package/docs/reference/features-matrix.md +0 -100
- package/docs/reference/orpo-quickstart.md +0 -135
- package/src/flags.ts +0 -13
- /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
- /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
- /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
- /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
- /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
- /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
- /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
- /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
- /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
- /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
- /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
- /package/docs/{planning → archive/planning}/journal.md +0 -0
- /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.13.md +0 -0
- /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
- /package/{docs/investigations → src/serve/assets}/curve-terrain.html +0 -0
- /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
# DSpark serving program — flip spec wall-clock positive + design the product surface
|
|
2
|
-
|
|
3
|
-
Status: **PLANNED** (2026-07-07). Trigger for Josh's pickup: TurboQuant merge —
|
|
4
|
-
but only Phase 5 actually depends on it; Phases 0–4 are start-anytime.
|
|
5
|
-
Owner: decode / spec. Predecessors: PR #19 (DSpark paper code-complete +
|
|
6
|
-
serve-integrated + DeepSpec oracle), the first-live-run findings in
|
|
7
|
-
[dspark-handoff.md](../investigations/dspark-handoff.md) "FIRST LIVE RUN".
|
|
8
|
-
|
|
9
|
-
## The problem, in numbers (2026-07-07 first live run, loaded machine)
|
|
10
|
-
|
|
11
|
-
`gemma-4-12B-it-OptiQ-4bit` + `deepseek-ai/dspark_gemma4_12b_block7` (γ=7):
|
|
12
|
-
|
|
13
|
-
- **τ ≈ 2.8** committed tokens per target forward (2.7× fewer target calls) —
|
|
14
|
-
the algorithm WORKS, at 26–33% per-token acceptance (the predicted
|
|
15
|
-
OptiQ-4bit-target degradation vs their bf16 training).
|
|
16
|
-
- **Wall-clock LOST ~3.4×** (spec 14.6 vs serial 49.8 agg tok/s). The tax is
|
|
17
|
-
the drafter itself: 6.9 GB bf16 → ~3 GB of weight reads per draft round
|
|
18
|
-
(2 GB untied lm_head + 7 × 134 MB markov_w2 + layers), ~14 host syncs per
|
|
19
|
-
round in the transcription-faithful `draftBlock`, tapped verifies falling
|
|
20
|
-
back to the unoptimized monolith, and ~14 GB of two-model weights
|
|
21
|
-
squeezing the 24 GB box.
|
|
22
|
-
- The 20 s bench TTFT was conc-4 queueing on the serial-forced spec lane
|
|
23
|
-
(documented routing), not prefill — but per-request slowdown is real.
|
|
24
|
-
|
|
25
|
-
**Goal:** spec ≥ 1.3× serial decode on 12B at the best config, clean-machine
|
|
26
|
-
paired A/B — then (and only then) design when it's on by default. Every phase
|
|
27
|
-
has its own gate; the drafter-quantization thesis
|
|
28
|
-
([[drafter-quantization-thesis]]) makes the risky-looking phase (aggressive
|
|
29
|
-
quant) the SAFEST: drafter numerics only move acceptance, never correctness,
|
|
30
|
-
so the entire quality gate is one acceptance A/B.
|
|
31
|
-
|
|
32
|
-
**THE OBJECTIVE, stated right (Josh, 2026-07-07): 26–33% acceptance with the
|
|
33
|
-
bf16 drafter is the WORKABLE BASELINE — τ≈2.8 already pays. The question
|
|
34
|
-
quantization must answer is PRESERVATION: do we still get that number at
|
|
35
|
-
4-bit?** The point of quantizing (and of mixed precision specifically) is
|
|
36
|
-
never compression for its own sake — it's cutting the drafter's cost 4×
|
|
37
|
-
WITHOUT making it terrible at predicting tokens.
|
|
38
|
-
|
|
39
|
-
**Sensitivity is MEASURED, never guessed — and THE TOOL ALREADY EXISTS
|
|
40
|
-
(Josh): optiq's sensitivity method** (mlx-optiq.com/docs/sensitivity —
|
|
41
|
-
per-group simulate-quant → KL vs reference on a curated calibration mix →
|
|
42
|
-
greedy knapsack allocation to target BPW, emitted as a quant predicate).
|
|
43
|
-
Phase 1e adopts it for the drafter rather than inventing anything; the
|
|
44
|
-
drafter's target-hiddens-in forward even makes it cheaper (cached hiddens →
|
|
45
|
-
no 12B in the sweep loop). Allocation comes from the measured table;
|
|
46
|
-
hypotheses (lm_head argmax-proximal, chain compounding, buffered layers)
|
|
47
|
-
are recorded for falsification only. Phase 1.5 (fine-tune) is an OPTIONAL
|
|
48
|
-
UPSIDE lever on top of the workable baseline, not a premise that acceptance
|
|
49
|
-
is broken.
|
|
50
|
-
|
|
51
|
-
**And TurboQuant's role, stated right (Josh): TQ is the better-quant-at-
|
|
52
|
-
EQUAL-bits instrument — the preservation tool, not a compression ladder.**
|
|
53
|
-
Mechanism: distribute the weight vectors Gaussian, then place the
|
|
54
|
-
quantization levels non-uniformly with FINER step sizes around the peak
|
|
55
|
-
where the mass lives — affine 4-bit spends half its levels on tails TQ
|
|
56
|
-
barely pays for. Expected: TQ-4bit preserves acceptance better than
|
|
57
|
-
affine-4bit at the same size; the Phase-5 headline comparison is TQ-4 vs
|
|
58
|
-
affine-4 AT EQUAL BPW, with lower-bpw rungs only after that's won.
|
|
59
|
-
|
|
60
|
-
## Phase 0 — baseline + attribution (no code; Josh's shell for GPU runs)
|
|
61
|
-
|
|
62
|
-
The scoreboard everything else is measured against. All directional runs
|
|
63
|
-
fine on a loaded box; the FINAL pre/post pair must be clean-machine.
|
|
64
|
-
|
|
65
|
-
- [ ] **0a. Oracle gate the bf16 port ONCE** (before any optimization, so
|
|
66
|
-
later acceptance deltas are attributable to quant/tuning, not port bugs):
|
|
67
|
-
torch venv + DeepSpec install (header of
|
|
68
|
-
`scripts/oracle-dspark-deepspec.py` documents setup), dump the temp-0
|
|
69
|
-
trace (threshold 0 and 0.5 arms), run
|
|
70
|
-
`scripts/dspark-deepspec-compare.ts` — target vs their reference on the
|
|
71
|
-
**bf16 HF 12B** (`--target` the bf16 snapshot; the OptiQ-4bit arm is
|
|
72
|
-
`--acceptance-only`, a measurement not a bit gate). Fixture per
|
|
73
|
-
goldens/README.md conventions. Exit: round-for-round PASS, or a filed
|
|
74
|
-
divergence with the first-divergent round attached.
|
|
75
|
-
- [ ] **0b. γ sweep, conc 1** (no code): serve with `--num-draft-tokens`
|
|
76
|
-
∈ {2, 3, 5, 7} × `bench-feature-matrix.ts --concurrency 1 --cells
|
|
77
|
-
serial,spec`. Record per-request tok/s + acceptance + TTFT per γ. Exit: a
|
|
78
|
-
table; the best-γ config is the Phase 1 comparison base.
|
|
79
|
-
- [ ] **0c. Time attribution**: xctrace (or coarse: MLX_BUN_LANE_DEBUG +
|
|
80
|
-
timers around `source.draft` / verify forward / commit in a scratch
|
|
81
|
-
branch) on ~20 rounds. Split: draft-block GPU, draft host syncs, verify
|
|
82
|
-
forward, tap/commit overhead. Plus the paging check: RSS + `vm_stat`
|
|
83
|
-
pageouts during a run (is the 14 GB pairing thrashing?). Exit: a
|
|
84
|
-
percentage breakdown — it ORDERS phases 1–3 by measured value, replacing
|
|
85
|
-
the estimates below.
|
|
86
|
-
|
|
87
|
-
## Phase 1 — quantize the drafter (uniform 4-bit baseline; NOT TurboQuant yet)
|
|
88
|
-
|
|
89
|
-
The expected big lever: 6.9 GB → ~1.8 GB kills bandwidth AND memory pressure.
|
|
90
|
-
mlx-native group quantization, no research dependency.
|
|
91
|
-
|
|
92
|
-
- [x] **1a. `scripts/dspark-quantize-drafter.ts`** *(DONE 2026-07-07 — thin
|
|
93
|
-
driver over the house quantizer: `src/spec/dspark/quantize-drafter.ts`
|
|
94
|
-
adds a `quantizePredicate` overlay (confidence_head kept bf16, recorded
|
|
95
|
-
as the mlx `false` convention); load smoke = DeepspecDrafter reload +
|
|
96
|
-
one quantized fc forward)* — reads a DeepSpec-format
|
|
97
|
-
checkpoint dir, writes a quantized sibling (same config.json + arch stamp,
|
|
98
|
-
plus the house `quantization: {bits, group_size}` block). Per-tensor
|
|
99
|
-
policy:
|
|
100
|
-
- QUANTIZE (group-64, 4-bit default, flag-tunable): every 2-D matmul
|
|
101
|
-
weight — `layers.*.self_attn.{q,k,o}_proj`, `layers.*.mlp.{gate,up,
|
|
102
|
-
down}_proj`, `fc`, `lm_head`, `markov_head.markov_w2`, and
|
|
103
|
-
`embed_tokens` + `markov_head.markov_w1` as quantized-gather lookups
|
|
104
|
-
(mlx QuantizedEmbedding semantics — mlx-lm quantizes embeddings; ours
|
|
105
|
-
must match its gather-dequant numerics).
|
|
106
|
-
- KEEP bf16: all norms, `layers.*.layer_scalar`, `confidence_head.proj.*`
|
|
107
|
-
(tiny), biases.
|
|
108
|
-
- Output verified loadable before exit (load smoke).
|
|
109
|
-
- [x] **1b. Quantized forward in `src/spec/dspark/deepspec-module.ts`**
|
|
110
|
-
*(DONE 2026-07-07 — MatW/TableW weight representation: `.scales` sibling
|
|
111
|
-
detection, quantized_matmul transpose=true for every Linear, mlx
|
|
112
|
-
QuantizedEmbedding gather-dequant for embed_tokens/markov_w1; bf16 path
|
|
113
|
-
keeps the lazy transpose views untouched; synthetic quantized-checkpoint
|
|
114
|
-
describe block added — 8-bit tracks bf16 token-for-token)*:
|
|
115
|
-
detect quantization at load (scales/biases sibling keys — the house
|
|
116
|
-
detection pattern), route matmuls through `quantized_matmul` and lookups
|
|
117
|
-
through the quantized-gather path; bf16 path untouched (both formats load
|
|
118
|
-
through the same class — kind detection unchanged). Synthetic-format test
|
|
119
|
-
extended with a tiny quantized checkpoint (same file, new describe block).
|
|
120
|
-
- [x] **1c. The acceptance A/B harness** *(DONE 2026-07-07 — runner drives
|
|
121
|
-
`specServeRun` per arm (target loaded once, drafters sequential); spec
|
|
122
|
-
telemetry extended with per-position draftedByPos/acceptedByPos; the
|
|
123
|
-
stats/verdict math is model-free in `src/spec/dspark/ab-stats.ts`,
|
|
124
|
-
unit-tested in tests/dspark-ab-stats.test.ts; chat-template rendering
|
|
125
|
-
pins enable_thinking OFF)* — `scripts/dspark-drafter-ab.ts`:
|
|
126
|
-
same target, same prompt set (≥32 prompts, temp 0), drafter A vs drafter
|
|
127
|
-
B; reports per-position acceptance, τ, tok/s, and a paired verdict. This
|
|
128
|
-
is THE gate for every quantization experiment from here on (Phase 5
|
|
129
|
-
reuses it unchanged). Model-free logic unit-tested; the run itself is
|
|
130
|
-
GPU/Josh.
|
|
131
|
-
- [ ] **1d. Run it**: 4-bit vs bf16 drafter at best-γ from 0b. Exit criteria:
|
|
132
|
-
acceptance drop ≤ 3 points absolute AND wall-clock strictly improves;
|
|
133
|
-
record both. If 4-bit alone flips spec past serial — say so loudly in the
|
|
134
|
-
handoff, that's the headline.
|
|
135
|
-
- [ ] **1e. The MEASURED sensitivity map — ADOPT OPTIQ'S METHOD, don't
|
|
136
|
-
invent** (mlx-optiq.com/docs/sensitivity; source readable in the oracle
|
|
137
|
-
venv's `site-packages/optiq`). Their loop, verbatim: reference logits on
|
|
138
|
-
calibration data → simulate-quantize ONE group (quantize→dequantize
|
|
139
|
-
round-trip) → KL divergence on the full output distribution → restore →
|
|
140
|
-
next (group, bits); then their greedy knapsack (max KL-reduction per
|
|
141
|
-
extra bit) allocates to a target BPW. **Applied to the drafter it gets
|
|
142
|
-
CHEAPER than optiq's own runs**: the drafter isn't mlx_lm-loadable
|
|
143
|
-
(its forward needs target hiddens), so `optiq convert` can't run on it
|
|
144
|
-
directly — but that same fact removes the 12B from the loop entirely.
|
|
145
|
-
Cache tapped hiddens ONCE over an optiq-style 6-domain calibration mix
|
|
146
|
-
(our PATH-B shard format stores exactly this), then the whole sweep is
|
|
147
|
-
drafter-forward-only KL: 3B × ~10 groups × candidate bits = minutes.
|
|
148
|
-
The knapsack's output config gets ONE end-to-end acceptance A/B (1c
|
|
149
|
-
harness) as confirmation — KL is the search signal, acceptance is the
|
|
150
|
-
ship gate. Their protected-tensor defaults (lm_head/embed highest bits,
|
|
151
|
-
first/last blocks) are noted as the static prior their own exact method
|
|
152
|
-
exists to replace — we run the exact method; the drafter is small.
|
|
153
|
-
|
|
154
|
-
## Phase 1.5 — acceptance upside (OPTIONAL; the baseline is already workable)
|
|
155
|
-
|
|
156
|
-
26–33% (τ≈2.8) with the bf16 drafter pays as-is — this phase is the
|
|
157
|
-
opportunistic numerator work on top, NOT a precondition: the gap vs their
|
|
158
|
-
bf16-target numbers is distribution shift with a known mechanism, and every
|
|
159
|
-
point recovered multiplies the cost work. Run it if Phase 1's preserved
|
|
160
|
-
acceptance + cost win lands short of the ≥1.3× goal, or whenever the upside
|
|
161
|
-
is worth the run.
|
|
162
|
-
|
|
163
|
-
- [ ] **1.5a. Adaptation fine-tune on OUR target's hiddens** — their
|
|
164
|
-
checkpoint as init (the expensive pretraining is done; this is short
|
|
165
|
-
distribution adaptation, not their 10-epoch/38 TB run). The data comes
|
|
166
|
-
from OUR stack by construction: tap `[5,17,29,41,46]` hidden dumps from
|
|
167
|
-
the OptiQ-4bit 12B over on-distribution generations (the PATH-B regen
|
|
168
|
-
tooling extracts exactly this). OPEN DESIGN (resolve first): where the
|
|
169
|
-
gradient runs — (a) export our tapped-hidden shards into DeepSpec's
|
|
170
|
-
torch trainer format and fine-tune with THEIR code (MIT; least new code,
|
|
171
|
-
needs a torch box/venv and a shard-format bridge), vs (b) a training
|
|
172
|
-
path for the deepspec module in our stack (autograd through the port —
|
|
173
|
-
more work, fully local). Gate: acceptance A/B (1c harness) pre/post
|
|
174
|
-
fine-tune on held-out prompts; expected: a large chunk of the
|
|
175
|
-
bf16-vs-OptiQ gap closes.
|
|
176
|
-
- [ ] **1.5b. Confidence-threshold activation** — at 26% acceptance the
|
|
177
|
-
scheduler is finally in its design regime: sweep the raw threshold
|
|
178
|
-
(their knob) and/or our calibrated thresholds; objective =
|
|
179
|
-
tokens-per-second, not τ (pruning doomed positions trades a little τ
|
|
180
|
-
for less wasted draft+verify work). Free: no code, the machinery
|
|
181
|
-
shipped in PR #19.
|
|
182
|
-
- [ ] **1.5c. Quantify the target-fidelity axis** (measurement, not a
|
|
183
|
-
build): acceptance vs target quant — e.g. the same drafter against a
|
|
184
|
-
higher-fidelity 12B variant if one fits (mixed/8-bit tap-layer
|
|
185
|
-
experiments), to split "drafter needs adapting" from "target hiddens
|
|
186
|
-
are too degraded". Informs whether 1.5a alone suffices.
|
|
187
|
-
|
|
188
|
-
## Phase 2 — tighten `draftBlock` (replay the proven tightening)
|
|
189
|
-
|
|
190
|
-
`Gemma4DSparkModel.draftBlock` kept the reference's per-position structure
|
|
191
|
-
(transcription fidelity): 7 argmax `itemUint32` syncs + 7 confidence
|
|
192
|
-
`toFloat32` syncs per round. We already solved this exact shape once
|
|
193
|
-
(module-dflash.ts, 2026-07-06 — bit-identity-pinned).
|
|
194
|
-
|
|
195
|
-
- [ ] **2a. On-device token chaining**: the sequential Markov loop keeps the
|
|
196
|
-
argmax result as a device `[1]` index feeding the next position's
|
|
197
|
-
`takeAxis(markov_w1, ·)`; ONE concat + ONE host read after the loop.
|
|
198
|
-
(Post-1b the bias matmul is quantized too.)
|
|
199
|
-
- [ ] **2b. Confidence: compute NOTHING at threshold ≤ 0** (their default —
|
|
200
|
-
today we compute + sync 7 confidences that are then unused); when a
|
|
201
|
-
threshold IS set, per-position reads are inherent to the truncation
|
|
202
|
-
decision (same reasoning as the dflash loop — document it).
|
|
203
|
-
- [ ] **2c. `collectLogits`-style skip** for `baseLogits` if the serve path
|
|
204
|
-
still materializes anything it discards (audit `DeepspecSource.draft` —
|
|
205
|
-
it disposes `block.baseLogits` unread; make the module skip building it,
|
|
206
|
-
mirroring `DflashDraftOpts.collectLogits`).
|
|
207
|
-
- [ ] **Gate**: bit-identity — pinned tokens on the deterministic synthetic
|
|
208
|
-
checkpoint pre/post rewrite (the tests/dspark-infer-loop.test.ts
|
|
209
|
-
pattern), plus real-checkpoint determinism (same prompt twice → same
|
|
210
|
-
drafts). Tightening is a pure optimization; any token change is a bug.
|
|
211
|
-
|
|
212
|
-
## Phase 3 — `captureLayer` in the generated gemma forwards
|
|
213
|
-
|
|
214
|
-
Tapped spec forwards (prefill + EVERY verify round) currently fall back to
|
|
215
|
-
the monolith (the 2026-07-07 guard fix — correct-but-unspecialized). The
|
|
216
|
-
verify forward is the spec path's biggest single GPU cost; give it back the
|
|
217
|
-
generated fast path. Independent of Phases 1–2; parallelizable.
|
|
218
|
-
|
|
219
|
-
- [ ] **3a. `scripts/gen-model.ts`**: emit the tap exactly as the monolith
|
|
220
|
-
does — `captureLayer(i, h)` after each layer's residual
|
|
221
|
-
(gemma4.ts:970 semantics) + the post-finalNorm sentinel
|
|
222
|
-
(index = nLayers, gemma4.ts:989) — and REMOVE `this.hiddenTap !== null`
|
|
223
|
-
from the emitted fallback guard.
|
|
224
|
-
- [ ] **3b. Regenerate all three** (12b / 26b / e4b; regen commands in each
|
|
225
|
-
file's header) — the hand-patched guards are superseded by generator
|
|
226
|
-
output.
|
|
227
|
-
- [ ] **Gate**: (i) generated-parity suite green (untapped behavior
|
|
228
|
-
untouched); (ii) NEW tap-parity check — tapped rows bit-equal
|
|
229
|
-
monolith-vs-generated on the same input (model-gated test, e4b);
|
|
230
|
-
(iii) spec bench pre/post for the verify-round win.
|
|
231
|
-
|
|
232
|
-
## Phase 4 — serving UX: flags, defaults, composition (the product pass)
|
|
233
|
-
|
|
234
|
-
Decisions, made on Phase 0–3 DATA, then implemented. The doctrine rails:
|
|
235
|
-
drop-in-replacement (a lone request must never get slower because a flag
|
|
236
|
-
exists), dont-delete-optionality (losing configs stay documented
|
|
237
|
-
default-off), spec = opt-in until it WINS a clean-machine paired A/B.
|
|
238
|
-
|
|
239
|
-
- [ ] **4a. γ default per drafter kind**: the checkpoint's trained γ is the
|
|
240
|
-
cap, not necessarily the default — if 0b says γ=3 beats γ=7 at our
|
|
241
|
-
acceptance, `numDraftTokens` defaults to the measured-best (per-kind
|
|
242
|
-
table in code, overridable), and the handoff documents why.
|
|
243
|
-
- [ ] **4b. Quantized-drafter UX**: `mlx-bun get` the bf16 →
|
|
244
|
-
`scripts/dspark-quantize-drafter.ts` is a manual step today; decide
|
|
245
|
-
whether `serve --draft-model <bf16-dir>` should offer/auto-run the
|
|
246
|
-
4-bit conversion (like the starter-model flow) or just print the
|
|
247
|
-
command. Also: registry listing shows drafters distinctly (they are not
|
|
248
|
-
servable models — `/v1/models` must NOT list them; verify).
|
|
249
|
-
- [ ] **4c. Spec × prompt-cache composition** (parity-plan §7.6 — currently
|
|
250
|
-
BYPASSED on the spec path, v1 note in serve-loop.ts): multi-turn agents
|
|
251
|
-
re-prefill every turn when a draft is mounted. Scope it here or
|
|
252
|
-
explicitly re-defer with the measured cost (12B multi-turn TTFT with
|
|
253
|
-
spec on). At minimum: the boundary-snapshot machinery must not regress
|
|
254
|
-
when spec is mounted.
|
|
255
|
-
- [ ] **4d. Surface audit**: `--draft-kind` (keep), `--num-draft-tokens`
|
|
256
|
-
semantics doc, `/stats` shows mounted drafter + kind + γ, `usage.
|
|
257
|
-
speculation` already ships. server-config.md gets a "speculative
|
|
258
|
-
serving" section consolidating the four kinds + the when-does-it-pay
|
|
259
|
-
table (from Phase 0/1 data). features-matrix + cli.md + README rows.
|
|
260
|
-
- [ ] **4e. The default decision, written down**: for each (model, drafter)
|
|
261
|
-
pair measured, spec default on/off per the clean-machine A/B — recorded
|
|
262
|
-
in RESULTS.md "composition" + the features matrix. (Prediction to test:
|
|
263
|
-
ON for 12B+quantized drafter, OFF for e4b anything.)
|
|
264
|
-
|
|
265
|
-
## Phase 5 — TurboQuant application (the trigger event)
|
|
266
|
-
|
|
267
|
-
Trigger, precisely: **TQ WEIGHT quantization** in the convert tooling — PR
|
|
268
|
-
#20 (2026-07-07) landed TurboQuant for KV; the rotation-based weight-side
|
|
269
|
-
is the noted follow-up (turboquant-kv.md), and it's what the drafter
|
|
270
|
-
needs. The drafter is its lowest-risk first customer — one-number gate,
|
|
271
|
-
no KL/eval battery. **TQ's HYPOTHESIS here is PRESERVATION AT EQUAL BITS**
|
|
272
|
-
(Gaussian-distributed vectors + finer step sizes around the peak, where
|
|
273
|
-
affine spends half its levels on tails) — a hypothesis 5b MEASURES, never
|
|
274
|
-
a default: TurboQuant earns its place the same way everything in this
|
|
275
|
-
repo does.
|
|
276
|
-
|
|
277
|
-
- [ ] **5a.** Extend `dspark-quantize-drafter.ts` with the TurboQuant
|
|
278
|
-
scheme.
|
|
279
|
-
- [ ] **5b. THE HEADLINE: TQ-4bit vs affine-4bit AT EQUAL BPW** through the
|
|
280
|
-
Phase-1c harness — same size, whose acceptance is closer to bf16? If
|
|
281
|
-
affine-4 bled in 1d, this is the expected fix; if affine-4 held, TQ's
|
|
282
|
-
margin becomes headroom for lower rungs. Only AFTER TQ-4 ≥ affine-4:
|
|
283
|
-
the lower-bpw ladder (3.5 / 3.0 / 2.5) → acceptance-per-byte curve,
|
|
284
|
-
knee adopted (dont-delete-optionality for the rest).
|
|
285
|
-
- [ ] **5b″. TQ IS HOW, SENSITIVITY-AWARE IS WHAT (Josh)** — two orthogonal
|
|
286
|
-
axes, never mixed: TQ vs affine is a METHOD question (decided by 5b's
|
|
287
|
-
equal-bpw measurement — a method that wins at equal bits wins for every
|
|
288
|
-
tensor, so there is no reason to mix METHODS within an artifact);
|
|
289
|
-
sensitivity is the bit ALLOCATION question (the 1e knapsack, whatever
|
|
290
|
-
the method — candidate set {method-2, method-3, method-4, method-8} per
|
|
291
|
-
group, measured KL cost each, greedy to target BPW). IF 5b confirms TQ,
|
|
292
|
-
the artifact is TQ-uniform at knapsack-allocated bits; if it doesn't,
|
|
293
|
-
affine-uniform at knapsack-allocated bits — either way the OUTCOME of
|
|
294
|
-
the measurement, not a premise. Nothing here is "on by default";
|
|
295
|
-
defaults are Phase 4e/6 decisions made on clean-machine numbers.
|
|
296
|
-
- [ ] **5b′. PER-TENSOR MIXED PRECISION rungs** (Josh, 2026-07-07). The
|
|
297
|
-
intuition "only 5 layers = few knobs" undercounts: the drafter's mass is
|
|
298
|
-
~10 TENSOR GROUPS, and two of them are 58% of the bytes — `lm_head`
|
|
299
|
-
(~2 GB, read FULLY every round: the bandwidth whale) and `embed_tokens`
|
|
300
|
-
(~2 GB, gather-only: ~free to read, pure resident-memory win), plus
|
|
301
|
-
`markov_w2` (134 MB read ×7/round ≈ 940 MB). Both whales only shape the
|
|
302
|
-
DRAFT distribution → acceptance-only risk. Mixed rungs to sweep: 3-bit
|
|
303
|
-
lm_head + 3-bit markov_w2 + 4-bit layers; 2-bit embed variants; k_proj
|
|
304
|
-
(2 M params) 8-bit for free. The ~10-group space is small enough for a
|
|
305
|
-
near-exhaustive sweep through the SAME one-number harness — unlike
|
|
306
|
-
sensitivity search on a full model. **Allocation objective (the point):
|
|
307
|
-
PRESERVE the bf16 acceptance at the smallest cost, not minimize bytes —
|
|
308
|
-
and allocation follows the MEASURED sensitivity table from 1e, never a
|
|
309
|
-
prior.** The mixed rungs are built FROM the table: give the measured-
|
|
310
|
-
sensitive groups more bits (or TQ them, post-Phase-5), squeeze the
|
|
311
|
-
measured-insensitive ones. The "only 5 layers" worry dissolves either
|
|
312
|
-
way — the tensor-group space (~10 knobs, two of them 58% of the bytes)
|
|
313
|
-
is the real granularity, and 1e prices every knob empirically.
|
|
314
|
-
- [ ] **5c.** If TurboQuant wins: fold the recipe into 4b's UX (the
|
|
315
|
-
conversion the server offers is the TurboQuant one).
|
|
316
|
-
|
|
317
|
-
## Phase 6 — quotable results + promotion
|
|
318
|
-
|
|
319
|
-
- [ ] Clean-machine protocol (reboot + `sudo purge`), then: bench-feature-
|
|
320
|
-
matrix conc-1 AND agg×4, serial vs best-spec-config, on 12B (and e4b as
|
|
321
|
-
the expected-negative control). Promote to `benchmarks/RESULTS.md`
|
|
322
|
-
"composition"; update decode-speed-program.md (lever 1c: measured),
|
|
323
|
-
STATUS, and the handoff's FIRST LIVE RUN section with the closing
|
|
324
|
-
numbers.
|
|
325
|
-
- [ ] Loose ends carried from PR #19, closed or re-deferred with reasons:
|
|
326
|
-
the paper-faithful gated RNN head (seqHead:"gru", currently variant-
|
|
327
|
-
documented), paper-Alg-1/STS survival-product scheduler (Lab item),
|
|
328
|
-
per-slot spec under batching (unified-engine frontier row — NOT this
|
|
329
|
-
program).
|
|
330
|
-
|
|
331
|
-
## Dependency graph + who does what
|
|
332
|
-
|
|
333
|
-
```
|
|
334
|
-
0a (oracle gate, Josh: venv+GPU) ──┐
|
|
335
|
-
0b (γ sweep, Josh: GPU) ──────────┼─→ 1a→1b→1c→1d (quant baseline; 1d Josh GPU)
|
|
336
|
-
0c (attribution, Josh: GPU) ───────┘ │
|
|
337
|
-
├─→ 1.5 (OPTIONAL acceptance
|
|
338
|
-
│ upside: fine-tune on our
|
|
339
|
-
│ target's hiddens + threshold
|
|
340
|
-
│ sweep; run if 1's preserved
|
|
341
|
-
│ acceptance falls short)
|
|
342
|
-
├─→ 2a-2c (tightening; CPU-gated)
|
|
343
|
-
3a-3b (generator tap; parallel anytime) ────┤
|
|
344
|
-
└─→ 4 (UX, needs 0–3 data)
|
|
345
|
-
TurboQuant merge ─→ 5a-5c (reuses 1c harness) ─→ 6 (clean machine, Josh)
|
|
346
|
-
```
|
|
347
|
-
Priority note: Phase 1's PRESERVATION question ("do we keep 26–33% at
|
|
348
|
-
4-bit?") is the program's hinge — one A/B answers it; if affine-4 bleeds,
|
|
349
|
-
the answers are MEASURED (1e sensitivity table → mixed allocation) and
|
|
350
|
-
ENGINEERED (Phase 5: TQ-4 at equal bpw — the better quant is the designed
|
|
351
|
-
fix, not a fallback).
|
|
352
|
-
|
|
353
|
-
Code phases (1a/1b/2/3/4-impl) are agent-runnable sessions; every GPU
|
|
354
|
-
measurement is Josh's shell. Nothing except Phase 5 waits on TurboQuant —
|
|
355
|
-
Phases 0–4 can land first so TurboQuant drops into a finished harness.
|
|
356
|
-
|
|
357
|
-
## Exit criteria for the whole program
|
|
358
|
-
|
|
359
|
-
1. Spec wall-clock ≥ 1.3× serial on 12B at the recommended config,
|
|
360
|
-
clean-machine paired — or a written verdict that it can't be reached and
|
|
361
|
-
why (with the config left as a characterized default-off lever).
|
|
362
|
-
2. **Acceptance PRESERVED and understood**: the quantized drafter holds the
|
|
363
|
-
bf16 baseline's 26–33% (or the mixed rung that does is adopted, or the
|
|
364
|
-
loss is measured and accepted with numbers); the optional 1.5 upside
|
|
365
|
-
levers are run-or-explicitly-deferred — the drafter predicts tokens;
|
|
366
|
-
small was never the goal.
|
|
367
|
-
3. The acceptance-per-byte curve exists (TurboQuant vs 4-bit vs mixed vs
|
|
368
|
-
bf16), with acceptance-at-fixed-budget allocation swept (5b′).
|
|
369
|
-
4. The serving surface is documented, defaults decided per-pair and
|
|
370
|
-
recorded, and a fresh `mlx-bun get` → serve → speedup flow works without
|
|
371
|
-
reading any design doc.
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
# DSpark speculative decoding for mlx-bun
|
|
2
|
-
|
|
3
|
-
Implementation of DeepSeek's **DSpark** ("Confidence-Scheduled Speculative
|
|
4
|
-
Decoding with Semi-Autoregressive Generation", `DSpark_paper.pdf`) against this
|
|
5
|
-
repo's models. DSpark = a **DFlash** parallel backbone (KV-injected, all γ draft
|
|
6
|
-
tokens in one pass) **+ a lightweight sequential head** (Markov, Eq 5, or RNN,
|
|
7
|
-
Eq 6) that adds intra-block dependency (the *semi-autoregressive* part) **+ a
|
|
8
|
-
confidence head → STS calibration → hardware-aware prefix scheduler**. Decode
|
|
9
|
-
becomes draft → verify → accept; output is lossless (bit-identical to the target
|
|
10
|
-
at any temperature); only decode speed (τ) changes.
|
|
11
|
-
|
|
12
|
-
> **DFlash vs DSpark:** DFlash is *only* the parallel backbone (prior work) and
|
|
13
|
-
> suffers suffix decay. DSpark adds the sequential head + confidence-scheduled
|
|
14
|
-
> verification. The sequential Markov head is what makes this DSpark.
|
|
15
|
-
|
|
16
|
-
## Two implementations (flag-selected, both in `src/spec/dspark/`)
|
|
17
|
-
|
|
18
|
-
| | `module.ts` (v1) | `module-dflash.ts` (v2, **the real one**) |
|
|
19
|
-
|---|---|---|
|
|
20
|
-
| context | **single vector** (final hidden at the anchor) fused as one token | faithful **multi-layer KV injection** (Eq 2–3): H_ctx = RMSNorm(W_c·[H^{l1};…;H^{lm}]) over the FULL context, re-projected into every draft layer's K/V |
|
|
21
|
-
| layers | 2 | 5 |
|
|
22
|
-
| status | **superseded** — dropped the paper's core idea (kept as baseline) | the actual DSpark model (Markov variant) |
|
|
23
|
-
|
|
24
|
-
v1 was a shortcut that removed the load-bearing mechanism; it never tested the
|
|
25
|
-
paper. v2 is faithful. Checkpoints stamp `variant` in `dspark.json`; the runtime
|
|
26
|
-
loads the matching module. (`variant:"dflash"` should be renamed to `"dspark"` —
|
|
27
|
-
see Open items.)
|
|
28
|
-
|
|
29
|
-
## The mechanism (v2, paper Eq 2–3)
|
|
30
|
-
|
|
31
|
-
- **Eq 2 (context):** tap the target's hidden states at layers `{l1…lm}` (e4b
|
|
32
|
-
default {20,31,41,42}, the last = post-finalNorm), concat on the feature axis,
|
|
33
|
-
project to the draft width: `H_ctx ∈ [L_ctx, d]`. Extraction via a parity-safe
|
|
34
|
-
`model.hiddenTap` (no-op when off) added to `gemma4.ts` `forwardLayers`.
|
|
35
|
-
- **Eq 3 (injection):** every draft layer forms `K_i=[W_i^K H_ctx; W_i^K H_d]`,
|
|
36
|
-
`V_i` likewise, `Q_i=W_i^Q H_d`; the γ-block queries attend bidirectionally
|
|
37
|
-
over `[context ++ block]`. Context is read-only memory re-projected fresh each
|
|
38
|
-
layer. The draft projects the target's HIDDEN STATES with its OWN Wk/Wv (not
|
|
39
|
-
the target's K/V — that's the separate `GemmaAssistantDrafter` baseline).
|
|
40
|
-
- **Markov head (Eq 5):** `B_k = W1[x_{k-1}]·W2`, r=256, W2=0 init → starts as
|
|
41
|
-
pure DFlash, τ climbs as intra-block dependency is learned.
|
|
42
|
-
- **Confidence head (Eq 7):** `c_k = σ(wᵀ[h_k; W1[x_{k-1}]])`.
|
|
43
|
-
- **Loss (Eq 9–12):** `0.1·CE + 0.9·TV + 1.0·BCE`, position-weighted.
|
|
44
|
-
- **Lossless verify** (`generate-dflash.ts`): greedy = longest-prefix match;
|
|
45
|
-
temp>0 = `min(1,p/q)` accept + residual `norm(relu(p−q))` resample. Growing
|
|
46
|
-
multi-layer H_ctx buffer; rollback via `trim(n, bypass=true)` (physically
|
|
47
|
-
slices the rejected tips past the sliding window — see `gemma4-base.ts`).
|
|
48
|
-
|
|
49
|
-
## Results & findings (measured, M1 Max 32GB, e4b OptiQ-4bit)
|
|
50
|
-
|
|
51
|
-
**The architecture is CORRECT — proven by an overfit test.** Trained on 3
|
|
52
|
-
articles, eval on the same 3: per-position acceptance **~0.75**, τ **3.24** —
|
|
53
|
-
squarely paper-range (0.6–0.9 / τ 3–4). So the faithful DFlash, correctly
|
|
54
|
-
implemented, reaches the paper's numbers.
|
|
55
|
-
|
|
56
|
-
**Getting there required finding a real bug — an off-by-one in the p^t target
|
|
57
|
-
alignment** (the TV loss, weight 0.9). Block position k predicts `x_{t+1+k}`,
|
|
58
|
-
whose target distribution is `softmax(LM_head(h_{t+k}))`; the data gathered the
|
|
59
|
-
hidden at `t+k+1` (shifted forward one). Present in **both v1 and v2** — so every
|
|
60
|
-
τ number before the fix was trained against a shifted target. Fixed in
|
|
61
|
-
`data-dflash.ts` (`blockIdx = g+k`, k=0..γ-1). Before fix: per-pos ~0.08. After:
|
|
62
|
-
~0.17 generalizing, ~0.75 overfit.
|
|
63
|
-
|
|
64
|
-
**Two things stand between "correct architecture" and "net speedup," now
|
|
65
|
-
separated:**
|
|
66
|
-
1. **Data.** 160 articles → generalizes only to per-pos ~0.17 (plateaus, doesn't
|
|
67
|
-
climb); overfit on 3 proves capacity. The paper uses 1.3M samples × 10 epochs.
|
|
68
|
-
→ needs real data scale.
|
|
69
|
-
2. **Target speed (the decisive one).** Spec decode amortizes the fixed draft
|
|
70
|
-
overhead only when the *target forward* is expensive. Measured decode:
|
|
71
|
-
**e4b 45.9 tok/s, 12b 27.5 tok/s, 27B ~15 tok/s.** On fast e4b the draft
|
|
72
|
-
overhead dominates → even τ≈3 nets ~0.4–0.5× (SLOWER). On a slow target (27B,
|
|
73
|
-
~67 ms/forward) that overhead is a small fraction → the same τ≈3 could land
|
|
74
|
-
~2–3× (15 → ~35–45 tok/s). **e4b is close to the worst case for spec decode;
|
|
75
|
-
the 27B agentic workload is the ideal target and the real motivation.**
|
|
76
|
-
|
|
77
|
-
Also confirmed: width is NOT the ceiling (`dDraft=1024` and `2560` both plateau
|
|
78
|
-
~0.17 pre-scale); the parity-safe `hiddenTap` doesn't change target numerics;
|
|
79
|
-
long-context spec rollback works via the `trim(n, bypass)` physical-slice.
|
|
80
|
-
|
|
81
|
-
## Serve integration (Phase 1, 2026-07-06)
|
|
82
|
-
|
|
83
|
-
DSpark is now serve-loadable behind the same `--draft-model` seam as every
|
|
84
|
-
other drafter — one verify/accept executor, no lane routing. The seam
|
|
85
|
-
(`src/spec/source.ts`) was extended from its two-model-only shape to carry the
|
|
86
|
-
target state KV-borrowing drafters need (it previously could NOT host these,
|
|
87
|
-
despite the header claiming so):
|
|
88
|
-
|
|
89
|
-
- `DraftProvider.open({sampler, target:{model,caches}})` — the source gets the
|
|
90
|
-
target model + its live caches.
|
|
91
|
-
- `DraftSource.tapLayers?` — when set (DSpark), the serve loop taps the
|
|
92
|
-
target's prefill + every verify forward and hands the captured `[1,L,m*H]`
|
|
93
|
-
context to `prefill(ids, ctxML)` / `commit(n, kAccept, vCtxML)` (ownership
|
|
94
|
-
transfers). `draft(feed, n, stepBase, anchorHidden?)` — the assistant borrows
|
|
95
|
-
the target anchor hidden; DSpark drafts from its growing `H_ctx`.
|
|
96
|
-
|
|
97
|
-
Provider selection is by artifact kind (`src/server.ts` `detectDraftKind`):
|
|
98
|
-
`dspark.json` → **DflashProvider** (`src/spec/dflash-source.ts`), a `*_assistant`
|
|
99
|
-
config → **AssistantProvider** (`src/spec/assistant-source.ts`, the optiq
|
|
100
|
-
KV-borrowing Gemma drafter — ships a real ~1.09× γ=1 decode win with no
|
|
101
|
-
training), else **TwoModelProvider**. `--draft-kind` overrides. The server pins
|
|
102
|
-
`--num-draft-tokens` to the DSpark checkpoint's trained block width
|
|
103
|
-
(`cfg.gamma`) so the serve loop never asks for more positions than were trained.
|
|
104
|
-
|
|
105
|
-
**Unified-engine alignment (per-slot readiness).** This is the
|
|
106
|
-
`DraftSource` seam the unified-engine plan names as the substrate for its
|
|
107
|
-
frontier "per-slot drafting behind the `DraftSource` seam" row
|
|
108
|
-
([docs/design/unified-engine-frontier-plan.md](unified-engine-frontier-plan.md)).
|
|
109
|
-
Spec still forces the serial lane today (upstream `is_batchable = draft is
|
|
110
|
-
None`); Phase 1 did NOT change that — it made the seam *carry per-source target
|
|
111
|
-
state* (each source binds its own `TargetView{model,caches}`, anchor hidden,
|
|
112
|
-
and tapped H_ctx), which is exactly what a batched executor would need to open
|
|
113
|
-
one `DraftSource` per row. So the seam is forward-compatible with per-slot
|
|
114
|
-
drafting; the hard part that remains is the executor, not the seam — variable
|
|
115
|
-
accept-length per slot breaks a uniform-B step (see
|
|
116
|
-
[spec-decode-larger-targets.md](spec-decode-larger-targets.md) caveats), so
|
|
117
|
-
per-slot spec is a real batched-scheduler project, not free composition.
|
|
118
|
-
|
|
119
|
-
**v1 acceptance caveat:** the serve loop verifies with TOKEN-MATCH acceptance
|
|
120
|
-
(mlx-lm/optiq style, lossless at any temperature), NOT the paper's
|
|
121
|
-
distribution-level rejection-sampling verify. Greedy is identical; temp>0 is
|
|
122
|
-
still lossless but lower-acceptance. The richer rejection-sampling verify stays
|
|
123
|
-
in the standalone `generate-dflash.ts` (the measure script). See
|
|
124
|
-
[[dspark-seam-kv-borrowing]].
|
|
125
|
-
|
|
126
|
-
## Files
|
|
127
|
-
- `src/spec/source.ts` — the extended DraftSource/DraftProvider/TargetView seam.
|
|
128
|
-
- `src/spec/assistant-source.ts` / `dflash-source.ts` — the two KV-borrowing providers.
|
|
129
|
-
- `src/spec/serve-loop.ts` — the shared verify/accept executor (now tap-aware).
|
|
130
|
-
- `src/model/gemma4.ts` — `hiddenTap`/`captureLayer` (parity-safe multi-layer tap).
|
|
131
|
-
- `src/model/gemma4-base.ts` — `trim(n, bypass)` on rotating caches (spec rollback past the window).
|
|
132
|
-
- `src/spec/dspark/module-dflash.ts` — faithful DFlash+Markov+confidence module.
|
|
133
|
-
- `src/spec/dspark/data-dflash.ts` — multi-layer shards, variable-length prefix context, left-pad masking.
|
|
134
|
-
- `src/spec/dspark/generate-dflash.ts` — growing-H_ctx lossless decode loop.
|
|
135
|
-
- `src/spec/dspark/{loss,sample}.ts` — loss (Eq 9–12) + temp>0 sampling (shared with v1).
|
|
136
|
-
- `src/spec/dspark/{module,data,generate}.ts` — v1 single-vector (superseded baseline).
|
|
137
|
-
- `scripts/dspark-regen-dflash.ts` / `dspark-train-dflash.ts` (`--resume`) / `dspark-measure-dflash.ts`.
|
|
138
|
-
- `scripts/dspark-dflash-smoke.ts` — CPU smoke (16/16). `scripts/dspark-smoke.ts` — v1 smoke (33/33).
|
|
139
|
-
|
|
140
|
-
## Run sequence (faithful DFlash; GPU = Josh runs)
|
|
141
|
-
```
|
|
142
|
-
bun scripts/dspark-regen-dflash.ts --topics <topics.txt> --out <data> --max-resp 320
|
|
143
|
-
bun scripts/dspark-train-dflash.ts --data <data> --out <ckpt> --iters 8000 --batch 8 [--resume] [--ddraft 2560]
|
|
144
|
-
bun scripts/dspark-measure-dflash.ts --drafter <ckpt> --data <prompts.jsonl> # τ + tok/s vs vanilla
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Paper components — Phase 2 (2026-07-06): the paper is CODE-COMPLETE
|
|
148
|
-
|
|
149
|
-
All remaining components landed the same day (multi-agent build, adversarially
|
|
150
|
-
reviewed; smoke 21/21, dspark test files 17/17, real-weights serve gate 3/3):
|
|
151
|
-
|
|
152
|
-
- **Alg 1, single-user form — confidence-scheduled draft-length pruning.**
|
|
153
|
-
`forwardInfer` drops position k (and truncates the block) when
|
|
154
|
-
`c_k < thresholds[k] ?? minConf`; position 0 always survives. Activation is
|
|
155
|
-
checkpoint-driven: STS thresholds in `dspark.json` (`cfg.sts`) or the
|
|
156
|
-
`MLX_BUN_DSPARK_MINCONF` env override — **uncalibrated checkpoints draft
|
|
157
|
-
fixed-γ exactly as before** (zero behavior change). Losslessness invariant:
|
|
158
|
-
pruning changes how many positions the target verifies, never what's emitted
|
|
159
|
-
(gated: truncation-never-redraw, prefix-identical to the unpruned block).
|
|
160
|
-
- **Variable-length draft contract.** `DraftSource.draft()` returns 1..n —
|
|
161
|
-
the RETURN LENGTH is authoritative; the serve loop and `dflashGenerate`
|
|
162
|
-
verify/trim/re-feed over `d = drafts.length`. Two-model/assistant return
|
|
163
|
-
exactly n (unchanged).
|
|
164
|
-
- **STS calibration (§3.2.1).** `src/spec/dspark/calibration.ts`
|
|
165
|
-
(`fitStsThresholds`: per position, smallest τ whose Laplace-smoothed
|
|
166
|
-
`P(accepted | conf ≥ τ)` ≥ target; pos 0 → 0, under-sampled → 0 (don't
|
|
167
|
-
prune on thin evidence), unreachable target → 1.0) +
|
|
168
|
-
`scripts/dspark-calibrate.ts` (GPU: greedy unpruned rounds via
|
|
169
|
-
`dflashGenerate`'s `onRound` hook → fit → patch `config.sts` into
|
|
170
|
-
dspark.json in place). ⚠ estimator shape is our reading — paper PDF absent.
|
|
171
|
-
- **RNN sequential head (Eq 6 — ⚠ design-doc-faithful shape, paper PDF
|
|
172
|
-
absent, flagged in code).** `cfg.seqHead: "markov"|"rnn"`; Elman recurrence
|
|
173
|
-
`s_k = tanh(s_{k-1}·wH + E[x_{k-1}] + bH)`, `B_k = s_k·wO`, `wO` zero-init
|
|
174
|
-
(starts as pure DFlash, like markov.w2); shares `markov.w1` as the token
|
|
175
|
-
embedding (also feeds the confidence head). Same loss, autograd-gated;
|
|
176
|
-
init-equivalence gate: rnn ≡ markov token-for-token at init.
|
|
177
|
-
Train with `scripts/dspark-train-dflash.ts --seq-head rnn`.
|
|
178
|
-
- **Draft loop TIGHTENED** (handoff item 3): greedy tokens chain ON-DEVICE
|
|
179
|
-
(one concat + one host read after the loop, was γ syncs); confidence reads
|
|
180
|
-
deferred+batched when pruning is inactive (per-position only when Alg 1
|
|
181
|
-
needs the answer mid-loop — inherent); `collectLogits: false` on the serve
|
|
182
|
-
path skips the per-position draft-logits materialization entirely
|
|
183
|
-
(`draftLogits` now optional). Gate: bit-identical to the pre-tightening
|
|
184
|
-
loop (pinned reference tokens, tests/dspark-infer-loop.test.ts).
|
|
185
|
-
- **Rename + central loader.** Canonical variant is now `"dspark"`
|
|
186
|
-
(`save()` stamps it; `load()` accepts legacy `"dflash"`);
|
|
187
|
-
`src/spec/dspark/loader.ts` `loadDsparkDrafter()` dispatches by variant and
|
|
188
|
-
refuses v1 single-vector checkpoints with a pointer at the v2 trainer. The
|
|
189
|
-
serve path and the bench (`bench-feature-matrix.ts` via the server's
|
|
190
|
-
exported `detectDraftKind`) both go through it.
|
|
191
|
-
|
|
192
|
-
## DeepSpec ground truth (2026-07-06 audit — paper arXiv:2607.05147 + source)
|
|
193
|
-
|
|
194
|
-
DeepSeek open-sourced the reference implementation (**DeepSpec**, MIT,
|
|
195
|
-
github.com/deepseek-ai/DeepSpec) + trained drafters incl.
|
|
196
|
-
**`deepseek-ai/dspark_gemma4_12b_block7`** (for google/gemma-4-12B-it — our
|
|
197
|
-
primary target; 6.86 GB bf16 single safetensors, γ=7). Two audit agents
|
|
198
|
-
verified our build against the paper AND the source. Verdicts:
|
|
199
|
-
|
|
200
|
-
- **MATCH the paper exactly:** Eq 2-3 (context + KV injection), the
|
|
201
|
-
anchor++masks block, Eq 5 Markov (r=256), Eq 7 confidence (we add a
|
|
202
|
-
zero-init bias — superset), **Eq 8-12 loss to the letter** (0.1/0.9/1.0,
|
|
203
|
-
w_k=exp(−(k−1)/γ), analytic c*). Our defaults = their production config
|
|
204
|
-
(γ=5, 5 layers, Markov head).
|
|
205
|
-
- **Eq 6 RNN differs:** paper is a gated cell over
|
|
206
|
-
`z_k=[s_{k−1}; W₁[x_{k−1}]; h_k]`, fused (2r+d)→3r projection,
|
|
207
|
-
`B_k=W₂ᵀtanh(W_o z_k)` (conditioned on the backbone hidden). Ours is
|
|
208
|
-
ungated Elman without h_k — kept as variant `"rnn"` (paper calls the gains
|
|
209
|
-
"marginal"; production uses Markov); DeepSpec also ships an RNNHead of the
|
|
210
|
-
gated form if we ever want the faithful one.
|
|
211
|
-
- **§3.2.1 STS + Alg 1: the paper's machinery is NOT in the released code.**
|
|
212
|
-
STS = Sequential Temperature Scaling (per-position temperatures by ECE grid
|
|
213
|
-
search on cumulative survival products); Alg 1 = expected-throughput
|
|
214
|
-
maximization over survival products with a profiled SPS(B) cost table —
|
|
215
|
-
both live in their UNRELEASED production serving layer. The released
|
|
216
|
-
reference ships **per-position threshold truncation on sigmoid confidence
|
|
217
|
-
(default 0 = off), ℓ=0 allowed** — i.e. the released reference is shaped
|
|
218
|
-
like OUR scheduler. Our threshold fit (`calibration.ts`) is therefore a
|
|
219
|
-
reasonable calibrator for the reference-shaped scheduler, NOT the paper's
|
|
220
|
-
STS; renamed framing in code comments. Paper-faithful STS/Alg-1 = a future
|
|
221
|
-
Lab item if the survival-product scheduler ever earns a default.
|
|
222
|
-
- **The reference drafter is a DIFFERENT module than ours:** a full
|
|
223
|
-
Gemma4-shaped 5-layer transformer — hidden 3840, 16 Q heads × head_dim 512,
|
|
224
|
-
**1 KV head with K≡V (`attention_k_eq_v`, no v_proj tensor; scale-less
|
|
225
|
-
v_norm)**, attention scale 1.0 (QK-norm), RoPE partial_rotary 0.25 θ=1e6,
|
|
226
|
-
per-layer learned `layer_scalar`, scaled embed (×√3840, not stored), UNTIED
|
|
227
|
-
lm_head, final softcap 30, and an **incremental context-KV cache** (stores
|
|
228
|
-
projected target-context K/V; crops the block's noise K/V each round).
|
|
229
|
-
Sequential Markov sampling + confidence head (input [h; w1[prev]] = 4096)
|
|
230
|
-
as in the paper. Checkpoint: 74 tensors, bf16, **no key prefix**;
|
|
231
|
-
config.json `architectures: ["Gemma4DSparkModel"]` (loader detection key).
|
|
232
|
-
**12B tap layers: `target_layer_ids [5,17,29,41,46]`** (their layer_id+1
|
|
233
|
-
output convention == our tapLayers index; no final-norm sentinel).
|
|
234
|
-
- **THE ORACLE:** their verify is leaky rejection sampling that at
|
|
235
|
-
temperature 0 **degenerates to exact argmax token-match — RNG-free,
|
|
236
|
-
token-for-token deterministic**. Their eval emits per-round
|
|
237
|
-
proposal/accepted/next-token traces. Protocol: run their eval at temp 0
|
|
238
|
-
(+ a threshold arm) on fixed prompts → JSONL round fixtures → our port
|
|
239
|
-
must match round-for-round. Same discipline as the D2 diffusion oracle,
|
|
240
|
-
minus RNG parity entirely.
|
|
241
|
-
|
|
242
|
-
**Consequence:** DSpark is no longer oracle-less L3. The port of their module
|
|
243
|
-
(the `deepspec` variant) + their checkpoint gives a bit-exact-gateable path to
|
|
244
|
-
a REAL 12B speedup with zero training. Our own trainable module remains the
|
|
245
|
-
research path for custom targets. Training recipe reference: open-perfectblend
|
|
246
|
-
regenerated by the target, 10 epochs, batch 512, lr 6e-4, position decay
|
|
247
|
-
exp(−pos/4), ~38 TB cached hiddens — i.e. our "thousands of generations" data
|
|
248
|
-
estimate was directionally right and their scale is far beyond a laptop run.
|
|
249
|
-
|
|
250
|
-
## Open items / next
|
|
251
|
-
|
|
252
|
-
- [x] Serve integration (Phase 1) · [x] Alg-1-shaped scheduler (matches the
|
|
253
|
-
RELEASED reference; paper Alg-1 unreleased) · [x] threshold calibration ·
|
|
254
|
-
[x] RNN head (Elman variant; paper's gated cell differs — documented above)
|
|
255
|
-
· [x] loop tightening · [x] `dspark` rename + loader —
|
|
256
|
-
**everything buildable without a GPU is DONE.**
|
|
257
|
-
- [ ] **DeepSpec-variant port** (`Gemma4DSparkModel`) + loader detection +
|
|
258
|
-
oracle scripts — the no-training path to the 12B speedup (in progress).
|
|
259
|
-
- [ ] **Josh-gated GPU (the payoff):** real data scale (thousands of
|
|
260
|
-
on-distribution generations) + **retarget to 12B** (`--model` +
|
|
261
|
-
`--tap-layers 5,17,29,41,46` (DeepSeek's trained taps); 27B memory-infeasible to train on 24 GB, kept
|
|
262
|
-
dim-generic) + train (`--seq-head` A/B optional) + **calibrate**
|
|
263
|
-
(`scripts/dspark-calibrate.ts`) + live-τ measure. Recipe:
|
|
264
|
-
[docs/investigations/dspark-handoff.md](../investigations/dspark-handoff.md).
|
|
265
|
-
- [ ] Verify the Eq 6 / §3.2.1 shapes against the actual paper when the PDF
|
|
266
|
-
is available (both flagged in code).
|
|
267
|
-
|
|
268
|
-
Full session handoff: `docs/investigations/dspark-handoff.md`.
|