@tryhamster/gerbil 1.1.3 → 1.2.1
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/dist/{architectures-wan0swXu.mjs → architectures-Ol7yUmKf.mjs} +128 -68
- package/dist/architectures-Ol7yUmKf.mjs.map +1 -0
- package/dist/cli.mjs +8 -8
- package/dist/cli.mjs.map +1 -1
- package/dist/{defaults-9komdrbY.mjs → defaults-bJcmOaRG.mjs} +2 -2
- package/dist/defaults-bJcmOaRG.mjs.map +1 -0
- package/dist/frameworks/express.mjs +1 -1
- package/dist/frameworks/fastify.mjs +1 -1
- package/dist/frameworks/hono.mjs +1 -1
- package/dist/frameworks/next.d.mts +2 -2
- package/dist/frameworks/next.mjs +1 -1
- package/dist/frameworks/trpc.mjs +1 -1
- package/dist/gerbil-0M50i8TK.mjs +4 -0
- package/dist/{gerbil-CQspp8fS.mjs → gerbil-DW1VioGN.mjs} +2 -2
- package/dist/{gerbil-CQspp8fS.mjs.map → gerbil-DW1VioGN.mjs.map} +1 -1
- package/dist/{gerbil-DZbWbIm2.d.mts → gerbil-DkilSf1Q.d.mts} +2 -2
- package/dist/{gerbil-DZbWbIm2.d.mts.map → gerbil-DkilSf1Q.d.mts.map} +1 -1
- package/dist/gpu/hooks.d.mts +24 -7
- package/dist/gpu/hooks.d.mts.map +1 -1
- package/dist/gpu/hooks.mjs +14 -7
- package/dist/gpu/hooks.mjs.map +1 -1
- package/dist/gpu/index.d.mts +2 -2
- package/dist/gpu/index.mjs +5 -5
- package/dist/{gpu-BYCQ5aTI.mjs → gpu-DR6EG0K-.mjs} +93 -24
- package/dist/gpu-DR6EG0K-.mjs.map +1 -0
- package/dist/index-Dgmb2kE3.d.mts.map +1 -1
- package/dist/{index-CKszv3lt.d.mts → index-HVS7yeLx.d.mts} +232 -133
- package/dist/index-HVS7yeLx.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +6 -6
- package/dist/integrations/ai-sdk.mjs +1 -1
- package/dist/integrations/langchain.mjs +1 -1
- package/dist/integrations/llamaindex.mjs +1 -1
- package/dist/integrations/mcp.d.mts +2 -2
- package/dist/integrations/mcp.mjs +4 -4
- package/dist/{mcp-CszII8GJ.mjs → mcp-8Tn3U-EE.mjs} +3 -3
- package/dist/{mcp-CszII8GJ.mjs.map → mcp-8Tn3U-EE.mjs.map} +1 -1
- package/dist/moonshine-stt-B3YtKcEE.mjs +4 -0
- package/dist/{moonshine-stt-DDUm5WfP.mjs → moonshine-stt-DSz3VW_0.mjs} +56 -6
- package/dist/{moonshine-stt-DDUm5WfP.mjs.map → moonshine-stt-DSz3VW_0.mjs.map} +1 -1
- package/dist/{one-liner-DVche8Eg.mjs → one-liner-BK9wqRYw.mjs} +2 -2
- package/dist/{one-liner-DVche8Eg.mjs.map → one-liner-BK9wqRYw.mjs.map} +1 -1
- package/dist/repl-B62rx3DS.mjs +9 -0
- package/dist/skills/index.d.mts +2 -2
- package/dist/skills/index.mjs +3 -3
- package/dist/{skills-BQI-VSn2.mjs → skills-BF3FVv8_.mjs} +2 -2
- package/dist/{skills-BQI-VSn2.mjs.map → skills-BF3FVv8_.mjs.map} +1 -1
- package/package.json +1 -1
- package/dist/architectures-wan0swXu.mjs.map +0 -1
- package/dist/defaults-9komdrbY.mjs.map +0 -1
- package/dist/gerbil-tHnYb9nZ.mjs +0 -4
- package/dist/gpu-BYCQ5aTI.mjs.map +0 -1
- package/dist/index-CKszv3lt.d.mts.map +0 -1
- package/dist/moonshine-stt-BtR-KiSP.mjs +0 -4
- package/dist/repl-BYJA2U7t.mjs +0 -9
|
@@ -148,6 +148,66 @@ function createDefaultHFKeyMapper() {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/gpu/quantize.ts
|
|
153
|
+
/**
|
|
154
|
+
* On-the-fly INT4 quantization for WebGPU inference.
|
|
155
|
+
*
|
|
156
|
+
* Converts F32 weight matrices to 4-bit unsigned integers with per-group
|
|
157
|
+
* scale/zero-point parameters. Matches the dequantization formula in the
|
|
158
|
+
* MatMulInt4 WGSL kernel:
|
|
159
|
+
*
|
|
160
|
+
* dequant_val = (raw_nibble - zero) * scale
|
|
161
|
+
*
|
|
162
|
+
* Packing: 8 × 4-bit values per u32, little-nibble-first order.
|
|
163
|
+
* Grouping: contiguous elements in row-major (K × N) layout.
|
|
164
|
+
*/
|
|
165
|
+
const DEFAULT_GROUP_SIZE = 128;
|
|
166
|
+
/**
|
|
167
|
+
* Quantize a flat F32 weight array to INT4.
|
|
168
|
+
*
|
|
169
|
+
* @param data - Source F32 weight data (row-major, K × N elements)
|
|
170
|
+
* @param groupSize - Number of elements per quantization group (default 128)
|
|
171
|
+
* @returns Packed INT4 data with per-group scales and zeros
|
|
172
|
+
*/
|
|
173
|
+
function quantizeInt4(data, groupSize = DEFAULT_GROUP_SIZE) {
|
|
174
|
+
const totalElements = data.length;
|
|
175
|
+
const numGroups = Math.ceil(totalElements / groupSize);
|
|
176
|
+
const packedSize = Math.ceil(totalElements / 8);
|
|
177
|
+
const packed = new Uint32Array(packedSize);
|
|
178
|
+
const scales = new Float32Array(numGroups);
|
|
179
|
+
const zeros = new Float32Array(numGroups);
|
|
180
|
+
for (let g = 0; g < numGroups; g++) {
|
|
181
|
+
const start = g * groupSize;
|
|
182
|
+
const end = Math.min(start + groupSize, totalElements);
|
|
183
|
+
let min = data[start];
|
|
184
|
+
let max = data[start];
|
|
185
|
+
for (let i = start + 1; i < end; i++) {
|
|
186
|
+
const v = data[i];
|
|
187
|
+
if (v < min) min = v;
|
|
188
|
+
if (v > max) max = v;
|
|
189
|
+
}
|
|
190
|
+
const range = max - min;
|
|
191
|
+
const scale = range > 0 ? range / 15 : 1;
|
|
192
|
+
const zero = range > 0 ? -min / scale : 0;
|
|
193
|
+
scales[g] = scale;
|
|
194
|
+
zeros[g] = zero;
|
|
195
|
+
const invRange = range > 0 ? 15 / range : 0;
|
|
196
|
+
for (let i = start; i < end; i++) {
|
|
197
|
+
const q = Math.round((data[i] - min) * invRange);
|
|
198
|
+
const clamped = q < 0 ? 0 : q > 15 ? 15 : q;
|
|
199
|
+
const packedIdx = i >>> 3;
|
|
200
|
+
const nibblePos = i & 7;
|
|
201
|
+
packed[packedIdx] |= clamped << nibblePos * 4;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
packed,
|
|
206
|
+
scales,
|
|
207
|
+
zeros
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
151
211
|
//#endregion
|
|
152
212
|
//#region src/gpu/architectures/kani_tts.ts
|
|
153
213
|
const KANI_TOKENISER_LENGTH = 64400;
|
|
@@ -195,19 +255,23 @@ const NANOCODEC_BASE_CHANNELS = 864;
|
|
|
195
255
|
const NANOCODEC_INPUT_DIM = 16;
|
|
196
256
|
function parseKaniConfig(rawConfig) {
|
|
197
257
|
const textVocabSize = rawConfig.text_vocab_size ?? KANI_TOKENISER_LENGTH;
|
|
258
|
+
const useLearnableRope = rawConfig.use_learnable_rope ?? false;
|
|
259
|
+
const archList = rawConfig.architectures ?? [];
|
|
260
|
+
const isKaniTTS2 = useLearnableRope || rawConfig.tokens_per_frame != null || rawConfig.audio_step != null || archList.includes("KaniTTS2ForCausalLM");
|
|
198
261
|
return {
|
|
199
262
|
textVocabSize,
|
|
200
263
|
vocabSize: rawConfig.vocab_size,
|
|
201
264
|
tokensPerFrame: rawConfig.tokens_per_frame ?? KANI_TOKENS_PER_FRAME,
|
|
202
265
|
audioStep: rawConfig.audio_step ?? 1,
|
|
203
|
-
useLearnableRope
|
|
266
|
+
useLearnableRope,
|
|
204
267
|
alphaMin: rawConfig.alpha_min ?? .1,
|
|
205
268
|
alphaMax: rawConfig.alpha_max ?? 2,
|
|
206
269
|
speakerEmbDim: rawConfig.speaker_emb_dim ?? 128,
|
|
207
270
|
audioTokensStart: textVocabSize + 10,
|
|
208
271
|
startOfSpeech: textVocabSize + 1,
|
|
209
272
|
endOfSpeech: textVocabSize + 2,
|
|
210
|
-
codebookSize: KANI_CODEBOOK_SIZE
|
|
273
|
+
codebookSize: KANI_CODEBOOK_SIZE,
|
|
274
|
+
frameLevelPositions: isKaniTTS2
|
|
211
275
|
};
|
|
212
276
|
}
|
|
213
277
|
/**
|
|
@@ -249,6 +313,10 @@ function kaniAttentionLayerIndices(rawConfig) {
|
|
|
249
313
|
*/
|
|
250
314
|
function computeKaniPositions(tokenIds, cfg = parseKaniConfig({})) {
|
|
251
315
|
const pos = new Float32Array(tokenIds.length);
|
|
316
|
+
if (!cfg.frameLevelPositions) {
|
|
317
|
+
for (let t = 0; t < tokenIds.length; t++) pos[t] = t;
|
|
318
|
+
return pos;
|
|
319
|
+
}
|
|
252
320
|
let textCount = 0;
|
|
253
321
|
let audioTokenCount = 0;
|
|
254
322
|
for (let t = 0; t < tokenIds.length; t++) {
|
|
@@ -652,15 +720,25 @@ function computeKaniFfnDim(rawConfig) {
|
|
|
652
720
|
return ff;
|
|
653
721
|
}
|
|
654
722
|
/**
|
|
655
|
-
* Generate the
|
|
723
|
+
* Generate the KaniTTS codec-LM backbone graph (LFM2-350M body, full-vocab logits,
|
|
656
724
|
* per-layer learnable MRoPE). Mirrors generateLfm2Graph block-for-block; the only
|
|
657
725
|
* difference is that each attention layer rotates Q/K with the MRoPE op fed a
|
|
658
726
|
* per-layer host cos/sin table instead of the position-counter RoPE op.
|
|
659
727
|
*
|
|
660
|
-
*
|
|
728
|
+
* dtype:
|
|
729
|
+
* • undefined / "f32" — full precision (the checkpoint is bf16/f32 → f32).
|
|
730
|
+
* • "q4" — weight-only group-wise INT4 (W4A16) for the LFM2 linear projections
|
|
731
|
+
* (q/k/v/o, gate/up/down, short-conv in/out_proj) via MatMulInt4. The tied
|
|
732
|
+
* embedding + LM head stay at f32 on purpose: decoder-LM heads are the most
|
|
733
|
+
* quantization-sensitive part of a codec-LM and the embed table is the single
|
|
734
|
+
* buffer shared by both, so quantizing it would degrade audio quality for no
|
|
735
|
+
* load-size win that the int4 projections do not already capture. Backbone
|
|
736
|
+
* drops from ~1.5 GB (f32) to ~0.37 GB. The NanoCodec decoder is a separate
|
|
737
|
+
* graph and always runs f32.
|
|
661
738
|
*/
|
|
662
|
-
function generateKaniTtsGraph(rawConfig, dtype,
|
|
663
|
-
|
|
739
|
+
function generateKaniTtsGraph(rawConfig, dtype, groupSize, kvDtype) {
|
|
740
|
+
const useQ4 = dtype === "q4";
|
|
741
|
+
const groupSz = groupSize ?? DEFAULT_GROUP_SIZE;
|
|
664
742
|
const hidden_size = rawConfig.hidden_size;
|
|
665
743
|
const num_layers = rawConfig.num_hidden_layers;
|
|
666
744
|
const num_heads = rawConfig.num_attention_heads;
|
|
@@ -711,6 +789,48 @@ function generateKaniTtsGraph(rawConfig, dtype, _groupSize, kvDtype) {
|
|
|
711
789
|
executionOrder.push(node.id);
|
|
712
790
|
};
|
|
713
791
|
const addLinear = (id, activationInput, weightName, weightShape, outputName, K, N) => {
|
|
792
|
+
if (useQ4) {
|
|
793
|
+
const wQ = `${weightName}.q`;
|
|
794
|
+
const wScales = `${weightName}.scales`;
|
|
795
|
+
const wZeros = `${weightName}.zeros`;
|
|
796
|
+
const totalElements = K * N;
|
|
797
|
+
addTensor({
|
|
798
|
+
name: wQ,
|
|
799
|
+
shape: [Math.ceil(totalElements / 8)],
|
|
800
|
+
dtype: "u32",
|
|
801
|
+
storage: "constant"
|
|
802
|
+
});
|
|
803
|
+
addTensor({
|
|
804
|
+
name: wScales,
|
|
805
|
+
shape: [Math.ceil(totalElements / groupSz)],
|
|
806
|
+
dtype: "f32",
|
|
807
|
+
storage: "constant"
|
|
808
|
+
});
|
|
809
|
+
addTensor({
|
|
810
|
+
name: wZeros,
|
|
811
|
+
shape: [Math.ceil(totalElements / groupSz)],
|
|
812
|
+
dtype: "f32",
|
|
813
|
+
storage: "constant"
|
|
814
|
+
});
|
|
815
|
+
addNode({
|
|
816
|
+
id,
|
|
817
|
+
opType: "MatMulInt4",
|
|
818
|
+
inputs: [
|
|
819
|
+
activationInput,
|
|
820
|
+
wQ,
|
|
821
|
+
wScales,
|
|
822
|
+
wZeros
|
|
823
|
+
],
|
|
824
|
+
outputs: [outputName],
|
|
825
|
+
attributes: {
|
|
826
|
+
M_tensor: activationInput,
|
|
827
|
+
K,
|
|
828
|
+
N,
|
|
829
|
+
group_size: groupSz
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
714
834
|
addTensor({
|
|
715
835
|
name: weightName,
|
|
716
836
|
shape: weightShape,
|
|
@@ -1239,66 +1359,6 @@ function generateKaniTtsGraph(rawConfig, dtype, _groupSize, kvDtype) {
|
|
|
1239
1359
|
};
|
|
1240
1360
|
}
|
|
1241
1361
|
|
|
1242
|
-
//#endregion
|
|
1243
|
-
//#region src/gpu/quantize.ts
|
|
1244
|
-
/**
|
|
1245
|
-
* On-the-fly INT4 quantization for WebGPU inference.
|
|
1246
|
-
*
|
|
1247
|
-
* Converts F32 weight matrices to 4-bit unsigned integers with per-group
|
|
1248
|
-
* scale/zero-point parameters. Matches the dequantization formula in the
|
|
1249
|
-
* MatMulInt4 WGSL kernel:
|
|
1250
|
-
*
|
|
1251
|
-
* dequant_val = (raw_nibble - zero) * scale
|
|
1252
|
-
*
|
|
1253
|
-
* Packing: 8 × 4-bit values per u32, little-nibble-first order.
|
|
1254
|
-
* Grouping: contiguous elements in row-major (K × N) layout.
|
|
1255
|
-
*/
|
|
1256
|
-
const DEFAULT_GROUP_SIZE = 128;
|
|
1257
|
-
/**
|
|
1258
|
-
* Quantize a flat F32 weight array to INT4.
|
|
1259
|
-
*
|
|
1260
|
-
* @param data - Source F32 weight data (row-major, K × N elements)
|
|
1261
|
-
* @param groupSize - Number of elements per quantization group (default 128)
|
|
1262
|
-
* @returns Packed INT4 data with per-group scales and zeros
|
|
1263
|
-
*/
|
|
1264
|
-
function quantizeInt4(data, groupSize = DEFAULT_GROUP_SIZE) {
|
|
1265
|
-
const totalElements = data.length;
|
|
1266
|
-
const numGroups = Math.ceil(totalElements / groupSize);
|
|
1267
|
-
const packedSize = Math.ceil(totalElements / 8);
|
|
1268
|
-
const packed = new Uint32Array(packedSize);
|
|
1269
|
-
const scales = new Float32Array(numGroups);
|
|
1270
|
-
const zeros = new Float32Array(numGroups);
|
|
1271
|
-
for (let g = 0; g < numGroups; g++) {
|
|
1272
|
-
const start = g * groupSize;
|
|
1273
|
-
const end = Math.min(start + groupSize, totalElements);
|
|
1274
|
-
let min = data[start];
|
|
1275
|
-
let max = data[start];
|
|
1276
|
-
for (let i = start + 1; i < end; i++) {
|
|
1277
|
-
const v = data[i];
|
|
1278
|
-
if (v < min) min = v;
|
|
1279
|
-
if (v > max) max = v;
|
|
1280
|
-
}
|
|
1281
|
-
const range = max - min;
|
|
1282
|
-
const scale = range > 0 ? range / 15 : 1;
|
|
1283
|
-
const zero = range > 0 ? -min / scale : 0;
|
|
1284
|
-
scales[g] = scale;
|
|
1285
|
-
zeros[g] = zero;
|
|
1286
|
-
const invRange = range > 0 ? 15 / range : 0;
|
|
1287
|
-
for (let i = start; i < end; i++) {
|
|
1288
|
-
const q = Math.round((data[i] - min) * invRange);
|
|
1289
|
-
const clamped = q < 0 ? 0 : q > 15 ? 15 : q;
|
|
1290
|
-
const packedIdx = i >>> 3;
|
|
1291
|
-
const nibblePos = i & 7;
|
|
1292
|
-
packed[packedIdx] |= clamped << nibblePos * 4;
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
return {
|
|
1296
|
-
packed,
|
|
1297
|
-
scales,
|
|
1298
|
-
zeros
|
|
1299
|
-
};
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
1362
|
//#endregion
|
|
1303
1363
|
//#region src/gpu/architectures/gemma3_encoder.ts
|
|
1304
1364
|
function generateGemma3EncoderGraph(rawConfig, dtype, groupSizeOverride, _kvDtype, _embedding) {
|
|
@@ -6059,5 +6119,5 @@ function isArchitectureSupported(name) {
|
|
|
6059
6119
|
}
|
|
6060
6120
|
|
|
6061
6121
|
//#endregion
|
|
6062
|
-
export {
|
|
6063
|
-
//# sourceMappingURL=architectures-
|
|
6122
|
+
export { quantizeInt4 as C, createDefaultHFKeyMapper as D, GEMMA4_VIS_KEYS as E, DEFAULT_GROUP_SIZE as S, DTYPE_BYTES as T, kaniCosTensor as _, generateMoonshineEncoderGraph as a, nanoCodecWeightMap as b, KANI_END_OF_HUMAN as c, buildKaniLayerCosSin as d, computeKaniPositions as f, kaniAttentionLayerIndices as g, generateNanoCodecDecoderGraph as h, generateMoonshineDecoderGraph as i, KANI_START_OF_HUMAN as l, generateKaniTtsGraph as m, isArchitectureSupported as n, moonshineEncoderFrames as o, foldNanoCodecWeightNorm as p, MOONSHINE_REMAINING_WORK as r, parseMoonshineConfig as s, generateGraph as t, audioTokensToCodes as u, kaniLayerAlpha as v, CANONICAL_KEYS as w, parseKaniConfig as x, kaniSinTensor as y };
|
|
6123
|
+
//# sourceMappingURL=architectures-Ol7yUmKf.mjs.map
|