Traducción de voz Hibiki Zero-3B (FR / ES / PT / DE → EN)
Hibiki Zero-3B es el modelo de traducción de voz a voz en streaming de Kyutai: la entrada es un flujo de audio de 24 kHz en francés, español, portugués o alemán; la salida es un flujo de audio en inglés a 24 kHz junto con una transcripción de texto en inglés paralela a la misma tasa de 12.5 Hz por cuadro. Está construido sobre la arquitectura multistream de Moshi/Mimi: un único transformador decoder-only modela conjuntamente el flujo de códec de audio origen y los flujos de texto+audio destino, por lo que no hay un pipeline separado de ASR + MT + TTS. La compilación de Soniqo se ejecuta como safetensors MLX cuantizados (INT4 por defecto, INT8 disponible) totalmente en Apple Silicon. CC-BY-4.0.
El ASR + MADLAD en estilo pipe (speech transcribe | speech translate) te ofrece más de 400 idiomas pero añade la latencia ida y vuelta de tres modelos. Hibiki es un único modelo de extremo a extremo y preserva la prosodia: elígelo cuando necesites voz en vivo en el idioma destino y no solo texto.
Inicio rápido
import HibikiTranslate
import AudioCommon
let model = try await HibikiTranslateModel.fromPretrained()
let pcm = try AudioFileLoader.load(url: input, targetSampleRate: 24000)
let (englishAudio, textTokens) = model.translate(
sourceAudio: pcm,
sourceLanguage: .fr // .fr / .es / .pt / .de — autodetectado pero pásalo para los metadatos
)
try WAVWriter.write(samples: englishAudio, sampleRate: 24000, to: output)
CLI
speech audio-translate input_fr.wav -o out_en.wav --source-lang fr
speech audio-translate input_es.wav -o out_en.wav --source-lang es --quantization 8bit
speech audio-translate input_pt.wav -o out_en.wav --source-lang pt --verbose
# Modo determinista (usado por los canarios de regresión del CI)
HIBIKI_GREEDY=1 speech audio-translate input_fr.wav -o out_en.wav --source-lang fr
# IDs de tokens de texto del monólogo interno (en bruto — la decodificación SPM es un paso posterior)
speech audio-translate input.wav -o out.wav --transcript
Arquitectura
Hibiki Zero-3B es un transformador multistream decoder-only de 3.1B parámetros. El modelo atiende conjuntamente sobre 33 flujos por cuadro: un flujo de texto, 16 codebooks de audio destino (la salida del agente) y 16 codebooks de audio origen (la entrada del usuario). En cada cuadro de 80 ms el modelo muestrea un token de texto más 16 códigos de audio mediante un pequeño depformer de 6 capas que ejecuta 16 subpasos por cuadro, uno por codebook destino, con una proyección MultiLinear programada de 9 cortes.
El códec de audio es Mimi a 12.5 Hz / 16 codebooks. El audio origen se codifica en los 16 codebooks del flujo origen (retardo [0, 2, 2, …, 2]); el audio destino generado rellena los 16 codebooks del flujo destino (mismo patrón de retardo); se aplica un un-shift por codebook antes de que Mimi decodifique el destino de vuelta a PCM en inglés a 24 kHz. La columna temporal son 28 capas GQA (dim = 2048, 16 cabezas de consulta, 8 cabezas KV, kv_repeat = 2, RoPE de mitades divididas rope_concat, sin condicionador — Zero es la variante no condicionada).
Bucle de decodificación
Hibiki emite tokens de relleno SPM (id 3) mientras acumula suficiente contexto origen para traducir, luego tokens de texto de contenido con audio destino correspondiente y, finalmente, EOS de texto (id 2). El driver en Swift se ejecuta hasta que se muestrea EOS más allá de la ventana origen, con un tope de max(tSrc × 5/2, tSrc + 20) pasos como límite de seguridad. La salida dura aproximadamente entre 1.0 y 1.6× la duración de la entrada en clips estilo FLEURS; los llamadores no deben asumir output_duration == input_duration.
La ruta autorregresiva de realimentación no es obvia: en el paso t el transformador lee tokens en el índice de caché step (uniforme para los 33 flujos, con sustitución por init-token cuando step ≤ delays[k]); el texto muestreado + los 16 códigos destino se escriben en el índice step + 1. Esto replica el upstream de Moshi lm.py, donde state.offsets += 1 ocurre antes del scatter de caché. La fila de text_emb para EOS (id 2) se aliasea a la fila 3 (PAD) en el momento de cargar los pesos, replicando el parche "reemplazar implícitamente EOS temprano por PAD" de Kyutai en loaders.py:312: cualquier EOS muestreado durante la ventana de streaming de audio es inofensivo, solo un EOS posterior al origen termina el bucle.
Variantes del modelo
| Variante | Cuantización | Tamaño | Cómputo | HuggingFace |
|---|---|---|---|---|
| Hibiki Zero-3B | INT4 | ~2.7 GB | Metal GPU (MLX) | aufklarer/Hibiki-Zero-3B-MLX-4bit |
| Hibiki Zero-3B | INT8 | ~3.9 GB | Metal GPU (MLX) | aufklarer/Hibiki-Zero-3B-MLX-8bit |
Cobertura de idiomas
Hibiki Zero-3B está entrenado en francés, español, portugués y alemán → inglés. El driver en Swift detecta automáticamente el idioma origen; la bandera --source-lang es solo metadato.
| Origen | Estado | Salida greedy de muestra |
|---|---|---|
| FR | Canario E2E estricto | "so it's a ski route." (de "Pensez à l'itinéraire de ski…") |
| ES | Canario E2E estricto | "gentlemen, the data is worrying." (muestra europarl de Hibiki) |
| PT | Solo advertencia (fiel al contenido, menor recall de palabras clave) | "the fifth c is p of the martyr." (FLEURS PT) |
| DE | Solo advertencia (fiel al contenido, menor recall de palabras clave) | "that didn't seem to me to be useful." (FLEURS DE) |
Los clips de FLEURS en español grabados por humanos a 16 kHz desencadenan generación degenerada tanto en el upstream de Python como en el port de Swift (Python emite 1643 pasos / ~131 s de audio roto sin muestrear EOS). El canario de regresión en ES en Swift usa un extracto recortado de 5 s del propio space de muestras de Kyutai (kyutai/hibiki-zero-samples) en audio generado por TTS a 24 kHz, que coincide con la distribución de entrenamiento y produce inglés limpio. Si vas a alimentar Hibiki con español en producción, preremuestrea a 24 kHz y limítate a clips más largos (5 s+).
Variables de entorno
| Variable | Efecto |
|---|---|
HIBIKI_GREEDY=1 | Forzar decodificación argmax tanto para texto como para audio destino. Reproducible — usado por los canarios estrictos del CI. |
HIBIKI_E2E=1 | Habilitar los casos de prueba E2E (requiere la descarga del modelo de ~2.7 GB). |
HIBIKI_STRICT_ALL=1 | Promover las pruebas PT/DE de solo advertencia a estrictas. |
HIBIKI_LENIENT=1 | Degradar las pruebas FR/ES de estrictas a solo advertencia (solo para depuración). |
HIBIKI_MODEL_ID=<repo> | Anular el id de modelo por defecto aufklarer/Hibiki-Zero-3B-MLX-4bit. |
Rendimiento (M2 Max, MLX 4-bit)
| Métrica | Greedy | Muestreado |
|---|---|---|
| Latencia por paso | ~75 ms | ~95 ms |
| Tiempo de reloj para una fuente FR de 3.54 s | ~5 s | ~7 s |
| Duración de la salida | 1.0–1.6× la fuente | 1.0–1.6× la fuente |
Limitaciones conocidas
translateStream()emite un solo fragmento final. El punto de entrada de streaming actualmente envuelve atranslate()offline. La decodificación verdadera de Mimi en streaming por fragmento es un seguimiento de v2.- Sin decodificador de texto SentencePiece. La bandera
--transcriptimprime IDs de token en bruto. El cableado de la decodificación SPM es un seguimiento. - El modo muestreado es notablemente más ruidoso que el greedy. Usa
HIBIKI_GREEDY=1para ejecuciones reproducibles. - Solo cuantización. El repositorio actualmente entrega Zero-3B 4-bit y 8-bit; las variantes 1B y 2B de Hibiki existen en el conversor (
models/hibiki/export/convert.py) pero el driver en Swift apunta a la disposición GQA + rope_concat + no condicionada de Zero-3B.
Referencias
- Artículo: High-Fidelity Simultaneous Speech-to-Speech Translation (Kyutai, 2025)
- Código upstream: kyutai-labs/hibiki
- Muestras: kyutai/hibiki-zero-samples
- Licencia: CC-BY-4.0