### Set Up GPU Instance Dependencies Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Installs necessary Python packages, clones the Qwen3-TTS repository, and installs system dependencies like SoX. ```bash ssh -i ~/.ssh/runpod -o StrictHostKeyChecking=no -p root@ pip install transformers accelerate peft datasets soundfile librosa flash-attn --no-build-isolation git clone https://github.com/QwenLM/Qwen3-TTS.git pip install -e ./Qwen3-TTS apt-get update -qq && apt-get install -y -qq sox libsox-fmt-all libsndfile1 ``` -------------------------------- ### Copy and Execute Remote Setup Script Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Copies a setup script to a remote Vast.ai instance via SCP and then executes it using SSH. Assumes SSH key is set up. ```bash scp -i ~/.ssh/runpod -P holler/training/remote_setup.sh root@:/workspace/ ``` ```bash ssh -i ~/.ssh/runpod -p root@ "bash /workspace/remote_setup.sh" ``` -------------------------------- ### Install Python Server Dependencies Source: https://github.com/sentiuminc/holler/blob/main/README.md Clone the Holler repository, create a virtual environment, and install required Python packages. ```bash git clone https://github.com/sentiuminc/holler.git cd holler python3 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt ``` -------------------------------- ### Install Dependencies and Run Inference Server Source: https://github.com/sentiuminc/holler/blob/main/CLAUDE.md This snippet shows how to set up a Python virtual environment, install project dependencies, and run the inference server. The server automatically downloads the default model on its first run. ```bash # 1. Create venv and install dependencies python3 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt # 2. Run server (auto-downloads sentiuminc/holler-0.6b from HuggingFace on first run) python3 inference/server.py python3 inference/server.py -c path/to/local/checkpoint --voice kit # → http://localhost:8100 # 4. Test curl "http://localhost:8100/tts?text=Hello+world" -o test.wav curl http://localhost:8100/benchmark ``` -------------------------------- ### Start Python Text-to-Speech Server Source: https://github.com/sentiuminc/holler/blob/main/README.md Start the Python server for text-to-speech. It downloads the default model on first run. Use the `-c` flag to specify an alternative model like the 6-bit variant for lower RAM usage. ```bash # Start the server (downloads sentiuminc/holler-0.6b from HuggingFace on first run, ~2.3GB) python3 inference/server.py # Or use the 6-bit model for lower RAM: python3 inference/server.py -c sentiuminc/holler-0.6b-6bit ``` -------------------------------- ### Start Multi-Voice Training Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Initiates the training process for multiple voices, specifying ports for each. ```bash bash /workspace/remote_train_multivoice.sh kit:3000 dakota:3001 nora:3002 joe:3003 ``` -------------------------------- ### Serve Quantized Model Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Starts a local inference server for the quantized model, accessible via HTTP. ```bash .venv/bin/python3 inference/server.py --checkpoint checkpoints/-6bit # → http://localhost:8100 with voice selector dropdown ``` -------------------------------- ### Holler CLI Usage Examples Source: https://github.com/sentiuminc/holler/blob/main/docs/holler-swift-plan.md Demonstrates basic and benchmark usage of the Holler command-line interface. Options for text, voice, model, output, and various synthesis parameters are shown. ```bash holler --text "Hello world" --voice kit [options] holler --benchmark [options] ``` -------------------------------- ### Swift TTS Integration Example Source: https://github.com/sentiuminc/holler/blob/main/docs/holler-swift-plan.md Illustrates how to integrate HollerKit into a Swift application to replace a Python TTS sidecar. Shows model loading, session management, and audio streaming. ```swift // In TTSService.swift import HollerKit private var model: HollerModel? private var session: SpeechSession? func ensureModelLoaded() async { guard model == nil else { return } model = try? await HollerModel.load(repo: "sentium/holler-0.6b-6bit") } // Called when ivi starts speaking a response func startSpeaking(voice: String) async { await ensureModelLoaded() guard let model else { return } session = model.makeSession(voice: voice) // Start consuming audio in background Task { guard let session else { return } for try await chunk in session.audio { TTSPlayer.shared.scheduleBuffer(chunk.samples, sampleRate: chunk.sampleRate) } } } // Called as LLM tokens arrive func feedText(_ token: String) async { await session?.feed(token) } // Called when LLM response is complete func finishSpeaking() async { await session?.finish() session = nil } // Called when user interrupts (barge-in) func cancelSpeaking() { session?.cancel() session = nil TTSPlayer.shared.stop() } ``` -------------------------------- ### Start Single-Voice Training Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Initiates the training process for a single voice using the provided script. ```bash bash /workspace/remote_train.sh ``` -------------------------------- ### Holler Inference Server Speak Request Example Source: https://github.com/sentiuminc/holler/blob/main/CLAUDE.md Example of a request body for the Holler inference server's /speak endpoint, specifying text, voice, temperature, and number of codebooks for speech generation. ```json {"text": "...", "voice": "kit", "temperature": 0.6, "n_codebooks": 12} ``` -------------------------------- ### GET /benchmark Source: https://github.com/sentiuminc/holler/blob/main/README.md Runs a benchmark test to measure Time To First Byte (TTFA) and Real-Time Factor (RTF) results. ```APIDOC ## GET /benchmark ### Description 6-sentence benchmark with TTFA/RTF results ### Method GET ### Endpoint /benchmark ``` -------------------------------- ### Training Configuration Parameters Source: https://github.com/sentiuminc/holler/blob/main/README.md These parameters define the training setup for the TTS model. Key settings include learning rate, number of epochs, batch size, and embedding normalization. ```text lr=5e-7, cosine warmup scheduler 2 epochs, batch_size=2, grad_accum=4, weight_decay=0.01 Embedding normalization: L2-norm all ECAPA-TDNN speaker embeddings to magnitude 10.0 All training data at uniform -22 LUFS ``` -------------------------------- ### GET /tts Source: https://github.com/sentiuminc/holler/blob/main/README.md Generates a WAV audio file for the given text. The audio can be saved directly to a file. ```APIDOC ## GET /tts — WAV file ### Description Returns a WAV file containing the spoken text. ### Method GET ### Endpoint /tts ### Parameters #### Query Parameters - **text** (string) - required - Text to speak - **voice** (string) - optional - Voice name (defaults to the first available voice) ### Request Example ```bash curl "http://localhost:8100/tts?text=Hello+world&voice=kit" -o hello.wav ``` ### Response #### Success Response (200) - WAV audio file ``` -------------------------------- ### Initialize Audio Context and Global Variables Source: https://github.com/sentiuminc/holler/blob/main/inference/tts-test.html Sets up the audio context, global variables for managing audio playback, and logging. ```javascript const SR = 24000; const BASE = location.origin || 'http://localhost:8100'; let audioCtx = null; let abortCtrl = null; let logCount = 0; let isPlaying = false; let nextPlayTime = 0; let allAudioChunks = []; ``` -------------------------------- ### Holler Inference Server Health Check Example Source: https://github.com/sentiuminc/holler/blob/main/CLAUDE.md Example of a health check response from the Holler inference server, indicating the status, loaded model, and available voices. ```json {"status": "ok", "model": "...", "voices": [...]} ``` -------------------------------- ### Build and Run HollerKit Source: https://github.com/sentiuminc/holler/blob/main/CLAUDE.md Use these commands to build and run the HollerKit CLI. Always use `./build.sh` as `swift build` does not compile Metal shaders correctly. ```bash ./build.sh ./build.sh --clean ./holler --text 'Hello world' --talk ``` -------------------------------- ### GET /health Source: https://github.com/sentiuminc/holler/blob/main/README.md Retrieves the server status, including the model name and a list of available voices. ```APIDOC ## GET /health ### Description Server status, model name, available voices ### Method GET ### Endpoint /health ``` -------------------------------- ### Build and Run Holler CLI Source: https://github.com/sentiuminc/holler/blob/main/README.md Build the Holler CLI tool. Use the `--talk` flag to speak text through your speakers or `--output` to save to a WAV file. ```bash # Build once (~3 min first time) ./build.sh # Speak text through your speakers ./holler --text 'Hello world' --talk # Save to file ./holler --text 'Hello world' --output hello.wav ``` -------------------------------- ### Set up HuggingFace Model Cache Source: https://github.com/sentiuminc/holler/blob/main/docs/holler-swift-plan.md Hard-link checkpoint files into the HuggingFace cache directory to make models available for mlx-audio-swift. This method uses zero disk space and is instantaneous. ```bash # Hard-link checkpoint into HF cache (zero disk space, instant) CACHE=~/.cache/huggingface/hub/mlx-audio/sentium_holler-kit-dakota-6bit mkdir -p "$CACHE/speech_tokenizer" for f in holler/checkpoints/holler-kit-dakota-6bit/*; do [ -f "$f" ] && ln -f "$f" "$CACHE/"; done for f in holler/checkpoints/holler-kit-dakota-6bit/speech_tokenizer/*; do [ -f "$f" ] && ln -f "$f" "$CACHE/speech_tokenizer/"; done ``` -------------------------------- ### Download Qwen3-TTS Models Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Downloads the base model and tokenizer from Hugging Face using `snapshot_download`. ```python from huggingface_hub import snapshot_download snapshot_download('Qwen/Qwen3-TTS-12Hz-0.6B-Base', local_dir='/workspace/models/0.6B-Base') snapshot_download('Qwen/Qwen3-TTS-Tokenizer-12Hz', local_dir='/workspace/models/Tokenizer-12Hz') ``` -------------------------------- ### Download Best Training Checkpoint Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Use rsync to download the best performing checkpoint from the training output directory. Replace placeholders for SSH connection details. ```bash # Download best epoch (probably epoch-9 or test several) rsync -avz -e "ssh -i ~/.ssh/runpod -p -i ~/.ssh/runpod" \ root@:/workspace/output/checkpoint-epoch-9/ \ ~/Downloads/ivi-tts-finetuned/ ``` -------------------------------- ### Search and Create Vast.ai Instances Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Searches for available GPU instances on Vast.ai based on specified criteria and creates a new instance with a specific Docker image and disk size. ```bash vastai search offers 'gpu_name=RTX_3090 num_gpus=1 rentable=true disk_space>=80' -o 'dph_total' --limit 10 ``` ```bash vastai create instance --image pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel --disk 80 --ssh ``` -------------------------------- ### Analyze Voice Quality Before Training Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Run an analysis on curated clips to verify audio quality against target metrics before proceeding to GPU training. This helps prevent wasting resources on subpar data. ```bash .venv-enhance-audio/bin/python tools/analyze_voice_quality.py \ --source voices//training-data/audio --label "-curated" --n 80 ``` -------------------------------- ### GET /tts API Endpoint for WAV file Source: https://github.com/sentiuminc/holler/blob/main/README.md Retrieve text as a WAV audio file. This endpoint takes text and voice as query parameters and saves the output to a specified file. ```bash curl "http://localhost:8100/tts?text=Hello+world&voice=kit" -o hello.wav ``` -------------------------------- ### Holler Inference Server API Endpoints Source: https://github.com/sentiuminc/holler/blob/main/CLAUDE.md This lists the available API endpoints for the Holler inference server, including POST for speech synthesis and GET requests for WAV file generation, benchmarking, health checks, and a browser UI. ```http POST /speak — streaming float32 PCM (24kHz mono), chunked transfer encoding Body: {"text": "...", "voice": "kit", "temperature": 0.6, "n_codebooks": 12} GET /tts?text= — returns complete WAV file GET /benchmark — runs 6-sentence benchmark, returns text report GET /health — {"status": "ok", "model": "...", "voices": [...]} GET / — browser test UI (disable with --no-ui) ``` -------------------------------- ### Train Qwen3-TTS Full SFT Model Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Execute the Full SFT training script for Qwen3-TTS. Ensure the correct paths and hyperparameters are set. This command runs the training in the background and logs output. ```bash cd /workspace/training-data # Remove tensorboard requirement if present sed -i 's/log_with="tensorboard"//' /workspace/Qwen3-TTS/finetuning/sft_12hz.py PYTHONUNBUFFERED=1 nohup python3 /workspace/Qwen3-TTS/finetuning/sft_12hz.py \ --init_model_path /workspace/models/0.6B-Base \ --output_model_path /workspace/output \ --train_jsonl /workspace/training-data/train_with_codes.jsonl \ --batch_size 2 \ --lr 2e-6 \ --num_epochs 10 \ --speaker_name ivi_female \ > /workspace/train.log 2>&1 & # Monitor tail -f /workspace/train.log ``` -------------------------------- ### Quantize Model Checkpoint Locally Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Quantizes the downloaded model checkpoint to a 6-bit affine g64 format using mlx_audio. ```python python3 -c " from mlx_audio.convert import convert convert(hf_path='checkpoints/', mlx_path='checkpoints/-6bit', quantize=True, q_bits=6, q_group_size=64, q_mode='affine') " ``` -------------------------------- ### Generate Training Data Locally Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Use this command to generate training clips locally on a Mac. Ensure you are in the 'holler' directory and have the virtual environment activated. Replace placeholders with your voice name and reference text. ```bash cd holler && .venv/bin/python tools/generate_training_data.py \ --voice --ref-text "" ``` -------------------------------- ### Upload Training Data to GPU Instance Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Uses rsync to efficiently transfer the local training data directory to the remote GPU instance. ```bash rsync -avz -e "ssh -i ~/.ssh/runpod -o StrictHostKeyChecking=no -p " \ ~/Downloads/ivi-tts-training-data/ root@:/workspace/training-data/ ``` -------------------------------- ### Auto-Curate Audio Clips (Apply Changes) Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Apply the auto-curation process to filter and prepare training data. This command writes reject files and curated JSONL files. ```bash .venv-enhance-audio/bin/python tools/auto_curate.py --voice --apply # write files ``` -------------------------------- ### Multi-Voice SFT Training Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md This script is for multi-voice Supervised Fine-Tuning (SFT). It requires a merged JSONL file with per-voice prefixes and a mapping of voice names to slot assignments in the codec embedding. Adjust batch size, learning rate, and epochs as needed. ```bash python3 sft_12hz_multivoice.py \ --init_model_path /path/to/Qwen3-TTS-12Hz-0.6B-Base \ --output_model_path /path/to/output \ --train_jsonl /path/to/merged_multivoice.jsonl \ --batch_size 2 --lr 1e-7 --num_epochs 2 \ --voice_slot_map_json '{"nora":3002,"joe":3001}' ``` -------------------------------- ### Build Combined JSONL and Upload Training Data Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Builds a combined JSONL file for training data and uploads voice-specific audio and reference files to R2. ```bash # Build combined JSONL python training/build_combined_jsonl.py --voices kit dakota nora joe oliver tessa # Upload to R2 (rclone remote 'r2-sentium' must be configured) for voice in kit dakota nora joe oliver tessa; do rclone copy "voices/$voice/training-data/audio/" "r2-sentium:holler/training-data/$voice/audio/" --transfers 16 rclone copyto "voices/$voice/training-data/ref.wav" "r2-sentium:holler/training-data/$voice/ref.wav" done rclone copyto training/train_multivoice.jsonl r2-sentium:holler/training-data/train_multivoice.jsonl ``` -------------------------------- ### Upload Checkpoint to R2 from Instance Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Uploads the trained model checkpoint from the instance to R2 storage. ```bash # On instance: upload to R2 rclone copy /workspace/output/checkpoint-epoch-1/ r2:holler/checkpoints// --transfers 4 -v ``` -------------------------------- ### Search for GPU Offers on Vast.ai Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Use this command to search for suitable GPU instances on Vast.ai based on VRAM, reliability, and cost. ```bash vastai search offers 'gpu_ram>=24 num_gpus=1 dph_total<0.40 reliability>0.95 rentable=True verified=True' -o 'dph_total' --limit 15 ``` -------------------------------- ### Simulate LLM Streaming with Holler CLI Source: https://github.com/sentiuminc/holler/blob/main/README.md Use the Holler CLI to simulate LLM token-by-token streaming with sentence buffering. ```bash # Simulate LLM streaming (token-by-token with sentence buffering) ./holler --session --text 'Sure. Let me check that for you. I think the answer is forty two.' ``` -------------------------------- ### Download Checkpoint from R2 to Mac Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Downloads the trained model checkpoint from R2 storage to a local Mac machine. ```bash # On Mac: pull from R2 rclone copy r2-sentium:holler/checkpoints// holler/checkpoints// --transfers 8 --progress ``` -------------------------------- ### Tokenize Training Data Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Prepares the training data by tokenizing the text using the specified tokenizer model. This script is part of the official Qwen3-TTS repository. ```bash cd /workspace/training-data python3 /workspace/Qwen3-TTS/finetuning/prepare_data.py \ --device cuda:0 \ --tokenizer_model_path /workspace/models/Tokenizer-12Hz \ --input_jsonl train.jsonl \ --output_jsonl train_with_codes.jsonl ``` -------------------------------- ### POST /speak Source: https://github.com/sentiuminc/holler/blob/main/README.md Generates and streams audio output as it's being created. The audio is returned as float32 PCM at 24kHz with chunked transfer encoding. ```APIDOC ## POST /speak — Streaming audio ### Description Returns audio as it's generated. Float32 PCM at 24kHz, chunked transfer encoding. ### Method POST ### Endpoint /speak ### Parameters #### Request Body - **text** (string) - required - Text to speak - **voice** (string) - optional - Voice name (defaults to the first available voice) - **temperature** (float) - optional - Sampling temperature (default: 0.7) - **top_k** (int) - optional - Top-k sampling (default: 50) - **n_codebooks** (int) - optional - Codec books (16 for best quality, 12 for fastest) - **continue** (bool) - optional - Carry over prosody from previous generation (default: false) ### Request Example ```json { "text": "The weather looks great today.", "voice": "kit" } ``` ### Response #### Success Response (200) - Audio stream (float32 PCM at 24kHz, chunked transfer encoding) ``` -------------------------------- ### Session-Based Synthesis Source: https://github.com/sentiuminc/holler/blob/main/docs/holler-swift-plan.md Creates a synthesis session for LLM integration, allowing token-by-token text input and streaming audio output. Maintains KV cache across sentences for prosody continuity. ```APIDOC ## Session-Based Synthesis ### Description Creates a synthesis session for LLM integration, allowing token-by-token text input and streaming audio output. Maintains KV cache across sentences for prosody continuity. ### Method `makeSession` ### Parameters #### Path Parameters - **voice** (String) - Required - The identifier of the voice to use for the session. ### Response #### Success Response - **Session** - An object representing the synthesis session. ### Example ```swift let session = model.makeSession(voice: "kit") // Feed text and consume audio concurrently: async let playback: Void = { for try await chunk in session.audio { playerNode.scheduleBuffer(chunk.asAudioBuffer()) } }() // Feed tokens as they arrive from an LLM for await token in llmTokenStream { await session.feed(token) // buffers internally, synthesizes on sentence boundaries } await session.finish() // flush remaining buffered text try await playback // audio stream ends after all sentences synthesized // Cancellation (barge-in: user interrupts while ivi is speaking) session.cancel() // stops generation, discards buffer, releases cache ``` ``` -------------------------------- ### Configure HollerKit Model Loading Source: https://github.com/sentiuminc/holler/blob/main/README.md Customize HollerKit configuration, including sampling temperature, codec books, retry attempts, and logging. Optionally load a 6-bit model for faster streaming. ```swift var config = HollerConfiguration() config.temperature = 0.7 // Sampling temperature config.codebooks = 16 // Codec books (16 = best quality, 12 = fast streaming) config.maxRetries = 3 // Retry attempts on failed generation config.log = { print($0) } // Enable debug logging // Default model is sentiuminc/holler-0.6b (bf16) // For faster streaming, use the 6-bit variant: let model = try await HollerModel.load(repo: "sentiuminc/holler-0.6b-6bit", configuration: config) ``` -------------------------------- ### Convert Qwen3-TTS Model to MLX Format (Option A) Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Attempt to convert a Hugging Face model to MLX format using mlx_lm.convert. This option may work if the model structure is standard. Use 8-bit quantization. ```bash # Option A: mlx_lm.convert (may work if model is standard enough) cd ~/Desktop/Files/AI/ivi/audio-test .venv-tts-bench/bin/python -m mlx_lm.convert \ --hf-path ~/Downloads/ivi-tts-finetuned/ \ --mlx-path ~/Downloads/ivi-tts-finetuned-mlx/ \ -q --q-bits 8 ``` -------------------------------- ### Cache and Upload Instance Data Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Compresses and uploads pip and model caches to R2 storage on the instance. ```bash tar czf /workspace/pip-cache.tar.gz -C /root/.cache pip/ tar czf /workspace/models-cache.tar.gz -C /workspace models/ rclone copyto /workspace/pip-cache.tar.gz r2:holler/instance-cache/pip-cache.tar.gz rclone copyto /workspace/models-cache.tar.gz r2:holler/instance-cache/models-cache.tar.gz ``` -------------------------------- ### Quantize Model to 6-bit Affine g64 Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Use mlx-audio's convert function for quantization. Ensure to copy the speech_tokenizer directory after conversion. ```python from mlx_audio.convert import convert convert(hf_path='', mlx_path='', quantize=True, q_bits=6, q_group_size=64, q_mode='affine') ``` -------------------------------- ### SCP Training Script to Instance Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Securely copies the training script from the local machine to the remote instance. ```bash scp -i ~/.ssh/runpod -P training/sft_12hz_multivoice.py root@:/workspace/ ``` -------------------------------- ### Download Audio as WAV Source: https://github.com/sentiuminc/holler/blob/main/inference/tts-test.html Merges all audio chunks into a single Float32Array, converts it to a 16-bit PCM WAV format, and initiates a download of the file. It constructs the WAV file header manually. ```javascript function downloadAudio() { if (allAudioChunks.length === 0) return; let total = 0; for (const c of allAudioChunks) total += c.length; const merged = new Float32Array(total); let off = 0; for (const c of allAudioChunks) { merged.set(c, off); off += c.length; } const dataSize = total * 2; const buf = new ArrayBuffer(44 + dataSize); const v = new DataView(buf); const w = (o, s) => { for (let i = 0; i < s.length; i++) v.setUint8(o + i, s.charCodeAt(i)); }; w(0,'RIFF'); v.setUint32(4,36+dataSize,true); w(8,'WAVE'); w(12,'fmt '); v.setUint32(16,16,true); v.setUint16(20,1,true); v.setUint16(22,1,true); v.setUint32(24,SR,true); v.setUint32(28,SR*2,true); v.setUint16(32,2,true); v.setUint16(34,16,true); w(36,'data'); v.setUint32(40,dataSize,true); for (let i = 0; i < total; i++) v.setInt16(44+i*2, Math.max(-32768, Math.min(32767, Math.round(merged[i]*32767))), true); const blob = new Blob([buf], {type:'audio/wav'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `holler-${new Date().toISOString().slice(11,19).replace(/:/g,'')}.wav`; a.click(); URL.revokeObjectURL(a.href); } ``` -------------------------------- ### Session-Based Streaming with LLM Integration Source: https://github.com/sentiuminc/holler/blob/main/docs/holler-swift-plan.md Manages a session for streaming text input token-by-token from an LLM and producing streaming audio output. It maintains KV cache for prosody continuity between sentences and supports cancellation. ```swift // === Tier 3: Session — streaming text in, streaming audio out === // For LLM integration. Text arrives token-by-token, audio starts // as soon as the first sentence is complete. KV cache carries over // between sentences automatically for prosody continuity. let session = model.makeSession(voice: "kit") // Feed text and consume audio concurrently: async let playback: Void = { for try await chunk in session.audio { playerNode.scheduleBuffer(chunk.asAudioBuffer()) } }() // Feed tokens as they arrive from an LLM for await token in llmTokenStream { await session.feed(token) // buffers internally, synthesizes on sentence boundaries } await session.finish() // flush remaining buffered text try await playback // audio stream ends after all sentences synthesized // Cancellation (barge-in: user interrupts while ivi is speaking) session.cancel() // stops generation, discards buffer, releases cache ``` -------------------------------- ### HollerKit Architecture Overview Source: https://github.com/sentiuminc/holler/blob/main/CLAUDE.md Illustrates the data flow from HollerModel API calls through inference to the consumer. ```text HollerModel.stream("text", voice:) → InferenceActor → mlx-audio-swift generateStream() ↓ ↓ ↓ AsyncThrowingStream StreamingPipeline Qwen3TTSModel + codec decoder ↓ (silence trim, abort) Consumer (app/CLI) ``` -------------------------------- ### Benchmark Holler CLI Source: https://github.com/sentiuminc/holler/blob/main/README.md Run the Holler CLI benchmark to measure performance. ```bash # Benchmark ./holler --benchmark ``` -------------------------------- ### Single-Voice SFT Training Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Use this script for single-voice Supervised Fine-Tuning (SFT). Ensure correct paths for initialization, output, and training data. The `--speaker_name` parameter is crucial for identifying the voice. ```bash python3 sft_12hz.py \ --init_model_path /path/to/Qwen3-TTS-12Hz-0.6B-Base \ --output_model_path /path/to/output \ --train_jsonl /path/to/train_curated.jsonl \ --batch_size 2 --lr 1e-7 --num_epochs 2 \ --speaker_name ``` -------------------------------- ### Check Default Learning Rate in SFT Script Source: https://github.com/sentiuminc/holler/blob/main/docs/handover-lora-failure.md Inspects the SFT script to find the default learning rate setting. This helps in understanding the default training parameters. ```bash # Check default LR grep -n "default=" /workspace/Qwen3-TTS/finetuning/sft_12hz.py | grep lr ``` -------------------------------- ### CLI Test for Holler TTS Source: https://github.com/sentiuminc/holler/blob/main/docs/holler-swift-plan.md Build and run the Holler CLI tool to test text-to-speech generation. Ensure you have built the mlx-audio-swift-tts product and have the necessary metallib files. ```bash cd mlx-audio-swift swift build -c release --product mlx-audio-swift-tts --disable-sandbox # Need metallib — build or copy from speech-swift .build/arm64-apple-macosx/release/mlx-audio-swift-tts \ --text "Hello world" \ --model sentium/holler-kit-dakota-6bit \ --voice kit \ --temperature 0.6 \ --output test.wav ``` -------------------------------- ### Auto-Curate Audio Clips (Report Only) Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Run the auto-curation process to identify clips that do not meet quality standards. This command only generates a report without applying changes. ```bash .venv-enhance-audio/bin/python tools/auto_curate.py --voice # report only ``` -------------------------------- ### Benchmark Model Quality Source: https://github.com/sentiuminc/holler/blob/main/docs/training-runbook.md Benchmarks a trained model checkpoint. Supports raw mode for true model quality assessment and comparison between two checkpoints. ```bash .venv/bin/python tools/benchmark_quality.py -c checkpoints/ --holler-bin ./holler --raw --temperature 0.7 --label ``` ```bash .venv/bin/python tools/benchmark_quality.py --compare ~/Downloads/holler-bench/v1 ~/Downloads/holler-bench/v2 --compare-labels v1 v2 ``` -------------------------------- ### Quality Benchmark Script Source: https://github.com/sentiuminc/holler/blob/main/README.md A Python script to benchmark quality using Whisper-based Word Error Rate (WER) and gap analysis. Requires a checkpoint path and specifies the mode and temperature. ```bash # Quality benchmark (Whisper-based WER + gap analysis) .venv/bin/python tools/benchmark_quality.py --checkpoint --mode raw --temperature 0.7 ``` -------------------------------- ### Synthesize Complete Audio (Batch) Source: https://github.com/sentiuminc/holler/blob/main/docs/holler-swift-plan.md Synthesizes a complete audio output for a given text input using a specified voice. The result contains audio samples, sample rate, and duration. ```swift // === Tier 1: Batch — complete text, complete audio === let audio = try await model.synthesize("Hello world", voice: "kit") // audio.samples: [Float], audio.sampleRate: 24000, audio.duration: Double ``` -------------------------------- ### Benchmark Endpoint Source: https://github.com/sentiuminc/holler/blob/main/CLAUDE.md Runs a performance benchmark consisting of a 6-sentence test and returns a text report. ```APIDOC ## GET /benchmark ### Description Runs a 6-sentence benchmark and returns a text report of the performance metrics. ### Method GET ### Endpoint /benchmark ``` -------------------------------- ### POST /speak API Endpoint Source: https://github.com/sentiuminc/holler/blob/main/README.md Use this endpoint to stream audio as it is generated. It accepts JSON payload with text and voice parameters. Audio is returned as Float32 PCM at 24kHz with chunked transfer encoding. ```bash curl -X POST http://localhost:8100/speak \ -H "Content-Type: application/json" \ -d '{"text": "The weather looks great today.", "voice": "kit"}' ``` -------------------------------- ### Manual Curation Script Source: https://github.com/sentiuminc/holler/blob/main/README.md A Python script for manual curation of audio clips, acting as a 'clip tinder' to listen and decide whether to keep or skip clips for a given voice. ```bash # Manual curation (clip tinder — listen, keep/skip) .venv-enhance-audio/bin/python tools/curate_clips.py --voice ```