Chatterbox Streaming

repository·master·Indexed 43 days ago

https://github.com/davidbrowne17/chatterbox-streaming

An open-source TTS and voice conversion model with a 0.5B Llama backbone, featuring real-time streaming capabilities and emotion exaggeration control. Version 0.1.3 includes the ChatterboxTTS client for full-sequence generation and low-latency streaming via generate_stream(), the S3Tokenizer for processing 16 kHz audio into speech tokens, and the AlignmentStreamAnalyzer for detecting hallucinations and repetitions during inference.

Tokens
4.5K
Snippets
13
Records
19
Agent score
55%

What's inside Chatterbox

  1. Fine-tune Chatterbox using GRPO

    master

    To perform GRPO fine-tuning:

    1. Place raw .wav files of the target speaker in a folder named audio_data.
    2. Run grpo.py.
    3. Configure training parameters (batch size, epochs, learning rate) at the top of grpo.py.

    Requirements:

    • CUDA GPU with at least 12GB VRAM.
    • Training progress is monitored via grpo_training_metrics.png.
  2. Install chatterbox-streaming

    master

    To install the package in a new Python 3.10 virtual environment, use the following commands:

    python3.10 -m venv .venv
    source .venv/bin/activate
    pip install chatterbox-streaming
    python3.10 -m venv .venv
    source .venv/bin/activate
    pip install chatterbox-streaming
  3. Tune speech expression and pacing

    master

    Use exaggeration and cfg_weight to control the style of the generated speech:

    • General Use: Use default settings (exaggeration=0.5, cfg_weight=0.5).
    • Fast Speakers: If the reference speaker is fast, lower cfg_weight to approximately 0.3 to improve pacing.
    • Dramatic/Expressive Speech: Increase exaggeration to 0.7 or higher. To prevent the increased speed caused by high exaggeration, lower cfg_weight (e.g., ~0.3) to maintain slower, more deliberate pacing.
  4. Fine-tune Chatterbox using LoRA

    master

    To perform LoRA fine-tuning:

    1. Place raw .wav files of the target speaker in a folder named audio_data.
    2. Run lora.py.
    3. Configure training parameters (batch size, epochs, learning rate) at the top of lora.py.

    Requirements:

    • CUDA GPU with at least 18GB VRAM (depending on dataset/params).
    • Training progress is monitored via training_metrics.png.
    • To use a checkpoint, run loadandmergecheckpoint.py (ensure R and Alpha values match training).
  5. How text normalization works (punc_norm)

    master

    The internal punc_norm function cleans up text (especially text coming from LLMs) before tokenization to ensure compatibility with the training data. It performs the following:

    1. Capitalization: Ensures the first letter is uppercase.
    2. Whitespace: Collapses multiple spaces into a single space.
    3. Punctuation Replacement: Converts uncommon or LLM-style punctuation to standard forms:
      • ... or … $\rightarrow$ ,
      • : $\rightarrow$ ,
      • - $\rightarrow$ ,
      • ; $\rightarrow$ ,
      • “/” $\rightarrow$ "
      • ‘/’ $\rightarrow$ '
    4. Sentence Completion: If the text does not end with a sentence ender (., !, ?, -, ,), a full stop (.) is appended.
  6. Initialize ChatterboxTTS

    master

    You can initialize the ChatterboxTTS client using two primary methods:

    1. from_pretrained(device): Downloads and loads the necessary model weights (VoiceEncoder, T3, S3Gen, tokenizer, and conditionals) from the Hugging Face Hub (ResembleAI/chatterbox).
    2. from_local(ckpt_dir, device): Loads the model from a local directory containing the required .pt and .json files.

    Supported devices include cpu, mps (macOS), and CUDA-enabled GPUs. When loading on non-CUDA devices, the client automatically handles mapping to CPU to prevent errors with CUDA-saved models.

    from chatterbox.tts import ChatterboxTTS
    
    # Option 1: Load from Hugging Face
    tts = ChatterboxTTS.from_pretrained(device="cuda")
    
    # Option 2: Load from local directory
    # ckpt_dir must contain ve.pt, t3_cfg.pt, s3gen.pt, tokenizer.json, and conds.pt
    tts = ChatterboxTTS.from_local("path/to/checkpoints", device="cpu")
  7. Stream TTS generation for real-time applications

    master

    For low-latency applications, use model.generate_stream(text, ...) which yields audio_chunk and metrics objects. This allows you to play audio chunks immediately as they are generated. You can combine all chunks into a single tensor using torch.cat(audio_chunks, dim=-1) for final saving.

    import torchaudio as ta
    import torch
    from chatterbox.tts import ChatterboxTTS
    
    model = ChatterboxTTS.from_pretrained(device="cuda")
    text = "Welcome to the world of streaming text-to-speech!"
    
    audio_chunks = []
    for audio_chunk, metrics in model.generate_stream(text):
        audio_chunks.append(audio_chunk)
        # Play audio_chunk immediately here for real-time playback
        print(f"Generated chunk {metrics.chunk_count}, RTF: {metrics.rtf:.3f}")
    
    final_audio = torch.cat(audio_chunks, dim=-1)
    ta.save("streaming_output.wav", final_audio, model.sr)
  8. Perform basic TTS generation

    master

    Use ChatterboxTTS.from_pretrained(device="cuda") to load the model and .generate(text) to produce audio. You can also perform voice cloning by providing an audio_prompt_path to a reference .wav file.

    import torchaudio as ta
    from chatterbox.tts import ChatterboxTTS
    
    model = ChatterboxTTS.from_pretrained(device="cuda")
    text = "Ezreal and Jinx teamed up with Ahri, Yasuo, and Teemo to take down the enemy's Nexus."
    
    # Standard generation
    wav = model.generate(text)
    ta.save("test-1.wav", wav, model.sr)
    
    # Voice cloning generation
    AUDIO_PROMPT_PATH = "YOUR_FILE.wav"
    wav = model.generate(text, audio_prompt_path=AUDIO_PROMPT_PATH)
    ta.save("test-2.wav", wav, model.sr)
  9. Configure streaming parameters

    master

    When calling generate_stream, you can tune the following parameters:

    • audio_prompt_path: Path to reference audio for voice cloning.
    • chunk_size: Number of speech tokens per chunk (default: 50). Smaller values reduce latency but increase overhead.
    • print_metrics: Boolean to enable automatic printing of latency and RTF (default: True).
    • exaggeration: Emotion intensity control (range: 0.0 to 1.0+).
    • cfg_weight: Classifier-free guidance weight (range: 0.0 to 1.0).
    • temperature: Sampling randomness (range: 0.1 to 1.0).
  10. Stream audio chunks with generate_stream()

    master

    For real-time applications, use generate_stream() to yield audio chunks as they are synthesized. This method yields a tuple of (audio_chunk, metrics).

    Parameters:

    • text (str): Input text.
    • audio_prompt_path (str, optional): Path to reference audio.
    • chunk_size (int): Number of speech tokens per chunk (default: 25).
    • context_window (int): Number of tokens from the previous chunk to include for smoothing (default: 50).
    • fade_duration (float): Seconds to apply a linear fade-in to each chunk to prevent clicking (default: 0.02).
    • print_metrics (bool): Whether to print RTF and latency to console (default: True).

    Yields:

    • audio_chunk (torch.Tensor): The synthesized audio chunk.
    • metrics (StreamingMetrics): An object containing timing and performance data.
    for audio_chunk, metrics in tts.generate_stream(
        text="Streaming text is much faster for user experience.",
        audio_prompt_path="ref.wav",
        chunk_size=20
    ):
        # Play audio_chunk immediately or send to a buffer
        print(f"Chunk received. Latency: {metrics.latency_to_first_chunk}s")
  11. Compute log-Mel spectrogram with log_mel_spectrogram()

    master

    The log_mel_spectrogram method computes the log-Mel spectrogram of an input audio waveform.

    Arguments:

    • audio: A torch.Tensor or numpy.ndarray containing the audio waveform in 16 kHz.
    • padding: (Optional) Number of zero samples to pad to the right. Defaults to 0.

    Returns:

    • A torch.Tensor of shape (128, n_frames) representing the log-Mel spectrogram.
    import torch
    import numpy as np
    
    # audio can be a Tensor or NumPy array
    audio = torch.randn(16000) 
    log_mel = tokenizer.log_mel_spectrogram(audio, padding=0)
  12. Perform basic TTS generation with generate()

    master

    The generate() method performs full-sequence text-to-speech. It returns a single torch.Tensor containing the synthesized audio.

    Key requirements:

    • You must either call prepare_conditionals(wav_fpath) first to set a reference voice, or provide an audio_prompt_path directly to the generate call.

    Parameters:

    • text (str): The text to synthesize.
    • audio_prompt_path (str, optional): Path to a reference WAV file for voice cloning.
    • exaggeration (float): Emotion exaggeration factor (default: 0.5).
    • cfg_weight (float): Classifier-free guidance weight (default: 0.5).
    • temperature (float): Sampling temperature (default: 0.8).
    # Using an audio prompt for voice cloning
    audio = tts.generate(
        text="Hello, this is a test of the chatterbox system.",
        audio_prompt_path="path/to/reference_voice.wav",
        exaggeration=0.7
    )
    
    # Using pre-prepared conditionals
    tts.prepare_conditionals("path/to/reference_voice.wav")
    audio = tts.generate("This uses the previously prepared voice.")