Forward backend options during streaming speech generation (#1389) (#1390)

This commit is contained in:
Hua.T
2026-10-11 17:23:05 -04:00
committed by GitHub
parent 55fadb4c56
commit e981d2d8fc
2 changed files with 31 additions and 5 deletions
@@ -92,7 +92,7 @@ class TextToSpeech(Pipeline):
# Streaming response
if stream:
return self.stream(texts, speaker, encoding)
return self.stream(texts, speaker, encoding, **kwargs)
# Transform text to speech
results = [self.execute(x, speaker, encoding, **kwargs) for x in texts]
@@ -137,7 +137,7 @@ class TextToSpeech(Pipeline):
return exists
def stream(self, texts, speaker, encoding):
def stream(self, texts, speaker, encoding, **kwargs):
"""
Iterates over texts, splits into segments and yields snippets of audio.
This method is designed to integrate with streaming LLM generation.
@@ -146,6 +146,7 @@ class TextToSpeech(Pipeline):
texts: list of input texts
speaker: speaker id
encoding: audio encoding format
kwargs: additional keyword args
Returns:
snippets of audio as NumPy arrays or audio bytes depending on encoding parameter
@@ -157,11 +158,11 @@ class TextToSpeech(Pipeline):
if x == "\n" or (x.strip().endswith(".") and len([y for y in buffer if y]) > 2):
data, buffer = "".join(buffer), []
yield self.execute(data, speaker, encoding)
yield self.execute(data, speaker, encoding, **kwargs)
if buffer:
data = "".join(buffer)
yield self.execute(data, speaker, encoding)
yield self.execute(data, speaker, encoding, **kwargs)
def execute(self, text, speaker, encoding, **kwargs):
"""
@@ -4,7 +4,9 @@ TextToSpeech module tests
import unittest
from unittest.mock import patch
from unittest.mock import call, patch
import numpy as np
from txtai.pipeline import TextToSpeech
@@ -80,3 +82,26 @@ class TestTextToSpeech(unittest.TestCase):
# Check that data is generated
self.assertGreater(len(speech), 0)
self.assertEqual(rate, 22050)
@patch("txtai.pipeline.audio.texttospeech.Kokoro")
@patch.object(TextToSpeech, "hasfile")
def testStreamingOptions(self, hasfile, kokoro):
"""
Test backend options reach both flushed and final streaming segments
"""
hasfile.side_effect = lambda _, name: name in ("model.onnx", "voices.json")
audio = np.array([0.1, -0.1], dtype=np.float32)
kokoro.return_value.return_value = (audio, 24000)
tts = TextToSpeech("neuml/kokoro-int8-onnx", rate=None)
chunks = list(tts(iter(["One ", "two ", "three.", "Tail"]), stream=True, speaker="af", speed=1.5, transcribe=False))
self.assertEqual(
kokoro.return_value.call_args_list,
[call("One two three.", "af", speed=1.5, transcribe=False), call("Tail", "af", speed=1.5, transcribe=False)],
)
self.assertEqual(len(chunks), 2)
for data, rate in chunks:
np.testing.assert_array_equal(data, audio)
self.assertEqual(rate, 24000)