mirror of
https://github.com/block/buzz.git
synced 2026-10-31 14:31:02 +00:00
perf(huddle): enable bit-exact streaming TTS by default
Signed-off-by: John Tennant <jtennant@squareup.com>
This commit is contained in:
@@ -426,8 +426,8 @@ fn tts_worker(
|
||||
// `tts_active` lifecycle: set on the first append while idle, cleared
|
||||
// whenever the player has fully drained — either in the idle timeout
|
||||
// arm or on item receipt before synthesis begins.
|
||||
// EXPERIMENTAL (latency bench): `Some(emit_frames)` = stream PCM deltas
|
||||
// out of Pocket as they are generated (see tts_streaming.rs).
|
||||
// `Some(emit_frames)` streams PCM deltas out of Pocket as they are
|
||||
// generated (see tts_streaming.rs). `None` is the operational fallback.
|
||||
let tts_streaming = streaming_emit_frames();
|
||||
// `first_append` = "no audio queued since the player last went idle".
|
||||
// Flipped by `build_sentence_append_buffer` on the first real append; the
|
||||
@@ -728,8 +728,8 @@ fn tts_worker(
|
||||
continue;
|
||||
}
|
||||
|
||||
// EXPERIMENTAL (latency bench): streaming synthesis path — see
|
||||
// tts_streaming.rs for the mechanics and exactness constraints.
|
||||
// Streaming synthesis path. See tts_streaming.rs for the mechanics
|
||||
// and exactness constraints.
|
||||
if let Some(emit_frames) = tts_streaming {
|
||||
let outcome = synthesize_streaming(
|
||||
&engine,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//! EXPERIMENTAL (latency bench): streaming synthesis path for the TTS worker.
|
||||
//! Streaming synthesis path for the TTS worker.
|
||||
//!
|
||||
//! `BUZZ_TTS_STREAMING=1` streams PCM deltas out of Pocket as they are
|
||||
//! generated instead of waiting for the full first-chunk synthesis.
|
||||
//! PCM deltas stream out of Pocket as they are generated instead of waiting
|
||||
//! for the full first-chunk synthesis. `BUZZ_TTS_STREAMING=0` restores the
|
||||
//! batch path as an operational fallback.
|
||||
//! `BUZZ_TTS_EMIT_FRAMES` tunes the delta size in Flow LM frames (80 ms of
|
||||
//! audio each). Default 12 = the Mimi decoder's native chunk, which keeps
|
||||
//! streamed audio bit-identical to the batch path; smaller deltas are faster
|
||||
@@ -12,17 +13,20 @@ use super::*;
|
||||
|
||||
use crate::huddle::pocket::{PocketTts, VoiceStyle};
|
||||
|
||||
/// Read the streaming env overrides once per worker: `Some(emit_frames)`
|
||||
/// when `BUZZ_TTS_STREAMING=1`, `None` for the production batch path.
|
||||
/// Read the streaming env overrides once per worker. Streaming defaults to the
|
||||
/// Mimi decoder's native 12-frame chunk; `BUZZ_TTS_STREAMING=0` opts out.
|
||||
pub(super) fn streaming_emit_frames() -> Option<usize> {
|
||||
std::env::var("BUZZ_TTS_STREAMING")
|
||||
.is_ok_and(|v| v == "1")
|
||||
.then(|| {
|
||||
std::env::var("BUZZ_TTS_EMIT_FRAMES")
|
||||
.ok()
|
||||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(12)
|
||||
})
|
||||
resolve_streaming_emit_frames(
|
||||
std::env::var("BUZZ_TTS_STREAMING").ok().as_deref(),
|
||||
std::env::var("BUZZ_TTS_EMIT_FRAMES").ok().as_deref(),
|
||||
)
|
||||
}
|
||||
|
||||
fn resolve_streaming_emit_frames(
|
||||
enabled: Option<&str>,
|
||||
emit_frames: Option<&str>,
|
||||
) -> Option<usize> {
|
||||
(enabled != Some("0")).then(|| emit_frames.and_then(|v| v.parse().ok()).unwrap_or(12))
|
||||
}
|
||||
|
||||
/// Playback context threaded through one streamed chunk.
|
||||
@@ -129,6 +133,26 @@ fn drive_streaming(
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn streaming_defaults_to_the_bit_exact_decoder_chunk() {
|
||||
assert_eq!(resolve_streaming_emit_frames(None, None), Some(12));
|
||||
assert_eq!(resolve_streaming_emit_frames(Some("1"), None), Some(12));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn streaming_can_be_disabled_for_operational_rollback() {
|
||||
assert_eq!(resolve_streaming_emit_frames(Some("0"), None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_emit_frames_remain_available_for_latency_benches() {
|
||||
assert_eq!(resolve_streaming_emit_frames(None, Some("6")), Some(6));
|
||||
assert_eq!(
|
||||
resolve_streaming_emit_frames(None, Some("invalid")),
|
||||
Some(12)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inference_failure_fades_the_retained_final_block() {
|
||||
let cancel = AtomicBool::new(false);
|
||||
|
||||
Reference in New Issue
Block a user