effidevFlutter・Cloudflareエッジ・クラウドコスト最適化
日本語

Cloudflare Workers AI + Whisperによるリアルタイム音声認識(STT)ストリーミングパイプラインの構築

Cloudflare Workers AI Whisper Real-time Speech to Text Pipeline

Cloudflare Workers AI + Whisperによるリアルタイム音声認識(STT)ストリーミングパイプラインの構築

音声認識(STT, Speech-to-Text)機能は、AI字幕生成、音声メモ、リアルタイム文字起こしなど、多様なアプリケーションの核となっています。しかし、従来のGPUサーバー構築やサードパーティAPIの利用は、高額なインフラ維持費用や転送コストが発生する原因となります。

Cloudflare Workers AI は、Cloudflareのグローバルエッジネットワーク上に構築されたGPUインフラを活用し、サーバーレスでOpenAIの Whisper モデル (@cf/openai/whisper) を超低遅延で実行可能にします。

本記事では、ブラウザの Web Audio API と連携し、Cloudflare Workers AI をベースにした リアルタイムSTTストリーミングパイプライン を構築する手順を解説します。


1. Cloudflare Workers AI + Whisper の優位性

区分 従来のGPUサーバー / 外部API Cloudflare Workers AI + Whisper
GPUインフラ管理 インスタンス確保やオートスケーリング構築が必要 100% サーバーレス(管理不要、自動スケーリング)
レイテンシ 遠くのデータセンターへの通信による遅延が発生 ユーザーに最も近いグローバルエッジPoPで実行
コスト体系 時間当たりの固定GPU料金または高額な分単位課金 秒単位 / ニューラルトークン使用量に応じた格安な従量課金
ストリーミング互換性 独自のプロキシサーバーの構築が必要 Workers Web Streams / WebSockets 標準内蔵

2. Workers AI Whisper モデルの呼び出し (wrangler.jsonc & Worker)

Cloudflare Workers内からは、バインディングを通じてAPIキーなしでWhisperモデルを直接呼び出すことができます。

1) wrangler.jsonc バインディング設定

{
  "name": "whisper-stt-worker",
  "main": "src/index.ts",
  "compatibility_date": "2026-07-01",
  "ai": {
    "binding": "AI"
  }
}

2) Worker STT 処理ロジック (src/index.ts)

export interface Env {
  AI: any;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== 'POST') {
      return new Response('Method Not Allowed', { status: 405 });
    }

    try {
      // クライアントから送信された音声バイナリデータ
      const audioBuffer = await request.arrayBuffer();

      // Workers AI Whisperモデルの実行
      const response = await env.AI.run('@cf/openai/whisper', {
        audio: [...new Uint8Array(audioBuffer)],
      });

      // テキスト変換結果の返却
      return Response.json({
        text: response.text,
        word_count: response.words?.length || 0,
        vtt: response.vtt, // WebVTT字幕フォーマット対応
      });
    } catch (error: any) {
      return Response.json({ error: error.message }, { status: 500 });
    }
  },
};

3. クライアント側の音声録音およびストリーミング送信

ブラウザの MediaRecorder APIを使い、マイク入力を1〜2秒ごとのチャンクに分割してWorkerへ継続送信する実装例です。

<!-- index.html -->
<button id="startBtn">録音開始</button>
<button id="stopBtn" disabled>停止</button>
<div id="transcript"></div>

<script>
  let mediaRecorder;
  const transcriptDiv = document.getElementById('transcript');

  document.getElementById('startBtn').onclick = async () => {
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });

    mediaRecorder.ondataavailable = async (event) => {
      if (event.data.size > 0) {
        const audioBlob = event.data;
        const arrayBuffer = await audioBlob.arrayBuffer();

        // Cloudflare WorkerのSTTエンドポイントへ送信
        const res = await fetch('/api/stt', {
          method: 'POST',
          headers: { 'Content-Type': 'application/octet-stream' },
          body: arrayBuffer
        });

        const result = await res.json();
        if (result.text) {
          transcriptDiv.innerText += " " + result.text;
        }
      }
    };

    // 2秒ごとに音声データを生成
    mediaRecorder.start(2000);
    document.getElementById('startBtn').disabled = true;
    document.getElementById('stopBtn').disabled = false;
  };
</script>

4. 本番運用の最適化ノウハウ

  1. VAD (Voice Activity Detection): 無音部分のデータ送信をフロントエンド側でスキップし、AI実行コストを削減します。
  2. 多言語および翻訳機能: 本記事で使用している @cf/openai/whisper(base)モデルは languagetask パラメータに対応していません。多言語認識や自動翻訳が必要な場合は @cf/openai/whisper-large-v3-turbo モデルに切り替えた上で、language: "ja"task: "translate" を指定すれば、音声の英語自動翻訳文字起こしを実現できます。
  3. WebSocketの活用: リアルタイムな双方向フィードバックが必要な場合は、WorkersのWebSocketバ인ディングを組み合わせて構築します。

まとめ

Cloudflare Workers AI と Whisper の組み合わせは、音声認識パイプラインの概念を大きく変えます。

[!NOTE]

  1. GPUインフラの管理なしに env.AI.run('@cf/openai/whisper', ...) のコードでSTTパイプラインを完結させましょう。
  2. MediaRecorder APIを使い1〜2秒単位のチャンク送信を行うことで、体感速度を最大化します。
  3. Cloudflareのエッジインフラを活用し、サーバー管理不要・低コスト・超低遅延を実現しましょう。

サーバー運用コストの心配なく、高度な音声認識機能を短時間でプロダクトに導入できます。