Back to all posts
Tutorial

Cloudflare Whisperで$0コストの多言語音声認識をChatbotに追加する

Chatbotを構築していて音声入力を追加したいが、Google Speech-to-Text、AWS Transcribe、OpenAI Whisper APIには課金したくない——そんなあなたは、すでに必要なものをすべて持っています。Cloudflareの無料プランの中に。

この記事では、Cloudflare Workers AI Whisper large-v3-turboを私のポートフォリオサイトのChatbotに統合し、99言語の音声認識を完全無料で実現した方法を詳しく解説します。また、本番環境で遭遇した2つのバグと、その正確な修正方法も共有します。


なぜCloudflare Workers AIなのか?

CloudflareはWorkers AIを通じて音声認識機能を提供しており、Cloudflareのグローバルエッジネットワーク上で動作します。無料プランには以下が含まれます:

  • Workers AI推論:無料、制限は公式ドキュメントを参照(個人プロジェクトや小規模アプリに十分)
  • コールドスタートなし:エッジノードで動作し、ユーザーに最も近い場所で実行
  • APIキー管理不要:env.AIを通じてWorkerに直接バインド
  • 99言語対応:中国語、日本語、韓国語、フランス語、スペイン語、アラビア語など

最大の利点:モデルをホストしたり、GPUインスタンスを管理したり、サードパーティAPIのレート制限を気にする必要がありません。すぐに使えます。


Whisper Base vs Whisper Large v3 Turbo:詳細比較

Cloudflare Workers AIは2つのWhisperモデルを提供しています。正しいモデルを選ぶことが重要です。

@cf/openai/whisper(ベース版)

オリジナルのWhisper baseモデル(約3,900万パラメータ)です。

メリット:

  • 推論速度が速い——レイテンシに敏感なアプリケーションに最適
  • リクエストあたりのリソース消費が少ない
  • Cloudflare上で十分に検証済みで安定している

デメリット:

  • 単語誤り率(WER)が高め、特に非英語言語で
  • アクセント、専門用語、混合言語入力の認識が弱い
  • audioパラメータ形式:number[](Uint8Arrayを通常のJS配列に展開)

最適なユースケース: スピードが精度より重要な高トラフィックアプリ、または英語専用のユースケース。


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

Whisper large-v3の軽量蒸留版(約8億900万パラメータ)で、large-v3より約2倍速く、精度の大部分を保持しています。

メリット:

  • ベース版と比較してWERが約50%低減——中国語、日本語、韓国語などで大幅に改善
  • 様々なアクセントに対して優れた多言語精度
  • オプションパラメータ対応:language、task(transcribe/translate)、vad_filter、beam_size
  • 豊富な出力:text、word_count、WebVTTタイミング付きsegments

デメリット:

  • ベース版より重い——リクエストあたりのレイテンシが若干高い
  • audioパラメータ形式:Base64文字列(数値配列ではない——これが最初のバグの原因)
  • webm/opusコンテナを安定してデコードできない(これが2番目のバグの原因)

最適なユースケース: 多言語Chatbot、音声アシスタント、アクセシビリティツール、精度が重要な文字起こしパイプライン。


比較サマリー

| | @cf/openai/whisper | @cf/openai/whisper-large-v3-turbo | |---|---|---| | パラメータ数 | 約3,900万 | 約8億900万 | | 対応言語 | 99言語 | 99言語 | | 認識精度 | 良好 | 優秀 | | 推論速度 | 最速 | 速い(large-v3より約2×) | | audioパラメータ形式 | number[] | Base64文字列 | | 対応コンテナ | webm、wav、mp3 | wav、mp3(webmは不安定) | | 追加出力フィールド | textのみ | text、word_count、segments | | Cloudflareコスト | 無料プラン | 無料プラン |


アーキテクチャ

構築したフルパイプライン:

ブラウザマイク
    ↓
MediaRecorder(webm/opus録音——ブラウザのデフォルト形式)
    ↓ 【クライアント側トランスコード】
AudioContext.decodeAudioData() → webm/opusをデコード
    ↓
encodeWAV() → 16-bit PCM WAV(モノラル、ネイティブサンプルレート)
    ↓ HTTP POST multipart/form-data
/api/transcribe(Next.js Edge Route on Cloudflare Pages)
    ↓
getRequestContext().env.AI(Cloudflare AIバインディング)
    ↓
btoa() → 8192バイトのチャンクでBase64エンコード
    ↓
env.AI.run('@cf/openai/whisper-large-v3-turbo', { audio: base64 })
    ↓
{ text: "文字起こし結果" } → Chatbot入力欄に反映

本番で遭遇した2つのバグ

バグ1:エラーコード5006 — タイプミスマッチ

@cf/openai/whisperからwhisper-large-v3-turboに切り替えた後、APIがエラー5006を返しました。

根本原因: ベースモデルが期待する古い形式audio: [...audioBytes](数値配列)をそのまま使い続けたことです。turboモデルはBase64文字列を要求します。2つのモデルは入力スキーマが完全に異なります——しかしドキュメントには明記されていませんでした。

修正方法: サーバー側でbtoa()を使ってチャンク処理し、Uint8ArrayをBase64文字列にエンコードしてから渡します。


バグ2:エラーコード3030 — 音声ファイルのデコード失敗

Base64形式を修正した後、エラー3030が発生しました。

根本原因: ブラウザはwebm/opus形式で録音します。Base64エンコードは正しかったのですが、turboモデルがwebm/opusコンテナをデコードできませんでした。Cloudflare Whisper turboが安定してサポートするのはWAVとMP3のみです。

修正方法: ブラウザ側でAudioContext.decodeAudioData()を使ってwebm/opusをデコードし、カスタムencodeWAV()で16-bit PCM WAVに再エンコードしてアップロードします。WAVはWhisperで最も普遍的にサポートされる入力形式です。


重要な注意点とヒント

  1. export const runtime = 'edge'は必須です。 これがないと、getRequestContext()はCloudflare Pages上で何も返しません。

  2. Edge RuntimeにはBufferがありません。 Base64エンコードにBuffer.from(bytes).toString('base64')は使えません。btoa()とチャンク処理を使用し、大きな音声ファイルでコールスタックオーバーフローを防いでください。

  3. turboとbaseモデルのaudioフィールドの型が異なります。 この違いはドキュメントに明記されていません——エラーと実験から発見しました。

  4. AudioContextは必ず閉じてください。 ブラウザは同時に存在できるAudioContextインスタンス数に上限があります。デコード後は必ずawait audioCtx.close()を呼び出してください。

  5. 空の録音に注意してください。 ユーザーが誤ってマイクをタップしてすぐ離した場合、decodeAudioDataは空のblobに対して例外をスローします。blob.size < 1000をチェックして早期リターンしてください。

  6. Base64は約33%のサイズ増加をもたらします。 10秒の音声録音(約160KB生PCM)はBase64後に約215KBになり、Cloudflareの制限内に収まります。

  7. iOSはユーザージェスチャが必要です。 AudioContextを作成するためにonPointerDown(タイマーやuseEffectではなく)を使用してください。


最終結果

このパイプラインを実装後、私のChatbotは以下をサポートします:

  • 長押しして話す:マイクボタンを押したまま話し、離したら文字起こし
  • タップ切り替え:一度タップして録音開始、話し終えたらもう一度タップして文字起こし
  • 99言語:中国語、日本語、韓国語、英語などで優れた認識精度
  • ゼロコスト:Cloudflareの無料プラン内で完結
  • サードパーティAPIキー不要:すべてCloudflareエッジで動作

多言語AIプロダクトを構築していて音声入力が必要な場合、Cloudflare Workers AI Whisperが答えです。私が遭遇した2つのバグはドキュメントに明記されていません——この記事が数時間のデバッグを節約するお役に立てれば幸いです。


完全な実装はelvisli.caで公開中です。