Omnilingual ASR
Omnilingual ASR de Meta est une famille de reconnaissance vocale agnostique au langage couvrant 1 672 langues dans 32 écritures distinctes — la couverture linguistique la plus large de tout modèle ASR embarqué sur Apple Silicon. Soniqo porte la variante CTC sur CoreML (Neural Engine) et sur MLX (GPU Metal), avec quatre tailles de modèle de 300M à 7B de paramètres.
Contrairement à Qwen3-ASR ou Parakeet TDT, Omnilingual CTC ne prend pas d'indice de langue à l'inférence — il utilise un vocabulaire SentencePiece partagé de 10 288 entrées couvrant toutes les langues prises en charge. Passez n'importe quel audio dans n'importe quelle langue prise en charge et le modèle produit automatiquement la bonne écriture.
Architecture
Omnilingual CTC est un fine-tune supervisé de la colonne wav2vec 2.0 de Meta avec une tête CTC linéaire sur un vocabulaire multilingue partagé. Le pipeline est parallèle et non-autorégressif — une passe avant par énoncé, sans boucle de décodeur.
audio brut [1, samples]
→ extracteur de caractéristiques wav2vec2 (7 couches CNN à stride, sous-échantillonnage ×320)
→ encodeur positionnel Conv1d à weight-norm
→ N couches d'encodeur Transformer pre-norm
→ layer norm finale
→ tête CTC linéaire → logits [1, T, 10288]
À 16 kHz en entrée, l'encodeur sous-échantillonné ×320 produit un taux de trame de 50 Hz. Un clip de 10 secondes produit 499 trames de logits. Le décodage CTC glouton fusionne les duplicatas consécutifs et saute les tokens spéciaux via le tokenizer SentencePiece.
Variantes du modèle
Dix variantes sont publiées sous le namespace aufklarer sur HuggingFace — deux tailles de fenêtre CoreML plus huit combinaisons de quantification MLX :
| Variante | Couches | Dim | Têtes | Taille | Runtime |
|---|---|---|---|---|---|
| CTC-300M-CoreML-INT8 (fenêtre 5 s) | 24 | 1024 | 16 | 312 Mo | Neural Engine |
| CTC-300M-CoreML-INT8 (fenêtre 10 s) | 24 | 1024 | 16 | 312 Mo | Neural Engine |
| CTC-300M-MLX-4bit | 24 | 1024 | 16 | 193 Mo | GPU Metal |
| CTC-300M-MLX-8bit | 24 | 1024 | 16 | 342 Mo | GPU Metal |
| CTC-1B-MLX-4bit | 48 | 1280 | 20 | 549 Mo | GPU Metal |
| CTC-1B-MLX-8bit | 48 | 1280 | 20 | 1006 Mo | GPU Metal |
| CTC-3B-MLX-4bit | 60 | 2048 | 32 | 1,71 Go | GPU Metal |
| CTC-3B-MLX-8bit | 60 | 2048 | 32 | 3,16 Go | GPU Metal |
| CTC-7B-MLX-4bit | 128 | 2048 | 32 | 3,55 Go | GPU Metal |
| CTC-7B-MLX-8bit | 128 | 2048 | 32 | 6,63 Go | GPU Metal |
Utilisation en CLI
CoreML (Neural Engine)
# Fenêtre 10 s (par défaut)
.build/release/audio transcribe recording.wav --engine omnilingual
# Fenêtre 5 s (mémoire plus faible, démarrage à froid plus rapide)
.build/release/audio transcribe recording.wav --engine omnilingual --window 5
MLX (GPU Metal)
# 300M @ 4 bits (variante MLX par défaut)
.build/release/audio transcribe recording.wav --engine omnilingual --backend mlx
# 1B @ 4 bits — précision supérieure
.build/release/audio transcribe recording.wav --engine omnilingual --backend mlx --variant 1B
# 3B @ 8 bits — s'approche de la qualité de référence
.build/release/audio transcribe recording.wav --engine omnilingual --backend mlx --variant 3B --bits 8
# 7B @ 4 bits — plus grande variante CTC, meilleure précision
.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
// Par défaut : 300M @ 4 bits
let model = try await OmnilingualASRMLXModel.fromPretrained()
// Variantes plus 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
Les deux backends produisent des transcriptions essentiellement identiques à 1-2 caractères près (différences de quantification et d'environnement d'exécution). Choisissez en fonction de votre cible de déploiement :
| CoreML | MLX | |
|---|---|---|
| Cible de calcul | Neural Engine | GPU Metal |
| Longueur d'entrée | Fenêtre fixe (5 s ou 10 s) | Toute longueur jusqu'à 40 s |
| Tailles de modèle | 300M uniquement | 300M / 1B / 3B / 7B |
| Quantification | Palettisation INT8 | QuantizedLinear 4 bits ou 8 bits |
| S'exécute en parallèle du TTS GPU | Oui (l'ANE est indépendant) | En concurrence avec le TTS GPU |
| Support iOS | iOS 17+ | Tout iOS Apple Silicon |
Détails de prétraitement
Omnilingual requiert une layer-norm au niveau de l'énoncé sur la forme d'onde brute, correspondant à apply_audio_normalization de fairseq2 :
normalized = (audio - mean(audio)) / sqrt(variance(audio) + 1e-5)
Le port Swift normalise le contenu audio réel avant le zero-padding vers la fenêtre fixe CoreML, de sorte que les entrées sous-fenêtre correspondent exactement aux statistiques du pipeline de référence. C'est le piège le plus courant — l'implémentation wav2vec2 de HuggingFace fait une group-norm par caractéristique, pas une layer-norm d'énoncé.
Le pipeline de référence impose une limite dure de 40 secondes (MAX_ALLOWED_AUDIO_SEC) sur l'audio en entrée. Le port Swift applique la même limite — des entrées plus longues lèvent une erreur claire pointant vers SpeechVAD ou ParakeetStreamingASR pour un traitement segmenté.
Couverture linguistique
Omnilingual prend en charge 1 672 langues dans 32 écritures, dont plus de 500 langues peu dotées ajoutées via une collecte de données communautaire. Couverture échantillon :
| Écriture | Langues | Codes d'exemple |
|---|---|---|
| Latin | 1 398 | eng_Latn, fra_Latn, spa_Latn, pcm_Latn, swh_Latn, zul_Latn, … |
| Arabe | 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, … |
| Cyrillique | 51 | rus_Cyrl, ukr_Cyrl, bel_Cyrl, bul_Cyrl, srp_Cyrl, mkd_Cyrl, kaz_Cyrl, … |
| Éthiopien | 10 | amh_Ethi, tir_Ethi, wal_Ethi, sgw_Ethi, … |
| Bengali | 8 | ben_Beng, asm_Beng, mni_Beng, … |
| Thaï / Lao / Myanmar / Tibétain | 9 / 1 / 3 / 6 | tha_Thai, lao_Laoo, mya_Mymr, bod_Tibt, dzo_Tibt, … |
| Han (simplifié / traditionnel) | 6 | cmn_Hans, cmn_Hant, yue_Hans, yue_Hant, cdo_Hans, … |
| Japonais / Coréen | 1 / 1 | jpn_Jpan, kor_Hang |
| Arménien, géorgien, hébreu, grec, gujarati, gurmukhi, kannada, malayalam, oriya, sinhala, tamil, telugu, tifinagh, thaana, plus 4 autres | 48 | Voir la liste complète → |
Liste complète des codes ISO 639-3 + ISO 15924 avec noms en anglais dans la source lang_ids.py, et regroupés par écriture avec des indices de pays dans la fiche du modèle.
Sortie vérifiée
Transcriptions du port Swift sur le benchmark FLEURS, CoreML 300M :
| Langue | Référence | Sortie |
|---|---|---|
| Anglais | Fellow wrestlers also paid tribute to Luna. | fellow wrestlers also paid tribute to luna |
| Arabe | كما أثنى الزملاء المصارعون على لونا | كما أثنى الزملاء المصارعون على لونا |
| Hindi | लूना को साथी पहलवानों ने भी श्रद्धांजलि दी | लूना को साथी पहलवानों ने भी सरधांजलीदी |
| Français | 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 produit une sortie essentiellement identique à 1-2 caractères près. Les variantes plus grandes (1B, 3B, 7B) réduisent progressivement les erreurs résiduelles.
Référence
- Article : Omnilingual ASR (arXiv 2511.09690)
- Implémentation en amont : facebookresearch/omnilingual-asr (Apache 2.0)
- Source du port Swift : speech-swift/Sources/OmnilingualASR
- Fiche du modèle : docs/models/omnilingual-asr.md