Voxtral Mini 4B Realtime
repository·main·Indexed 21 days ago
https://github.com/trevors/voxtral-mini-realtime-rsA pure Rust implementation of Mistral's Voxtral Mini 4B Realtime (ASR) and Voxtral 4B TTS models using the Burn ML framework. It supports high-performance inference via WebGPU/WGPU natively and in the browser via WASM. The project includes a CLI for streaming speech recognition and text-to-speech synthesis, supporting both BF16 and Q4 GGUF quantized models.
What's inside voxtral-mini-realtime
- Voxtral Mini 4B Realtime is a 4B parameter streaming Automatic Speech Recognition (ASR) system designed to run entirely in the browser using WebGPU. It provides low-latency speech-to-text capabilities by leveraging local GPU acceleration via the browser.
Overview of Voxtral 4B TTS
mainVoxtral 4B TTS is a text-to-speech model designed to run directly in the browser using WebGPU. It is optimized for client-side execution, providing low-latency speech generation without requiring a backend server for inference.Project structure overview
mainThe repository is organized as follows:
src/lib.rs: The public API entry point providingVoxtralRealtime<B>.src/models/: Contains the core model components (encoder.rs,decoder.rs,adapter.rs,voxtral.rs) and theVoxtralModelLoader.src/audio/: Handles audio processing, includingMelSpectrogramextraction, resampling, and chunking.src/tokenizer/: A wrapper around the Tekken tokenizer.scripts/: Python utilities for weight inspection, reference generation, and validation.web/: Contains the browser demo, includingworker.jsfor off-main-thread inference andvoxtral-client.jsfor the high-level API.
Module declaration convention for TTS
mainTo prevent merge conflicts during concurrent development, the
src/tts/mod.rsfile acts as the central module root. It declares all submodules upfront. When adding new functionality, ensure the corresponding module is declared in this file:pub mod config; pub mod backbone; pub mod voice; pub mod embeddings; // flow-matching pub mod sequence; // flow-matching pub mod flow_matching; // flow-matching pub mod codec; // integration pub mod pipeline; // integrationImplement streaming inference with the correct prefix length
mainWhen performing autoregressive streaming inference, you must use a prefix length of 38 instead of the standard 39. Using 39 tokens causes an anomaly at position 38 that results in the model outputting only padding tokens.
Correct Prefix Pattern:
- Use
[1](BOS) followed by 37[STREAMING_PAD](token 32) tokens. - Total prefix length = 38.
Token Reference:
[STREAMING_PAD](token 32): Marks pauses.[STREAMING_WORD](token 33): Starts words.- Important: Text token IDs are offset by 1000 from vocab indices (e.g., Token ID 1000+ maps to vocab index
token_id - 1000).
# Correct prefix for autoregressive generation prefix_tokens = [1] + [32] * 37 # BOS + 37 STREAMING_PAD = 38 tokens- Use
Inference with the Flow-Matching Transformer
mainThe Flow-Matching Transformer predicts acoustic tokens using an Euler ODE solver. During inference, the model performs 8 steps (dt = 1/8) to transition from noise to the target state.
Inference Steps:
- Sample
x_1 ~ N(0, 1)in $\mathbb{R}^{36}$. - For each step
tin[1.0, 0.875, 0.75, ..., 0.125]:- Calculate conditional velocity:
v_cond = FM(x_t, t, h) - Calculate unconditional velocity:
v_uncond = FM(x_t, t, zeros) - Apply Classifier-Free Guidance (CFG) with $\alpha=1.2$:
v = 1.2 * v_cond + (1 - 1.2) * v_uncond - Update state:
x_{t-dt} = x_t - v * dt
- Calculate conditional velocity:
- Quantize the final
x_0to 21 FSQ levels per dimension.
Transformer Inputs per frame:
- Position 0: Backbone hidden state
h(projected viallm_projection[3072, 3072]) - Position 1: Sinusoidal time step
t(projected viatime_projection[3072, 3072]) - Position 2: Current acoustic state
x_t(36-dim, projected viainput_projection[3072, 36])
- Sample
Implement Causal and Sliding Window Attention for Streaming
mainTo enable streaming in the audio encoder, you must use causal attention instead of bidirectional attention. For optimized streaming, combine causal attention with a sliding window constraint to limit the attention span.
Causal Mask: Ensures position
ican only attend to positions0..=i. Sliding Causal Mask: Ensures positionican only attend to positions within a specificwindowsize behind it.fn create_causal_mask(seq_len: usize, device: &Device) -> Tensor { let mut mask = vec![f32::NEG_INFINITY; seq_len * seq_len]; for i in 0..seq_len { for j in 0..=i { mask[i * seq_len + j] = 0.0; } } Tensor::from_vec(mask, (seq_len, seq_len), device) } fn create_sliding_causal_mask(seq_len: usize, window: usize, device: &Device) -> Tensor { let mut mask = vec![f32::NEG_INFINITY; seq_len * seq_len]; for i in 0..seq_len { let start = i.saturating_sub(window); for j in start..=i { mask[i * seq_len + j] = 0.0; } } Tensor::from_vec(mask, (seq_len, seq_len), device) }Language Model Architecture and GQA
mainThe language model is a decoder-only transformer based on Ministral-3B that processes audio embeddings.
Technical Specifications
- Hidden Dimension: 3,072
- Layers: 26
- Vocabulary Size: 131,072 (Tekken tokenizer)
- Sliding Window: 8,192 tokens
- Embeddings: Tied (
embed_tokens=lm_head.T)
Grouped Query Attention (GQA)
To reduce KV cache memory, the model uses a 4:1 GQA ratio:
- 32 Query heads (4096 dimension)
- 8 KV heads (1024 dimension)
- Each KV head is shared by 4 query heads, resulting in a 4x reduction in KV cache memory compared to standard Multi-Head Attention (MHA).
Understand the Voxtral Mini 4B Realtime Model Architecture
mainVoxtral Mini 4B Realtime is a pure Rust implementation of a streaming ASR (Automatic Speech Recognition) model built using the Burn ML framework. The model consists of three primary components:
- Audio Encoder: A 32-layer stack using causal self-attention, RMSNorm, and SwiGLU MLPs. It processes audio with a window of 750 and uses a 4x downsampler.
- Language Model: A 26-layer stack using Grouped Query Attention (GQA) with a 4:1 ratio (32Q/8KV heads), ADA RMSNorm, and a sliding window of 8192 tokens.
- Adapter: A 2-layer component that bridges the Audio Encoder and Language Model using GELU activation.
Key Timing Metric: 1 text token corresponds to approximately 80ms of audio (1280 samples @ 16kHz).
Use Finite Scalar Quantization (FSQ) for acoustic tokens
mainFinite Scalar Quantization (FSQ) is used to map continuous 36-dimensional vectors to discrete levels. This is applied after the Euler ODE solver to prepare data for the codec decoder.
Quantization Logic:
- Maps each of the 36 dimensions to the nearest of 21 uniformly-spaced levels in the range
[-1, 1]. - Quantize:
idx = argmin(|x - levels|)per dimension, producing 36 integer indices in the range[0..20]. - Dequantize:
x = levels[idx](used for codec decoder input).
This process is purely arithmetic and uses no learned parameters.
- Maps each of the 36 dimensions to the nearest of 21 uniformly-spaced levels in the range
Audio Encoder Architecture and Input Processing
mainThe audio encoder is a causal transformer designed for streaming mel spectrograms.
Input Specifications
- Sample Rate: 16,000 Hz
- Mel Bins: 128
- Hop Length: 160 samples (10ms)
- Window Size: 400 samples (25ms, Hann window)
- Raw Frame Rate: 100 Hz
Processing Pipeline
- Log Mel Normalization: Mel spectrograms are normalized using
clamp(log(max(mel, 1e-10)) / 1.5, -1.0, 1.0). - Convolutional Downsampling: Two 1D convolutional layers with stride 2 reduce the raw 100 Hz frame rate to 25 Hz (a 4x total downsample).
- Final Reshape: The 25 Hz output is reshaped (grouping 2 frames) to reach a final rate of 12.5 Hz (80ms per frame).
Encoder Technical Details
- Hidden Dimension: 1,280
- Layers: 32
- Attention: Multi-Head Attention (MHA) with 32 Query heads and 32 KV heads.
- Sliding Window: 750 tokens (~60 seconds of audio).
- FFN Type: SwiGLU (gate * silu(up)).
- Normalization: RMS Norm with ADA (Adaptive) conditioning.
Understand Audio Codebook Embedding Summation
mainThe audio codebook embedding layer maps semantic and acoustic token indices to a single 3072-dim vector by summing all 37 embeddings (1 semantic + 36 acoustic).
Index Layout:
- Semantic Specials: Indices 0..1 (
EMPTY_AUDIO=0,END_AUDIO=1). - Semantic VQ: Indices 2..8193 (8192 entries, offset by +2).
- Acoustic Codebooks: 36 codebooks, each with 23 entries (2 specials + 21 FSQ levels). Indices 8194..9021.
- Padding: Indices 9022..9087 (unused).
Index Arithmetic:
semantic_global = raw_semantic_idx + 2acoustic_global = 8194 + cb * 23 + (level + 2)
- Semantic Specials: Indices 0..1 (