@qvac/sdk 0.13.5 → 0.14.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/NOTICE +95 -1151
- package/README.md +1 -2
- package/bare-imports.json +0 -5
- package/dist/client/api/bci-transcribe.js +2 -1
- package/dist/client/api/download-asset.js +2 -1
- package/dist/client/api/finetune.js +6 -5
- package/dist/client/api/index.d.ts +1 -0
- package/dist/client/api/index.js +1 -0
- package/dist/client/api/load-model.d.ts +11 -8
- package/dist/client/api/load-model.js +6 -6
- package/dist/client/api/subscribe-logs.d.ts +28 -0
- package/dist/client/api/subscribe-logs.js +43 -0
- package/dist/client/api/text-to-speech.js +2 -1
- package/dist/client/config-loader/config-utils.js +2 -4
- package/dist/client/config-loader/resolve-config.bare.js +4 -3
- package/dist/client/parse-input.d.ts +3 -0
- package/dist/client/parse-input.js +14 -0
- package/dist/client/rpc/expo-rpc-client.js +2 -11
- package/dist/client/rpc/node-rpc-client.js +8 -2
- package/dist/client/rpc/rpc-client.js +39 -7
- package/dist/commands/bundle/constants.js +2 -1
- package/dist/commands/bundle/entry-gen.d.ts +1 -1
- package/dist/commands/bundle/entry-gen.js +6 -6
- package/dist/commands/bundle/index.js +3 -1
- package/dist/commands/bundle/resolve-sdk-import.d.ts +6 -0
- package/dist/commands/bundle/resolve-sdk-import.js +60 -0
- package/dist/examples/bci/bci-filesystem-streaming.js +14 -14
- package/dist/examples/bci/bci-filesystem.js +17 -13
- package/dist/examples/cache-management.js +38 -38
- package/dist/examples/cancel-by-request-id.js +9 -9
- package/dist/examples/completion-events.js +20 -14
- package/dist/examples/completion-stop-reason.js +13 -7
- package/dist/examples/concurrent-completion-collision.js +7 -7
- package/dist/examples/config-reload.js +7 -8
- package/dist/examples/default-config-usage.js +4 -4
- package/dist/examples/delegated-inference/composite.js +14 -10
- package/dist/examples/delegated-inference/consumer-profiled.js +13 -13
- package/dist/examples/delegated-inference/consumer.js +16 -12
- package/dist/examples/delegated-inference/provider.js +12 -12
- package/dist/examples/diffusion-esrgan-upscale.js +19 -15
- package/dist/examples/diffusion-flux2-klein-img2img.js +16 -11
- package/dist/examples/diffusion-flux2-klein.js +14 -9
- package/dist/examples/diffusion-img2img.js +9 -10
- package/dist/examples/diffusion-img2vid.js +17 -12
- package/dist/examples/diffusion-simple.js +1 -1
- package/dist/examples/diffusion-txt2img.js +14 -9
- package/dist/examples/diffusion-txt2vid.js +15 -10
- package/dist/examples/download-with-blind-relays.js +16 -21
- package/dist/examples/download-with-cancel.js +15 -16
- package/dist/examples/embed-multi-gpu.js +3 -4
- package/dist/examples/embed-p2p.js +11 -7
- package/dist/examples/finetune/llamacpp-finetune.js +7 -7
- package/dist/examples/kv-cache-cleanup.js +35 -35
- package/dist/examples/kv-cache-custom-key.js +24 -24
- package/dist/examples/kv-cache-example.js +9 -9
- package/dist/examples/llamacpp-cache.js +18 -14
- package/dist/examples/llamacpp-dynamic-tools.js +15 -9
- package/dist/examples/llamacpp-filesystem.js +15 -9
- package/dist/examples/llamacpp-http.js +12 -10
- package/dist/examples/llamacpp-multi-gpu.js +4 -4
- package/dist/examples/llamacpp-multimodal.js +13 -9
- package/dist/examples/llamacpp-p2p.js +8 -4
- package/dist/examples/llamacpp-sharded.js +5 -5
- package/dist/examples/llamacpp-structured-output.js +15 -9
- package/dist/examples/logging-file-transport.js +3 -3
- package/dist/examples/logging-global.d.ts +2 -0
- package/dist/examples/logging-global.js +34 -0
- package/dist/examples/logging-streaming.js +7 -10
- package/dist/examples/mcp-websearch.js +24 -18
- package/dist/examples/multi-model-demo.js +17 -11
- package/dist/examples/ocr-fasttext.js +14 -16
- package/dist/examples/parallel-download.js +7 -7
- package/dist/examples/plugins.js +40 -28
- package/dist/examples/profiling/basic.js +16 -10
- package/dist/examples/profiling/per-call.js +17 -11
- package/dist/examples/quickstart.bare.d.ts +2 -0
- package/dist/examples/quickstart.bare.js +18 -0
- package/dist/examples/quickstart.js +10 -3
- package/dist/examples/rag/rag-chromadb.js +18 -14
- package/dist/examples/rag/rag-hyperdb/cancellation.js +17 -14
- package/dist/examples/rag/rag-hyperdb/ingest.js +14 -12
- package/dist/examples/rag/rag-hyperdb/pipeline.js +19 -17
- package/dist/examples/rag/rag-hyperdb/workspaces.js +31 -27
- package/dist/examples/rag/rag-lancedb.js +12 -8
- package/dist/examples/rag/rag-sqlite.js +11 -7
- package/dist/examples/registry-query.js +17 -17
- package/dist/examples/seed-p2p.js +10 -6
- package/dist/examples/suspend-resume.js +20 -16
- package/dist/examples/tools/llamacpp-native-tools.js +24 -18
- package/dist/examples/tools/llamacpp-tools-gemma4.js +14 -8
- package/dist/examples/tools/llamacpp-tools-harmony-multiturn.js +20 -14
- package/dist/examples/tools/llamacpp-tools-pythonic.js +14 -8
- package/dist/examples/tools/llamacpp-tools-qwen35.js +14 -8
- package/dist/examples/transcription/parakeet-ctc-filesystem.js +12 -9
- package/dist/examples/transcription/parakeet-microphone-record.js +15 -9
- package/dist/examples/transcription/parakeet-microphone-stream.js +15 -9
- package/dist/examples/transcription/parakeet-sortformer-streaming.js +12 -6
- package/dist/examples/transcription/parakeet-sortformer.js +3 -5
- package/dist/examples/transcription/parakeet-tdt-filesystem.js +13 -10
- package/dist/examples/transcription/whispercpp-filesystem-streaming.js +16 -17
- package/dist/examples/transcription/whispercpp-filesystem.js +14 -10
- package/dist/examples/transcription/whispercpp-microphone-conversation.js +10 -10
- package/dist/examples/transcription/whispercpp-microphone-record.js +6 -6
- package/dist/examples/transcription/whispercpp-prompt.js +14 -10
- package/dist/examples/translation/translation-bergamot-batch.js +11 -7
- package/dist/examples/translation/translation-bergamot-pivot.js +13 -9
- package/dist/examples/translation/translation-bergamot.js +8 -4
- package/dist/examples/translation/translation-indic.js +8 -4
- package/dist/examples/translation/translation-llm-afriquegemma.js +7 -3
- package/dist/examples/translation/translation-llm-context.js +8 -4
- package/dist/examples/translation/translation-llm.js +7 -3
- package/dist/examples/translation/translation-stream.js +4 -4
- package/dist/examples/tts/chatterbox.js +19 -11
- package/dist/examples/tts/llm-to-tts-streaming.js +27 -14
- package/dist/examples/tts/supertonic-multilingual.js +18 -14
- package/dist/examples/tts/supertonic.js +19 -15
- package/dist/examples/tts/utils.js +1 -1
- package/dist/examples/vla-pi05.js +18 -14
- package/dist/examples/vla-smolvla.js +18 -14
- package/dist/examples/voice-assistant/voice-assistant.js +12 -12
- package/dist/index.d.ts +3 -4
- package/dist/index.js +3 -4
- package/dist/logging/client-logger.js +2 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/logging/namespaces.d.ts +1 -0
- package/dist/logging/namespaces.js +2 -0
- package/dist/logging/server-logger.js +1 -4
- package/dist/logging/utils.js +6 -1
- package/dist/models/registry/index.d.ts +17 -0
- package/dist/models/registry/index.js +20 -1
- package/dist/models/registry/models.d.ts +1062 -38
- package/dist/models/registry/models.js +3546 -2490
- package/dist/pear/pre.js +2 -2
- package/dist/schemas/bci-config.d.ts +37 -0
- package/dist/schemas/bci-config.js +2 -0
- package/dist/schemas/bci.d.ts +2 -0
- package/dist/schemas/common.d.ts +171 -94
- package/dist/schemas/completion-stream.d.ts +6 -3
- package/dist/schemas/completion-stream.js +10 -2
- package/dist/schemas/download-asset.d.ts +5 -5
- package/dist/schemas/engine-addon-map.d.ts +1 -1
- package/dist/schemas/engine-addon-map.js +6 -3
- package/dist/schemas/error.js +6 -1
- package/dist/schemas/llamacpp-config.d.ts +27 -8
- package/dist/schemas/llamacpp-config.js +19 -2
- package/dist/schemas/load-model.d.ts +4170 -570
- package/dist/schemas/load-model.js +85 -26
- package/dist/schemas/logging-stream.js +7 -1
- package/dist/schemas/model-src-utils.d.ts +6 -6
- package/dist/schemas/model-types.d.ts +14 -15
- package/dist/schemas/model-types.js +10 -11
- package/dist/schemas/ocr.d.ts +10 -8
- package/dist/schemas/ocr.js +8 -6
- package/dist/schemas/plugin.d.ts +6 -5
- package/dist/schemas/plugin.js +4 -4
- package/dist/schemas/rag.d.ts +4 -4
- package/dist/schemas/registry.d.ts +8 -8
- package/dist/schemas/registry.js +1 -1
- package/dist/schemas/reload-config.d.ts +6 -6
- package/dist/schemas/sdcpp-config.d.ts +12 -12
- package/dist/schemas/sdk-config.d.ts +171 -117
- package/dist/schemas/sdk-config.js +5 -5
- package/dist/schemas/sdk-errors-client.d.ts +1 -0
- package/dist/schemas/sdk-errors-client.js +7 -2
- package/dist/schemas/text-to-speech.d.ts +157 -13
- package/dist/schemas/text-to-speech.js +70 -7
- package/dist/schemas/transcription-config.d.ts +5 -1
- package/dist/schemas/transcription-config.js +2 -0
- package/dist/schemas/transcription.d.ts +3 -0
- package/dist/schemas/transcription.js +2 -1
- package/dist/schemas/translate.d.ts +6 -6
- package/dist/schemas/translate.js +2 -3
- package/dist/schemas/translation-config.d.ts +20 -20
- package/dist/server/bare/hyperswarm.js +3 -3
- package/dist/server/bare/ops/transcribe.js +46 -15
- package/dist/server/bare/plugins/bci-whispercpp-transcription/args.d.ts +3 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/args.js +13 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.d.ts +41 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.js +6 -11
- package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.d.ts +75 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.js +11 -0
- package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.d.ts +16 -10
- package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.js +25 -18
- package/dist/server/bare/plugins/index.d.ts +1 -1
- package/dist/server/bare/plugins/index.js +1 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.d.ts +10 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.js +29 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +4 -22
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +15 -7
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +7 -7
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +2 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +10 -10
- package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +14 -8
- package/dist/server/bare/plugins/tts-ggml/plugin.js +12 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +3 -1
- package/dist/server/bare/registry/logging-stream-registry.d.ts +4 -2
- package/dist/server/bare/registry/logging-stream-registry.js +12 -7
- package/dist/server/bare/registry/model-config-utils.js +2 -2
- package/dist/server/bare/registry/registry-client.js +1 -1
- package/dist/server/bare/runtime-lifecycle.d.ts +9 -0
- package/dist/server/bare/runtime-lifecycle.js +24 -0
- package/dist/server/bare/types/addon-responses.d.ts +1 -0
- package/dist/server/env.js +7 -10
- package/dist/server/plugins/registry.js +2 -4
- package/dist/server/rpc/handlers/load-model/handler.js +2 -4
- package/dist/server/rpc/handlers/load-model/http.js +253 -51
- package/dist/server/rpc/handlers/logging-stream.js +4 -2
- package/dist/server/rpc/handlers/plugin-invoke.js +5 -16
- package/dist/server/utils/completion-normalizer.js +13 -4
- package/dist/server/utils/worker-lock.js +5 -5
- package/dist/server/worker-core.d.ts +1 -1
- package/dist/server/worker-core.js +28 -18
- package/dist/utils/errors-client.d.ts +3 -0
- package/dist/utils/errors-client.js +5 -0
- package/dist/utils/errors-server.d.ts +2 -0
- package/dist/utils/errors-server.js +3 -0
- package/dist/utils/zod-error.d.ts +3 -0
- package/dist/utils/zod-error.js +4 -0
- package/package.json +21 -24
- package/dist/polyfills/bare-globals.d.ts +0 -2
- package/dist/polyfills/bare-globals.js +0 -4
- package/dist/polyfills/bare-globals.noop.d.ts +0 -2
- package/dist/polyfills/bare-globals.noop.js +0 -1
- /package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/ops/ocr-stream.d.ts +0 -0
- /package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/ops/ocr-stream.js +0 -0
|
@@ -21,17 +21,17 @@ try {
|
|
|
21
21
|
throw new Error("FFmpeg not found");
|
|
22
22
|
}
|
|
23
23
|
catch {
|
|
24
|
-
console.error("
|
|
24
|
+
console.error("✖ FFmpeg is required. Install it and try again.");
|
|
25
25
|
process.exit(1);
|
|
26
26
|
}
|
|
27
27
|
let modelId = null;
|
|
28
28
|
let ffmpeg = null;
|
|
29
29
|
async function cleanup() {
|
|
30
|
-
console.log("\n
|
|
30
|
+
console.log("\n▸ Stopping...");
|
|
31
31
|
ffmpeg?.kill();
|
|
32
32
|
if (modelId)
|
|
33
33
|
await unloadModel({ modelId });
|
|
34
|
-
console.log("Done.");
|
|
34
|
+
console.log("▸ Done.");
|
|
35
35
|
}
|
|
36
36
|
process.on("SIGINT", () => {
|
|
37
37
|
void cleanup().finally(() => process.exit(0));
|
|
@@ -40,12 +40,18 @@ process.on("SIGTERM", () => {
|
|
|
40
40
|
void cleanup().finally(() => process.exit(0));
|
|
41
41
|
});
|
|
42
42
|
try {
|
|
43
|
-
console.log("Loading Parakeet (EOU) streaming model...");
|
|
43
|
+
console.log("▸ Loading Parakeet (EOU) streaming model...");
|
|
44
44
|
modelId = await loadModel({
|
|
45
45
|
modelSrc: PARAKEET_EOU_120M_V1_Q8_0,
|
|
46
|
-
onProgress: (p) =>
|
|
46
|
+
onProgress: (p) => {
|
|
47
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
48
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
49
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
50
|
+
if (p.percentage >= 100)
|
|
51
|
+
process.stderr.write("\n");
|
|
52
|
+
},
|
|
47
53
|
});
|
|
48
|
-
console.log("Model loaded
|
|
54
|
+
console.log("▸ Model loaded.");
|
|
49
55
|
ffmpeg = startMicrophone({ sampleRate: SAMPLE_RATE, format: "s16le" });
|
|
50
56
|
const session = await transcribeStream({
|
|
51
57
|
modelId,
|
|
@@ -55,7 +61,7 @@ try {
|
|
|
55
61
|
},
|
|
56
62
|
});
|
|
57
63
|
ffmpeg.stdout.on("data", (chunk) => session.write(chunk));
|
|
58
|
-
console.log("Listening... speak and pause to see transcripts. End-of-turn boundaries fire when the EOU model emits an <EOU> token
|
|
64
|
+
console.log("▸ Listening... speak and pause to see transcripts. End-of-turn boundaries fire when the EOU model emits an <EOU> token.");
|
|
59
65
|
for await (const event of session) {
|
|
60
66
|
switch (event.type) {
|
|
61
67
|
case "text":
|
|
@@ -64,7 +70,7 @@ try {
|
|
|
64
70
|
}
|
|
65
71
|
break;
|
|
66
72
|
case "endOfTurn":
|
|
67
|
-
console.log("\n[endOfTurn] turn boundary detected
|
|
73
|
+
console.log("\n▸ [endOfTurn] turn boundary detected");
|
|
68
74
|
break;
|
|
69
75
|
}
|
|
70
76
|
}
|
|
@@ -72,7 +78,7 @@ try {
|
|
|
72
78
|
process.exit(0);
|
|
73
79
|
}
|
|
74
80
|
catch (error) {
|
|
75
|
-
console.error("
|
|
81
|
+
console.error("✖", error);
|
|
76
82
|
await cleanup();
|
|
77
83
|
process.exit(1);
|
|
78
84
|
}
|
|
@@ -70,20 +70,26 @@ function readS16leFromWav(wavPath) {
|
|
|
70
70
|
const loadOptions = {
|
|
71
71
|
modelType: "parakeet-transcription",
|
|
72
72
|
modelConfig: { ...SORTFORMER_V21_AOSC_LOAD_CONFIG },
|
|
73
|
-
onProgress: (p) =>
|
|
73
|
+
onProgress: (p) => {
|
|
74
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
75
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
76
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
77
|
+
if (p.percentage >= 100)
|
|
78
|
+
process.stderr.write("\n");
|
|
79
|
+
},
|
|
74
80
|
...(sortformerOverride
|
|
75
81
|
? { modelSrc: sortformerOverride }
|
|
76
82
|
: { modelSrc: PARAKEET_SORTFORMER_4SPK_V2_1_Q8_0 }),
|
|
77
83
|
};
|
|
78
84
|
try {
|
|
79
|
-
console.log("Loading Sortformer v2.1 with streaming + AOSC (load-time config)...");
|
|
85
|
+
console.log("▸ Loading Sortformer v2.1 with streaming + AOSC (load-time config)...");
|
|
80
86
|
modelId = await loadModel(loadOptions);
|
|
81
|
-
console.log(
|
|
87
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
82
88
|
const session = await transcribeStream({
|
|
83
89
|
modelId,
|
|
84
90
|
parakeetStreamingConfig: { chunkMs: STREAM_CHUNK_MS },
|
|
85
91
|
});
|
|
86
|
-
console.log(
|
|
92
|
+
console.log(`▸ Streaming ${audioFilePath} in ${STREAM_CHUNK_MS}ms chunks (wall-clock paced)...`);
|
|
87
93
|
const pcm = await readS16leFromWav(audioFilePath);
|
|
88
94
|
const trailingSilenceMs = 1500;
|
|
89
95
|
const trailingBytes = new Uint8Array(Math.floor((trailingSilenceMs / 1000) * SAMPLE_RATE) * BYTES_PER_S16_SAMPLE);
|
|
@@ -109,13 +115,13 @@ try {
|
|
|
109
115
|
console.log(event.text.trim());
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
|
-
console.log("\n
|
|
118
|
+
console.log("\n▸ Streaming diarization transcript");
|
|
113
119
|
console.log(lines.join("\n") || "(no speaker lines emitted)");
|
|
114
120
|
await cleanup();
|
|
115
121
|
process.exit(0);
|
|
116
122
|
}
|
|
117
123
|
catch (error) {
|
|
118
|
-
console.error("
|
|
124
|
+
console.error("✖", error);
|
|
119
125
|
await cleanup();
|
|
120
126
|
process.exit(1);
|
|
121
127
|
}
|
|
@@ -59,17 +59,15 @@ try {
|
|
|
59
59
|
await unloadModel({ modelId: tdtModelId });
|
|
60
60
|
// ── Step 3: Merge consecutive same-speaker segments and print ──
|
|
61
61
|
const merged = mergeSpeakers(results);
|
|
62
|
-
console.log("\n
|
|
63
|
-
console.log("=".repeat(60));
|
|
62
|
+
console.log("\n▸ Diarized transcription");
|
|
64
63
|
for (const entry of merged) {
|
|
65
64
|
console.log(`Speaker ${entry.speaker} (${entry.start.toFixed(2)}s - ${entry.end.toFixed(2)}s):`);
|
|
66
65
|
console.log(` ${entry.text}\n`);
|
|
67
66
|
}
|
|
68
|
-
console.log("
|
|
69
|
-
console.log("\nDone!");
|
|
67
|
+
console.log("▸ Done");
|
|
70
68
|
}
|
|
71
69
|
catch (error) {
|
|
72
|
-
console.error("
|
|
70
|
+
console.error("✖", error);
|
|
73
71
|
process.exit(1);
|
|
74
72
|
}
|
|
75
73
|
// ── Helpers ──
|
|
@@ -21,25 +21,28 @@ if (!args[0]) {
|
|
|
21
21
|
const audioFilePath = args[0];
|
|
22
22
|
const parakeetModelSrc = args[1] ?? PARAKEET_TDT_0_6B_V3_Q8_0;
|
|
23
23
|
try {
|
|
24
|
-
console.log("Starting Parakeet transcription example...");
|
|
25
|
-
console.log("Loading Parakeet model...");
|
|
24
|
+
console.log("▸ Starting Parakeet transcription example...");
|
|
25
|
+
console.log("▸ Loading Parakeet model...");
|
|
26
26
|
const modelId = await loadModel({
|
|
27
27
|
modelSrc: parakeetModelSrc,
|
|
28
28
|
modelType: "parakeet-transcription",
|
|
29
|
-
onProgress: (
|
|
30
|
-
|
|
29
|
+
onProgress: (p) => {
|
|
30
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
31
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
32
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
33
|
+
if (p.percentage >= 100)
|
|
34
|
+
process.stderr.write("\n");
|
|
31
35
|
},
|
|
32
36
|
});
|
|
33
|
-
console.log(
|
|
34
|
-
console.log("Transcribing audio...");
|
|
37
|
+
console.log(`▸ Parakeet model loaded with ID: ${modelId}`);
|
|
38
|
+
console.log("▸ Transcribing audio...");
|
|
35
39
|
const text = await transcribe({ modelId, audioChunk: audioFilePath });
|
|
36
|
-
console.log("Transcription result:");
|
|
37
40
|
console.log(text);
|
|
38
|
-
console.log("Unloading Parakeet model...");
|
|
41
|
+
console.log("▸ Unloading Parakeet model...");
|
|
39
42
|
await unloadModel({ modelId });
|
|
40
|
-
console.log("Parakeet model unloaded successfully");
|
|
43
|
+
console.log("▸ Parakeet model unloaded successfully");
|
|
41
44
|
}
|
|
42
45
|
catch (error) {
|
|
43
|
-
console.error("
|
|
46
|
+
console.error("✖", error);
|
|
44
47
|
process.exit(1);
|
|
45
48
|
}
|
|
@@ -23,10 +23,10 @@ const SAMPLE_RATE = 16000;
|
|
|
23
23
|
const BYTES_PER_SAMPLE = 4; // f32le
|
|
24
24
|
const CHUNK_SIZE = Math.floor(0.1 * SAMPLE_RATE) * BYTES_PER_SAMPLE; // 100ms chunks
|
|
25
25
|
try {
|
|
26
|
-
console.log("
|
|
27
|
-
console.log(
|
|
28
|
-
console.log(
|
|
29
|
-
console.log("Loading model...");
|
|
26
|
+
console.log("▸ transcribeStream file test");
|
|
27
|
+
console.log(`▸ File: ${SAMPLE_FILE}`);
|
|
28
|
+
console.log(`▸ Chunk size: ${CHUNK_SIZE} bytes (100ms)`);
|
|
29
|
+
console.log("▸ Loading model...");
|
|
30
30
|
const modelId = await loadModel({
|
|
31
31
|
modelSrc: WHISPER_TINY,
|
|
32
32
|
modelConfig: {
|
|
@@ -48,10 +48,10 @@ try {
|
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
50
|
});
|
|
51
|
-
console.log(
|
|
52
|
-
console.log("Opening live session...");
|
|
51
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
52
|
+
console.log("▸ Opening live session...");
|
|
53
53
|
const session = await transcribeStream({ modelId, metadata: true });
|
|
54
|
-
console.log("Session open. Streaming audio
|
|
54
|
+
console.log("▸ Session open. Streaming audio...");
|
|
55
55
|
const ffmpeg = spawn("ffmpeg", [
|
|
56
56
|
"-i",
|
|
57
57
|
SAMPLE_FILE,
|
|
@@ -75,8 +75,8 @@ try {
|
|
|
75
75
|
});
|
|
76
76
|
ffmpeg.on("close", () => {
|
|
77
77
|
const durationSec = totalBytes / (SAMPLE_RATE * BYTES_PER_SAMPLE);
|
|
78
|
-
console.log(
|
|
79
|
-
console.log("Waiting for transcription
|
|
78
|
+
console.log(`▸ Audio streamed: ${totalBytes} bytes (~${durationSec.toFixed(1)}s)`);
|
|
79
|
+
console.log("▸ Waiting for transcription...");
|
|
80
80
|
session.end();
|
|
81
81
|
});
|
|
82
82
|
const segments = [];
|
|
@@ -84,22 +84,21 @@ try {
|
|
|
84
84
|
segments.push(segment);
|
|
85
85
|
const start = (segment.startMs / 1000).toFixed(2);
|
|
86
86
|
const end = (segment.endMs / 1000).toFixed(2);
|
|
87
|
-
console.log(
|
|
87
|
+
console.log(`▸ [${segments.length}] [${start}s → ${end}s] (id=${segment.id}, append=${segment.append}) ${segment.text.trim()}`);
|
|
88
88
|
}
|
|
89
|
-
console.log(
|
|
90
|
-
console.log(`Segments: ${segments.length}`);
|
|
89
|
+
console.log(`\n▸ Segments: ${segments.length}`);
|
|
91
90
|
if (segments.length > 0) {
|
|
92
|
-
console.log(
|
|
91
|
+
console.log(segments.map((s) => s.text.trim()).join(" "));
|
|
93
92
|
}
|
|
94
93
|
else {
|
|
95
|
-
console.log("
|
|
94
|
+
console.log("▸ No transcription segments received!");
|
|
96
95
|
}
|
|
97
|
-
console.log("
|
|
96
|
+
console.log("▸ Unloading model...");
|
|
98
97
|
await unloadModel({ modelId });
|
|
99
|
-
console.log("Done.");
|
|
98
|
+
console.log("▸ Done.");
|
|
100
99
|
process.exit(0);
|
|
101
100
|
}
|
|
102
101
|
catch (error) {
|
|
103
|
-
console.error("
|
|
102
|
+
console.error("✖", error);
|
|
104
103
|
process.exit(1);
|
|
105
104
|
}
|
|
@@ -7,9 +7,9 @@ if (!args[0]) {
|
|
|
7
7
|
}
|
|
8
8
|
const audioFilePath = args[0];
|
|
9
9
|
try {
|
|
10
|
-
console.log("
|
|
10
|
+
console.log("▸ Starting Whisper transcription example...");
|
|
11
11
|
// Load the Whisper model
|
|
12
|
-
console.log("
|
|
12
|
+
console.log("▸ Loading Whisper model...");
|
|
13
13
|
const modelId = await loadModel({
|
|
14
14
|
modelSrc: WHISPER_TINY,
|
|
15
15
|
modelConfig: {
|
|
@@ -47,19 +47,23 @@ try {
|
|
|
47
47
|
gpu_device: 0,
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
|
-
onProgress: (
|
|
51
|
-
|
|
50
|
+
onProgress: (p) => {
|
|
51
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
52
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
53
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
54
|
+
if (p.percentage >= 100)
|
|
55
|
+
process.stderr.write("\n");
|
|
52
56
|
},
|
|
53
57
|
});
|
|
54
|
-
console.log(
|
|
58
|
+
console.log(`▸ Whisper model loaded with ID: ${modelId}`);
|
|
55
59
|
// Perform transcription with per-segment metadata
|
|
56
|
-
console.log("
|
|
60
|
+
console.log("▸ Transcribing audio...");
|
|
57
61
|
const segments = await transcribe({
|
|
58
62
|
modelId,
|
|
59
63
|
audioChunk: audioFilePath,
|
|
60
64
|
metadata: true,
|
|
61
65
|
});
|
|
62
|
-
console.log("
|
|
66
|
+
console.log("▸ Transcription result:");
|
|
63
67
|
for (const segment of segments) {
|
|
64
68
|
const start = (segment.startMs / 1000).toFixed(2);
|
|
65
69
|
const end = (segment.endMs / 1000).toFixed(2);
|
|
@@ -70,11 +74,11 @@ try {
|
|
|
70
74
|
.join("")
|
|
71
75
|
.trim()}`);
|
|
72
76
|
// Unload the model when done
|
|
73
|
-
console.log("
|
|
77
|
+
console.log("▸ Unloading Whisper model...");
|
|
74
78
|
await unloadModel({ modelId });
|
|
75
|
-
console.log("
|
|
79
|
+
console.log("▸ Whisper model unloaded successfully");
|
|
76
80
|
}
|
|
77
81
|
catch (error) {
|
|
78
|
-
console.error("
|
|
82
|
+
console.error("✖", error);
|
|
79
83
|
process.exit(1);
|
|
80
84
|
}
|
|
@@ -26,17 +26,17 @@ try {
|
|
|
26
26
|
throw new Error("FFmpeg not found");
|
|
27
27
|
}
|
|
28
28
|
catch {
|
|
29
|
-
console.error("
|
|
29
|
+
console.error("✖ FFmpeg is required. Install it and try again.");
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
32
|
let modelId = null;
|
|
33
33
|
let ffmpeg = null;
|
|
34
34
|
async function cleanup() {
|
|
35
|
-
console.log("\n\
|
|
35
|
+
console.log("\n\n▸ Stopping...");
|
|
36
36
|
ffmpeg?.kill();
|
|
37
37
|
if (modelId)
|
|
38
38
|
await unloadModel({ modelId });
|
|
39
|
-
console.log("Done.");
|
|
39
|
+
console.log("▸ Done.");
|
|
40
40
|
}
|
|
41
41
|
process.on("SIGINT", () => {
|
|
42
42
|
void cleanup().finally(() => process.exit(0));
|
|
@@ -45,7 +45,7 @@ process.on("SIGTERM", () => {
|
|
|
45
45
|
void cleanup().finally(() => process.exit(0));
|
|
46
46
|
});
|
|
47
47
|
try {
|
|
48
|
-
console.log("Loading model (whisper-tiny + Silero VAD)...");
|
|
48
|
+
console.log("▸ Loading model (whisper-tiny + Silero VAD)...");
|
|
49
49
|
modelId = await loadModel({
|
|
50
50
|
modelSrc: WHISPER_TINY,
|
|
51
51
|
modelConfig: {
|
|
@@ -67,7 +67,7 @@ try {
|
|
|
67
67
|
},
|
|
68
68
|
},
|
|
69
69
|
});
|
|
70
|
-
console.log("Model loaded.\n");
|
|
70
|
+
console.log("▸ Model loaded.\n");
|
|
71
71
|
ffmpeg = startMicrophone({ sampleRate: SAMPLE_RATE, format: "f32le" });
|
|
72
72
|
const session = await transcribeStream({
|
|
73
73
|
modelId,
|
|
@@ -75,7 +75,7 @@ try {
|
|
|
75
75
|
endOfTurnSilenceMs: 800,
|
|
76
76
|
});
|
|
77
77
|
ffmpeg.stdout.on("data", (chunk) => session.write(chunk));
|
|
78
|
-
console.log("Listening... speak and pause to see transcripts, VAD events, and end-of-turn signals.\n");
|
|
78
|
+
console.log("▸ Listening... speak and pause to see transcripts, VAD events, and end-of-turn signals.\n");
|
|
79
79
|
let lastSpeaking = false;
|
|
80
80
|
for await (const event of session) {
|
|
81
81
|
switch (event.type) {
|
|
@@ -84,23 +84,23 @@ try {
|
|
|
84
84
|
break;
|
|
85
85
|
case "vad":
|
|
86
86
|
if (event.speaking !== lastSpeaking) {
|
|
87
|
-
console.log(
|
|
87
|
+
console.log(`▸ [vad] speaking=${event.speaking} probability=${event.probability.toFixed(2)}`);
|
|
88
88
|
lastSpeaking = event.speaking;
|
|
89
89
|
}
|
|
90
90
|
break;
|
|
91
91
|
case "endOfTurn":
|
|
92
92
|
if (event.source === "whisper") {
|
|
93
|
-
console.log(
|
|
93
|
+
console.log(`▸ [endOfTurn] silence ${event.silenceDurationMs}ms — turn complete\n`);
|
|
94
94
|
}
|
|
95
95
|
else {
|
|
96
|
-
console.log(
|
|
96
|
+
console.log(`▸ [endOfTurn] turn complete (token-driven EOU)\n`);
|
|
97
97
|
}
|
|
98
98
|
break;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
catch (error) {
|
|
103
|
-
console.error("
|
|
103
|
+
console.error("✖", error);
|
|
104
104
|
await cleanup();
|
|
105
105
|
process.exit(1);
|
|
106
106
|
}
|
|
@@ -19,10 +19,10 @@ try {
|
|
|
19
19
|
throw new Error("FFmpeg not found");
|
|
20
20
|
}
|
|
21
21
|
catch {
|
|
22
|
-
console.error("FFmpeg is required. Install it and try again.");
|
|
22
|
+
console.error("✖ FFmpeg is required. Install it and try again.");
|
|
23
23
|
process.exit(1);
|
|
24
24
|
}
|
|
25
|
-
console.log("Loading model (whisper-tiny + Silero VAD)...");
|
|
25
|
+
console.log("▸ Loading model (whisper-tiny + Silero VAD)...");
|
|
26
26
|
const modelId = await loadModel({
|
|
27
27
|
modelSrc: WHISPER_TINY,
|
|
28
28
|
modelConfig: {
|
|
@@ -44,22 +44,22 @@ const modelId = await loadModel({
|
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
46
|
});
|
|
47
|
-
console.log("Model loaded.\n");
|
|
47
|
+
console.log("▸ Model loaded.\n");
|
|
48
48
|
const ffmpeg = startMicrophone({
|
|
49
49
|
sampleRate: SAMPLE_RATE,
|
|
50
50
|
format: "f32le",
|
|
51
51
|
});
|
|
52
52
|
const session = await transcribeStream({ modelId });
|
|
53
53
|
ffmpeg.stdout.on("data", (chunk) => session.write(chunk));
|
|
54
|
-
console.log("Listening... speak and pause to see transcriptions.\n");
|
|
54
|
+
console.log("▸ Listening... speak and pause to see transcriptions.\n");
|
|
55
55
|
for await (const text of session) {
|
|
56
56
|
console.log(`> ${text.trim()}`);
|
|
57
57
|
}
|
|
58
58
|
async function cleanup() {
|
|
59
|
-
console.log("\n\
|
|
59
|
+
console.log("\n\n▸ Stopping...");
|
|
60
60
|
ffmpeg.kill();
|
|
61
61
|
await unloadModel({ modelId });
|
|
62
|
-
console.log("Done.");
|
|
62
|
+
console.log("▸ Done.");
|
|
63
63
|
}
|
|
64
64
|
process.on("SIGINT", () => void cleanup());
|
|
65
65
|
process.on("SIGTERM", () => void cleanup());
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { loadModel, unloadModel, transcribe, WHISPER_TINY } from "@qvac/sdk";
|
|
13
13
|
try {
|
|
14
|
-
console.log("
|
|
14
|
+
console.log("▸ Starting Whisper transcription with prompt example...");
|
|
15
15
|
// Load the Whisper model
|
|
16
|
-
console.log("
|
|
16
|
+
console.log("▸ Loading Whisper model...");
|
|
17
17
|
const modelId = await loadModel({
|
|
18
18
|
modelSrc: WHISPER_TINY,
|
|
19
19
|
modelConfig: {
|
|
@@ -51,27 +51,31 @@ try {
|
|
|
51
51
|
gpu_device: 0,
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
|
-
onProgress: (
|
|
55
|
-
|
|
54
|
+
onProgress: (p) => {
|
|
55
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
56
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
57
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
58
|
+
if (p.percentage >= 100)
|
|
59
|
+
process.stderr.write("\n");
|
|
56
60
|
},
|
|
57
61
|
});
|
|
58
|
-
console.log(
|
|
62
|
+
console.log(`▸ Whisper model loaded with ID: ${modelId}`);
|
|
59
63
|
// Perform transcription
|
|
60
|
-
console.log("
|
|
64
|
+
console.log("▸ Transcribing audio...");
|
|
61
65
|
const text = await transcribe({
|
|
62
66
|
modelId,
|
|
63
67
|
audioChunk: "examples/audio/sample-16khz.wav",
|
|
64
68
|
prompt: "This is a test recording with clear speech and proper punctuation.",
|
|
65
69
|
});
|
|
66
|
-
console.log("
|
|
70
|
+
console.log("▸ Transcription result:");
|
|
67
71
|
console.log(text);
|
|
68
72
|
// Unload the model when done
|
|
69
|
-
console.log("
|
|
73
|
+
console.log("▸ Unloading Whisper model...");
|
|
70
74
|
await unloadModel({ modelId });
|
|
71
|
-
console.log("
|
|
75
|
+
console.log("▸ Whisper model unloaded successfully");
|
|
72
76
|
process.exit(0);
|
|
73
77
|
}
|
|
74
78
|
catch (error) {
|
|
75
|
-
console.error("
|
|
79
|
+
console.error("✖", error);
|
|
76
80
|
process.exit(1);
|
|
77
81
|
}
|
|
@@ -12,11 +12,15 @@ try {
|
|
|
12
12
|
norepeatngramsize: 3,
|
|
13
13
|
lengthpenalty: 1.2,
|
|
14
14
|
},
|
|
15
|
-
onProgress: (
|
|
16
|
-
|
|
15
|
+
onProgress: (p) => {
|
|
16
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
17
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
18
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
19
|
+
if (p.percentage >= 100)
|
|
20
|
+
process.stderr.write("\n");
|
|
17
21
|
},
|
|
18
22
|
});
|
|
19
|
-
console.log(
|
|
23
|
+
console.log(`▸ Bergamot model loaded: ${modelId}`);
|
|
20
24
|
// Test with array of texts for batch processing
|
|
21
25
|
const texts = [
|
|
22
26
|
"Hello world",
|
|
@@ -24,8 +28,8 @@ try {
|
|
|
24
28
|
"This is a test of batch translation",
|
|
25
29
|
"The weather is nice",
|
|
26
30
|
];
|
|
27
|
-
console.log("
|
|
28
|
-
texts.forEach((text, i) => console.log(
|
|
31
|
+
console.log("▸ Translating batch of texts:");
|
|
32
|
+
texts.forEach((text, i) => console.log(`▸ ${i + 1}. ${text}`));
|
|
29
33
|
const result = translate({
|
|
30
34
|
modelId,
|
|
31
35
|
text: texts, // Pass array for batch processing
|
|
@@ -34,7 +38,7 @@ try {
|
|
|
34
38
|
});
|
|
35
39
|
const translatedText = await result.text;
|
|
36
40
|
const translations = translatedText.split("\n");
|
|
37
|
-
console.log("
|
|
41
|
+
console.log("▸ Translations:");
|
|
38
42
|
translations.forEach((translation, i) => {
|
|
39
43
|
if (i < texts.length) {
|
|
40
44
|
console.log(` ${i + 1}. ${texts[i]} -> "${translation}"`);
|
|
@@ -43,6 +47,6 @@ try {
|
|
|
43
47
|
await unloadModel({ modelId });
|
|
44
48
|
}
|
|
45
49
|
catch (error) {
|
|
46
|
-
console.error("
|
|
50
|
+
console.error("✖", error);
|
|
47
51
|
process.exit(1);
|
|
48
52
|
}
|
|
@@ -36,18 +36,22 @@ try {
|
|
|
36
36
|
lengthpenalty: 1.2,
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
|
-
onProgress: (
|
|
40
|
-
|
|
39
|
+
onProgress: (p) => {
|
|
40
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
41
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
42
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
43
|
+
if (p.percentage >= 100)
|
|
44
|
+
process.stderr.write("\n");
|
|
41
45
|
},
|
|
42
46
|
});
|
|
43
|
-
console.log(
|
|
44
|
-
console.log("
|
|
45
|
-
console.log("
|
|
47
|
+
console.log(`▸ Pivot translation model loaded: ${modelId}`);
|
|
48
|
+
console.log("▸ Primary: Spanish → English");
|
|
49
|
+
console.log("▸ Pivot: English → Italian");
|
|
46
50
|
// Spanish text to translate
|
|
47
51
|
const spanishText = `Era una mañana soleada cuando María decidió visitar el mercado local.
|
|
48
52
|
Compró frutas frescas, verduras y flores para su casa.
|
|
49
53
|
El vendedor le recomendó las mejores manzanas de la temporada.`;
|
|
50
|
-
console.log("
|
|
54
|
+
console.log("▸ Original Spanish text:");
|
|
51
55
|
console.log(spanishText);
|
|
52
56
|
// Translate Spanish → English → Italian
|
|
53
57
|
const result = translate({
|
|
@@ -57,16 +61,16 @@ try {
|
|
|
57
61
|
stream: false,
|
|
58
62
|
});
|
|
59
63
|
const italianText = await result.text;
|
|
60
|
-
console.log("
|
|
64
|
+
console.log("▸ Translated to Italian (via English):");
|
|
61
65
|
console.log(italianText);
|
|
62
66
|
// Expected output (approximate):
|
|
63
67
|
// "Era una mattina di sole quando Maria decise di visitare il mercato locale.
|
|
64
68
|
// Ha comprato frutta fresca, verdura e fiori per la sua casa.
|
|
65
69
|
// Il venditore ha consigliato le migliori mele della stagione."
|
|
66
70
|
await unloadModel({ modelId });
|
|
67
|
-
console.log("
|
|
71
|
+
console.log("▸ Model unloaded successfully");
|
|
68
72
|
}
|
|
69
73
|
catch (error) {
|
|
70
|
-
console.error("
|
|
74
|
+
console.error("✖", error);
|
|
71
75
|
process.exit(1);
|
|
72
76
|
}
|
|
@@ -16,11 +16,15 @@ try {
|
|
|
16
16
|
norepeatngramsize: 3,
|
|
17
17
|
lengthpenalty: 1.2,
|
|
18
18
|
},
|
|
19
|
-
onProgress: (
|
|
20
|
-
|
|
19
|
+
onProgress: (p) => {
|
|
20
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
21
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
22
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
23
|
+
if (p.percentage >= 100)
|
|
24
|
+
process.stderr.write("\n");
|
|
21
25
|
},
|
|
22
26
|
});
|
|
23
|
-
console.log(
|
|
27
|
+
console.log(`▸ Bergamot model loaded: ${modelId}`);
|
|
24
28
|
const text = "This is a test of the Bergamot translation model.";
|
|
25
29
|
const result = translate({
|
|
26
30
|
modelId,
|
|
@@ -33,6 +37,6 @@ try {
|
|
|
33
37
|
await unloadModel({ modelId });
|
|
34
38
|
}
|
|
35
39
|
catch (error) {
|
|
36
|
-
console.error("
|
|
40
|
+
console.error("✖", error);
|
|
37
41
|
process.exit(1);
|
|
38
42
|
}
|
|
@@ -5,8 +5,12 @@ import { loadModel, translate, unloadModel, MARIAN_EN_HI_INDIC_1B_Q4_0, } from "
|
|
|
5
5
|
try {
|
|
6
6
|
const modelId = await loadModel({
|
|
7
7
|
modelSrc: MARIAN_EN_HI_INDIC_1B_Q4_0,
|
|
8
|
-
onProgress: (
|
|
9
|
-
|
|
8
|
+
onProgress: (p) => {
|
|
9
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
10
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
11
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
12
|
+
if (p.percentage >= 100)
|
|
13
|
+
process.stderr.write("\n");
|
|
10
14
|
},
|
|
11
15
|
modelConfig: {
|
|
12
16
|
engine: "IndicTrans",
|
|
@@ -14,7 +18,7 @@ try {
|
|
|
14
18
|
to: "hin_Deva",
|
|
15
19
|
},
|
|
16
20
|
});
|
|
17
|
-
console.log(
|
|
21
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
18
22
|
const text = "Hello, how are you today?";
|
|
19
23
|
const result = translate({
|
|
20
24
|
modelId,
|
|
@@ -27,6 +31,6 @@ try {
|
|
|
27
31
|
await unloadModel({ modelId });
|
|
28
32
|
}
|
|
29
33
|
catch (error) {
|
|
30
|
-
console.error("
|
|
34
|
+
console.error("✖", error);
|
|
31
35
|
process.exit(1);
|
|
32
36
|
}
|
|
@@ -2,8 +2,12 @@ import { translate, loadModel, unloadModel, AFRICAN_4B_TRANSLATION_Q4_K_M, } fro
|
|
|
2
2
|
try {
|
|
3
3
|
const modelId = await loadModel({
|
|
4
4
|
modelSrc: AFRICAN_4B_TRANSLATION_Q4_K_M,
|
|
5
|
-
onProgress: (
|
|
6
|
-
|
|
5
|
+
onProgress: (p) => {
|
|
6
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
7
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
8
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
9
|
+
if (p.percentage >= 100)
|
|
10
|
+
process.stderr.write("\n");
|
|
7
11
|
},
|
|
8
12
|
// IMPORTANT: these parameters are validated to be optimal
|
|
9
13
|
modelConfig: {
|
|
@@ -33,6 +37,6 @@ try {
|
|
|
33
37
|
await unloadModel({ modelId, clearStorage: false });
|
|
34
38
|
}
|
|
35
39
|
catch (error) {
|
|
36
|
-
console.error("
|
|
40
|
+
console.error("✖", error);
|
|
37
41
|
process.exit(1);
|
|
38
42
|
}
|