Omnilingual ASR
Omnilingual ASR de Meta es una familia de reconocimiento de voz agnóstica al idioma que cubre 1.672 idiomas en 32 escrituras distintas — la mayor cobertura de idiomas de cualquier modelo ASR en el dispositivo en Apple Silicon. Soniqo porta la variante CTC tanto a CoreML (Neural Engine) como a MLX (GPU Metal), con cuatro tamaños de modelo desde 300M hasta 7B parámetros.
A diferencia de Qwen3-ASR o Parakeet TDT, Omnilingual CTC no recibe una pista de idioma en tiempo de inferencia — usa un vocabulario SentencePiece compartido de 10.288 entradas que abarca todos los idiomas soportados. Pasa cualquier audio en cualquier idioma soportado y el modelo producirá automáticamente la escritura correcta.
Arquitectura
Omnilingual CTC es un ajuste fino supervisado del backbone wav2vec 2.0 de Meta con una cabeza CTC lineal sobre un vocabulario multilingüe compartido. El pipeline es paralelo y no autorregresivo — una pasada hacia adelante por enunciado, sin bucle de decodificador.
raw audio [1, samples]
→ wav2vec2 feature extractor (7 strided CNN layers, ×320 downsample)
→ weight-normalised Conv1d positional encoder
→ N × pre-norm Transformer encoder layers
→ final layer norm
→ linear CTC head → logits [1, T, 10288]
Con entrada a 16 kHz, el codificador con downsampling ×320 produce una tasa de frames de 50 Hz. Un clip de 10 segundos produce 499 frames de logits. La decodificación greedy CTC colapsa duplicados consecutivos y omite tokens especiales mediante el tokenizer SentencePiece.
Variantes del modelo
Hay diez variantes publicadas bajo el espacio de nombres aufklarer en HuggingFace — dos tamaños de ventana CoreML más ocho combinaciones de cuantización MLX:
| Variante | Capas | Dim | Cabezas | Tamaño | Runtime |
|---|---|---|---|---|---|
| CTC-300M-CoreML-INT8 (ventana 5 s) | 24 | 1024 | 16 | 312 MB | Neural Engine |
| CTC-300M-CoreML-INT8 (ventana 10 s) | 24 | 1024 | 16 | 312 MB | Neural Engine |
| CTC-300M-MLX-4bit | 24 | 1024 | 16 | 193 MB | GPU Metal |
| CTC-300M-MLX-8bit | 24 | 1024 | 16 | 342 MB | GPU Metal |
| CTC-1B-MLX-4bit | 48 | 1280 | 20 | 549 MB | GPU Metal |
| CTC-1B-MLX-8bit | 48 | 1280 | 20 | 1006 MB | GPU Metal |
| CTC-3B-MLX-4bit | 60 | 2048 | 32 | 1.71 GB | GPU Metal |
| CTC-3B-MLX-8bit | 60 | 2048 | 32 | 3.16 GB | GPU Metal |
| CTC-7B-MLX-4bit | 128 | 2048 | 32 | 3.55 GB | GPU Metal |
| CTC-7B-MLX-8bit | 128 | 2048 | 32 | 6.63 GB | GPU Metal |
Uso de CLI
CoreML (Neural Engine)
# ventana de 10 s (por defecto)
.build/release/audio transcribe recording.wav --engine omnilingual
# ventana de 5 s (menor memoria, arranque en frío más rápido)
.build/release/audio transcribe recording.wav --engine omnilingual --window 5
MLX (GPU Metal)
# 300M @ 4-bit (variante MLX por defecto)
.build/release/audio transcribe recording.wav --engine omnilingual --backend mlx
# 1B @ 4-bit — mayor precisión
.build/release/audio transcribe recording.wav --engine omnilingual --backend mlx --variant 1B
# 3B @ 8-bit — se acerca a la calidad de referencia
.build/release/audio transcribe recording.wav --engine omnilingual --backend mlx --variant 3B --bits 8
# 7B @ 4-bit — la variante CTC más grande, mejor precisión
.build/release/audio transcribe recording.wav --engine omnilingual --backend mlx --variant 7B
API Swift
Backend CoreML
import OmnilingualASR
import AudioCommon
let model = try await OmnilingualASRModel.fromPretrained()
let audio = try AudioFileLoader.load(url: url, targetSampleRate: 16000)
let text = try model.transcribeAudio(audio, sampleRate: 16000)
print(text)
Backend MLX
import OmnilingualASR
// Por defecto: 300M @ 4-bit
let model = try await OmnilingualASRMLXModel.fromPretrained()
// Variantes más grandes
let big = try await OmnilingualASRMLXModel.fromPretrained(variant: .b1, bits: 4)
let huge = try await OmnilingualASRMLXModel.fromPretrained(variant: .b3, bits: 8)
let max = try await OmnilingualASRMLXModel.fromPretrained(variant: .b7, bits: 4)
let text = try model.transcribeAudio(audio, sampleRate: 16000)
CoreML vs MLX
Ambos backends producen transcripciones esencialmente idénticas salvo 1-2 caracteres (diferencias de cuantización y runtime). Elige según tu objetivo de despliegue:
| CoreML | MLX | |
|---|---|---|
| Objetivo de cómputo | Neural Engine | GPU Metal |
| Longitud de entrada | Ventana fija (5 s o 10 s) | Cualquier longitud hasta 40 s |
| Tamaños de modelo | Solo 300M | 300M / 1B / 3B / 7B |
| Cuantización | Paletización INT8 | 4 bits o 8 bits con QuantizedLinear |
| Ejecución concurrente con TTS en GPU | Sí (el ANE es independiente) | Contiende con TTS en GPU |
| Soporte iOS | iOS 17+ | Cualquier iOS con Apple Silicon |
Detalles de preprocesamiento
Omnilingual requiere layer-norm a nivel de enunciado sobre la forma de onda en bruto, coincidiendo con el apply_audio_normalization de fairseq2:
normalized = (audio - mean(audio)) / sqrt(variance(audio) + 1e-5)
El port Swift normaliza el contenido de audio real antes del zero-padding a la ventana fija de CoreML, por lo que las entradas sub-ventana coinciden exactamente con las estadísticas del pipeline de referencia. Este es el fallo de porting más común — la implementación de wav2vec2 de HuggingFace hace group-norm por característica, no layer-norm a nivel de enunciado.
El pipeline de referencia impone un límite duro de 40 segundos (MAX_ALLOWED_AUDIO_SEC) en el audio de entrada. El port Swift impone el mismo límite — entradas más largas lanzan un error claro que apunta a SpeechVAD o ParakeetStreamingASR para procesamiento segmentado.
Cobertura de idiomas
Omnilingual soporta 1.672 idiomas en 32 escrituras, incluyendo más de 500 idiomas de bajos recursos añadidos mediante recolección de datos comunitaria. Muestra de la cobertura:
| Escritura | Idiomas | Códigos de muestra |
|---|---|---|
| Latina | 1.398 | eng_Latn, fra_Latn, spa_Latn, pcm_Latn, swh_Latn, zul_Latn, … |
| Árabe | 70 | arb_Arab, arz_Arab, ary_Arab, arq_Arab, fas_Arab, urd_Arab, ckb_Arab, uig_Arab, … |
| Devanagari | 65 | hin_Deva, mar_Deva, nep_Deva, bho_Deva, mai_Deva, awa_Deva, brx_Deva, … |
| Cirílica | 51 | rus_Cyrl, ukr_Cyrl, bel_Cyrl, bul_Cyrl, srp_Cyrl, mkd_Cyrl, kaz_Cyrl, … |
| Etíope | 10 | amh_Ethi, tir_Ethi, wal_Ethi, sgw_Ethi, … |
| Bengalí | 8 | ben_Beng, asm_Beng, mni_Beng, … |
| Tailandés / Lao / Birmano / Tibetano | 9 / 1 / 3 / 6 | tha_Thai, lao_Laoo, mya_Mymr, bod_Tibt, dzo_Tibt, … |
| Han (simplificado / tradicional) | 6 | cmn_Hans, cmn_Hant, yue_Hans, yue_Hant, cdo_Hans, … |
| Japonés / Coreano | 1 / 1 | jpn_Jpan, kor_Hang |
| Armenio, georgiano, hebreo, griego, gujarati, gurmukhi, canarés, malayalam, oriya, cingalés, tamil, télugu, tifinagh, thaana, más otros 4 | 48 | Ver lista completa → |
Lista completa de códigos ISO 639-3 + ISO 15924 con nombres en inglés en el fuente lang_ids.py, y agrupada por escritura con indicaciones de país en la ficha del modelo.
Salida verificada
Transcripciones del port Swift en el benchmark FLEURS, CoreML 300M:
| Idioma | Referencia | Salida |
|---|---|---|
| Inglés | Fellow wrestlers also paid tribute to Luna. | fellow wrestlers also paid tribute to luna |
| Árabe | كما أثنى الزملاء المصارعون على لونا | كما أثنى الزملاء المصارعون على لونا |
| Hindi | लूना को साथी पहलवानों ने भी श्रद्धांजलि दी | लूना को साथी पहलवानों ने भी सरधांजलीदी |
| Francés | Pensez à l'itinéraire de ski comme à un itinéraire de randonnée similaire. | pense à létineraire desqui comme un étineraire de rent donner similaire |
La variante MLX 300M-4bit produce una salida esencialmente idéntica salvo 1-2 caracteres. Las variantes más grandes (1B, 3B, 7B) reducen los errores residuales de forma progresiva.
Referencias
- Paper: Omnilingual ASR (arXiv 2511.09690)
- Implementación original: facebookresearch/omnilingual-asr (Apache 2.0)
- Fuente del port Swift: speech-swift/Sources/OmnilingualASR
- Ficha del modelo: docs/models/omnilingual-asr.md