음성을 출력하는 기능을 만들 때 모델 파일이 작다는 이유만으로 도입을 결정하기는 어렵습니다. 어떤 기기에서 실행하는지, 숫자를 어떻게 읽는지, 첫 실행과 재생까지 얼마나 기다리는지를 함께 봐야 합니다.
2026년 11월 5일 Hugging Face에 공개된 Phonon 해설은 on-device TTS의 구현과 integration을 자세히 소개합니다.[11] 모델의 open-weight 공개 자체는 10월 20일이므로, 오늘 처음 출시된 모델로 소개하는 글은 아닙니다.[12]
💡 💡 핵심: 음성 모델과 전처리기, 실행 위치, 재생 경로를 분리해서 판단하세요. Phonon을 쓰지 않더라도 로컬 AI 기능의 도입을 검토할 때 가져갈 수 있는 기준입니다.
Phonon은 텍스트를 음성으로 바꾸는 Text-to-Speech 모델군입니다.[53] 영어용 Phonon 31m과 영어·프랑스어·독일어·스페인어·포르투갈어를 위한 40m 계열이 있으며, 범용 LLM이나 음성 인식 모델이 아닙니다.[53]
31m English의 모델 카드는 31M이라는 parameter 수에서 audio tokenizer를 제외한다고 명시합니다.[53] 또한 64.5 MB는 q8 가중치 파일의 크기이며, 프로그램 전체의 실행 메모리 요구량이라는 설명이 아닙니다.[53]
실행을 담당하는 ptts는 별도 runtime입니다.[54] Rust로 작성되어 PyTorch 없이 동작하며 브라우저, 앱, 로컬 서버 등의 연결 경로를 제공합니다.[54]
Micdrop의 Node.js integration 문서는 Phonon을 로드해 합성하는 Node process의 메모리를 약 450 MB로 보고합니다.[16] 이는 해당 integration의 관찰값이지, 모든 Phonon 실행 환경의 최소 RAM이나 고정 사용량은 아닙니다.
도입 판단 의견: 가중치 다운로드 크기, tokenizer·codec을 포함한 모델 구성, runtime과 애플리케이션의 메모리를 따로 예산에 넣으세요. 작은 파일 하나를 내려받는 문제와 서비스를 계속 운영하는 문제는 다릅니다.
공식 설명을 역할별로 나누면 다음 흐름입니다.[12][15]
공식 발표에서 생성의 한 단위는 80 ms 분량의 음성입니다.[12] 80 ms는 생성되는 오디오의 길이이지, 한 요청의 실제 처리 시간이 80 ms라는 뜻이 아닙니다.
전체 문장을 완성한 뒤 파일을 돌려주는 방식과 달리, chunk를 내보내는 경로에서는 뒤쪽 음성을 생성하는 동안 앞부분을 재생할 수 있습니다.[53][54]
Phonon의 Transformers 문서는 tokenizer가 금액·숫자·주소를 언어에 맞는 읽기 표현으로 풀어 쓰지 않는다고 명시합니다.[15] 이 작업에는 ptts의 text normalization을 사용하거나 입력을 직접 풀어 쓰라고 안내합니다.[15]
문서 예제에서 It is 21°C는 tokenizer만 통과하면 숫자와 기호가 그대로 남지만, Gradium runtime의 정규화 결과는 It is 21 degrees Celsius.로 제시됩니다.[15] 여기서 확인한 것은 문서에 적힌 전처리 예시이며, 이 글에서 음성을 생성하거나 청취한 결과가 아닙니다.
따라서 같은 checkpoint라도 전처리기를 바꾸면 모델이 받는 텍스트가 달라질 수 있습니다.[15][53] “이 모델은 날짜와 금액을 잘 읽는다”는 소개를 가중치만의 성질로 이해해서는 안 됩니다.
설계 제안: 버전 번호, 날짜, 금액, 주문번호, 이메일을 별도의 검증 문장으로 관리하세요. 예를 들어 3.10을 버전으로 읽어야 하는지 소수로 읽어야 하는지부터 제품 요구사항으로 정하는 방식입니다. 이는 제안 입력이지 검증된 합성 출력이 아닙니다.
공식 ptts README의 브라우저 package는 WebAssembly 기반 경로를 제공하며, 첫 로드에서 파일을 다운로드하고 cache합니다.[54] 반면 Micdrop은 Node process의 worker thread에서 합성을 수행합니다.[16]
즉 사용자의 브라우저에서 합성하는 구조와 우리 서버의 Node에서 합성하는 구조는 다릅니다.[16][54] 서버에 둔 Node integration을 연결했다는 이유로 사용자 텍스트가 사용자 기기 밖으로 나가지 않는다고 설명하면 안 됩니다.
11월 5일 해설은 ptts를 기기의 단일 stream 실행에, Transformers를 GPU의 batched generation과 torch.compile을 활용한 처리량 중심 경로에 대응시킵니다.[11] 같은 모델을 다루더라도 두 구현을 같은 성능·운영 조건으로 비교하는 글은 아닙니다.
별도로 공개된 ExecuTorch WebGPU conversion은 방문자의 GPU에서 실행되는 브라우저 demo를 위한 변환본입니다.[17] 이 문서는 WebGPU가 활성화된 브라우저를 요구하고, 공식 runtime의 숫자·날짜 정규화는 애플리케이션이 담당해야 한다고 안내합니다.[17]
편집 의견: 처음에는 목표 실행 위치 하나만 정하세요. “웹도 되고 모바일도 된다”는 지원 목록보다 우리 앱이 사용할 runtime·backend·모델 파일의 조합이 먼저입니다.
Micdrop은 모델 파일이 이미 cache된 MacBook Pro M2, 단일 CPU core라는 조건에서 모델 로드와 첫 단어에 0.70.9초, 문장의 첫 오디오에 30100 ms를 보고합니다.[16] integration 작성자의 측정이며, 제가 재현한 수치나 모든 기기에서의 성능 보장이 아닙니다.
이 수치를 첫 다운로드부터 사용자가 소리를 듣기까지의 전체 시간으로 바꾸어 읽을 수는 없습니다. 문서 자체도 최초 다운로드와 cache, 로드, 문장 합성을 구분하고 있습니다.[16]
다음은 고객 사례가 아니라 설계 제안입니다. 연결이 불안정한 장소에서 짧은 영어 안내문을 읽는 앱을 가정합니다.
동시 요청도 따로 봐야 합니다. Micdrop 문서는 모델·언어·precision 조합의 instance를 공유하고 한 worker에서 문장을 차례로 처리한다고 설명합니다.[16] worker를 사용해 event loop를 막지 않는 것과 여러 통화를 동시에 합성하는 것은 같은 보장이 아닙니다.[16]
Micdrop 문서는 @micdrop/phonon이 Node worker thread에서 runtime을 실행하며 별도 sidecar 서버가 필요 없다고 설명합니다.[16] 이는 공개 integration의 구조를 확인한 사례이며, 대규모 운영 처리량이나 고객 도입 성과를 검증한 결과는 아닙니다.
10월 26일 Gladys 커뮤니티 글의 작성자는 Node integration이 별도의 공식 ptts-openai-server container를 제어해 MP3를 받는 구성을 공개했습니다.[24] 첫 설치 뒤에는 offline으로 동작하는 구조라고 설명합니다.[24]
같은 글에서 작성자는 당시 integration에 streaming을 추가하는 것을 개선 방향으로 제시하고, Raspberry Pi 4에서는 합성이 실시간보다 느렸다고 보고합니다.[24] 또한 소수 기기에서 시험한 beta이므로 경보·보안 같은 중요한 알림에는 사용하지 말라고 경고합니다.[24]
다른 이용자가 QNAP NAS에서 안내 음성을 출력했다고 쓴 후속 댓글도 확인했습니다.[24] 이는 이용자 보고이며 독립적으로 재현한 시험은 아닙니다. 게시자가 적은 부정확해 보이는 하드웨어 용량은 검증하지 못해 인용하지 않았습니다.
이 사례에서 가져갈 설계 교훈은 명확합니다. 모델이 stream을 만들 수 있어도 중간 integration이 완성된 파일을 기다린다면, 그 앱의 조기 재생까지 보장되지는 않습니다.[24]
확인한 공개 모델군의 언어는 영어·프랑스어·독일어·스페인어·포르투갈어입니다.[15][53] 한국어를 요구하는 앱이라면 이 공개 모델군을 그대로 채택할 근거가 부족합니다.
ptts v0.6.0 release note에는 ko를 포함한 추가 언어 코드 처리가 등장하지만, 해당 언어로 학습된 checkpoint가 필요하다고 명시합니다.[32] runtime이 언어 코드를 받아들인다고 영어 가중치가 한국어를 말할 수 있게 되는 것은 아닙니다.[32][53]
ptts 코드는 MIT 또는 Apache-2.0이지만 모델 가중치는 별도 조건입니다.[54] Phonon 31m English는 Apache 2.0으로 상업적 이용을 허용하고, 40m 계열은 CC BY-NC 4.0으로 안내되어 있습니다.[15][53]
또한 공식 문서의 로컬 음성 재생은 로컬 voice cloning까지 뜻하지 않습니다. Transformers 문서는 speaker codec이 공개되지 않아 녹음으로부터 목소리를 복제할 수 없다고 설명하며, Gradium은 Studio에서 목소리를 만들고 파일을 내려받는 별도 절차를 안내합니다.[15][54] 실제 사람의 목소리를 복제할 때에는 당사자 동의를 얻으라고 모델 카드가 명시합니다.[53]
공개 issue #318에서는 Core ML의 짧은 prefill에 맞춰 긴 문장을 나누며 원래 없던 문장 끝이 들린다는 사용자 보고가 있었습니다.[28] 보고자는 모든 단어가 읽혀 ASR 검사만으로는 문제를 놓칠 수 있다고 설명합니다.[28]
후속 PR #326은 기본 export의 prefill을 48에서 200 token으로 늘리고 문장 묶음 처리를 조정했으며, 11월 3일 merge된 것을 확인했습니다.[52] PR은 첫 오디오와 메모리의 추가 비용, 기존 48-token bundle은 기존처럼 동작한다는 점도 설명합니다.[52]
그러나 maintainer 댓글은 release bundle의 재export를 다음 release 작업으로 구분합니다.[29] 이번 조회의 GitHub latest stable은 v0.6.0, 10월 30일 발행이었고 해당 Core ML asset의 수정 시각도 같은 날이었습니다.[32] 코드 merge를 기존 다운로드 bundle의 수정 완료로 간주하지 마세요. 이 글에서는 bundle을 내려받아 내용까지 검증하지 않았습니다.
웹 앱에서 기본 읽어주기만 필요하다면 Web Speech API부터 검토할 수 있습니다. MDN은 SpeechSynthesis가 기기에서 사용할 수 있는 voice 조회와 발화 시작·일시정지 등을 제공한다고 설명합니다.[33]
선택 기준에 대한 의견은 다음과 같습니다.
로컬 실행이 항상 더 저렴하거나 더 빠르다고 결론 내릴 수는 없습니다. 이 글의 권고는 요청당 요금만이 아니라 초기 다운로드, 기기 자원, 업데이트와 장애 대응까지 비교하자는 것입니다.
💡 🔍 검증 범위: 자료 확인일은 2026-11-06입니다. 공식 발표·기술 문서, Micdrop·ExecuTorch의 integration 문서, Gladys의 전체 공개 게시물, GitHub issue와 후속 댓글·PR·release metadata를 대조했습니다. 모델 카드는 revision
92741c5b07d085ff840e26fea8ce43110b87852f로 고정했습니다. 모델 설치·합성·청취·benchmark 재현은 수행하지 않았습니다. 공개 측정과 사용자 보고는 읽었지만 실제 안정성·우리 환경의 성능을 독립 검증한 글은 아닙니다.
Phonon에서 가져갈 핵심은 작은 모델의 수치보다 텍스트 전처리, 실행 위치, 음성 전달 방식이 최종 기능을 바꾼다는 점입니다.[15][16][24]
도입은 필요한 언어와 license를 확인하는 것부터 시작하세요. 그다음 한 실행 경로에서 첫 준비와 warm 요청을 나눠 측정하고, 숫자와 장문을 실제로 들어 보며, 문제가 나면 텍스트로 돌아갈 수 있도록 설계하는 것이 이 글의 권장 순서입니다.
[11] https://huggingface.co/blog/phonon-tts — A Closer Look at Phonon TTS — Hugging Face / Gradium
[12] https://gradium.ai/blog/release-phonon-open-weight — Open-Sourcing Phonon — Gradium official announcement
[15] https://huggingface.co/docs/transformers/model_doc/gradium_phonon_tts — Gradium Phonon TTS — Transformers technical documentation
[16] https://micdrop.dev/docs/ai-integration/provided-integrations/phonon.md — Phonon TTS in Node.js — Micdrop integration documentation
[17] https://huggingface.co/executorch-community/Phonon-31M-EN-ExecuTorch-WebGPU/raw/main/README.md — Phonon 31M for ExecuTorch WebGPU — conversion model card
[24] https://community.gladysassistant.com/t/phonon-tts-une-voix-100-locale-pour-gladys/11421.json — Phonon TTS for Gladys — complete public discussion (JSON)
[28] https://api.github.com/repos/gradium-ai/xn-ptts/issues/318 — Core ML long-sentence prosody — user report, issue 318
[29] https://api.github.com/repos/gradium-ai/xn-ptts/issues/318/comments?per_page=100&page=1 — Issue 318 — complete maintainer follow-up comments
[32] https://api.github.com/repos/gradium-ai/xn-ptts/releases/latest — ptts latest stable release and asset metadata — GitHub API
[33] https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis — SpeechSynthesis — MDN Web API reference
[52] https://api.github.com/repos/gradium-ai/xn-ptts/pulls/326 — Core ML prefill correction — merged PR 326
[53] https://huggingface.co/gradium/phonon-31m-en/raw/92741c5b07d085ff840e26fea8ce43110b87852f/README.md — Phonon 31M English — pinned model card
[54] https://raw.githubusercontent.com/gradium-ai/xn-ptts/ee395caac058950cbcabfa3785c63630942f31ed/README.md — ptts — pinned runtime README