Whisper 및 Deepgram을 사용한 음성-텍스트 변환
실시간 및 일괄 전사, 언어 감지, 구두점 처리를 다룹니다.
Whisper 및 Deepgram을 사용한 음성-텍스트 변환은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
음성 에이전트의 음성 텍스트 변환
음성 에이전트는 LLM이 처리하기 전에 음성 오디오를 텍스트로 변환해야 합니다. 이 단계를 음성 텍스트 변환(STT) 또는 자동 음성 인식(ASR)이라고 합니다.
대표적인 두 가지 옵션은 OpenAI 위스퍼(파일 기반 일괄 처리)와 딥그램(스트리밍, 실시간 처리, 화자 분리 및 단어 타임스탬프 지원)입니다.
OpenAI 위스퍼: 기본 전사
OpenAI API를 통한 위스퍼는 오디오 파일을 전사합니다. 지원 형식은 mp3, mp4, wav, webm, m4a, flac입니다. 최대 파일 크기는 25MB입니다.
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def transcribe_file(audio_path, language=None):
with open(audio_path, 'rb') as audio_file:
params = {
'model': 'whisper-1',
'file': audio_file,
'response_format': 'json' # or 'text', 'srt', 'vtt', 'verbose_json'
}
if language:
params['language'] = language # e.g., 'en', 'fr', 'de'
transcript = client.audio.transcriptions.create(**params)
return transcript.text
# Basic usage
text = transcribe_file('meeting_recording.mp3')
print('Transcribed:', text[:200])단어 타임스탬프를 포함한 위스퍼
response_format='verbose_json'을 사용하면 각 단어와 구간의 타임스탬프를 가져올 수 있습니다. 이는 녹음에서 특정 순간을 찾거나, 노래방처럼 구간을 강조 표시하거나, 전사 결과를 오디오 재생과 맞추는 데 유용합니다.
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def transcribe_with_timestamps(audio_path):
with open(audio_path, 'rb') as f:
result = client.audio.transcriptions.create(
model='whisper-1',
file=f,
response_format='verbose_json',
timestamp_granularities=['word', 'segment'] # get both word and segment times
)
segments = []
for seg in result.segments:
segments.append({
'start': seg.start,
'end': seg.end,
'text': seg.text
})
words = []
if hasattr(result, 'words'):
for word in result.words:
words.append({'word': word.word, 'start': word.start, 'end': word.end})
return {'text': result.text, 'segments': segments, 'words': words}딥그램 SDK: 비동기 스트리밍
딥그램은 실시간 스트리밍 전사에 최적화되어 있습니다. 오디오를 녹음하는 동안 청크 단위로 전송하며, 화자가 문장을 끝내기 전에 부분 전사 결과를 반환합니다.
pip install deepgram-sdk로 설치합니다.
import asyncio
import os
from deepgram import DeepgramClient, PrerecordedOptions
client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))
async def transcribe_with_deepgram(audio_path):
with open(audio_path, 'rb') as f:
audio_data = f.read()
options = PrerecordedOptions(
model='nova-2', # Deepgram's best accuracy model
language='en',
smart_format=True, # auto-add punctuation and formatting
utterances=True, # segment by speaker turns
punctuate=True,
diarize=True # speaker identification
)
response = await client.listen.asyncrest.v('1').transcribe_file(
{'buffer': audio_data},
options
)
return response.results.channels[0].alternatives[0].transcript화자 분리
화자 분리는 언제 누가 말하는지 식별하여 각 구간에 화자 0, 화자 1 등의 레이블을 지정합니다. 회의 전사와 다자간 대화에 필수적입니다.
async def transcribe_with_diarization(audio_path):
from deepgram import DeepgramClient, PrerecordedOptions
import os
dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))
options = PrerecordedOptions(
model='nova-2',
diarize=True,
utterances=True,
smart_format=True
)
with open(audio_path, 'rb') as f:
audio_data = f.read()
response = await dg_client.listen.asyncrest.v('1').transcribe_file(
{'buffer': audio_data}, options
)
utterances = []
for utt in response.results.utterances:
utterances.append({
'speaker': f'Speaker {utt.speaker}',
'start': round(utt.start, 2),
'end': round(utt.end, 2),
'text': utt.transcript
})
return utterances
# Output:
# [{'speaker': 'Speaker 0', 'start': 0.0, 'end': 3.2, 'text': 'Hello everyone.'},
# {'speaker': 'Speaker 1', 'start': 3.5, 'end': 6.1, 'text': 'Good morning!'}]언어 감지
사용자의 언어를 알 수 없는 경우 위스퍼와 딥그램 모두 음성 언어를 자동으로 감지할 수 있습니다. 위스퍼는 오디오의 처음 30초를 바탕으로 언어를 감지합니다.
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def detect_language(audio_path):
with open(audio_path, 'rb') as f:
# Use translations endpoint to get verbose JSON with language detection
result = client.audio.transcriptions.create(
model='whisper-1',
file=f,
response_format='verbose_json'
)
return {
'detected_language': result.language,
'text': result.text
}
result = detect_language('user_audio.wav')
print(f"Language: {result['detected_language']}")
print(f"Text: {result['text'][:100]}")
# Deepgram: set language='auto' in options
from deepgram import PrerecordedOptions
options = PrerecordedOptions(model='nova-2', language='auto', detect_language=True)긴 오디오 파일 청크 분할
위스퍼의 25MB 제한 때문에 긴 녹음(예: 1시간 회의)은 청크로 나누어야 합니다. pydub를 사용해 무음 구간을 기준으로 오디오를 분할한 다음, 각 청크를 전사하고 결과를 이어 붙입니다.
pip install pydub로 설치합니다. ffmpeg가 필요합니다.
from pydub import AudioSegment
from pydub.silence import split_on_silence
import io
def transcribe_long_audio(audio_path, chunk_length_ms=60000):
audio = AudioSegment.from_file(audio_path)
# Split on silence
chunks = split_on_silence(
audio,
min_silence_len=1000, # 1 second of silence
silence_thresh=-40, # dBFS
keep_silence=500 # keep 500ms at each end
)
# If no silence splitting worked, use fixed-length chunks
if len(chunks) <= 1:
chunks = [
audio[i:i + chunk_length_ms]
for i in range(0, len(audio), chunk_length_ms)
]
full_transcript = []
for i, chunk in enumerate(chunks):
print(f'Transcribing chunk {i+1}/{len(chunks)}')
buf = io.BytesIO()
chunk.export(buf, format='mp3')
buf.seek(0)
buf.name = f'chunk_{i}.mp3'
result = client.audio.transcriptions.create(model='whisper-1', file=buf)
full_transcript.append(result.text)
return ' '.join(full_transcript)딥그램 실시간 스트리밍
실시간 음성 대화에는 딥그램의 WebSocket 실시간 스트리밍 API를 사용합니다. 오디오 청크는 녹음되는 즉시 전송되며, 중간 전사 결과와 최종 전사 결과가 수 밀리초 안에 도착합니다.
import asyncio
import os
from deepgram import DeepgramClient, LiveTranscriptionEvents, LiveOptions
async def live_transcribe(on_transcript_callback):
dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))
connection = dg_client.listen.asynclive.v('1')
async def on_message(self, result, **kwargs):
sentence = result.channel.alternatives[0].transcript
is_final = result.is_final
if sentence:
await on_transcript_callback(sentence, is_final)
connection.on(LiveTranscriptionEvents.Transcript, on_message)
options = LiveOptions(
model='nova-2',
language='en',
smart_format=True,
interim_results=True, # get partial results before sentence ends
endpointing=500 # ms of silence before finalizing
)
await connection.start(options)
return connection # caller sends audio chunks via connection.send(audio_chunk)오류 처리 및 재시도
오디오 전사 API는 네트워크 문제, 지원되지 않는 형식 또는 요청 한도 초과로 인해 실패할 수 있습니다. 지수 백오프를 적용한 재시도를 구현하고, 전송하기 전에 오디오를 검증합니다.
import time
import os
MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024 # 25MB
SUPPORTED_FORMATS = ('.mp3', '.mp4', '.wav', '.webm', '.m4a', '.flac', '.ogg')
def validate_audio_file(audio_path):
if not os.path.exists(audio_path):
raise FileNotFoundError(f'Audio file not found: {audio_path}')
size = os.path.getsize(audio_path)
if size > MAX_FILE_SIZE_BYTES:
raise ValueError(f'File too large: {size / 1024 / 1024:.1f}MB (max 25MB)')
ext = os.path.splitext(audio_path)[1].lower()
if ext not in SUPPORTED_FORMATS:
raise ValueError(f'Unsupported format: {ext}. Supported: {SUPPORTED_FORMATS}')
def transcribe_with_retry(audio_path, max_retries=3):
validate_audio_file(audio_path)
for attempt in range(max_retries):
try:
return transcribe_file(audio_path)
except Exception as e:
if attempt < max_retries - 1:
wait = 2 ** attempt
print(f'Retry {attempt + 1} after error: {e}. Waiting {wait}s')
time.sleep(wait)
else:
raise위스퍼와 딥그램 중 선택하기
두 도구는 서로 다른 상황에서 뛰어난 성능을 발휘합니다. 이 의사 결정표를 사용하여 음성 에이전트에 적합한 도구를 선택하세요.
COMPARISON = '''
Whisper (OpenAI API):
- Best for: batch transcription, podcast processing, meeting notes
- Latency: file upload latency + ~1-5 seconds processing
- Strengths: excellent multilingual, high accuracy, cheap
- Word timestamps: yes (verbose_json)
- Diarization: NO (must use separate tool)
- Use when: accuracy > speed, offline processing
DeeGram:
- Best for: real-time voice agents, call center transcription
- Latency: <300ms for streaming, ~1s for file upload
- Strengths: streaming, diarization, custom vocabulary
- Word timestamps: yes, with confidence scores
- Diarization: YES (built-in, up to 10 speakers)
- Use when: speed > accuracy, real-time required
Rule of thumb:
Agent voice conversation -> Deepgram live streaming
Batch audio files -> Whisper API
Meeting transcripts with speakers -> Deepgram with diarize=True
'''
print(COMPARISON)오디오 형식 변환
위스퍼와 딥그램은 일반적인 오디오 형식을 지원하지만, 사용자의 오디오는 흔하지 않은 형식으로 들어올 수 있습니다(ogg, opus, 브라우저에서 생성된 webm, iOS에서 생성된 m4a). API로 전송하기 전에 표준 WAV 또는 MP3로 변환합니다.
from pydub import AudioSegment
import os
SUPPORTED_FORMATS = {'.mp3', '.wav', '.flac', '.m4a', '.ogg', '.webm', '.opus'}
def convert_to_wav(input_path, output_path=None):
ext = os.path.splitext(input_path)[1].lower()
if ext not in SUPPORTED_FORMATS:
raise ValueError(f'Unsupported audio format: {ext}')
if output_path is None:
output_path = input_path.rsplit('.', 1)[0] + '.wav'
# pydub handles format detection automatically
audio = AudioSegment.from_file(input_path)
# Normalize to 16kHz mono (optimal for Whisper)
audio = audio.set_frame_rate(16000).set_channels(1)
audio.export(output_path, format='wav')
print(f'Converted {input_path} -> {output_path} ({len(audio) / 1000:.1f}s)')
return output_path
def ensure_compatible_audio(audio_path):
ext = os.path.splitext(audio_path)[1].lower()
if ext in {'.mp3', '.wav', '.m4a', '.flac'}:
return audio_path # already compatible
return convert_to_wav(audio_path)지식 확인
음성 텍스트 전사에서 화자 분리란 무엇인가요?
복습: 위스퍼와 딥그램을 사용한 음성 텍스트 변환
위스퍼(OpenAI API)는 일괄 전사에 적합합니다. 높은 정확도와 다국어를 지원하며, verbose_json을 사용하면 단어 타임스탬프도 제공합니다. 지연 시간이 중요하지 않은 파일 기반 처리에 사용하세요.
딥그램은 실시간 스트리밍을 위해 설계되었습니다. 중간 결과를 제공하는 실시간 WebSocket 전사, 내장 화자 분리, 300밀리초 미만의 지연 시간을 지원합니다. 대화형 음성 에이전트에 사용하세요. 두 도구 모두 언어 감지를 지원하며, 운영 환경에서는 재시도 로직과 파일 검증이 필요합니다.
자주 묻는 질문
“Whisper 및 Deepgram을 사용한 음성-텍스트 변환” 강의는 무료인가요?
네 — “Whisper 및 Deepgram을 사용한 음성-텍스트 변환” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
“Whisper 및 Deepgram을 사용한 음성-텍스트 변환”에서 뭘 배우나요?
실시간 및 일괄 전사, 언어 감지, 구두점 처리를 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Agents을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“Whisper 및 Deepgram을 사용한 음성-텍스트 변환” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- Whisper 및 Deepgram을 사용한 음성-텍스트 변환
- 에이전트 응답의 텍스트-음성 변환
- 음성 대화 반복 과정 만들기
- 음성 에이전트 지연 시간 최적화