mlx-bun 0.0.8 → 0.0.10
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 +112 -20
- package/docs/design/batching-perf-path.md +232 -0
- package/docs/design/batching-v2-plan.md +515 -0
- package/docs/design/bucketing-stage.md +196 -0
- package/docs/design/compat-cli-surface-design.md +11 -11
- package/docs/design/docs-reorg-plan.md +1 -1
- package/docs/design/dreaming-nightly-pipeline.md +291 -0
- package/docs/design/dspark-speculative-decoding.md +106 -0
- package/docs/design/generic-model-support.md +381 -0
- package/docs/design/memory-inference-path.md +422 -0
- package/docs/design/memory-synthesis.md +287 -0
- package/docs/design/minicpm5-decode-megakernel.md +484 -0
- package/docs/design/mlx-lm-tool-parity-plan.md +535 -0
- package/docs/design/omlx-adoption-map.md +90 -0
- package/docs/design/orpo-dynamic-lambda.md +41 -0
- package/docs/design/orpo-training.md +35 -5
- package/docs/design/parallel-slots.md +12 -1
- package/docs/design/parity-tier-dag.md +13 -5
- package/docs/design/segmented-backward-training.md +15 -0
- package/docs/design/spec-decode-larger-targets.md +229 -0
- package/docs/design/ssd-kv-cold-tier.md +158 -0
- package/docs/design/tauri-desktop-app.md +2 -2
- package/docs/design/the-dreaming-handoff.md +141 -0
- package/docs/design/the-dreaming-master-plan.md +446 -0
- package/docs/design/write-pipeline-entity.md +468 -0
- package/docs/investigations/curve-bisector-routing.md +1 -1
- package/docs/investigations/decode-roofline-lookagain.md +348 -0
- package/docs/investigations/dspark-handoff.md +58 -0
- package/docs/investigations/kernel-perf-review-2026-07.md +171 -0
- package/docs/planning/PRODUCT_ROADMAP.md +2 -2
- package/docs/planning/curve-sampler-research-plan.md +331 -0
- package/docs/planning/memory-docs-and-dag-plan.md +185 -0
- package/docs/planning/pi-integration-review.md +178 -0
- package/docs/planning/release-notes-v0.0.10.md +57 -0
- package/docs/planning/release-notes-v0.0.9.md +122 -0
- package/docs/planning/web-ui-pass-plan.md +213 -0
- package/docs/planning/website-readme-pass-plan.md +224 -0
- package/docs/reference/cli.md +255 -0
- package/docs/reference/embedding.md +7 -2
- package/docs/reference/library-api.md +22 -3
- package/docs/reference/memory.md +5 -5
- package/docs/reference/models.md +137 -0
- package/docs/reference/orpo-quickstart.md +6 -0
- package/docs/reference/server-api.md +187 -9
- package/docs/reference/server-config.md +43 -9
- package/docs/reference/training.md +31 -12
- package/package.json +1 -1
- package/src/anthropic.ts +22 -0
- package/src/assets/curve-designer.html +1 -1
- package/src/chat-template.ts +25 -7
- package/src/cli.ts +1077 -90
- package/src/config.ts +4 -1
- package/src/download.ts +99 -8
- package/src/embed.ts +77 -0
- package/src/eval/perplexity.ts +164 -0
- package/src/eval/runner.ts +15 -6
- package/src/eval/tasks/bfcl.ts +1 -1
- package/src/generate.ts +149 -18
- package/src/harness-pi.ts +43 -17
- package/src/index.ts +2 -0
- package/src/kv-store.ts +240 -98
- package/src/lora.ts +2 -2
- package/src/memory/article.ts +558 -0
- package/src/memory/chunk-validation.ts +150 -0
- package/src/memory/chunk.ts +305 -12
- package/src/memory/cluster.ts +344 -17
- package/src/memory/coverage.ts +134 -0
- package/src/memory/crosslink.ts +0 -0
- package/src/memory/db.ts +184 -45
- package/src/memory/entity.ts +203 -0
- package/src/memory/gate.ts +187 -0
- package/src/memory/history.ts +152 -0
- package/src/memory/ingest.ts +324 -11
- package/src/memory/model.ts +321 -0
- package/src/memory/normalize.ts +671 -0
- package/src/memory/parse.ts +22 -0
- package/src/memory/pipeline.ts +242 -30
- package/src/memory/prompts.ts +42 -0
- package/src/memory/query.ts +334 -0
- package/src/memory/reconcile.ts +734 -0
- package/src/memory/redirect.ts +108 -0
- package/src/memory/reindex.ts +325 -0
- package/src/memory/resolve.ts +307 -0
- package/src/memory/route.ts +272 -0
- package/src/memory/schedule.ts +6 -4
- package/src/memory/stages.ts +774 -0
- package/src/memory/synthesize.ts +1629 -20
- package/src/memory/tools.ts +446 -96
- package/src/memory/vault.ts +462 -35
- package/src/memory/wikify.ts +1057 -16
- package/src/mlx/array.ts +21 -0
- package/src/mlx/ffi.ts +3 -0
- package/src/mlx/ops.ts +72 -0
- package/src/model/compiled-decode.ts +43 -8
- package/src/model/factory.ts +29 -8
- package/src/model/flash-attention.ts +4 -2
- package/src/model/fused-decode-kernel.ts +14 -7
- package/src/model/fused-mlp-kernel.ts +169 -0
- package/src/model/fused-swiglu-kernel.ts +240 -0
- package/src/model/gemma4-base.ts +96 -7
- package/src/model/gemma4.ts +33 -2
- package/src/model/minicpm5.ts +106 -8
- package/src/model/qwen3-delta.ts +48 -1
- package/src/model/qwen3.ts +276 -0
- package/src/model/qwen3_5.ts +11 -2
- package/src/model/steel-linear-kernel.ts +96 -0
- package/src/model/support.ts +38 -8
- package/src/model/universal/archs.ts +332 -0
- package/src/model/universal/dense.ts +576 -0
- package/src/model/universal/modules.ts +163 -0
- package/src/model/universal/rope.ts +366 -0
- package/src/pi-provider.ts +1 -1
- package/src/pi-terminal.ts +29 -8
- package/src/pi-web.ts +19 -2
- package/src/prompt-cache.ts +55 -9
- package/src/quantize/config-writer.ts +1 -1
- package/src/registry.ts +219 -8
- package/src/responses.ts +23 -0
- package/src/sampler.ts +220 -9
- package/src/serve/batch-scheduler.ts +307 -83
- package/src/serve/generation-gateway.ts +156 -29
- package/src/server.ts +746 -73
- package/src/spec/drafter.ts +81 -49
- package/src/spec/dspark/data-dflash.ts +156 -0
- package/src/spec/dspark/data.ts +201 -0
- package/src/spec/dspark/generate-dflash.ts +193 -0
- package/src/spec/dspark/generate.ts +290 -0
- package/src/spec/dspark/loss.ts +213 -0
- package/src/spec/dspark/module-dflash.ts +361 -0
- package/src/spec/dspark/module.ts +540 -0
- package/src/spec/dspark/sample.ts +112 -0
- package/src/spec/generate.ts +40 -19
- package/src/ssd-cache.ts +213 -0
- package/src/status-page.html +1 -1
- package/src/tokenizer.ts +7 -0
- package/src/train/flash-cce.ts +81 -23
- package/src/train/fuse.ts +243 -0
- package/src/train/index.ts +3 -0
- package/src/train/job.ts +8 -0
- package/src/train/loss.ts +341 -40
- package/src/train/prefix-shared.ts +62 -11
- package/src/train/segmented.ts +215 -55
- package/src/train/trainer.ts +112 -38
- package/src/web/skills/memory/SKILL.md +40 -17
|
@@ -22,7 +22,7 @@ Training is reachable several ways — all of them drive the **same** runner
|
|
|
22
22
|
|
|
23
23
|
| Path | How | Use when |
|
|
24
24
|
|---|---|---|
|
|
25
|
-
| **CLI** | `mlx-bun train <model> --data <dir> [options]` — foreground, full ORPO stack on by default; auto-detects e4b/Gemma + sets its env; `--save-every`, `--resume`, `--dry-run`; streams loss to the terminal. `mlx-bun help train` for all flags. Run long jobs detached: `nohup mlx-bun train … &` | **The default for CLI users** |
|
|
25
|
+
| **CLI** | `mlx-bun train <model> --data <dir> [options]` — foreground, full ORPO stack on by default; auto-detects e4b/Gemma + sets its env; `--save-every`, `--resume`, `--dry-run`, `--sft-scope full\|response`, `--grad-accum`, `--grad-clip`, `--seed`, `--val-size`; streams loss to the terminal. `mlx-bun help train` for all flags. Run long jobs detached: `nohup mlx-bun train … &` | **The default for CLI users** |
|
|
26
26
|
| **Web UI** | `mlx-bun serve`, open `/finetune` — pick model → dataset → hyperparameters → train; watch live train/val loss; merge/export the adapter | Interactive, in the browser |
|
|
27
27
|
| **HTTP API** | `POST /api/finetune/submit` (job id + SSE events); `POST /api/finetune/inspect-dataset` to probe a file; `POST /api/finetune/merge` to fold an adapter into base weights | Scripted / remote |
|
|
28
28
|
| **ORPO launcher** | [`scripts/train-orpo.ts`](../../scripts/train-orpo.ts) — the same stack driven by env vars (`MODEL=`, `DATA=`, `RANK=`, `RESUME=`, …). See [orpo-quickstart](./orpo-quickstart.md) | Env-var scripting |
|
|
@@ -36,7 +36,7 @@ isolation + a single GPU lease across concurrent server requests).
|
|
|
36
36
|
### Quick start (HTTP API)
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
curl -s localhost:
|
|
39
|
+
curl -s localhost:8080/api/finetune/submit -X POST -H 'content-type: application/json' -d '{
|
|
40
40
|
"model_dir": "/path/to/snapshot",
|
|
41
41
|
"data_dir": "/path/to/dataset", // dir with train.jsonl (+ optional valid.jsonl)
|
|
42
42
|
"adapter_path": "/path/to/output-adapter",
|
|
@@ -81,7 +81,7 @@ differ from the trainer/API defaults in the table below:
|
|
|
81
81
|
|
|
82
82
|
The script hard-codes `method=sft`, `batch_size=1`, `steps_per_report=1`, and
|
|
83
83
|
uses the default `ops.sdpa` training attention (set `MLX_BUN_TRAIN_ATTN=flash`
|
|
84
|
-
to override —
|
|
84
|
+
to override — experimental, much slower; see Methodology).
|
|
85
85
|
|
|
86
86
|
## Data formats
|
|
87
87
|
|
|
@@ -112,12 +112,19 @@ Probe a file before submitting: `POST /api/finetune/inspect-dataset` with
|
|
|
112
112
|
and a preference term, `L = L_NLL(chosen) + λ·L_OR`, with
|
|
113
113
|
`L_OR = -log σ(log_odds)` and
|
|
114
114
|
`log_odds = (ℓ_w − ℓ_r) − (log1mexp(ℓ_w) − log1mexp(ℓ_r))`, where `ℓ` is the
|
|
115
|
-
**length-normalized** (mean over response tokens) log-prob.
|
|
115
|
+
**length-normalized** (mean over response tokens) log-prob. The SFT term's
|
|
116
|
+
scope is `sft_scope`: **`full`** (default; paper/TRL-faithful) computes
|
|
117
|
+
`L_NLL` as the token-mean cross-entropy over the **full prompt+response** of
|
|
118
|
+
the chosen sequence (only padding excluded — TRL's `chosen_nll_loss`),
|
|
119
|
+
from the same chosen forward (no extra forward); **`response`** uses
|
|
120
|
+
`L_NLL = −ℓ_w` (response-only — the pre-2026-07 mlx-bun behavior, kept for
|
|
121
|
+
reproducing old runs). The odds-ratio `ℓ_w/ℓ_r` stay response-only in **both**
|
|
122
|
+
modes (that also matches TRL). Uses the same
|
|
116
123
|
`{prompt, chosen, rejected}` preference data as DPO but needs **no reference
|
|
117
124
|
model** (2 forwards/step vs DPO's 4). Default LR `1e-5` (lower than DPO — the
|
|
118
125
|
loss carries a full SFT NLL term a high LR destabilizes). Tune with
|
|
119
|
-
`orpo_lambda`, `orpo_warmup_iters`, `orpo_lr_schedule`. Design +
|
|
120
|
-
roadmap: [orpo-training](../design/orpo-training.md).
|
|
126
|
+
`orpo_lambda`, `orpo_warmup_iters`, `orpo_lr_schedule`, `sft_scope`. Design +
|
|
127
|
+
optimization roadmap: [orpo-training](../design/orpo-training.md).
|
|
121
128
|
|
|
122
129
|
The ORPO head + long-context machinery compose into one stack (all B=1), each
|
|
123
130
|
piece independently toggled and each falling back cleanly:
|
|
@@ -125,6 +132,11 @@ piece independently toggled and each falling back cleanly:
|
|
|
125
132
|
- **`orpo_flash_ce`** — the [M,vocab]-free flash-CCE Metal head (steel GEMM fwd
|
|
126
133
|
**and** bwd; e4b backward 754 ms, peak 0.93 GB flat at M=8192). Implies the
|
|
127
134
|
fused head. Falls back to the MLX fused head when the tiling isn't clean.
|
|
135
|
+
**Auto-dispatch by M** (2026-07-02): batches with M below `MLX_BUN_FLASH_MIN_M`
|
|
136
|
+
(default 1024) take the exact MLX fused head instead — it is faster at short
|
|
137
|
+
M (e4b M=64 1.6×, M=512 1.13×; CPM5 at every M), while flash wins memory
|
|
138
|
+
everywhere and time at long M on e4b (M≥2048; 8K: 10.7 vs 13.2 s with the
|
|
139
|
+
filter/blockMax defaults). `MLX_BUN_FLASH_MIN_M=0` always honors flash.
|
|
128
140
|
- **`segment_size`** — segmented backward (gradient-checkpointed layer
|
|
129
141
|
activations) for long context; the head is ~free in memory, the activations
|
|
130
142
|
are the wall.
|
|
@@ -177,8 +189,9 @@ are `DEFAULT_TRAIN_CONFIG` (trainer.ts:89).
|
|
|
177
189
|
| `orpo_lr_schedule` | `constant` \| `cosine` | `cosine` | ORPO LR schedule (orpo only) |
|
|
178
190
|
| `orpo_chunk_size` | int | `0` (off) | Token-chunk the response head, bounding the `[M,vocab]` logits to `[chunk,vocab]` (defaults to 512 when a fused head is on). Exact (orpo only) |
|
|
179
191
|
| `orpo_fused_ce` | bool | `false` | Fused linear-CE head: one CustomVjp with an analytic softmax−onehot backward (MLX `quantizedMatmul` both ways) — no autograd through the head, no retained `[M,vocab]`. Exact; `[chunk,vocab]` transient (orpo only) |
|
|
180
|
-
| `orpo_flash_ce` | bool | `false` | Route the fused head through the **flash-CCE Metal kernel** (verbatim MLX steel GEMM + ORPO epilogue, fwd **and** bwd): neither `[M,vocab]` nor a dequantized head touches HBM → `[M,vocab]`-free
|
|
192
|
+
| `orpo_flash_ce` | bool | `false` | Route the fused head through the **flash-CCE Metal kernel** (verbatim MLX steel GEMM + ORPO epilogue, fwd **and** bwd): neither `[M,vocab]` nor a dequantized head touches HBM → `[M,vocab]`-free (e4b 0.93 GB flat @ M=8192). Implies the fused head. The Apple-CCE coeff filter + blockMax skip default ON at 1e-5 (2026-07-02; combined bwd 1.71× CPM5 / 3.16× e4b vs exact — `MLX_BUN_CCE_BWD_FILTER_EPS=0` / `_BLOCK_EPS=0` restore exact). Batches with M < `MLX_BUN_FLASH_MIN_M` (default 1024) auto-take the exact fused head (faster at short M; `=0` always honors flash). B=1 (orpo only) |
|
|
181
193
|
| `orpo_prefix_shared` | bool | `false` | Shared prompt-prefix: one forward over `[prompt; chosen; rejected]` with a block-sparse mask + block-wise RoPE, so the shared prompt is encoded **once** (a big win when the prompt dominates). Falls back to two-forward per row on prompt mismatch. Composes with the flash head and the segmented backward (MiniCPM5 + e4b). B=1 (orpo only) |
|
|
194
|
+
| `sft_scope` | `full` \| `response` | `full` | Scope of ORPO's chosen-NLL term. `full` (paper/TRL-faithful): token-mean CE over the **full prompt+response** (only padding excluded), from the same chosen forward. `response`: `L_NLL = −ℓ_w` — reproduces pre-2026-07 runs bit-exactly. The odds-ratio `ℓ_w/ℓ_r` are response-only in both modes. Applies to every ORPO path (naive/chunked/fused/flash/prefix/segmented) (orpo only). CLI spelling: `mlx-bun train … --sft-scope full\|response` |
|
|
182
195
|
|
|
183
196
|
### Environment variables (training)
|
|
184
197
|
|
|
@@ -186,7 +199,7 @@ are `DEFAULT_TRAIN_CONFIG` (trainer.ts:89).
|
|
|
186
199
|
|---|---|---|---|
|
|
187
200
|
| `MLX_BUN_FUSED_GELU` | **`0` (required for Gemma)** | on | The fused GeGLU is a **CustomKernel with no gradient (vjp)** ([`fused-geglu-kernel.ts`](../../src/model/fused-geglu-kernel.ts)); the Gemma forward uses it ([`gemma4.ts:277`](../../src/model/gemma4.ts)), so a Gemma (e4b/12B/26B) backward fails unless it's off. MiniCPM5 (Llama-arch SwiGLU) never hits it, so the `.ts` script's MiniCPM5 default doesn't need it. |
|
|
188
201
|
| `MLX_BUN_PERF_KERNEL` | **`0` for training** | on | The fused quantized-decode kernel likewise has no vjp. It only fires at decode L=1 (rare in the L>1 training forward), but the e4b recipe sets `0` to be safe. |
|
|
189
|
-
| `MLX_BUN_TRAIN_ATTN` | **leave unset** | unset → `ops.sdpa` | Default `ops.sdpa` **is** mlx's fused flash-attention kernel — the correct, working path. `flash` selects a *different* hand-rolled
|
|
202
|
+
| `MLX_BUN_TRAIN_ATTN` | **leave unset** | unset → `ops.sdpa` | Default `ops.sdpa` **is** mlx's fused flash-attention kernel — the correct, working path. `flash` selects a *different* hand-rolled O(L)-memory kernel: its two port bugs (dK buffer-transpose, dQ divergent causal barrier) are fixed and FD-validated (`tests/flash-attention.test.ts`, T≤256), but it is ~30× slower and the historical e4b ≥2K crash has **not been re-validated at that scale** since the fix — leave unset unless memory-bound and re-verified. |
|
|
190
203
|
| `MLX_BUN_MEM_LOG` | `1` to profile | off | Print per-step peak/active/cache memory |
|
|
191
204
|
|
|
192
205
|
> Important: the trainer itself ([`trainer.ts`](../../src/train/trainer.ts))
|
|
@@ -221,7 +234,7 @@ What the recipe pins (and why it differs from the bare defaults):
|
|
|
221
234
|
| `RANK` / `SCALE` / `LR` | `16` / `20` / `1e-5` | task-tuned |
|
|
222
235
|
| `ITERS` | `2` (probe) / `900` (train) | ~2 epochs over 450 examples |
|
|
223
236
|
| `MLX_BUN_PERF_KERNEL` / `MLX_BUN_FUSED_GELU` | `0` / `0` | **required** — the fused kernels have no vjp (see env table) |
|
|
224
|
-
| attention | default `ops.sdpa` | mlx's fused flash kernel; **not** `MLX_BUN_TRAIN_ATTN=flash` (
|
|
237
|
+
| attention | default `ops.sdpa` | mlx's fused flash kernel; **not** `MLX_BUN_TRAIN_ATTN=flash` (~30× slower; e4b ≥2K unvalidated since the kernel fix) |
|
|
225
238
|
|
|
226
239
|
The two non-negotiables for e4b: **segmented backward** (`SEG>0`, so the
|
|
227
240
|
long-context activations fit) and the **fused kernels off** (so the backward
|
|
@@ -265,9 +278,15 @@ At long `max_seq_length`, activation memory dominates. Two levers:
|
|
|
265
278
|
### Training attention kernel (`MLX_BUN_TRAIN_ATTN`)
|
|
266
279
|
- **default `ops.sdpa`** — mlx's fused SDPA; correct (0.00% vs autograd),
|
|
267
280
|
O(L²) backward memory. Use this.
|
|
268
|
-
- **`flash`** — opt-in O(L)
|
|
269
|
-
|
|
270
|
-
|
|
281
|
+
- **`flash`** — opt-in O(L)-memory path. Its two port bugs (dK
|
|
282
|
+
buffer-transpose, dQ divergent causal barrier) were **fixed** and
|
|
283
|
+
FD-validated (`scripts/experiments/flash-fd-check.ts`; regression test
|
|
284
|
+
`tests/flash-attention.test.ts`, T≤256), but it remains ~30× slower than
|
|
285
|
+
`ops.sdpa`, and the historical e4b multi-K (≥2K) SIGTRAP has **not been
|
|
286
|
+
re-validated at that scale since the fix**
|
|
287
|
+
(`scripts/experiments/segmented-grad-test-e4b.ts` is the repro harness).
|
|
288
|
+
Prefer the default; treat `flash` as experimental on e4b long context.
|
|
289
|
+
Detail in segmented-backward-training §6.
|
|
271
290
|
|
|
272
291
|
## Outputs
|
|
273
292
|
|
package/package.json
CHANGED
package/src/anthropic.ts
CHANGED
|
@@ -50,6 +50,18 @@ export interface AnthropicRequest {
|
|
|
50
50
|
top_k?: number;
|
|
51
51
|
stop_sequences?: string[];
|
|
52
52
|
stream?: boolean;
|
|
53
|
+
/** mlx-lm sampler/penalty extensions — not part of the Anthropic protocol,
|
|
54
|
+
* accepted as pass-through extras with the same names as our /v1 chat
|
|
55
|
+
* surface. Anthropic has NO logit_bias, so none is accepted here. */
|
|
56
|
+
min_p?: number;
|
|
57
|
+
xtc_probability?: number;
|
|
58
|
+
xtc_threshold?: number;
|
|
59
|
+
repetition_penalty?: number;
|
|
60
|
+
repetition_context_size?: number;
|
|
61
|
+
presence_penalty?: number;
|
|
62
|
+
presence_context_size?: number;
|
|
63
|
+
frequency_penalty?: number;
|
|
64
|
+
frequency_context_size?: number;
|
|
53
65
|
tools?: Array<{
|
|
54
66
|
name?: string;
|
|
55
67
|
description?: string;
|
|
@@ -167,6 +179,16 @@ export function anthropicToChatBody(body: AnthropicRequest): Record<string, unkn
|
|
|
167
179
|
if (body.top_k != null) oai.top_k = body.top_k;
|
|
168
180
|
if (body.stop_sequences?.length) oai.stop = body.stop_sequences;
|
|
169
181
|
if (body.stream) oai.stream = true;
|
|
182
|
+
// mlx-lm sampler/penalty extensions: straight pass-through (same wire names
|
|
183
|
+
// on the chat surface). No logit_bias — it doesn't exist in this protocol.
|
|
184
|
+
for (const k of [
|
|
185
|
+
"min_p", "xtc_probability", "xtc_threshold",
|
|
186
|
+
"repetition_penalty", "repetition_context_size",
|
|
187
|
+
"presence_penalty", "presence_context_size",
|
|
188
|
+
"frequency_penalty", "frequency_context_size",
|
|
189
|
+
] as const) {
|
|
190
|
+
if (body[k] != null) oai[k] = body[k];
|
|
191
|
+
}
|
|
170
192
|
|
|
171
193
|
// Client tools only (entries with name + input_schema); server-tool
|
|
172
194
|
// types (web_search etc.) have no local meaning and are dropped.
|
|
@@ -89,7 +89,7 @@ button.ghost{background:var(--card);border:1px solid var(--bd);border-radius:8px
|
|
|
89
89
|
<script>
|
|
90
90
|
const ln=Math.log;
|
|
91
91
|
const UMIN=ln(1e-6); // bottom-left / plot floor (matches src/curve-sampler.ts CURVE_UMIN)
|
|
92
|
-
const ENGINE_BASE = location.protocol.startsWith("http") ? location.origin : "http://localhost:
|
|
92
|
+
const ENGINE_BASE = location.protocol.startsWith("http") ? location.origin : "http://localhost:8080";
|
|
93
93
|
// ---- curve state: 5 movable control points, sorted ascending in p_in ----
|
|
94
94
|
function identityPoints(){ return [{x_pct:1e-4,y_pct:1e-4},{x_pct:0.1,y_pct:0.1},{x_pct:1,y_pct:1},{x_pct:9,y_pct:9},{x_pct:100,y_pct:100}]; }
|
|
95
95
|
let C = { space:"logprob", points:identityPoints(), monotonic:true };
|
package/src/chat-template.ts
CHANGED
|
@@ -131,20 +131,38 @@ export class ChatTemplate {
|
|
|
131
131
|
/** True when the model has a switchable reasoning channel we can parse. */
|
|
132
132
|
readonly supportsThinking: boolean;
|
|
133
133
|
|
|
134
|
-
private constructor(
|
|
134
|
+
private constructor(
|
|
135
|
+
source: string,
|
|
136
|
+
bosToken: string | null,
|
|
137
|
+
eosToken: string | null,
|
|
138
|
+
forceNoThinking = false,
|
|
139
|
+
) {
|
|
135
140
|
this.#template = new Template(source);
|
|
136
141
|
this.#bosToken = bosToken;
|
|
137
142
|
this.#eosToken = eosToken;
|
|
138
143
|
const gatesThinking = source.includes("enable_thinking");
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
// `forceNoThinking` suppresses the switchable channel even when the template
|
|
145
|
+
// carries the gemma markers. DiffusionGemma ships the shared gemma-family
|
|
146
|
+
// template (with the `<|channel>thought…<channel|>` reasoning channel), but
|
|
147
|
+
// its non-autoregressive canvas decode cannot reliably emit the `<channel|>`
|
|
148
|
+
// close, so an enabled channel never ends (everything is captured as
|
|
149
|
+
// reasoning, no answer). The OptiQ reference never enables thinking for this
|
|
150
|
+
// model — it always renders the template's `default(false)` pre-closed empty
|
|
151
|
+
// channel and decodes the whole canvas as plain text. We match that.
|
|
152
|
+
this.thinkingFormat = forceNoThinking
|
|
153
|
+
? null
|
|
154
|
+
: gatesThinking && source.includes("<think>")
|
|
155
|
+
? "think-tag"
|
|
156
|
+
: gatesThinking && source.includes("<|channel>")
|
|
157
|
+
? "gemma-channel"
|
|
158
|
+
: null;
|
|
144
159
|
this.supportsThinking = this.thinkingFormat !== null;
|
|
145
160
|
}
|
|
146
161
|
|
|
147
|
-
static async load(
|
|
162
|
+
static async load(
|
|
163
|
+
modelDir: string,
|
|
164
|
+
opts: { disableThinking?: boolean } = {},
|
|
165
|
+
): Promise<ChatTemplate> {
|
|
148
166
|
const config = (await Bun.file(`${modelDir}/tokenizer_config.json`).json()) as Record<string, any>;
|
|
149
167
|
let source: string | undefined = config.chat_template;
|
|
150
168
|
if (!source) {
|