abogen은 "audiobook generator"의 줄임말이다. ePub·PDF·TXT·Markdown·SRT/ASS/VTT 자막 파일을 드래그하면, Kokoro-82M이라는 초경량 오픈소스 TTS 모델로 자연스러운 음성을 만들고, 발화 타이밍에 정확히 맞춘 자막까지 함께 뽑아낸다.
오디오북, YouTube 내레이션, TikTok·Instagram 보이스오버, 자기계발용 "들으면서 공부하기" — 텍스트가 있는 모든 작업에 쓸 수 있다. 그리고 전부 로컬에서 돈다. 클라우드 결제도, API 키도, 인터넷도 필요 없다.
오디오북 한 권을 사람이 녹음하면 어떻게 될까? 전문 성우가 6~10시간 동안 스튜디오에서 한 자 한 자 읽는다. 한 권에 수십만 원, 출판사가 결정해야 만들어진다.
abogen은 그 일을 당신 노트북에서 11초 만에 해낸다. ~3,000자 텍스트를 RTX 2060 모바일 GPU로 11초에 처리해서 3분 28초짜리 오디오를 만든다. 사람 성우가 28초 동안 읽는 분량을 11초에 만드는 셈 — 실시간보다 ~19배 빠르다.
Windows 사용자라면 WINDOWS_INSTALL.bat 더블클릭이 전부다. Python을 따로 깔 필요도 없고, CUDA 드라이버를 손볼 필요도 없다. 스크립트가 임베디드 파이썬 + 모든 의존성 + CUDA 호환 PyTorch를 자동으로 받아 설치한다. 비개발자도 5분이면 GUI를 띄울 수 있다.
이 프로젝트의 심장. 82M 파라미터(허깅페이스 hexgrad/Kokoro-82M)는 ChatGPT-4o 음성 모델 대비 0.x% 크기인데도, 영어 기준으로 유튜브에 그대로 올려도 어색하지 않은 수준의 발화 품질을 낸다. Apache-2.0 라이선스라 상업 이용도 자유롭다.
| 모델 | 파라미터 | 특징 |
|---|---|---|
| ChatGPT-4o Voice | 비공개(추정 수억) | OpenAI 클라우드 전용, API 과금 |
| ElevenLabs | 비공개 | 최고 품질, 분당 과금 |
| Kokoro-82M | 82M | 오픈, 로컬, Apache-2.0 |
| Coqui XTTS-v2 | ~870M | 다국어 좋지만 무겁다 |
경쟁 도구(audiblez, autiobooks 등)들은 대부분 시간 기반 분배 — 즉 "이 문장은 3초니까 3초로 잘라"식. abogen은 Kokoro의 timestamp token을 직접 받아서 단어 단위까지 정확히 정렬한다. 1단어 자막, 2단어 자막, 문장 + 강조(highlighting) 같은 카라오케 스타일까지 지원.
단순히 마침표로 자르면 "Mr. Smith said..."가 "Mr."에서 끊긴다. abogen은 옵션으로 spaCy NLP 라이브러리를 켜서 진짜 문장 경계를 잡는다. 비영어 텍스트는 오디오 생성 전에, 영어는 자막 생성 중에 spaCy를 돌려서 자연스러운 호흡을 만든다.
같은 코어 위에 3가지 사용 방식이 있다:
abogen — PyQt6 데스크탑 GUI (드래그앤드롭, 즉시 사용 가능)abogen-web — Flask 기반 웹 UI (NAS·서버에 띄워서 브라우저로 접근, htmx로 실시간 진행률 표시)abogen-cli — CLI 모드 (디버깅, 자동화, 스크립트 통합용)Web UI는 한 발 앞선 기능을 먼저 받는다 — Supertonic TTS, LLM 텍스트 정규화, Audiobookshelf 통합 같은 신기능이 거기서 먼저 안정화되고 데스크탑으로 백포팅된다.
변환 끝난 M4B 파일을 셀프호스팅 오디오북 서버(Audiobookshelf)에 한 번에 업로드한다. 폴더 자동 매핑, API 토큰 인증, Nginx Proxy Manager용 리버스 프록시 가이드까지 README에 들어 있다 — 진짜 셀프호스터에 친화적이다.
v1.3.1 기준 GitHub 별 4.2k, 256 fork, 24개 릴리스. 한 명이 시작한 프로젝트인데 @jeremiahsb의 PR 한 방(+55,000줄)으로 Web UI가 통째로 추가됐다. 메인테이너 Deniz Şafak는 PR에 친화적이고, jborza·robmckinnon·brianxiadong 등 외부 기여자가 챕터 지원, 단어별 자막, 마크다운 지원을 각각 가져왔다.
| 라이브러리 | 버전 | 역할 |
|---|---|---|
kokoro | ≥0.9.4 | TTS 엔진의 본체. hexgrad/Kokoro-82M 모델 추론 |
misaki[zh] | ≥0.9.4 | 중국어 G2P(자소→음소) 변환기. 일본어용 misaki[ja]도 옵션 |
supertonic | ≥0.1.0 | 차세대 TTS 엔진 (현재 Web UI에서 주로 활성화, PyQt에는 미연동) |
spacy | ≥3.8.7 | 문장 경계 탐지. "Mr." "Dr." 함정 회피 |
torch | 버전 미고정 (CUDA 인덱스에서 자동 결정) | 딥러닝 백본. CUDA 12.6/12.8/13.0, ROCm 6.4 분기 |
| 라이브러리 | 역할 |
|---|---|
ebooklib | EPUB 파일 파싱. 챕터·메타데이터·표지 이미지 추출 |
PyMuPDF | PDF 텍스트·페이지 추출 (속도가 빠른 fitz) |
beautifulsoup4 | EPUB 내 HTML/XHTML 정제 |
Markdown | Markdown 파싱 + 챕터 추출 |
charset_normalizer + chardet | 인코딩 자동 감지 (한글 EUC-KR도 OK) |
num2words | "123" → "one hundred twenty three" 같은 정규화 |
| 라이브러리 | 역할 |
|---|---|
soundfile | WAV/FLAC 파일 입출력 |
mutagen | MP3/M4B 메타데이터·챕터 마커 삽입 |
static_ffmpeg | FFmpeg을 패키지로 번들 — 사용자가 설치 안 해도 됨. MP3/OPUS/M4B 인코딩 + time-stretch에 사용 |
pygame | 음성 프리뷰 재생용 가벼운 오디오 백엔드 |
| 인터페이스 | 스택 | 특징 |
|---|---|---|
| 데스크탑 GUI | PyQt6 ≥ 6.5 | 크로스 플랫폼 네이티브 위젯, 드래그앤드롭 |
| Web UI | Flask ≥ 3.0.3 + htmx (추정) | 실시간 진행률, 작업 큐, JSON API 노출 |
| CLI | abogen-cli | 디버깅·자동화·스크립트 통합용 |
| 도구 | 역할 |
|---|---|
docker-compose.yaml | GPU 컨테이너 기본값. NVIDIA Container Toolkit 통합 |
abogen/webui/Dockerfile | Web UI 전용 슬림 이미지. TORCH_INDEX_URL 빌드 인자로 CUDA 버전 가변 |
uv (Astral) | Python 패키지 매니저. CUDA 12.6/12.8/13.0/ROCm용 분기 인덱스 자동 라우팅 |
hatchling | 빌드 백엔드. pyproject.toml 기반 wheel/sdist 빌드 |
| GitHub Actions | .github/workflows/test_pip.yml — pip 설치 회귀 테스트 CI |
| 임베디드 Python (Windows) | 독립 실행형. Python·pip 사전 설치본을 다운로드해서 sandbox 생성 |
| 대상 | 통합 방식 |
|---|---|
| Audiobookshelf | HTTP API + 폴더 자동 매핑. M4B 자동 푸시 |
| OpenAI-호환 LLM (Ollama, OpenAI, Mistral …) | LLM 텍스트 정규화 — "don't" 같은 contraction을 자연스럽게 풀어줌 |
| espeak-ng | Kokoro의 G2P 백엔드. 영어 외 언어의 음소화 담당 |
| Hugging Face Hub | 모델·음성 가중치 자동 다운로드. HF_HOME로 캐시 경로 제어 |
EPUB·PDF·MD를 입력받으면 abogen은 곧장 음성을 만들지 않는다. 먼저 캐시 디렉토리에 .txt 파일을 만들고 거기에 <<CHAPTER_MARKER:Chapter 1>> 같은 챕터 마커를 끼워넣는다. 사용자는 이 텍스트를 편집할 수 있고, 음성 생성에서 오류가 나면 특정 챕터만 재생성할 수 있다.
TTS 생성은 GPU에서도 10~30분 걸리는 일이다. 만약 16번째 챕터에서 오타 발견 → 다 다시 만든다? 사용자 입장에선 재앙. abogen은 "파싱은 캐시 가능한 텍스트로, TTS는 챕터 단위로 격리"라는 두 레이어 분리로 이 문제를 해결한다.
Kokoro가 영어 텍스트에서 timestamp token(각 단어가 언제 시작하는지)을 직접 출력한다. abogen은 이 토큰을 받아서 자막 모드별로 재구성한다:
비영어 텍스트는 timestamp token이 없으니 duration-based fallback을 쓴다 — 즉 spaCy로 잘라낸 문장의 길이로 시간을 분배. 한국어 등 비영어는 단어 단위 자막이 안 되는 이유가 여기 있다.
여러 파일을 한 번에 처리할 때 골치 아픈 게 "파일마다 다른 음성/속도/포맷"을 쓰고 싶을 때다. abogen의 큐 매니저는 각 파일이 추가될 시점의 설정을 스냅샷한다. 메인 UI를 바꿔도 큐 안 항목엔 영향 없음. 필요하면 "Override item settings" 옵션으로 일괄 적용도 가능.
입력이 SRT/ASS 자막 파일일 때(자막→오디오), 자막 시간과 실제 발화 시간이 안 맞을 수 있다. abogen은 두 가지 전략을 제공한다:
웹 UI는 별도 워커 프로세스가 큐를 소비하고, 브라우저는 GET /partials/jobs를 폴링해서 진행률을 그린다. GET /api/jobs/<id>는 JSON으로 같은 정보를 반환 — 외부 자동화에 그대로 쓸 수 있다.
pyqt/와 webui/ 분리 — 같은 코어 모듈을 import해서 쓰는 "두 개의 얼굴". 어느 한쪽 코드를 끊어도 다른 쪽은 정상 동작.abogen, abogen-web, abogen-cli) — pyproject.toml의 [project.scripts]와 [project.gui-scripts]로 노출. CLI/GUI 모두 동일 진입.resources/ 제외 — 무거운 바이너리 리소스는 wheel에만 포함 시켜 sdist는 가볍게.docker-compose.yaml이 GPU 기본 — CPU만 쓰려면 deploy.resources 블록만 주석 처리. 셀프호스터 친화적 선택./data(작업), /config(설정), /data/outputs(결과물), /data/cache(임시). 백업 정책을 폴더별로 다르게 잡을 수 있게 설계.Kokoro 같은 외부 모델을 자신의 앱에 통합할 때 abogen이 보여주는 패턴은 그대로 응용 가능하다:
HF_HOME에 보존Electron 대안으로 PyQt6는 메모리도 적게 먹고 네이티브 모양에 가깝다. abogen이 보여주는 PyQt6 활용 포인트:
platformdirs로 OS별 표준 경로에 저장 (Win: %APPDATA%, macOS: ~/Library, Linux: ~/.config)React/Vue 대신 Flask 서버사이드 렌더링 + htmx 폴링으로 같은 UX를 만든다. 이 조합의 장점:
hx-trigger="every 2s" 한 줄이면 끝/api/jobs/<id>)와 HTML 파셜(/partials/jobs)을 같은 라우터에서 공존PyTorch는 CUDA 버전마다 다른 wheel을 쓴다. abogen의 pyproject.toml은 extras로 분기를 명시한다:
# [project.optional-dependencies]
cuda126 = ["torch"] # CUDA 12.6
cuda = ["torch"] # CUDA 12.8 (기본)
cuda130 = ["torch"] # CUDA 13.0
rocm = ["torch", "pytorch-triton-rocm"] # AMD ROCm 6.4
# [tool.uv.sources]
torch = [
{ index = "pytorch-rocm-64-nightly", marker = "extra == 'rocm'" },
{ index = "pytorch-cuda-130", marker = "extra == 'cuda130'" },
{ index = "pytorch-cuda-126", marker = "extra == 'cuda126'" },
{ index = "pytorch-cuda-128", marker = "extra == 'cuda'" },
]
이 패턴 하나를 알아두면 "GPU 의존성을 가진 모든 Python 패키지"의 배포 골치가 사라진다. CUDA 환경마다 별도 빌드를 만들 필요 없이 uv tool install abogen[cuda130] 한 줄로 끝.
static_ffmpeg오디오 도구들이 늘 부딪히는 벽: "사용자에게 FFmpeg을 설치하라고 시킬 거냐?". abogen은 static_ffmpeg 패키지로 정적 컴파일된 ffmpeg 바이너리를 번들로 가져온다. 의존성 0개로 MP3/OPUS/M4B 인코딩, time-stretch까지 다 처리 — 데스크탑 앱을 만드는 사람에게 매우 실용적인 트릭이다.
EPUB은 ZIP 안에 XHTML 여럿이 든 구조다. PDF는 페이지 단위. 둘을 "챕터를 인식한 평문 + 마커"로 통일하는 abogen의 접근은 다른 문서 처리 앱에도 그대로 쓸 수 있다:
<<METADATA_TITLE:해리포터와 마법사의 돌>>
<<METADATA_ARTIST:J.K. Rowling>>
<<METADATA_COVER_PATH:/cache/cover.jpg>>
<<CHAPTER_MARKER:1장 살아남은 아이>>
프리벳가 4번지에 사는 더즐리 부부는...
<<CHAPTER_MARKER:2장 사라진 유리>>
거의 10년이 지났다...
| 환경 | 속도(체감) | 비고 |
|---|---|---|
| CPU 전용 (어떤 PC든) | 실시간의 0.3~1x | 긴 책엔 부담. 짧은 텍스트 OK |
| RTX 2060 Mobile (저가 노트북 GPU) | 실시간 19x (3,000자 → 11초) | README의 데모 환경 |
| RTX 4070/4080 (CUDA 12.8) | 실시간 30~50x 추정 | 가장 추천. CUDA 12.8 wheel 사용 |
| Apple Silicon (M1/M2/M3) | 실시간 5~15x | Kokoro의 MPS 지원. git+https://github.com/hexgrad/kokoro.git 개발판 필요 |
| AMD GPU (Linux ROCm 6.4) | 실시간 10~30x 추정 | Windows는 ROCm 미지원 — 리눅스 필수 |
| NAS / 라즈베리파이 4 | CPU 모드 한정. 매우 느림 | "잘 때 큐에 던지고 아침에 받기"용 |
| OS | 꼭 깔아야 할 것 |
|---|---|
| Windows | espeak-ng MSI + (선택) NVIDIA 드라이버 |
| macOS | brew install espeak-ng + uv |
| Linux | apt install espeak-ng / pacman -S espeak-ng / dnf install espeak-ng |
| Docker | NVIDIA Container Toolkit (GPU 사용 시) + 8GB 메모리 권장 |
3.13에서는 일부 의존성(spaCy 3.8.x, PyMuPDF)이 아직 안정화 안 됐다. uv로 설치할 때 --python 3.12 명시를 권장. 일본어 지원은 추가로 pip install misaki[ja] 필요.
좋아하는 영어 책 PDF 하나를 잡고 abogen GUI를 띄워 드래그앤드롭. Female 미국 영어 음성으로 챕터별 분리 + M4B 출력. 핸드폰에 옮겨서 출퇴근길에 들어보기.
배움 포인트: Kokoro 영어 음성 비교(am/af 등), 챕터 분리의 실용성, M4B 메타데이터.
Voice Mixer에서 영국 남성(bm) 70% + 미국 여성(af) 30% 같은 식으로 가중치 조합. Save profile로 저장해놓고 다음에도 같은 톤으로 책을 만든다.
배움 포인트: latent voice blending, weight tuning, profile 저장 구조.
NAS나 미니 PC에 Audiobookshelf 컨테이너를 띄우고, abogen 설정의 Integrations에 연결. 이후 GUI에서 "Send to Audiobookshelf" 한 방으로 라이브러리 갱신. 진짜 "내 오디오북 스트리밍 서비스"를 만든다.
배움 포인트: 리버스 프록시 + Bearer 토큰 인증, 라이브러리 ID 개념, 셀프호스팅 워크플로.
로컬에 Ollama로 Llama 3.2를 띄우고, ABOGEN_LLM_BASE_URL=http://localhost:11434 설정. 한국어 책의 "8.5%", "Mr. 홍" 같은 까다로운 부분을 LLM이 미리 "팔점오 퍼센트", "미스터 홍"으로 정규화하게 만든다.
배움 포인트: OpenAI 호환 API 라우팅, 프롬프트 템플릿 설계, context window 모드(sentence/paragraph/document).
특정 폴더에 새 EPUB이 들어오면 cron이 abogen-web의 JSON API를 호출해 큐에 추가, 완료되면 webhook으로 Telegram에 알림 + Audiobookshelf 자동 등록. NAS 24/7 자동 파이프라인.
배움 포인트: 워크플로 자동화, JSON 엔드포인트 활용, 파일 시스템 watch, 컨테이너 헬스체크.
| 주차 | 주제 | 실습 결과물 |
|---|---|---|
| 1주 | TTS 기초 — Kokoro·VITS·Coqui XTTS 비교 | 같은 문장을 세 모델로 합성해서 품질·속도·라이선스 비교 표 |
| 2주 | 음소화(G2P)와 espeak-ng 내부 | 한국어 G2P 직접 구현 (음운 변동 규칙 1~2개) |
| 3주 | PyTorch 추론 최적화 — half precision · torch.compile | Kokoro fp16 변환 → 속도 1.5x 향상 측정 |
| 4주 | 오디오 파일 포맷 — WAV/FLAC/MP3/OPUS/M4B 깊이 이해 | FFmpeg 직접 옵션으로 같은 음원을 5가지 포맷 변환 + 크기·품질 비교 |
| 5주 | EPUB/PDF 구조와 ebooklib · PyMuPDF | EPUB → JSON(챕터 트리) 변환기 직접 작성 |
| 6주 | PyQt6 — QThread, 신호/슬롯, 다크모드 | 드래그앤드롭 + 진행률 + 시스템 트레이 갖춘 미니 데스크탑 앱 |
| 7주 | Flask + htmx — 백그라운드 워커, 작업 큐 | RQ·Celery 대신 in-process queue로 단순 잡 큐 직접 구현 |
| 8주 | 셀프호스팅 — Audiobookshelf, Nginx Proxy Manager, Tailscale | 내 NAS에서 오디오북 스트리밍 + 외부 폰에서 재생까지 완성 |
[tool.uv.sources]로 의존성 인덱스를 분기시킬 수 있다. abogen이 CUDA 12.6/12.8/13.0/ROCm을 하나의 설정으로 다루는 비결.hx-get, hx-trigger 같은 속성으로 부분 갱신을 선언. React 없이도 실시간 UI가 가능하게 해주는 abogen Web UI의 핵심.%APPDATA%, macOS: ~/Library, Linux: ~/.config. abogen이 설정 파일 위치를 자동 결정하는 데 쓴다.