@qvac/sdk 0.20.1 → 0.21.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/NOTICE +76 -13
- package/README.md +39 -5
- package/dist/examples/advisory-model-fit.d.ts +17 -16
- package/dist/examples/advisory-model-fit.js +18 -18
- package/dist/examples/asr/parakeet-indic-conformer-filesystem.js +3 -3
- package/dist/examples/asr/parakeet-unified-coreml.d.ts +2 -0
- package/dist/examples/asr/parakeet-unified-coreml.js +113 -0
- package/dist/examples/assess-model-fit.js +9 -4
- package/dist/examples/model-fit-ui/server.js +5 -2
- package/dist/examples/rpc-inference.d.ts +2 -0
- package/dist/examples/rpc-inference.js +51 -0
- package/dist/examples/rpc-server.d.ts +2 -0
- package/dist/examples/rpc-server.js +32 -0
- package/dist/examples/tools/llamacpp-deferred-tools.d.ts +2 -0
- package/dist/examples/tools/llamacpp-deferred-tools.js +77 -0
- package/dist/examples/tts/audio8.js +4 -0
- package/dist/examples/tts/moss-dialogue.d.ts +2 -0
- package/dist/examples/tts/moss-dialogue.js +63 -0
- package/dist/examples/tts/moss.d.ts +2 -0
- package/dist/examples/tts/moss.js +71 -0
- package/dist/scripts/contract/build-contract.d.ts +2 -1
- package/dist/scripts/contract/build-contract.js +4 -1
- package/dist/scripts/contract/build-numeric-constants.d.ts +15 -0
- package/dist/scripts/contract/build-numeric-constants.js +13 -0
- package/dist/scripts/contract/method-shapes.d.ts +3 -0
- package/dist/scripts/contract/method-shapes.js +3 -0
- package/dist/scripts/enforce-inference-versions.d.ts +18 -0
- package/dist/scripts/enforce-inference-versions.js +158 -0
- package/dist/scripts/generate-bare-kit-runtimes.d.ts +2 -0
- package/dist/scripts/generate-bare-kit-runtimes.js +106 -0
- package/dist/src/client/api/assess-model-fit.d.ts +5 -4
- package/dist/src/client/api/assess-model-fit.js +24 -7
- package/dist/src/client/api/bci-transcribe.d.ts +4 -1
- package/dist/src/client/api/get-system-resources.d.ts +8 -0
- package/dist/src/client/api/get-system-resources.js +8 -0
- package/dist/src/client/api/index.d.ts +1 -0
- package/dist/src/client/api/index.js +1 -0
- package/dist/src/client/api/rpc-server.d.ts +20 -0
- package/dist/src/client/api/rpc-server.js +45 -0
- package/dist/src/client/api/text-to-speech.d.ts +9 -0
- package/dist/src/client/api/text-to-speech.js +9 -0
- package/dist/src/client/api/transcribe.d.ts +21 -15
- package/dist/src/client/api/transcribe.js +65 -20
- package/dist/src/client/rpc/rpc-error.js +11 -7
- package/dist/src/commands/bundle/entry-gen.d.ts +2 -2
- package/dist/src/commands/bundle/entry-gen.js +8 -4
- package/dist/src/commands/bundle/index.d.ts +20 -0
- package/dist/src/commands/bundle/index.js +88 -12
- package/dist/src/commands/bundle/plugins.js +1 -1
- package/dist/src/commands/command-logger.d.ts +6 -0
- package/dist/src/commands/command-logger.js +12 -0
- package/dist/src/commands/host-prebuilds/index.d.ts +71 -0
- package/dist/src/commands/host-prebuilds/index.js +227 -0
- package/dist/src/commands/host-prebuilds/package-manager.d.ts +54 -0
- package/dist/src/commands/host-prebuilds/package-manager.js +278 -0
- package/dist/src/commands/index.d.ts +10 -1
- package/dist/src/commands/index.js +6 -0
- package/dist/src/commands/verify/abi.d.ts +22 -2
- package/dist/src/commands/verify/abi.js +49 -27
- package/dist/src/commands/verify/addon-source.d.ts +22 -0
- package/dist/src/commands/verify/addon-source.js +69 -3
- package/dist/src/commands/verify/bare-kit-runtime.d.ts +38 -0
- package/dist/src/commands/verify/bare-kit-runtime.js +201 -0
- package/dist/src/commands/verify/bare-kit-runtimes.d.ts +12 -0
- package/dist/src/commands/verify/bare-kit-runtimes.js +108 -0
- package/dist/src/commands/verify/bundle-source.js +16 -15
- package/dist/src/commands/verify/engines-advice.d.ts +73 -0
- package/dist/src/commands/verify/engines-advice.js +271 -0
- package/dist/src/commands/verify/index.d.ts +22 -0
- package/dist/src/commands/verify/index.js +151 -13
- package/dist/src/commands/verify/node-modules-source.js +43 -39
- package/dist/src/commands/verify/prebuilds.d.ts +19 -0
- package/dist/src/commands/verify/prebuilds.js +52 -13
- package/dist/src/expo/plugins/index.d.ts +2 -0
- package/dist/src/expo/plugins/withMobileBundle.d.ts +15 -5
- package/dist/src/expo/plugins/withMobileBundle.js +68 -42
- package/dist/src/expo/plugins/withQvacSDK.d.ts +7 -1
- package/dist/src/expo/plugins/withQvacSDK.js +6 -3
- package/dist/src/index.d.ts +5 -2
- package/dist/src/index.js +4 -2
- package/dist/src/schemas/sdk-errors-client.d.ts +2 -0
- package/dist/src/schemas/sdk-errors-client.js +16 -0
- package/dist/src/schemas/sdk-errors-server.d.ts +1 -0
- package/dist/src/schemas/sdk-errors-server.js +5 -0
- package/dist/src/utils/errors-client.d.ts +15 -0
- package/dist/src/utils/errors-client.js +26 -0
- package/dist/src/utils/errors-server.d.ts +1 -0
- package/dist/src/utils/errors-server.js +1 -0
- package/dist/src/utils/mcp-adapter.js +7 -1
- package/dist/src/utils/tool-helpers.d.ts +4 -0
- package/dist/src/utils/tool-helpers.js +2 -0
- package/dist/src/worker/ggml-rpc-server-provider.d.ts +2 -0
- package/dist/src/worker/ggml-rpc-server-provider.js +1 -0
- package/dist/src/worker/rpc-server-provider.d.ts +3 -0
- package/dist/src/worker/rpc-server-provider.js +1 -0
- package/package.json +30 -25
- package/dist/scripts/enforce-inference-peer-dependencies.d.ts +0 -2
- package/dist/scripts/enforce-inference-peer-dependencies.js +0 -39
- package/dist/src/deprecate.d.ts +0 -2
- package/dist/src/deprecate.js +0 -9
- package/dist/src/worker/legacy-worker-entry.d.ts +0 -2
- package/dist/src/worker/legacy-worker-entry.js +0 -3
- package/dist/src/worker/worker-core.d.ts +0 -7
- package/dist/src/worker/worker-core.js +0 -8
package/NOTICE
CHANGED
|
@@ -71,6 +71,8 @@ Third-Party Model Licenses
|
|
|
71
71
|
https://huggingface.co/Audio8/Audio8-TTS-Preview-0.6b
|
|
72
72
|
bci-embedder
|
|
73
73
|
https://github.com/tetherto/qvac/releases/download/bci-test-assets-v0.1.0/bci-embedder.bin
|
|
74
|
+
coremldata
|
|
75
|
+
https://huggingface.co/Audio8/Audio8-TTS-Preview-0.6b
|
|
74
76
|
cosyvoice3-campplus-f32
|
|
75
77
|
https://huggingface.co/FunAudioLLM/Fun-CosyVoice3-0.5B-2512
|
|
76
78
|
cosyvoice3-flow-bf16
|
|
@@ -136,7 +138,7 @@ Third-Party Model Licenses
|
|
|
136
138
|
LightOnOCR-2-1B-ocr-soup-GGUF
|
|
137
139
|
https://huggingface.co/noctrex/LightOnOCR-2-1B-ocr-soup-GGUF
|
|
138
140
|
Llama_3.2_1B_Intruct_Tool_Calling_V2-GGUF
|
|
139
|
-
https://huggingface.co/
|
|
141
|
+
https://huggingface.co/mradermacher/Llama_3.2_1B_Intruct_Tool_Calling_V2-GGUF
|
|
140
142
|
MedPsy-1.7B-GGUF
|
|
141
143
|
https://huggingface.co/qvac/MedPsy-1.7B-GGUF
|
|
142
144
|
MedPsy-4B-GGUF
|
|
@@ -145,6 +147,14 @@ Third-Party Model Licenses
|
|
|
145
147
|
https://huggingface.co/FunAudioLLM/Fun-CosyVoice3-0.5B-2512
|
|
146
148
|
mmproj-unlimited-ocr-Q8_0
|
|
147
149
|
https://huggingface.co/baidu/Unlimited-OCR
|
|
150
|
+
model
|
|
151
|
+
https://huggingface.co/Audio8/Audio8-TTS-Preview-0.6b
|
|
152
|
+
moss-codec-decoder-f16
|
|
153
|
+
https://huggingface.co/OpenMOSS-Team/MOSS-TTS
|
|
154
|
+
moss-codec-encoder-f16
|
|
155
|
+
https://huggingface.co/OpenMOSS-Team/MOSS-TTS
|
|
156
|
+
moss-tts-delay-f16
|
|
157
|
+
https://huggingface.co/OpenMOSS-Team/MOSS-TTS
|
|
148
158
|
nb-tiny-ggml-model
|
|
149
159
|
https://huggingface.co/NbAiLab/nb-whisper-tiny
|
|
150
160
|
parler-indic-f16
|
|
@@ -211,6 +221,8 @@ Third-Party Model Licenses
|
|
|
211
221
|
https://huggingface.co/HuggingFaceVLA/smolvla_libero
|
|
212
222
|
SmolVLM2-500M-Video-Instruct-GGUF
|
|
213
223
|
https://huggingface.co/ggml-org/SmolVLM2-500M-Video-Instruct-GGUF
|
|
224
|
+
Ternary-Bonsai-2-27B-gguf
|
|
225
|
+
https://huggingface.co/prism-ml/Ternary-Bonsai-2-27B-gguf
|
|
214
226
|
TranslatePsy-AfriSLM-0.8B-Q4-GGUF
|
|
215
227
|
https://huggingface.co/qvac/TranslatePsy-AfriSLM-0.8B-Q4-GGUF
|
|
216
228
|
TranslatePsy-AfriSLM-0.8B-Q8-GGUF
|
|
@@ -251,6 +263,8 @@ Third-Party Model Licenses
|
|
|
251
263
|
https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged
|
|
252
264
|
Wan2.2-TI2V-5B-Turbo-GGUF
|
|
253
265
|
https://huggingface.co/hum-ma/Wan2.2-TI2V-5B-Turbo-GGUF
|
|
266
|
+
weight
|
|
267
|
+
https://huggingface.co/Audio8/Audio8-TTS-Preview-0.6b
|
|
254
268
|
|
|
255
269
|
--- bsd-3-clause (BSD 3-Clause License) ---
|
|
256
270
|
|
|
@@ -277,30 +291,58 @@ Third-Party Model Licenses
|
|
|
277
291
|
|
|
278
292
|
AfriqueGemma-4B-GGUF
|
|
279
293
|
https://huggingface.co/mradermacher/AfriqueGemma-4B-GGUF
|
|
294
|
+
coremldata
|
|
295
|
+
https://huggingface.co/nvidia/parakeet-ctc-0.6b
|
|
296
|
+
coremldata
|
|
297
|
+
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
298
|
+
coremldata
|
|
299
|
+
https://huggingface.co/nvidia/parakeet-tdt-1.1b
|
|
300
|
+
coremldata
|
|
301
|
+
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
302
|
+
model
|
|
303
|
+
https://huggingface.co/nvidia/parakeet-ctc-0.6b
|
|
304
|
+
model
|
|
305
|
+
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
306
|
+
model
|
|
307
|
+
https://huggingface.co/nvidia/parakeet-tdt-1.1b
|
|
308
|
+
model
|
|
309
|
+
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
310
|
+
parakeet_realtime_eou_120m-v1.f16
|
|
311
|
+
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
312
|
+
parakeet_realtime_eou_120m-v1.q4_0
|
|
313
|
+
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
314
|
+
parakeet_realtime_eou_120m-v1.q8_0
|
|
315
|
+
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
280
316
|
parakeet-ctc-0.6b.f16
|
|
281
317
|
https://huggingface.co/nvidia/parakeet-ctc-0.6b
|
|
282
318
|
parakeet-ctc-0.6b.q4_0
|
|
283
319
|
https://huggingface.co/nvidia/parakeet-ctc-0.6b
|
|
284
320
|
parakeet-ctc-0.6b.q8_0
|
|
285
321
|
https://huggingface.co/nvidia/parakeet-ctc-0.6b
|
|
286
|
-
parakeet-eou-120m-v1.f16
|
|
287
|
-
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
288
|
-
parakeet-eou-120m-v1.q4_0
|
|
289
|
-
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
290
|
-
parakeet-eou-120m-v1.q8_0
|
|
291
|
-
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
292
322
|
parakeet-tdt-0.6b-v3.f16
|
|
293
323
|
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
294
324
|
parakeet-tdt-0.6b-v3.q4_0
|
|
295
325
|
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
296
326
|
parakeet-tdt-0.6b-v3.q8_0
|
|
297
327
|
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
328
|
+
parakeet-tdt-1.1b.f16
|
|
329
|
+
https://huggingface.co/nvidia/parakeet-tdt-1.1b
|
|
330
|
+
parakeet-tdt-1.1b.q8_0
|
|
331
|
+
https://huggingface.co/nvidia/parakeet-tdt-1.1b
|
|
298
332
|
sortformer-4spk-v1.f16
|
|
299
333
|
https://huggingface.co/nvidia/diar_sortformer_4spk-v1
|
|
300
334
|
sortformer-4spk-v1.q4_0
|
|
301
335
|
https://huggingface.co/nvidia/diar_sortformer_4spk-v1
|
|
302
336
|
sortformer-4spk-v1.q8_0
|
|
303
337
|
https://huggingface.co/nvidia/diar_sortformer_4spk-v1
|
|
338
|
+
weight
|
|
339
|
+
https://huggingface.co/nvidia/parakeet-ctc-0.6b
|
|
340
|
+
weight
|
|
341
|
+
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
342
|
+
weight
|
|
343
|
+
https://huggingface.co/nvidia/parakeet-tdt-1.1b
|
|
344
|
+
weight
|
|
345
|
+
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
304
346
|
|
|
305
347
|
--- gemma (Gemma Terms of Use) ---
|
|
306
348
|
|
|
@@ -362,6 +404,8 @@ Third-Party Model Licenses
|
|
|
362
404
|
https://huggingface.co/ResembleAI/chatterbox
|
|
363
405
|
chatterbox-t3-turbo
|
|
364
406
|
https://huggingface.co/ResembleAI/chatterbox-turbo
|
|
407
|
+
coremldata
|
|
408
|
+
https://huggingface.co/ai4bharat/indic-conformer-600m-multilingual
|
|
365
409
|
de-base-ggml-model-f16
|
|
366
410
|
https://huggingface.co/aware-ai/whisper-base-german
|
|
367
411
|
DeepSeek-V4-Flash-0731-GGUF
|
|
@@ -384,16 +428,18 @@ Third-Party Model Licenses
|
|
|
384
428
|
https://huggingface.co/ChristianAzinn/gte-large-gguf
|
|
385
429
|
gte-large-gguf
|
|
386
430
|
https://huggingface.co/ChristianAzinn/gte-large-gguf
|
|
387
|
-
indic-conformer-
|
|
431
|
+
indic-conformer-600m-multilingual.f16
|
|
388
432
|
https://huggingface.co/ai4bharat/indic-conformer-600m-multilingual
|
|
389
|
-
indic-conformer-
|
|
433
|
+
indic-conformer-600m-multilingual.q4_0
|
|
390
434
|
https://huggingface.co/ai4bharat/indic-conformer-600m-multilingual
|
|
391
|
-
indic-conformer-
|
|
435
|
+
indic-conformer-600m-multilingual.q8_0
|
|
392
436
|
https://huggingface.co/ai4bharat/indic-conformer-600m-multilingual
|
|
393
437
|
lavasr-denoiser-f16
|
|
394
438
|
https://huggingface.co/spaces/YatharthS
|
|
395
439
|
lavasr-enhancer-f16
|
|
396
440
|
https://huggingface.co/spaces/YatharthS
|
|
441
|
+
model
|
|
442
|
+
https://huggingface.co/ai4bharat/indic-conformer-600m-multilingual
|
|
397
443
|
pt-tiny-ggml-model-f16
|
|
398
444
|
https://huggingface.co/DavyCosta701/whisper-tiny-pt-bpra
|
|
399
445
|
taew2_2_f16
|
|
@@ -404,6 +450,8 @@ Third-Party Model Licenses
|
|
|
404
450
|
https://voiceinput.futo.org/VoiceInput/tiny_en_acft_q8_0.bin
|
|
405
451
|
vae-BF16
|
|
406
452
|
https://huggingface.co/ACE-Step/Ace-Step1.5
|
|
453
|
+
weight
|
|
454
|
+
https://huggingface.co/ai4bharat/indic-conformer-600m-multilingual
|
|
407
455
|
whisper-vad
|
|
408
456
|
https://huggingface.co/ggml-org/whisper-vad
|
|
409
457
|
whisper.cpp
|
|
@@ -618,6 +666,12 @@ Third-Party Model Licenses
|
|
|
618
666
|
|
|
619
667
|
--- nvidia-open-model-license ---
|
|
620
668
|
|
|
669
|
+
coremldata
|
|
670
|
+
https://huggingface.co/nvidia/diar_streaming_sortformer_4spk-v2.1
|
|
671
|
+
coremldata
|
|
672
|
+
https://huggingface.co/nvidia/nemotron-3.5-asr-streaming-0.6b
|
|
673
|
+
coremldata
|
|
674
|
+
https://huggingface.co/nvidia/parakeet-unified-en-0.6b
|
|
621
675
|
diar_streaming_sortformer_4spk-v2.1.f16
|
|
622
676
|
https://huggingface.co/nvidia/diar_streaming_sortformer_4spk-v2.1
|
|
623
677
|
diar_streaming_sortformer_4spk-v2.1.q4_0
|
|
@@ -628,6 +682,12 @@ Third-Party Model Licenses
|
|
|
628
682
|
https://huggingface.co/nvidia/GR00T-N1.7-LIBERO
|
|
629
683
|
groot-q8_vf16
|
|
630
684
|
https://huggingface.co/nvidia/GR00T-N1.7-3B
|
|
685
|
+
model
|
|
686
|
+
https://huggingface.co/nvidia/diar_streaming_sortformer_4spk-v2.1
|
|
687
|
+
model
|
|
688
|
+
https://huggingface.co/nvidia/nemotron-3.5-asr-streaming-0.6b
|
|
689
|
+
model
|
|
690
|
+
https://huggingface.co/nvidia/parakeet-unified-en-0.6b
|
|
631
691
|
nemotron-3.5-asr-streaming-0.6b.f16
|
|
632
692
|
https://huggingface.co/nvidia/nemotron-3.5-asr-streaming-0.6b
|
|
633
693
|
nemotron-3.5-asr-streaming-0.6b.q4_0
|
|
@@ -640,6 +700,12 @@ Third-Party Model Licenses
|
|
|
640
700
|
https://huggingface.co/nvidia/parakeet-unified-en-0.6b
|
|
641
701
|
parakeet-unified-en-0.6b.q8_0
|
|
642
702
|
https://huggingface.co/nvidia/parakeet-unified-en-0.6b
|
|
703
|
+
weight
|
|
704
|
+
https://huggingface.co/nvidia/diar_streaming_sortformer_4spk-v2.1
|
|
705
|
+
weight
|
|
706
|
+
https://huggingface.co/nvidia/nemotron-3.5-asr-streaming-0.6b
|
|
707
|
+
weight
|
|
708
|
+
https://huggingface.co/nvidia/parakeet-unified-en-0.6b
|
|
643
709
|
|
|
644
710
|
--- openrail ---
|
|
645
711
|
|
|
@@ -682,7 +748,6 @@ the underlying models.
|
|
|
682
748
|
|
|
683
749
|
Source URLs for original weights are recorded in each model's
|
|
684
750
|
metadata entry within the registry.
|
|
685
|
-
|
|
686
751
|
=========================================================================
|
|
687
752
|
JavaScript Dependencies
|
|
688
753
|
=========================================================================
|
|
@@ -722,8 +787,6 @@ JavaScript Dependencies
|
|
|
722
787
|
https://github.com/tetherto/qvac
|
|
723
788
|
@qvac/logging@0.1.1
|
|
724
789
|
https://github.com/tetherto/qvac
|
|
725
|
-
@qvac/model-fit@0.12.2
|
|
726
|
-
https://github.com/tetherto/qvac
|
|
727
790
|
@qvac/ocr-ggml@0.24.3
|
|
728
791
|
https://github.com/tetherto/qvac
|
|
729
792
|
@qvac/rag@0.8.1
|
package/README.md
CHANGED
|
@@ -22,6 +22,13 @@ For AI/LLM tools, use [https://docs.qvac.tether.io/llms-full.txt](https://docs.q
|
|
|
22
22
|
|
|
23
23
|
See https://docs.qvac.tether.io/sdk/getting-started/installation
|
|
24
24
|
|
|
25
|
+
On Node.js, the SDK installs and launches its own Bare worker through `bare-runtime`.
|
|
26
|
+
Its dependency range must satisfy `@qvac/inference`'s `engines.bare` requirement.
|
|
27
|
+
When upgrading the SDK, reinstall dependencies with the existing lockfile so the
|
|
28
|
+
package manager can replace an older, incompatible runtime. Remove any override
|
|
29
|
+
or resolution that forces the worker below that requirement; installing a newer
|
|
30
|
+
global `bare` executable does not change the SDK's worker dependency.
|
|
31
|
+
|
|
25
32
|
## Quickstart
|
|
26
33
|
|
|
27
34
|
1. Create the examples workspace:
|
|
@@ -143,16 +150,16 @@ initialized, the event omits the resource block.
|
|
|
143
150
|
## Pre-download model fit assessment
|
|
144
151
|
|
|
145
152
|
Use `assessModelFit` to check, before downloading anything, whether models are
|
|
146
|
-
likely to fit in this device's memory.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
no load:
|
|
153
|
+
likely to fit in this device's memory. Each candidate is described as `loadModel`
|
|
154
|
+
takes it. It reads generated catalog metadata plus a fresh memory sample, and for
|
|
155
|
+
a single candidate the registry's weightless description of the artifact, so the
|
|
156
|
+
engine's own fitter can answer — no weights, no load:
|
|
150
157
|
|
|
151
158
|
```ts
|
|
152
159
|
import { assessModelFit, QWEN3_8B_INST_Q4_K_M } from '@qvac/sdk'
|
|
153
160
|
|
|
154
161
|
const result = await assessModelFit({
|
|
155
|
-
models: [{
|
|
162
|
+
models: [{ modelSrc: QWEN3_8B_INST_Q4_K_M, modelType: 'llm', modelConfig: { ctx_size: 8192 } }],
|
|
156
163
|
execution: 'sequential',
|
|
157
164
|
policy: 'interactive-v1'
|
|
158
165
|
})
|
|
@@ -187,6 +194,33 @@ console.log(stats?.audioDuration, stats?.realTimeFactor)
|
|
|
187
194
|
`session.stats` resolves to `undefined` when the engine does not report
|
|
188
195
|
statistics.
|
|
189
196
|
|
|
197
|
+
Batch `transcribe()` calls also expose terminal statistics:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
const call = transcribe({ modelId, audioChunk })
|
|
201
|
+
const text = await call
|
|
202
|
+
const stats = await call.stats
|
|
203
|
+
console.log(text, stats?.encoderUsedCoreml)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
`call.stats` resolves to `undefined` when the engine reports no statistics and
|
|
207
|
+
rejects if transcription fails.
|
|
208
|
+
|
|
209
|
+
## Parakeet Core ML encoders on Apple devices
|
|
210
|
+
|
|
211
|
+
Load a supported Parakeet registry constant as usual. On macOS and iOS, the SDK
|
|
212
|
+
downloads any complete, published Core ML encoder bundle with its GGUF and
|
|
213
|
+
places the `.mlmodelc` directory where the native addon discovers it. This is
|
|
214
|
+
available for TDT 0.6B v3, Unified English 0.6B, EOU 120M v1, and streaming
|
|
215
|
+
Sortformer v2.1. The download includes the sidecar weights, so first load takes
|
|
216
|
+
more time and disk space. Other platforms download only the GGUF. If the
|
|
217
|
+
sidecar is unavailable or cannot load, inference uses the GGUF encoder.
|
|
218
|
+
Sortformer v2.1 also needs a GGUF with the
|
|
219
|
+
`parakeet.model_variant=sortformer-streaming-v2.1-aosc` metadata. Caching both
|
|
220
|
+
sidecars alone does not activate Core ML. See
|
|
221
|
+
[`examples/asr/parakeet-unified-coreml.ts`](examples/asr/parakeet-unified-coreml.ts)
|
|
222
|
+
for a local check of a Unified GGUF and its encoder bundle.
|
|
223
|
+
|
|
190
224
|
## Examples
|
|
191
225
|
|
|
192
226
|
In the `./examples` subdirectory, you will find scripts demonstrating how to use all SDK functionalities. To try any of them:
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Advisory
|
|
2
|
+
* Advisory model fit check.
|
|
3
3
|
*
|
|
4
|
-
* Before a
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Before a load, the SDK runs the fitter belonging to the engine that would
|
|
5
|
+
* run it and projects whether the exact configuration it is about to load will
|
|
6
|
+
* fit in device memory. Desktop runs it in a disposable Bare child; mobile,
|
|
7
|
+
* which cannot spawn one, runs it on a worker thread.
|
|
7
8
|
*
|
|
8
9
|
* The result is ADVISORY. It never blocks a load. `does-not-fit` is logged and
|
|
9
10
|
* the ordinary load path runs unchanged. Crashes, timeouts, malformed
|
|
10
11
|
* responses, unsupported configurations, and internal errors all resolve to
|
|
11
|
-
* "no evidence" and are equally non-blocking.
|
|
12
|
-
*
|
|
12
|
+
* "no evidence" and are equally non-blocking. No verdict changes the load;
|
|
13
|
+
* `getLoadedModelInfo` returns it as `fitProbe`.
|
|
13
14
|
*
|
|
14
15
|
* The verdict is emitted on the SDK server log stream, not to stdout, so this
|
|
15
16
|
* example subscribes to `loggingStream({ id: SDK_LOG_ID })` and reprints the
|
|
@@ -19,9 +20,8 @@
|
|
|
19
20
|
* What fits on this machine (Apple M4 Pro, 24 GiB unified memory)
|
|
20
21
|
* ---------------------------------------------------------------------------
|
|
21
22
|
*
|
|
22
|
-
* Measured
|
|
23
|
-
*
|
|
24
|
-
* fitter budgets against what the machine can actually keep resident
|
|
23
|
+
* Measured at the default 1024 MiB margin. The fitter budgets against what the
|
|
24
|
+
* machine can actually keep resident
|
|
25
25
|
* (total − wired − compressor: 17.4 GiB on this machine at idle), not the raw
|
|
26
26
|
* RAM figure.
|
|
27
27
|
*
|
|
@@ -30,10 +30,12 @@
|
|
|
30
30
|
* gpt-oss-20B Q4_K_M 10.8 GiB @ 32k ctx
|
|
31
31
|
* gte-large fp16 0.6 GiB (embedding, context pinned to 512)
|
|
32
32
|
*
|
|
33
|
-
* PROJECTED NOT TO FIT —
|
|
33
|
+
* PROJECTED NOT TO FIT — with `gpu_layers: 99` pinned
|
|
34
34
|
* gpt-oss-20B Q4_K_M 10.8 GiB @ 128k ctx with an f32 KV cache ← below
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
*
|
|
36
|
+
* These rows were measured with `gpu_layers` pinned at 99. Loads no longer pin
|
|
37
|
+
* the layer count, and the `does-not-fit` row has not been re-measured
|
|
38
|
+
* unpinned.
|
|
37
39
|
*
|
|
38
40
|
* gpt-oss-20B at 128k context FITS with the default KV cache and DOES NOT FIT
|
|
39
41
|
* once `cache-type-k`/`cache-type-v` are set to `f32`. Same model, same
|
|
@@ -42,10 +44,9 @@
|
|
|
42
44
|
*
|
|
43
45
|
* Two boundaries worth understanding when reading verdicts:
|
|
44
46
|
*
|
|
45
|
-
* 1. The verdict answers for a PLACEMENT, not a model.
|
|
46
|
-
*
|
|
47
|
-
* means "not at this placement".
|
|
48
|
-
* to move layers to the CPU side instead.
|
|
47
|
+
* 1. The verdict answers for a PLACEMENT, not a model. With `gpu_layers`
|
|
48
|
+
* unset, the fitter may move layers to the CPU side; setting it pins the
|
|
49
|
+
* layer count, and `does-not-fit` then means "not at this placement".
|
|
49
50
|
* 2. A `does-not-fit` configuration can still RUN on macOS when the OS
|
|
50
51
|
* compresses and pages hard enough — and a `fits` configuration right at
|
|
51
52
|
* the boundary can still fail at first decode under memory pressure.
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Advisory
|
|
2
|
+
* Advisory model fit check.
|
|
3
3
|
*
|
|
4
|
-
* Before a
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Before a load, the SDK runs the fitter belonging to the engine that would
|
|
5
|
+
* run it and projects whether the exact configuration it is about to load will
|
|
6
|
+
* fit in device memory. Desktop runs it in a disposable Bare child; mobile,
|
|
7
|
+
* which cannot spawn one, runs it on a worker thread.
|
|
7
8
|
*
|
|
8
9
|
* The result is ADVISORY. It never blocks a load. `does-not-fit` is logged and
|
|
9
10
|
* the ordinary load path runs unchanged. Crashes, timeouts, malformed
|
|
10
11
|
* responses, unsupported configurations, and internal errors all resolve to
|
|
11
|
-
* "no evidence" and are equally non-blocking.
|
|
12
|
-
*
|
|
12
|
+
* "no evidence" and are equally non-blocking. No verdict changes the load;
|
|
13
|
+
* `getLoadedModelInfo` returns it as `fitProbe`.
|
|
13
14
|
*
|
|
14
15
|
* The verdict is emitted on the SDK server log stream, not to stdout, so this
|
|
15
16
|
* example subscribes to `loggingStream({ id: SDK_LOG_ID })` and reprints the
|
|
@@ -19,9 +20,8 @@
|
|
|
19
20
|
* What fits on this machine (Apple M4 Pro, 24 GiB unified memory)
|
|
20
21
|
* ---------------------------------------------------------------------------
|
|
21
22
|
*
|
|
22
|
-
* Measured
|
|
23
|
-
*
|
|
24
|
-
* fitter budgets against what the machine can actually keep resident
|
|
23
|
+
* Measured at the default 1024 MiB margin. The fitter budgets against what the
|
|
24
|
+
* machine can actually keep resident
|
|
25
25
|
* (total − wired − compressor: 17.4 GiB on this machine at idle), not the raw
|
|
26
26
|
* RAM figure.
|
|
27
27
|
*
|
|
@@ -30,10 +30,12 @@
|
|
|
30
30
|
* gpt-oss-20B Q4_K_M 10.8 GiB @ 32k ctx
|
|
31
31
|
* gte-large fp16 0.6 GiB (embedding, context pinned to 512)
|
|
32
32
|
*
|
|
33
|
-
* PROJECTED NOT TO FIT —
|
|
33
|
+
* PROJECTED NOT TO FIT — with `gpu_layers: 99` pinned
|
|
34
34
|
* gpt-oss-20B Q4_K_M 10.8 GiB @ 128k ctx with an f32 KV cache ← below
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
*
|
|
36
|
+
* These rows were measured with `gpu_layers` pinned at 99. Loads no longer pin
|
|
37
|
+
* the layer count, and the `does-not-fit` row has not been re-measured
|
|
38
|
+
* unpinned.
|
|
37
39
|
*
|
|
38
40
|
* gpt-oss-20B at 128k context FITS with the default KV cache and DOES NOT FIT
|
|
39
41
|
* once `cache-type-k`/`cache-type-v` are set to `f32`. Same model, same
|
|
@@ -42,10 +44,9 @@
|
|
|
42
44
|
*
|
|
43
45
|
* Two boundaries worth understanding when reading verdicts:
|
|
44
46
|
*
|
|
45
|
-
* 1. The verdict answers for a PLACEMENT, not a model.
|
|
46
|
-
*
|
|
47
|
-
* means "not at this placement".
|
|
48
|
-
* to move layers to the CPU side instead.
|
|
47
|
+
* 1. The verdict answers for a PLACEMENT, not a model. With `gpu_layers`
|
|
48
|
+
* unset, the fitter may move layers to the CPU side; setting it pins the
|
|
49
|
+
* layer count, and `does-not-fit` then means "not at this placement".
|
|
49
50
|
* 2. A `does-not-fit` configuration can still RUN on macOS when the OS
|
|
50
51
|
* compresses and pages hard enough — and a `fits` configuration right at
|
|
51
52
|
* the boundary can still fail at first decode under memory pressure.
|
|
@@ -98,8 +99,7 @@ try {
|
|
|
98
99
|
// Unloaded before the next phase, so the second verdict is measured on an
|
|
99
100
|
// idle machine and stays comparable to the fixture tables above. Leaving it
|
|
100
101
|
// loaded would shift the verdict: the check reserves resident weight bytes
|
|
101
|
-
// through the fit margin, and
|
|
102
|
-
// system-wide wired memory.
|
|
102
|
+
// through the fit margin, and the fitter also sees system-wide wired memory.
|
|
103
103
|
await unloadModel({ modelId: smallModelId, clearStorage: false });
|
|
104
104
|
watchVerdicts();
|
|
105
105
|
// 2. A load the fitter projects NOT to fit. The point of this example is that
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Usage:
|
|
5
5
|
* bun run examples/asr/parakeet-indic-conformer-filesystem.ts <wav-file> <language> [gguf]
|
|
6
6
|
*
|
|
7
|
-
* Loads a single GGUF checkpoint (`
|
|
7
|
+
* Loads a single GGUF checkpoint (`PARAKEET_INDIC_CONFORMER_600M_Q8_0` by
|
|
8
8
|
* default) and transcribes with the batch `transcribe` API. `language` is
|
|
9
9
|
* required (e.g. `hi`, `ta`) because Indic Conformer CTC masks the vocab
|
|
10
10
|
* with `parakeet.ctc.lang_*` ranges. English Parakeet CTC ignores this field.
|
|
11
11
|
*
|
|
12
12
|
* Audio should be 16 kHz mono PCM in a WAV container.
|
|
13
13
|
*/
|
|
14
|
-
import { loadModel, unloadModel, transcribe,
|
|
14
|
+
import { loadModel, unloadModel, transcribe, PARAKEET_INDIC_CONFORMER_600M_Q8_0 } from '@qvac/sdk';
|
|
15
15
|
const args = process.argv.slice(2);
|
|
16
16
|
if (!args[0] || !args[1]) {
|
|
17
17
|
console.error('Usage: bun run examples/asr/parakeet-indic-conformer-filesystem.ts ' +
|
|
@@ -22,7 +22,7 @@ if (!args[0] || !args[1]) {
|
|
|
22
22
|
}
|
|
23
23
|
const audioFilePath = args[0];
|
|
24
24
|
const language = args[1];
|
|
25
|
-
const parakeetModelSrc = args[2] ??
|
|
25
|
+
const parakeetModelSrc = args[2] ?? PARAKEET_INDIC_CONFORMER_600M_Q8_0;
|
|
26
26
|
try {
|
|
27
27
|
console.log('▸ Loading Indic Conformer CTC model...');
|
|
28
28
|
const modelId = await loadModel({
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcribe a WAV file with Parakeet Unified and its Core ML encoder sidecar.
|
|
3
|
+
*
|
|
4
|
+
* From packages/sdk:
|
|
5
|
+
* bun run examples/asr/parakeet-unified-coreml.ts \
|
|
6
|
+
* /path/to/parakeet-unified-en-0.6b.q4_0.gguf [16-kHz-wav-file]
|
|
7
|
+
*
|
|
8
|
+
* The GGUF must be a regenerated Unified artifact. The five compiled Core ML
|
|
9
|
+
* files are downloaded through the SDK registry and staged beside the GGUF.
|
|
10
|
+
* The default audio is examples/audio/sample-16khz.wav.
|
|
11
|
+
*/
|
|
12
|
+
import { downloadAsset, getModelInfo, loadModel, transcribe, unloadModel } from '@qvac/sdk';
|
|
13
|
+
import { link, mkdir, mkdtemp, open, rm, symlink } from 'node:fs/promises';
|
|
14
|
+
import { tmpdir } from 'node:os';
|
|
15
|
+
import { basename, join, resolve } from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
const MODEL_STEM = 'parakeet-unified-en-0.6b';
|
|
18
|
+
const COREML_FILES = [
|
|
19
|
+
['PARAKEET_UNIFIED_COREMLDATA', 'analytics/coremldata.bin'],
|
|
20
|
+
['PARAKEET_UNIFIED_COREMLDATA_1', 'coremldata.bin'],
|
|
21
|
+
['PARAKEET_UNIFIED_METADATA', 'metadata.json'],
|
|
22
|
+
['PARAKEET_UNIFIED_MODEL', 'model.mil'],
|
|
23
|
+
['PARAKEET_UNIFIED_WEIGHT', 'weights/weight.bin']
|
|
24
|
+
];
|
|
25
|
+
const defaultAudioPath = fileURLToPath(new URL('../audio/sample-16khz.wav', import.meta.url));
|
|
26
|
+
const modelPath = process.argv[2];
|
|
27
|
+
const audioPath = process.argv[3] ?? defaultAudioPath;
|
|
28
|
+
async function checkModel(path) {
|
|
29
|
+
const name = basename(path);
|
|
30
|
+
if (!/^parakeet-unified-en-0\.6b\.(?:f16|q4_0|q8_0)\.gguf$/.test(name)) {
|
|
31
|
+
throw new Error(`Expected a regenerated Unified GGUF, got: ${name}`);
|
|
32
|
+
}
|
|
33
|
+
const file = await open(path, 'r');
|
|
34
|
+
try {
|
|
35
|
+
const header = Buffer.alloc(1024 * 1024);
|
|
36
|
+
const { bytesRead } = await file.read(header, 0, header.length, 0);
|
|
37
|
+
if (!header.subarray(0, bytesRead).includes('parakeet.unified.left_context_frames')) {
|
|
38
|
+
throw new Error(`Unified GGUF lacks the new streaming metadata: ${path}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await file.close();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function stageModel(path) {
|
|
46
|
+
if (process.platform !== 'darwin')
|
|
47
|
+
throw new Error('Core ML requires macOS');
|
|
48
|
+
await checkModel(path);
|
|
49
|
+
const dir = await mkdtemp(join(tmpdir(), 'qvac-unified-coreml-'));
|
|
50
|
+
try {
|
|
51
|
+
const modelSrc = join(dir, basename(path));
|
|
52
|
+
await symlink(resolve(path), modelSrc);
|
|
53
|
+
const bundleDir = join(dir, `${MODEL_STEM}-encoder.mlmodelc`);
|
|
54
|
+
for (const [name, relativePath] of COREML_FILES) {
|
|
55
|
+
const info = await getModelInfo({ name });
|
|
56
|
+
if (!info.isCached) {
|
|
57
|
+
if (!info.registrySource || !info.registryPath) {
|
|
58
|
+
throw new Error(`Registry location missing for ${name}`);
|
|
59
|
+
}
|
|
60
|
+
console.log(`▸ Downloading Core ML ${relativePath}...`);
|
|
61
|
+
await downloadAsset({ assetSrc: `registry://${info.registrySource}/${info.registryPath}` });
|
|
62
|
+
}
|
|
63
|
+
const cached = await getModelInfo({ name });
|
|
64
|
+
const sourcePath = cached.cacheFiles.find((file) => file.isCached)?.path;
|
|
65
|
+
if (!sourcePath)
|
|
66
|
+
throw new Error(`Core ML file is missing from the SDK cache: ${name}`);
|
|
67
|
+
const targetPath = join(bundleDir, relativePath);
|
|
68
|
+
await mkdir(join(targetPath, '..'), { recursive: true });
|
|
69
|
+
await link(sourcePath, targetPath);
|
|
70
|
+
}
|
|
71
|
+
return { modelSrc, dir };
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
await rm(dir, { recursive: true, force: true });
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function main() {
|
|
79
|
+
if (!modelPath) {
|
|
80
|
+
throw new Error('Usage: bun run examples/asr/parakeet-unified-coreml.ts ' +
|
|
81
|
+
'<regenerated-unified-gguf> [16-kHz-wav-file]');
|
|
82
|
+
}
|
|
83
|
+
let staged;
|
|
84
|
+
let modelId;
|
|
85
|
+
try {
|
|
86
|
+
staged = await stageModel(modelPath);
|
|
87
|
+
console.log('▸ Loading Parakeet Unified with its Core ML encoder sidecar...');
|
|
88
|
+
modelId = await loadModel({
|
|
89
|
+
modelSrc: staged.modelSrc,
|
|
90
|
+
modelType: 'parakeet-transcription',
|
|
91
|
+
modelConfig: { useGPU: true }
|
|
92
|
+
});
|
|
93
|
+
console.log('▸ Transcribing audio...');
|
|
94
|
+
const text = await transcribe({ modelId, audioChunk: audioPath });
|
|
95
|
+
if (!text.trim())
|
|
96
|
+
throw new Error('Parakeet Unified returned an empty transcription');
|
|
97
|
+
console.log(text);
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
try {
|
|
101
|
+
if (modelId)
|
|
102
|
+
await unloadModel({ modelId });
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
if (staged)
|
|
106
|
+
await rm(staged.dir, { recursive: true, force: true });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
main().catch((error) => {
|
|
111
|
+
console.error('✖', error);
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
});
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* call either way. Show it as "can't say", never as "no".
|
|
12
12
|
*/
|
|
13
13
|
import { assessModelFit, QWEN3_600M_INST_Q4, QWEN3_1_7B_INST_Q4, QWEN3_4B_INST_Q4_K_M, QWEN3_8B_INST_Q4_K_M, QWEN3_8_27B_MULTIMODAL_UD_Q8_K_XL } from '@qvac/sdk';
|
|
14
|
-
//
|
|
15
|
-
|
|
14
|
+
// Sizes the assessment the way it sizes the load: the estimator reads the
|
|
15
|
+
// context out of the config `loadModel` would be given.
|
|
16
|
+
const CONTEXT_TOKENS = 8192;
|
|
16
17
|
// A ladder ending well past what a laptop has, so one screen shows every verdict.
|
|
17
18
|
const CANDIDATES = [
|
|
18
19
|
QWEN3_600M_INST_Q4,
|
|
@@ -31,7 +32,11 @@ function gib(bytes) {
|
|
|
31
32
|
}
|
|
32
33
|
try {
|
|
33
34
|
const result = await assessModelFit({
|
|
34
|
-
models: CANDIDATES.map((model) => ({
|
|
35
|
+
models: CANDIDATES.map((model) => ({
|
|
36
|
+
modelSrc: model,
|
|
37
|
+
modelType: 'llamacpp-completion',
|
|
38
|
+
modelConfig: { ctx_size: CONTEXT_TOKENS }
|
|
39
|
+
})),
|
|
35
40
|
// Declared for aggregation only, not a scheduling instruction: 'sequential'
|
|
36
41
|
// counts the largest operation peak, 'concurrent' counts one per model.
|
|
37
42
|
execution: 'sequential',
|
|
@@ -49,7 +54,7 @@ try {
|
|
|
49
54
|
const placement = result.assumptions.find((line) => line.includes('assumed to execute on'));
|
|
50
55
|
if (placement)
|
|
51
56
|
console.log(`▸ ${placement}`);
|
|
52
|
-
console.log(`\n▸ At ${
|
|
57
|
+
console.log(`\n▸ At ${CONTEXT_TOKENS} tokens of context`);
|
|
53
58
|
for (const [index, model] of result.models.entries()) {
|
|
54
59
|
const mark = VERDICT_MARK[model.verdict];
|
|
55
60
|
const size = gib(CANDIDATES[index].expectedSize).padStart(9);
|
|
@@ -102,9 +102,12 @@ function sendJson(response, status, payload) {
|
|
|
102
102
|
async function estimate(body) {
|
|
103
103
|
const names = Array.isArray(body['names']) ? body['names'] : [];
|
|
104
104
|
const contextTokens = Number(body['contextTokens'] ?? 8192);
|
|
105
|
-
const workload = { kind: 'llm', contextTokens };
|
|
106
105
|
return assessModelFit({
|
|
107
|
-
models: names.map((name) => ({
|
|
106
|
+
models: names.map((name) => ({
|
|
107
|
+
modelSrc: byName(name),
|
|
108
|
+
modelType: 'llamacpp-completion',
|
|
109
|
+
modelConfig: { ctx_size: contextTokens }
|
|
110
|
+
})),
|
|
108
111
|
// Declared for aggregation only. 'sequential' counts the largest operation
|
|
109
112
|
// peak; 'concurrent' counts one per model.
|
|
110
113
|
execution: 'sequential',
|