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

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. 本番運用の最適化ノウハウ
- VAD (Voice Activity Detection): 無音部分のデータ送信をフロントエンド側でスキップし、AI実行コストを削減します。
- 多言語および翻訳機能: 本記事で使用している
@cf/openai/whisper(base)モデルはlanguage・taskパラメータに対応していません。多言語認識や自動翻訳が必要な場合は@cf/openai/whisper-large-v3-turboモデルに切り替えた上で、language: "ja"やtask: "translate"を指定すれば、音声の英語自動翻訳文字起こしを実現できます。 - WebSocketの活用: リアルタイムな双方向フィードバックが必要な場合は、WorkersのWebSocketバ인ディングを組み合わせて構築します。
まとめ
Cloudflare Workers AI と Whisper の組み合わせは、音声認識パイプラインの概念を大きく変えます。
[!NOTE]
- GPUインフラの管理なしに
env.AI.run('@cf/openai/whisper', ...)のコードでSTTパイプラインを完結させましょう。- MediaRecorder APIを使い1〜2秒単位のチャンク送信を行うことで、体感速度を最大化します。
- Cloudflareのエッジインフラを活用し、サーバー管理不要・低コスト・超低遅延を実現しましょう。
サーバー運用コストの心配なく、高度な音声認識機能を短時間でプロダクトに導入できます。