Communitygithub.com

local-tts

자체 GPU(또는 CPU)에서 사람 같은 음성을 생성하여 API 비용 없이 음성 해설, 설명 영상 내레이션, 텍스트 낭독, 오디오 클립을 만들고, 알려진 라인 타이밍을 기반으로 한 .srt 자막도 함께 제공합니다.

local-tts란 무엇인가요?

이 스킬은 Qwen3-TTS 1.7B (8-bit GGUF) 모델을 qwentts.cpp 엔진을 통해 로컬에서 실행하여 고품질 음성을 생성합니다. API 비용이 전혀 들지 않으며, RTX 4070 노트북 GPU에서 18분 분량의 내레이션을 약 4.5분 만에 처리할 정도로 빠릅니다. 유료 또는 클라우드 TTS API나 저품질 내장 음성에 의존하기 전에, HyperFrames, fframes, Remotion 등 비디오 프로젝트에서 텍스트를 음성으로 변환해야 할 때 사용하세요. 또한 사용자가 더 최신이거나 더 나은 로컬 TTS 모델을 찾거나 비교하거나 시도해보라고 요청할 때도 유용합니다. 기본 음성은 'aiden' 스피커로, 친근한 기술 설명 영상 내레이터 스타일이며, 블라인드 청취 테스트에서 Kokoro, Chatterbox, PyTorch Qwen3-TTS, VoxCPM2, Phonon 등을 능가했습니다. 스킬은 한 번의 프로세스로 여러 줄을 처리하여 모델 로딩 시간을 절약하고, .srt 자막 생성을 지원하며, 지속적으로 더 나은 모델을 찾도록 장려합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Ayushmaniar/claude-explainer-skills/tree/HEAD/plugins/explainer-skills/skills/local-tts

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Local TTS

기본 음성: Qwen3-TTS 1.7B CustomVoice, 스피커 aiden, 8-bit GGUF (Q8_0), qwentts.cpp (C++/ggml, MIT) 구동, 다음 스타일 지시 포함:

따뜻하고, 맑고, 호기심 가득한, 마치 친근한 기술 설명 영상 내레이터처럼. 편안하고 일정한 속도.

블라인드 청취 테스트에서 Kokoro, Chatterbox, PyTorch Qwen3-TTS, VoxCPM2 및 Phonon을 이겼습니다 (자세한 내용은 references/benchmarks.md 참조). 8GB RTX 4070 노트북 GPU에서 모델 로딩을 포함해 약 실시간의 4배 속도로 실행됩니다: 18분 내레이션을 약 4.5분 만에 처리합니다.

설정 (머신당 한 번)

python -I <skill>/scripts/say.py --check를 먼저 실행하세요. OK가 출력되면 이 섹션은 건너뛰십시오. 그렇지 않으면 엔진을 설정하거나 사용자에게 설정을 요청하세요. 10-20분 정도 걸리며 약 2.5GB의 디스크 공간이 필요합니다.

  1. qwentts.cpp 빌드. 미리 빌드된 Windows 바이너리가 없으므로 소스에서 빌드하세요:
    git clone --recurse-submodules https://github.com/ServeurpersoCom/qwentts.cpp ~/tools/qwentts.cpp
    cd ~/tools/qwentts.cpp
    ./buildcuda.sh       # NVIDIA (Linux); AMD/Intel의 경우 ./buildvulkan.sh; CPU 전용(e.g. macOS)의 경우 ./buildcpu.sh
    
    Windows에서는 VS 2022(또는 최신) 빌드 도구(C++ 워크로드 포함), CMake, Ninja 및 CUDA 툴킷을 설치한 후, 리포지토리에서 buildcuda.cmd를 실행하세요. vcvars64.bat가 다른 위치에 있으면 해당 스크립트 상단의 경로를 편집하세요. 단일 GPU만 대상으로 하려면 cmake 라인에 -DCMAKE_CUDA_ARCHITECTURES=89 (RTX 40xx; 86 = RTX 30xx, 120 = RTX 50xx)를 추가하세요.
  2. 가중치 다운로드 (~2 GB) Hugging Face의 Serveurperso/Qwen3-TTS-GGUF에서:
    pip install -U huggingface_hub
    hf download Serveurperso/Qwen3-TTS-GGUF qwen-talker-1.7b-customvoice-Q8_0.gguf qwen-tokenizer-12hz-Q8_0.gguf --local-dir ~/tools/qwen-gguf
    
  3. say.py가 이들을 가리키도록 설정 다른 폴더를 사용한 경우: QWEN_TTS_HOME (체크아웃 폴더), QWEN_TTS_EXE (바이너리) 또는 QWEN_TTS_MODELS (.gguf 폴더)를 설정하세요. Windows에서 say.py는 PATH에 %CUDA_PATH%\bin\x64를 자동으로 추가합니다 (CUDA_BIN으로 재정의 가능).
  4. say.py --check를 다시 실행한 후, 한 줄을 테스트로 음성 출력하세요.

하드웨어: Q8_0의 경우 8GB VRAM이면 충분합니다 (~3GB 사용). GPU가 없으면 CPU 빌드가 약 4분의 1 속도로 작동합니다. GGML_BACKEND=CPU는 GPU 빌드를 강제로 CPU에서 실행하도록 합니다.

생성 전에

  1. GPU를 다른 것이 사용 중인가요? 게임이나 GPU 집약적인 앱이 실행 중이면 생성 속도가 약 4배 느려지고 해당 앱이 버벅거릴 수 있습니다. 긴 작업을 시작하기 전에 물어보세요. 사용자가 그러한 앱을 지정하면 TTS_BUSY_APPS=app1,app2를 설정하고 say.py가 실행 중일 때 경고합니다.
  2. 더 나은 모델을 확인할 가치가 있나요? 아래 "계속해서 더 나은 모델 찾기"를 참조하세요. 마지막 확인이 약 6주 이상 지났고 작업이 (한 줄 테스트가 아닌) 실제 내레이션이라면 먼저 빠른 스캔을 수행하세요.
  3. 텍스트가 사람처럼 들리나요? 음성은 AI스러운 표현을 매번 같은 억양으로 읽으므로, 페이지에서보다 패턴이 더 두드러집니다. 몇 줄 이상의 내레이션의 경우 whiteboard-explainer 스킬(동일 플러그인, references/)에서 natural-narration.md를 읽고 scripts/aispeak_scan.py를 실행하세요. 이 스크립트는 script.py 또는 일반 텍스트 파일을 입력으로 받습니다.

생성

스크립트는 표준 라이브러리만 사용하므로 Python 3.10+이면 작동합니다. <skill>은 이 스킬의 폴더입니다.

python -I <skill>/scripts/say.py "첫 번째 줄." "두 번째 줄." -o out.wav       # 하나의 WAV, 0.35초 간격
python -I <skill>/scripts/say.py --file lines.txt -o clips/                    # 000.wav, 001.wav, ...

옵션:

플래그기능
--speakeraiden (기본값); ryan은 다른 네이티브 영어 음성입니다
--instruct스타일 텍스트, 예: "신나고 빠르게" 또는 "차분하고 진지하게"
--seed N반복 가능한 테이크를 제공합니다
--gap S결합된 파일에서 줄 사이의 침묵 시간(초)
--srt F결합된 WAV와 동기화된 자막도 작성합니다 (자막 참조)
--quantQ8_0 (기본값, 최고) 또는 Q4_K_M (더 작고 약간 덜 부드러움; 먼저 다운로드 필요)
--check발견된 엔진, 모델 및 CUDA 폴더를 보고합니다

작동 방식:

  • 모든 줄이 하나의 프로세스를 통해 처리되므로 모델이 한 번만 로드됩니다 (3-8초). 줄을 한 번에 하나씩 호출하지 말고 한꺼번에 전달하세요.
  • 출력은 24kHz 모노 16비트 WAV입니다.

테이크는 샘플링되므로 실행마다 다릅니다:

  • 마음에 드는 클립은 보관하세요. 텍스트와 설정을 키로 하여 줄별로 캐시하세요.
  • 줄 길이가 문자당 ~0.07초에서 크게 벗어나면 다시 테이크하세요. 이는 단어가 누락되거나 생성되었음을 의미합니다.

비디오 내레이션의 경우:

  • 각 클립의 침묵을 약 50ms 패딩으로 자르고, 자신의 간격으로 타임라인에 줄을 배치하세요.
  • 최종 트랙을 음량 정규화하세요: ffmpeg -af loudnorm=I=-16:TP=-1.5:LRA=11.

자막 (.srt): 모든 내레이션 비디오에 제공하세요

각 줄의 시작과 끝을 이미 알고 있으므로, 받아쓸 필요가 없습니다. 해당 타이밍을 사용하여 자막을 만드세요.

  • say.py와 함께: --srt narration.srt 추가 (-o .wav 필요). 자막은 결합된 트랙과 정확히 일치합니다.
  • 자체 파이프라인에서: scripts/srt.py의 to_srt([(start_s, end_s, text), ...], display=[...])를 호출하세요. 각 음성 줄의 비디오 시간 시작/끝을 전달하세요. 또는 CLI 사용: python srt.py timings.tsv -o video.srt.
  • 음성 철자 수정. 내레이션 텍스트는 종종 음성에 맞춰 작성됩니다: "D I L", 이름의 음성적 재철자, "runner dot HTML", 숫자를 단어로 표기. display / --display display.tsv (말한 대로작성된 대로)를 사용하여 다시 매핑하세요. 작성된 형식은 화면에 표시된 것에서 가져오고, 숫자에는 숫자 기호를 사용하세요 ("$232", "83%").
  • 결과 확인. 남아 있는 띄어쓰기된 대문자 ([A-Z] [A-Z])와 " dot "이 있는지 grep으로 확인하세요.
  • 모듈이 적용하는 규칙:
    • 자막당 최대 2줄, 42자
    • 문장, 구, 단어 순으로 줄 바꿈
    • 짧은 문장은 너무 빠르게 지나가지 않도록 병합
    • 시간은 길이에 비례하여 분배
  • 비디오와 같은 이름 (Video Name.srt를 Video Name.mp4 옆에)으로 지정하여 플레이어가 자동으로 로드하게 하세요. VLC에서는 --sub-file=로 파일을 강제할 수 있습니다.

whiteboard-explainer 스킬의 template/narration/build_vo.py는 완전한 작동 파이프라인 예제입니다: 줄별 캐시, 재테이크, 침묵 자르기, 일시 정지 성형, 단어 정렬, 큐 테이블 및 립싱크 봉투.

주의사항

  • CUDA DLL이 PATH에 있어야 함 (Windows). CUDA 13은 이를 ...\CUDA\v13.x\bin\x64에 유지합니다. 해당 폴더가 PATH에 없으면 qwen-tts.exe가 출력 없이 자동 종료됩니다. say.py가 자동으로 추가합니다.
  • --stream-by-line -o -는 스트리밍 WAV 헤더를 작성합니다 (크기 0x7fffffff), 줄당 하나씩. RIFF....WAVEfmt 에서 분할하고 각 44바이트 헤더를 버리세요. 크기 필드는 신뢰하지 마세요.
  • Aiden이 단일 문자와 특수 토큰을 잘못 읽습니다. 무작위 Whisper 감사에서 발견됨:
    • "h star"는 "a hap" 또는 "our star", "y t"는 "VT", "y"는 "we", "arXiv"는 "ArcSireFolk"로 출력됨.
    • 다음은 잘 작동함: 대문자 "H star" / "under H", "why tee" / "why tilde", "archive", "SMILES check".
    • "aitch"는 불규칙적입니다. 이름은 단독으로는 괜찮을 수 있지만 문장 중간에 변형될 수 있습니다: 전체 줄 안에서 테스트하세요.
    • 문장 첫머리의 K가 누락될 수 있음 ("Kwenputer" → "When Pooter"): "And" 또는 "So"로 줄을 시작하세요.
    • 초기 프롬프트 없이 각 클립을 전사한 후, 스크립트와 비교하여 감사하세요. 프롬프트된 Whisper는 의도된 단어를 "듣고" 오류를 숨깁니다. 도구: whiteboard-explainer/template/narration/audit_vo.py 및 tts_try.py.
  • 콜론에서의 일시 정지. Qwen은 콜론에서 0.6-0.8초 동안 멈추고 때로는 구 중간에도 멈춥니다. 내레이션에서는 구두점 앞의 침묵으로 각 침묵을 제한하고 (템플릿의 build_vo.py에 있는 shape()) 콜론-단편 줄을 피하세요 ("첫째: ...").
  • CPU 폴백: Kokoro 82M (kokoro-onnx)은 평탄하지만 CPU에서 빠르며, GPU가 사용 중일 때 초안 작업에 적합합니다.

계속해서 더 나은 모델 찾기

로컬 TTS는 빠르게 개선되고 있으며, 현재 선택이 곧 깨질 것입니다. 이를 최종 답이 아닌 현 챔피언으로 취급하세요. 특히 큰 내레이션 작업 전이나 마지막 확인이 약 6주 이상 지났을 때 더 새롭고 더 나은 모델을 찾으세요.

  1. 스캔. 마지막 확인 이후 출시 또는 업데이트된 오픈 가중치 TTS를 웹에서 검색하세요. 다음을 확인하세요:
    • TTS Arena / Artificial Analysis 음성 리더보드
    • Hugging Face 트렌딩 text-to-speech 모델
    • r/LocalLLaMA
    • 아래 엔진의 GitHub 릴리스
  2. 필터. 다음 조건을 모두 충족하는 경우에만 후보로 유지하세요:
    • 로컬에서 무료로 사용 가능 (오픈 가중치, 허용적 또는 개인용 라이선스)
    • 사용자의 GPU 메모리와 OS에서 실행 가능
    • 필요한 언어를 지원
    • 품질 면에서 챔피언을 능가하거나, 동등한 품질이면서 훨씬 빠름
  3. 시험. 후보로 eval/lines.txt를 생성하세요. scripts/voice_metrics.py (pip install numpy librosa; 챔피언 및 기준 녹음은 eval/에 있음)로 챔피언과 점수를 비교하세요:
    • 피치 표준편차 ≥ ~5 반음, 범위 ≥ ~17 반음이 자연스러운 소리에 필요합니다.
    • 속도는 생성 시간당 오디오 시간(초)으로 측정하세요.
  4. 듣기. 사용자에게 후보와 eval/champion_*.wav (ffplay -nodisp -autoexit file.wav) 사이를 귀로 선택하도록 요청하세요. 메트릭은 후보를 선별할 뿐; 귀가 최종 결정을 내립니다.
  5. 기록. 변경된 사항이 없더라도 아래 "마지막 확인" 줄과 references/benchmarks.md를 업데이트하세요. 챔피언이 변경되면 eval/champion_*.wav를 교체하고 say.py를 업데이트한 후, 이전 모델을 삭제하기 전에 물어보세요.

마지막 확인: 2026-11-02 (웹 설문 조사 및 로컬 VoxCPM2 Q8 및 Phonon 31m/Miles 시험). Aiden이 두 경우 모두 귀로 선호되었습니다. 아직 로컬에서 시도하지 않음: Phonon 40m, OmniVoice, Breeze TTS 2, Drama 3, Orpheus, Dia, Sesame CSM, Spark-TTS, IndexTTS-2, VibeVoice, Higgs Audio, Kyutai TTS 및 Fish/OpenAudio. 자세한 내용은 references/benchmarks.md에 있습니다.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

관련 스킬