Cloudflare Workers AI + Whisper로 실시간 음성 인식(STT) 스트리밍 파이프라인 구현하기

Cloudflare Workers AI + Whisper로 실시간 음성 인식(STT) 스트리밍 파이프라인 구현하기
음성 인식(STT, Speech-to-Text) 기능은 AI 자막 생성, 음성 메모, 실시간 회의록 작성 등 다양한 애플리케이션에서 핵심적인 요소로 자리잡았습니다. 그러나 OpenAI API나 기존 온프레미스 Whisper GPU 서버를 운용하려면 고비용의 이그레스 요금이나 고정 GPU 인프라 유지 비용이 발생합니다.
Cloudflare Workers AI는 Cloudflare 글로벌 에지 네트워크에 탑재된 GPU 인프라를 활용하여 서버리스 방식으로 OpenAI의 Whisper 모델(@cf/openai/whisper)을 초저지연으로 실행할 수 있게 해줍니다.
이번 글에서는 브라우저의 Web Audio API 및 WebSocket/Chunked Stream을 연결하여, Cloudflare Workers AI 기반의 실시간 STT 스트리밍 파이프라인을 구현하는 가이드를 소개합니다.
1. Cloudflare Workers AI + Whisper 아키텍처 이점
| 구분 | 기존 GPU 서버 / 외부 API | Cloudflare Workers AI + Whisper |
|---|---|---|
| GPU 인프라 관리 | GPU 인스턴스 할당 및 자동 스케일링 필요 | 100% 서버리스 (자동 스케일링 및 0ms 관리) |
| 대기 시간 (Latency) | 중앙 데이터센터 통신으로 라운드트립 지연 발생 | 유저와 가장 가까운 글로벌 에지 PoP에서 실행 |
| 비용 체계 | 시간당 고정 GPU 요금 또는 비싼 API 분당 과금 | 실행된 신경망 토큰/초 단위 초저가 서버리스 요금 |
| 스트리밍 호환성 | 별도의 프록시 서버 구축 필요 | Workers WebSocket / Web Streams API 표준 내장 |
2. Workers AI Whisper 모델 호출 코드 (wrangler.jsonc & Worker)
Cloudflare Workers 내에서 바인딩을 통해 별도의 REST 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 {
// 클라이언트로부터 전송된 오디오 바이너리 데이터(WAV/PCM/WebM)
const audioBuffer = await request.arrayBuffer();
// Cloudflare 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, // 자막 파일 포맷 지원
});
} catch (error: any) {
return Response.json({ error: error.message }, { status: 500 });
}
},
};
3. 클라이언트 웹 오디오 레코더 및 스트리밍 전송
브라우저의 MediaRecorder API를 이용해 마이크 음성을 1~2초 단위 Chunk로 잘라 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): 무음 구간 오디오 조각은 API 전송 전 클라이언트에서 캔슬하여 불필요한 AI 호출 비용을 차단합니다.
- 다국어 및 번역 모드: 이 글에서 사용한
@cf/openai/whisper(base) 모델은language/task파라미터를 지원하지 않습니다. 다국어 인식이나 자동 번역이 필요하다면@cf/openai/whisper-large-v3-turbo모델로 교체한 뒤language: "ko"옵션을 명시하거나task: "translate"를 전달해 영어 자동 번역 STT로 활용하세요. - WebSockets 병용: 실시간 양방향 텍스트 피드백이 필요한 경우 Cloudflare Workers의 WebSocket 지원 기능을 결합합니다.
요약 및 결론
Cloudflare Workers AI와 Whisper의 결합은 음성 인식 파이프라인의 구축 및 운용 패러다임을 혁신합니다.
[!NOTE]
- 별도의 외부 GPU 인스턴스 구축 없이
env.AI.run('@cf/openai/whisper', ...)한 줄로 STT 인프라를 완성하세요.- 브라우저의 MediaRecorder API를 통해 1~2초 청크 단위로 분할하여 실시간 체감 속도를 극대화하세요.
- Cloudflare 글로벌 에지 인프라를 활용하여 서버 관리 비용 제로와 글로벌 초저지연을 달성하세요.
서버 프로비저닝 부담 없이 고성능 음성 인식 기능을 서비스에 즉시 도입할 수 있습니다.