한 문장으로 이 프로젝트가 뭘 하는지부터.
Miso TTS 8B = "글자 → 감정 실린 대화 음성" 변환기. 텍스트와 (선택적으로) 화자 번호·이전 대화를 입력하면, 그에 어울리는 24kHz 음성 파형(.wav)을 만들어 낸다. 보통의 TTS가 한 문장을 무미건조하게 읽는다면, Miso는 "누가, 어떤 맥락에서, 어떤 감정으로" 말하는지를 함께 모델링해 더 사람 같은 대화를 만든다.
일반 TTS는 대본을 받아 또박또박 읽는 오디오북 낭독기에 가깝다. 반면 Miso는 대본뿐 아니라 "방금 상대가 이렇게 말했으니, 나는 이런 톤으로 받아쳐야지"까지 계산한다. 즉 낭독기가 아니라, 대화 상황을 이해하는 연기 디렉터 + 성우 세트에 가깝다.
그래서 결과물도 "문장 하나"가 아니라, 두 화자가 주고받는 자연스러운 대화 한 토막이 나온다.
저장소에는 모델을 학습시키는 코드가 아니라 "이미 학습된 모델을 돌리는(추론) 코드"가 들어 있다. 실제 가중치는 Hugging Face의 MisoLabs/MisoTTS에서 자동으로 내려받는다. 즉 이 레포는 엔진 설계도 + 시동 키이고, 연료(가중치)는 별도 창고(HF)에서 가져오는 구조다.
TrendShift 일간 4위까지 올라온 이유 — 트렌딩의 배경.
2025~2026년은 "오픈 음성 모델 전쟁"의 해다. 글자를 읽는 건 이미 잘 되니, 경쟁의 초점이 "얼마나 사람처럼, 감정을 실어, 대화하듯 말하느냐"로 옮겨갔다. Miso는 이 흐름의 정중앙에 있다.
핵심 차별점. Miso의 입력은 text 하나가 아니라 (text, speaker, context) 세 가지다. context에는 이전 발화의 텍스트 + 실제 오디오가 함께 들어간다. 모델은 "앞 화자가 이런 톤으로 이렇게 말했다"를 듣고, 그에 맞춰 다음 대사의 억양·호흡·감정을 정한다. 예제 코드(run_misotts.py)부터가 화자 0번과 1번이 주고받는 4턴짜리 대화를 생성한다.
ElevenLabs·OpenAI TTS 같은 최고 품질 경쟁자들은 API 뒤에 숨은 폐쇄형(closed)이다. 비용·검열·데이터 유출 우려가 따라온다. 반면 Miso는 가중치를 HF에 올려, 내 서버에서 오프라인으로, 무료로, 무제한 돌릴 수 있다. 자막 더빙·게임 NPC·접근성 도구를 만드는 개발자에게 이건 큰 차이다.
짧은 prompt.wav 하나와 그 대본을 context로 넣으면, 그 목소리의 톤을 흉내 내 새 문장을 말하게 할 수 있다. 별도 파인튜닝 없이 예시 음성만으로 화자를 따라 한다(zero-shot voice cloning).
Miso는 무에서 발명한 게 아니라, Sesame AI Labs가 공개한 CSM(Conversational Speech Model) 구조를 그대로 따른다. 오디오 토크나이저(Mimi), 워터마크(SilentCipher), 생성 API(Segment/Generator)까지 CSM 생태계를 재사용한다. 검증된 레시피를 8B로 스케일업했다는 점이 신뢰를 준다.
일반 TTS = 자동응답기 안내음 — 정확하지만 영혼 없는 목소리.
Miso TTS = 라디오 드라마 녹음 현장 — 대본·상황·상대 배우의 연기를 모두 보고, 거기에 맞춰 감정을 실어 연기한다. 결과는 한 문장이 아니라 살아있는 '장면'이다.
GitHub 스타 수는 아직 적고(저장소는 거의 새것), 인기는 X(트위터) 등 소셜 멘션에서 온 '신상 화제성'이 크다. 8B 모델이라 실행 장벽(GPU)이 높고, 품질·라이선스(license: other)·상업적 사용 조건은 직접 확인이 필요하다. "트렌딩이라 무조건 좋다"가 아니라, 구조를 공부하기 좋은 최신 사례로 보는 게 맞다.
requirements.txt · pyproject.toml · 소스코드에서 뽑아낸 실제 구성.
Miso는 웹 백엔드/프론트엔드가 아니라 "딥러닝 추론 파이프라인"이다. 그래서 스택을 ⓐ 모델 코어 ⓑ 오디오 처리 ⓒ 실행·배포 세 층으로 나눠 본다.
| 구성요소 | 무엇 | 역할 |
|---|---|---|
| PyTorch 2.4 | 딥러닝 프레임워크 | 모든 신경망 연산의 기반. bfloat16 정밀도로 추론. |
| torchtune 0.4 | LLM 빌딩 블록 | Llama 3.2 구조(backbone·decoder)를 그대로 가져다 씀. |
| torchao 0.9 | 양자화/최적화 | 모델 경량화·가속을 위한 PyTorch 부속. |
| transformers 4.49 | HF 라이브러리 | Llama 3 텍스트 토크나이저 로딩. |
| bitsandbytes 0.45 | 양자화(리눅스) | 저정밀 가중치 지원(선택). Miso는 비양자화 경로도 패치해 둠. |
| 구성요소 | 무엇 | 역할 |
|---|---|---|
| Mimi (moshi 0.2.2) | 신경망 오디오 코덱 | 음성↔'오디오 토큰' 변환기. 32개 코드북, 24kHz. Miso의 입·귀. |
| torchaudio 2.4 | 오디오 I/O | .wav 읽기/쓰기, 샘플레이트 리샘플링. |
| SilentCipher | 오디오 워터마크 | 생성 음성에 사람 귀엔 안 들리는 식별 신호를 새김(AI 생성 표시). |
| 구성요소 | 무엇 | 역할 |
|---|---|---|
| uv | 초고속 패키지 매니저 | 의존성 설치·가상환경 구성을 pip보다 빠르게. uv sync. |
| Hugging Face Hub | 모델 저장소 | 8B 가중치 + Mimi + 워터마커를 자동 다운로드·캐시. |
| Python 3.10–3.12 | 런타임 | 고정 버전(.python-version = 3.10). |
| CUDA GPU | 하드웨어 | 8B 추론에 사실상 필수. CPU 폴백은 있으나 매우 느림. |
LLM은 본래 '토큰(숫자) 다음에 올 토큰'을 맞히는 기계다. 글자를 토큰으로 바꾸면 글을 생성하고, 소리를 토큰으로 바꾸면 소리를 생성한다. Mimi는 바로 그 "소리 → 숫자" 변환기다. Miso의 신경망은 결국 "다음 오디오 토큰 맞히기"를 반복하는 것뿐이다.
두 개의 트랜스포머가 한 프레임을 만든다 — models.py / generator.py 해부.
Miso의 심장은 크기가 다른 트랜스포머 두 개다. 이 "큰 두뇌 + 작은 입" 구조가 CSM 계열의 핵심 설계다.
| 이름 | 크기 | 스펙(models.py) | 하는 일 |
|---|---|---|---|
| Backbone (백본) | Llama 3.2 8B | 32층, 헤드 32, KV헤드 8(GQA), 차원 4096 | 텍스트+오디오 맥락을 읽고 프레임의 '뼈대'(코드북 0)를 예측 |
| Decoder (디코더) | Llama 3.2 300M | 8층, 헤드 24, KV헤드 6, 차원 1536 | 한 프레임 안의 나머지 31개 코드북을 순차 예측 |
Mimi는 음성을 80ms짜리 '프레임' 단위로 쪼갠다(1초 = 12.5프레임). 그리고 한 프레임은 32개 코드북의 토큰으로 표현된다. 0번 코드북은 소리의 큰 윤곽(의미·음소), 1~31번은 점점 미세한 음색·디테일을 담는다. 이게 RVQ(잔차 벡터 양자화) 방식이다.
32개 코드북을 8B 모델이 매번 32번 통째로 돌리면 너무 느리고 무겁다. 그래서 비싼 8B 백본은 프레임당 딱 한 번 돌려 가장 중요한 0번 코드북과 '맥락 요약'만 뽑고, 나머지 31겹의 디테일은 값싼 300M 디코더가 빠르게 채운다. "대가는 큰 결정만, 조수는 디테일을"이라는 분업이다.
generate_frame()은 한 프레임의 33개 토큰(텍스트1 + 오디오32) 임베딩에 마스크를 곱한 뒤 sum(dim=2)으로 더해 하나의 벡터로 만든다. 그래서 백본 입장에선 "프레임 = 토큰 1개"처럼 보여 시퀀스가 짧아지고 빨라진다.
백본은 헤드 32개에 KV헤드는 8개뿐인 GQA(그룹 쿼리 어텐션)를 쓴다. 메모리·속도를 아끼는 표준 기법. 또 생성 중 과거 계산을 KV cache에 저장하되, 디코더 캐시는 프레임마다 reset한다(한 프레임 안의 31겹만 보면 되므로).
sample_topk()은 temperature·top-k로 후보를 거른 뒤, 지수분포 난수로 나눠 argmax하는 Gumbel-max 트릭으로 샘플링한다. GPU를 멈추지 않고(no-sync) 뽑아 추론을 빠르게 한다. 기본값 temperature=0.9, topk=50.
파일 7개짜리 작고 단단한 레포 — 각 파일이 뭘 하는지.
Miso는 거대한 모노레포가 아니다. 핵심 파이썬 파일 5개 + 설정 파일들로 끝난다. 그래서 처음부터 끝까지 읽기 좋은 '교과서' 같은 코드베이스다.
| 파일 | 핵심 내용 |
|---|---|
| models.py | llama3_2_8B()/llama3_2_300M() 정의, ModelArgs 설정값, Model 클래스(generate_frame = 프레임 1개 생성의 전 과정), top-k 샘플링·인과 마스크 유틸. |
| generator.py | Segment(화자·텍스트·오디오 묶음), Generator.generate()(전체 생성 루프), 텍스트/오디오 토큰화, Mimi·워터마커 로딩, HF에서 가중치 다운로드. |
models.py = 엔진 그 자체(피스톤·실린더가 어떻게 생겼나). generator.py = 운전석(연료 넣고, 시동 걸고, 기어 바꾸며 목적지까지 운전). 엔진만 있어도, 운전석만 있어도 차는 못 간다. 둘을 함께 읽어야 그림이 완성된다.
bitsandbytes(양자화 라이브러리)를 전제로 짜여 있다. Miso는 양자화를 안 쓰는 일반 레이어에서도 동작하도록 quantize.linear 함수를 런타임에 슬쩍 바꿔치기(monkey-patch)한다. 외부 코드를 포크하지 않고 호환을 맞추는 영리한 수법이다.이 레포에서 무엇을 배울 수 있나 — 기술별 + 실습 아이디어.
가장 큰 배움. 언어모델은 본래 텍스트용이지만, 소리를 토큰으로 바꾸면 똑같은 LLM 기법으로 소리를 생성할 수 있다. Miso는 이 다리(텍스트 토큰 ↔ 오디오 토큰)를 어떻게 놓는지 보여 준다.
generator.py의 _tokenize_text_segment/_tokenize_audio를 읽고, "텍스트 토큰은 프레임의 마지막 칸, 오디오 토큰은 앞 32칸"에 어떻게 배치되는지 종이에 그려 보기.
왜 코드북이 32개나 필요한지, 0번과 31번의 역할 차이가 무엇인지 이해하면 현대 오디오 생성의 절반을 이해한 셈이다. Mimi·EnCodec·SoundStream이 모두 이 RVQ 계열이다.
Mimi로 짧은 음성을 인코딩해 토큰을 뽑고, 코드북을 1·4·16·32개만 써서 디코딩한 소리를 각각 들어 보기 → 겹을 쌓을수록 음질이 어떻게 좋아지는지 귀로 확인.
"큰 모델은 가끔, 작은 모델은 자주"라는 분업은 비용을 줄이는 강력한 패턴이다. 음성뿐 아니라 영상·코드 생성에도 응용된다.
generate_frame()에 print()를 넣어, 한 프레임을 만들 때 백본은 몇 번, 디코더는 몇 번 호출되는지 세어 보기. (예상: 백본 1, 디코더 31)
바닥부터 트랜스포머를 짜지 않고, torchtune.models.llama3_2를 불러와 tok_embeddings·output을 nn.Identity()로 갈아끼우는 기법. "검증된 블록을 가져와 입출력만 바꾼다"는 실전 엔지니어링 감각을 배운다.
모든 출력에 들리지 않는 워터마크를 기본으로 새기는 설계는, AI 음성 악용(사칭·사기)에 대한 현실적 방어다. watermarking.py의 watermark()/verify() 쌍을 보면 "삽입 → 검출"의 전체 사이클을 알 수 있다.
README도 강조한다: 다른 앱에 Miso를 넣을 땐 자기만의 비밀 워터마크 키를 쓰고 공개하지 말 것. 키가 공개되면 누구나 "이건 내 모델 출력이 아니다"라고 위조하거나, 추적을 회피할 수 있다.
"내 컴퓨터에서 돌아갈까?"를 먼저 따져 보자.
| 항목 | 요구/권장 | 설명 |
|---|---|---|
| GPU | CUDA(NVIDIA) GPU 사실상 필수 | 기본 추론은 torch.bfloat16. CPU 폴백은 있지만 8B라 매우 느려 실사용 불가에 가깝다. |
| VRAM | 대략 16GB+ 권장 | 8B를 bf16로 올리면 가중치만 ~16GB. 여유 있게 24GB(예: RTX 4090/3090)면 편하다. (정밀도·구현에 따라 달라짐) |
| 디스크 | 수십 GB | 8B 가중치 + Mimi + 워터마커가 HF 캐시로 내려온다. |
| Python | 3.10 ~ 3.12 | .python-version은 3.10 고정. uv sync --python 3.10 권장. |
| OS | 리눅스 우선 | bitsandbytes는 리눅스에서만 설치(설정 조건부). macOS는 MPS의 float64 한계로 CPU로 폴백. |
| 네트워크 | 최초 1회 필요 | 가중치·코덱·워터마커 다운로드 때문. 이후엔 캐시 재사용으로 오프라인 가능. |
예제는 cuda 없으면 cpu로 떨어지게 짜여 있지만, 8B를 CPU로 돌리면 한 문장에 수 분~수십 분이 걸릴 수 있다. GPU 없는 환경이면 클라우드 GPU(런팟·코랩 등)나 misolabs.ai의 데모를 먼저 써 보는 편이 현실적이다.
난이도별로. 위에서 아래로 갈수록 어렵다.
레포를 클론하고 uv sync --python 3.10 → uv run python run_misotts.py 실행. full_conversation.wav가 생기는 걸 확인하고 들어 본다. (GPU 환경 전제)
run_misotts.py의 conversation 리스트를 내가 쓴 대사로 교체하고, speaker_id를 0/1로 번갈아 줘서 두 사람 대화를 만들어 본다. max_audio_length_ms도 바꿔 보기.
README의 "Prompted generation" 예제를 따라, 짧은 prompt.wav + 그 대본을 Segment로 넣어 context를 구성. 그 목소리 톤으로 새 문장을 말하게 해 본다.
watermarking.py의 CLI(check_audio_from_file)로 내가 만든 .wav가 "Watermarked"로 나오는지 확인. 그다음 일반 음성 파일을 넣어 "Not watermarked"가 나오는지 대조한다.
generate_frame()과 generate()에 타이머·카운터를 심어, 프레임당 백본/디코더 호출 횟수와 소요 시간을 측정. temperature·topk를 바꿔 가며 음질과 속도의 트레이드오프를 그래프로 그려 본다.
set_num_codebooks를 만져 직접 실험.Miso를 발판 삼아 "음성 AI"를 제대로 파고드는 4주 코스.
| 주차 | 주제 | 핵심 학습 + 산출물 |
|---|---|---|
| 1주차 | 오디오 토큰의 세계 | 샘플링·STFT·멜스펙트로그램 기초 → 신경망 코덱(EnCodec/Mimi) 개념. 산출물: 음성을 토큰으로 인코딩→디코딩하는 노트북. |
| 2주차 | RVQ & 멀티 코드북 | 잔차 양자화 원리, 코드북 수 vs 음질 실험. 산출물: 코드북 수별 음질 비교 리포트. |
| 3주차 | CSM 아키텍처 | Sesame CSM 논문/블로그 + Miso models.py 정독, 백본·디코더 분업 재현. 산출물: 아키텍처 다이어그램 + 코드 주석본. |
| 4주차 | 응용 & 책임 | 음성 클로닝·대화 맥락 조건화 실험, 워터마킹·딥페이크 윤리. 산출물: 미니 대화 더빙 데모 + 윤리 체크리스트. |
코덱(소리↔토큰)을 먼저 이해해야 그 위의 LLM(토큰 생성)이 보인다. "코덱 → RVQ → 트랜스포머 → 응용" 순서를 지키면, Miso뿐 아니라 VALL-E·Bark·VibeVoice 같은 다른 음성 모델도 같은 렌즈로 읽힌다.
Miso와 같은 "오픈 음성 모델" 계보를 함께 보면 좌표가 잡힌다: Sesame CSM(원조 구조), Kyutai Moshi/Mimi(코덱 출처), VALL-E(코덱 언어모델의 시초), Bark·XTTS·VibeVoice·Kokoro(다양한 오픈 TTS). 이 문서 폴더의 VibeVoice·VoxCPM·stable-audio-3 딥다이브와 함께 읽으면 비교가 쉽다.
레포에 등장하는 용어를 한 곳에 모았다.
원문으로 더 깊이 들어가고 싶다면.