- Introduction : La valeur opérationnelle de la reconnaissance vocale
Dans les flux de travail modernes, convertir la parole en texte est une nécessité récurrente. La documentation de réunions, la retranscription d'entretiens, le sous-titrage de vidéos ou la numérisation de notes vocales sont des tâches qui, manuellement, consomment un temps précieux et sont sujettes aux erreurs.
Les solutions traditionnelles de reconnaissance vocale (ASR) se heurtent souvent à des limitations : support linguistique restreint, difficulté avec les dialectes, déploiement complexité et courbe d'apprentissage abrupte. Le service basé sur le modèle Qwen3-ASR-1.7B est spécifiquement conçu pour pallier ces problèmes.
Ce service offre une prise en charge étendue de plus de 30 langues et de 22 dialectes chinois. Qu'il s'agisse d'un enregistrement de réunion en anglais, d'un entretien en cantonais ou de mandarin avec un accent régional, la transcription en texte est réalisée avec précision. Son avantage majeur réside également dans un schéma de déploiement simplifié, permettant aux développeurs de monter rapidement leur propre plateforme de conversion de la parole à l'écrit.
Cet article guide pas à pas à travers le déploiement et l'utilisation de Qwen3-ASR, depuis la préparation de l'environnement jusqu'à son application concrète, pour une maîtrise rapide de cet outil puissant.
- Préparation de l'environnement et déploiement rapide
2.1 Vérification des prérequis système
Avant de commencer, assurez-vous que votre système répond à ces exigences minimales :
- Système d'exploitation : Ubuntu 20.04 ou supérieur (recommandé)
- Version de Python : 3.10+
- Version de CUDA : 12.x (pour l'accélération GPU)
- Mémoire GPU : ≥ 16 Go
- Mémoire système : ≥ 32 Go
- Espace disque : ≥ 10 Go
Vérifiez la configuration système avec les commandes suivantes :
# Vérification de la version du système
lsb_release -a
# Vérification de la version de Python
python3 --version
# Vérification de la version de CUDA
nvcc --version
# Vérification de la mémoire et de l'espace disque
free -h
df -h
2.2 Schémas de déploiement
Qwen3-ASR propose deux méthodes de déploiement. Pour une prise en main rapide, la méthode directe est recommandée.
Méthode 1 : Démarrage direct (recommandé pour le développement et les tests)
# Accéder au répertoire du projet et lancer le service
cd /chemin/vers/Qwen3-ASR-1.7B/
./start.sh
Ce script de démarrage automatise les étapes suivantes : activation de l'environnement virtuel Python, configuration des variables d'environnement, chargement du modèle de reconnaissance vocale et démarrage de l'interface web.
Méthode 2 : Service systemd (adapté aux environnements de production)
Pour un fonctionnement continu, systemd est préconisé :
# Installation de la configuration du service
sudo cp /chemin/vers/Qwen3-ASR-1.7B/qwen3-asr.service /etc/systemd/system/
sudo systemctl daemon-reload
# Démarrage du service et activation au démarrage
sudo systemctl enable --now qwen3-asr
# Vérification de l'état du service
sudo systemctl status qwen3-asr
Une fois déployé, le service écoute par défaut sur le port 7860. L'interface web est accessible via http://adresse_ip_serveur:7860.
- Capacités principales et support multilingue
3.1 Langues et dialectes supportés
La force de Qwen3-ASR réside dans son couverture linguistique étendue :
Langues principales (30+) : Chinois (Mandarin), Anglais, Japonais, Coréen, Français, Allemand, Espagnol, Russe, Arabe, Portugais, Italien, Néerlandais, ainsi que de nombreuses autres langues européennes et asiatiques.
Dialectes chinois (22) : Cantonais (Guangdong), Sichuanais, Shanghaïen, Minnan, Hakka, Tianjinois, Nord-Est, Shandong, Henan, Shaanxi, entre autres dialectes majeurs.
Cette large couverture permet à Qwen3-ASR de s'adapter à de multiples scénarios réels, depuis les conférences internationales jusqu'aux entretiens régionaux.
3.2 Détection automatique de la langue
Qwen3-ASR intègre une intelligence de détection linguistique. Il n'est pas nécessaire de spécifier manuellement la langue. Le système analyse automatiquement le contenu audio, identifie la langue ou le dialecte utilisé et procède à la transcription appropriée.
Cette fonctionnalité est particulièrement utile en pratique, notamment lors du traitement d'audios multilingues mélangés, où le système bascule automatiquement de mode de reconnaissance pour garantir l'exactitude de la conversion.
- Mise en pratique : Exemples d'appels API
4.1 Appel via un client Python
L'utilisation de Python pour interagir avec le service Qwen3-ASR est simple. Voici un exemple complet :
import requests
import json
class TranscripteurQwen:
def __init__(self, url_serveur="http://localhost:7860"):
self.url_serveur = url_serveur
def convertir_audio(self, chemin_audio):
"""Transcrit un fichier audio en texte"""
try:
with open(chemin_audio, "rb") as fichier_audio:
fichiers = {"audio": fichier_audio}
reponse = requests.post(
f"{self.url_serveur}/api/predict",
files=fichiers,
timeout=30
)
if reponse.status_code == 200:
resultat = reponse.json()
return resultat
else:
print(f"Échec de la requête, code statut : {reponse.status_code}")
return None
except Exception as e:
print(f"Erreur durant la transcription : {str(e)}")
return None
# Exemple d'utilisation
if __name__ == "__main__":
client_asr = TranscripteurQwen()
resultat = client_asr.convertir_audio("enregistrement_reunion.wav")
if resultat:
print("Résultat de la transcription :")
print(f"Texte identifié : {resultat.get('text', '')}")
print(f"Langue détectée : {resultat.get('language', 'Inconnue')}")
print(f"Temps de traitement : {resultat.get('process_time', 0):.2f}s")
4.2 Appel en ligne de commande
Pour une utilisation via le terminal, curl permet d'interroger directement l'API :
# Appel de base
curl -X POST http://localhost:7860/api/predict \
-F "audio=@audio.wav"
# Sauvegarde du résultat dans un fichier
curl -X POST http://localhost:7860/api/predict \
-F "audio=@entretien.mp3" \
-o resultat_transcription.json
# Traitement par lot de plusieurs fichiers
for fichier in *.wav; do
echo "Traitement du fichier : $fichier"
curl -X POST http://localhost:7860/api/predict \
-F "audio=@$fichier" \
-o "${fichier%.wav}_resultat.json"
sleep 1 # Délai pour éviter une surcharge de requêtes
done
4.3 Traitemant de flux audio en temps réel
Au-delà du traitement de fichiers, Qwen3-ASR peut reconnaître des flux audio en direct :
import pyaudio
import requests
import json
class TranscripteurTempsReel:
def __init__(self, url_serveur, taille_bloc=1024, format_audio=pyaudio.paInt16, canaux=1, taux_echantillonnage=16000):
self.url_serveur = url_serveur
self.taille_bloc = taille_bloc
self.format_audio = format_audio
self.canaux = canaux
self.taux = taux_echantillonnage
self.interface_audio = pyaudio.PyAudio()
self.flux = self.interface_audio.open(
format=self.format_audio,
channels=self.canaux,
rate=self.taux,
input=True,
frames_per_buffer=self.taille_bloc
)
def demarrer_transcription(self, duree=10):
"""Enregistre l'audio et le transcrit en temps réel"""
print("Début de l'enregistrement...")
trames = []
nombre_blocs = int(self.taux / self.taille_bloc * duree)
for _ in range(nombre_blocs):
donnees = self.flux.read(self.taille_bloc)
trames.append(donnees)
print("Enregistrement terminé, début de la reconnaissance...")
donnees_audio = b''.join(trames)
reponse = requests.post(
f"{self.url_serveur}/api/predict",
files={"audio": ("temps_reel.wav", donnees_audio, "audio/wav")}
)
if reponse.status_code == 200:
resultat = reponse.json()
print(f"Résultat de la reconnaissance en temps réel : {resultat.get('text', '')}")
self.flux.stop_stream()
self.flux.close()
self.interface_audio.terminate()
# Exemple d'utilisation
transcripteur_rt = TranscripteurTempsReel("http://localhost:7860")
transcripteur_rt.demarrer_transcription(duree=5) # Enregistre 5 secondes d'audio
- Dépannage et optimisation
5.1 Optimisation des performances
Optimisation de la mémoire GPU : En cas de manque de mémoire graphique, ajustez la taille du lot d'inférence :
# Modification du paramètre backend-kwargs dans le script de démarrage
--backend-kwargs '{"max_inference_batch_size":4}'
Activation du mode haute performance : Pour la production, l'utilisation du backend vLLM est recommandée :
# Édition du fichier start.sh, modification du paramètre backend
--backend vllm \
--backend-kwargs '{"gpu_memory_utilization":0.7,"max_inference_batch_size":128}'
Accélération avec FlashAttention : L'installation de FlashAttention2 peut améliorer la vitesse de traitement :
pip install flash-attn --no-build-isolation
# Ajout dans backend-kwargs
--backend-kwargs '{"attn_implementation":"flash_attention_2"}'
5.2 Gestion des erreurs courantes
Conflit de port : Si le port 7860 est déjà utilisé, modifiez le port du service :
# Vérification des processus utilisant le port
sudo lsof -i :7860
# Démarrage avec un port différent
PORT=7861 ./start.sh
Échec du chargement du modèle : Vérifiez l'intégrité des fichiers du modèle :
# Vérification des fichiers du modèle
ls -lh /chemin/vers/ai-models/Qwen/Qwen3-ASR-1___7B/
# Vérification de l'espace disque
df -h
Format audio non supporté : Assurez-vous que le fichier audio est dans un format compatible (WAV, MP3, etc.) avec un taux d'échantillonnage recommandé de 16 kHz :
# Conversion du format audio avec ffmpeg
ffmpeg -i entree.m4a -ar 16000 -ac 1 sortie.wav
5.3 Commandes de gestion du service
Consulter l'état du service :
# État du service systemd
sudo systemctl status qwen3-asr
# Visualisation des journaux du service
sudo journalctl -u qwen3-asr -f
# Consultation directe des fichiers log
tail -f /var/log/qwen-asr/stdout.log
tail -f /var/log/qwen-asr/stderr.log
Redémarrer le service :
# Redémarrage via systemd
sudo systemctl restart qwen3-asr
# Pour le démarrage direct, terminer le processus puis relancer
ps aux | grep qwen-asr-demo
kill <PID>
/root/Qwen3-ASR-1.7B/start.sh
- Exemples de scénarios d'application
6.1 Automatisation des comptes-rendus de réunion
Contexte : La documentation des réunions d'entreprise est souvent chronophage et sujette aux omissions. Qwen3-ASR permet de l'automatiser.
Implémentation :
import os
from datetime import datetime
class EnregistreurReunion:
def __init__(self, client_asr):
self.client_asr = client_asr
self.repertoire_sortie = "comptes_rendus"
os.makedirs(self.repertoire_sortie, exist_ok=True)
def enregistrer_reunion(self, chemin_audio, sujet_reunion):
"""Enregistre une réunion et génère la transcription"""
resultat = self.client_asr.convertir_audio(chemin_audio)
if resultat:
horodatage = datetime.now().strftime("%Y%m%d_%H%M%S")
nom_fichier = f"{sujet_reunion}_{horodatage}.txt"
chemin_fichier = os.path.join(self.repertoire_sortie, nom_fichier)
with open(chemin_fichier, "w", encoding="utf-8") as f:
f.write(f"Sujet de la réunion : {sujet_reunion}\n")
f.write(f"Heure de la réunion : {horodatage}\n")
f.write(f"Langue identifiée : {resultat.get('language', 'Inconnue')}\n")
f.write("\nContenu de la réunion :\n")
f.write(resultat.get('text', ''))
print(f"Le compte-rendu a été sauvegardé : {chemin_fichier}")
return chemin_fichier
return None
# Exemple d'utilisation
client = TranscripteurQwen()
enregistreur = EnregistreurReunion(client)
enregistreur.enregistrer_reunion("reunion_hebdo.wav", "Réunion technique hebdomadaire")
6.2 Génération de sous-titres pour contenus multimédias
Contexte : L'ajout manuel de sous-titres aux vidéos est une tâche fastidieuse pour les créateurs de contenu.
Implémentation :
import moviepy.editor as mp
import os
class GenerateurSousTitres:
def __init__(self, client_asr):
self.client_asr = client_asr
def generer_sous_titres(self, chemin_video, chemin_sortie):
"""Génère un fichier de sous-titres pour une vidéo"""
video = mp.VideoFileClip(chemin_video)
chemin_audio_temp = "audio_temporaire.wav"
video.audio.write_audiofile(chemin_audio_temp, fps=16000)
resultat = self.client_asr.convertir_audio(chemin_audio_temp)
if resultat:
texte_transcrit = resultat.get('text', '')
contenu_srt = self._texte_vers_srt(texte_transcrit, video.duration)
with open(chemin_sortie, "w", encoding="utf-8") as f:
f.write(contenu_srt)
os.remove(chemin_audio_temp)
return chemin_sortie
return None
def _texte_vers_srt(self, texte, duree_totale):
"""Convertit le texte en format SRT (simplifié)"""
phrases = texte.split('。')
contenu_srt = ""
for i, phrase in enumerate(phrases):
if phrase.strip():
heure_debut = i * duree_totale / len(phrases)
heure_fin = (i + 1) * duree_totale / len(phrases)
contenu_srt += f"{i+1}\n"
contenu_srt += f"{self._formater_heure(heure_debut)} --> {self._formater_heure(heure_fin)}\n"
contenu_srt += f"{phrase.strip()}。\n\n"
return contenu_srt
def _formater_heure(self, secondes):
"""Formate un horodatage en SRT"""
heures = int(secondes // 3600)
minutes = int((secondes % 3600) // 60)
secondes_entieres = int(secondes % 60)
millisecondes = int((secondes - int(secondes)) * 1000)
return f"{heures:02d}:{minutes:02d}:{secondes_entieres:02d},{millisecondes:03d}"
# Exemple d'utilisation
client = TranscripteurQwen()
gene_st = GenerateurSousTitres(client)
gene_st.generer_sous_titres("presentation.mp4", "presentation.srt")
6.3 Intégration dans un système de service client multilingue
Contexte : Les entreprises internationales doivent traiter des demandes client dans plusieurs langues. La reconnaissance vocale peut automatiquement convertir les appels en texte pour analyse et traitement.
Implémentation :
import sqlite3
class GestionnaireServiceClient:
def __init__(self, client_asr, chemin_bd="service_client.db"):
self.client_asr = client_asr
self.chemin_bd = chemin_bd
self._initialiser_base_de_donnees()
def _initialiser_base_de_donnees(self):
"""Initialise la base de données SQLite"""
connexion = sqlite3.connect(self.chemin_bd)
curseur = connexion.cursor()
curseur.execute('''
CREATE TABLE IF NOT EXISTS appels_clients (
id INTEGER PRIMARY KEY AUTOINCREMENT,
horodatage DATETIME DEFAULT CURRENT_TIMESTAMP,
fichier_audio TEXT,
texte_transcrit TEXT,
langue_detectee TEXT,
traite INTEGER DEFAULT 0
)
''')
connexion.commit()
connexion.close()
def traiter_appel_client(self, chemin_audio):
"""Traite un enregistrement d'appel client"""
resultat = self.client_asr.convertir_audio(chemin_audio)
if resultat:
connexion = sqlite3.connect(self.chemin_bd)
curseur = connexion.cursor()
curseur.execute('''
INSERT INTO appels_clients (fichier_audio, texte_transcrit, langue_detectee)
VALUES (?, ?, ?)
''', (chemin_audio, resultat.get('text', ''), resultat.get('language', '')))
connexion.commit()
connexion.close()
self._router_vers_service_approprie(resultat)
return True
return False
def _router_vers_service_approprie(self, resultat):
"""Route l'appel vers l'équipe appropriée selon la langue"""
langue = resultat.get('language', '').lower()
texte = resultat.get('text', '')
print(f"Langue détectée : {langue}")
print(f"Contenu de la demande client : { texte}")
if 'english' in langue:
print("Routage vers l'équipe support anglais")
elif 'chinese' in langue:
print("Routage vers l'équipe support chinois")
elif 'french' in langue:
print("Routage vers l'équipe support français")
else:
print("Routage vers l'équipe support multilingue")
def generer_rapport_linguistique(self):
"""Génère un rapport sur la distribution des langues"""
connexion = sqlite3.connect(self.chemin_bd)
curseur = connexion.cursor()
curseur.execute('''
SELECT langue_detectee, COUNT(*) as nombre
FROM appels_clients
GROUP BY langue_detectee
ORDER BY nombre DESC
''')
rapport = curseur.fetchall()
connexion.close()
print("Rapport de distribution des langues des demandes clients :")
for langue, nombre in rapport:
print(f"{langue}: {nombre} demandes")
return rapport
# Exemple d'utilisation
client = TranscripteurQwen()
gestionnaire_sc = GestionnaireServiceClient(client)
gestionnaire_sc.traiter_appel_client("appel_client_en.wav")
gestionnaire_sc.traiter_appel_client("appel_client_fr.wav")
gestionnaire_sc.generer_rapport_linguistique()