Épisode 2 — Premiers pas : du scraping, de la transcription… et un modèle qui hallucine
Deuxième épisode de la série où je raconte, cet été, la construction d'un RAG sur mes propres serveurs.
Pour commencer cette aventure, j'ai choisi la simplicité. J'ai installé n8n (avec Docker) et créé un premier workflow : une URL en entrée, un scraper en Python, un nettoyage du code récupéré, et une sortie au format JSON. Rien d'extraordinaire, mais ça fonctionne, et c'est hébergé chez moi. Il n'est pas nécessaire de développer une interface graphique complète pour tester des PoC.
Ensuite, un deuxième workflow : envoyer un fichier audio à un modèle et récupérer la transcription au format JSON. J'ai monté un conteneur Docker avec faster-whisper. Avec de petits fichiers, tout fonctionnait bien. Puis j'ai transcrit des enregistrements plus longs — 50 minutes, une heure. Et là, surprise : « Sous-titrage Société Radio-Canada » au milieu de ma transcription, ou des centaines de « Oui » qui tournent en boucle. Le modèle hallucine : il invente du texte qui n'a jamais été prononcé. Première leçon — ce qui fonctionne sur un petit fichier ne fonctionne pas forcément à l'échelle. Il a fallu comprendre, chercher, corriger.
Deuxième mur, matériel celui-là. faster-whisper tournait très bien sur mes machines x86, mais je voulais faire tourner tout ça sur un serveur GPU en architecture ARM — et là, pas de support. Changement de moteur : je passe à Voxtral, servi par vLLM, qui, lui, tourne sur l'ARM. Sauf que Voxtral ne rend que du texte, sans les horodatages dont j'avais besoin. J'ai donc développé un service d'alignement pour réassocier un timestamp à chaque mot.
Et un problème en cache souvent un autre : Voxtral partait parfois en boucle, à générer du texte sans fin — des transcriptions vides ou du charabia. Retour à Whisper (large-v3), cette fois servi par vLLM et alimenté par des tranches audio courtes. Avec, autour, tout ce qu'il fallait pour que ça tienne : un pré-traitement du son (réduire le bruit, renforcer les voix), une correction des hallucinations, et le stockage des fichiers dans un S3. De fil en aiguille, j'en suis arrivé à une solution fonctionnelle. Perfectible, à ajuster, à optimiser — mais fonctionnelle.
Au-delà du service lui-même, ce que je retiens de cette première étape, c'est une méthode de travail. Ce n'est ni mon premier développement, ni mes premiers tests avec l'aide de l'IA. Ce qui a fonctionné ici, c'est ce que j'applique à chaque projet — nouvelle fonctionnalité, mise à jour, optimisation. Aujourd'hui, l'IA permet d'aller plus vite ; mais pour aller plus vite, il faut le faire correctement. Il est impératif de préparer, rédiger, lire et challenger avant de lancer un agent dans le développement. On peut lui dire : « Développe-moi un service STT. » Mais le résultat ne sera pas celui attendu.
Lorsque j'ai un besoin, j'utilise l'IA pour échanger les premières idées, lui donner mes contraintes, puis je rédige un document de cadrage — ce que le service doit faire, ce qu'il ne doit pas faire, les cas limites. Puis un plan de développement, découpé en étapes. Je relis, et je demande à un autre agent de tout challenger : trouver les failles, les oublis, les cas non prévus. Le développement ne démarre qu'après, et les tests sont écrits en même temps. Chaque développement se termine par une documentation — d'utilisation, d'implémentation — qui servira au suivant.
Voici la suite de l'histoire.