mlx-bun 0.3.0 → 0.5.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 +57 -32
- package/docs/README.md +58 -42
- package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +3617 -0
- package/docs/archive/investigations/openjarvis-fit.md +198 -0
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
- package/docs/archive/planning/release-notes-v0.4.0.md +45 -0
- package/docs/archive/planning/release-notes-v0.5.0.md +37 -0
- package/docs/design/batching.md +1535 -50
- package/docs/design/decode-speed-program.md +394 -1171
- package/docs/design/generic-model-support.md +195 -3
- package/docs/design/kv-cache.md +538 -225
- package/docs/design/speculative-decoding.md +552 -50
- package/docs/design/turboquant.md +140 -17
- package/docs/design/unified-engine-frontier-plan.md +259 -150
- package/docs/planning/PRODUCT_ROADMAP.md +21 -6
- package/docs/planning/public-readiness-handoff.md +244 -0
- package/docs/planning/public-readiness.md +149 -0
- package/docs/reference/benchmarks.md +3537 -1112
- package/docs/reference/cli.md +102 -2
- package/docs/reference/distribution.md +45 -13
- package/docs/reference/environment.md +159 -13
- package/docs/reference/library-api.md +18 -4
- package/docs/reference/memory.md +1 -1
- package/docs/reference/models.md +28 -7
- package/docs/reference/server-api.md +257 -33
- package/docs/reference/server-config.md +372 -151
- package/docs/reference/troubleshooting.md +13 -21
- package/package.json +2 -2
- package/src/audio/audiotoolbox.ts +112 -0
- package/src/audio/conformer.ts +8 -0
- package/src/audio/mic-capture.ts +98 -0
- package/src/audio/silero-vad.ts +379 -0
- package/src/audio/whisper-decode.ts +774 -0
- package/src/audio/whisper-fast.ts +732 -0
- package/src/audio/whisper-format.ts +73 -0
- package/src/audio/whisper-mel.ts +185 -0
- package/src/audio/whisper-timing.ts +274 -0
- package/src/audio/whisper-tokenizer.ts +239 -0
- package/src/audio/whisper-transcribe.ts +410 -0
- package/src/backends/mlx/assistant-target.ts +46 -0
- package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
- package/src/backends/mlx/autoregressive.ts +22 -1
- package/src/backends/mlx/batch-group.ts +464 -236
- package/src/backends/mlx/cache-attachment.ts +67 -0
- package/src/backends/mlx/cache-layout.ts +31 -0
- package/src/backends/mlx/checkpoint-state.ts +53 -0
- package/src/backends/mlx/continuation-persistence.ts +107 -0
- package/src/backends/mlx/continuation-request.ts +43 -0
- package/src/backends/mlx/continuation.ts +77 -0
- package/src/backends/mlx/draft-target.ts +7 -22
- package/src/backends/mlx/encoder-cache.ts +25 -0
- package/src/backends/mlx/fill-append.ts +21 -8
- package/src/backends/mlx/fill-group.ts +497 -0
- package/src/backends/mlx/full-kv-row-append.ts +32 -0
- package/src/backends/mlx/full-kv-row-donor.ts +54 -0
- package/src/backends/mlx/full-transitioning-kv-rows.ts +65 -0
- package/src/backends/mlx/gateway-binding.ts +122 -19
- package/src/backends/mlx/kv-codec.ts +9 -0
- package/src/backends/mlx/kv-maintenance.ts +161 -0
- package/src/backends/mlx/kv-tensor-rows.ts +212 -0
- package/src/backends/mlx/mixed-iteration.ts +62 -0
- package/src/backends/mlx/model-prompt.ts +46 -32
- package/src/backends/mlx/model-serving.ts +5 -4
- package/src/backends/mlx/paged-cache-codec.ts +27 -0
- package/src/backends/mlx/prefill-cohort.ts +100 -0
- package/src/backends/mlx/prefill-policy.ts +26 -0
- package/src/backends/mlx/prefill-rows.ts +244 -0
- package/src/backends/mlx/prefill.ts +1 -1
- package/src/backends/mlx/projected-context-rows.ts +72 -0
- package/src/backends/mlx/prompt-input.ts +29 -0
- package/src/backends/mlx/qwen-prompt-input.ts +40 -0
- package/src/backends/mlx/request-state-policy.ts +54 -0
- package/src/backends/mlx/rollback.ts +45 -4
- package/src/backends/mlx/row-sampling.ts +49 -0
- package/src/backends/mlx/serial-executor.ts +51 -73
- package/src/backends/mlx/speculative-group.ts +438 -0
- package/src/backends/mlx/speculative-round.ts +161 -0
- package/src/backends/mlx/speculative.ts +24 -7
- package/src/backends/mlx/state-rows.ts +104 -0
- package/src/backends/mlx/state-views.ts +21 -1
- package/src/backends/mlx/target-layout-capability.ts +35 -0
- package/src/backends/mlx/transitioning-kv-rows.ts +173 -0
- package/src/cli.ts +333 -36
- package/src/contracts/execution.ts +21 -0
- package/src/contracts/object-cache.ts +8 -0
- package/src/contracts/pi-provider.ts +1 -1
- package/src/contracts/pi.ts +3 -1
- package/src/contracts/prefix-cache.ts +33 -0
- package/src/contracts/resources.ts +7 -0
- package/src/contracts/sampling.ts +23 -0
- package/src/contracts/scheduling.ts +27 -0
- package/src/engine/execution-plan.ts +38 -25
- package/src/engine/execution-tasks.ts +44 -0
- package/src/engine/namespaced-cache.ts +13 -0
- package/src/engine/resources.ts +12 -1
- package/src/engine/scheduler.ts +32 -7
- package/src/fill/fill-session.ts +14 -3
- package/src/fit.ts +29 -15
- package/src/generate.ts +105 -195
- package/src/grammar.ts +13 -0
- package/src/inference/draft-acceptance.ts +41 -0
- package/src/inference/draft-output.ts +49 -0
- package/src/inference/prefill.ts +6 -0
- package/src/inference/rollback.ts +2 -2
- package/src/kv-scheme.ts +92 -12
- package/src/kv-store.ts +183 -93
- package/src/lab/README.md +5 -1
- package/src/lab/paged-kv/paged-attention.ts +117 -0
- package/src/lab/paged-kv/paged-kv-rows.ts +111 -0
- package/src/lab/paged-kv/paged-kv.ts +126 -46
- package/src/md-modules.d.ts +5 -0
- package/src/mlx/array.ts +39 -1
- package/src/mlx/ffi.ts +19 -0
- package/src/mlx/normalized-argmax.ts +116 -0
- package/src/mlx/ops.ts +97 -10
- package/src/model/artifact-identity.ts +73 -0
- package/src/model/batched-kv.ts +235 -0
- package/src/model/batched-mask.ts +12 -4
- package/src/model/batched-quant.ts +8 -2
- package/src/model/batched-quantized-kv.ts +144 -0
- package/src/model/batched-rotating-quant.ts +76 -15
- package/src/model/batched-rotating-state.ts +76 -0
- package/src/model/batched-rotating.ts +64 -22
- package/src/model/batched-row-storage.ts +52 -0
- package/src/model/batched-ssm.ts +52 -0
- package/src/model/batched-turboquant-kv.ts +94 -0
- package/src/model/compiled-decode.ts +7 -1
- package/src/model/decoded-kv-donor.ts +12 -0
- package/src/model/delayed-quantized-kv.ts +72 -0
- package/src/model/delayed-rotating-quantized-kv.ts +93 -0
- package/src/model/delayed-turboquant-kv.ts +57 -0
- package/src/model/factory.ts +26 -0
- package/src/model/fingerprint.ts +12 -0
- package/src/model/full-prefill-padding.ts +56 -0
- package/src/model/full-prefill-row.ts +105 -0
- package/src/model/gemma4-base.ts +183 -82
- package/src/model/gemma4.ts +116 -28
- package/src/model/generated/gemma4-12b.ts +4 -1
- package/src/model/generated/gemma4-26b.ts +4 -1
- package/src/model/generated/gemma4-e4b.ts +4 -1
- package/src/model/glm52-cache.ts +80 -4
- package/src/model/glm52-mla.ts +12 -6
- package/src/model/glm52.ts +19 -40
- package/src/model/kv-attention-view.ts +70 -0
- package/src/model/minicpm5.ts +11 -7
- package/src/model/profile.ts +29 -4
- package/src/model/quantized-append-attention.ts +31 -0
- package/src/model/qwen3-delta-state.ts +74 -0
- package/src/model/qwen3-delta.ts +59 -36
- package/src/model/qwen3-mrope.ts +7 -9
- package/src/model/qwen3_5.ts +177 -75
- package/src/model/rotating-kv-donor.ts +35 -0
- package/src/model/rotating-kv-layout.ts +262 -0
- package/src/model/rotating-row-transaction.ts +35 -0
- package/src/model/speculative-rotating-kv.ts +101 -0
- package/src/model/ssm-prefill-padding.ts +39 -0
- package/src/model/support.ts +8 -0
- package/src/model/token-groups.ts +66 -0
- package/src/model/trellis-linear.ts +4 -4
- package/src/model/turboquant-codec.ts +89 -0
- package/src/model/universal/dense.ts +14 -13
- package/src/model/whisper.ts +435 -0
- package/src/native/mic_capture.swift +92 -0
- package/src/native-pack.ts +6 -5
- package/src/pi-web.ts +9 -1
- package/src/preflight.ts +31 -15
- package/src/prompt-cache.ts +306 -86
- package/src/runtime-config.ts +1 -5
- package/src/safetensors.ts +9 -2
- package/src/sampler.ts +37 -25
- package/src/serve/audio-routes.ts +323 -0
- package/src/serve/chat-request.ts +2 -0
- package/src/serve/chat-stage.ts +19 -14
- package/src/serve/completion-executor.ts +9 -1
- package/src/serve/discovery-routes.ts +17 -1
- package/src/serve/generated-token-history.ts +57 -0
- package/src/serve/generation-gateway.ts +88 -38
- package/src/serve/model-binding.ts +7 -1
- package/src/serve/model-host.ts +3 -4
- package/src/serve/preparation.ts +3 -3
- package/src/serve/prompt-response-trace.ts +14 -0
- package/src/serve/request-plan.ts +6 -3
- package/src/serve/request-prep.ts +40 -25
- package/src/serve/text-completion-stage.ts +2 -2
- package/src/serve/transcription-server.ts +64 -0
- package/src/serve/transcription-service.ts +502 -0
- package/src/server.ts +185 -261
- package/src/spec/assistant-rows.ts +93 -0
- package/src/spec/assistant-source.ts +28 -18
- package/src/spec/cache-identity.ts +22 -0
- package/src/spec/deepspec-rows.ts +29 -0
- package/src/spec/deepspec-source.ts +12 -10
- package/src/spec/dflash-source.ts +28 -4
- package/src/spec/drafter.ts +153 -142
- package/src/spec/dspark/deepspec-module.ts +95 -120
- package/src/spec/dspark/module-dflash.ts +126 -170
- package/src/spec/glm52-mtp-graph.ts +29 -0
- package/src/spec/glm52-mtp-rows.ts +132 -0
- package/src/spec/glm52-mtp-source.ts +54 -136
- package/src/spec/glm52-mtp-state.ts +33 -0
- package/src/spec/ngram-source.ts +115 -21
- package/src/spec/projected-draft-rows.ts +73 -0
- package/src/spec/qwen-mtp-module.ts +171 -0
- package/src/spec/qwen-mtp-rows.ts +230 -0
- package/src/spec/qwen-mtp-source.ts +84 -226
- package/src/spec/qwen-mtp-state.ts +30 -0
- package/src/spec/serve-loop.ts +73 -69
- package/src/spec/source.ts +93 -15
- package/src/spec/two-model-rows.ts +62 -0
- package/src/spec/two-model.ts +45 -103
- package/src/ssd-cache.ts +107 -36
- package/src/ssd-durability.ts +29 -27
- package/src/storage/host-buffer.ts +24 -0
- package/src/storage/kv-writer.ts +83 -0
- package/src/storage/kv-writer.worker.js +264 -0
- package/src/storage/retention-policy.ts +37 -0
- package/src/tiered-prompt-cache.ts +45 -0
- package/src/vision/embedder.ts +8 -0
- package/src/vision/prompt.ts +101 -65
- package/src/vision/qwen3vl-prompt.ts +101 -64
- package/src/vision/qwen3vl-tower.ts +11 -0
- package/src/vision/siglip.ts +8 -0
- package/src/web/app.html +12 -0
- package/src/web/app.js +217 -57
- package/src/web/src/chat.ts +4 -1
- package/src/web/src/composer.ts +3 -0
- package/src/web/src/voice.ts +141 -0
- package/src/web/sw.js +1 -1
- package/src/backends/mlx/memory-guard.ts +0 -40
- package/src/spec/prefix-state.ts +0 -45
- /package/docs/{planning → archive/planning}/release-notes-v0.3.0.md +0 -0
package/src/inference/prefill.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/** Request-level chunk policy. Execution consumes the selected size; model
|
|
2
|
+
* backends can account for their temporary workspace without changing admission. */
|
|
3
|
+
export interface PrefillPolicy {
|
|
4
|
+
chunkSize(promptTokens: number): number;
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
export interface PrefillPosition {
|
|
2
8
|
readonly length: number;
|
|
3
9
|
readonly position: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** A complete transaction over every participating target state layer.
|
|
2
2
|
* A failed begin/resolve invalidates the run; its state must be discarded. */
|
|
3
|
-
export interface SpeculativeTransaction {
|
|
3
|
+
export interface SpeculativeTransaction<Acceptance = number> {
|
|
4
4
|
canBegin(drafts: number): boolean;
|
|
5
5
|
begin(drafts: number): void;
|
|
6
|
-
resolve(accepted:
|
|
6
|
+
resolve(accepted: Acceptance): void;
|
|
7
7
|
}
|
package/src/kv-scheme.ts
CHANGED
|
@@ -86,6 +86,42 @@ export function kvBytesAt(
|
|
|
86
86
|
value.linearStateBytes;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/** Head dims MLX 0.32.2's fused multi-query SDPA kernel serves for L > 8
|
|
90
|
+
* queries on M1–M4 GPUs (mlx/backend/metal/scaled_dot_product_attention.cpp
|
|
91
|
+
* `use_fallback`: 192 and 256 always fall back off-NAX; `has_fused_kernel`
|
|
92
|
+
* lists 64/72/80/96/128 for the full kernel). Every other head dim runs
|
|
93
|
+
* mlx/fast.cpp's composed fallback, which materializes the bf16 scores
|
|
94
|
+
* tensor [heads, L, S] plus a bool mask per full-attention layer. The
|
|
95
|
+
* decode kernel (L ≤ 8) fuses 256, so this term is a prefill-only cost. */
|
|
96
|
+
export const FUSED_SDPA_HEAD_DIMS: ReadonlySet<number> = new Set([64, 72, 80, 96, 128]);
|
|
97
|
+
const SDPA_SCORES_BYTES = 2; // bf16 scores in q's dtype
|
|
98
|
+
const SDPA_FUSED_MAX_QUERIES = 8;
|
|
99
|
+
|
|
100
|
+
/** Peak bytes of the SDPA-fallback scores tensor live during one prefill
|
|
101
|
+
* chunk of `chunk` queries against a `ctx`-token context: the last chunk
|
|
102
|
+
* sees the longest keys, and the lazy graph keeps one layer's scores live
|
|
103
|
+
* at a time. Zero when every attention layer's head dim fuses. Sliding
|
|
104
|
+
* layers see at most `window + L` keys. Admission-only (fit and the
|
|
105
|
+
* in-flight memory guard); nothing here changes what is computed. */
|
|
106
|
+
export function sdpaFallbackBytes(config: ModelConfig, chunk: number, ctx: number): number {
|
|
107
|
+
const text = config.text;
|
|
108
|
+
const heads = text.numAttentionHeads || 0;
|
|
109
|
+
const queries = Math.min(chunk, ctx);
|
|
110
|
+
if (heads <= 0 || queries <= SDPA_FUSED_MAX_QUERIES) return 0;
|
|
111
|
+
let peak = 0;
|
|
112
|
+
const layers = text.numHiddenLayers || text.layerTypes.length;
|
|
113
|
+
for (let layer = 0; layer < layers; layer++) {
|
|
114
|
+
const type = text.layerTypes[layer] ?? "full_attention";
|
|
115
|
+
if (type === "linear_attention") continue;
|
|
116
|
+
const sliding = type === "sliding_attention" && text.slidingWindow > 0;
|
|
117
|
+
const headDim = sliding ? text.headDim : text.globalHeadDim;
|
|
118
|
+
if (FUSED_SDPA_HEAD_DIMS.has(headDim)) continue;
|
|
119
|
+
const keys = sliding ? Math.min(ctx, text.slidingWindow + queries) : ctx;
|
|
120
|
+
peak = Math.max(peak, heads * queries * keys * SDPA_SCORES_BYTES);
|
|
121
|
+
}
|
|
122
|
+
return peak;
|
|
123
|
+
}
|
|
124
|
+
|
|
89
125
|
export class KvScheme {
|
|
90
126
|
readonly kind: KvSchemeKind;
|
|
91
127
|
readonly options: Readonly<ResolvedKvSchemeOptions>;
|
|
@@ -112,10 +148,17 @@ export class KvScheme {
|
|
|
112
148
|
get cacheKey(): string {
|
|
113
149
|
if (this.kind === "turbo") {
|
|
114
150
|
const turbo = this.options.turboQuant!;
|
|
115
|
-
|
|
151
|
+
const start = this.options.quantizedKvStart ?? 0;
|
|
152
|
+
return `turbo-k${turbo.kBits}v${turbo.vBits}${start > 0 ? `-start${start}` : ""}`;
|
|
153
|
+
}
|
|
154
|
+
if (this.kind === "affine-uniform") {
|
|
155
|
+
const start = this.options.quantizedKvStart ?? 5000, group = this.options.kvGroupSize ?? 64;
|
|
156
|
+
return `kv${this.options.kvBits}${group !== 64 ? `-g${group}` : ""}${start > 0 ? `-start${start}` : ""}`;
|
|
157
|
+
}
|
|
158
|
+
if (this.kind === "affine-config") {
|
|
159
|
+
const start = this.options.quantizedKvStart ?? 0;
|
|
160
|
+
return `config${start > 0 ? `-start${start}` : ""}`;
|
|
116
161
|
}
|
|
117
|
-
if (this.kind === "affine-uniform") return `kv${this.options.kvBits}`;
|
|
118
|
-
if (this.kind === "affine-config") return "config";
|
|
119
162
|
return "bf16";
|
|
120
163
|
}
|
|
121
164
|
|
|
@@ -129,6 +172,28 @@ export class KvScheme {
|
|
|
129
172
|
return "bf16";
|
|
130
173
|
}
|
|
131
174
|
|
|
175
|
+
/** Configured attention storage, not live allocator occupancy. Recurrent
|
|
176
|
+
* layers retain their own state and never acquire an attention KV codec. */
|
|
177
|
+
describe(config: ModelConfig) {
|
|
178
|
+
const layers: Record<string, number> = {};
|
|
179
|
+
const attention = { global: 0, sliding_window: 0 };
|
|
180
|
+
let recurrent_layers = 0;
|
|
181
|
+
const perLayer = new Map(this.options.kvConfig?.map(entry => [entry.layerIdx, entry.bits]));
|
|
182
|
+
for (let layer = 0; layer < config.text.numHiddenLayers; layer++) {
|
|
183
|
+
const type = config.text.layerTypes[layer] ?? "full_attention";
|
|
184
|
+
if (type === "linear_attention") { recurrent_layers++; continue; }
|
|
185
|
+
const sliding = type === "sliding_attention";
|
|
186
|
+
attention[sliding ? "sliding_window" : "global"]++;
|
|
187
|
+
const bits = this.kind === "affine-config" ? perLayer.get(layer)
|
|
188
|
+
: this.kind === "affine-uniform" ? this.options.kvBits : undefined;
|
|
189
|
+
const codec = this.kind === "turbo" && !sliding
|
|
190
|
+
? `turbo-k${this.options.turboQuant!.kBits}v${this.options.turboQuant!.vBits}`
|
|
191
|
+
: bits ? `kv${bits}` : "bf16";
|
|
192
|
+
layers[codec] = (layers[codec] ?? 0) + 1;
|
|
193
|
+
}
|
|
194
|
+
return { mode: this.label, layers, attention, recurrent_layers };
|
|
195
|
+
}
|
|
196
|
+
|
|
132
197
|
bytesAt(config: ModelConfig, tokens: number): number {
|
|
133
198
|
// TurboQuant stays conservatively billed as bf16 until its packed layout
|
|
134
199
|
// exposes a stable projector.
|
|
@@ -154,14 +219,24 @@ export class KvScheme {
|
|
|
154
219
|
return this.kind === "turbo" ? {} : this.generationOptions;
|
|
155
220
|
}
|
|
156
221
|
|
|
157
|
-
/**
|
|
158
|
-
*
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
batchable(config: ModelConfig, canConvert?: (layerIdx: number) => boolean): boolean {
|
|
222
|
+
/** Affine layouts convert during solo prefill. TQ also has a transitional
|
|
223
|
+
* row layout that preserves each request's delayed conversion boundary. */
|
|
224
|
+
batchable(config: ModelConfig, canConvert?: (layerIdx: number) => boolean,
|
|
225
|
+
cacheLayerCount = config.text.numHiddenLayers, capabilities: { delayedAffine?: boolean } = {}): boolean {
|
|
162
226
|
if (this.kind === "bf16") return true;
|
|
163
|
-
if (this.kind !== "affine-config") return false;
|
|
227
|
+
if (this.kind !== "affine-config" && this.kind !== "affine-uniform" && this.kind !== "turbo") return false;
|
|
164
228
|
if (!canConvert) return false;
|
|
229
|
+
const start = this.options.quantizedKvStart ?? (this.kind === "affine-uniform" ? 5000 : 0);
|
|
230
|
+
if (start > 0 && this.kind !== "turbo" && !capabilities.delayedAffine) return false;
|
|
231
|
+
if (this.kind === "affine-uniform" || this.kind === "turbo") {
|
|
232
|
+
// Some models share the donor prefix's KV in later layers. Probe the
|
|
233
|
+
// actual cache list, just as uniform conversion does.
|
|
234
|
+
for (let layer = 0; layer < cacheLayerCount; layer++) {
|
|
235
|
+
if (config.text.layerTypes[layer] === "linear_attention") continue;
|
|
236
|
+
if (!canConvert(layer)) return false;
|
|
237
|
+
}
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
165
240
|
return this.options.kvConfig!.every((entry) => {
|
|
166
241
|
if (entry.layerIdx < 0 || entry.layerIdx >= config.text.numHiddenLayers) return false;
|
|
167
242
|
return (config.text.layerTypes[entry.layerIdx] ?? "full_attention") !== "linear_attention" &&
|
|
@@ -175,11 +250,15 @@ export function resolveKvScheme(input: {
|
|
|
175
250
|
turboQuant?: TurboQuantScheme;
|
|
176
251
|
config?: readonly KvQuantSpec[] | null;
|
|
177
252
|
missingConfig?: "bf16" | "error";
|
|
253
|
+
quantizedKvStart?: number;
|
|
178
254
|
}): KvScheme {
|
|
255
|
+
const start = input.quantizedKvStart;
|
|
256
|
+
if (start !== undefined && (!Number.isSafeInteger(start) || start < 0))
|
|
257
|
+
throw new Error("quantizedKvStart must be a nonnegative integer");
|
|
179
258
|
if (input.turboQuant) {
|
|
180
259
|
return new KvScheme("turbo", {
|
|
181
260
|
turboQuant: input.turboQuant,
|
|
182
|
-
quantizedKvStart: 0,
|
|
261
|
+
quantizedKvStart: start ?? 0,
|
|
183
262
|
});
|
|
184
263
|
}
|
|
185
264
|
if (input.override === "off" || input.override === undefined)
|
|
@@ -190,10 +269,11 @@ export function resolveKvScheme(input: {
|
|
|
190
269
|
throw new Error("model has no kv_config.json (--kv-quant config)");
|
|
191
270
|
return new KvScheme("bf16", {});
|
|
192
271
|
}
|
|
193
|
-
return new KvScheme("affine-config", { kvConfig: [...input.config]
|
|
272
|
+
return new KvScheme("affine-config", { kvConfig: [...input.config],
|
|
273
|
+
...(start === undefined ? {} : { quantizedKvStart: start }) });
|
|
194
274
|
}
|
|
195
275
|
return new KvScheme("affine-uniform", {
|
|
196
276
|
kvBits: input.override,
|
|
197
|
-
quantizedKvStart: 0,
|
|
277
|
+
quantizedKvStart: start ?? 0,
|
|
198
278
|
});
|
|
199
279
|
}
|