diskformer 0.6.12 → 0.6.13
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/CHANGELOG.md +7 -0
- package/engines/lfm3_omni.js +12 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.13 (2026-10-30)
|
|
4
|
+
- LFM3-Omni: one reply at a time. `generate()` and `greedyIds()` share the decoder's caches and onnxruntime's sessions;
|
|
5
|
+
two replies overlapping on WebGPU failed ("Failed to download data from buffer") or hung (the NakliOS assistant: a
|
|
6
|
+
text reply with tools left running, then a speech reply). A call made while another runs now waits its turn.
|
|
7
|
+
- Gate `test/browser/lfm3-omni-overlap.html`: text then speech on one engine, and speech started while text runs; both
|
|
8
|
+
stream audio, nothing throws or times out.
|
|
9
|
+
|
|
3
10
|
## 0.6.12 (2026-10-30)
|
|
4
11
|
- LFM3-Omni-2B speaks: `generate(messages, { output_modalities: ['text', 'audio'], onAudio })` runs Liquid's
|
|
5
12
|
interleaved mode (6 text tokens, 12 speech frames in turn), the depth decoder's MaskGIT (12 codes a frame) and the
|
package/engines/lfm3_omni.js
CHANGED
|
@@ -710,7 +710,15 @@ export class Lfm3Omni {
|
|
|
710
710
|
// stopReason 'eos' | 'length' | 'aborted'. Streaming: onText(delta) with each new piece of text (held back while
|
|
711
711
|
// a token ends inside a UTF-8 character), onToken(id), and a transformers.js streamer (put([[id]]), end()). signal
|
|
712
712
|
// (AbortSignal) is read before every decode step; an abort resolves, it does not throw.
|
|
713
|
-
|
|
713
|
+
// One reply at a time: generate() and greedyIds() share the decoder's caches and onnxruntime's sessions, and two runs
|
|
714
|
+
// overlapping on WebGPU fail ("Failed to download data from buffer") or hang (2026-10-30: a caller that stopped
|
|
715
|
+
// reading a text reply without aborting it, then asked for speech). A call made while another runs waits its turn.
|
|
716
|
+
#turn = Promise.resolve();
|
|
717
|
+
#serial(fn) { const run = this.#turn.then(fn); this.#turn = run.catch(() => {}); return run; }
|
|
718
|
+
|
|
719
|
+
generate(messages, opts = {}) { return this.#serial(() => this.#generate(messages, opts)); }
|
|
720
|
+
|
|
721
|
+
async #generate(messages, opts) {
|
|
714
722
|
const { max_new_tokens = 1024, signal, onText, onToken, streamer, seed, output_modalities = ['text'] } = opts;
|
|
715
723
|
if (output_modalities.includes('audio')) {
|
|
716
724
|
if (!output_modalities.includes('text')) throw new Error("LFM3-Omni speaks in interleaved mode: output_modalities ['text', 'audio']");
|
|
@@ -818,7 +826,9 @@ export class Lfm3Omni {
|
|
|
818
826
|
}
|
|
819
827
|
|
|
820
828
|
// Greedy ids after prompt ids (the gate's comparison): no template, no stop on EOS unless asked.
|
|
821
|
-
|
|
829
|
+
greedyIds(ids, side = {}, n = 32, opts = {}) { return this.#serial(() => this.#greedyIds(ids, side, n, opts)); }
|
|
830
|
+
|
|
831
|
+
async #greedyIds(ids, side = {}, n = 32, { stopAtEos = true } = {}) {
|
|
822
832
|
const T = this.tokens, suppress = [T.audio, T.audio_out, T.image, T.video, T.mixed_start, T.audio_start], out = [];
|
|
823
833
|
try {
|
|
824
834
|
let { logits } = await this.prefill(ids, side);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "diskformer",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.13",
|
|
4
4
|
"description": "Run a model larger than your GPU memory in a browser tab: weights stay in OPFS, WebGPU holds only what each step needs. llama.cpp with paged MoE experts (diskformer/llama), a disk tier, and hand-written MoE engines.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|