@qvac/tts-ggml 0.13.0 → 0.14.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/README.md +51 -10
- package/docs/pocket-tts.md +12 -10
- package/index.d.ts +43 -1130
- package/index.js +127 -3042
- 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.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
|
@@ -34,6 +34,7 @@ const {
|
|
|
34
34
|
const { resolveRefWavPath } = require('../utils/runChatterboxTTS')
|
|
35
35
|
const { TTS_TEST_THREADS } = require('../utils/testThreads')
|
|
36
36
|
const { GPU_ONLY_USE_GPU } = require('../utils/gpuOnly')
|
|
37
|
+
const { assertDesktopGpuBackend } = require('../utils/desktopGpuBackend')
|
|
37
38
|
|
|
38
39
|
const platform = os.platform()
|
|
39
40
|
const isMobile = platform === 'ios' || platform === 'android'
|
|
@@ -42,11 +43,6 @@ const isMobile = platform === 'ios' || platform === 'android'
|
|
|
42
43
|
// fallback from a failure to a warning (e.g. a Linux host with no Vulkan SDK).
|
|
43
44
|
const NO_GPU = proc.env && proc.env.NO_GPU === 'true'
|
|
44
45
|
const RELAX = proc.env && proc.env.QVAC_TTS_GPU_SMOKE_RELAX === '1'
|
|
45
|
-
const GPU_BACKEND_IDS = { metal: 1, cuda: 2, vulkan: 3, opencl: 4 }
|
|
46
|
-
// CI rows whose prebuild bundles more than one usable GPU backend (the linux
|
|
47
|
-
// runners carry CUDA and Vulkan) pin the engine cascade through
|
|
48
|
-
// TTS_CPP_GPU_BACKEND; the enhancer assertion expects whatever the row pinned
|
|
49
|
-
// and falls back to the platform's cascade default when unset.
|
|
50
46
|
const PINNED_GPU_BACKEND = (proc.env && proc.env.TTS_CPP_GPU_BACKEND) || ''
|
|
51
47
|
|
|
52
48
|
const ENHANCED_RATE = 48000
|
|
@@ -92,10 +88,6 @@ function expectsGpu() {
|
|
|
92
88
|
)
|
|
93
89
|
}
|
|
94
90
|
|
|
95
|
-
function expectedDesktopEnhancerBackendId() {
|
|
96
|
-
return GPU_BACKEND_IDS[PINNED_GPU_BACKEND] || GPU_BACKEND_IDS.vulkan
|
|
97
|
-
}
|
|
98
|
-
|
|
99
91
|
// Strict check that the LavaSR *enhancer* network engaged the GPU. Reads the
|
|
100
92
|
// enhancer-specific backend surfaced by ChatterboxModel/SupertonicModel
|
|
101
93
|
// runtimeStats (enhancerBackendDevice: -1 none / 0 CPU / 1 GPU;
|
|
@@ -134,12 +126,7 @@ function assertEnhancerGpuBackend(t, stats) {
|
|
|
134
126
|
if (platform === 'darwin' || platform === 'ios') {
|
|
135
127
|
t.is(id, 1, `enhancer/${platform}: expected Metal backendId=1, got ${backendIdToName(id)}`)
|
|
136
128
|
} else if (platform === 'linux' || platform === 'win32') {
|
|
137
|
-
|
|
138
|
-
t.is(
|
|
139
|
-
id,
|
|
140
|
-
expectedId,
|
|
141
|
-
`enhancer/${platform}: expected ${backendIdToName(expectedId)} backendId=${expectedId}, got ${backendIdToName(id)}`
|
|
142
|
-
)
|
|
129
|
+
assertDesktopGpuBackend(t, `enhancer/${platform}`, dev, id, PINNED_GPU_BACKEND)
|
|
143
130
|
} else if (platform === 'android') {
|
|
144
131
|
t.ok(
|
|
145
132
|
id === 3 || id === 4,
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const path = require('bare-path')
|
|
4
|
+
const fs = require('bare-fs')
|
|
4
5
|
const proc = require('bare-process')
|
|
5
6
|
const test = require('brittle')
|
|
6
7
|
|
|
7
8
|
const TTSGgml = require('@qvac/tts-ggml')
|
|
9
|
+
const { assertMossBackend } = require('../utils/mossBackend')
|
|
8
10
|
|
|
9
11
|
const SFX_SAMPLE_RATE = 48000
|
|
10
12
|
const TENTHS_PER_SECOND = 10
|
|
@@ -14,13 +16,35 @@ const MODEL_DIR_ENV = 'QVAC_TEST_MOSS_SFX_MODEL_DIR'
|
|
|
14
16
|
const QUICK_STEPS = 2
|
|
15
17
|
const SHORT_SECONDS = 1.5
|
|
16
18
|
const LONGER_SECONDS = 2.5
|
|
17
|
-
const
|
|
18
|
-
const GPU_DEVICE = 1
|
|
19
|
+
const PINNED_GPU_BACKEND = (proc.env && proc.env.TTS_CPP_GPU_BACKEND) || ''
|
|
19
20
|
|
|
20
21
|
const modelDir = (proc.env && proc.env[MODEL_DIR_ENV]) || ''
|
|
21
22
|
const skipWithoutModels = modelDir === ''
|
|
22
23
|
const noGpu = proc.env && proc.env.NO_GPU === 'true'
|
|
23
24
|
|
|
25
|
+
if (proc.env && proc.env.QVAC_TEST_MOSS_FULL_GPU === 'true') {
|
|
26
|
+
if (noGpu || !['cuda', 'vulkan', 'metal', 'opencl'].includes(PINNED_GPU_BACKEND.toLowerCase())) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
'MOSS-SFX full GPU validation requires an explicit GPU backend and NO_GPU=false'
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
if (
|
|
32
|
+
!modelDir ||
|
|
33
|
+
!fs.existsSync(modelDir) ||
|
|
34
|
+
!fs
|
|
35
|
+
.readdirSync(modelDir)
|
|
36
|
+
.some(
|
|
37
|
+
(name) =>
|
|
38
|
+
/^moss-sfx(-[a-z0-9_]+)*\.gguf$/i.test(name) &&
|
|
39
|
+
fs.statSync(path.join(modelDir, name)).isFile()
|
|
40
|
+
)
|
|
41
|
+
) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
'MOSS-SFX full GPU validation requires QVAC_TEST_MOSS_SFX_MODEL_DIR with a GGUF'
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
24
48
|
function createSfxModel(useGPU = false) {
|
|
25
49
|
return new TTSGgml({
|
|
26
50
|
engine: TTSGgml.ENGINE_MOSS_SFX,
|
|
@@ -70,7 +94,7 @@ test(
|
|
|
70
94
|
try {
|
|
71
95
|
const result = await generate(model, { seconds: SHORT_SECONDS })
|
|
72
96
|
assertClip(t, 'cpu clip', result, SHORT_SECONDS)
|
|
73
|
-
t
|
|
97
|
+
assertMossBackend(t, 'cpu clip', result.stats, false, PINNED_GPU_BACKEND)
|
|
74
98
|
} finally {
|
|
75
99
|
await model.unload()
|
|
76
100
|
}
|
|
@@ -88,7 +112,8 @@ test(
|
|
|
88
112
|
const longer = await generate(model, { seconds: LONGER_SECONDS, negativePrompt: 'music' })
|
|
89
113
|
assertClip(t, 'short clip', short, SHORT_SECONDS)
|
|
90
114
|
assertClip(t, 'longer clip', longer, LONGER_SECONDS)
|
|
91
|
-
t
|
|
115
|
+
assertMossBackend(t, 'short clip', short.stats, true, PINNED_GPU_BACKEND)
|
|
116
|
+
assertMossBackend(t, 'longer clip', longer.stats, true, PINNED_GPU_BACKEND)
|
|
92
117
|
} finally {
|
|
93
118
|
await model.unload()
|
|
94
119
|
}
|
|
@@ -290,7 +290,7 @@ test(
|
|
|
290
290
|
{ dialogueReferences: references, seed: 7, files: { modelDir: path.resolve(modelDir) } },
|
|
291
291
|
async (model) => {
|
|
292
292
|
t.ok(
|
|
293
|
-
DIALOGUE_BACKBONE_RE.test(path.basename(model.
|
|
293
|
+
DIALOGUE_BACKBONE_RE.test(path.basename(model._setup.paths.mossBackbonePath)),
|
|
294
294
|
'dialogue picks the TTSD backbone'
|
|
295
295
|
)
|
|
296
296
|
const started = Date.now()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const GPU_DEVICE = 1
|
|
4
|
+
const GPU_BACKEND_IDS = { metal: 1, cuda: 2, vulkan: 3, opencl: 4 }
|
|
5
|
+
const AUTOMATIC_BACKEND_IDS = [GPU_BACKEND_IDS.cuda, GPU_BACKEND_IDS.vulkan]
|
|
6
|
+
|
|
7
|
+
function expectedBackendIds(pinnedBackend) {
|
|
8
|
+
if (!pinnedBackend) return AUTOMATIC_BACKEND_IDS
|
|
9
|
+
const name = pinnedBackend.toLowerCase()
|
|
10
|
+
return Object.prototype.hasOwnProperty.call(GPU_BACKEND_IDS, name) ? [GPU_BACKEND_IDS[name]] : []
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function assertDesktopGpuBackend(t, label, device, backendId, pinnedBackend = '') {
|
|
14
|
+
t.is(device, GPU_DEVICE, `${label}: GPU device required`)
|
|
15
|
+
t.ok(
|
|
16
|
+
expectedBackendIds(pinnedBackend).includes(backendId),
|
|
17
|
+
`${label}: expected ${pinnedBackend || 'CUDA or Vulkan'} backend, got backendId=${backendId}`
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = { assertDesktopGpuBackend }
|
package/test/utils/runTTS.js
CHANGED
|
@@ -58,7 +58,7 @@ async function runTTSWithSplit(model, params, expectation = {}, options = {}) {
|
|
|
58
58
|
const splitLanguage =
|
|
59
59
|
typeof params.splitLanguage === 'string' && params.splitLanguage.length > 0
|
|
60
60
|
? params.splitLanguage
|
|
61
|
-
: model?.
|
|
61
|
+
: model?._setup?.config?.language || 'en'
|
|
62
62
|
const splitOpts = {
|
|
63
63
|
language: splitLanguage,
|
|
64
64
|
mergeToMaxScalars: false,
|