@qvac/sdk 0.15.0 → 0.16.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 +31 -45
- package/dist/client/api/ocr.d.ts +9 -0
- package/dist/client/api/ocr.js +9 -0
- package/dist/client/api/translate.js +6 -17
- package/dist/client/api/video.d.ts +7 -4
- package/dist/client/api/video.js +7 -4
- package/dist/client/api/vla.d.ts +14 -10
- package/dist/client/api/vla.js +14 -10
- package/dist/client/rpc/rpc-error.js +7 -1
- package/dist/examples/diffusion-ideogram.d.ts +2 -0
- package/dist/examples/diffusion-ideogram.js +108 -0
- package/dist/examples/diffusion-img2vid-ltx.d.ts +2 -0
- package/dist/examples/diffusion-img2vid-ltx.js +98 -0
- package/dist/examples/diffusion-txt2vid-ltx.d.ts +2 -0
- package/dist/examples/diffusion-txt2vid-ltx.js +92 -0
- package/dist/examples/logging-streaming.js +5 -1
- package/dist/examples/transcription/parakeet-tdt-filesystem-chunked.d.ts +2 -0
- package/dist/examples/transcription/parakeet-tdt-filesystem-chunked.js +203 -0
- package/dist/examples/vla-groot.d.ts +2 -0
- package/dist/examples/vla-groot.js +118 -0
- package/dist/models/registry/models.d.ts +5711 -9637
- package/dist/models/registry/models.js +2747 -6886
- package/dist/models/update-models/naming.js +5 -1
- package/dist/schemas/batch-completion-stream.d.ts +4 -4
- package/dist/schemas/common.d.ts +385 -4
- package/dist/schemas/common.js +3 -1
- package/dist/schemas/completion-stream.d.ts +186 -2
- package/dist/schemas/completion-stream.js +67 -0
- package/dist/schemas/constants-registry.d.ts +67 -0
- package/dist/schemas/constants-registry.js +51 -0
- package/dist/schemas/delete-cache.js +7 -3
- package/dist/schemas/engine-addon-map.d.ts +1 -0
- package/dist/schemas/engine-addon-map.js +1 -1
- package/dist/schemas/finetune.js +6 -3
- package/dist/schemas/get-loaded-model-info.d.ts +16 -0
- package/dist/schemas/get-loaded-model-info.js +14 -6
- package/dist/schemas/llamacpp-config.d.ts +24 -4
- package/dist/schemas/llamacpp-config.js +1 -6
- package/dist/schemas/load-model.d.ts +1380 -60
- package/dist/schemas/load-model.js +6 -3
- package/dist/schemas/plugin.d.ts +4 -4
- package/dist/schemas/plugin.js +4 -4
- package/dist/schemas/reload-config.js +3 -1
- package/dist/schemas/sdcpp-config.d.ts +239 -0
- package/dist/schemas/sdcpp-config.js +116 -10
- package/dist/schemas/sdk-config.d.ts +790 -40
- package/dist/schemas/sdk-errors-server.js +3 -1
- package/dist/schemas/text-to-speech.d.ts +14 -0
- package/dist/schemas/text-to-speech.js +10 -4
- package/dist/schemas/tools.d.ts +1 -1
- package/dist/schemas/tools.js +2 -1
- package/dist/schemas/translate.js +12 -6
- package/dist/schemas/vla.d.ts +10 -0
- package/dist/schemas/vla.js +31 -11
- package/dist/scripts/contract/build-contract.d.ts +38 -0
- package/dist/scripts/contract/build-contract.js +620 -0
- package/dist/scripts/contract/build-error-codes.d.ts +17 -0
- package/dist/scripts/contract/build-error-codes.js +17 -0
- package/dist/scripts/contract/build-model-type-maps.d.ts +22 -0
- package/dist/scripts/contract/build-model-type-maps.js +16 -0
- package/dist/scripts/contract/build-models-registry.d.ts +17 -0
- package/dist/scripts/contract/build-models-registry.js +31 -0
- package/dist/scripts/contract/plugin-contract.d.ts +23 -0
- package/dist/scripts/contract/plugin-contract.js +28 -0
- package/dist/scripts/export-contract.d.ts +2 -0
- package/dist/scripts/export-contract.js +27 -0
- package/dist/scripts/export-plugin-contract.d.ts +2 -0
- package/dist/scripts/export-plugin-contract.js +18 -0
- package/dist/server/bare/ops/translate.js +16 -3
- package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.d.ts +2 -1
- package/dist/server/bare/plugins/ggml-ocr/plugin.js +2 -23
- package/dist/server/bare/plugins/ggml-ocr/resolve-config.d.ts +6 -0
- package/dist/server/bare/plugins/ggml-ocr/resolve-config.js +73 -0
- package/dist/server/bare/plugins/ggml-vla/plugin.d.ts +5 -0
- package/dist/server/bare/plugins/ggml-vla/plugin.js +1 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +11 -22
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.d.ts +8 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.js +8 -0
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +8 -3
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +6 -1
- package/dist/server/bare/plugins/sdcpp-generation/ops/video.d.ts +3 -1
- package/dist/server/bare/plugins/sdcpp-generation/ops/video.js +31 -2
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +129 -1
- package/dist/server/bare/plugins/sdcpp-generation/plugin.js +94 -22
- package/dist/server/bare/plugins/tts-ggml/ops/text-to-speech.js +2 -16
- package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +6 -0
- package/dist/server/bare/plugins/tts-ggml/plugin.js +3 -1
- package/dist/server/bare/types/addon-responses.d.ts +2 -0
- package/dist/server/bare/utils/tts-stats.d.ts +8 -4
- package/dist/server/bare/utils/tts-stats.js +6 -0
- package/dist/server/rpc/create-server.js +23 -1
- package/dist/server/rpc/handler-registry.js +5 -0
- package/dist/server/rpc/handlers/completion-orchestrate.d.ts +42 -0
- package/dist/server/rpc/handlers/completion-orchestrate.js +190 -0
- package/dist/server/rpc/handlers/get-loaded-model-info.js +8 -2
- package/dist/server/rpc/handlers/index.d.ts +2 -0
- package/dist/server/rpc/handlers/index.js +2 -0
- package/dist/server/rpc/method-shapes.d.ts +51 -0
- package/dist/server/rpc/method-shapes.js +48 -0
- package/dist/server/rpc/profiling/operation-metrics.js +20 -0
- package/dist/server/utils/cache/auto-history.js +13 -9
- package/package.json +16 -13
package/NOTICE
CHANGED
|
@@ -127,6 +127,12 @@ Third-Party Model Licenses
|
|
|
127
127
|
https://huggingface.co/qvac/MedPsy-4B-GGUF
|
|
128
128
|
nb-tiny-ggml-model
|
|
129
129
|
https://huggingface.co/NbAiLab/nb-whisper-tiny
|
|
130
|
+
parler-indic-f16
|
|
131
|
+
https://huggingface.co/ai4bharat/indic-parler-tts
|
|
132
|
+
parler-large-v1-f16
|
|
133
|
+
https://huggingface.co/parler-tts/parler-tts-large-v1
|
|
134
|
+
parler-mini-v1-f16
|
|
135
|
+
https://huggingface.co/parler-tts/parler-tts-mini-v1
|
|
130
136
|
parseq
|
|
131
137
|
https://github.com/felixdittrich92/OnnxTR
|
|
132
138
|
pi05-base-q-aggressive
|
|
@@ -147,6 +153,8 @@ Third-Party Model Licenses
|
|
|
147
153
|
https://huggingface.co/Qwen/Qwen3-4B-GGUF
|
|
148
154
|
Qwen3-8B-GGUF
|
|
149
155
|
https://huggingface.co/Qwen/Qwen3-8B-GGUF
|
|
156
|
+
Qwen3-Embedding-0.6B-Q8_0
|
|
157
|
+
https://huggingface.co/Qwen/Qwen3-Embedding-0.6B
|
|
150
158
|
Qwen3-VL-2B-Instruct-GGUF
|
|
151
159
|
https://huggingface.co/Qwen/Qwen3-VL-2B-Instruct-GGUF
|
|
152
160
|
Qwen3.5-0.8B-GGUF
|
|
@@ -243,14 +251,6 @@ Third-Party Model Licenses
|
|
|
243
251
|
|
|
244
252
|
AfriqueGemma-4B-GGUF
|
|
245
253
|
https://huggingface.co/mradermacher/AfriqueGemma-4B-GGUF
|
|
246
|
-
decoder_joint-model
|
|
247
|
-
https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx
|
|
248
|
-
diar_streaming_sortformer_4spk-v2-onnx
|
|
249
|
-
https://huggingface.co/cgus/diar_streaming_sortformer_4spk-v2-onnx
|
|
250
|
-
encoder-model
|
|
251
|
-
https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx
|
|
252
|
-
parakeet-ctc-0.6b-ONNX
|
|
253
|
-
https://huggingface.co/onnx-community/parakeet-ctc-0.6b-ONNX
|
|
254
254
|
parakeet-ctc-0.6b.f16
|
|
255
255
|
https://huggingface.co/nvidia/parakeet-ctc-0.6b
|
|
256
256
|
parakeet-ctc-0.6b.q4_0
|
|
@@ -263,18 +263,12 @@ Third-Party Model Licenses
|
|
|
263
263
|
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
264
264
|
parakeet-eou-120m-v1.q8_0
|
|
265
265
|
https://huggingface.co/nvidia/parakeet_realtime_eou_120m-v1
|
|
266
|
-
parakeet-rs
|
|
267
|
-
https://huggingface.co/altunenes/parakeet-rs
|
|
268
|
-
parakeet-tdt-0.6b-v3-onnx
|
|
269
|
-
https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx
|
|
270
266
|
parakeet-tdt-0.6b-v3.f16
|
|
271
267
|
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
272
268
|
parakeet-tdt-0.6b-v3.q4_0
|
|
273
269
|
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
274
270
|
parakeet-tdt-0.6b-v3.q8_0
|
|
275
271
|
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3
|
|
276
|
-
preprocessor
|
|
277
|
-
https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx
|
|
278
272
|
sortformer-4spk-v1.f16
|
|
279
273
|
https://huggingface.co/nvidia/diar_sortformer_4spk-v1
|
|
280
274
|
sortformer-4spk-v1.q4_0
|
|
@@ -305,6 +299,14 @@ Third-Party Model Licenses
|
|
|
305
299
|
|
|
306
300
|
--- mit (MIT License) ---
|
|
307
301
|
|
|
302
|
+
acestep-5Hz-lm-0.6B-Q8_0
|
|
303
|
+
https://huggingface.co/ACE-Step/acestep-5Hz-lm-0.6B
|
|
304
|
+
acestep-v15-sft-Q8_0
|
|
305
|
+
https://huggingface.co/ACE-Step/acestep-v15-sft
|
|
306
|
+
acestep-v15-turbo-Q4_K_M
|
|
307
|
+
https://huggingface.co/ACE-Step/Ace-Step1.5
|
|
308
|
+
acestep-v15-turbo-Q8_0
|
|
309
|
+
https://huggingface.co/ACE-Step/Ace-Step1.5
|
|
308
310
|
bitnet_b1_58-3B-TQ2_0
|
|
309
311
|
https://huggingface.co/1bitLLM/bitnet_b1_58-3B
|
|
310
312
|
bitnet_b1_58-large-TQ2_0
|
|
@@ -313,8 +315,6 @@ Third-Party Model Licenses
|
|
|
313
315
|
https://huggingface.co/1bitLLM/bitnet_b1_58-xl
|
|
314
316
|
Cangjie5_TC
|
|
315
317
|
https://github.com/Jackchows/Cangjie5
|
|
316
|
-
chatterbox-multilingual-ONNX
|
|
317
|
-
https://huggingface.co/onnx-community/chatterbox-multilingual-ONNX
|
|
318
318
|
chatterbox-s3gen
|
|
319
319
|
https://huggingface.co/ResembleAI/chatterbox-turbo
|
|
320
320
|
chatterbox-s3gen-mtl
|
|
@@ -323,20 +323,8 @@ Third-Party Model Licenses
|
|
|
323
323
|
https://huggingface.co/ResembleAI/chatterbox
|
|
324
324
|
chatterbox-t3-turbo
|
|
325
325
|
https://huggingface.co/ResembleAI/chatterbox-turbo
|
|
326
|
-
chatterbox-turbo-ONNX
|
|
327
|
-
https://huggingface.co/ResembleAI/chatterbox-turbo-ONNX
|
|
328
326
|
de-base-ggml-model-f16
|
|
329
327
|
https://huggingface.co/aware-ai/whisper-base-german
|
|
330
|
-
denoiser_core_legacy_fixed63
|
|
331
|
-
s3:///qvac_models_compiled/onnx/lavasr/2026-04-03/denoiser_core_legacy_fixed63.onnx
|
|
332
|
-
enhancer_backbone
|
|
333
|
-
s3:///qvac_models_compiled/onnx/lavasr/2026-04-03/enhancer_backbone.onnx
|
|
334
|
-
enhancer_backbone.onnx
|
|
335
|
-
s3:///qvac_models_compiled/onnx/lavasr/2026-04-03/enhancer_backbone.onnx.data
|
|
336
|
-
enhancer_spec_head
|
|
337
|
-
s3:///qvac_models_compiled/onnx/lavasr/2026-04-03/enhancer_spec_head.onnx
|
|
338
|
-
enhancer_spec_head.onnx
|
|
339
|
-
s3:///qvac_models_compiled/onnx/lavasr/2026-04-03/enhancer_spec_head.onnx.data
|
|
340
328
|
es-tiny-ggml-model-f16
|
|
341
329
|
https://huggingface.co/JaepaX/whisper-tiny-es
|
|
342
330
|
ggml-indictrans2-en-indic-1B-f16
|
|
@@ -365,6 +353,8 @@ Third-Party Model Licenses
|
|
|
365
353
|
https://voiceinput.futo.org/VoiceInput/tiny_en_acft_q8_0.bin
|
|
366
354
|
tiny_en_acft_q8_0
|
|
367
355
|
https://voiceinput.futo.org/VoiceInput/tiny_en_acft_q8_0.bin
|
|
356
|
+
vae-BF16
|
|
357
|
+
https://huggingface.co/ACE-Step/Ace-Step1.5
|
|
368
358
|
whisper-vad
|
|
369
359
|
https://huggingface.co/ggml-org/whisper-vad
|
|
370
360
|
whisper.cpp
|
|
@@ -585,21 +575,17 @@ Third-Party Model Licenses
|
|
|
585
575
|
https://huggingface.co/nvidia/diar_streaming_sortformer_4spk-v2.1
|
|
586
576
|
diar_streaming_sortformer_4spk-v2.1.q8_0
|
|
587
577
|
https://huggingface.co/nvidia/diar_streaming_sortformer_4spk-v2.1
|
|
578
|
+
groot-q8_vf16
|
|
579
|
+
https://huggingface.co/nvidia/GR00T-N1.7-LIBERO
|
|
588
580
|
|
|
589
581
|
--- openrail ---
|
|
590
582
|
|
|
591
583
|
supertonic
|
|
592
584
|
s3:///qvac_models_compiled/supertonic/2026-05-08/supertonic.gguf
|
|
593
|
-
supertonic
|
|
594
|
-
https://huggingface.co/Supertone/supertonic
|
|
595
|
-
supertonic-2
|
|
596
|
-
https://huggingface.co/Supertone/supertonic-2
|
|
597
585
|
supertonic-q4_0
|
|
598
586
|
s3:///qvac_models_compiled/ggml/supertonic/2026-05-18/supertonic-q4_0.gguf
|
|
599
587
|
supertonic-q8_0
|
|
600
588
|
s3:///qvac_models_compiled/ggml/supertonic/2026-05-18/supertonic-q8_0.gguf
|
|
601
|
-
Supertonic-TTS-ONNX
|
|
602
|
-
https://huggingface.co/onnx-community/Supertonic-TTS-ONNX
|
|
603
589
|
supertonic2
|
|
604
590
|
s3:///qvac_models_compiled/supertonic/2026-05-08/supertonic2.gguf
|
|
605
591
|
supertonic2-q4_0
|
|
@@ -637,17 +623,17 @@ JavaScript Dependencies
|
|
|
637
623
|
|
|
638
624
|
@hyperswarm/secret-stream@6.9.1
|
|
639
625
|
https://github.com/holepunchto/hyperswarm-secret-stream
|
|
640
|
-
@qvac/bci-whispercpp@0.
|
|
626
|
+
@qvac/bci-whispercpp@0.5.1
|
|
641
627
|
https://github.com/tetherto/qvac
|
|
642
|
-
@qvac/classification-ggml@0.
|
|
628
|
+
@qvac/classification-ggml@0.13.0
|
|
643
629
|
https://github.com/tetherto/qvac
|
|
644
630
|
@qvac/decoder-audio@0.5.0
|
|
645
631
|
https://github.com/tetherto/qvac
|
|
646
632
|
@qvac/diagnostics@0.1.2
|
|
647
633
|
https://github.com/tetherto/qvac
|
|
648
|
-
@qvac/diffusion-cpp@0.
|
|
634
|
+
@qvac/diffusion-cpp@0.15.0
|
|
649
635
|
https://github.com/tetherto/qvac
|
|
650
|
-
@qvac/embed-llamacpp@0.
|
|
636
|
+
@qvac/embed-llamacpp@0.28.0
|
|
651
637
|
https://github.com/tetherto/qvac
|
|
652
638
|
@qvac/error@0.1.1
|
|
653
639
|
@qvac/infer-base@0.4.2
|
|
@@ -656,10 +642,10 @@ JavaScript Dependencies
|
|
|
656
642
|
https://github.com/tetherto/qvac
|
|
657
643
|
@qvac/langdetect-text@0.1.2
|
|
658
644
|
https://github.com/tetherto/qvac
|
|
659
|
-
@qvac/llm-llamacpp@0.
|
|
645
|
+
@qvac/llm-llamacpp@0.38.0
|
|
660
646
|
https://github.com/tetherto/qvac
|
|
661
647
|
@qvac/logging@0.1.0
|
|
662
|
-
@qvac/ocr-ggml@0.
|
|
648
|
+
@qvac/ocr-ggml@0.12.1
|
|
663
649
|
https://github.com/tetherto/qvac
|
|
664
650
|
@qvac/rag@0.6.4
|
|
665
651
|
https://github.com/tetherto/qvac
|
|
@@ -667,15 +653,15 @@ JavaScript Dependencies
|
|
|
667
653
|
https://github.com/tetherto/qvac
|
|
668
654
|
@qvac/registry-schema@0.3.0
|
|
669
655
|
https://github.com/tetherto/qvac
|
|
670
|
-
@qvac/transcription-parakeet@0.
|
|
656
|
+
@qvac/transcription-parakeet@0.10.1
|
|
671
657
|
https://github.com/tetherto/qvac
|
|
672
|
-
@qvac/transcription-whispercpp@0.
|
|
658
|
+
@qvac/transcription-whispercpp@0.12.1
|
|
673
659
|
https://github.com/tetherto/qvac
|
|
674
|
-
@qvac/translation-nmtcpp@
|
|
660
|
+
@qvac/translation-nmtcpp@8.1.0
|
|
675
661
|
https://github.com/tetherto/qvac
|
|
676
|
-
@qvac/tts-ggml@0.
|
|
662
|
+
@qvac/tts-ggml@0.5.1
|
|
677
663
|
https://github.com/tetherto/qvac
|
|
678
|
-
@qvac/vla-ggml@0.
|
|
664
|
+
@qvac/vla-ggml@0.14.0
|
|
679
665
|
https://github.com/tetherto/qvac
|
|
680
666
|
adaptive-timeout@1.0.1
|
|
681
667
|
https://github.com/holepunchto/adaptive-timeout
|
package/dist/client/api/ocr.d.ts
CHANGED
|
@@ -10,6 +10,15 @@ import { type OCRClientParams, type OCRTextBlock, type OCRStats } from '../../sc
|
|
|
10
10
|
* @returns Object with blockStream generator, blocks promise, and stats promise
|
|
11
11
|
* @example
|
|
12
12
|
* ```typescript
|
|
13
|
+
* // Load an OCR model first. Registry GGUF models resolve their pipeline
|
|
14
|
+
* // and detector automatically:
|
|
15
|
+
* // EasyOCR (default): OCR_LATIN (CRAFT detector auto-derived)
|
|
16
|
+
* // DocTR: OCR_DOCTR (DBNet detector auto-derived)
|
|
17
|
+
* const modelId = await loadModel({
|
|
18
|
+
* modelSrc: OCR_LATIN.src,
|
|
19
|
+
* modelType: MODEL_TYPES.ggmlOcr,
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
13
22
|
* // Non-streaming mode (default) - get all blocks at once
|
|
14
23
|
* const { blocks } = ocr({ modelId, image: "/path/to/image.png" });
|
|
15
24
|
* for (const block of await blocks) {
|
package/dist/client/api/ocr.js
CHANGED
|
@@ -11,6 +11,15 @@ import { stream as streamRpc } from '../rpc/rpc-client.js';
|
|
|
11
11
|
* @returns Object with blockStream generator, blocks promise, and stats promise
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
|
+
* // Load an OCR model first. Registry GGUF models resolve their pipeline
|
|
15
|
+
* // and detector automatically:
|
|
16
|
+
* // EasyOCR (default): OCR_LATIN (CRAFT detector auto-derived)
|
|
17
|
+
* // DocTR: OCR_DOCTR (DBNet detector auto-derived)
|
|
18
|
+
* const modelId = await loadModel({
|
|
19
|
+
* modelSrc: OCR_LATIN.src,
|
|
20
|
+
* modelType: MODEL_TYPES.ggmlOcr,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
14
23
|
* // Non-streaming mode (default) - get all blocks at once
|
|
15
24
|
* const { blocks } = ocr({ modelId, image: "/path/to/image.png" });
|
|
16
25
|
* for (const block of await blocks) {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { stream as streamRpc } from '../rpc/rpc-client.js';
|
|
2
|
-
import { translateResponseSchema
|
|
3
|
-
import { detectOne } from '@qvac/langdetect-text';
|
|
4
|
-
import { TranslationFailedError } from '../../utils/errors-client.js';
|
|
2
|
+
import { translateResponseSchema } from '../../schemas/index.js';
|
|
5
3
|
/**
|
|
6
4
|
* Translates text from one language to another using a specified translation model.
|
|
7
5
|
* Supports both NMT (Neural Machine Translation) and LLM models.
|
|
@@ -44,22 +42,13 @@ import { TranslationFailedError } from '../../utils/errors-client.js';
|
|
|
44
42
|
* ```
|
|
45
43
|
*/
|
|
46
44
|
export function translate(params, options) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const detected = detectOne(params.text);
|
|
52
|
-
if (detected.code === 'und' || detected.language === 'Undetermined') {
|
|
53
|
-
throw new TranslationFailedError("Could not detect the source language. Please specify the 'from' parameter explicitly.");
|
|
54
|
-
}
|
|
55
|
-
sourceLanguage = detected.language;
|
|
56
|
-
}
|
|
45
|
+
// Source-language auto-detection lives in the worker now
|
|
46
|
+
// (server/bare/ops/translate.ts): `from` is passed through when present and
|
|
47
|
+
// resolved server-side when absent, so every language binding shares one
|
|
48
|
+
// detector instead of each shipping its own.
|
|
57
49
|
const request = {
|
|
58
50
|
type: 'translate',
|
|
59
|
-
...params
|
|
60
|
-
...(isLlm && {
|
|
61
|
-
from: sourceLanguage
|
|
62
|
-
})
|
|
51
|
+
...params
|
|
63
52
|
};
|
|
64
53
|
let stats;
|
|
65
54
|
let statsResolver = () => { };
|
|
@@ -16,10 +16,13 @@ export interface VideoResult {
|
|
|
16
16
|
* @param params - Video request parameters (model, prompt, dimensions, frame count, fps, sampler, seed, etc.).
|
|
17
17
|
* @returns A result object exposing `requestId` (stable identifier for this in-flight generation), `progressStream` (async iterator of `{ step, totalSteps, elapsedMs }`), `outputs` (promise of the generated video buffers, typically a single AVI file), and `stats` (promise of generation statistics).
|
|
18
18
|
*
|
|
19
|
-
* Supports `txt2vid` (text-to-video) and `img2vid` (image-to-video)
|
|
20
|
-
*
|
|
21
|
-
* `
|
|
22
|
-
* `
|
|
19
|
+
* Supports `txt2vid` (text-to-video) and `img2vid` (image-to-video) for both the
|
|
20
|
+
* Wan and LTX-2 layouts. For Wan `img2vid`, load the pipeline with
|
|
21
|
+
* `modelConfig.clipVisionModelSrc` set to `clip_vision_h.safetensors`; LTX-2
|
|
22
|
+
* `img2vid` conditions on the first frame through its video VAE and needs no
|
|
23
|
+
* CLIP vision weights (the same LTX-2 model loaded for txt2vid also does
|
|
24
|
+
* img2vid). On React Native, prefer a `modelId` loaded with a `delegate` since
|
|
25
|
+
* the bundled video diffusion models are too large for typical mobile devices.
|
|
23
26
|
*
|
|
24
27
|
* @example Basic txt2vid generation
|
|
25
28
|
* ```typescript
|
package/dist/client/api/video.js
CHANGED
|
@@ -8,10 +8,13 @@ import { decodeBase64, encodeBase64 } from '../../utils/encoding.js';
|
|
|
8
8
|
* @param params - Video request parameters (model, prompt, dimensions, frame count, fps, sampler, seed, etc.).
|
|
9
9
|
* @returns A result object exposing `requestId` (stable identifier for this in-flight generation), `progressStream` (async iterator of `{ step, totalSteps, elapsedMs }`), `outputs` (promise of the generated video buffers, typically a single AVI file), and `stats` (promise of generation statistics).
|
|
10
10
|
*
|
|
11
|
-
* Supports `txt2vid` (text-to-video) and `img2vid` (image-to-video)
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
* `
|
|
11
|
+
* Supports `txt2vid` (text-to-video) and `img2vid` (image-to-video) for both the
|
|
12
|
+
* Wan and LTX-2 layouts. For Wan `img2vid`, load the pipeline with
|
|
13
|
+
* `modelConfig.clipVisionModelSrc` set to `clip_vision_h.safetensors`; LTX-2
|
|
14
|
+
* `img2vid` conditions on the first frame through its video VAE and needs no
|
|
15
|
+
* CLIP vision weights (the same LTX-2 model loaded for txt2vid also does
|
|
16
|
+
* img2vid). On React Native, prefer a `modelId` loaded with a `delegate` since
|
|
17
|
+
* the bundled video diffusion models are too large for typical mobile devices.
|
|
15
18
|
*
|
|
16
19
|
* @example Basic txt2vid generation
|
|
17
20
|
* ```typescript
|
package/dist/client/api/vla.d.ts
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
import { type VlaClientRunParams, type VlaClientRunResult, type VlaHparams } from '../../schemas/index';
|
|
2
2
|
/**
|
|
3
|
-
* Run VLA inference on a loaded model (SmolVLA or
|
|
3
|
+
* Run VLA inference on a loaded model (SmolVLA, π₀.₅, or GR00T) and return the
|
|
4
4
|
* produced action chunk plus per-stage timings.
|
|
5
5
|
*
|
|
6
6
|
* @param params - Inference inputs.
|
|
7
7
|
* @param params.modelId - Identifier of the loaded VLA model (returned by
|
|
8
8
|
* `loadModel({ modelType: "vla", ... })`).
|
|
9
|
-
* @param params.images - The preprocessed camera frames
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
9
|
+
* @param params.images - The preprocessed camera frames, one per camera. For
|
|
10
|
+
* pixel-input models (SmolVLA, π₀.₅) each is a `Float32Array` of length
|
|
11
|
+
* `3 * imgWidth * imgHeight` in CHW layout, range `[-1, 1]`, produced by the
|
|
12
|
+
* addon's `preprocessImage()` (re-exported as `vlaPreprocessImage`). For
|
|
13
|
+
* patch-input models (GR00T, `hparams.imageInputMode === 'patches'`) each is
|
|
14
|
+
* the pre-patchified buffer of length `hparams.imagePatchElems` instead. Pass
|
|
15
|
+
* exactly `hparams.numCameras` frames (2 for SmolVLA and GR00T, 3 for π₀.₅).
|
|
14
16
|
* @param params.imgWidth - Width of each preprocessed image; must equal
|
|
15
17
|
* `hparams.visionImageSize`.
|
|
16
18
|
* @param params.imgHeight - Height of each preprocessed image; must equal
|
|
17
19
|
* `hparams.visionImageSize`.
|
|
18
20
|
* @param params.state - Robot end-effector / gripper state. For
|
|
19
|
-
* continuous-state models (SmolVLA) pad to `hparams.maxStateDim` with
|
|
21
|
+
* continuous-state models (SmolVLA, GR00T) pad to `hparams.maxStateDim` with
|
|
20
22
|
* `vlaPadState`. For discrete-state models (π₀.₅,
|
|
21
23
|
* `hparams.stateInputMode === 'discrete'`) the state is tokenised into the
|
|
22
24
|
* prompt and this buffer is ignored — pass an empty `Float32Array(0)`.
|
|
23
25
|
* @param params.tokens - Tokenized instruction (`Int32Array` of length
|
|
24
26
|
* `hparams.tokenizerMaxLength`). Tokenize on the consumer side with the
|
|
25
|
-
* model's tokenizer (SmolVLM2 for SmolVLA, PaliGemma/Gemma for
|
|
27
|
+
* model's tokenizer (SmolVLM2 for SmolVLA, PaliGemma/Gemma for π₀.₅,
|
|
28
|
+
* Qwen3-VL for GR00T).
|
|
26
29
|
* @param params.mask - Token attention mask (`Uint8Array` matching `tokens`).
|
|
27
|
-
* @param params.noise -
|
|
30
|
+
* @param params.noise - Seeded noise prior
|
|
28
31
|
* (`Float32Array` of length `hparams.chunkSize * hparams.maxActionDim`).
|
|
29
|
-
*
|
|
32
|
+
* Optional for SmolVLA / π₀.₅ (addon samples its own prior when omitted).
|
|
33
|
+
* Required for GR00T (`hparams.imageInputMode === 'patches'`).
|
|
30
34
|
* @returns A `VlaClientRunResult` with the produced `actions` Float32Array
|
|
31
35
|
* (length `chunkSize * actionDim`), the corresponding `chunkSize` /
|
|
32
36
|
* `actionDim` returned by the addon, and optional per-stage `stats`.
|
package/dist/client/api/vla.js
CHANGED
|
@@ -13,33 +13,37 @@ function f32FromBase64(b64) {
|
|
|
13
13
|
return new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Run VLA inference on a loaded model (SmolVLA or
|
|
16
|
+
* Run VLA inference on a loaded model (SmolVLA, π₀.₅, or GR00T) and return the
|
|
17
17
|
* produced action chunk plus per-stage timings.
|
|
18
18
|
*
|
|
19
19
|
* @param params - Inference inputs.
|
|
20
20
|
* @param params.modelId - Identifier of the loaded VLA model (returned by
|
|
21
21
|
* `loadModel({ modelType: "vla", ... })`).
|
|
22
|
-
* @param params.images - The preprocessed camera frames
|
|
23
|
-
*
|
|
24
|
-
* `
|
|
25
|
-
*
|
|
26
|
-
* `
|
|
22
|
+
* @param params.images - The preprocessed camera frames, one per camera. For
|
|
23
|
+
* pixel-input models (SmolVLA, π₀.₅) each is a `Float32Array` of length
|
|
24
|
+
* `3 * imgWidth * imgHeight` in CHW layout, range `[-1, 1]`, produced by the
|
|
25
|
+
* addon's `preprocessImage()` (re-exported as `vlaPreprocessImage`). For
|
|
26
|
+
* patch-input models (GR00T, `hparams.imageInputMode === 'patches'`) each is
|
|
27
|
+
* the pre-patchified buffer of length `hparams.imagePatchElems` instead. Pass
|
|
28
|
+
* exactly `hparams.numCameras` frames (2 for SmolVLA and GR00T, 3 for π₀.₅).
|
|
27
29
|
* @param params.imgWidth - Width of each preprocessed image; must equal
|
|
28
30
|
* `hparams.visionImageSize`.
|
|
29
31
|
* @param params.imgHeight - Height of each preprocessed image; must equal
|
|
30
32
|
* `hparams.visionImageSize`.
|
|
31
33
|
* @param params.state - Robot end-effector / gripper state. For
|
|
32
|
-
* continuous-state models (SmolVLA) pad to `hparams.maxStateDim` with
|
|
34
|
+
* continuous-state models (SmolVLA, GR00T) pad to `hparams.maxStateDim` with
|
|
33
35
|
* `vlaPadState`. For discrete-state models (π₀.₅,
|
|
34
36
|
* `hparams.stateInputMode === 'discrete'`) the state is tokenised into the
|
|
35
37
|
* prompt and this buffer is ignored — pass an empty `Float32Array(0)`.
|
|
36
38
|
* @param params.tokens - Tokenized instruction (`Int32Array` of length
|
|
37
39
|
* `hparams.tokenizerMaxLength`). Tokenize on the consumer side with the
|
|
38
|
-
* model's tokenizer (SmolVLM2 for SmolVLA, PaliGemma/Gemma for
|
|
40
|
+
* model's tokenizer (SmolVLM2 for SmolVLA, PaliGemma/Gemma for π₀.₅,
|
|
41
|
+
* Qwen3-VL for GR00T).
|
|
39
42
|
* @param params.mask - Token attention mask (`Uint8Array` matching `tokens`).
|
|
40
|
-
* @param params.noise -
|
|
43
|
+
* @param params.noise - Seeded noise prior
|
|
41
44
|
* (`Float32Array` of length `hparams.chunkSize * hparams.maxActionDim`).
|
|
42
|
-
*
|
|
45
|
+
* Optional for SmolVLA / π₀.₅ (addon samples its own prior when omitted).
|
|
46
|
+
* Required for GR00T (`hparams.imageInputMode === 'patches'`).
|
|
43
47
|
* @returns A `VlaClientRunResult` with the produced `actions` Float32Array
|
|
44
48
|
* (length `chunkSize * actionDim`), the corresponding `chunkSize` /
|
|
45
49
|
* `actionDim` returned by the addon, and optional per-stage `stats`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContextOverflowError, RequestIdConflictError, RequestNotFoundError, RequestRejectedByPolicyError } from '../../utils/errors-server.js';
|
|
1
|
+
import { ContextOverflowError, RequestIdConflictError, RequestNotFoundError, RequestRejectedByPolicyError, TranslationFailedError } from '../../utils/errors-server.js';
|
|
2
2
|
export class RPCError extends Error {
|
|
3
3
|
timestamp;
|
|
4
4
|
remoteStack;
|
|
@@ -112,6 +112,12 @@ const RECONSTRUCTORS = {
|
|
|
112
112
|
},
|
|
113
113
|
CONTEXT_OVERFLOW: (response) => {
|
|
114
114
|
return new ContextOverflowError(readOptionalNumberField(response.typedFields, 'promptTokens'), readOptionalNumberField(response.typedFields, 'ctxSize'), readOptionalStringField(response.typedFields, 'modelId'), response.cause);
|
|
115
|
+
},
|
|
116
|
+
// Source-language autodetect now fails server-side (translate detection moved
|
|
117
|
+
// into the worker), so this crosses the RPC and reconstructs as the typed
|
|
118
|
+
// class -- matching the Python client's reconstructor.
|
|
119
|
+
TRANSLATION_FAILED: (response) => {
|
|
120
|
+
return new TranslationFailedError(response.message, response.cause);
|
|
115
121
|
}
|
|
116
122
|
};
|
|
117
123
|
/**
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { diffusion, loadModel, unloadModel } from '@qvac/sdk';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
const diffusionModelSrc = process.argv[2] ||
|
|
5
|
+
'https://huggingface.co/leejet/ideogram-4-GGUF/resolve/main/ideogram4-Q4_0.gguf';
|
|
6
|
+
const uncondModelSrc = process.argv[3] ||
|
|
7
|
+
'https://huggingface.co/leejet/ideogram-4-GGUF/resolve/main/ideogram4_uncond-Q4_0.gguf';
|
|
8
|
+
const llmModelSrc = process.argv[4] ||
|
|
9
|
+
'https://huggingface.co/unsloth/Qwen3-VL-8B-Instruct-GGUF/resolve/main/Qwen3-VL-8B-Instruct-Q4_K_M.gguf';
|
|
10
|
+
const vaeModelSrc = process.argv[5] ||
|
|
11
|
+
'https://huggingface.co/Comfy-Org/flux2-dev/resolve/main/split_files/vae/flux2-vae.safetensors';
|
|
12
|
+
const outputDir = process.argv[6] || '.';
|
|
13
|
+
function formatMb(bytes) {
|
|
14
|
+
return (bytes / 1e6).toFixed(1);
|
|
15
|
+
}
|
|
16
|
+
// Ideogram 4 expects a JSON-serialized structured caption with explicit
|
|
17
|
+
// bounding boxes. Plain-text prompts produce degenerate or placeholder output.
|
|
18
|
+
const structuredPrompt = {
|
|
19
|
+
high_level_description: 'A bright product photo of one yellow coffee mug on a clean office desk with a tiny readable label that says IDEO.',
|
|
20
|
+
style_description: {
|
|
21
|
+
aesthetics: 'simple product photography, clean bright office desk, minimal composition',
|
|
22
|
+
lighting: 'soft studio light with gentle shadows',
|
|
23
|
+
photo: 'sharp focus, crisp readable label text',
|
|
24
|
+
medium: 'product photo',
|
|
25
|
+
color_palette: ['#FFD54A', '#FFFFFF', '#111111', '#7EC8E3']
|
|
26
|
+
},
|
|
27
|
+
compositional_deconstruction: {
|
|
28
|
+
canvas: 'Square canvas, upright orientation. All text is horizontal and readable.',
|
|
29
|
+
background: 'Clean white office desk with a soft blue background gradient.',
|
|
30
|
+
elements: [
|
|
31
|
+
{
|
|
32
|
+
type: 'obj',
|
|
33
|
+
bbox: [230, 260, 800, 740],
|
|
34
|
+
desc: 'Exactly one matte yellow ceramic coffee mug centered on the desk.'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'text',
|
|
38
|
+
bbox: [510, 360, 620, 640],
|
|
39
|
+
text: 'IDEO',
|
|
40
|
+
desc: 'Small black label printed horizontally on the mug.'
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
if (process.argv.includes('--help')) {
|
|
46
|
+
console.log('Usage: tsx examples/diffusion-ideogram.ts [model] [uncond] [llm] [vae] [output-dir]');
|
|
47
|
+
console.log('▸ Defaults use the four Hugging Face model URLs supported by the diffusion addon.');
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
let modelId;
|
|
51
|
+
try {
|
|
52
|
+
console.log('▸ Loading Ideogram 4 split-layout model...');
|
|
53
|
+
modelId = await loadModel({
|
|
54
|
+
modelSrc: diffusionModelSrc,
|
|
55
|
+
modelType: 'sdcpp-generation',
|
|
56
|
+
modelConfig: {
|
|
57
|
+
device: 'gpu',
|
|
58
|
+
threads: 4,
|
|
59
|
+
diffusion_fa: true,
|
|
60
|
+
offload_to_cpu: true,
|
|
61
|
+
llmModelSrc,
|
|
62
|
+
vaeModelSrc,
|
|
63
|
+
uncondModelSrc
|
|
64
|
+
},
|
|
65
|
+
onProgress: (progress) => {
|
|
66
|
+
const line = `▸ Downloading ${progress.percentage.toFixed(0)}% (${formatMb(progress.downloaded)}/${formatMb(progress.total)} MB)`;
|
|
67
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
68
|
+
if (progress.percentage >= 100)
|
|
69
|
+
process.stderr.write('\n');
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
73
|
+
const { progressStream, outputs, stats } = diffusion({
|
|
74
|
+
modelId,
|
|
75
|
+
prompt: JSON.stringify(structuredPrompt),
|
|
76
|
+
width: 768,
|
|
77
|
+
height: 768,
|
|
78
|
+
steps: 16,
|
|
79
|
+
cfg_scale: 7,
|
|
80
|
+
seed: 42
|
|
81
|
+
});
|
|
82
|
+
for await (const { step, totalSteps } of progressStream) {
|
|
83
|
+
console.log(`▸ step ${step}/${totalSteps}`);
|
|
84
|
+
}
|
|
85
|
+
const buffers = await outputs;
|
|
86
|
+
for (let i = 0; i < buffers.length; i++) {
|
|
87
|
+
const outputPath = path.join(outputDir, `ideogram_${i}.png`);
|
|
88
|
+
fs.writeFileSync(outputPath, buffers[i]);
|
|
89
|
+
console.log(`▸ Saved ${outputPath}`);
|
|
90
|
+
}
|
|
91
|
+
console.log('▸ Stats:', await stats);
|
|
92
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
93
|
+
modelId = undefined;
|
|
94
|
+
console.log('▸ Done');
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (modelId) {
|
|
99
|
+
try {
|
|
100
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Preserve the original error.
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
console.error('✖', error);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { loadModel, unloadModel, video } from '@qvac/sdk';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
// Image-to-video (+ synchronized audio) with LTX-2. Unlike Wan I2V, LTX-2
|
|
5
|
+
// conditions on the first frame through its video VAE, so it needs NO CLIP
|
|
6
|
+
// vision weights (clipVisionModelSrc) — the same LTX-2 layout used for
|
|
7
|
+
// txt2vid works for img2vid, you just add an init_image at generation time.
|
|
8
|
+
//
|
|
9
|
+
// This example needs powerful hardware: LTX-2.3 is a ~21B model, budget at
|
|
10
|
+
// least 20+ GB of video / unified memory.
|
|
11
|
+
//
|
|
12
|
+
// No LTX-2 model constants ship in the SDK registry, so the model sources
|
|
13
|
+
// default to public HuggingFace URLs (the SDK downloads http(s) sources
|
|
14
|
+
// directly). Pass your own paths / URLs via argv to override.
|
|
15
|
+
const HF = 'https://huggingface.co';
|
|
16
|
+
const initImagePath = process.argv[2];
|
|
17
|
+
const prompt = process.argv[3] || 'the subject slowly turns and smiles, soft natural lighting, cinematic';
|
|
18
|
+
const outputDir = process.argv[4] || '.';
|
|
19
|
+
const diffusionModelSrc = process.argv[5] ||
|
|
20
|
+
`${HF}/QuantStack/LTX-2.3-GGUF/resolve/main/LTX-2.3-distilled-1.1/LTX-2.3-22B-distilled-1.1-Q5_K_M.gguf`;
|
|
21
|
+
const llmModelSrc = process.argv[6] || `${HF}/unsloth/gemma-3-12b-it-GGUF/resolve/main/gemma-3-12b-it-UD-Q4_K_XL.gguf`;
|
|
22
|
+
const vaeModelSrc = process.argv[7] ||
|
|
23
|
+
`${HF}/unsloth/LTX-2.3-GGUF/resolve/main/vae/ltx-2.3-22b-distilled_video_vae.safetensors`;
|
|
24
|
+
const audioVaeModelSrc = process.argv[8] ||
|
|
25
|
+
`${HF}/unsloth/LTX-2.3-GGUF/resolve/main/vae/ltx-2.3-22b-distilled_audio_vae.safetensors`;
|
|
26
|
+
const embeddingsConnectorsModelSrc = process.argv[9] ||
|
|
27
|
+
`${HF}/unsloth/LTX-2.3-GGUF/resolve/main/text_encoders/ltx-2.3-22b-distilled_embeddings_connectors.safetensors`;
|
|
28
|
+
if (!initImagePath) {
|
|
29
|
+
console.error('✖ init image path is required');
|
|
30
|
+
console.error('Usage: bun run bare:example dist/examples/diffusion-img2vid-ltx.js ' +
|
|
31
|
+
'<initImagePath> [prompt] [outputDir] ' +
|
|
32
|
+
'[diffusionModelSrc] [llmModelSrc] [vaeModelSrc] [audioVaeModelSrc] [embeddingsConnectorsModelSrc]');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
console.log('▸ Loading LTX-2 model (diffusion + Gemma + video VAE + audio VAE + connectors)...');
|
|
37
|
+
// no clipVisionModelSrc — LTX-2 img2vid does not use CLIP vision.
|
|
38
|
+
const modelId = await loadModel({
|
|
39
|
+
modelSrc: diffusionModelSrc,
|
|
40
|
+
modelType: 'sdcpp-generation',
|
|
41
|
+
modelConfig: {
|
|
42
|
+
mode: 'video',
|
|
43
|
+
device: 'gpu',
|
|
44
|
+
threads: 4,
|
|
45
|
+
// Supplying embeddingsConnectorsModelSrc selects the LTX-2 layout.
|
|
46
|
+
llmModelSrc,
|
|
47
|
+
vaeModelSrc,
|
|
48
|
+
audioVaeModelSrc,
|
|
49
|
+
embeddingsConnectorsModelSrc,
|
|
50
|
+
diffusion_fa: true,
|
|
51
|
+
vae_tiling: true
|
|
52
|
+
},
|
|
53
|
+
onProgress: (p) => {
|
|
54
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
55
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
56
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
57
|
+
if (p.percentage >= 100)
|
|
58
|
+
process.stderr.write('\n');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
62
|
+
const init_image = new Uint8Array(fs.readFileSync(initImagePath));
|
|
63
|
+
console.log(`▸ Generating video for: "${prompt}"`);
|
|
64
|
+
const { progressStream, outputs, stats } = video({
|
|
65
|
+
modelId,
|
|
66
|
+
mode: 'img2vid',
|
|
67
|
+
prompt,
|
|
68
|
+
init_image,
|
|
69
|
+
negative_prompt: 'blurry, distorted, low quality, jittery, static, frozen, distorted audio',
|
|
70
|
+
strength: 0.85,
|
|
71
|
+
// LTX-2 requires width/height as multiples of 32 and (8*k + 1) frames (max 257).
|
|
72
|
+
width: 512,
|
|
73
|
+
height: 320,
|
|
74
|
+
video_frames: 121,
|
|
75
|
+
fps: 24,
|
|
76
|
+
steps: 10,
|
|
77
|
+
cfg_scale: 1.0,
|
|
78
|
+
seed: 42,
|
|
79
|
+
temporal_tiling: true
|
|
80
|
+
});
|
|
81
|
+
for await (const { step, totalSteps } of progressStream) {
|
|
82
|
+
console.log(`▸ step ${step}/${totalSteps}`);
|
|
83
|
+
}
|
|
84
|
+
const buffers = await outputs;
|
|
85
|
+
for (let i = 0; i < buffers.length; i++) {
|
|
86
|
+
const outputPath = path.join(outputDir, `ltx_i2v_${i}.avi`);
|
|
87
|
+
fs.writeFileSync(outputPath, buffers[i]);
|
|
88
|
+
console.log(`▸ Saved ${outputPath} (play in VLC to hear the muxed audio track)`);
|
|
89
|
+
}
|
|
90
|
+
console.log('▸ Stats:', await stats);
|
|
91
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
92
|
+
console.log('▸ Done');
|
|
93
|
+
process.exit(0);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error('✖', error);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|