LLM멀티모달 AI강의 5개 중 4번째난이도 중급

오디오 처리 — Whisper 음성 인식과 TTS

발행 읽는 시간 약 1 분

  • LLM
  • Whisper
  • TTS
  • 음성인식
  • 음성합성
  • 오디오

강의 소개

Whisper API로 음성을 텍스트로 변환하고, TTS API로 텍스트를 자연스러운 음성으로 합성하는 방법을 배웁니다. 실시간 오디오 처리 패턴도 익힙니다.

Whisper: 음성 → 텍스트#

Python
from openai import OpenAI
from pathlib import Path

client = OpenAI()

# 기본 음성 인식
def transcribe(audio_path: str, language: str = "ko") -> str:
    with open(audio_path, "rb") as f:
        transcript = client.audio.transcriptions.create(
            model="whisper-1",
            file=f,
            language=language,  # 없으면 자동 감지
        )
    return transcript.text

# 타임스탬프 포함
def transcribe_with_timestamps(audio_path: str) -> dict:
    with open(audio_path, "rb") as f:
        transcript = client.audio.transcriptions.create(
            model="whisper-1",
            file=f,
            response_format="verbose_json",
            timestamp_granularities=["word", "segment"],
        )

    return {
        "text": transcript.text,
        "segments": [
            {
                "text": s.text,
                "start": s.start,
                "end": s.end,
            }
            for s in transcript.segments
        ],
    }

지원 형식과 제한#

Python
# 지원 형식: mp3, mp4, mpeg, mpga, m4a, wav, webm
# 최대 파일 크기: 25MB
# 긴 파일은 분할 필요

from pydub import AudioSegment

def split_audio(audio_path: str, chunk_ms: int = 10 * 60 * 1000) -> list[str]:
    """10분씩 분할"""
    audio = AudioSegment.from_file(audio_path)
    chunks = []

    for i, start in enumerate(range(0, len(audio), chunk_ms)):
        chunk = audio[start:start + chunk_ms]
        chunk_path = f"/tmp/chunk_{i}.mp3"
        chunk.export(chunk_path, format="mp3")
        chunks.append(chunk_path)

    return chunks

def transcribe_long_audio(audio_path: str) -> str:
    chunks = split_audio(audio_path)
    texts = []
    for chunk in chunks:
        texts.append(transcribe(chunk))
    return " ".join(texts)

Whisper 실전 패턴: 회의록 생성#

Python
def generate_meeting_minutes(audio_path: str) -> str:
    # 1. 음성 인식
    transcript = transcribe_with_timestamps(audio_path)

    # 2. GPT로 회의록 정리
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": "회의 내용을 구조화된 회의록으로 정리해주세요."
            },
            {
                "role": "user",
                "content": f"""다음 회의 내용을 회의록으로 정리해주세요:
- 참석자 (추정 가능하면)
- 주요 논의사항
- 결정사항
- Action Items (담당자, 기한 포함)

회의 내용:
{transcript['text']}"""
            }
        ],
    )
    return response.choices[0].message.content

TTS: 텍스트 → 음성#

Python
# 기본 TTS
def text_to_speech(text: str, output_path: str, voice: str = "alloy") -> None:
    """
    voices: alloy, echo, fable, onyx, nova, shimmer
    """
    response = client.audio.speech.create(
        model="tts-1",       # tts-1 (빠름) or tts-1-hd (고품질)
        voice=voice,
        input=text,
        response_format="mp3",  # mp3, opus, aac, flac, wav, pcm
        speed=1.0,              # 0.25 ~ 4.0
    )
    response.stream_to_file(output_path)

# 스트리밍 TTS (실시간 재생)
def stream_speech(text: str) -> bytes:
    with client.audio.speech.with_streaming_response.create(
        model="tts-1",
        voice="nova",
        input=text,
    ) as response:
        return b"".join(response.iter_bytes())

음성 챗봇 파이프라인#

Python
import sounddevice as sd
import soundfile as sf
import numpy as np

def voice_chatbot():
    """음성 입력 → LLM → 음성 출력"""
    conversation = []

    while True:
        # 1. 음성 녹음
        print("말씀하세요... (Enter 눌러 중지)")
        recording = []
        with sd.InputStream(samplerate=16000, channels=1) as stream:
            input()
            recording, _ = stream.read(stream.read_frames())

        audio_path = "/tmp/input.wav"
        sf.write(audio_path, np.array(recording), 16000)

        # 2. 음성 인식
        user_text = transcribe(audio_path)
        print(f"사용자: {user_text}")

        # 3. LLM 응답
        conversation.append({"role": "user", "content": user_text})
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=conversation,
        )
        assistant_text = response.choices[0].message.content
        conversation.append({"role": "assistant", "content": assistant_text})
        print(f"AI: {assistant_text}")

        # 4. TTS로 응답
        text_to_speech(assistant_text, "/tmp/response.mp3", voice="nova")
        # 재생 (macOS: afplay, Linux: aplay, Windows: playsound)
        import os
        os.system("afplay /tmp/response.mp3")

정리#

기능API모델
음성 인식audio.transcriptions.createwhisper-1
음성 번역 (→영어)audio.translations.createwhisper-1
텍스트 → 음성audio.speech.createtts-1, tts-1-hd

다음 편에서는 멀티모달 실전 프로젝트 — 이미지 분석 + 음성 처리를 결합한 접근성 앱을 만듭니다.

Follow · Ask · Work

이 글이 도움이 됐다면

짧은 작업 기록과 데모는 인스타그램에 올립니다. 만들고 싶은 것이 있다면 프로젝트 의뢰나 협업 제안도 편하게 보내 주세요.

글쓴이

파란여우

직접 만든 AI 앱·제품의 개발·배포를 공개하는 실전형 테크 크리에이터

파란여우 소개 Instagram @bluefox._.hi

이어서 보기

만들고 싶은 것이 있다면 프로젝트 의뢰로 알려 주세요.