Back to all posts
Tutorial

Reconnaissance vocale multilingue à $0 pour votre Chatbot avec Cloudflare Whisper

Vous développez un Chatbot et souhaitez ajouter la saisie vocale sans payer pour Google Speech-to-Text, AWS Transcribe ou l'API OpenAI Whisper ? Vous avez déjà tout ce qu'il vous faut — dans le plan gratuit de Cloudflare.

Dans cet article, je vous explique en détail comment j'ai intégré Cloudflare Workers AI Whisper large-v3-turbo dans le Chatbot de mon site portfolio, avec une reconnaissance vocale en 99 langues à coût absolument nul. Je partage également les deux bugs de production rencontrés et leurs solutions précises.


Pourquoi Cloudflare Workers AI ?

Cloudflare propose la reconnaissance vocale via Workers AI, qui s'exécute sur le réseau edge mondial de Cloudflare. Le plan gratuit comprend :

  • Inférence Workers AI : gratuite, voir les limites officielles (largement suffisant pour les projets personnels et les petites applications)
  • Aucun cold start : s'exécute sur les nœuds edge, au plus près de vos utilisateurs
  • Aucune clé API à gérer : directement lié à votre Worker via env.AI
  • 99 langues supportées : chinois, japonais, coréen, français, espagnol, arabe, etc.

Le meilleur avantage : vous n'avez pas besoin d'héberger un modèle, gérer des instances GPU, ni vous préoccuper des limites de débit d'une API tierce. Prêt à l'emploi.


Whisper Base vs Whisper Large v3 Turbo : Comparaison approfondie

Cloudflare Workers AI propose deux variantes du modèle Whisper. Choisir le bon est crucial.

@cf/openai/whisper (Version de base)

C'est le modèle Whisper base original (≈39 millions de paramètres).

Avantages :

  • Inférence rapide — idéal pour les applications sensibles à la latence
  • Faible consommation de ressources par requête
  • Testé et stable sur Cloudflare

Inconvénients :

  • Taux d'erreur de mots (WER) plus élevé, particulièrement pour les langues non-anglaises
  • Difficultés avec les accents, le vocabulaire technique et les entrées multilingues
  • Format du paramètre audio : number[] (Uint8Array décomposé en tableau JS ordinaire)

Idéal pour : Applications à fort trafic où la vitesse prime sur la précision, ou cas d'usage uniquement en anglais.


@cf/openai/whisper-large-v3-turbo (Version Turbo)

Version distillée allégée de Whisper large-v3 (≈809 millions de paramètres), environ 2× plus rapide que large-v3 tout en conservant la majorité de sa précision.

Avantages :

  • WER réduit d'environ 50% par rapport à la version de base — amélioration dramatique pour le chinois, le japonais, le coréen, etc.
  • Excellente précision multilingue, même avec des accents variés
  • Paramètres optionnels : language, task (transcribe/translate), vad_filter, beam_size
  • Sortie enrichie : text, word_count, segments avec timing WebVTT

Inconvénients :

  • Plus lourd que la version de base — latence légèrement plus élevée par requête
  • Format du paramètre audio : chaîne Base64 (pas un tableau de nombres — cause de mon premier bug)
  • Ne décode pas stablement les conteneurs webm/opus (cause de mon deuxième bug)

Idéal pour : Chatbots multilingues, assistants vocaux, outils d'accessibilité, pipelines de transcription où la précision est critique.


Tableau comparatif

| | @cf/openai/whisper | @cf/openai/whisper-large-v3-turbo | |---|---|---| | Paramètres | ≈39M | ≈809M | | Langues | 99 | 99 | | Précision | Bonne | Excellente | | Vitesse | La plus rapide | Rapide (≈2× plus vite que large-v3) | | Format audio | number[] | Chaîne Base64 | | Conteneurs supportés | webm, wav, mp3 | wav, mp3 (webm instable) | | Champs de sortie supplémentaires | text uniquement | text, word_count, segments | | Coût Cloudflare | Plan gratuit | Plan gratuit |


Deux bugs de production rencontrés

Bug 1 : Erreur 5006 — Type mismatch

Après le passage de @cf/openai/whisper à whisper-large-v3-turbo, l'API retournait l'erreur 5006.

Cause principale : J'avais conservé l'ancien format audio: [...audioBytes] (tableau de nombres), attendu par le modèle de base. Le modèle turbo exige une chaîne Base64. Les deux modèles ont des schémas d'entrée complètement différents — ce qui n'est pas clairement documenté.

Solution : Côté serveur, utiliser btoa() par morceaux pour convertir Uint8Array en chaîne Base64 avant de la passer au modèle.


Bug 2 : Erreur 3030 — Échec du décodage du fichier audio

Après correction du format Base64, l'erreur 3030 est apparue.

Cause principale : Le navigateur enregistre en format webm/opus. Même avec un encodage Base64 correct, le modèle turbo ne pouvait pas décoder le conteneur webm/opus. Cloudflare Whisper turbo ne supporte de manière stable que WAV et MP3.

Solution : Décoder l'enregistrement webm/opus dans le navigateur avec AudioContext.decodeAudioData(), puis ré-encoder en WAV PCM 16-bit avec encodeWAV() avant l'upload. Le WAV est le format d'entrée Whisper le plus universellement supporté.


Points clés et conseils

  1. export const runtime = 'edge' est obligatoire. Sans cela, getRequestContext() ne retourne rien sur Cloudflare Pages.

  2. Pas de Buffer dans Edge Runtime. N'utilisez pas Buffer.from(bytes).toString('base64') — utilisez btoa() avec du chunking pour éviter le dépassement de pile sur les gros fichiers audio.

  3. Les types du champ audio diffèrent entre turbo et base. Cette différence n'est pas documentée explicitement — découverte par l'erreur et l'expérimentation.

  4. Toujours fermer AudioContext. Les navigateurs limitent le nombre d'instances AudioContext simultanées. Appelez toujours await audioCtx.close() après le décodage.

  5. Protégez-vous contre les enregistrements vides. Un tap accidentel sur le micro déclenchera une exception de decodeAudioData sur un blob vide. Vérifiez blob.size < 1000 et retournez prématurément.

  6. Base64 augmente la taille d'environ 33%. Un enregistrement de 10 secondes (~160KB PCM brut) devient ~215KB en Base64 — bien en dessous des limites Cloudflare.

  7. iOS exige un geste utilisateur pour créer AudioContext. Utilisez onPointerDown (pas un timer ou useEffect) pour satisfaire cette exigence.


Résultat final

Après implémentation de ce pipeline, mon Chatbot supporte :

  • Maintenir pour parler : Maintenez le bouton micro enfoncé, parlez, relâchez pour transcrire
  • Tap pour basculer : Un tap pour démarrer, parlez, un autre tap pour transcrire
  • 99 langues avec une excellente précision en chinois, japonais, coréen, anglais, etc.
  • Zéro coût — entièrement dans le plan gratuit de Cloudflare
  • Aucune clé API tierce — tout s'exécute sur l'edge Cloudflare

Si vous développez un produit IA multilingue avec besoin de saisie vocale, Cloudflare Workers AI Whisper est la réponse. Les deux bugs rencontrés ne sont pas documentés explicitement — j'espère que cet article vous épargnera des heures de débogage.


L'implémentation complète est en ligne sur elvisli.ca.