@qvac/tts-ggml 0.13.0 → 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/README.md +84 -11
- package/docs/pocket-tts.md +12 -10
- package/examples/audio8-streaming.js +74 -0
- package/index.d.ts +43 -1130
- package/index.js +129 -3041
- package/lib/addonEvents.d.ts +26 -0
- package/lib/addonEvents.js +51 -0
- package/lib/conditioning.d.ts +50 -0
- package/lib/conditioning.js +184 -0
- package/lib/engineDetection.d.ts +14 -0
- package/lib/engineDetection.js +110 -0
- package/lib/engineIds.d.ts +15 -0
- package/lib/engineIds.js +39 -0
- package/lib/engineParams.d.ts +3 -0
- package/lib/engineParams.js +34 -0
- package/lib/engineSetup.d.ts +153 -0
- package/lib/engineSetup.js +2 -0
- package/lib/engines/audio8.d.ts +83 -0
- package/lib/engines/audio8.js +262 -0
- package/lib/engines/chatterbox.d.ts +10 -0
- package/lib/engines/chatterbox.js +112 -0
- package/lib/engines/cosyvoice.d.ts +87 -0
- package/lib/engines/cosyvoice.js +267 -0
- package/lib/engines/moss.d.ts +26 -0
- package/lib/engines/moss.js +177 -0
- package/lib/engines/mossSoundEffect.d.ts +41 -0
- package/lib/engines/mossSoundEffect.js +117 -0
- package/lib/engines/mossSpeech.d.ts +86 -0
- package/lib/engines/mossSpeech.js +228 -0
- package/lib/engines/parler.d.ts +71 -0
- package/lib/engines/parler.js +287 -0
- package/lib/engines/supertonic.d.ts +11 -0
- package/lib/engines/supertonic.js +115 -0
- package/lib/exclusiveQueue.d.ts +16 -0
- package/lib/exclusiveQueue.js +45 -0
- package/lib/jobFields.d.ts +20 -0
- package/lib/jobFields.js +73 -0
- package/lib/modelFiles.d.ts +207 -0
- package/lib/modelFiles.js +117 -0
- package/lib/nativeParams.d.ts +12 -0
- package/lib/nativeParams.js +73 -0
- package/lib/optionValidation.d.ts +2 -0
- package/lib/optionValidation.js +103 -0
- package/lib/options.d.ts +4 -0
- package/lib/options.js +17 -0
- package/lib/pocketLifecycle.d.ts +67 -0
- package/lib/pocketLifecycle.js +170 -0
- package/lib/reload.d.ts +12 -0
- package/lib/reload.js +76 -0
- package/lib/sentenceStream.d.ts +85 -0
- package/lib/sentenceStream.js +367 -0
- package/lib/setup.d.ts +7 -0
- package/lib/setup.js +169 -0
- package/lib/streamingSupport.d.ts +8 -0
- package/lib/streamingSupport.js +77 -0
- package/lib/types.d.ts +465 -0
- package/lib/types.js +2 -0
- package/lib/voiceControls.d.ts +12 -0
- package/lib/voiceControls.js +23 -0
- package/package.json +11 -10
- package/test/integration/audio8-streaming.test.js +66 -0
- package/test/integration/audio8.test.js +6 -12
- package/test/integration/gpu-smoke.test.js +2 -11
- package/test/integration/lavasr-enhancer.test.js +2 -15
- package/test/integration/moss-sfx.test.js +29 -4
- package/test/integration/moss.test.js +1 -1
- package/test/utils/desktopGpuBackend.js +21 -0
- package/test/utils/runTTS.js +1 -1
- package/tts.d.ts +1 -0
package/README.md
CHANGED
|
@@ -17,6 +17,22 @@ LavaSR neural denoise + 48 kHz bandwidth-extension enhancement. Unsure
|
|
|
17
17
|
which checkpoint to stage? Start with [Choosing a model](#choosing-a-model).
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
### CosyVoice3 Core ML sidecars
|
|
21
|
+
|
|
22
|
+
Apple builds support optional CosyVoice3 Core ML sidecars through the native
|
|
23
|
+
`speech-cpp` 2026-10-19 dependency. Export and placement details are in the
|
|
24
|
+
[CosyVoice3 Core ML guide](https://github.com/tetherto/qvac-fabric-speech.cpp/blob/ea128498e23d20cd122729275e92361b11a361df/engines/tts/docs/cosyvoice3.md#core-ml-sidecars).
|
|
25
|
+
Re-export existing CosyVoice3 LM sidecars with the updated exporter to include
|
|
26
|
+
the cache feedback correction for consecutive predictions.
|
|
27
|
+
|
|
28
|
+
The LM, flow frontend/decoder, F0 predictor and HiFT vocoder use resident
|
|
29
|
+
sidecars when present and fall back to ggml when unavailable. HiFT exports
|
|
30
|
+
use FP32 for waveform parity. Core ML chooses operation placement, so a
|
|
31
|
+
sidecar does not guarantee ANE execution or a speed improvement.
|
|
32
|
+
When a sidecar is present, `assessFit` returns an error with reason
|
|
33
|
+
`coreml-memory-estimate-unavailable`; its memory usage is not projected.
|
|
34
|
+
|
|
35
|
+
|
|
20
36
|
Runs in-process with a persistent native engine — the GGUFs, the S3Gen
|
|
21
37
|
preload, the ggml backend, and any voice-conditioning tensors are
|
|
22
38
|
loaded once and reused across every synthesis call. GPU acceleration
|
|
@@ -38,7 +54,7 @@ and registry prerequisites described under [MOSS](#moss).
|
|
|
38
54
|
|
|
39
55
|
- Batch synthesis (`run({ input })` → single PCM buffer).
|
|
40
56
|
- **Sentence-granularity streaming** — `runStreaming(asyncIterable)`:
|
|
41
|
-
yields
|
|
57
|
+
yields audio for each input sentence; Audio8 emits PCM as codec windows finish.
|
|
42
58
|
- **Native per-chunk streaming** — set `streamChunkTokens` and audio
|
|
43
59
|
flows out of the C++ engine chunk-by-chunk as T3 tokens produce
|
|
44
60
|
S3Gen+HiFT output; sub-second first-audio-out inside a single
|
|
@@ -675,6 +691,8 @@ Notes:
|
|
|
675
691
|
engine runs its ggml graph on the GPU (falling back to the ggml CPU backend
|
|
676
692
|
when no GPU backend initialises), a CPU engine keeps the scalar core.
|
|
677
693
|
`denoiserBackendDevice` / `denoiserBackendId` in the stats report where it ran.
|
|
694
|
+
- Android ARM Mali devices can use Vulkan for denoising with `config.useGPU: true`.
|
|
695
|
+
This path is validated on Pixel 9 Pro XL (Mali-G715).
|
|
678
696
|
- The tts-cpp UL-UNAS forward is implemented in
|
|
679
697
|
[qvac-fabric-speech.cpp#78](https://github.com/tetherto/qvac-fabric-speech.cpp/pull/78)
|
|
680
698
|
(scalar CPU port, validated bit-close to the ONNX reference); it requires a
|
|
@@ -964,6 +982,19 @@ await model.load()
|
|
|
964
982
|
await model.run({ input: 'Hello from a fully on-device pipeline.' })
|
|
965
983
|
```
|
|
966
984
|
|
|
985
|
+
`runStream(text)`, `runStreaming(asyncIterable)` and
|
|
986
|
+
`run({ input: text, streamOutput: true })` emit PCM as codec windows finish,
|
|
987
|
+
before the current text chunk's complete waveform is ready. Ordinary `run()`
|
|
988
|
+
retains batch synthesis. Native end markers have an empty `outputArray`. Use `response.await()`
|
|
989
|
+
for completion and aggregate statistics, including for asynchronous text input. PCM window sizes are fixed by the codec, so
|
|
990
|
+
`streamChunkTokens` and `streamFirstChunkTokens` remain unsupported.
|
|
991
|
+
|
|
992
|
+
The native streaming API is included in the pinned `speech-cpp` dependency.
|
|
993
|
+
Rebuild the addon to use it; an older published prebuild does not gain native
|
|
994
|
+
streaming from a JavaScript update alone.
|
|
995
|
+
Use [audio8-streaming.js](examples/audio8-streaming.js) to measure first PCM
|
|
996
|
+
and completion through the wrapper, excluding model loading.
|
|
997
|
+
|
|
967
998
|
Sampling is **repetition-aware**: a semantic token that repeats one from the
|
|
968
999
|
recent window is re-drawn under a narrower nucleus at a higher temperature,
|
|
969
1000
|
which is what keeps the model out of the babble attractor that pure top-p
|
|
@@ -987,6 +1018,15 @@ synthesis, the analysis half only to clone a voice or run a dialogue, so a
|
|
|
987
1018
|
text-only deployment can omit `files.mossCodecEncoder`. The backbones have 8B
|
|
988
1019
|
parameters, so MOSS targets desktop hosts; mobile is not supported.
|
|
989
1020
|
|
|
1021
|
+
On Metal, the backbone projects only the text-control logits needed during
|
|
1022
|
+
audio generation and omits text projection during the forced drain. Embedding
|
|
1023
|
+
tables stay on the GPU, and the model weight type is preserved.
|
|
1024
|
+
|
|
1025
|
+
When `dialogueReferences` contains one recording, its encoded codes also serve
|
|
1026
|
+
as continuation, avoiding a duplicate encoder pass during engine creation.
|
|
1027
|
+
Multiple references retain their joined-audio continuation encoding. Prepared
|
|
1028
|
+
reference codes stay cached per instance for batch and streaming synthesis.
|
|
1029
|
+
|
|
990
1030
|
```js
|
|
991
1031
|
const model = new TTSGgml({
|
|
992
1032
|
engine: TTSGgml.ENGINE_MOSS,
|
|
@@ -1072,20 +1112,16 @@ The combined desktop CUDA/Vulkan speech changes in
|
|
|
1072
1112
|
[Vulkan #308](https://github.com/tetherto/qvac-fabric-speech.cpp/pull/308),
|
|
1073
1113
|
including [CUDA #321](https://github.com/tetherto/qvac-fabric-speech.cpp/pull/321),
|
|
1074
1114
|
merged to native master at `84b02694001cfea863167776dbc185474a816656`.
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
`06f1b66806626a635904f31db6914ad2d0e71197`. The earlier native `f4d4c257`
|
|
1115
|
+
The exact native dependency versions are declared in [vcpkg.json](vcpkg.json),
|
|
1116
|
+
and the registry configuration is declared in
|
|
1117
|
+
[vcpkg-configuration.json](vcpkg-configuration.json). The earlier native `f4d4c257`
|
|
1079
1118
|
passed ten smaller-model CUDA/Vulkan cases; those results do not establish GPU
|
|
1080
1119
|
validation of the final native revision or the packaged addon. Rebuild the addon
|
|
1081
1120
|
before running its GPU tests. Native desktop results also do not establish
|
|
1082
1121
|
Android support or speech-quality signoff.
|
|
1083
1122
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
This baseline update completes the TTS registry configuration; packaged-addon
|
|
1087
|
-
CUDA/Vulkan inference still requires validation on provisioned GPU hosts before
|
|
1088
|
-
claiming a validated release.
|
|
1123
|
+
Packaged-addon CUDA/Vulkan inference still requires validation on provisioned
|
|
1124
|
+
GPU hosts before claiming a validated release.
|
|
1089
1125
|
|
|
1090
1126
|
From `packages/tts-ggml`, resolve the checked-in manifest without building or
|
|
1091
1127
|
downloading models (with `VCPKG_ROOT` set):
|
|
@@ -1128,7 +1164,29 @@ case completes. Run both files together without test filters: a successful full
|
|
|
1128
1164
|
run has 12 passing tests, including the two completion checks, and no skips.
|
|
1129
1165
|
Preflight only checks asset presence; actual model loading and inference must
|
|
1130
1166
|
also pass. These commands cover TTS, TTSD and Speech, not MOSS-SoundEffect (SFX).
|
|
1131
|
-
|
|
1167
|
+
To validate the fresh packaged addons on the provisioned Linux GPU runner,
|
|
1168
|
+
dispatch the existing integration workflow on the branch being tested:
|
|
1169
|
+
|
|
1170
|
+
```sh
|
|
1171
|
+
gh workflow run integration-test-nx.yml --repo tetherto/qvac --ref <branch> -f moss_packaged_gpu=true
|
|
1172
|
+
```
|
|
1173
|
+
|
|
1174
|
+
This opt-in mode retains the `release` environment gate and builds both addons
|
|
1175
|
+
from the dispatch SHA with build concurrency capped at two. It stages the fresh
|
|
1176
|
+
platform packages through `link:platform`, verifies that both CUDA and Vulkan
|
|
1177
|
+
plugins are present, then runs CUDA and Vulkan sequentially. Each backend must
|
|
1178
|
+
pass the 12 TTS/TTSD/Speech tests above, two SFX tests (including exact backend
|
|
1179
|
+
and no-fallback assertions for both GPU clips), and the focused ASR Spanish
|
|
1180
|
+
transcription test with default and hotword prompts. Fixture skips fail the run.
|
|
1181
|
+
CPU control cases remain part of the TTS/SFX suites.
|
|
1182
|
+
|
|
1183
|
+
The runner stages q8_0 TTS/TTSD/Speech/SFX backbones and q5_0 Transcribe, with
|
|
1184
|
+
the required codec precision preserved. TTS/TTSD q8_0 are generated on the
|
|
1185
|
+
runner from the source checkpoints using the pinned native quantizer. The
|
|
1186
|
+
artifacts retain source pins, model and prebuild hashes, the fresh prebuilds,
|
|
1187
|
+
and per-backend logs/results; model weights are removed and never uploaded.
|
|
1188
|
+
This mode does not publish. A dispatched or building run is not GPU validation:
|
|
1189
|
+
only passing case logs from both backends establish packaged-addon coverage.
|
|
1132
1190
|
|
|
1133
1191
|
Without strict mode, developer behavior is unchanged: an unpinned run accepts
|
|
1134
1192
|
the normal GPU cascade, missing model directories skip tests, and missing
|
|
@@ -1146,6 +1204,15 @@ to 30 seconds. It is not a speech model, and it ships as one GGUF. Select it
|
|
|
1146
1204
|
with `engine: TTSGgml.ENGINE_MOSS_SFX` or by staging `moss-sfx-*.gguf` in the
|
|
1147
1205
|
`modelDir`.
|
|
1148
1206
|
|
|
1207
|
+
Native generation reuses fixed cross-attention K/V across diffusion steps and
|
|
1208
|
+
uses Metal DiT FlashAttention when the GPU supports both attention shapes.
|
|
1209
|
+
Memory preflight includes the request cache (360 MiB for guided generation
|
|
1210
|
+
with the released models) alongside the scheduler's retained peak across text
|
|
1211
|
+
encoding, diffusion and VAE decoding, including repeated requests.
|
|
1212
|
+
FlashAttention can slightly change waveform samples. See the
|
|
1213
|
+
[native SoundEffect guide](https://github.com/tetherto/qvac-fabric-speech.cpp/blob/33174cc8693b1c8cdb44b5ff57b0f120bc89e454/engines/tts/docs/moss.md#moss-soundeffect)
|
|
1214
|
+
for precision details and the M1 Ultra measurements.
|
|
1215
|
+
|
|
1149
1216
|
```js
|
|
1150
1217
|
const sfx = new TTSGgml({
|
|
1151
1218
|
engine: TTSGgml.ENGINE_MOSS_SFX,
|
|
@@ -1549,6 +1616,7 @@ Runnable demos under `examples/`:
|
|
|
1549
1616
|
| `parler-enhanced.js` | Parler + LavaSR 48 kHz enhancement. `bare examples/parler-enhanced.js "Hello" Laura happy` |
|
|
1550
1617
|
| `cosyvoice-tts.js` | CosyVoice3 batch synth with the cross-engine emotion option (24 kHz; CPU by default, `--gpu` opts into Metal / desktop Vulkan / Android GPU). `bare examples/cosyvoice-tts.js --gpu "Hello" happy` |
|
|
1551
1618
|
| `cosyvoice-enhanced.js` | CosyVoice3 + LavaSR 48 kHz enhancement (add `--denoise` for the denoiser). `bare examples/cosyvoice-enhanced.js "Hello"` |
|
|
1619
|
+
| `audio8-streaming.js` | Measure Audio8 wrapper batch, streaming, or duplex latency: `bare examples/audio8-streaming.js ./models stream "Hello"`. Modes: `batch`, `stream`, `duplex`. |
|
|
1552
1620
|
| `audio8-tts.js` | Audio8 batch synth, optionally cloning a reference. Set `QVAC_TTS_AUDIO8_GPU=1` for the desktop GPU backend (CUDA or Vulkan on linux, Vulkan on Windows). `bare examples/audio8-tts.js "Hello" voice.wav "What it says."` |
|
|
1553
1621
|
| `moss-tts.js` | MOSS batch synth, optionally cloning a reference. Set `QVAC_TTS_MOSS_STREAM_FRAMES=25` for native chunk streaming, `QVAC_TTS_MOSS_DURATION=38` for a target length and `QVAC_TTS_MOSS_GPU=1` for the GPU backend. `bare examples/moss-tts.js "Hello" voice.wav` |
|
|
1554
1622
|
| `moss-sound-effect.js` | MOSS-SoundEffect text-to-sound-effects at 48 kHz. Set `QVAC_TTS_MOSS_SFX_GPU=1` for the GPU backend and `QVAC_TTS_MOSS_SFX_STEPS` to trade quality for time. `bare examples/moss-sound-effect.js "Rain on a tin roof." 5` |
|
|
@@ -1720,4 +1788,9 @@ Apache-2.0. See [LICENSE](./LICENSE).
|
|
|
1720
1788
|
|
|
1721
1789
|
## Pocket TTS
|
|
1722
1790
|
|
|
1791
|
+
The native `speech-cpp` dependency includes Pocket Metal, CUDA, Vulkan and
|
|
1792
|
+
OpenCL support in the native library. The JavaScript Pocket API continues
|
|
1793
|
+
to require `config.useGPU: false`; updating the native dependency does not
|
|
1794
|
+
remove that addon validation.
|
|
1795
|
+
|
|
1723
1796
|
See [Pocket TTS](docs/pocket-tts.md) for model conversion, addon/SDK usage, supported controls and validation commands.
|
package/docs/pocket-tts.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Pocket TTS
|
|
2
2
|
|
|
3
|
-
Pocket is an English
|
|
4
|
-
library
|
|
3
|
+
Pocket is an English TTS engine implemented in the Fabric speech library.
|
|
4
|
+
The native library supports CPU, Metal, CUDA, Vulkan and OpenCL; the
|
|
5
|
+
`@qvac/tts-ggml` JavaScript API currently accepts CPU inference only.
|
|
6
|
+
It streams PCM16 audio through the addon. Python
|
|
5
7
|
is used only to convert weights and benchmark the upstream reference; it is
|
|
6
8
|
not needed for native synthesis. Inference plugin and public SDK integration
|
|
7
9
|
will follow in a separate change after the addon release.
|
|
@@ -139,22 +141,22 @@ audio and broad subjective quality evaluations remain outside this coverage.
|
|
|
139
141
|
|
|
140
142
|
## Native dependencies and measured performance
|
|
141
143
|
|
|
142
|
-
The
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
[
|
|
147
|
-
|
|
144
|
+
The exact native dependency versions are declared in [vcpkg.json](../vcpkg.json).
|
|
145
|
+
The Pocket GPU implementation comes from the merged
|
|
146
|
+
[Fabric #338](https://github.com/tetherto/qvac-fabric-speech.cpp/pull/338)
|
|
147
|
+
change, registered in
|
|
148
|
+
[registry #433](https://github.com/tetherto/qvac-registry-vcpkg/pull/433).
|
|
149
|
+
Pocket resolves CPU memory planning through the
|
|
148
150
|
backend registry, fixing the Linux/Android unresolved `ggml_graph_plan` import.
|
|
149
151
|
The native fixes are merged in [ggml #92](https://github.com/tetherto/qvac-ext-ggml/pull/92)
|
|
150
152
|
and [speech #251](https://github.com/tetherto/qvac-fabric-speech.cpp/pull/251).
|
|
151
153
|
|
|
152
|
-
Before the addon-only review revision,
|
|
154
|
+
Before the addon-only review revision, the original CPU-only native dependency versions passed
|
|
153
155
|
[the full prebuild and integration run](https://github.com/tetherto/qvac/actions/runs/34975293366)
|
|
154
156
|
at Fabric `49d864d2e1a2070a4cb9872cd0f62319fdb9e839`: nine platform prebuilds
|
|
155
157
|
and seven desktop integration lanes covering CPU, Metal, Vulkan and CUDA.
|
|
156
158
|
That run validates the native dependencies; it does not validate subsequent
|
|
157
|
-
JavaScript review changes.
|
|
159
|
+
JavaScript review changes. Those original native pins also passed all 10 Pocket
|
|
158
160
|
CTests with upstream numerical fixtures, static/dynamic CPU planner tests,
|
|
159
161
|
and 116 selected Supertonic Metal operations against CPU. Six paired
|
|
160
162
|
old-versus-merged native audio cases produced bit-identical PCM; this is
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const TTSGgml = require('..')
|
|
4
|
+
const process = require('bare-process')
|
|
5
|
+
|
|
6
|
+
const DEFAULT_TEXT = 'The first audio should arrive while the rest of this response is generated.'
|
|
7
|
+
const MODES = ['batch', 'stream', 'duplex']
|
|
8
|
+
|
|
9
|
+
async function* textSource(text) {
|
|
10
|
+
yield text
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function start(model, mode, text) {
|
|
14
|
+
if (mode === 'batch') return model.run({ input: text })
|
|
15
|
+
if (mode === 'stream') return model.runStream(text, { maxChunkScalars: Array.from(text).length })
|
|
16
|
+
return model.runStreaming(textSource(text), { accumulateSentences: false })
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function measure(model, mode, text) {
|
|
20
|
+
const started = Date.now()
|
|
21
|
+
let firstAudioMs = null
|
|
22
|
+
let samples = 0
|
|
23
|
+
let sampleRate = 0
|
|
24
|
+
let chunks = 0
|
|
25
|
+
const response = await start(model, mode, text)
|
|
26
|
+
response.onUpdate((data) => {
|
|
27
|
+
if (!data.outputArray?.length) return
|
|
28
|
+
firstAudioMs ??= Date.now() - started
|
|
29
|
+
samples += data.outputArray.length
|
|
30
|
+
sampleRate = data.sampleRate
|
|
31
|
+
chunks++
|
|
32
|
+
})
|
|
33
|
+
await response.await()
|
|
34
|
+
if (firstAudioMs === null || sampleRate <= 0) throw new Error('Synthesis returned no audio')
|
|
35
|
+
console.log(
|
|
36
|
+
JSON.stringify({
|
|
37
|
+
mode,
|
|
38
|
+
firstAudioMs,
|
|
39
|
+
totalMs: Date.now() - started,
|
|
40
|
+
audioSeconds: samples / sampleRate,
|
|
41
|
+
chunks,
|
|
42
|
+
stats: response.stats
|
|
43
|
+
})
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function main() {
|
|
48
|
+
const [, , modelDir, mode = 'stream', text = DEFAULT_TEXT] = process.argv
|
|
49
|
+
if (!modelDir || !MODES.includes(mode)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
'Usage: bare examples/audio8-streaming.js MODEL_DIR [batch|stream|duplex] [TEXT]'
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
const model = new TTSGgml({
|
|
55
|
+
engine: TTSGgml.ENGINE_AUDIO8,
|
|
56
|
+
files: { modelDir },
|
|
57
|
+
greedy: true,
|
|
58
|
+
seed: 42,
|
|
59
|
+
threads: 4,
|
|
60
|
+
config: { useGPU: process.env.QVAC_TTS_AUDIO8_GPU === '1' },
|
|
61
|
+
opts: { stats: true }
|
|
62
|
+
})
|
|
63
|
+
try {
|
|
64
|
+
await model.load()
|
|
65
|
+
await measure(model, mode, text)
|
|
66
|
+
} finally {
|
|
67
|
+
await model.unload()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
main().catch((error) => {
|
|
72
|
+
console.error(error)
|
|
73
|
+
process.exitCode = 1
|
|
74
|
+
})
|