Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion docs/models/breeze_tts.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,30 @@ audiocpp_cli \
--out breeze_tts_design.wav
```

Streaming:

```bash
audiocpp_cli \
--task tts \
--mode streaming \
--family breeze_tts \
--model models/Breeze-TTS-2-GGUF/breeze-tts-2-q8_0.gguf \
--backend cuda \
--text "Welcome to the BreezeTTS 2 streaming demo." \
--request-option instruction="A confident product demo narrator with steady pacing." \
--request-option stream_frames_per_event=16 \
--out breeze_tts_stream.wav \
--out-dir breeze_tts_stream_chunks
```

## Model

| Field | Value |
|---|---|
| Family | `breeze_tts` |
| Default GGUF | `models/Breeze-TTS-2-GGUF/breeze-tts-2-q8_0.gguf` |
| Tasks | `tts`, `clon` |
| Modes | `offline` |
| Modes | `offline`, `streaming` |
| Languages | `zh`, `en` |
| Voice input | Optional for `tts`; required for `clon` |

Expand All @@ -66,10 +82,32 @@ audiocpp_cli \
| `--request-option top_k=<n>` | integer >= 0 | `50` | Top-k sampling limit; `0` disables top-k filtering. |
| `--request-option top_p=<f>` | `0..1` | `1.0` | Top-p sampling limit. |
| `--request-option seed=<n>` | integer >= 0 | `0` | Generation seed. |
| `--request-option stream_frames_per_event=<n>` | integer > 0 | `16` | Streaming codec frames per emitted audio event. Smaller values can reduce TTFT but increase event/decoder overhead. |
| `--request-option stream_lookahead_margin=<n>` | integer >= 0 | `12` | Trailing codec frames held before emission to reduce streaming boundary artifacts. |
| `--session-option breeze_tts.reference_cache_slots=<n>` | integer >= 0 | `1` | Prepared reference-audio cache slots. |
| `--session-option breeze_tts.attention=<mode>` | `auto`, `flash`, `eager` | `auto` | Attention kernel. `auto` uses flash except on Volta/Turing GPUs (e.g. V100), where it falls back to eager to avoid missing MMA kernels. |
| `--session-option weight_type=<type>` | `native`, `f32`, `f16`, `bf16`, `q8_0`, `q4_0`, `q4_k` | `native` | Weight storage type; quantized types convert at load time from the BF16 package. |

BreezeTTS streaming is incremental by default. It emits audio events from the
generated codec-frame stream instead of waiting for a whole text chunk. For the
OpenAI-compatible speech endpoint, pass streaming options inside the request
`options` object:

```json
{
"model": "breeze-stream",
"input": "Welcome to the BreezeTTS 2 streaming demo.",
"stream": true,
"stream_format": "sse",
"response_format": "pcm",
"options": {
"instruction": "A confident product demo narrator with steady pacing.",
"stream_frames_per_event": "16",
"stream_lookahead_margin": "12"
}
}
```

Quantized weight storage is the largest measured speedup and applies to CUDA
and HIP alike: `q8_0` cut the fixed 100-token regression case from RTF ~1.5 to
~0.95 on gfx1151 and from ~0.77 to ~0.56 on an RTX 2080 Ti, and `q4_k` reached
Expand Down
8 changes: 8 additions & 0 deletions include/engine/models/breeze_tts/generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ struct BreezeGenerationRequest {
uint64_t seed = 0;
};

struct BreezeStreamEvent {
engine::runtime::AudioBuffer audio;
bool done = false;
};

class BreezeGeneratorRuntime {
public:
BreezeGeneratorRuntime(
Expand All @@ -42,6 +47,9 @@ class BreezeGeneratorRuntime {

engine::runtime::AudioBuffer generate(const BreezeGenerationRequest & request);
BreezeSpeechCodes encode_reference(const engine::runtime::AudioBuffer & audio) const;
void begin_stream(const BreezeGenerationRequest & request);
BreezeStreamEvent next_stream_audio(size_t max_new_frames, int64_t lookahead_margin);
void end_stream();

private:
struct Impl;
Expand Down
6 changes: 6 additions & 0 deletions include/engine/models/breeze_tts/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <cstddef>
#include <cstdint>
#include <chrono>
#include <memory>
#include <optional>
#include <vector>
Expand Down Expand Up @@ -77,7 +78,12 @@ class BreezeTTSSession final
std::vector<engine::runtime::TaskRequest> stream_chunk_requests_;
std::optional<BreezeSpeechCodes> stream_reference_codes_;
engine::runtime::AudioBuffer stream_merged_audio_;
std::chrono::steady_clock::time_point stream_started_at_;
size_t stream_chunk_index_ = 0;
size_t stream_frames_per_event_ = 16;
int64_t stream_lookahead_margin_ = 12;
bool stream_chunk_active_ = false;
size_t stream_event_seq_ = 0;
bool stream_started_ = false;
};

Expand Down
12 changes: 12 additions & 0 deletions include/engine/models/breeze_tts/speech_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,31 @@ class BreezeSpeechDecoderRuntime {
~BreezeSpeechDecoderRuntime();

runtime::AudioBuffer decode(const BreezeSpeechCodes & codec_codes) const;
void reset_streaming_state() const;
runtime::AudioBuffer decode_streaming_step(
const BreezeSpeechCodes & codec_codes,
int64_t lookahead_margin,
bool final) const;
runtime::AudioBuffer decode_and_trim_reference(
const BreezeSpeechCodes & reference_codes,
const BreezeSpeechCodes & generated_codes) const;
void release_runtime_graphs() const;

private:
std::vector<float> decode_window_samples(
const std::vector<int32_t> & chunk,
int64_t chunk_frames,
int64_t context_frames) const;

std::shared_ptr<const BreezeTTSAssets> assets_;
core::ExecutionContext * execution_context_ = nullptr;
std::shared_ptr<const BreezeSpeechDecoderWeights> weights_;
size_t graph_arena_bytes_ = 0;
bool allow_flash_attention_ = true;
std::unique_ptr<core::ConstantTensorCache> constants_;
mutable std::unique_ptr<BreezeSpeechDecoderGraph> graph_;
struct StreamingState;
mutable std::unique_ptr<StreamingState> streaming_state_;
// Always present to keep this public class layout identical when the private
// Strix Halo compile definition differs between translation units.
mutable std::array<std::unique_ptr<BreezeSpeechDecoderGraph>, 2> optimized_graphs_;
Expand Down
16 changes: 16 additions & 0 deletions model_specs/breeze_tts.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,22 @@
"required": false,
"min": 0,
"default": 0
},
{
"name": "stream_frames_per_event",
"type": "int",
"description": "Generated codec frames per streaming audio event.",
"required": false,
"min": 1,
"default": 16
},
{
"name": "stream_lookahead_margin",
"type": "int",
"description": "Trailing codec frames held before emission to reduce streaming boundary artifacts.",
"required": false,
"min": 0,
"default": 12
}
],
"session": [
Expand Down
Loading
Loading