supertone-inc/supertonic은 텍스트를 음성으로 읽어 주는(Text-to-Speech, TTS) 모델을 내 컴퓨터·휴대폰·브라우저에서 직접 돌리는 오픈소스 저장소다. 핵심은 세 가지 — ① 모델이 아주 작다(약 99M 파라미터), ② 클라우드가 필요 없다(CPU만으로 실시간), ③ 31개 언어를 하나의 모델로 말한다. 저장소가 내건 한 줄은 이것 — "Lightning-Fast, On-Device, Multilingual TTS — running natively via ONNX."(번개처럼 빠른, 온디바이스, 다국어 TTS — ONNX로 네이티브 실행).
가장 먼저 풀어야 할 오해 — supertonic은 서버에 요청을 보내는 API가 아니다. ElevenLabs·OpenAI TTS·Gemini TTS처럼 "인터넷 너머 GPU 서버가 대신 만들어 주는" 방식이 아니라, 모델 파일 몇 개를 내 기기에 두고 그 자리에서 직접 계산한다. 그래서 비행기 모드의 전자책 단말기(Onyx Boox)에서도, 라즈베리파이에서도 소리가 난다. 이렇게 서버 없이 기기 안에서 AI를 돌리는 걸 온디바이스(on-device) 추론이라 한다.
.onnx). ONNX Runtime은 그 파일을 Python이든 Swift든 Rust든 브라우저든 똑같이 로드해 실행해 주는 엔진이다. supertonic이 "11개 언어에서 동일하게 동작"하는 비결이 바로 이것 — 모델은 .onnx 4개로 고정하고, 언어별로는 그 파일을 로드해 입력·출력 텐서를 맞춰 주는 얇은 코드만 다시 쓴다.클라우드 TTS가 멀리 있는 거대한 콘서트홀에 전화로 곡을 신청하는 것이라면(연결이 끊기면 아무 소리도 못 듣는다), supertonic은 내 주머니 속 작은 오르골이다. 인터넷이 없어도, 전기(GPU)를 많이 안 써도, 태엽만 감으면(CPU만으로) 그 자리에서 소리를 낸다.
게다가 이 오르골은 특별하다 — 발음기호라는 "번역 악보"를 거치지 않고, 세계 어느 나라 글자든 유니코드 숫자 그대로 받아 연주한다. 그래서 한국어·영어·독일어·터키어… 31개 언어를, 그리고 "언어를 특정하지 않는" 모드(na)까지 하나의 작은 통 안에서 소화한다.
supertonic이 8개월 만에 별 1.3만+를 모으며 트렌딩에 오른 이유는 "또 하나의 TTS"여서가 아니다. 상용 클라우드 TTS의 벽(비용·프라이버시·오프라인 불가)과, 기존 오픈 TTS의 약점(영어 편중·기호 오독)을 동시에 겨냥했기 때문이다. 핵심 셀링 포인트는 "작은 모델로 온디바이스", "발음기 없이 다국어", 그리고 의외로 "숫자·통화·전화번호를 정확히 읽는 텍스트 정규화"다.
| 포인트 | 내용 |
|---|---|
| 정체 | 온디바이스 멀티링구얼 TTS. Supertonic 3 모델(≈99M)을 ONNX Runtime으로 구동, 텍스트를 44.1kHz 16-bit WAV로. 11개 언어 바인딩(Py·Node·Web·Java·C++·C#·Go·Swift·iOS·Rust·Flutter) 예제 완비. |
| 차별점 ① | 모델이 작다(≈99M). 0.7B~2B급 오픈 TTS의 일부 크기(참고: Kokoro ~82M과 동급). 다운로드·콜드스타트·메모리에서 유리 → 엣지·모바일 친화. |
| 차별점 ② | 발음기(G2P) 없음. espeak-ng 같은 발음기호 변환을 안 쓰고 유니코드 글자를 직접 넣는다 → 언어 확장이 쉬워 31개 언어 + 언어무관 na 모드. |
| 차별점 ③ | 텍스트 정규화가 강하다. $5.2M, (212) 555-0142, 2.3h, 30kph 같은 통화·전화번호·기술단위를 별도 전처리 없이 정확히 발음(README 비교표에서 ElevenLabs/OpenAI/Gemini가 ❌인 케이스). |
| 제작자 · 라이선스 | Supertone Inc.(한국 음성 AI 기업, supertone.ai). 코드 MIT · 모델 OpenRAIL-M — 라이선스가 이원화돼 있으니 상업적 사용 시 주의(뒤에서 상술). |
supertonic의 서사는 "큰 모델을 클라우드에서 돌려야 좋은 음성이 나온다"는 통념에 대한 반례다. README는 저사양 기기 사례를 전면에 내세운다 — 라즈베리파이 실시간, Onyx Boox 전자책 단말기(비행기 모드)에서 평균 RTF 0.3배. 정확도 벤치마크(Minimax-MLS-test, WER/CER)에서도 VoxCPM2·OmniVoice·Qwen3-TTS 같은 대형 모델과 경쟁 범위 안에 든다(예: 영어 WER 2.06, 독일어 0.86, 한국어 CER 3.26).
대부분의 오픈 TTS(Piper 등)는 espeak-ng 같은 G2P(자소→음소) 엔진으로 글자를 발음기호로 바꾼 뒤 모델에 넣는다. 이 방식은 발음이 정밀하지만, 언어를 늘리려면 그 언어의 발음 규칙 사전을 새로 붙여야 한다. supertonic은 이 단계를 통째로 버리고 유니코드 글자를 그대로 숫자(코드포인트)로 바꿔 모델에 넣는다. 발음의 부담을 모델이 데이터로 학습해 떠안는 대신, 언어 확장은 극도로 쉬워졌다 — 그래서 31개 언어, 나아가 언어를 지정하지 않는 na 모드까지 가능하다.
supertonic이 학습 표본으로 훌륭한 진짜 이유는 동일한 4개 ONNX 모델을 11개 언어에서 로드해 돌리는 완성된 예제가 한 저장소에 모여 있기 때문이다. Python 원본(py/helper.py)을 기준으로, 같은 파이프라인(텍스트 전처리 → 유니코드 토크나이즈 → 4개 세션 실행 → 플로우매칭 루프 → WAV 저장)을 Swift·Rust·Go·Java·C++·C#·브라우저까지 그대로 재현했다. "같은 신경망을 여러 플랫폼에 이식하는 법"을 언어별로 비교하며 배울 수 있는 드문 자료다.
냉정히 보자. ① 모델 라이선스는 코드와 다르다. 코드는 관대한 MIT지만 모델 가중치는 OpenRAIL-M(용도 제한 조항이 있는 Responsible-AI 라이선스)이다. "전부 MIT"로 오해하면 안 된다. ② 공개 가중치는 고정 화자(fixed-voice) 전용이고, 임의 목소리 복제(zero-shot voice cloning)나 다양한 상업용 프리셋은 유료 Supertone Play/API로 안내된다. ③ 일부 언어는 약하다(예: 베트남어·일본어 CER이 상대적으로 높음). ④ 벤치마크 수치는 제작사 자체 측정이니 참고로만. 즉 "만능 무료 음성 생성기"가 아니라 "작고 이식성 좋은, 잘 만든 온디바이스 TTS 엔진(고정 화자)"로 보는 게 정확하다.
supertonic의 스택은 두 층으로 나눠 봐야 한다. ① 모델 층 — 학습된 신경망이 4개의 .onnx 파일로 쪼개져 있고, 언어 불문 이 파일들이 "진짜 두뇌"다. ② 바인딩 층 — 각 언어(Python·Swift·Rust…)가 그 파일들을 로드해 입출력을 맞춰 주는 얇은 코드다. Python 원본 py/helper.py가 기준 구현이고, 나머지 10개는 이걸 포팅한 것이다(전부 스텁 아닌 완전 구현, 합쳐 약 1만 줄).
supertonic은 "발음기호 → 멜 스펙트로그램 → 보코더"라는 전통 구조가 아니라, 잠재 공간에서 플로우매칭(flow-matching)으로 음성을 그려 내는 구조다(SupertonicTTS 논문). 실행 시 로드되는 파일은 다음과 같다.
| 파일 | 역할 · 입력 → 출력 |
|---|---|
| duration_predictor.onnx | 발화 총 길이(초)를 예측. (text_ids, style_dp, text_mask) → dur. dur/speed로 말 속도 조절 |
| text_encoder.onnx | 텍스트를 임베딩으로. (text_ids, style_ttl, text_mask) → text_emb |
| vector_estimator.onnx | 플로우매칭 속도장(velocity field) 추정기. ODE 적분을 위해 total_step번 반복 호출되는 핵심 |
| vocoder.onnx | 잠재 표현(latent) → 파형(wav). 44.1kHz. ISTFT가 그래프 내부에 포함돼 호스트 쪽 FFT가 불필요 |
| 보조 자산 | tts.json(설정: sample_rate=44100 등) · unicode_indexer.json(글자→토큰 매핑) · voice_styles/*.json(화자 임베딩, M1–M5·F1–F5 10종) |
vector_estimator.onnx(속도장)이고, 몇 걸음을 걸을지가 NFE(Number of Function Evaluations) = total_step이다(기본 8, 범위 5~12). 걸음을 늘리면 품질↑·속도↓, 줄이면 반대. iOS 예제는 이 값을 그대로 nfe 파라미터로 노출한다. "학습 epoch"가 아니라 추론 시 반복 횟수라는 점이 함정이다.각 폴더가 하나의 언어/런타임 예제다. 모두 동일한 4개 ONNX를 로드하지만, 의존성·실행 제공자(EP)는 제각각이다.
| 바인딩 | 런타임 · 버전 · 특기 |
|---|---|
| Python (py/) | onnxruntime 1.23.1 · numpy·soundfile·librosa · uv 관리. 기준(원본) 구현 |
| Node.js (nodejs/) | onnxruntime-node ^1.19.2 · Node≥16 · ESM |
| Web (web/) | onnxruntime-web ^1.17.0 · WebGPU→WASM 폴백 · Vite ^5. 브라우저 데모 |
| Java (java/) | onnxruntime 1.23.1 · Jackson · JTransforms · JDK 11 · Maven shade |
| C++ (cpp/) | 시스템 ONNX Runtime C++ API · C++17 · OpenMP · -O3 -ffast-math · CMake≥3.15 |
| C# (csharp/) | Microsoft.ML.OnnxRuntime 1.20.1 · .NET 9 · System.Text.Json |
| Go (go/) | yalue/onnxruntime_go 1.11.0 · ORT C 라이브러리 필요 · go 1.21 |
| Swift (swift/) | onnxruntime-swift-package-manager from 1.16.0 · macOS v13 CLI |
| iOS (ios/) | OnnxRuntimeBindings(pod) · SwiftUI 앱 · XcodeGen(project.yml) |
| Rust (rust/) | ort 2.0.0-rc.7 · ndarray · hound(WAV) · clap · rayon |
| Flutter (flutter/) | flutter_onnxruntime ^1.6.0 · Dart ^3.5.0 · just_audio (레포엔 macOS 러너만) |
여러 바인딩에 FFT 라이브러리(Node의 fft.js, Rust의 rustfft, Java의 JTransforms, Go의 go-dsp, Python의 librosa)가 딸려 있어 "STFT/멜 스펙트로그램을 직접 계산하나?"라고 오해하기 쉽다. 하지만 현재(v3) 추론 경로에서는 대부분 미사용이다 — vocoder.onnx가 파형을 직접 뱉고 ISTFT를 그래프 안에서 처리하기 때문이다. 특히 nodejs/README의 "Preprocessor STFT/Mel" 설명은 오래된(stale) 문서다.
supertonic의 핵심 질문은 하나다 — "발음기호도 없이, 어떻게 텍스트가 소리가 되나?" 답은 6단계 파이프라인이다. Python 원본 py/helper.py를 기준으로 흐름을 그리면 이렇다.
가장 특징적인 부분이다. 보통 TTS는 "cat"을 /kæt/ 같은 발음기호로 바꿔 넣지만, supertonic은 글자 하나하나를 유니코드 번호(ord(char), 16비트)로 바꾼 뒤 unicode_indexer.json으로 토큰 id에 매핑한다. 발음 규칙 사전이 없으니 새 언어를 붙이는 비용이 거의 없다 — 그 언어의 글자 코드포인트만 인덱서에 있으면 된다. 언어는 <ko>...</ko>처럼 태그로 감싸 알려 주고, 특정 언어를 지정하기 어려우면 na(language-agnostic) 모드를 쓴다.
발음기(G2P)를 쓰는 TTS는 "모든 나라 글자를 한 번 국제음성기호(IPA)로 번역한 뒤 읽는 성우"다. 정확하지만, 새 언어를 맡기려면 그 언어의 번역 규칙을 성우에게 통째로 가르쳐야 한다. supertonic은 다른 성우다 — 글자 모양(코드포인트)을 그대로 보고 소리를 떠올리도록 방대한 데이터로 훈련된 성우다. 번역 사전이 필요 없으니, 새 언어의 글자만 보여 주면 바로 흉내 낸다. 대신 발음 정밀도는 "얼마나 잘 배웠나(데이터·모델)"에 달려 있다.
목소리 정체성(화자)은 voice_styles/M1.json 같은 파일에 두 개의 임베딩으로 들어 있다 — style_dp(duration predictor용)와 style_ttl(text-to-latent용). 즉 "얼마나 빠르게/길게 말하나"와 "어떤 음색으로 말하나"를 서로 다른 경로에 각각 주입한다. 프리셋은 남성 5·여성 5(M1–M5, F1–F5) 총 10종이다. 임의의 새 목소리를 만드는 voice cloning은 이 오픈 레포에 없고, 외부 Voice Builder나 유료 API를 거쳐 이 JSON을 얻는 구조다.
4단계에서 무작위 노이즈 xt를 만든 뒤, 5단계에서 vector_estimator.onnx를 total_step번 반복 호출해 노이즈를 점점 "진짜 음성 잠재값"으로 밀어 간다. 이게 ODE(상미분방정식) 적분이다 — 매 스텝 속도장을 구해 한 걸음 이동한다. 이 반복 횟수(NFE)가 유일한 품질/속도 손잡이다. 논문이 쓰는 기법들 — LARoPE(Length-Aware RoPE, 텍스트-음성 정렬), Self-Purifying Flow Matching(노이즈 라벨에도 견고한 학습), RobustSpeechFlow — 이 루프의 안정성·정렬을 담당한다.
# py/helper.py — 플로우매칭 추론 루프(요지)
xt, latent_mask = sample_noisy_latent(dur) # 노이즈에서 출발
for step in range(total_step): # NFE 회 반복(기본 8)
xt = vector_estimator.run(
noisy_latent=xt, text_emb=text_emb, style=style_ttl,
text_mask=text_mask, latent_mask=latent_mask,
current_step=step, total_step=total_step,
)
wav = vocoder.run(latent=xt) # 잠재값 → 파형(ISTFT 내장)
많은 TTS는 모델이 스펙트로그램(주파수 그림)을 내놓고, 호스트 코드가 역-STFT(ISTFT)로 파형을 복원한다. supertonic의 vocoder.onnx는 ISTFT를 그래프 안에 넣어 wav_tts(파형)를 바로 출력한다. 덕분에 각 언어 바인딩은 별도 FFT 라이브러리 없이도 오디오를 얻는다(위 "함정"에서 본 fft.js 등이 실은 잉여인 이유). 이런 "전처리·후처리를 모델 그래프 안으로 흡수"하는 설계는 이식성을 극대화하는 현대적 패턴이다.
긴 텍스트는 한 번에 합성하지 않는다. chunk_text()가 기본 300자(한국어·일본어는 120자) 단위로 잘라 청크별로 합성한 뒤 0.3초 무음을 사이에 넣어 이어 붙인다. 언어별 청크 길이가 다른 건 문자당 정보 밀도(CJK가 높음) 때문이다. 배치 모드(--batch)를 켜면 자동 청킹이 꺼지므로, 입력 개수와 출력 개수가 어긋나지 않게 주의해야 한다.
py/가 기준 구현 · 나머지 10개 폴더는 언어별 포팅 · 모델은 별도 다운로드저장소는 의외로 단출하다(파일 115개). 뼈대는 "언어별 폴더 11개 + 공용 문서·테스트"다. 각 언어 폴더는 거의 같은 골격 — helper.*(파이프라인 본체) + example_onnx.*(실행 예제) + 매니페스트다. Python py/helper.py를 읽고 다른 언어를 대조하면 "같은 로직을 이 언어에선 이렇게 쓰는구나"가 한눈에 들어온다.
읽는 순서는 이렇다. ① README.md(벤치마크·언어·라이선스 지도) → ② py/helper.py(전처리·토크나이즈·4개 세션·플로우매칭 루프의 원본) → ③ py/example_onnx.py(CLI 진입점, 인자 파싱) → ④ 관심 언어의 helper.*를 Python과 대조(예: rust/src/helper.rs, swift/Sources/Helper.swift) → ⑤ web/main.js(브라우저 WebGPU 폴백) 또는 ios/ExampleiOSApp(모바일 통합). 한 언어만 깊게 읽고, 나머지는 "차이점"만 훑는 것이 효율적이다.
.gitignore가 assets/·*.onnx를 제외하므로, git clone만 하면 모델이 없어 각 assets 심볼릭 링크가 깨진 상태다. HuggingFace에서 Git LFS로 모델을 받아 assets/로 넣어야 한다(git clone https://huggingface.co/Supertone/supertonic-3 assets). 참고로 pip용 SDK(supertonic-py)는 첫 실행 시 자동 다운로드하지만, 그건 이 저장소의 py/와 다른 별도 레포다(뒤 함정 참고).
supertonic이 학습 표본으로 훌륭한 이유는 ONNX Runtime 크로스플랫폼 추론, 플로우매칭 TTS 구조, 발음기 없는 토크나이제이션, 온디바이스 최적화, 그리고 "같은 모델의 11개 언어 이식"이 한 저장소에 모여 있기 때문이다. 관심사별로 배울 것을 짚어 보자.
이 저장소의 최대 교육 가치다. 동일한 4개 .onnx를 Python·Node·브라우저·Java·C++·C#·Go·Swift·iOS·Rust·Flutter에서 로드해 입출력 텐서 이름 계약(text_ids·style_*·…·wav_tts)이 언어 불문 동일하다는 걸 눈으로 확인할 수 있다. "학습은 PyTorch, 배포는 ONNX"라는 실무 패턴, 그리고 실행 제공자(EP: CPU/WebGPU/WASM) 추상화를 배운다.
멜 스펙트로그램+보코더의 전통을 벗어나, 잠재 공간에서 속도장을 반복 적분(ODE)해 음성을 생성하는 최신 구조를 코드로 본다. 디퓨전/CNF(연속 정규화 흐름)의 감을 잡고, "스텝 수(NFE)와 품질의 트레이드오프"를 실측할 수 있다. 학술 논문(SupertonicTTS 등)과 실제 추론 코드를 함께 대조하기 좋은 자료다.
helper.py의 유니코드 코드포인트 방식은 "발음 정밀도 vs 언어 확장성"이라는 설계 트레이드오프를 생생히 보여 준다. espeak 기반(Piper)과 비교하며 "왜 어떤 프로젝트는 발음기를 쓰고 어떤 건 안 쓰는가"를 이해하게 된다.
작은 모델(99M) 설계, C++의 -O3 -ffast-math+OpenMP, 그래프 슬리밍(OnnxSlim), ISTFT를 그래프에 흡수해 후처리를 없앤 것까지 — "저사양 기기에서 실시간을 뽑기 위한" 실전 최적화가 곳곳에 있다. RTF를 직접 측정해 보며 최적화 효과를 체감할 수 있다.
ios/는 SwiftUI 앱에서 번들 리소스로 .onnx를 로드하고 NFE를 nfe 파라미터로 노출하는 통합 예시, web/main.js는 onnxruntime-web의 WebGPU→WASM 폴백 전략과 대용량 모델 서빙(Vite)을 보여 준다. "AI를 앱·웹에 실제로 넣는 법"의 축소판이다.
cd py && uv run example_onnx.py로 첫 WAV를 만들어 본다. ② --lang·--voice-style을 바꿔 한국어/영어, 남/여 화자를 비교한다. ③ --total-step을 5·8·12로 바꿔 "스텝 수 ↔ 품질 ↔ 생성 시간" 관계를 귀와 시계로 확인한다. 이 세 가지만 해 봐도 "이 엔진이 안에서 뭘 하는지" 손에 잡힌다.supertonic은 특별한 가속기가 필요 없다. 모든 예제가 기본적으로 CPU 실행 제공자(CPUExecutionProvider)로 돈다. 오히려 "저사양에서 얼마나 잘 도는가"가 셀링 포인트다. 정리하면 다음과 같다.
| 항목 | 요구 / 설명 |
|---|---|
| 가속기 | GPU 불필요 — 전 예제 기본 CPU. Python --use-gpu는 현재 미구현(예외 발생), 브라우저만 WebGPU 가속 |
| 검증된 기기 | 데스크탑 · 모바일 · 브라우저 · 라즈베리파이(실시간) · Onyx Boox 전자책(비행기 모드, RTF 0.3배) |
| 모델 크기 | 약 99M 파라미터(4개 ONNX 합계). 개별 파일 크기는 HuggingFace에서 확인(저장소 미포함) |
| OS | macOS · Linux · Windows(Py·Node·Java·C++·C#·Go·Rust) · iOS 네이티브 · macOS(Swift CLI·Flutter) · 브라우저 |
| 실행 제공자(EP) | CPUExecutionProvider(기본) · WebGPU/WASM(web). iOS의 CoreML EP는 예제에 미배선(기본 CPU) |
| 출력 | 44.1kHz 16-bit PCM WAV (+ 샘플별 duration 정보) |
| 모델 취득 | HuggingFace Supertone/supertonic-3를 Git LFS로 assets/에 clone(코드와 별도) |
서버·GPU·API 키가 전혀 필요 없다는 건 사실이다. 다만 실제로 돌리려면 ① 모델(.onnx)을 HuggingFace에서 받아 assets/에 넣고, ② 쓰려는 언어의 툴체인(Python+uv / Node / .NET 9 / JDK 11 / Rust / Xcode 등)을 갖춰야 한다. 저사양 기기에서도 돌지만, 스텝 수(NFE)를 올리면 그만큼 느려지므로 기기 성능에 맞춰 --total-step을 조절하는 게 핵심이다.
HuggingFace에서 모델을 assets/로 clone(Git LFS)한 뒤, cd py && uv sync && uv run example_onnx.py로 results/*.wav를 만들어 재생한다. "텍스트가 실제 파형이 되어 나오는" 전 과정을 눈과 귀로 확인한다. 목표: 온디바이스 TTS 추론의 최소 왕복을 체감.
--lang ko·--text "한국어 문장"·--voice-style F1.json으로 언어와 화자를 교체하고, 언어를 지정하지 않는 lang="na" 모드와 비교한다. 남/여 프리셋 10종(M1–M5·F1–F5)의 음색 차이를 들어 본다. 목표: "발음기 없는 다국어"와 화자 임베딩의 효과를 체험.
--total-step을 5·8·12로 바꿔 가며 같은 문장의 음질과 생성 시간을 비교한다. --speed도 0.9~1.5로 바꿔 duration predictor의 효과를 관찰한다. 목표: 플로우매칭의 "스텝 수 ↔ 품질 ↔ 속도" 트레이드오프를 정량적으로 이해.
생성 시간 ÷ 오디오 길이로 RTF를 계산해 출력하는 작은 래퍼를 짠다(helper.py의 타이머 활용). 청크 모드·배치 모드, 짧은 문장 vs 장문에서 처리량이 어떻게 달라지는지 표로 정리한다. 목표: 온디바이스 성능을 스스로 벤치마크하는 습관.
Python TextToSpeech를 FastAPI로 감싸 OpenAI 호환 /v1/audio/speech 엔드포인트를 만들어 본다(공식 supertonic serve 재현). 여유가 되면 rust/나 go/ 예제를 참고해 단일 바이너리 데몬으로 포팅한다. 목표: "온디바이스 엔진을 서비스로 만드는" 실전 통합.
| 주차 | 주제 · 학습 목표 |
|---|---|
| 1주차 신경망 배포 · ONNX | 학습과 배포의 분리. PyTorch 모델을 .onnx로 내보내고 ONNX Runtime으로 로드·실행하는 법, 입출력 텐서 이름 계약, 실행 제공자(EP) 개념. 작은 분류 모델을 직접 export해 Python·브라우저에서 같은 결과를 내 본다. |
| 2주차 TTS 파이프라인 | 텍스트가 소리가 되기까지. 텍스트 정규화, 토크나이제이션(G2P vs 유니코드 방식), 어쿠스틱 모델·보코더, 그리고 flow-matching/디퓨전 생성. supertonic py/helper.py를 줄 단위로 읽고 Piper(espeak)와 구조를 비교. |
| 3주차 온디바이스 최적화 | 저사양에서 실시간 뽑기. 양자화(quantization)·그래프 슬리밍, EP별 성능(CPU/WASM/WebGPU/CoreML), RTF 측정, C++ 컴파일 최적화·OpenMP. NFE·청킹으로 품질/지연을 조절하는 실험 설계. |
| 4주차 크로스플랫폼 · 서비스화 | 여러 플랫폼에 얹기. 같은 모델을 Swift/iOS·Flutter·브라우저에 이식, 스트리밍·큐잉, HTTP/OpenAI 호환 서버로 노출. supertonic의 11개 바인딩을 "이식 패턴 카탈로그"로 삼아 자신의 모델을 배포해 본다. |
.onnx)과, 이를 어느 언어/플랫폼에서든 실행하는 엔진. supertonic이 11개 언어에서 동일하게 도는 비결.ISTFT(역-STFT)를 그래프에 내장해 파형을 직접 출력한다.speed 인자로 말 속도를 조절하는 지점이다.ord(char)(유니코드 번호)로 바꾼 뒤 unicode_indexer.json으로 토큰 id에 매핑. 발음 사전 없이 다국어를 처리하고 na(언어무관) 모드를 가능케 하는 핵심.style_dp(길이)·style_ttl(음색) 두 개를 voice_styles/*.json에 두고 서로 다른 경로에 주입. 프리셋 10종.<laugh>·<breath>·<sigh> 같은 태그를 넣어 뉘앙스를 주는 기능(v3 신규, 10종). lang="na"는 특정 언어를 지정하지 않는 언어무관 모드.| 도구 | supertonic과의 관계 |
|---|---|
| Piper | 가장 익숙한 오픈 온디바이스 TTS. 단 espeak-ng 발음기(G2P) 기반·영어권 중심 vs supertonic은 발음기 없이 유니코드·31개 언어 |
| Kokoro (~82M) | 비슷한 소형 온디바이스 모델. supertonic(≈99M)과 크기·지향이 가장 가까운 편 |
| Coqui XTTS · VoxCPM | 훨씬 큰 모델 + voice cloning 강점. supertonic은 작고 빠르지만 오픈판은 고정 화자 |
| ElevenLabs · OpenAI TTS · Gemini TTS | 클라우드 API(품질↑, 유료·온라인). supertonic은 반대편의 완전 온디바이스·무료·오프라인 |
저장소 · 제품
· GitHub: github.com/supertone-inc/supertonic (MIT 코드 · 별 13,242 · 최신 커밋 2026-05-22)
· 모델(HuggingFace, OpenRAIL-M): huggingface.co/Supertone/supertonic-3 · 데모 Space
· pip SDK(별도 레포): supertonic-py (pip install supertonic, 모델 자동 다운로드)
· 제작사·제품: supertone.ai · Play · 오디오 샘플 supertonic3.github.io
핵심 파일(클론 후)
· py/helper.py — 전처리·유니코드 토크나이즈·4개 세션·플로우매칭 루프(기준 구현)
· py/example_onnx.py — CLI 진입점(인자 파싱)
· rust/src/helper.rs · swift/Sources/Helper.swift — 대조용 포팅 예
· web/main.js — 브라우저 WebGPU→WASM 폴백
· ios/ExampleiOSApp/ — SwiftUI 모바일 통합
배경 지식 · 논문
· ONNX Runtime 문서 — 크로스플랫폼 추론
· SupertonicTTS arXiv:2503.23108 · LARoPE 2509.11084 · Self-Purifying FM 2509.19091
· Piper · Kokoro — 비교용 오픈 TTS
① 라이선스 이원화 — 코드는 MIT지만 모델 가중치는 OpenRAIL-M(용도 제한). 오픈판은 고정 화자 전용이고 voice cloning·다양 프리셋은 유료 Play/API. ② 모델은 저장소에 없다 — .onnx는 gitignore, HuggingFace에서 Git LFS로 별도 다운로드. ③ 발음기 없음 — 유니코드 코드포인트 방식(espeak 아님). ④ 예제는 GPU 미지원 — 기본 CPU, --use-gpu는 예외 발생, 브라우저만 WebGPU. ⑤ 레포 둘 혼동 — 이 저장소=11개 언어 예제, supertonic-py=pip SDK(자동 다운로드·serve). pip install supertonic은 이 저장소의 py/가 아니다. ⑥ 버전-of-truth — main=Supertonic 3(99M·31언어·태그10), v2(66M·5언어)는 release/supertonic-2 브랜치. 또 total_step=NFE(추론 반복, epoch 아님)이고, vocoder가 파형을 직접 뱉으므로 딸려 온 FFT 라이브러리는 대부분 잉여다.