
대규모 AI 기반 음성 전사 시스템 구축: 엔지니어링 교훈
요약
Vomo가 단순 음성 메모 앱에서 대규모 음성 우선 생산성 플랫폼으로 진화하며 겪은 엔지니어링 경험을 공유합니다. 실시간 스트리밍 전사 방식의 중요성과 오디오 파이프라인 구축 시 고려해야 할 기술적 결정들을 다룹니다.
핵심 포인트
- 실시간 스트리밍 전사는 사용자 경험 측면에서 매우 중요한 결정임
- 단순 전사를 넘어 구조화된 노트와 요약 기능이 제품의 핵심 가치임
- 50개 이상의 언어와 엄격한 지연 시간 요구 사항을 충족해야 함
- 오디오 청크 단위의 스트리밍 파이프라인 구축 경험 공유
18개월 전, 우리는 단순히 간단한 음성 메모 앱을 만들고 있다고 생각했습니다.
우리는 그 "간단한" 부분에 대해 틀렸습니다.
Vomo에서, 음성 노트를 캡처하고 전사(Transcription)하는 도구로 시작했던 것은 50개 이상의 언어, 실시간 스트리밍 전사(Real-time streaming transcription), 그리고 엄격한 지연 시간(Latency) 및 정확도 요구 사항을 가진 점점 늘어나는 기업 고객을 지원하는 완전한 음성 우선(Voice-first) 생산성 플랫폼으로 진화했습니다. 그 과정에서 우리는 많은 것을 배웠으며, 그중 일부는 고통스러운 경험을 통해 얻은 것이었습니다.
이 포스트는 우리가 내린 엔지니어링 결정들, 우리를 힘들게 했던 결정들, 그리고 우리가 다르게 했을 일들에 대해 다룹니다. 만약 여러분이 오디오/음성(Audio/speech) 분야에서 무언가를 구축하고 있다면, 이 글이 여러분의 고통을 줄여줄 수 있기를 바랍니다.
왜 우리는 음성 우선 AI 도구를 만들었는가
초기 통찰은 부끄러울 정도로 단순했습니다. 사람들은 타이핑하는 것보다 더 빠르게 생각한다는 것입니다. 음성 메모는 수십 년 동안 존재해 왔지만, 그것을 사용하는 경험은 끔찍합니다. 무언가를 녹음하면, 그것은 그냥... 거기 놓여 있을 뿐입니다. 전체를 다시 듣거나, 아니면 잊어버리거나 둘 중 하나죠.
우리의 기회는 음성 메모를 실제로 유용하게 만드는 것이었습니다. 단순히 저장된 오디오가 아니라, 자동으로 정리되고, 요약되며, 실행 가능한(Actionable) 캡처된 생각이 되는 것입니다.
그것은 전사(Transcription)가 기본 요건(Table stakes)임을 의미했습니다. 하지만 전사만으로는 지루합니다. 진짜 제품은 그 이후에 텍스트에 일어나는 일들입니다. 구조화된 노트, 실행 항목(Action items), 검색 가능한 아카이브, 스마트 요약, 그리고 Notion, Slack 및 지식 노동자들이 이미 사용 중인 다른 모든 것과의 통합이 그것입니다.
우리는 2주 만에 MVP(Minimum Viable Product)의 범위를 정했습니다. 하지만 그 범위는 현실과 마주하며 살아남지 못했습니다.
기술 아키텍처 (Technical Architecture)
오디오 캡처 및 스트리밍 파이프라인 (Audio Capture and Streaming Pipeline)
우리가 직면한 첫 번째 질문은 이것이었습니다: 사용자가 말하는 동안 오디오를 청크(Chunks) 단위로 서버에 보낼 것인가, 아니면 사용자가 끝낼 때까지 기다렸다가 전체 파일을 처리할 것인가?
우리는 첫날부터 스트리밍 (Streaming) 방식을 선택했으며, 이는 제가 내린 결정 중 가장 잘했다고 생각하는 결정 중 하나입니다.
실시간 스트리밍 (Real-time streaming)은 사용자가 말하는 동안 텍스트가 나타나는 것을 의미합니다. 심리적인 차이는 엄청납니다. 도구가 데이터를 처리하는 것이 아니라, 사용자의 말을 듣고 있다는 느낌을 줍니다. 스트리밍 전사 (Streaming transcription)를 사용하는 사용자는 대화를 계속 이어갈 가능성이 현저히 높으며, 이는 결과적으로 더 길고 유용한 녹음 결과물로 이어집니다.
아키텍처 (Architecture):
Mobile/Web Client
↓ (WebSocket, 100ms audio chunks, Opus codec)
API Gateway (load balanced)
...
여기서의 주요 결정 사항:
- 16kHz에서의 Opus 코덱 (Opus codec): 음성 데이터에 대해 MP3보다 더 나은 압축률을 제공하고, WAV보다 대역폭 (Bandwidth) 소모가 적으며, Whisper가 이 코덱에서 잘 작동합니다. Whisper가 실제로 필요로 하는 것은 PCM 16kHz이므로, 워커 (Worker) 측에서 변환을 수행합니다.
- 100ms 청크 (Chunk) 윈도우: 청크가 작을수록 체감 지연 시간 (Latency)이 낮아지고, 청크가 클수록 단어 경계 검출 (Word boundary detection)을 위한 문맥 (Context) 확보에 유리합니다. 50ms, 100ms, 200ms, 500ms 윈도우를 테스트한 결과, 100ms가 적절한 균형점을 찾았습니다.
- HTTP 롱 폴링 (Long-polling) 대신 WebSocket 사용: 당사의 테스트 조건에서 지연 시간이 40% 더 낮았습니다. 연결 관리 오버헤드 (Connection management overhead)가 실제로 존재하지만 관리 가능한 수준입니다.
모델 선택: Whisper, Cloud ASR, 또는 그 외
우리는 네 가지 옵션을 평가했습니다:
- 자체 호스팅 Whisper large-v3 — 최고의 정확도, 가장 높은 인프라 비용, 완전한 제어권
- OpenAI Whisper API — 낮은 운영 오버헤드 (Ops overhead), 분당 과금 방식, 양호한 정확도
- Google Cloud Speech-to-Text v2 — 강력한 실시간 스트리밍 지원, 양호하지만 독보적이지는 않은 정확도
- Deepgram Nova-2 — 실시간 전용으로 구축됨, 뛰어난 스트리밍 지연 시간
우리는 결국 하이브리드 (Hybrid) 방식을 선택했습니다. 실시간 스트리밍(지연 시간이 가장 중요한 경우)에는 Deepgram Nova-2를 사용하고, 업로드된 파일의 사후 처리(정확도가 가장 중요하고 지연 시간이 허용되는 경우)에는 자체 호스팅하는 Whisper large-v3를 사용합니다.
이러한 모델들 사이의 정확도 차이는 깨끗한 환경(모든 모델이 선명한 스튜디오 오디오에서 95% 이상 달성)에서는 중요도가 낮지만, 소음이 있는 환경에서는 엄청나게 커집니다. 카페 식당 녹음본에 대해 Whisper large-v3는 여전히 약 91%를 기록하지만, 동일한 녹음본을 중간 단계의 상용 ASR (Automatic Speech Recognition, 자동 음성 인식)로 돌리면 78-83%로 떨어집니다.
통근 중이거나, 걷거나, 회의 사이에 음성 메모를 녹음하는 우리의 타겟 사용자들에게 소음 강건성(Noise robustness)은 타협할 수 없는 요소였습니다. 이로 인해 인프라 오버헤드(Infrastructure overhead)가 발생하더라도 품질 측면에서 Whisper를 선택하게 되었습니다.
지연 시간 최적화 (Latency Optimization)
우리의 초기 스트리밍 구현 방식은 '첫 단어 지연 시간(First word latency)'이 약 1.8초였습니다. 이는 사용자가 말을 시작한 시점부터 화면에 첫 번째 전사된 단어가 나타날 때까지의 시간입니다. 사용자들은 이를 불편하게 느꼈습니다. 도구가 따라오지 못한다는 느낌을 받았습니다.
우리는 세 가지 변경 사항을 통해 이를 340ms까지 단축했습니다.
1. 모델 웜 키핑 (Model warm-keeping): 전사 워커(Transcription workers)가 모델을 메모리에 로드한 상태로 유지됩니다. Whisper large-v3를 콜드 스타트(Cold-starting)하는 데는 하드웨어에 따라 3~8초가 소요됩니다. 웜 요청(Warm requests)은 밀리초(ms) 단위로 처리됩니다. 우리는 콜드 스타트 없이 95백분위수 동시성을 처리할 수 있는 규모의 웜 워커 풀(Pool of warm workers)을 유지합니다.
2. 부분 전사 스트리밍 (Partial Transcription Streaming): 문장이 완성될 때까지 기다리는 대신, 활성 발화 중에는 500ms마다 부분적인 결과(Partial results)를 내보냅니다. 이 결과들은 문맥이 개선됨에 따라 교체됩니다. 사용자들은 텍스트가 실시간으로 "굳어지는(solidifying)" 것을 보게 됩니다. 즉, 더 많은 오디오 문맥이 들어옴에 따라 초기 거친 전사가 수정되는 과정을 보게 됩니다.
3. 엣지 전처리 (Edge pre-processing): 스트리밍 전 클라이언트에서 가벼운 VAD (Voice Activity Detection, 음성 활동 감지) 모델을 실행합니다. 무음 구간은 전송되지 않습니다. 이를 통해 서버가 처리하는 오디오 양을 줄이고, 긴 휴지기(Pause)로 인해 불완전한 문장 세그먼트가 생성되어 발생하는 혼란을 제거합니다.
예상치 못했던 확장성 문제 (The Scaling Challenges We Didn't Expect)
동시성 급증 (Concurrency Spikes)
문제는 우리의 오토스케일링(Auto-scaling)이 너무 느렸다는 점입니다. 우리는 구동(Spin-up)에 3~5분이 소요되는 클라우드 VM 오토스케일링을 사용하고 있었습니다. 이는 점진적인 트래픽 증가에는 괜찮지만, 급격한 트래픽 스파이크(Spike traffic)에는 무용지물입니다.
해결책은 두 가지 측면에서 접근했습니다:
- 과거 트래픽 패턴(시간대, 요일)에 기반한 워커 용량 사전 예열 (Pre-warming worker capacity): 예측된 피크 시간대에는 약 30% 정도 용량을 초과 할당(Overprovision)합니다.
- 클라우드 함수 폴백 (Cloud function fallback): 워커 풀(Worker pool) 용량을 초과하는 오버플로가 발생할 경우, 성능은 다소 저하되더라도 기능은 작동하는 클라우드 기반 ASR (Deepgram API)로 라우팅합니다. 정확도는 낮아지지만, 대기열(Queue) 타임아웃이 발생하는 것보다는 낫습니다.
이제 오토스케일링 (Auto-scaling)은 단순히 CPU 사용률(CPU utilization)이 아닌 대기열 깊이(Queue depth)에 반응합니다. 임계값을 초과하는 대기열 깊이는 CPU가 포화 상태가 될 때까지 기다리지 않고 즉각적인 스케일 아웃 (Scale-out)을 트리거합니다.
다국어 모델 로딩 (Multi-Language Model Loading)
50개 이상의 언어를 지원하기 위해서는 다국어 전사를 처리할 수 있는 Whisper large-v3가 필요했습니다. 과제는 언어 감지 (Language detection)를 위해 오디오의 처음 30초를 처리해야 한다는 점이었습니다.
30초 미만의 짧은 녹음의 경우, 초기에는 약 12%의 확률로 언어를 잘못 추측했습니다. 일본어로 녹음된 음성 메모가 충분한 오디오 데이터가 없어 확신을 주지 못하면 영어로 처리를 시작하는 식이었습니다.
우리의 해결책은 가벼운 언어 식별 모델 (fastText language identification)을 사용하여 처음 3초 동안 언어를 감지한 다음, 감지된 언어를 강제 파라미터 (Forced parameter)로 사용하여 Whisper 처리를 수행하는 것이었습니다. 이를 통해 언어 오감지율을 2% 미만으로 낮추었으며
Whisper가 오디오를 처리하기 전에 DeepFilterNet 노이즈 억제 (noise suppression) 모델을 사용하는 선택적 전처리 (pre-processing) 단계를 추가했습니다. 심하게 손상된 오디오의 경우, 이는 단어 오류율 (WER)을 일관되게 4~8%포인트 개선했습니다. 깨끗한 오디오에서는 사실상 아무런 영향이 없었습니다.
트레이드오프 (Tradeoff): DeepFilterNet은 약 150ms의 처리 지연 시간 (latency)을 추가합니다. 우리는 입력 오디오가 빠른 신호 대 잡음비 (SNR) 체크를 통과하지 못할 때만 적응형 (adaptively)으로 이를 활성화합니다.
6개월 후 우리가 출시한 것
MVP 출시 6개월 후:
- 첫 단어 지연 시간 340ms의 실시간 스트리밍 전사 (real-time streaming transcription)
- 자동 언어 감지 기능을 포함한 50개 이상의 언어 지원
- 화자 분리 (Speaker diarization) (2~6명의 화자, 당사 테스트 결과 정확도 >88%)
- 후처리 파이프라인 (Post-processing pipeline): 정제 → 요약 → 실행 항목 추출 → 구조화된 노트
- 통합 서비스: Notion, Google Docs, Obsidian, Slack, Zapier
- 데이터 거주성 (data residency) 요구 사항이 있는 기업 고객을 위한 온디바이스 (on-device) 처리 옵션
제가 가장 자랑스럽게 생각하는 부분은 후처리 파이프라인입니다. 인프라 비용을 지불할 의사가 있다면 전사를 정확하게 만드는 것은 이미 해결된 문제입니다. 하지만 지능 계층 (intelligence layer)을 제대로 만드는 것 — 즉, 실제로 유용한 요약, 쓰레기가 아닌 실행 항목, 지식 노동자들이 생각하는 방식에 맞는 구조를 만드는 것 — 이 부분이 바로 어려운 문제입니다.
우리는 결국 자체적인 구조화된 출력 (structured outputs)을 바탕으로 더 작은 Claude 모델을 미세 조정 (fine-tuning)했으며, 이는 제로샷 프롬프팅 (zero-shot prompting)과 비교했을 때 AI 생성 노트의 품질을 크게 향상시켰습니다. 학습 데이터는 수백 개의 실제 음성 메모 전사본에 대해 당사 팀이 직접 수행한 주석 (annotations)이었습니다.
교훈 및 남겨진 질문들
효과적이었던 것:
- 첫날부터 스트리밍 (streaming)에 투자하는 것. 나중에 추가하는 것은 처음부터 구축하는 것보다 훨씬 어렵습니다.
- 선택적 전처리 단계로서의 노이즈 억제 (Noise suppression). 강제하지 마세요. 적응형 적용 (adaptive application)이 더 낫습니다.
- CPU가 아닌 큐 깊이 (Queue depth)를 오토스케일링 (auto-scaling) 신호로 사용하는 것. 큐 깊이는 CPU보다 사용자 경험에 더 가깝습니다.
- 하이브리드 모델 전략: 지연 시간에 민감한 경로 (latency-critical paths)에는 목적에 맞게 제작된 ASR을, 품질에 민감한 경로 (quality-critical paths)에는 더 높은 정확도의 모델을 사용합니다.
어려웠던 점:
- 실제 운영 환경의 오디오 다양성을 과소평가했습니다. 스튜디오 마이크뿐만 아니라 휴대폰, AirPods, 저가형 헤드셋, 차량용 거치대, 스마트워치에서 녹음된 파일로 테스트하세요.
- 오토스케일링 설정을 올바르게 잡는 데 4번의 스프린트 (sprints)가 소요되었습니다. 이는 초기에 투자할 가치가 있습니다.
- 화자 분리 (Speaker diarization) 정확도는 화자가 4명을 넘어가면 급격히 떨어집니다. UX에서 올바른 기대치를 설정하지 않으면 고객 지원 티켓 (support tickets)을 받게 될 것입니다.
여전히 해결 중인 질문들:
- 실시간 교차 언어 코드 스위칭 (cross-lingual code-switching)을 어떻게 처리할 것인가 (예: 문장 중간에 언어가 바뀌는 스페인어-영어 대화)
- 불확실한 전사 내용을 하위 단계에서 강조 표시하기 위한 단어 수준의 신뢰도 점수 (Confidence scores)
- 모바일 클라이언트의 지연 시간 페널티 없이 실시간 노이즈 억제를 구현하는 방법
다음 단계
우리가 구축한 플랫폼은 음성을 입력값 (input)으로 취급합니다. 우리의 다음 개척지는 음성을 인터페이스 (interface)로 사용하는 것입니다. 즉, 자신의 녹음 파일에 질의하고, 지난 회의에서 말한 내용에 대해 질문하며, 음성 명령을 통해 관련 메모를 불러올 수 있는 단계입니다.
이를 위해서는 전사(transcription) 및 구조화 시스템에서 시맨틱 검색 (semantic search), 장기 문맥 (long-term context), 개인화 (personalization)를 갖춘 실제 메모리 시스템 (memory system)으로 진화해야 합니다. 우리가 구축한 전사 및 AI 레이어는 그 토대입니다. 다음 레이어는 훨씬 더 흥미로울 것입니다.
만약 여러분이 오디오 파이프라인 (audio pipelines), 음성 AI (speech AI), 또는 보이스 퍼스트 (voice-first) 제품과 관련된 문제를 다루고 있다면, 기꺼이 의견을 나누고 싶습니다. 이 분야의 엔지니어링 커뮤니티는 놀라울 정도로 규모가 작고, 놀라울 정도로 협력적입니다.
기술 스택: Python 워커 (FastAPI), Redis pub/sub를 통한 WebSocket, A10G GPU 기반의 Whisper large-v3, 스트리밍을 위한 Deepgram Nova-2, 노이즈 억제 (Noise suppression)를 위한 DeepFilterNet, 전사 데이터 (Transcript) 저장 및 검색을 위한 PostgreSQL + pgvector.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기