REPO DEEP DIVE · 2026-07-29 · HUGGINGFACE/SPEECH-TO-SPEECH · 오픈소스 음성 에이전트 파이프라인

huggingface/speech-to-speech 딥다이브
전부 갈아끼울 수 있는 오픈소스 음성 대화 엔진

speech-to-speech는 허깅페이스가 만든 저지연(low-latency) 음성 대화 파이프라인이다. 핵심 아이디어는 하나의 통짜 음성 모델을 쓰는 대신, 네 개의 부품을 사슬처럼 연결하는 것이다 — VAD(말이 시작·끝났는지 감지) → STT(음성을 글자로) → LLM(답을 생성) → TTS(글자를 음성으로). 이 네 부품이 각각 독립된 스레드에서 돌고, 큐(queue)로 이어져 흐른다.

가장 큰 매력은 모든 부품이 교체 가능(swappable)하다는 점이다. STT는 Parakeet·Whisper·Paraformer 중 고르고, TTS는 Qwen3-TTS·Kokoro·Pocket TTS 중 고르며, LLM은 로컬(transformers·mlx-lm)이든 클라우드(OpenAI·vLLM·llama.cpp)든 OpenAI 호환 API면 뭐든 꽂을 수 있다. 게다가 서버는 OpenAI Realtime 프로토콜과 호환되는 WebSocket API를 노출하므로, 기존 OpenAI 클라이언트의 접속 주소만 바꾸면 그대로 셀프호스팅으로 갈아탈 수 있다.

장난감 데모가 아니다. 이 파이프라인은 실제로 수천 대의 Reachy Mini 로봇의 대화 백엔드로 프로덕션에서 돌아가고 있다.

(저장소 huggingface/speech-to-speech · 라이선스 Apache-2.0 · 언어 Python 3.10+ · 버전 0.2.11 · 소스 파일 91개 · TrendShift Daily 트렌딩 진입 · pip install speech-to-speech로 바로 설치)
목차
  1. 한 줄 요약 — 이게 대체 뭐냐
  2. 왜 지금 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 — 큐로 이어진 4단 사슬
  5. 디렉토리 구조 해부
  6. 학습 포인트 — 여기서 뭘 배우나
  7. 하드웨어·시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 로드맵 (주차별)
  10. 핵심 키워드 사전
  11. 참고 링크

1한 줄 요약 — 이게 대체 뭐냐

"음성을 넣으면 음성이 나온다"를 부품 조립식으로 구현한 것

사람과 AI가 말로 대화하려면 최소 네 가지 일이 순서대로 일어나야 한다. (1) 상대가 지금 말하고 있는지를 알아채고, (2) 그 말을 글자로 받아적고, (3) 그 글자에 대한 답을 생각해내고, (4) 그 답을 다시 소리로 바꿔 들려줘야 한다. speech-to-speech는 이 네 단계를 각각 하나의 핸들러(handler)로 만들고, 이들을 큐로 연결해 하나의 흐름으로 묶은 프로그램이다.

한 문장 비유

주방의 4단 조립 라인 같은 구조다.

손님(사용자)이 주문을 말하면 → 웨이터(VAD)가 "주문이 끝났다"를 알아채고 → 주방 보조(STT)가 주문서를 종이에 받아적고 → 요리사(LLM)가 요리를 만들고 → 서빙(TTS)이 접시에 담아 내온다.

핵심은 요리사가 마음에 안 들면 다른 요리사로 바꿔도 라인 전체는 그대로 돈다는 것. 이게 이 프로젝트가 말하는 "모듈러(modular)"의 의미다.

용어
S2S (Speech-to-Speech)
"음성 입력 → 음성 출력"을 통칭하는 말. 방식은 두 가지다. ① 캐스케이드(cascade): 이 프로젝트처럼 STT·LLM·TTS를 이어붙이는 방식(부품 교체가 자유롭다). ② 엔드투엔드(end-to-end): 음성을 직접 먹고 음성을 직접 뱉는 통짜 모델(GPT-4o 음성 등). 이 레포는 명시적으로 캐스케이드를 택했다 — 대신 유연성과 로컬 실행 자유를 얻는다.

결과물은 pip install speech-to-speech 한 줄로 설치되는 파이썬 패키지 + speech-to-speech CLI 명령어다. 실행하면 ws://localhost:8765/v1/realtime에 OpenAI Realtime 호환 서버가 뜨고, 어떤 OpenAI Realtime 클라이언트든 접속할 수 있다.

2왜 지금 주목받는가

"OpenAI Realtime의 셀프호스팅 오픈소스 버전"이라는 포지션

음성 AI 시장에서 지금 뜨거운 키워드는 Realtime API다. OpenAI가 실시간 음성 대화 표준을 만들었지만, 그건 클라우드 종속 + 종량제 과금 + 데이터 외부 전송이라는 대가를 요구한다. speech-to-speech는 정확히 그 지점을 노린다.

차별점 1
주소만 바꾸면 갈아탄다 (drop-in replacement)

서버가 OpenAI Realtime 프로토콜을 그대로 구현했기 때문에, 기존에 OpenAI로 음성 앱을 짰다면 클라이언트의 base_urllocalhost:8765로 바꾸면 된다. 코드 재작성이 거의 없다. "OpenAI를 쓰다가 비용·프라이버시 때문에 셀프호스팅으로 넘어가고 싶다"는 수요를 정확히 겨냥한다.

차별점 2
완전 로컬 스택이 가능하다

STT(Parakeet)·TTS(Qwen3-TTS)는 로컬에서 돌고, LLM만 llama.cpp/vLLM으로 내 컴퓨터에 띄우면 인터넷 없이 100% 로컬로 음성 대화가 돌아간다. 의료·법률·기업 내부처럼 데이터가 밖으로 나가면 안 되는 곳에서 결정적 장점이다.

차별점 3
프로덕션 검증 (수천 대 로봇)

Reachy Mini 로봇 수천 대의 대화 백엔드로 실제 운영 중이라고 README가 명시한다. GitHub의 흔한 "데모 수준 토이 프로젝트"와 달리, 끊김·중간 끼어들기(interruption)·턴 관리 같은 실전 문제를 이미 다뤄본 코드라는 신뢰 신호다.

차별점 4
허깅페이스 생태계 + 25개 유럽어

Transformers·HF Hub·HF Inference Providers와 자연스럽게 연결된다. 기본 STT인 Parakeet TDT는 25개 유럽 언어를, 기본 TTS인 Qwen3-TTS는 다국어를 지원한다. --language auto로 말할 때마다 언어를 자동 감지해 스위칭할 수도 있다.

냉정하게 보면
캐스케이드의 태생적 한계

부품을 이어붙이는 구조라 지연(latency)이 각 단계 합산으로 쌓인다. VAD가 "말 끝"을 감지하고 → STT가 받아적고 → LLM이 생각하고 → TTS가 소리를 만드는 시간이 순차적으로 더해진다. 그래서 이 레포는 스레드 병렬화, 스트리밍, 화자 끼어들기(speculative turns) 같은 기법으로 그 지연을 깎는 데 상당한 코드를 쏟는다. 통짜 엔드투엔드 음성 모델의 즉답성과는 근본 결이 다르다.

3기술 스택 전체 지도

"파이썬 + 스레드 + 큐"라는 뼈대 위에 갈아끼울 수 있는 모델들

백본(런타임) — 서버와 동시성

레이어기술역할
언어Python 3.10+전체 파이프라인. 타입힌트·mypy·ruff 적용
웹서버FastAPI + uvicorn/v1/realtime WebSocket 엔드포인트 서빙
실시간 통신websockets, WebRTC(옵션)오디오 스트림 양방향 전송
동시성threading + Queue각 부품을 독립 스레드로, 큐로 연결
설정 검증Pydantic v2RuntimeConfig — 세션 설정을 공유 모델로
수치·오디오numpy, scipy, soundfile, sounddevicePCM 처리·리샘플링·마이크/스피커 I/O
ML 프레임워크PyTorch 2.4+, Transformers 4.57+로컬 모델 추론(CUDA/CPU)
Apple 실리콘MLX, mlx-lm, mlx-audio맥에서 GPU(MPS) 가속 경로
LLM 클라이언트openai 2.28OpenAI 호환 API 호출(Responses/Chat)
용어
플랫폼 마커 (platform markers)
pyproject.toml을 보면 torch==2.11.0; platform_system == 'Darwin'처럼 OS별로 다른 의존성이 걸려 있다. 맥(Darwin)에서는 MLX 기반, 리눅스에서는 CUDA 기반 패키지가 자동 선택된다. "한 코드베이스, 여러 하드웨어"를 pip 레벨에서 푸는 방식 — 배울 만한 실전 패턴이다.

교체 가능한 4개 부품 (핵심)

부품기본값대안들
VAD
음성감지
Silero VAD v5(단일) — 임계값·묵음 길이만 튜닝
STT
받아쓰기
Parakeet TDT 0.6BWhisper, Faster-Whisper, Paraformer, Lightning Whisper MLX
LLM
답 생성
gpt-5.4-mini (Responses API)transformers·mlx-lm(로컬), vLLM·llama.cpp(자체서버), 모든 OpenAI 호환 제공자
TTS
음성합성
Qwen3-TTS 1.7BKokoro-82M, Pocket TTS(음성 복제), ChatTTS, MMS TTS
비유로 이해하기

이 표를 레고 블록 카탈로그라고 보면 된다. 4개의 슬롯(VAD·STT·LLM·TTS)이 있고, 각 슬롯에 끼울 블록이 여러 개 준비돼 있다. CLI 플래그(--stt, --tts, --llm_backend)가 곧 "어떤 블록을 끼울지" 고르는 스위치다. 조합만 바꾸면 "완전 로컬 프라이버시 세팅"도, "클라우드 최고성능 세팅"도 같은 코드로 만든다.

4아키텍처 심화 — 큐로 이어진 4단 사슬

스레드 + 큐 + 공유 설정. 이 셋이 전부다

이 프로젝트의 심장은 baseHandler.pyBaseHandler 클래스다. 모든 부품(VAD·STT·LLM·TTS)이 이걸 상속한다. 규칙은 단순하다 — 입력 큐에서 꺼내(queue_in) → process()로 처리 → 출력 큐에 넣는다(queue_out). 각 핸들러는 자기 스레드에서 이 루프를 무한 반복한다. 부품끼리는 서로를 직접 부르지 않고 오직 큐를 통해서만 데이터를 주고받는다.

[클라이언트] ── WebSocket(/v1/realtime) ──┐ │ base64 PCM 오디오 ▼ ┌───────────────┐ │ RealtimeService│ 디코딩·16kHz 리샘플·512샘플 청크 └──────┬────────┘ │ recv_audio_chunks_queue ▼ ┌──────┐ 음성구간 ┌──────┐ 전사문 ┌──────────────────┐ 전사+알림 ┌──────┐ │ VAD │────────▶│ STT │──────▶│TranscriptionNotifier│─────────▶│ LLM │ └──┬───┘ └──────┘ └──────────────────┘ └──┬───┘ │ speech_started/stopped │ 텍스트+툴콜 │ (끼어들기 신호) ▼ │ ┌──────────────┐ │ │LMOutputProcessor│ 깨끗한 문장만 추림 │ └──────┬───────┘ │ │ clean text │ ▼ │ ┌──────┐ │ │ TTS │ PCM 오디오 생성 │ └──┬───┘ ▼ 모든 서버 이벤트(JSON) + 오디오 델타 │ send_audio_chunks_queue ┌─────────────────── WebSocket Router (async _send_loop) ◀────────┘ └──▶ [클라이언트] response.output_audio.delta 등으로 되돌려줌 ※ RuntimeConfig(Pydantic) 는 VAD·LLM·TTS 가 실행 중에 함께 읽는 "공유 설정판" session.update 이벤트가 오면 여기에 deep-merge 되어 즉시 반영됨
용어
VAD (Voice Activity Detection)
"지금 사람이 말하고 있나?"를 오디오 신호만 보고 판단하는 기술. 이게 있어야 "말이 끝났으니 이제 답할 차례"를 알 수 있다. 이 레포는 Silero VAD v5를 쓰고, --thresh(민감도), --min_silence_ms(몇 ms 조용하면 말이 끝난 것으로 볼지) 같은 값으로 턴 감지를 정교하게 튜닝한다.

설계 패턴 1 — 스레드 + 큐 = 파이프라인 병렬화

왜 굳이 스레드로 쪼갤까? 겹쳐서 일하기 위해서다. STT가 방금 문장을 넘기면, STT 스레드는 곧바로 다음 오디오 청크를 받기 시작한다. 동시에 LLM 스레드는 넘겨받은 문장으로 답을 만든다. 만약 한 스레드에서 순차로 돌렸다면 STT가 끝날 때까지 LLM은 놀아야 한다. 큐로 이어진 파이프라인은 공장 컨베이어벨트처럼 각 공정이 쉬지 않고 돌게 만들어 전체 지연을 줄인다.

용어
PIPELINE_END / SESSION_END
큐 기반 시스템의 고질병은 데드락(deadlock) — 한 스레드가 오지 않을 데이터를 영원히 기다리는 것. 이 레포는 PIPELINE_END라는 특수 신호를 큐에 흘려보내 "이제 끝, 다들 정리해"를 전파한다. SESSION_END는 스레드를 죽이지 않고 세션 상태만 리셋하는 부드러운 신호다(다음 대화를 위해 스레드는 살려둠).

설계 패턴 2 — 공유 설정판 RuntimeConfig

대화 도중 사용자가 "목소리를 바꿔줘"나 "다른 지시를 줄게"라고 하면? 클라이언트가 session.update 이벤트를 보내고, 이게 Pydantic으로 검증된 RuntimeConfig에 deep-merge된다. VAD(턴 감지 임계값)·LLM(지시문·툴)·TTS(목소리)는 매 처리 시점에 이 공유 설정을 읽으므로, 파이프라인을 재시작하지 않고도 실시간으로 동작이 바뀐다. 설정을 한 곳(단일 진실원)에 모으고 여러 스레드가 읽게 하는 전형적 패턴이다.

설계 패턴 3 — 끼어들기와 speculative turns

실제 대화의 묘미는 말 자르기다. AI가 답하는 도중 사용자가 끼어들면 AI는 즉시 입을 다물어야 한다. VAD가 speech_started를 감지하면 라우터로 신호가 가고, 진행 중이던 응답이 취소된다(response.cancel). 여기서 어려운 건 "진짜 끼어든 건지, 잠깐 숨 고른 건지" 구분이다.

용어
Speculative turns (추측성 턴) · CancelScope
speculative_turns.pySpeculativeTurnTracker는 "말이 끝난 것 같다"를 확정이 아니라 잠정(speculative)으로 처리한다. 살짝 멈췄다가 이어 말하면(reopen window 안이면) 턴을 다시 열어 하나로 잇는다. CancelScope는 각 처리 항목에 "세대(generation)" 번호를 붙여, 취소된 옛 세대의 결과물(stale output)이 뒤늦게 큐에 흘러들어도 버리도록 한다. 실시간 음성 UX의 자연스러움이 여기서 갈린다.

4가지 실행 모드

모드전송 방식언제 쓰나
realtime
(기본)
WebSocket, OpenAI Realtime 프로토콜표준 음성 API로 앱·기기를 만들 때
local내 PC의 마이크·스피커클라이언트 없이 바로 대화해보고 싶을 때
websocket원시 PCM over WebSocket프로토콜 없는 최소 커스텀 클라이언트
socket원시 PCM over TCP모델은 원격 서버, 마이크·재생만 로컬

5디렉토리 구조 해부

부품별로 폴더가 딱딱 나뉜다 — 읽기 쉬운 코드베이스의 표본
speech-to-speech/ ├── src/speech_to_speech/ │ ├── baseHandler.py ★ 모든 부품의 부모 클래스 (큐 in/out 루프) │ ├── s2s_pipeline.py ★ 진입점 — CLI 파싱 후 파이프라인 조립 │ ├── VAD/ 음성 감지 │ │ ├── vad_handler.py │ │ └── vad_iterator.py Silero VAD 스트림 처리 (임계값·묵음·패딩) │ ├── STT/ 받아쓰기 (백엔드별 핸들러 6종) │ │ ├── base_stt_handler.py │ │ ├── parakeet_tdt_handler.py ← 기본값 │ │ ├── whisper_stt_handler.py │ │ ├── faster_whisper_handler.py │ │ ├── paraformer_handler.py │ │ └── smart_progressive_streaming.py 라이브 부분 전사 │ ├── LLM/ 답 생성 │ │ ├── base_openai_compatible_language_model.py │ │ ├── responses_api_language_model.py ← /v1/responses │ │ ├── chat_completions_language_model.py ← /v1/chat/completions │ │ ├── language_model.py 로컬 transformers/mlx │ │ ├── chat.py 대화 기록(context) 관리 │ │ ├── compaction_prompt.py 긴 대화 압축 │ │ └── tool_call/ 함수 호출(tool use) 지원 │ ├── TTS/ 음성 합성 (백엔드별 핸들러 5종) │ │ ├── qwen3_tts_handler.py ← 기본값 │ │ ├── kokoro_handler.py │ │ ├── pocket_tts_handler.py 음성 복제 │ │ └── ... │ ├── api/openai_realtime/ ★ Realtime 프로토콜 서버 │ │ ├── server.py / service.py / websocket_router.py │ │ ├── runtime_config.py 공유 설정판(Pydantic) │ │ ├── webrtc_session.py WebRTC 전송(옵션) │ │ └── handlers/ │ ├── pipeline/ ★ 파이프라인 뼈대·제어 신호 │ │ ├── control.py / messages.py / events.py │ │ ├── cancel_scope.py 취소·stale 판정 │ │ ├── speculative_turns.py 끼어들기/턴 재개 │ │ └── queue_types.py │ ├── connections/ 소켓·스트림 연결 │ └── arguments_classes/ CLI 인자 정의(부품별 dataclass 20여 개) ├── demo/ 웹 데모(FastAPI + JS 프론트, WebRTC 클라이언트) ├── scripts/ listen_and_play*.py, benchmark_tts.py ├── archive/ 폐기된 구현(MeloTTS 등, CLI 미연결) ├── tests/ pytest ├── pyproject.toml 의존성·플랫폼 마커·extras ├── Dockerfile / docker-compose.yml llama.cpp+파이프라인 컨테이너 └── AGENTS.md 에이전트/기여 가이드
읽는 법

폴더 이름만 봐도 구조가 읽힌다 — VAD/ STT/ LLM/ TTS/는 곧 4단 사슬 그 자체다. 새 STT 모델을 추가하고 싶으면 STT/ 폴더에 base_stt_handler.py를 상속한 파일 하나를 더하고 arguments_classes/에 인자 dataclass를 추가하면 끝. "어디를 고쳐야 하는지"가 폴더 구조에 그대로 드러나는 게 잘 설계된 코드베이스의 특징이다.

6학습 포인트 — 여기서 뭘 배우나

음성 AI 지식 + 파이썬 동시성 실전 패턴, 두 마리 토끼

① 파이썬 동시성: 스레드 + 큐 파이프라인

asyncio만 배운 사람에게 이 레포는 스레드 + 큐라는 다른 동시성 모델의 교과서다. 각 스레드가 블로킹 I/O(모델 추론)를 맡고, 큐가 스레드 간 안전한 데이터 전달과 백프레셔(backpressure)를 담당한다. 데드락을 피하는 종료 신호(PIPELINE_END) 설계까지 실전 그대로다.

② 프로토콜 어댑터 패턴: OpenAI 호환성

이 레포의 상업적 가치의 핵심은 "OpenAI Realtime을 그대로 흉내낸다"는 것. 남의 API 스펙(이벤트 종류·JSON 형태)을 읽고 자기 시스템에 매핑하는 어댑터(adapter) 패턴을 실물로 배울 수 있다. websocket_router.py가 내부 메시지를 response.output_audio.delta 같은 프로토콜 이벤트로 번역하는 부분이 백미다.

③ 음성 파이프라인의 실전 문제들

④ 크로스플랫폼 배포 (맥 vs 리눅스)

pyproject.toml의 플랫폼 마커로 "맥=MLX, 리눅스=CUDA"를 pip 레벨에서 분기하는 법, extras([kokoro], [pocket])로 선택 의존성을 관리하는 법을 배운다. numpy<2(DeepFilterNet)와 numpy>=2(Pocket TTS)의 충돌을 문서로 경고하는 대목은, 파이썬 의존성 지옥의 현실을 보여주는 살아있는 사례다.

7하드웨어·시스템 요구사항

"어디까지 로컬로 돌릴 것인가"가 사양을 결정한다
세팅필요 하드웨어비고
클라우드 LLM일반 노트북 (CPU)STT·TTS만 로컬, LLM은 OpenAI/HF API. 진입장벽 최저
Apple 실리콘 로컬M1~M4 Mac (MPS)--local_mac_optimal_settings. MLX로 STT·LLM·TTS 전부 로컬
Linux GPU 로컬NVIDIA GPU + CUDA 12/13Qwen3-TTS GGML 백엔드는 CUDA 런타임 필요(휠 매칭 주의)
CPU-only서버/PC (GPU 없음)가능하나 지연 큼. +cpu 휠 설치
DockerNVIDIA Container Toolkitdocker compose up → llama.cpp(Gemma 4) + 소켓서버, 포트 8080/12345/12346
용어
GGML / CUDA 휠 매칭
기본 TTS인 Qwen3-TTS의 GGML 백엔드(qwentts-cpp-python)는 PyPI 기본 휠이 CUDA 12.8을 기대한다. 내 GPU의 CUDA 버전이 다르면 허깅페이스 휠하우스에서 맞는 버전(+cu130/+cu124/+cpu)을 먼저 깔아야 한다. 로컬 GPU 세팅에서 가장 흔한 설치 함정이다.

최소 요건은 Python 3.10+ 하나뿐이다. "일단 돌려보기"는 클라우드 LLM 세팅으로 노트북에서도 되고, "완전 로컬 프라이버시"로 갈수록 GPU/통합메모리 요구가 커지는 구조다.

8직접 해볼 수 있는 실습 과제

설치 5분짜리부터 코드 확장까지, 난이도별로
난이도 ★ 입문

1. 클라우드 LLM으로 첫 대화 (10분)

pip install speech-to-speechexport OPENAI_API_KEY=...speech-to-speech. 서버가 뜨면 다른 터미널에서 python scripts/listen_and_play_realtime.py --host 127.0.0.1 --port 8765로 말을 걸어본다. STT·TTS는 로컬, 답만 클라우드로 오는 구조를 체감.

난이도 ★ 입문

2. 로컬 모드로 마이크 대화 (맥)

speech-to-speech --local_mac_optimal_settings 한 줄이면 STT·LLM·TTS 전부 로컬(MLX)로 돌아간다. 인터넷을 꺼도 대화가 되는지 확인해보고, "완전 로컬 음성 AI"가 실제로 가능함을 눈으로 본다.

난이도 ★★ 초중급

3. 부품 갈아끼우기 실험

--tts kokoro vs --tts pocket, --stt whisper vs --stt parakeet-tdt로 조합을 바꿔가며 음질·지연을 비교한다. python scripts/benchmark_tts.py로 Qwen3-TTS 양자화(bf16/4bit/6bit/8bit) 속도를 측정해 표로 정리해보기.

난이도 ★★★ 중급

4. 완전 로컬 스택 구축 (llama.cpp)

터미널 1에서 llama-server -hf ggml-org/gemma-4-E4B-it-GGUF ...로 LLM을 띄우고, 터미널 2에서 speech-to-speech--responses_api_base_url을 그 서버로 가리킨다. 클라우드 API 없이 100% 로컬로 돌리는 걸 성공시키기. Docker(docker compose up)로도 재현.

난이도 ★★★★ 심화

5. 나만의 핸들러 추가

BaseHandler를 상속해 새 부품을 만든다. 예: STT와 LLM 사이에 "욕설 필터" 핸들러를 끼워 전사문을 검열하기. 혹은 TTS/에 새 음성 모델 핸들러를 추가하고 arguments_classes/에 CLI 인자를 등록해 --tts mytts로 부를 수 있게 만들기. 큐 in/out 규약만 지키면 파이프라인이 그대로 받아준다.

9관련 기술 심화 로드맵 (주차별)

음성 AI 엔지니어로 가는 8주 커리큘럼
주차주제할 것
1주차파이프라인 감 잡기실습 1·2 완료. 4단 사슬(VAD→STT→LLM→TTS)을 그림으로 직접 그려보기
2주차VAD·오디오 기초16kHz PCM·int16이 뭔지, Silero VAD가 확률로 말/침묵을 나누는 원리. vad_iterator.py 정독
3주차STT 심화Whisper vs Parakeet 아키텍처 비교. 스트리밍 전사(smart_progressive_streaming.py)가 부분 결과를 어떻게 내는지
4주차TTS 심화Qwen3-TTS·Kokoro·Pocket 비교, 음성 복제(voice cloning) 원리. 양자화(6bit)가 속도·품질에 주는 영향 벤치마크
5주차LLM 백엔드Responses API vs Chat Completions 차이, reasoning 끄기(reasoning_effort none)로 음성 지연 줄이기. vLLM·llama.cpp 서버 직접 띄우기
6주차파이썬 동시성threading + Queue 패턴 정복. 데드락·백프레셔·종료 신호 설계. baseHandler.py 필사
7주차실시간 프로토콜OpenAI Realtime 이벤트 스펙 학습, WebSocket vs WebRTC. websocket_router.py 이벤트 번역 읽기
8주차실전 UX끼어들기·speculative turns·cancel scope로 자연스러운 대화 만들기. 실습 5로 나만의 핸들러 완성
학습 순서 팁

이 로드맵은 바깥에서 안으로 파고드는 순서다. 먼저 "돌려보며 감을 잡고"(1주) → "각 부품을 하나씩 뜯고"(2~5주) → "부품을 잇는 뼈대(동시성·프로토콜)를 이해하고"(6~7주) → "실전 UX 디테일까지"(8주). 처음부터 speculative_turns.py 같은 어려운 코드를 보면 지치니, 반드시 실행 경험을 먼저 쌓고 들어갈 것.

10핵심 키워드 사전

이 레포를 읽을 때 마주칠 단어들
용어
캐스케이드 파이프라인 (cascaded pipeline)
STT·LLM·TTS 같은 개별 모델을 이어붙여 음성 대화를 만드는 방식. 통짜 엔드투엔드 모델의 반대. 유연성↑, 누적 지연↓이 트레이드오프.
용어
VAD (Voice Activity Detection)
오디오에서 사람이 말하는 구간을 감지. 턴 감지(말 끝났나?)의 출발점. 이 레포는 Silero VAD v5 사용.
용어
STT / ASR
Speech-to-Text(=Automatic Speech Recognition). 음성을 글자로. Parakeet TDT(기본), Whisper 등.
용어
TTS (Text-to-Speech)
글자를 음성으로 합성. Qwen3-TTS(기본), Kokoro, Pocket TTS(음성 복제) 등.
용어
OpenAI Realtime API
OpenAI의 실시간 음성 대화 프로토콜. WebSocket으로 오디오·이벤트를 스트리밍한다. 이 레포는 이 스펙을 셀프호스팅으로 구현해 "클라이언트 주소만 바꾸면 갈아타기"를 가능케 함.
용어
핸들러 (Handler) / BaseHandler
파이프라인의 한 부품. 입력 큐에서 꺼내 처리하고 출력 큐에 넣는 루프를 도는 단위. 모든 부품이 BaseHandler를 상속한다.
용어
RuntimeConfig
세션 설정을 담은 공유 Pydantic 모델. VAD·LLM·TTS가 실행 중 함께 읽는다. session.update로 실시간 변경.
용어
Speculative turns / Barge-in
"말이 끝난 듯"을 잠정 처리했다가 이어 말하면 턴을 재개, AI 말 중 끼어들면(barge-in) 즉시 취소. 자연스러운 대화 UX의 핵심.
용어
Responses API vs Chat Completions
둘 다 OpenAI 호환 LLM 백엔드. /v1/responses(기본) vs /v1/chat/completions. 제공자의 툴콜 스트리밍 안정성·reasoning 제어에 따라 골라 쓴다.
용어
MLX
Apple 실리콘 전용 ML 프레임워크. 맥에서 GPU(MPS) 가속으로 로컬 모델을 돌리는 경로. 리눅스의 CUDA에 대응.
용어
Reachy Mini
허깅페이스가 미는 오픈소스 데스크톱 로봇. 이 파이프라인이 수천 대의 대화 백엔드로 프로덕션 운영 중 — 실전 검증의 근거.

11참고 링크

더 파고들 곳