@qvac/tts-ggml 0.10.0 → 0.11.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.
@@ -7,18 +7,17 @@
7
7
 
8
8
  const os = require('bare-os')
9
9
  const path = require('bare-path')
10
- const proc = require('bare-process')
11
10
  const test = require('brittle')
12
11
 
13
12
  const { loadParlerTTS, runParlerTTS } = require('../utils/runParlerTTS')
14
13
  const { ensureParlerModel } = require('../utils/downloadModel')
15
14
  const { recordTtsStats } = require('../utils/perf-helper')
16
15
  const { TTS_TEST_THREADS } = require('../utils/testThreads')
16
+ const { NO_GPU, SKIP_PARLER_GPU_ONLY, PARLER_GPU_ONLY_USE_GPU } = require('../utils/gpuOnly')
17
17
 
18
18
  const platform = os.platform()
19
19
  const isMobile = platform === 'ios' || platform === 'android'
20
20
  const isApple = platform === 'darwin' || platform === 'ios'
21
- const NO_GPU = proc.env && proc.env.NO_GPU === 'true'
22
21
 
23
22
  function getBaseDir() {
24
23
  return isMobile && global.testDir ? global.testDir : '.'
@@ -137,7 +136,7 @@ test(
137
136
 
138
137
  test(
139
138
  'Parler TTS (ggml): description matrix — conflicts throw, per-call wins, defaults work',
140
- { timeout: 600000 },
139
+ { timeout: 600000, skip: SKIP_PARLER_GPU_ONLY },
141
140
  async (t) => {
142
141
  const baseDir = getBaseDir()
143
142
  const download = await ensureParlerModel({ targetDir: path.join(baseDir, 'models') })
@@ -191,7 +190,8 @@ test(
191
190
  threads: TTS_TEST_THREADS,
192
191
  parlerModelPath: download.path,
193
192
  voice: 'Laura',
194
- seed: 42
193
+ seed: 42,
194
+ useGPU: PARLER_GPU_ONLY_USE_GPU
195
195
  })
196
196
  try {
197
197
  // Per-call description conflict (same level) rejects.
@@ -234,7 +234,8 @@ test(
234
234
  threads: TTS_TEST_THREADS,
235
235
  parlerModelPath: download.path,
236
236
  description: 'A calm female voice, very clear audio.',
237
- seed: 42
237
+ seed: 42,
238
+ useGPU: PARLER_GPU_ONLY_USE_GPU
238
239
  })
239
240
  try {
240
241
  await t.exception(
@@ -252,7 +253,7 @@ test(
252
253
 
253
254
  test(
254
255
  'Parler TTS (ggml): emotion flag changes the audio; per-call switch needs no reload',
255
- { timeout: 600000 },
256
+ { timeout: 600000, skip: SKIP_PARLER_GPU_ONLY },
256
257
  async (t) => {
257
258
  const baseDir = getBaseDir()
258
259
  const download = await ensureParlerModel({ targetDir: path.join(baseDir, 'models') })
@@ -265,7 +266,8 @@ test(
265
266
  threads: TTS_TEST_THREADS,
266
267
  parlerModelPath: download.path,
267
268
  voice: 'Laura',
268
- seed: 42
269
+ seed: 42,
270
+ useGPU: PARLER_GPU_ONLY_USE_GPU
269
271
  })
270
272
  try {
271
273
  const text = 'The weather is wonderful today.'
@@ -300,7 +302,7 @@ test(
300
302
 
301
303
  test(
302
304
  'Parler TTS (ggml): fixed seed is deterministic across runs and reload',
303
- { timeout: 600000 },
305
+ { timeout: 600000, skip: SKIP_PARLER_GPU_ONLY },
304
306
  async (t) => {
305
307
  const baseDir = getBaseDir()
306
308
  const download = await ensureParlerModel({ targetDir: path.join(baseDir, 'models') })
@@ -314,7 +316,8 @@ test(
314
316
  parlerModelPath: download.path,
315
317
  voice: 'Laura',
316
318
  emotion: 'neutral',
317
- seed: 42
319
+ seed: 42,
320
+ useGPU: PARLER_GPU_ONLY_USE_GPU
318
321
  })
319
322
  try {
320
323
  const text = 'Deterministic synthesis check.'
@@ -345,7 +348,7 @@ test(
345
348
 
346
349
  test(
347
350
  'Parler TTS (ggml): runStream emits per-sentence chunks with one pinned description',
348
- { timeout: 600000 },
351
+ { timeout: 600000, skip: SKIP_PARLER_GPU_ONLY },
349
352
  async (t) => {
350
353
  const baseDir = getBaseDir()
351
354
  const download = await ensureParlerModel({ targetDir: path.join(baseDir, 'models') })
@@ -360,6 +363,7 @@ test(
360
363
  engine: TTSGgml.ENGINE_PARLER,
361
364
  files: { parlerModel: download.path },
362
365
  seed: 42,
366
+ config: { useGPU: PARLER_GPU_ONLY_USE_GPU },
363
367
  opts: { stats: true }
364
368
  })
365
369
  await model.load()
@@ -393,7 +397,7 @@ test(
393
397
 
394
398
  test(
395
399
  'Parler TTS (ggml): native streaming emits monotonic chunks equal to batch',
396
- { timeout: 900000 },
400
+ { timeout: 900000, skip: SKIP_PARLER_GPU_ONLY },
397
401
  async (t) => {
398
402
  const baseDir = getBaseDir()
399
403
  const download = await ensureParlerModel({ targetDir: path.join(baseDir, 'models') })
@@ -526,22 +530,24 @@ test(
526
530
 
527
531
  // Desktop quant + backend coverage: q8_0 + f16 for indic/mini, q8_0 for large.
528
532
  // Runs on the platform's GPU-if-available backend (Metal on Apple GPU runners,
529
- // CPU otherwise). large self-gates on RAM; any tier that isn't staged skips
530
- // (t.pass) so a not-yet-registered tier never fails CI. Registered per PR #3372.
531
- // Desktop-only: the mobile Parler surface is covered by the gpu-smoke legs.
533
+ // CPU otherwise). mini f16 and large are the slowest tiers on CPU (roughly
534
+ // 45-80 s per synthesis), so they run on Metal only. large self-gates on RAM; any tier that isn't
535
+ // staged skips (t.pass) so a not-yet-registered tier never fails CI. Registered
536
+ // per PR #3372. Desktop-only: the mobile Parler surface is covered by the
537
+ // gpu-smoke legs.
532
538
  const PARLER_QUANT_MATRIX = [
533
- { variant: 'indic', quant: 'q8_0' },
534
- { variant: 'indic', quant: 'f16' },
535
- { variant: 'mini', quant: 'q8_0' },
536
- { variant: 'mini', quant: 'f16' },
537
- { variant: 'large', quant: 'q8_0' }
539
+ { variant: 'indic', quant: 'q8_0', gpuOnly: false },
540
+ { variant: 'indic', quant: 'f16', gpuOnly: false },
541
+ { variant: 'mini', quant: 'q8_0', gpuOnly: false },
542
+ { variant: 'mini', quant: 'f16', gpuOnly: true },
543
+ { variant: 'large', quant: 'q8_0', gpuOnly: true }
538
544
  ]
539
545
  const LARGE_MIN_RAM_BYTES = 16 * 1024 ** 3
540
546
 
541
- for (const { variant, quant } of PARLER_QUANT_MATRIX) {
547
+ for (const { variant, quant, gpuOnly } of PARLER_QUANT_MATRIX) {
542
548
  test(
543
549
  `Parler TTS (ggml): ${variant} ${quant} synthesizes 44.1 kHz audio on the target backend`,
544
- { timeout: 900000, skip: isMobile },
550
+ { timeout: 900000, skip: isMobile || (gpuOnly && SKIP_PARLER_GPU_ONLY) },
545
551
  async (t) => {
546
552
  if (variant === 'large' && os.totalmem() < LARGE_MIN_RAM_BYTES) {
547
553
  t.pass(
@@ -50,6 +50,14 @@ async function runLavasrEnhancerTest (options = {}) { // eslint-disable-line no-
50
50
  return runIntegrationModule('../integration/lavasr-enhancer.test.js', options)
51
51
  }
52
52
 
53
+ async function runMossSfxTest (options = {}) { // eslint-disable-line no-unused-vars
54
+ return runIntegrationModule('../integration/moss-sfx.test.js', options)
55
+ }
56
+
57
+ async function runMossSpeechTest (options = {}) { // eslint-disable-line no-unused-vars
58
+ return runIntegrationModule('../integration/moss-speech.test.js', options)
59
+ }
60
+
53
61
  async function runMossTest (options = {}) { // eslint-disable-line no-unused-vars
54
62
  return runIntegrationModule('../integration/moss.test.js', options)
55
63
  }
@@ -70,6 +78,10 @@ async function runParlerTest (options = {}) { // eslint-disable-line no-unused-v
70
78
  return runIntegrationModule('../integration/parler.test.js', options)
71
79
  }
72
80
 
81
+ async function runPocketIntegrationTest (options = {}) { // eslint-disable-line no-unused-vars
82
+ return runIntegrationModule('../integration/pocket.integration.test.js', options)
83
+ }
84
+
73
85
  async function runRtfBenchmarkTest (options = {}) { // eslint-disable-line no-unused-vars
74
86
  return runIntegrationModule('../integration/rtf-benchmark.test.js', options)
75
87
  }
@@ -106,11 +118,14 @@ module.exports = {
106
118
  runFitTest,
107
119
  runGpuSmokeTest,
108
120
  runLavasrEnhancerTest,
121
+ runMossSfxTest,
122
+ runMossSpeechTest,
109
123
  runMossTest,
110
124
  runMultipleRunsTest,
111
125
  runOutputSampleRateTest,
112
126
  runParlerWerTest,
113
127
  runParlerTest,
128
+ runPocketIntegrationTest,
114
129
  runRtfBenchmarkTest,
115
130
  runStreamingBenchmarkTest,
116
131
  runSupertonicMtlTest,
package/tts.d.ts CHANGED
@@ -17,6 +17,26 @@ export interface TTSJobData {
17
17
  instruct?: string;
18
18
  referenceAudio?: string;
19
19
  referenceText?: string;
20
+ seconds?: number;
21
+ negativePrompt?: string;
22
+ steps?: number;
23
+ guidance?: number;
24
+ shift?: number;
25
+ messages?: Array<{
26
+ role: string;
27
+ text?: string;
28
+ audio?: Int16Array | Float32Array;
29
+ sampleRate?: number;
30
+ }>;
31
+ replyVoice?: Int16Array | Float32Array;
32
+ replyVoiceSampleRate?: number;
33
+ textReply?: boolean;
34
+ maxReplySeconds?: number;
35
+ maxNewTokens?: number;
36
+ greedy?: boolean;
37
+ temperature?: number;
38
+ topP?: number;
39
+ topK?: number;
20
40
  }
21
41
  export interface TTSWeightData {
22
42
  filename: string;