@omnid/tinyemo 0.0.0-stage → 1.0.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.
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Compact English-only unigram tokenizer ("ETK2") matching tinyemo/tiny_tokenizer.py.
3
+ *
4
+ * File layout: b"ETK2" | u16 n_pieces | n x ( u8 len | ascii bytes | i8 score*8 )
5
+ * Piece 0 is <unk>.
6
+ */
7
+ const MAGIC = "ETK2";
8
+ const SCORE_SCALE = 8.0;
9
+ const UNK_SCORE = -30.0;
10
+ export class TinyTokenizer {
11
+ pieces;
12
+ scores;
13
+ index;
14
+ unkId = 0;
15
+ maxLen;
16
+ constructor(data) {
17
+ const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
18
+ if (bytes.byteLength < 6) {
19
+ throw new Error("Invalid tokenizer file: too short");
20
+ }
21
+ const magic = String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3]);
22
+ if (magic !== MAGIC) {
23
+ throw new Error(`Invalid tokenizer magic: expected "${MAGIC}", got "${magic}"`);
24
+ }
25
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
26
+ const nPieces = view.getUint16(4, true);
27
+ let offset = 6;
28
+ this.pieces = new Array(nPieces);
29
+ this.scores = new Float64Array(nPieces);
30
+ this.index = new Map();
31
+ let maxLen = 0;
32
+ const decoder = new TextDecoder("ascii");
33
+ for (let i = 0; i < nPieces; i++) {
34
+ const len = bytes[offset];
35
+ offset += 1;
36
+ const piece = decoder.decode(bytes.subarray(offset, offset + len));
37
+ offset += len;
38
+ const qScore = view.getInt8(offset);
39
+ offset += 1;
40
+ this.pieces[i] = piece;
41
+ this.scores[i] = qScore / SCORE_SCALE;
42
+ if (i > 0) {
43
+ this.index.set(piece, i);
44
+ }
45
+ if (piece.length > maxLen) {
46
+ maxLen = piece.length;
47
+ }
48
+ }
49
+ this.maxLen = maxLen;
50
+ }
51
+ /**
52
+ * Serialize pieces and scores into an ETK2 binary buffer.
53
+ */
54
+ static dump(pieces, scores) {
55
+ const encoder = new TextEncoder();
56
+ const encodedPieces = pieces.map((p) => encoder.encode(p));
57
+ const totalBytes = 6 + encodedPieces.reduce((acc, b) => acc + 2 + b.byteLength, 0);
58
+ const out = new Uint8Array(totalBytes);
59
+ const view = new DataView(out.buffer);
60
+ out[0] = 0x45; // E
61
+ out[1] = 0x54; // T
62
+ out[2] = 0x4b; // K
63
+ out[3] = 0x32; // 2
64
+ view.setUint16(4, pieces.length, true);
65
+ let offset = 6;
66
+ for (let i = 0; i < pieces.length; i++) {
67
+ const b = encodedPieces[i];
68
+ out[offset++] = b.byteLength;
69
+ out.set(b, offset);
70
+ offset += b.byteLength;
71
+ const q = Math.max(-128, Math.min(127, Math.round(scores[i] * SCORE_SCALE)));
72
+ view.setInt8(offset++, q);
73
+ }
74
+ return out;
75
+ }
76
+ /**
77
+ * Encode already-normalized text using Viterbi dynamic programming.
78
+ */
79
+ encode(normText, maxTokens) {
80
+ const s = "_" + normText.replace(/ /g, "_");
81
+ const n = s.length;
82
+ if (n <= 1) {
83
+ return [];
84
+ }
85
+ const best = new Float64Array(n + 1).fill(-1e18);
86
+ best[0] = 0.0;
87
+ const bp = new Int32Array(n + 1);
88
+ const bid = new Int32Array(n + 1).fill(this.unkId);
89
+ for (let i = 1; i <= n; i++) {
90
+ const startJ = Math.max(0, i - this.maxLen);
91
+ for (let j = startJ; j < i; j++) {
92
+ const sub = s.slice(j, i);
93
+ const tid = this.index.get(sub);
94
+ if (tid !== undefined) {
95
+ const sc = best[j] + this.scores[tid];
96
+ if (sc > best[i]) {
97
+ best[i] = sc;
98
+ bp[i] = j;
99
+ bid[i] = tid;
100
+ }
101
+ }
102
+ }
103
+ const unkSc = best[i - 1] + UNK_SCORE;
104
+ if (unkSc > best[i]) {
105
+ best[i] = unkSc;
106
+ bp[i] = i - 1;
107
+ bid[i] = this.unkId;
108
+ }
109
+ }
110
+ const ids = [];
111
+ let cur = n;
112
+ while (cur > 0) {
113
+ ids.push(bid[cur]);
114
+ cur = bp[cur];
115
+ }
116
+ ids.reverse();
117
+ if (maxTokens !== undefined && ids.length > maxTokens) {
118
+ return ids.slice(-maxTokens);
119
+ }
120
+ return ids;
121
+ }
122
+ }
123
+ //# sourceMappingURL=tokenizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Model hyperparameters matching tinyemo/config.json.
3
+ */
4
+ export interface TinyEmoModelConfig {
5
+ vocab: number;
6
+ n_buckets: number;
7
+ ng_dim: number;
8
+ tok_dim: number;
9
+ d_model: number;
10
+ n_layers: number;
11
+ n_heads: number;
12
+ ffn: number;
13
+ head_hidden: number;
14
+ n_labels: number;
15
+ max_tokens: number;
16
+ max_features: number;
17
+ }
18
+ /**
19
+ * Tensor metadata and float32 data extracted from safetensors or ONNX.
20
+ */
21
+ export interface TensorData {
22
+ dtype: string;
23
+ shape: number[];
24
+ data: Float32Array;
25
+ }
26
+ /**
27
+ * Parsed Safetensors file representation.
28
+ */
29
+ export interface SafetensorsFile {
30
+ metadata: Record<string, string>;
31
+ tensors: Record<string, TensorData>;
32
+ }
33
+ /**
34
+ * Supported weight container formats.
35
+ */
36
+ export type WeightsFormat = "safetensors" | "onnx" | "auto";
37
+ /**
38
+ * Supported Web Streams compression formats.
39
+ */
40
+ export type StreamCompressionFormat = "gzip" | "deflate" | "deflate-raw";
41
+ /**
42
+ * Options for initializing a TinyEmo WebGPU instance.
43
+ */
44
+ export interface TinyEmoOptions {
45
+ /**
46
+ * Optional pre-initialized WebGPU device. If omitted, requests one via `navigator.gpu`.
47
+ */
48
+ device?: GPUDevice;
49
+ /**
50
+ * Optional adapter options when requesting a WebGPU adapter.
51
+ */
52
+ adapterOptions?: GPURequestAdapterOptions;
53
+ /**
54
+ * Optional custom weights buffer (raw or compressed safetensors / ONNX).
55
+ * Defaults to the compressed safetensors weights packed in the SDK.
56
+ */
57
+ weights?: Uint8Array | ArrayBuffer;
58
+ /**
59
+ * Format of the provided `weights` buffer. Defaults to `"auto"`.
60
+ */
61
+ weightsFormat?: WeightsFormat;
62
+ /**
63
+ * Optional custom ETK2 tokenizer binary (raw or compressed).
64
+ * Defaults to the compressed tokenizer packed in the SDK.
65
+ */
66
+ tokenizer?: Uint8Array | ArrayBuffer;
67
+ /**
68
+ * Optional model configuration override.
69
+ */
70
+ config?: TinyEmoModelConfig;
71
+ /**
72
+ * Optional emoji label list override.
73
+ */
74
+ labels?: readonly string[];
75
+ }
76
+ /**
77
+ * Single emoji suggestion returned by `suggest()`.
78
+ * Supports both object property access (`{ emoji, probability, score, index }`)
79
+ * and tuple destructuring (`const [emoji, probability] = suggestion`).
80
+ */
81
+ export interface EmojiSuggestion {
82
+ readonly emoji: string;
83
+ readonly probability: number;
84
+ readonly score: number;
85
+ readonly index: number;
86
+ readonly 0: string;
87
+ readonly 1: number;
88
+ [Symbol.iterator](): Iterator<string | number>;
89
+ }
90
+ /**
91
+ * Preprocessed features for a single input phrase.
92
+ */
93
+ export interface EncodedInput {
94
+ normalized: string;
95
+ tokIds: Uint32Array;
96
+ tokMask: Uint32Array;
97
+ ngBucket: Uint32Array;
98
+ ngSign: Float32Array;
99
+ ngCount: number;
100
+ }
101
+ /**
102
+ * Preprocessed batched inputs ready for WebGPU execution.
103
+ */
104
+ export interface EncodedBatch {
105
+ batchSize: number;
106
+ maxTokens: number;
107
+ maxFeatures: number;
108
+ tokIds: Uint32Array;
109
+ tokMask: Uint32Array;
110
+ ngBucket: Uint32Array;
111
+ ngSign: Float32Array;
112
+ ngCount: Float32Array;
113
+ }
114
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;OAEG;IACH,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C;;;OAGG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACnC;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACrC;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;CACvB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ import { TinyTokenizer } from "./tokenizer.js";
2
+ import type { SafetensorsFile, TensorData, TinyEmoModelConfig, WeightsFormat } from "./types.js";
3
+ /**
4
+ * Parse a Safetensors binary buffer into metadata and Float32Array tensors.
5
+ */
6
+ export declare function parseSafetensors(buffer: ArrayBuffer | Uint8Array): SafetensorsFile;
7
+ /**
8
+ * Serialize a dictionary of Float32Array tensors into a valid Safetensors binary buffer.
9
+ */
10
+ export declare function serializeSafetensors(tensors: Record<string, TensorData>, metadata?: Record<string, string>): Uint8Array;
11
+ /**
12
+ * Parse float32 weights from an ONNX model buffer (`model.onnx`), automatically
13
+ * un-transposing folded MatMul initializers back to standard TinyEmo parameter names.
14
+ */
15
+ export declare function parseOnnxWeights(buffer: ArrayBuffer | Uint8Array): Record<string, TensorData>;
16
+ /**
17
+ * Detect whether a decompressed weight buffer is Safetensors or ONNX and parse it.
18
+ */
19
+ export declare function loadWeightsFromBuffer(buffer: ArrayBuffer | Uint8Array, format?: WeightsFormat): Promise<Record<string, TensorData>>;
20
+ /**
21
+ * Decode and decompress the built-in packed `model.safetensors` using `DecompressionStream`.
22
+ */
23
+ export declare function loadPackedWeights(): Promise<Record<string, TensorData>>;
24
+ /**
25
+ * Decode and decompress the built-in packed `tiny_tokenizer.bin` using `DecompressionStream`.
26
+ */
27
+ export declare function loadPackedTokenizer(): Promise<TinyTokenizer>;
28
+ export interface LayerWeightOffsets {
29
+ norm1Weight: number;
30
+ norm1Bias: number;
31
+ qkvWeight: number;
32
+ qkvBias: number;
33
+ projWeight: number;
34
+ projBias: number;
35
+ norm2Weight: number;
36
+ norm2Bias: number;
37
+ ff1Weight: number;
38
+ ff1Bias: number;
39
+ ff2Weight: number;
40
+ ff2Bias: number;
41
+ }
42
+ export interface PackedGpuWeights {
43
+ buffer: Float32Array;
44
+ offsets: {
45
+ posEmb: number;
46
+ poolQ: number;
47
+ tokEmbWeight: number;
48
+ tokProjWeight: number;
49
+ ngEmbWeight: number;
50
+ ngNormWeight: number;
51
+ ngNormBias: number;
52
+ layers: LayerWeightOffsets[];
53
+ finalNormWeight: number;
54
+ finalNormBias: number;
55
+ poolProjWeight: number;
56
+ poolProjBias: number;
57
+ poolNormWeight: number;
58
+ poolNormBias: number;
59
+ head1Weight: number;
60
+ head1Bias: number;
61
+ head2Weight: number;
62
+ head2Bias: number;
63
+ };
64
+ }
65
+ /**
66
+ * Pack all model tensors into a single contiguous Float32Array with float-element offsets
67
+ * for direct binding as a single WebGPU storage buffer.
68
+ */
69
+ export declare function packWeightsForGpu(tensors: Record<string, TensorData>, config: TinyEmoModelConfig): PackedGpuWeights;
70
+ //# sourceMappingURL=weights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weights.d.ts","sourceRoot":"","sources":["../src/weights.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,eAAe,CA+ClF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EACnC,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAoB,GAClD,UAAU,CAoCZ;AAgED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,GAAG,UAAU,GAC/B,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CA+E5B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,GAAG,UAAU,EAChC,MAAM,GAAE,aAAsB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAiBrC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAM7E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,aAAa,CAAC,CAMlE;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,kBAAkB,EAAE,CAAC;QAC7B,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EACnC,MAAM,EAAE,kBAAkB,GACzB,gBAAgB,CAmGlB"}
@@ -0,0 +1,320 @@
1
+ import { decodePackedAsset, maybeDecompress } from "./compression.js";
2
+ import { PACKED_COMPRESSION_FORMAT, PACKED_SAFETENSORS_B64, PACKED_TOKENIZER_B64 } from "./packed-assets.js";
3
+ import { TinyTokenizer } from "./tokenizer.js";
4
+ /**
5
+ * Parse a Safetensors binary buffer into metadata and Float32Array tensors.
6
+ */
7
+ export function parseSafetensors(buffer) {
8
+ const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
9
+ if (bytes.byteLength < 8) {
10
+ throw new Error("Invalid safetensors buffer: fewer than 8 bytes");
11
+ }
12
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
13
+ const headerLenBig = view.getBigUint64(0, true);
14
+ const headerLen = Number(headerLenBig);
15
+ if (headerLen <= 0 || 8 + headerLen > bytes.byteLength) {
16
+ throw new Error(`Invalid safetensors header length: ${headerLen}`);
17
+ }
18
+ const headerJson = new TextDecoder("utf-8").decode(bytes.subarray(8, 8 + headerLen));
19
+ const rawHeader = JSON.parse(headerJson);
20
+ const metadata = {};
21
+ const tensors = {};
22
+ const dataStart = 8 + headerLen;
23
+ for (const [key, entry] of Object.entries(rawHeader)) {
24
+ if (key === "__metadata__") {
25
+ Object.assign(metadata, entry);
26
+ continue;
27
+ }
28
+ const tensorEntry = entry;
29
+ const [start, end] = tensorEntry.data_offsets;
30
+ const byteLength = end - start;
31
+ const slice = bytes.subarray(dataStart + start, dataStart + end);
32
+ // Copy to 4-byte aligned Float32Array
33
+ const aligned = new Uint8Array(byteLength);
34
+ aligned.set(slice);
35
+ const data = new Float32Array(aligned.buffer, 0, byteLength / 4);
36
+ tensors[key] = {
37
+ dtype: tensorEntry.dtype,
38
+ shape: tensorEntry.shape,
39
+ data
40
+ };
41
+ }
42
+ return { metadata, tensors };
43
+ }
44
+ /**
45
+ * Serialize a dictionary of Float32Array tensors into a valid Safetensors binary buffer.
46
+ */
47
+ export function serializeSafetensors(tensors, metadata = { format: "pt" }) {
48
+ const headerObj = { __metadata__: metadata };
49
+ let dataOffset = 0;
50
+ const blobs = [];
51
+ for (const [name, tensor] of Object.entries(tensors)) {
52
+ const byteLen = tensor.data.byteLength;
53
+ headerObj[name] = {
54
+ dtype: tensor.dtype || "F32",
55
+ shape: tensor.shape,
56
+ data_offsets: [dataOffset, dataOffset + byteLen]
57
+ };
58
+ blobs.push(new Uint8Array(tensor.data.buffer, tensor.data.byteOffset, tensor.data.byteLength));
59
+ dataOffset += byteLen;
60
+ }
61
+ const headerBytes = new TextEncoder().encode(JSON.stringify(headerObj));
62
+ const padLen = (8 - (headerBytes.byteLength % 8)) % 8;
63
+ const paddedHeaderLen = headerBytes.byteLength + padLen;
64
+ const out = new Uint8Array(8 + paddedHeaderLen + dataOffset);
65
+ const view = new DataView(out.buffer);
66
+ view.setBigUint64(0, BigInt(paddedHeaderLen), true);
67
+ out.set(headerBytes, 8);
68
+ for (let i = 0; i < padLen; i++) {
69
+ out[8 + headerBytes.byteLength + i] = 0x20; // space padding per safetensors spec
70
+ }
71
+ let pos = 8 + paddedHeaderLen;
72
+ for (const blob of blobs) {
73
+ out.set(blob, pos);
74
+ pos += blob.byteLength;
75
+ }
76
+ return out;
77
+ }
78
+ function readVarint(b, pos) {
79
+ let res = 0n;
80
+ let shift = 0n;
81
+ while (pos < b.length) {
82
+ const byte = b[pos++];
83
+ res |= BigInt(byte & 0x7f) << shift;
84
+ if ((byte & 0x80) === 0) {
85
+ return [Number(res), pos];
86
+ }
87
+ shift += 7n;
88
+ }
89
+ return [Number(res), pos];
90
+ }
91
+ function parseProtoFields(b, start = 0, end = b.length) {
92
+ const fields = [];
93
+ let pos = start;
94
+ while (pos < end) {
95
+ const [tag, p1] = readVarint(b, pos);
96
+ pos = p1;
97
+ const fieldNum = tag >>> 3;
98
+ const wireType = tag & 7;
99
+ if (wireType === 0) {
100
+ const [val, p2] = readVarint(b, pos);
101
+ pos = p2;
102
+ fields.push({ fieldNum, wireType, val });
103
+ }
104
+ else if (wireType === 2) {
105
+ const [len, p2] = readVarint(b, pos);
106
+ pos = p2;
107
+ fields.push({ fieldNum, wireType, start: pos, end: pos + len });
108
+ pos += len;
109
+ }
110
+ else if (wireType === 5) {
111
+ fields.push({ fieldNum, wireType, start: pos, end: pos + 4 });
112
+ pos += 4;
113
+ }
114
+ else if (wireType === 1) {
115
+ fields.push({ fieldNum, wireType, start: pos, end: pos + 8 });
116
+ pos += 8;
117
+ }
118
+ else {
119
+ throw new Error(`Unsupported protobuf wireType: ${wireType}`);
120
+ }
121
+ }
122
+ return fields;
123
+ }
124
+ function transpose2D(data, rows, cols) {
125
+ const out = new Float32Array(rows * cols);
126
+ for (let r = 0; r < rows; r++) {
127
+ for (let c = 0; c < cols; c++) {
128
+ out[c * rows + r] = data[r * cols + c];
129
+ }
130
+ }
131
+ return out;
132
+ }
133
+ /**
134
+ * Parse float32 weights from an ONNX model buffer (`model.onnx`), automatically
135
+ * un-transposing folded MatMul initializers back to standard TinyEmo parameter names.
136
+ */
137
+ export function parseOnnxWeights(buffer) {
138
+ const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
139
+ const modelFields = parseProtoFields(bytes);
140
+ const graphField = modelFields.find((f) => f.fieldNum === 7 && f.start !== undefined);
141
+ if (!graphField || graphField.start === undefined || graphField.end === undefined) {
142
+ throw new Error("Invalid ONNX buffer: missing GraphProto field");
143
+ }
144
+ const graphFields = parseProtoFields(bytes, graphField.start, graphField.end);
145
+ const initFields = graphFields.filter((f) => f.fieldNum === 5 && f.start !== undefined);
146
+ const decoder = new TextDecoder("utf-8");
147
+ const rawTensors = {};
148
+ const matmulKeys = [];
149
+ for (const init of initFields) {
150
+ const tf = parseProtoFields(bytes, init.start, init.end);
151
+ const dims = [];
152
+ for (const f of tf) {
153
+ if (f.fieldNum === 1 && f.val !== undefined) {
154
+ dims.push(f.val);
155
+ }
156
+ else if (f.fieldNum === 1 && f.start !== undefined && f.end !== undefined) {
157
+ let p = f.start;
158
+ while (p < f.end) {
159
+ const [v, nextP] = readVarint(bytes, p);
160
+ dims.push(v);
161
+ p = nextP;
162
+ }
163
+ }
164
+ }
165
+ const nameField = tf.find((f) => f.fieldNum === 8);
166
+ if (!nameField || nameField.start === undefined || nameField.end === undefined) {
167
+ continue;
168
+ }
169
+ const name = decoder.decode(bytes.subarray(nameField.start, nameField.end));
170
+ const rawDataField = tf.find((f) => f.fieldNum === 9);
171
+ if (!rawDataField || rawDataField.start === undefined || rawDataField.end === undefined) {
172
+ continue;
173
+ }
174
+ const rawSlice = bytes.subarray(rawDataField.start, rawDataField.end);
175
+ const aligned = new Uint8Array(rawSlice.byteLength);
176
+ aligned.set(rawSlice);
177
+ const data = new Float32Array(aligned.buffer, 0, aligned.byteLength / 4);
178
+ rawTensors[name] = { dtype: "F32", shape: dims, data };
179
+ if (name.startsWith("onnx::MatMul_")) {
180
+ matmulKeys.push(name);
181
+ }
182
+ }
183
+ // In TinyEmo ONNX export, the 6 linear weights without Gemm fusion are exported
184
+ // in order as onnx::MatMul_* with transposed shape [in_features, out_features]:
185
+ // 0: tok_proj.weight [48, 128] -> [128, 48]
186
+ // 1: blocks.0.qkv.weight [128, 384] -> [384, 128]
187
+ // 2: blocks.0.proj.weight [128, 128] -> [128, 128]
188
+ // 3: blocks.0.ff1.weight [128, 256] -> [256, 128]
189
+ // 4: blocks.0.ff2.weight [256, 128] -> [128, 256]
190
+ // 5: pool_proj.weight [128, 128] -> [128, 128]
191
+ const matmulTargets = [
192
+ "tok_proj.weight",
193
+ "blocks.0.qkv.weight",
194
+ "blocks.0.proj.weight",
195
+ "blocks.0.ff1.weight",
196
+ "blocks.0.ff2.weight",
197
+ "pool_proj.weight"
198
+ ];
199
+ if (matmulKeys.length === matmulTargets.length) {
200
+ for (let i = 0; i < matmulKeys.length; i++) {
201
+ const src = rawTensors[matmulKeys[i]];
202
+ const [rows, cols] = src.shape;
203
+ rawTensors[matmulTargets[i]] = {
204
+ dtype: "F32",
205
+ shape: [cols, rows],
206
+ data: transpose2D(src.data, rows, cols)
207
+ };
208
+ delete rawTensors[matmulKeys[i]];
209
+ }
210
+ }
211
+ return rawTensors;
212
+ }
213
+ /**
214
+ * Detect whether a decompressed weight buffer is Safetensors or ONNX and parse it.
215
+ */
216
+ export async function loadWeightsFromBuffer(buffer, format = "auto") {
217
+ const decompressed = await maybeDecompress(buffer);
218
+ if (format === "safetensors") {
219
+ return parseSafetensors(decompressed).tensors;
220
+ }
221
+ if (format === "onnx") {
222
+ return parseOnnxWeights(decompressed);
223
+ }
224
+ // Auto-detect: safetensors starts with 8-byte u64 header length followed by '{"'
225
+ if (decompressed.byteLength > 10 &&
226
+ decompressed[8] === 0x7b && // '{'
227
+ decompressed[9] === 0x22 // '"'
228
+ ) {
229
+ return parseSafetensors(decompressed).tensors;
230
+ }
231
+ return parseOnnxWeights(decompressed);
232
+ }
233
+ /**
234
+ * Decode and decompress the built-in packed `model.safetensors` using `DecompressionStream`.
235
+ */
236
+ export async function loadPackedWeights() {
237
+ const rawBytes = await decodePackedAsset(PACKED_SAFETENSORS_B64, PACKED_COMPRESSION_FORMAT);
238
+ return parseSafetensors(rawBytes).tensors;
239
+ }
240
+ /**
241
+ * Decode and decompress the built-in packed `tiny_tokenizer.bin` using `DecompressionStream`.
242
+ */
243
+ export async function loadPackedTokenizer() {
244
+ const rawBytes = await decodePackedAsset(PACKED_TOKENIZER_B64, PACKED_COMPRESSION_FORMAT);
245
+ return new TinyTokenizer(rawBytes);
246
+ }
247
+ /**
248
+ * Pack all model tensors into a single contiguous Float32Array with float-element offsets
249
+ * for direct binding as a single WebGPU storage buffer.
250
+ */
251
+ export function packWeightsForGpu(tensors, config) {
252
+ const orderedNames = [
253
+ "pos_emb",
254
+ "pool_q",
255
+ "tok_emb.weight",
256
+ "tok_proj.weight",
257
+ "ng_emb.weight",
258
+ "ng_norm.weight",
259
+ "ng_norm.bias"
260
+ ];
261
+ for (let l = 0; l < config.n_layers; l++) {
262
+ orderedNames.push(`blocks.${l}.norm1.weight`, `blocks.${l}.norm1.bias`, `blocks.${l}.qkv.weight`, `blocks.${l}.qkv.bias`, `blocks.${l}.proj.weight`, `blocks.${l}.proj.bias`, `blocks.${l}.norm2.weight`, `blocks.${l}.norm2.bias`, `blocks.${l}.ff1.weight`, `blocks.${l}.ff1.bias`, `blocks.${l}.ff2.weight`, `blocks.${l}.ff2.bias`);
263
+ }
264
+ orderedNames.push("final_norm.weight", "final_norm.bias", "pool_proj.weight", "pool_proj.bias", "pool_norm.weight", "pool_norm.bias", "head1.weight", "head1.bias", "head2.weight", "head2.bias");
265
+ let totalFloats = 0;
266
+ const offsetMap = {};
267
+ for (const name of orderedNames) {
268
+ const t = tensors[name];
269
+ if (!t) {
270
+ throw new Error(`Missing required model weight tensor: "${name}"`);
271
+ }
272
+ offsetMap[name] = totalFloats;
273
+ totalFloats += t.data.length;
274
+ }
275
+ const buffer = new Float32Array(totalFloats);
276
+ for (const name of orderedNames) {
277
+ buffer.set(tensors[name].data, offsetMap[name]);
278
+ }
279
+ const layers = [];
280
+ for (let l = 0; l < config.n_layers; l++) {
281
+ layers.push({
282
+ norm1Weight: offsetMap[`blocks.${l}.norm1.weight`],
283
+ norm1Bias: offsetMap[`blocks.${l}.norm1.bias`],
284
+ qkvWeight: offsetMap[`blocks.${l}.qkv.weight`],
285
+ qkvBias: offsetMap[`blocks.${l}.qkv.bias`],
286
+ projWeight: offsetMap[`blocks.${l}.proj.weight`],
287
+ projBias: offsetMap[`blocks.${l}.proj.bias`],
288
+ norm2Weight: offsetMap[`blocks.${l}.norm2.weight`],
289
+ norm2Bias: offsetMap[`blocks.${l}.norm2.bias`],
290
+ ff1Weight: offsetMap[`blocks.${l}.ff1.weight`],
291
+ ff1Bias: offsetMap[`blocks.${l}.ff1.bias`],
292
+ ff2Weight: offsetMap[`blocks.${l}.ff2.weight`],
293
+ ff2Bias: offsetMap[`blocks.${l}.ff2.bias`]
294
+ });
295
+ }
296
+ return {
297
+ buffer,
298
+ offsets: {
299
+ posEmb: offsetMap["pos_emb"],
300
+ poolQ: offsetMap["pool_q"],
301
+ tokEmbWeight: offsetMap["tok_emb.weight"],
302
+ tokProjWeight: offsetMap["tok_proj.weight"],
303
+ ngEmbWeight: offsetMap["ng_emb.weight"],
304
+ ngNormWeight: offsetMap["ng_norm.weight"],
305
+ ngNormBias: offsetMap["ng_norm.bias"],
306
+ layers,
307
+ finalNormWeight: offsetMap["final_norm.weight"],
308
+ finalNormBias: offsetMap["final_norm.bias"],
309
+ poolProjWeight: offsetMap["pool_proj.weight"],
310
+ poolProjBias: offsetMap["pool_proj.bias"],
311
+ poolNormWeight: offsetMap["pool_norm.weight"],
312
+ poolNormBias: offsetMap["pool_norm.bias"],
313
+ head1Weight: offsetMap["head1.weight"],
314
+ head1Bias: offsetMap["head1.bias"],
315
+ head2Weight: offsetMap["head2.weight"],
316
+ head2Bias: offsetMap["head2.bias"]
317
+ }
318
+ };
319
+ }
320
+ //# sourceMappingURL=weights.js.map