mlx-bun 0.2.0 → 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 -588
- package/docs/README.md +91 -0
- package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
- package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
- package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
- package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
- package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
- package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
- package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
- 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 +2 -2
- package/docs/reference/benchmarks.md +1162 -0
- package/docs/reference/cli.md +394 -159
- package/docs/reference/distribution.md +321 -182
- package/docs/reference/environment.md +348 -0
- package/docs/reference/glossary.md +39 -0
- package/docs/reference/library-api.md +566 -168
- package/docs/reference/memory.md +227 -64
- package/docs/reference/models.md +104 -6
- package/docs/reference/server-api.md +886 -425
- package/docs/reference/server-config.md +638 -330
- package/docs/reference/training.md +393 -254
- package/docs/reference/troubleshooting.md +166 -0
- package/package.json +9 -4
- 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 +58 -25
- 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 +236 -3
- package/src/eval/reference-logits.ts +207 -0
- package/src/eval/runner.ts +8 -96
- 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 +1 -1
- package/src/generate.ts +656 -268
- package/src/grammar.ts +12 -7
- package/src/harness-pi.ts +14 -33
- package/src/hub-rest.ts +4 -4
- package/src/index.ts +7 -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 +12 -12
- 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-store.ts +109 -49
- 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} +5 -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 +1 -1
- package/src/memory/article.ts +1 -1
- package/src/memory/chunk.ts +1 -1
- package/src/memory/model.ts +30 -169
- 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 +1 -3
- package/src/mlx/array.ts +9 -10
- package/src/mlx/compile.ts +12 -2
- package/src/mlx/ffi.ts +58 -11
- package/src/mlx/materialize.ts +23 -0
- package/src/mlx/metal-kernel.ts +10 -11
- package/src/mlx/ops.ts +33 -13
- 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 +8 -2
- package/src/model/batched-quant.ts +1 -1
- package/src/model/batched-rotating-quant.ts +2 -2
- package/src/model/batched-rotating.ts +1 -1
- package/src/model/compiled-decode.ts +1 -1
- package/src/model/diffusion-gemma.ts +8 -8
- package/src/model/factory.ts +76 -33
- package/src/model/fingerprint.ts +1 -1
- package/src/model/flash-attention.ts +3 -3
- package/src/model/gemma4-base.ts +26 -9
- package/src/model/gemma4.ts +6 -6
- package/src/model/generated/gemma4-12b.ts +2 -2
- package/src/model/generated/gemma4-26b.ts +2 -2
- package/src/model/generated/gemma4-e4b.ts +2 -2
- package/src/model/glm52-dsa.ts +13 -9
- package/src/model/glm52-memory.ts +1 -1
- package/src/model/implementation.ts +69 -0
- package/src/model/minicpm5.ts +6 -8
- package/src/model/profile.ts +12 -2
- package/src/model/qwen-append.ts +12 -0
- package/src/model/qwen-conv.ts +52 -0
- package/src/model/qwen3_5-checkpoint.ts +164 -0
- package/src/model/qwen3_5.ts +140 -56
- 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-pack.ts +6 -5
- package/src/pi-provider.ts +6 -64
- package/src/pi-web.ts +8 -315
- package/src/prompt-cache.ts +96 -53
- package/src/quantize/allocator.ts +1 -1
- package/src/quantize/config-writer.ts +10 -3
- package/src/quantize/rotate.ts +4 -4
- package/src/quantize/trellis.ts +586 -0
- package/src/responses.ts +28 -1
- package/src/runtime-config.ts +18 -4
- package/src/sampler.ts +4 -4
- package/src/serve/batch-scheduler.ts +8 -1671
- 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 +15 -7
- package/src/serve/discovery-routes.ts +12 -13
- package/src/serve/generation-gateway.ts +154 -193
- 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/lab-routes.ts +3 -0
- package/src/serve/lane-registry.ts +2 -1
- package/src/serve/model-admin-routes.ts +7 -5
- 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/request-plan.ts +19 -15
- 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 +5 -5
- package/src/serve/text-completion-stage.ts +104 -0
- package/src/serve/token-streams.ts +519 -0
- package/src/server.ts +317 -2649
- package/src/spec/assistant-source.ts +10 -44
- package/src/spec/deepspec-source.ts +6 -6
- package/src/spec/dflash-source.ts +8 -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 +4 -3
- 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 +1 -1
- package/src/spec/ngram-source.ts +1 -1
- package/src/spec/prefix-state.ts +45 -0
- package/src/spec/qwen-mtp-source.ts +166 -69
- package/src/spec/serve-loop.ts +154 -156
- package/src/spec/source.ts +42 -10
- package/src/spec/two-model.ts +1 -1
- package/src/ssd-cache.ts +80 -12
- package/src/ssd-durability.ts +25 -13
- package/src/tool-call.ts +51 -14
- package/src/train/flash-cce.ts +2 -2
- package/src/train/forward.ts +6 -0
- package/src/train/loss.ts +1 -1
- package/src/train/prefix-shared.ts +5 -1
- package/src/train/segmented.ts +5 -3
- package/src/train/trainer.ts +6 -6
- package/src/vision/prompt.ts +1 -1
- package/src/vision/qwen3vl-tower.ts +52 -10
- package/src/web/app.html +1 -1
- package/src/web/app.js +5 -3
- package/src/web/src/adapters-panel.ts +3 -3
- package/src/web/src/assistant.ts +2 -36
- package/src/web/src/chat.ts +4 -4
- 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 +55 -9
- package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
- package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
- package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
- package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
- package/docs/archive/investigations/hlg-ab.html +0 -34
- package/docs/archive/investigations/hlg-explorer.html +0 -238
- package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
- package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
- package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
- package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
- package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
- package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
- package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
- package/docs/archive/investigations/hlg-report.html +0 -262
- package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
- package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
- package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
- package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
- package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
- package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
- package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
- package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
- package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
- package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
- package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
- package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
- package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
- package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
- package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
- package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
- package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
- package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
- package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
- package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
- package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
- package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
- package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
- package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
- package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
- package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
- package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
- package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
- package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
- package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
- package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
- package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
- package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
- package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
- package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
- package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
- package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
- package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
- package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
- package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
- package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
- package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
- package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
- package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
- package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
- package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
- 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 -318
- 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-serving-execution-seam.md +0 -81
- 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 -231
- 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 -415
- 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/turboquant-weights.md +0 -467
- 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/planning/IDEAS.md +0 -69
- package/docs/reference/embedding.md +0 -197
- package/docs/reference/features-matrix.md +0 -101
- package/docs/reference/orpo-quickstart.md +0 -135
- package/src/flags.ts +0 -11
- /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
- /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
- /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
- /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
- /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
- /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
- /package/{docs/archive/investigations → src/serve/assets}/curve-terrain.html +0 -0
- /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
|
@@ -1,848 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<title>mlx-bun — a WWDC keynote</title>
|
|
7
|
-
<style>
|
|
8
|
-
/* ————————————————————————————————————————————————
|
|
9
|
-
mlx-bun · keynote deck
|
|
10
|
-
Apple keynote grammar: black stage, SF Pro Display,
|
|
11
|
-
gradient hero type, one idea per slide, numbers that land.
|
|
12
|
-
———————————————————————————————————————————————— */
|
|
13
|
-
:root{
|
|
14
|
-
--bg:#000;
|
|
15
|
-
--ink:#f5f5f7;
|
|
16
|
-
--dim:#86868b;
|
|
17
|
-
--dimmer:#515154;
|
|
18
|
-
--hairline:rgba(255,255,255,.14);
|
|
19
|
-
--card:rgba(255,255,255,.045);
|
|
20
|
-
--card-hover:rgba(255,255,255,.08);
|
|
21
|
-
--blue:#0a84ff; --cyan:#64d2ff; --indigo:#5e5ce6; --purple:#bf5af2;
|
|
22
|
-
--pink:#ff375f; --orange:#ff9f0a; --yellow:#ffd60a; --green:#30d158;
|
|
23
|
-
--red:#ff453a;
|
|
24
|
-
--ease:cubic-bezier(.22,.61,.21,1);
|
|
25
|
-
}
|
|
26
|
-
*{box-sizing:border-box;margin:0;padding:0}
|
|
27
|
-
html,body{height:100%}
|
|
28
|
-
body{
|
|
29
|
-
background:var(--bg);
|
|
30
|
-
color:var(--ink);
|
|
31
|
-
font-family:"SF Pro Display","SF Pro Text",-apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,sans-serif;
|
|
32
|
-
-webkit-font-smoothing:antialiased;
|
|
33
|
-
overflow:hidden;
|
|
34
|
-
user-select:none;
|
|
35
|
-
}
|
|
36
|
-
::selection{background:rgba(10,132,255,.4)}
|
|
37
|
-
|
|
38
|
-
/* ——— deck mechanics ——— */
|
|
39
|
-
#deck{position:fixed;inset:0}
|
|
40
|
-
.slide{
|
|
41
|
-
position:absolute;inset:0;
|
|
42
|
-
display:flex;flex-direction:column;align-items:center;justify-content:center;
|
|
43
|
-
padding:6vh 7vw;
|
|
44
|
-
opacity:0;visibility:hidden;transform:scale(.985);
|
|
45
|
-
transition:opacity .65s var(--ease),transform .65s var(--ease),visibility 0s linear .65s;
|
|
46
|
-
overflow:hidden;
|
|
47
|
-
}
|
|
48
|
-
.slide.active{
|
|
49
|
-
opacity:1;visibility:visible;transform:none;
|
|
50
|
-
transition:opacity .65s var(--ease),transform .65s var(--ease),visibility 0s;
|
|
51
|
-
}
|
|
52
|
-
/* ambient color blooms, per-slide hues */
|
|
53
|
-
.slide::before{
|
|
54
|
-
content:"";position:absolute;inset:-25%;pointer-events:none;
|
|
55
|
-
background:
|
|
56
|
-
radial-gradient(55vw 42vh at 18% 86%, var(--g1,transparent), transparent 68%),
|
|
57
|
-
radial-gradient(60vw 48vh at 84% 10%, var(--g2,transparent), transparent 68%);
|
|
58
|
-
filter:blur(70px);
|
|
59
|
-
opacity:0;transition:opacity 1.4s var(--ease);
|
|
60
|
-
}
|
|
61
|
-
.slide.active::before{opacity:1}
|
|
62
|
-
.inner{position:relative;max-width:1180px;width:100%}
|
|
63
|
-
|
|
64
|
-
/* staggered reveals */
|
|
65
|
-
[data-reveal]{
|
|
66
|
-
opacity:0;transform:translateY(26px);
|
|
67
|
-
transition:opacity .9s var(--ease),transform .9s var(--ease);
|
|
68
|
-
transition-delay:calc(var(--d,0)*1ms);
|
|
69
|
-
}
|
|
70
|
-
.slide.active [data-reveal]{opacity:1;transform:none}
|
|
71
|
-
@media (prefers-reduced-motion:reduce){
|
|
72
|
-
[data-reveal]{transition:none;opacity:1;transform:none}
|
|
73
|
-
.slide{transition:opacity .2s}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/* ——— type ——— */
|
|
77
|
-
.eyebrow{
|
|
78
|
-
font-size:15px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
|
|
79
|
-
color:var(--dim);margin-bottom:26px;
|
|
80
|
-
}
|
|
81
|
-
h1.mega{
|
|
82
|
-
font-size:clamp(64px,11.5vw,176px);
|
|
83
|
-
font-weight:700;letter-spacing:-.035em;line-height:1.0;
|
|
84
|
-
}
|
|
85
|
-
h2.head{
|
|
86
|
-
font-size:clamp(40px,6.2vw,86px);
|
|
87
|
-
font-weight:700;letter-spacing:-.028em;line-height:1.04;
|
|
88
|
-
margin-bottom:30px;
|
|
89
|
-
}
|
|
90
|
-
h2.head .soft{color:var(--dimmer)}
|
|
91
|
-
p.lede{
|
|
92
|
-
font-size:clamp(17px,1.55vw,22px);line-height:1.5;color:var(--dim);
|
|
93
|
-
max-width:62ch;font-weight:400;
|
|
94
|
-
}
|
|
95
|
-
p.lede strong{color:var(--ink);font-weight:600}
|
|
96
|
-
.grad{
|
|
97
|
-
background-clip:text;-webkit-background-clip:text;color:transparent;
|
|
98
|
-
}
|
|
99
|
-
.g-hero{background-image:linear-gradient(96deg,var(--orange) 0%,var(--pink) 30%,var(--purple) 62%,var(--blue) 100%)}
|
|
100
|
-
.g-blue{background-image:linear-gradient(94deg,var(--cyan),var(--blue) 55%,var(--indigo))}
|
|
101
|
-
.g-green{background-image:linear-gradient(94deg,#a8ff9e,var(--green) 45%,var(--cyan))}
|
|
102
|
-
.g-pink{background-image:linear-gradient(94deg,var(--orange),var(--pink) 55%,var(--purple))}
|
|
103
|
-
.g-purple{background-image:linear-gradient(94deg,var(--pink),var(--purple) 55%,var(--indigo))}
|
|
104
|
-
.fine{
|
|
105
|
-
font-size:12.5px;color:var(--dimmer);letter-spacing:.01em;line-height:1.6;
|
|
106
|
-
margin-top:42px;
|
|
107
|
-
}
|
|
108
|
-
.center{text-align:center}
|
|
109
|
-
.num{font-variant-numeric:tabular-nums}
|
|
110
|
-
|
|
111
|
-
/* ——— hero ——— */
|
|
112
|
-
#s-hero .wwdc{
|
|
113
|
-
font-size:16px;font-weight:600;letter-spacing:.32em;color:var(--dim);
|
|
114
|
-
text-transform:uppercase;margin-bottom:34px;
|
|
115
|
-
}
|
|
116
|
-
#s-hero .sub{
|
|
117
|
-
margin-top:34px;font-size:clamp(19px,2.1vw,28px);color:var(--dim);
|
|
118
|
-
font-weight:500;letter-spacing:-.01em;
|
|
119
|
-
}
|
|
120
|
-
#s-hero .sub b{color:var(--ink);font-weight:600}
|
|
121
|
-
#s-hero .begin{
|
|
122
|
-
margin-top:8vh;font-size:13px;color:var(--dimmer);letter-spacing:.14em;
|
|
123
|
-
text-transform:uppercase;animation:pulse 2.6s ease-in-out infinite;
|
|
124
|
-
}
|
|
125
|
-
@keyframes pulse{0%,100%{opacity:.45}50%{opacity:1}}
|
|
126
|
-
|
|
127
|
-
/* ——— binding row (problem slide) ——— */
|
|
128
|
-
.bindings{display:flex;gap:14px;flex-wrap:wrap;margin:40px 0 8px}
|
|
129
|
-
.bind{
|
|
130
|
-
padding:13px 22px;border:1px solid var(--hairline);border-radius:999px;
|
|
131
|
-
font-size:17px;font-weight:600;color:var(--ink);
|
|
132
|
-
display:flex;align-items:center;gap:10px;background:var(--card);
|
|
133
|
-
}
|
|
134
|
-
.bind .ok{color:var(--green);font-weight:700}
|
|
135
|
-
.bind.missing{border-color:rgba(255,69,58,.5);color:var(--dim);background:rgba(255,69,58,.06)}
|
|
136
|
-
.bind.missing .ok{color:var(--red)}
|
|
137
|
-
|
|
138
|
-
/* ——— stacks (architecture slide) ——— */
|
|
139
|
-
.stacks{display:grid;grid-template-columns:1fr 1fr;gap:56px;margin-top:14px;align-items:start}
|
|
140
|
-
.stack h3{
|
|
141
|
-
font-size:14px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
|
|
142
|
-
color:var(--dim);margin-bottom:20px;
|
|
143
|
-
}
|
|
144
|
-
.stack h3.now{color:var(--cyan)}
|
|
145
|
-
.layer{
|
|
146
|
-
border:1px solid var(--hairline);border-radius:16px;background:var(--card);
|
|
147
|
-
padding:17px 22px;font-size:16.5px;font-weight:600;letter-spacing:-.01em;
|
|
148
|
-
display:flex;justify-content:space-between;align-items:baseline;gap:14px;
|
|
149
|
-
}
|
|
150
|
-
.layer small{font-size:12.5px;color:var(--dimmer);font-weight:500;text-align:right;white-space:nowrap}
|
|
151
|
-
.layer.pain{border-color:rgba(255,69,58,.35);background:rgba(255,69,58,.05)}
|
|
152
|
-
.layer.pain small{color:rgba(255,99,90,.85)}
|
|
153
|
-
.layer.glowy{
|
|
154
|
-
border-color:rgba(100,210,255,.45);background:rgba(10,132,255,.09);
|
|
155
|
-
box-shadow:0 0 44px rgba(10,132,255,.18);
|
|
156
|
-
}
|
|
157
|
-
.down{
|
|
158
|
-
text-align:center;color:var(--dimmer);font-size:15px;line-height:1;
|
|
159
|
-
padding:7px 0;
|
|
160
|
-
}
|
|
161
|
-
.stack .verdict{margin-top:20px;font-size:14.5px;color:var(--dim);line-height:1.55}
|
|
162
|
-
.stack .verdict b{color:var(--ink)}
|
|
163
|
-
|
|
164
|
-
/* ——— giant zero (correctness) ——— */
|
|
165
|
-
.delta{
|
|
166
|
-
font-size:clamp(96px,17vw,260px);font-weight:700;letter-spacing:-.04em;line-height:1;
|
|
167
|
-
margin:6px 0 26px;
|
|
168
|
-
}
|
|
169
|
-
.chips{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:36px}
|
|
170
|
-
.chip{
|
|
171
|
-
font-size:13.5px;font-weight:600;color:var(--ink);
|
|
172
|
-
border:1px solid var(--hairline);border-radius:999px;padding:9px 17px;
|
|
173
|
-
background:var(--card);letter-spacing:.01em;
|
|
174
|
-
}
|
|
175
|
-
.chip b{color:var(--green);margin-right:7px}
|
|
176
|
-
|
|
177
|
-
/* ——— stat grid ——— */
|
|
178
|
-
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:26px;margin-top:18px}
|
|
179
|
-
.stat{padding:8px 4px;text-align:center}
|
|
180
|
-
.stat .v{
|
|
181
|
-
font-size:clamp(44px,5.6vw,84px);font-weight:700;letter-spacing:-.03em;line-height:1.05;
|
|
182
|
-
white-space:nowrap;
|
|
183
|
-
}
|
|
184
|
-
.stat .v small{font-size:.45em;font-weight:600;letter-spacing:-.01em}
|
|
185
|
-
.stat .k{margin-top:14px;font-size:15px;color:var(--dim);line-height:1.45;font-weight:500}
|
|
186
|
-
.stat .k b{color:var(--ink)}
|
|
187
|
-
|
|
188
|
-
/* ——— bar charts ——— */
|
|
189
|
-
.charts{display:grid;grid-template-columns:1fr 1fr 1fr;gap:48px;margin-top:24px}
|
|
190
|
-
.chart h4{font-size:16px;font-weight:600;letter-spacing:-.01em;margin-bottom:4px}
|
|
191
|
-
.chart .u{font-size:12.5px;color:var(--dimmer);margin-bottom:22px;font-weight:500}
|
|
192
|
-
.brow{margin-bottom:18px}
|
|
193
|
-
.brow .lbl{
|
|
194
|
-
display:flex;justify-content:space-between;align-items:baseline;
|
|
195
|
-
font-size:13.5px;color:var(--dim);margin-bottom:8px;font-weight:500;
|
|
196
|
-
}
|
|
197
|
-
.brow .lbl b{color:var(--ink);font-weight:600}
|
|
198
|
-
.brow .val{font-variant-numeric:tabular-nums;font-weight:600;color:var(--ink);font-size:14px}
|
|
199
|
-
.track{height:10px;border-radius:99px;background:rgba(255,255,255,.07);overflow:hidden}
|
|
200
|
-
.bar{
|
|
201
|
-
height:100%;width:0;border-radius:99px;
|
|
202
|
-
transition:width 1.25s var(--ease);
|
|
203
|
-
background:rgba(255,255,255,.32);
|
|
204
|
-
}
|
|
205
|
-
.slide.active .bar{width:var(--w)}
|
|
206
|
-
.bar.us{background:linear-gradient(90deg,var(--cyan),var(--blue) 70%,var(--indigo))}
|
|
207
|
-
.brow.failed .val{color:var(--red);font-weight:700}
|
|
208
|
-
.brow.failed .track{background:rgba(255,69,58,.12)}
|
|
209
|
-
|
|
210
|
-
/* ——— model cards ——— */
|
|
211
|
-
.models{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;margin-top:14px}
|
|
212
|
-
.model{
|
|
213
|
-
border:1px solid var(--hairline);border-radius:22px;background:var(--card);
|
|
214
|
-
padding:30px 28px;display:flex;flex-direction:column;gap:0;min-height:280px;
|
|
215
|
-
transition:background .3s,border-color .3s,transform .3s var(--ease);
|
|
216
|
-
}
|
|
217
|
-
.model:hover{background:var(--card-hover);transform:translateY(-4px)}
|
|
218
|
-
.model .size{font-size:13px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
|
|
219
|
-
.model .name{font-size:25px;font-weight:700;letter-spacing:-.02em;margin:12px 0 4px}
|
|
220
|
-
.model .speed{font-size:42px;font-weight:700;letter-spacing:-.03em;margin:18px 0 2px}
|
|
221
|
-
.model .speed small{font-size:15px;color:var(--dim);font-weight:500;letter-spacing:0}
|
|
222
|
-
.model .desc{font-size:14.5px;color:var(--dim);line-height:1.55;margin-top:14px}
|
|
223
|
-
.model .desc b{color:var(--ink)}
|
|
224
|
-
.model .tagrow{display:flex;gap:8px;flex-wrap:wrap;margin-top:auto;padding-top:20px}
|
|
225
|
-
.tag{font-size:11.5px;font-weight:600;padding:5px 11px;border-radius:99px;letter-spacing:.03em}
|
|
226
|
-
.tag.b{background:rgba(10,132,255,.16);color:#7dc1ff}
|
|
227
|
-
.tag.p{background:rgba(191,90,242,.16);color:#d9a0f7}
|
|
228
|
-
.tag.g{background:rgba(48,209,88,.14);color:#7ce69a}
|
|
229
|
-
.tag.o{background:rgba(255,159,10,.15);color:#ffc46b}
|
|
230
|
-
|
|
231
|
-
/* ——— feature grid ——— */
|
|
232
|
-
.feats{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:10px}
|
|
233
|
-
.feat{
|
|
234
|
-
border:1px solid var(--hairline);border-radius:18px;background:var(--card);
|
|
235
|
-
padding:20px 22px;display:flex;gap:16px;align-items:flex-start;
|
|
236
|
-
transition:background .3s;
|
|
237
|
-
}
|
|
238
|
-
.feat:hover{background:var(--card-hover)}
|
|
239
|
-
.glyph{
|
|
240
|
-
flex:0 0 40px;height:40px;border-radius:11px;display:flex;align-items:center;justify-content:center;
|
|
241
|
-
font-size:19px;font-weight:700;color:#fff;
|
|
242
|
-
}
|
|
243
|
-
.feat h5{font-size:15.5px;font-weight:600;letter-spacing:-.01em;margin-bottom:5px}
|
|
244
|
-
.feat p{font-size:13px;color:var(--dim);line-height:1.5}
|
|
245
|
-
|
|
246
|
-
/* ——— one more thing ——— */
|
|
247
|
-
#s-omt h1{
|
|
248
|
-
font-size:clamp(40px,6.5vw,92px);font-weight:600;letter-spacing:-.02em;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/* ——— terminal ——— */
|
|
252
|
-
.term{
|
|
253
|
-
width:min(840px,100%);margin:34px auto 0;border-radius:14px;overflow:hidden;
|
|
254
|
-
border:1px solid var(--hairline);
|
|
255
|
-
background:rgba(18,18,20,.92);
|
|
256
|
-
box-shadow:0 30px 80px rgba(0,0,0,.6),0 0 60px rgba(94,92,230,.12);
|
|
257
|
-
text-align:left;
|
|
258
|
-
}
|
|
259
|
-
.term .bar3{
|
|
260
|
-
display:flex;gap:8px;align-items:center;padding:13px 16px;
|
|
261
|
-
background:rgba(255,255,255,.05);border-bottom:1px solid rgba(255,255,255,.07);
|
|
262
|
-
}
|
|
263
|
-
.term .dot3{width:12px;height:12px;border-radius:50%}
|
|
264
|
-
.term .title3{margin-left:10px;font-size:12px;color:var(--dimmer);font-weight:500}
|
|
265
|
-
.term pre{
|
|
266
|
-
padding:24px 26px 28px;
|
|
267
|
-
font-family:"SF Mono",ui-monospace,Menlo,monospace;
|
|
268
|
-
font-size:14.5px;line-height:1.9;color:#d8d8dc;white-space:pre-wrap;
|
|
269
|
-
}
|
|
270
|
-
.term .c{color:#6e6e73}
|
|
271
|
-
.term .p{color:#7ce69a}
|
|
272
|
-
.term .cmd{color:#fff;font-weight:600}
|
|
273
|
-
.term .hl{color:#7dc1ff}
|
|
274
|
-
.term .ok{color:#30d158}
|
|
275
|
-
|
|
276
|
-
/* ——— findings ——— */
|
|
277
|
-
.finds{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:8px}
|
|
278
|
-
.find{
|
|
279
|
-
border:1px solid var(--hairline);border-radius:16px;background:var(--card);
|
|
280
|
-
padding:20px;transition:background .3s;
|
|
281
|
-
}
|
|
282
|
-
.find:hover{background:var(--card-hover)}
|
|
283
|
-
.find .n{
|
|
284
|
-
font-size:12px;font-weight:700;color:var(--dimmer);letter-spacing:.12em;margin-bottom:12px;
|
|
285
|
-
font-variant-numeric:tabular-nums;
|
|
286
|
-
}
|
|
287
|
-
.find h5{font-size:15px;font-weight:600;letter-spacing:-.01em;line-height:1.3;margin-bottom:9px}
|
|
288
|
-
.find p{font-size:12.5px;color:var(--dim);line-height:1.55}
|
|
289
|
-
.find p b{color:var(--ink);font-weight:600}
|
|
290
|
-
|
|
291
|
-
/* ——— roadmap ——— */
|
|
292
|
-
.road{margin-top:10px;display:flex;flex-direction:column}
|
|
293
|
-
.ritem{
|
|
294
|
-
display:grid;grid-template-columns:240px 1fr;gap:36px;align-items:baseline;
|
|
295
|
-
padding:24px 6px;border-bottom:1px solid rgba(255,255,255,.08);
|
|
296
|
-
}
|
|
297
|
-
.ritem:last-child{border-bottom:none}
|
|
298
|
-
.ritem .rt{font-size:23px;font-weight:700;letter-spacing:-.02em}
|
|
299
|
-
.ritem .rd{font-size:15.5px;color:var(--dim);line-height:1.55}
|
|
300
|
-
.ritem .rd b{color:var(--ink)}
|
|
301
|
-
|
|
302
|
-
/* ——— pillars (vision) ——— */
|
|
303
|
-
.pillars{display:grid;grid-template-columns:repeat(3,1fr);gap:30px;margin-top:48px;text-align:left}
|
|
304
|
-
.pillar h4{font-size:21px;font-weight:700;letter-spacing:-.015em;margin-bottom:12px}
|
|
305
|
-
.pillar p{font-size:15px;color:var(--dim);line-height:1.6}
|
|
306
|
-
.pillar .rule{height:3px;width:44px;border-radius:99px;margin-bottom:20px}
|
|
307
|
-
|
|
308
|
-
/* ——— outro ——— */
|
|
309
|
-
#s-outro .tag-line{
|
|
310
|
-
margin-top:30px;font-size:clamp(19px,2.2vw,30px);color:var(--dim);font-weight:500;letter-spacing:-.01em;
|
|
311
|
-
}
|
|
312
|
-
#s-outro .tag-line b{color:var(--ink)}
|
|
313
|
-
|
|
314
|
-
/* ——— HUD ——— */
|
|
315
|
-
#hud{
|
|
316
|
-
position:fixed;bottom:26px;left:0;right:0;display:flex;justify-content:center;gap:9px;
|
|
317
|
-
z-index:10;
|
|
318
|
-
}
|
|
319
|
-
#hud .dot{
|
|
320
|
-
width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.22);
|
|
321
|
-
cursor:pointer;transition:all .35s var(--ease);border:none;padding:0;
|
|
322
|
-
}
|
|
323
|
-
#hud .dot.on{background:#fff;transform:scale(1.25)}
|
|
324
|
-
#hint{
|
|
325
|
-
position:fixed;bottom:22px;left:30px;font-size:12px;color:var(--dimmer);
|
|
326
|
-
letter-spacing:.1em;text-transform:uppercase;z-index:10;transition:opacity .8s;
|
|
327
|
-
}
|
|
328
|
-
#count{
|
|
329
|
-
position:fixed;bottom:22px;right:30px;font-size:12px;color:var(--dimmer);
|
|
330
|
-
font-variant-numeric:tabular-nums;letter-spacing:.08em;z-index:10;
|
|
331
|
-
}
|
|
332
|
-
.edge{
|
|
333
|
-
position:fixed;top:0;bottom:0;width:9vw;z-index:5;cursor:pointer;border:none;background:transparent;
|
|
334
|
-
color:transparent;font-size:30px;transition:color .3s;
|
|
335
|
-
}
|
|
336
|
-
.edge:hover{color:rgba(255,255,255,.35)}
|
|
337
|
-
.edge.l{left:0}.edge.r{right:0}
|
|
338
|
-
|
|
339
|
-
@media (max-width:980px){
|
|
340
|
-
.stats{grid-template-columns:repeat(2,1fr);gap:34px}
|
|
341
|
-
.charts{grid-template-columns:1fr;gap:30px}
|
|
342
|
-
.models,.feats{grid-template-columns:1fr;gap:14px}
|
|
343
|
-
.finds{grid-template-columns:repeat(2,1fr)}
|
|
344
|
-
.stacks{grid-template-columns:1fr;gap:34px}
|
|
345
|
-
.pillars{grid-template-columns:1fr}
|
|
346
|
-
.ritem{grid-template-columns:1fr;gap:6px;padding:18px 2px}
|
|
347
|
-
.slide{padding:5vh 6vw;overflow-y:auto;justify-content:flex-start}
|
|
348
|
-
.model{min-height:0}
|
|
349
|
-
}
|
|
350
|
-
</style>
|
|
351
|
-
</head>
|
|
352
|
-
<body>
|
|
353
|
-
|
|
354
|
-
<main id="deck">
|
|
355
|
-
|
|
356
|
-
<!-- ─── 1 · HERO ─────────────────────────────────────────── -->
|
|
357
|
-
<section class="slide center" id="s-hero" style="--g1:rgba(191,90,242,.20);--g2:rgba(10,132,255,.22)">
|
|
358
|
-
<div class="inner">
|
|
359
|
-
<div class="wwdc" data-reveal style="--d:0">WWDC26 · Special Event</div>
|
|
360
|
-
<h1 class="mega grad g-hero" data-reveal style="--d:150">mlx-bun</h1>
|
|
361
|
-
<p class="sub" data-reveal style="--d:380">Native MLX inference for Bun. <b>No Python. No sidecar. One runtime.</b></p>
|
|
362
|
-
<div class="begin" data-reveal style="--d:900">Press → to begin</div>
|
|
363
|
-
</div>
|
|
364
|
-
</section>
|
|
365
|
-
|
|
366
|
-
<!-- ─── 2 · THE PROBLEM ──────────────────────────────────── -->
|
|
367
|
-
<section class="slide" style="--g1:rgba(255,69,58,.10);--g2:rgba(94,92,230,.14)">
|
|
368
|
-
<div class="inner">
|
|
369
|
-
<div class="eyebrow" data-reveal style="--d:0">The problem</div>
|
|
370
|
-
<h2 class="head" data-reveal style="--d:120">Apple Silicon is extraordinary.<br><span class="soft">JavaScript can’t reach it.</span></h2>
|
|
371
|
-
<p class="lede" data-reveal style="--d:280">MLX is Apple’s ML framework — hand-tuned Metal kernels for the unified-memory GPU. It ships official bindings for four languages. The language of every agent, every dev tool, every Electron and Tauri app isn’t one of them.</p>
|
|
372
|
-
<div class="bindings" data-reveal style="--d:440">
|
|
373
|
-
<span class="bind"><span class="ok">✓</span> Python</span>
|
|
374
|
-
<span class="bind"><span class="ok">✓</span> C++</span>
|
|
375
|
-
<span class="bind"><span class="ok">✓</span> Swift</span>
|
|
376
|
-
<span class="bind"><span class="ok">✓</span> C</span>
|
|
377
|
-
<span class="bind missing"><span class="ok">✗</span> JavaScript</span>
|
|
378
|
-
</div>
|
|
379
|
-
<p class="lede" data-reveal style="--d:600;margin-top:26px">So today, a TypeScript app that wants local inference shells out to a Python server — and inherits that stack’s fragility: venv setup, brittle downloads, monkey-patched HTTP layers, segfaults on exit.</p>
|
|
380
|
-
</div>
|
|
381
|
-
</section>
|
|
382
|
-
|
|
383
|
-
<!-- ─── 3 · THE INSIGHT ──────────────────────────────────── -->
|
|
384
|
-
<section class="slide" style="--g1:rgba(100,210,255,.13);--g2:rgba(48,209,88,.10)">
|
|
385
|
-
<div class="inner">
|
|
386
|
-
<div class="eyebrow" data-reveal style="--d:0">The insight</div>
|
|
387
|
-
<h2 class="head" data-reveal style="--d:120">The GPU sets the speed.<br><span class="grad g-blue">Delete everything around it.</span></h2>
|
|
388
|
-
<p class="lede" data-reveal style="--d:300">Every matmul, every attention pass already lives in MLX’s C++ and Metal core, exposed through <strong>mlx-c</strong>. The Python on top is pure orchestration — loading, tokenizing, sampling, serving. The GPU dominates; that layer is <strong>performance-neutral</strong>.</p>
|
|
389
|
-
<p class="lede" data-reveal style="--d:480;margin-top:24px">Which means it can be rewritten in any runtime without losing a single token per second. So we rewrote it in the one your code already lives in.</p>
|
|
390
|
-
<p class="fine" data-reveal style="--d:640">Decode is memory-bandwidth-bound: ~273 GB/s on an M4 Pro ÷ bytes-of-weights = the ceiling. Wins come from fewer bytes per token — never from “faster JS.”</p>
|
|
391
|
-
</div>
|
|
392
|
-
</section>
|
|
393
|
-
|
|
394
|
-
<!-- ─── 4 · INTRODUCING / ARCHITECTURE ───────────────────── -->
|
|
395
|
-
<section class="slide" style="--g1:rgba(10,132,255,.16);--g2:rgba(191,90,242,.12)">
|
|
396
|
-
<div class="inner">
|
|
397
|
-
<div class="eyebrow" data-reveal style="--d:0">Introducing</div>
|
|
398
|
-
<h2 class="head" data-reveal style="--d:100"><span class="grad g-hero">mlx-bun</span></h2>
|
|
399
|
-
<div class="stacks">
|
|
400
|
-
<div class="stack" data-reveal style="--d:260">
|
|
401
|
-
<h3>Yesterday</h3>
|
|
402
|
-
<div class="layer">Your TypeScript app</div>
|
|
403
|
-
<div class="down">↓</div>
|
|
404
|
-
<div class="layer pain">HTTP to localhost <small>serialize · deserialize</small></div>
|
|
405
|
-
<div class="down">↓</div>
|
|
406
|
-
<div class="layer pain">Python venv · mlx-lm server <small>−5–7% server tax</small></div>
|
|
407
|
-
<div class="down">↓</div>
|
|
408
|
-
<div class="layer">MLX · Metal kernels</div>
|
|
409
|
-
<div class="verdict">Two runtimes. Two package managers. A process boundary in the hot path.</div>
|
|
410
|
-
</div>
|
|
411
|
-
<div class="stack" data-reveal style="--d:460">
|
|
412
|
-
<h3 class="now">Today</h3>
|
|
413
|
-
<div class="layer">Your TypeScript app</div>
|
|
414
|
-
<div class="down">↓</div>
|
|
415
|
-
<div class="layer glowy">bun:ffi → mlx-c <small>zero-copy · ≈0% overhead</small></div>
|
|
416
|
-
<div class="down">↓</div>
|
|
417
|
-
<div class="layer">MLX · Metal kernels</div>
|
|
418
|
-
<div class="verdict"><b>One process.</b> Lazy native weight loading opens an 8.9 GB model in milliseconds. <b>Bun.Image</b> decodes HEIC & AVIF for vision. <b>bun:sqlite</b> holds the registry. One binary, one toolchain.</div>
|
|
419
|
-
</div>
|
|
420
|
-
</div>
|
|
421
|
-
</div>
|
|
422
|
-
</section>
|
|
423
|
-
|
|
424
|
-
<!-- ─── 5 · CORRECTNESS ──────────────────────────────────── -->
|
|
425
|
-
<section class="slide center" style="--g1:rgba(48,209,88,.13);--g2:rgba(100,210,255,.12)">
|
|
426
|
-
<div class="inner">
|
|
427
|
-
<div class="eyebrow" data-reveal style="--d:0">Correctness</div>
|
|
428
|
-
<div class="delta grad g-green" data-reveal style="--d:150">max |Δ| = 0</div>
|
|
429
|
-
<p class="lede" data-reveal style="--d:340;margin:0 auto">Logit parity with the Python reference is the project’s oracle. The forward pass is <strong>bit-exact</strong> — every model, every step, every quantized-KV configuration. Not approximately right. <strong>Exactly</strong> right.</p>
|
|
430
|
-
<div class="chips" data-reveal style="--d:540">
|
|
431
|
-
<span class="chip"><b>✓</b>12B dense</span>
|
|
432
|
-
<span class="chip"><b>✓</b>e4b per-layer-input</span>
|
|
433
|
-
<span class="chip"><b>✓</b>26B MoE · top-8 of 128</span>
|
|
434
|
-
<span class="chip"><b>✓</b>kv8</span>
|
|
435
|
-
<span class="chip"><b>✓</b>kv4</span>
|
|
436
|
-
<span class="chip"><b>✓</b>mixed per-layer KV</span>
|
|
437
|
-
<span class="chip"><b>✓</b>fused quantized prefill</span>
|
|
438
|
-
<span class="chip"><b>✓</b>vision · token-exact</span>
|
|
439
|
-
</div>
|
|
440
|
-
<p class="fine" data-reveal style="--d:720">157/157 tests. Golden files regenerate only from the Python oracle. The one latent divergence ever found — rope frequencies computed host-side — was root-caused and fixed.</p>
|
|
441
|
-
</div>
|
|
442
|
-
</section>
|
|
443
|
-
|
|
444
|
-
<!-- ─── 6 · FAST (STAT GRID) ─────────────────────────────── -->
|
|
445
|
-
<section class="slide center" style="--g1:rgba(255,159,10,.13);--g2:rgba(255,55,95,.13)">
|
|
446
|
-
<div class="inner">
|
|
447
|
-
<div class="eyebrow" data-reveal style="--d:0">Performance</div>
|
|
448
|
-
<h2 class="head" data-reveal style="--d:100">And it’s <span class="grad g-pink">fast.</span></h2>
|
|
449
|
-
<div class="stats">
|
|
450
|
-
<div class="stat" data-reveal style="--d:260">
|
|
451
|
-
<div class="v grad g-pink"><span class="num" data-count="5" data-prefix="up to ">up to 5</span>×</div>
|
|
452
|
-
<div class="k">faster time to first token, served<br><b>45–90 ms</b> vs Python’s 219–331 ms</div>
|
|
453
|
-
</div>
|
|
454
|
-
<div class="stat" data-reveal style="--d:380">
|
|
455
|
-
<div class="v grad g-pink"><span class="num" data-count="394">394</span><small> ms</small></div>
|
|
456
|
-
<div class="k">cold start → first token<br>of a <b>cached prompt</b>, fresh process</div>
|
|
457
|
-
</div>
|
|
458
|
-
<div class="stat" data-reveal style="--d:500">
|
|
459
|
-
<div class="v grad g-pink">≈<span class="num" data-count="0">0</span><small>%</small></div>
|
|
460
|
-
<div class="k">server overhead vs direct decode<br>mlx-lm pays <b>−5–7%</b></div>
|
|
461
|
-
</div>
|
|
462
|
-
<div class="stat" data-reveal style="--d:620">
|
|
463
|
-
<div class="v grad g-pink"><span class="num" data-count="1.8" data-decimals="1">1.8</span><small>×</small></div>
|
|
464
|
-
<div class="k">prefill throughput vs mlx-lm<br>at <b>8k context</b></div>
|
|
465
|
-
</div>
|
|
466
|
-
</div>
|
|
467
|
-
<p class="fine" data-reveal style="--d:800">Apple M4 Pro, 24 GB · same machine, same day, same weights · cleared-machine matrix, median-of-N, warmups discarded · 2026-06-11</p>
|
|
468
|
-
</div>
|
|
469
|
-
</section>
|
|
470
|
-
|
|
471
|
-
<!-- ─── 7 · CHARTS ───────────────────────────────────────── -->
|
|
472
|
-
<section class="slide" style="--g1:rgba(10,132,255,.14);--g2:rgba(100,210,255,.10)">
|
|
473
|
-
<div class="inner">
|
|
474
|
-
<div class="eyebrow" data-reveal style="--d:0">Head-to-head</div>
|
|
475
|
-
<h2 class="head" data-reveal style="--d:100">Served. Warm. <span class="grad g-blue">Measured.</span></h2>
|
|
476
|
-
<div class="charts">
|
|
477
|
-
<div class="chart" data-reveal style="--d:280">
|
|
478
|
-
<h4>Time to first token</h4>
|
|
479
|
-
<div class="u">milliseconds · gemma-4-e4b, served · lower is better</div>
|
|
480
|
-
<div class="brow">
|
|
481
|
-
<div class="lbl"><b>mlx-bun</b><span class="val">45 ms</span></div>
|
|
482
|
-
<div class="track"><div class="bar us" style="--w:13.6%"></div></div>
|
|
483
|
-
</div>
|
|
484
|
-
<div class="brow">
|
|
485
|
-
<div class="lbl">mlx-lm<span class="val">219 ms</span></div>
|
|
486
|
-
<div class="track"><div class="bar" style="--w:66%"></div></div>
|
|
487
|
-
</div>
|
|
488
|
-
<div class="brow">
|
|
489
|
-
<div class="lbl">optiq<span class="val">222 ms</span></div>
|
|
490
|
-
<div class="track"><div class="bar" style="--w:67%"></div></div>
|
|
491
|
-
</div>
|
|
492
|
-
</div>
|
|
493
|
-
<div class="chart" data-reveal style="--d:440">
|
|
494
|
-
<h4>Server start → ready</h4>
|
|
495
|
-
<div class="u">seconds · lower is better</div>
|
|
496
|
-
<div class="brow">
|
|
497
|
-
<div class="lbl"><b>mlx-bun</b><span class="val">0.36 s</span></div>
|
|
498
|
-
<div class="track"><div class="bar us" style="--w:24%"></div></div>
|
|
499
|
-
</div>
|
|
500
|
-
<div class="brow">
|
|
501
|
-
<div class="lbl">mlx-lm<span class="val">0.98 s</span></div>
|
|
502
|
-
<div class="track"><div class="bar" style="--w:65%"></div></div>
|
|
503
|
-
</div>
|
|
504
|
-
<div class="brow">
|
|
505
|
-
<div class="lbl">optiq<span class="val">0.79 s</span></div>
|
|
506
|
-
<div class="track"><div class="bar" style="--w:53%"></div></div>
|
|
507
|
-
</div>
|
|
508
|
-
</div>
|
|
509
|
-
<div class="chart" data-reveal style="--d:600">
|
|
510
|
-
<h4>Decode, 26B MoE</h4>
|
|
511
|
-
<div class="u">tokens / second, served · higher is better</div>
|
|
512
|
-
<div class="brow">
|
|
513
|
-
<div class="lbl"><b>mlx-bun</b><span class="val">54.9</span></div>
|
|
514
|
-
<div class="track"><div class="bar us" style="--w:88%"></div></div>
|
|
515
|
-
</div>
|
|
516
|
-
<div class="brow">
|
|
517
|
-
<div class="lbl">mlx-lm<span class="val">52.2</span></div>
|
|
518
|
-
<div class="track"><div class="bar" style="--w:84%"></div></div>
|
|
519
|
-
</div>
|
|
520
|
-
<div class="brow failed">
|
|
521
|
-
<div class="lbl">optiq<span class="val">crashed</span></div>
|
|
522
|
-
<div class="track"></div>
|
|
523
|
-
</div>
|
|
524
|
-
</div>
|
|
525
|
-
</div>
|
|
526
|
-
<p class="fine" data-reveal style="--d:760">The fastest TTFT and startup on every model tested, by 2–5×. And the full matrix records where we lose, too — every number, including the honest negatives, lives in <span style="font-family:'SF Mono',ui-monospace,monospace">benchmarks-h2h-2026-06-11</span> with per-row provenance.</p>
|
|
527
|
-
</div>
|
|
528
|
-
</section>
|
|
529
|
-
|
|
530
|
-
<!-- ─── 8 · MODELS TODAY ─────────────────────────────────── -->
|
|
531
|
-
<section class="slide" style="--g1:rgba(191,90,242,.13);--g2:rgba(255,159,10,.10)">
|
|
532
|
-
<div class="inner">
|
|
533
|
-
<div class="eyebrow" data-reveal style="--d:0">Available today</div>
|
|
534
|
-
<h2 class="head" data-reveal style="--d:100">Three models. <span class="soft">Held to zero.</span></h2>
|
|
535
|
-
<div class="models">
|
|
536
|
-
<div class="model" data-reveal style="--d:260">
|
|
537
|
-
<div class="size">7.0 GB · fits 16 GB</div>
|
|
538
|
-
<div class="name">gemma-4-e4b</div>
|
|
539
|
-
<div class="speed num">54<small> tok/s</small></div>
|
|
540
|
-
<div class="desc">The good first model. Per-layer-input embeddings and KV-shared layers, bit-exact through the whole stack.</div>
|
|
541
|
-
<div class="tagrow"><span class="tag b">OptiQ 4-bit</span><span class="tag g">bit-exact</span></div>
|
|
542
|
-
</div>
|
|
543
|
-
<div class="model" data-reveal style="--d:400">
|
|
544
|
-
<div class="size">8.4 GB · fits 16 GB</div>
|
|
545
|
-
<div class="name">gemma-4-12B</div>
|
|
546
|
-
<div class="speed num">25<small> tok/s</small></div>
|
|
547
|
-
<div class="desc"><b>Vision and tool calling</b>, both verified end-to-end — a real photo described, a real agent task completed through tool calls.</div>
|
|
548
|
-
<div class="tagrow"><span class="tag p">vision</span><span class="tag o">tools</span><span class="tag g">bit-exact</span></div>
|
|
549
|
-
</div>
|
|
550
|
-
<div class="model" data-reveal style="--d:540">
|
|
551
|
-
<div class="size">18 GB · fits 24 GB</div>
|
|
552
|
-
<div class="name">gemma-4-26B-A4B</div>
|
|
553
|
-
<div class="speed num">55<small> tok/s</small></div>
|
|
554
|
-
<div class="desc">Mixture-of-Experts, top-8 of 128. Decode reads ~2.4 GB of 14 GB expert weights per token. <b>The Python servers crash loading it on 24 GB.</b></div>
|
|
555
|
-
<div class="tagrow"><span class="tag b">MoE</span><span class="tag g">bit-exact</span></div>
|
|
556
|
-
</div>
|
|
557
|
-
</div>
|
|
558
|
-
<p class="fine" data-reveal style="--d:700">Scope is the strategy: a few model families held to bit-exact parity, rather than dozens held to none. Not sure what fits? <span style="font-family:'SF Mono',ui-monospace,monospace">mlx-bun fit</span> gives a deterministic answer — weights, KV, transient, wired ceiling — for your machine or the whole Apple Silicon lineup.</p>
|
|
559
|
-
</div>
|
|
560
|
-
</section>
|
|
561
|
-
|
|
562
|
-
<!-- ─── 9 · PLATFORM ─────────────────────────────────────── -->
|
|
563
|
-
<section class="slide" style="--g1:rgba(10,132,255,.12);--g2:rgba(48,209,88,.10)">
|
|
564
|
-
<div class="inner">
|
|
565
|
-
<div class="eyebrow" data-reveal style="--d:0">The platform</div>
|
|
566
|
-
<h2 class="head" data-reveal style="--d:100">Not a demo. <span class="grad g-blue">An appliance.</span></h2>
|
|
567
|
-
<div class="feats">
|
|
568
|
-
<div class="feat" data-reveal style="--d:240">
|
|
569
|
-
<div class="glyph" style="background:linear-gradient(140deg,#0a84ff,#5e5ce6)"></></div>
|
|
570
|
-
<div><h5>OpenAI-compatible API</h5><p>Chat completions, SSE streaming, stop sequences, seeded sampling. Any OpenAI client just works.</p></div>
|
|
571
|
-
</div>
|
|
572
|
-
<div class="feat" data-reveal style="--d:300">
|
|
573
|
-
<div class="glyph" style="background:linear-gradient(140deg,#bf5af2,#ff375f)">✱</div>
|
|
574
|
-
<div><h5>Anthropic Messages API</h5><p>Full streaming event grammar, tool_use, image blocks. Claude Code runs against it as a local backend.</p></div>
|
|
575
|
-
</div>
|
|
576
|
-
<div class="feat" data-reveal style="--d:360">
|
|
577
|
-
<div class="glyph" style="background:linear-gradient(140deg,#64d2ff,#0a84ff)">↺</div>
|
|
578
|
-
<div><h5>Responses API</h5><p>The protocol Codex, Cursor and Continue speak — with previous_response_id resumption.</p></div>
|
|
579
|
-
</div>
|
|
580
|
-
<div class="feat" data-reveal style="--d:420">
|
|
581
|
-
<div class="glyph" style="background:linear-gradient(140deg,#ff9f0a,#ff375f)">ƒ</div>
|
|
582
|
-
<div><h5>Tool calling</h5><p>Native marker tokens parsed into tool_calls JSON; tool-role round-trips verified on the live model.</p></div>
|
|
583
|
-
</div>
|
|
584
|
-
<div class="feat" data-reveal style="--d:480">
|
|
585
|
-
<div class="glyph" style="background:linear-gradient(140deg,#30d158,#64d2ff)">◎</div>
|
|
586
|
-
<div><h5>Vision, native codecs</h5><p>HEIC, AVIF, WebP, JPEG via the OS — EXIF auto-orientation included. Token-exact with the reference.</p></div>
|
|
587
|
-
</div>
|
|
588
|
-
<div class="feat" data-reveal style="--d:540">
|
|
589
|
-
<div class="glyph" style="background:linear-gradient(140deg,#ffd60a,#ff9f0a)">⚡</div>
|
|
590
|
-
<div><h5>Prompt cache + KV persistence</h5><p>Byte-capped LRU prefix reuse, automatic. Page-aligned cache files reload as zero-copy GPU mmaps in 1 ms.</p></div>
|
|
591
|
-
</div>
|
|
592
|
-
<div class="feat" data-reveal style="--d:600">
|
|
593
|
-
<div class="glyph" style="background:linear-gradient(140deg,#5e5ce6,#bf5af2)">⇄</div>
|
|
594
|
-
<div><h5>LoRA hot-swap</h5><p>Mount adapters at runtime, select per request, stack them. The base model never reloads.</p></div>
|
|
595
|
-
</div>
|
|
596
|
-
<div class="feat" data-reveal style="--d:660">
|
|
597
|
-
<div class="glyph" style="background:linear-gradient(140deg,#64d2ff,#30d158)">¼</div>
|
|
598
|
-
<div><h5>Mixed-precision KV</h5><p>Per-layer KV quantization from the repo’s own config — KV bytes ÷4, decode-neutral, fused FlashAttention prefill.</p></div>
|
|
599
|
-
</div>
|
|
600
|
-
<div class="feat" data-reveal style="--d:720">
|
|
601
|
-
<div class="glyph" style="background:linear-gradient(140deg,#ff453a,#ff9f0a)">△</div>
|
|
602
|
-
<div><h5>Memory admission control</h5><p>The GPU OOM is uncatchable by design — so over-budget requests are rejected before generation, ever.</p></div>
|
|
603
|
-
</div>
|
|
604
|
-
</div>
|
|
605
|
-
<p class="fine" data-reveal style="--d:820">Plus: resumable checksum-verified downloads, a sqlite model registry, deterministic memory-fit predictions, and a relocatable 61 MB single-binary build for embedding in Mac apps.</p>
|
|
606
|
-
</div>
|
|
607
|
-
</section>
|
|
608
|
-
|
|
609
|
-
<!-- ─── 10 · ONE MORE THING ──────────────────────────────── -->
|
|
610
|
-
<section class="slide center" id="s-omt" style="--g1:rgba(191,90,242,.10);--g2:rgba(10,132,255,.10)">
|
|
611
|
-
<div class="inner">
|
|
612
|
-
<h1 data-reveal style="--d:200">One more thing.</h1>
|
|
613
|
-
</div>
|
|
614
|
-
</section>
|
|
615
|
-
|
|
616
|
-
<!-- ─── 11 · CLAUDE CODE LOCAL ───────────────────────────── -->
|
|
617
|
-
<section class="slide center" style="--g1:rgba(94,92,230,.16);--g2:rgba(255,55,95,.12)">
|
|
618
|
-
<div class="inner">
|
|
619
|
-
<div class="eyebrow" data-reveal style="--d:0">Agents, unplugged</div>
|
|
620
|
-
<h2 class="head" data-reveal style="--d:100">Claude Code. <span class="grad g-purple">Fully local.</span></h2>
|
|
621
|
-
<p class="lede" data-reveal style="--d:280;margin:0 auto">One environment variable points any Anthropic-SDK tool at your Mac. The model, the cache, the conversation — none of it leaves the machine.</p>
|
|
622
|
-
<div class="term" data-reveal style="--d:460">
|
|
623
|
-
<div class="bar3">
|
|
624
|
-
<span class="dot3" style="background:#ff5f57"></span>
|
|
625
|
-
<span class="dot3" style="background:#febc2e"></span>
|
|
626
|
-
<span class="dot3" style="background:#28c840"></span>
|
|
627
|
-
<span class="title3">zsh — 80×24</span>
|
|
628
|
-
</div>
|
|
629
|
-
<pre><span class="p">$</span> <span class="cmd">bun src/cli.ts serve 12B</span>
|
|
630
|
-
<span class="ok">✓</span> gemma-4-12B-it-OptiQ-4bit <span class="c">· vision · tools · mixed-precision KV</span>
|
|
631
|
-
<span class="ok">✓</span> ready in <span class="hl">0.37 s</span> — http://localhost:8090
|
|
632
|
-
|
|
633
|
-
<span class="p">$</span> <span class="cmd">export ANTHROPIC_BASE_URL=http://localhost:8090</span>
|
|
634
|
-
<span class="p">$</span> <span class="cmd">claude</span> <span class="c"># every token now decoded on your own GPU</span></pre>
|
|
635
|
-
</div>
|
|
636
|
-
<p class="fine" data-reveal style="--d:640">Works the same for pi, OpenClaw, Codex-style clients via the Responses API, and anything that speaks OpenAI.</p>
|
|
637
|
-
</div>
|
|
638
|
-
</section>
|
|
639
|
-
|
|
640
|
-
<!-- ─── 12 · WHAT WE LEARNED ─────────────────────────────── -->
|
|
641
|
-
<section class="slide" style="--g1:rgba(255,159,10,.11);--g2:rgba(255,214,10,.08)">
|
|
642
|
-
<div class="inner">
|
|
643
|
-
<div class="eyebrow" data-reveal style="--d:0">Findings</div>
|
|
644
|
-
<h2 class="head" data-reveal style="--d:100">What the port <span class="grad g-pink">taught us.</span></h2>
|
|
645
|
-
<div class="finds">
|
|
646
|
-
<div class="find" data-reveal style="--d:240">
|
|
647
|
-
<div class="n">01</div>
|
|
648
|
-
<h5>Bun.mmap traps past 4 GB</h5>
|
|
649
|
-
<p>Weight shards run 5.35 GB. We bind <b>libc mmap through bun:ffi</b> and pass MLX raw pointers — JS views only for small ranges.</p>
|
|
650
|
-
</div>
|
|
651
|
-
<div class="find" data-reveal style="--d:300">
|
|
652
|
-
<div class="n">02</div>
|
|
653
|
-
<h5>Metal reads garbage off unaligned pointers</h5>
|
|
654
|
-
<p>Silently. Weights load via MLX’s lazy loader instead; our own KV files are <b>page-aligned</b>, so cache reloads are true zero-copy GPU mmaps.</p>
|
|
655
|
-
</div>
|
|
656
|
-
<div class="find" data-reveal style="--d:360">
|
|
657
|
-
<div class="n">03</div>
|
|
658
|
-
<h5>The JIT deleted our reads</h5>
|
|
659
|
-
<p>After tier-up, JSC elides typed-array reads across FFI calls. Every out-param readback now uses <b>read.u64</b>. Filed upstream as bun#32054.</p>
|
|
660
|
-
</div>
|
|
661
|
-
<div class="find" data-reveal style="--d:420">
|
|
662
|
-
<div class="n">04</div>
|
|
663
|
-
<h5>bf16 rounds x·x·x ≠ x³</h5>
|
|
664
|
-
<p>One op-order slip compounds across 48 layers into wrong logits. The rule: <b>port the implementation, never the docstring.</b></p>
|
|
665
|
-
</div>
|
|
666
|
-
<div class="find" data-reveal style="--d:480">
|
|
667
|
-
<div class="n">05</div>
|
|
668
|
-
<h5>Wired memory is load-bearing</h5>
|
|
669
|
-
<p>The 26B decoded at 8.6 tok/s — Metal re-faulting weights every token — until one wired-limit call. Then <b>32.3</b>. Same code.</p>
|
|
670
|
-
</div>
|
|
671
|
-
<div class="find" data-reveal style="--d:540">
|
|
672
|
-
<div class="n">06</div>
|
|
673
|
-
<h5>GPU OOM is uncatchable</h5>
|
|
674
|
-
<p>MLX throws from Metal’s completion thread; no handler is on that stack. <b>Admission control before generation</b> is the only defense.</p>
|
|
675
|
-
</div>
|
|
676
|
-
<div class="find" data-reveal style="--d:600">
|
|
677
|
-
<div class="n">07</div>
|
|
678
|
-
<h5>Speculative decoding can lose</h5>
|
|
679
|
-
<p>0.51–0.91× on e4b — the drafter can’t outrun a 54 tok/s target. Measured against an identical reference trace, recorded, kept behind a flag.</p>
|
|
680
|
-
</div>
|
|
681
|
-
<div class="find" data-reveal style="--d:660">
|
|
682
|
-
<div class="n">08</div>
|
|
683
|
-
<h5>Our 4% decode “gap” was an accounting story</h5>
|
|
684
|
-
<p>An allocator stall mlx-lm bills to <em>prompt</em> time, we billed to decode. Fixed reference-faithfully — the 12B now decodes <b>at-or-above</b> the reference, paired.</p>
|
|
685
|
-
</div>
|
|
686
|
-
</div>
|
|
687
|
-
<p class="fine" data-reveal style="--d:780">Every finding lives in PLAN.md with its root cause, fix, and the test that pins it. The losing experiments stay too — as documented, default-off flags. Measurement over memory.</p>
|
|
688
|
-
</div>
|
|
689
|
-
</section>
|
|
690
|
-
|
|
691
|
-
<!-- ─── 13 · ROADMAP ─────────────────────────────────────── -->
|
|
692
|
-
<section class="slide" style="--g1:rgba(94,92,230,.15);--g2:rgba(191,90,242,.13)">
|
|
693
|
-
<div class="inner">
|
|
694
|
-
<div class="eyebrow" data-reveal style="--d:0">The road ahead</div>
|
|
695
|
-
<h2 class="head" data-reveal style="--d:100">What’s <span class="grad g-purple">next.</span></h2>
|
|
696
|
-
<div class="road">
|
|
697
|
-
<div class="ritem" data-reveal style="--d:260">
|
|
698
|
-
<div class="rt">Qwen 3.x</div>
|
|
699
|
-
<div class="rd">The second model family — and the home of <b>MTP multi-token prediction</b>: its quants ship a trained drafting head, so speculative decoding finally gets a drafter fast enough to win.</div>
|
|
700
|
-
</div>
|
|
701
|
-
<div class="ritem" data-reveal style="--d:360">
|
|
702
|
-
<div class="rt">SigLIP vision</div>
|
|
703
|
-
<div class="rd">Eyes for e4b and the 26B — extending the verified, token-exact vision path beyond the 12B’s sidecar.</div>
|
|
704
|
-
</div>
|
|
705
|
-
<div class="ritem" data-reveal style="--d:460">
|
|
706
|
-
<div class="rt">Compiled decode graphs</div>
|
|
707
|
-
<div class="rd"><b>mlx_compile</b> moves per-step graph construction into C++ — erasing the last ~5% of host overhead on small, fast models.</div>
|
|
708
|
-
</div>
|
|
709
|
-
<div class="ritem" data-reveal style="--d:560">
|
|
710
|
-
<div class="rt">npm</div>
|
|
711
|
-
<div class="rd">The library-first API, published. Today it’s clone-and-import; tomorrow it’s <b>bun add mlx-bun</b>.</div>
|
|
712
|
-
</div>
|
|
713
|
-
<div class="ritem" data-reveal style="--d:660">
|
|
714
|
-
<div class="rt">More silicon</div>
|
|
715
|
-
<div class="rd">The benchmark matrix extends across machines, and <b>fit --skus</b> already predicts memory and throughput for the entire Apple Silicon lineup — before you download a byte.</div>
|
|
716
|
-
</div>
|
|
717
|
-
</div>
|
|
718
|
-
</div>
|
|
719
|
-
</section>
|
|
720
|
-
|
|
721
|
-
<!-- ─── 14 · VISION ──────────────────────────────────────── -->
|
|
722
|
-
<section class="slide center" style="--g1:rgba(10,132,255,.16);--g2:rgba(255,55,95,.13)">
|
|
723
|
-
<div class="inner">
|
|
724
|
-
<div class="eyebrow" data-reveal style="--d:0">Why it matters</div>
|
|
725
|
-
<h2 class="head" data-reveal style="--d:120">Every Mac app<br>can be an <span class="grad g-hero">AI app.</span></h2>
|
|
726
|
-
<div class="pillars">
|
|
727
|
-
<div class="pillar" data-reveal style="--d:340">
|
|
728
|
-
<div class="rule" style="background:linear-gradient(90deg,var(--green),var(--cyan))"></div>
|
|
729
|
-
<h4>Private by design</h4>
|
|
730
|
-
<p>Prompts, photos, documents, conversations — decoded on your own GPU. Nothing leaves the machine. No quota, no per-token bill, no network required.</p>
|
|
731
|
-
</div>
|
|
732
|
-
<div class="pillar" data-reveal style="--d:460">
|
|
733
|
-
<div class="rule" style="background:linear-gradient(90deg,var(--blue),var(--purple))"></div>
|
|
734
|
-
<h4>Embedded anywhere</h4>
|
|
735
|
-
<p>A relocatable 61 MB binary, signed and notarized, drops into any Tauri, Electron, or Swift app as a sidecar — first-run weights via the built-in downloader.</p>
|
|
736
|
-
</div>
|
|
737
|
-
<div class="pillar" data-reveal style="--d:580">
|
|
738
|
-
<div class="rule" style="background:linear-gradient(90deg,var(--orange),var(--pink))"></div>
|
|
739
|
-
<h4>Standard protocols</h4>
|
|
740
|
-
<p>OpenAI, Anthropic, and Responses APIs out of the box. The tools you already use — Claude Code, pi, Codex-style clients — point at localhost and keep working.</p>
|
|
741
|
-
</div>
|
|
742
|
-
</div>
|
|
743
|
-
</div>
|
|
744
|
-
</section>
|
|
745
|
-
|
|
746
|
-
<!-- ─── 15 · OUTRO ───────────────────────────────────────── -->
|
|
747
|
-
<section class="slide center" id="s-outro" style="--g1:rgba(191,90,242,.20);--g2:rgba(10,132,255,.22)">
|
|
748
|
-
<div class="inner">
|
|
749
|
-
<h1 class="mega grad g-hero" data-reveal style="--d:100">mlx-bun</h1>
|
|
750
|
-
<p class="tag-line" data-reveal style="--d:340">No Python. No sidecar. <b>One runtime.</b></p>
|
|
751
|
-
<p class="lede" data-reveal style="--d:520;margin:30px auto 0">Available now. MIT licensed.</p>
|
|
752
|
-
<p class="fine" data-reveal style="--d:700">All numbers measured on an Apple M4 Pro, 24 GB, 2026-06-11 — cleared machine, same day, same weights, per-row provenance in the repo.<br>Built in TypeScript. Verified against the reference, bit for bit.</p>
|
|
753
|
-
</div>
|
|
754
|
-
</section>
|
|
755
|
-
|
|
756
|
-
</main>
|
|
757
|
-
|
|
758
|
-
<nav id="hud" aria-label="slides"></nav>
|
|
759
|
-
<div id="hint">← → to navigate</div>
|
|
760
|
-
<div id="count" class="num"></div>
|
|
761
|
-
<button class="edge l" id="prevEdge" aria-label="previous slide">‹</button>
|
|
762
|
-
<button class="edge r" id="nextEdge" aria-label="next slide">›</button>
|
|
763
|
-
|
|
764
|
-
<script>
|
|
765
|
-
(() => {
|
|
766
|
-
const slides = Array.from(document.querySelectorAll('.slide'));
|
|
767
|
-
const hud = document.getElementById('hud');
|
|
768
|
-
const count = document.getElementById('count');
|
|
769
|
-
const hint = document.getElementById('hint');
|
|
770
|
-
let cur = -1, navved = false;
|
|
771
|
-
|
|
772
|
-
// dots
|
|
773
|
-
slides.forEach((_, i) => {
|
|
774
|
-
const d = document.createElement('button');
|
|
775
|
-
d.className = 'dot';
|
|
776
|
-
d.setAttribute('aria-label', 'slide ' + (i + 1));
|
|
777
|
-
d.addEventListener('click', () => go(i));
|
|
778
|
-
hud.appendChild(d);
|
|
779
|
-
});
|
|
780
|
-
const dots = Array.from(hud.children);
|
|
781
|
-
|
|
782
|
-
// count-up animation for [data-count]
|
|
783
|
-
function runCounters(slide) {
|
|
784
|
-
slide.querySelectorAll('[data-count]').forEach(el => {
|
|
785
|
-
const target = parseFloat(el.dataset.count);
|
|
786
|
-
const decimals = parseInt(el.dataset.decimals || '0', 10);
|
|
787
|
-
const prefix = el.dataset.prefix || '';
|
|
788
|
-
if (el._raf) cancelAnimationFrame(el._raf);
|
|
789
|
-
const t0 = performance.now(), dur = 1300;
|
|
790
|
-
const tick = now => {
|
|
791
|
-
const p = Math.min(1, (now - t0) / dur);
|
|
792
|
-
const eased = 1 - Math.pow(1 - p, 3);
|
|
793
|
-
el.textContent = prefix + (target * eased).toFixed(decimals);
|
|
794
|
-
if (p < 1) el._raf = requestAnimationFrame(tick);
|
|
795
|
-
};
|
|
796
|
-
el._raf = requestAnimationFrame(tick);
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
function go(i) {
|
|
801
|
-
i = Math.max(0, Math.min(slides.length - 1, i));
|
|
802
|
-
if (i === cur) return;
|
|
803
|
-
if (cur >= 0) slides[cur].classList.remove('active');
|
|
804
|
-
cur = i;
|
|
805
|
-
slides[cur].classList.add('active');
|
|
806
|
-
dots.forEach((d, j) => d.classList.toggle('on', j === cur));
|
|
807
|
-
count.textContent = (cur + 1) + ' / ' + slides.length;
|
|
808
|
-
history.replaceState(null, '', '#' + (cur + 1));
|
|
809
|
-
runCounters(slides[cur]);
|
|
810
|
-
if (!navved && cur > 0) { navved = true; hint.style.opacity = '0'; }
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
const next = () => go(cur + 1);
|
|
814
|
-
const prev = () => go(cur - 1);
|
|
815
|
-
|
|
816
|
-
addEventListener('keydown', e => {
|
|
817
|
-
if (['ArrowRight', 'ArrowDown', 'PageDown', ' '].includes(e.key)) { e.preventDefault(); next(); }
|
|
818
|
-
else if (['ArrowLeft', 'ArrowUp', 'PageUp'].includes(e.key)) { e.preventDefault(); prev(); }
|
|
819
|
-
else if (e.key === 'Home') go(0);
|
|
820
|
-
else if (e.key === 'End') go(slides.length - 1);
|
|
821
|
-
});
|
|
822
|
-
|
|
823
|
-
// wheel / trackpad, debounced
|
|
824
|
-
let wheelLock = 0;
|
|
825
|
-
addEventListener('wheel', e => {
|
|
826
|
-
const now = Date.now();
|
|
827
|
-
if (now - wheelLock < 750 || Math.abs(e.deltaY) < 24) return;
|
|
828
|
-
wheelLock = now;
|
|
829
|
-
e.deltaY > 0 ? next() : prev();
|
|
830
|
-
}, { passive: true });
|
|
831
|
-
|
|
832
|
-
// touch swipe
|
|
833
|
-
let tx = 0, ty = 0;
|
|
834
|
-
addEventListener('touchstart', e => { tx = e.touches[0].clientX; ty = e.touches[0].clientY; }, { passive: true });
|
|
835
|
-
addEventListener('touchend', e => {
|
|
836
|
-
const dx = e.changedTouches[0].clientX - tx, dy = e.changedTouches[0].clientY - ty;
|
|
837
|
-
if (Math.abs(dx) > 56 && Math.abs(dx) > Math.abs(dy)) (dx < 0 ? next() : prev());
|
|
838
|
-
}, { passive: true });
|
|
839
|
-
|
|
840
|
-
document.getElementById('nextEdge').addEventListener('click', next);
|
|
841
|
-
document.getElementById('prevEdge').addEventListener('click', prev);
|
|
842
|
-
|
|
843
|
-
const fromHash = parseInt(location.hash.slice(1), 10);
|
|
844
|
-
go(Number.isFinite(fromHash) ? fromHash - 1 : 0);
|
|
845
|
-
})();
|
|
846
|
-
</script>
|
|
847
|
-
</body>
|
|
848
|
-
</html>
|