CosyVoice3
Mac에서 MLX로 CosyVoice3를 로컬 실행해 9개 언어의 음성을 합성하고 짧은 녹음으로 목소리를 복제하세요. 기본 음성, 복제 음성, 스타일 제어 예제를 듣고 참조 오디오와 정확한 전사문으로 복제를 시도할 수 있습니다.
오디오 샘플 · CLI로 음성 복제하기 · 지원 언어 · 5개 언어 음성 복제 비교와 측정 방법
오디오 샘플
기존 기본 음성, Kokoro af_heart에서 복제한 음성, 스타일 제어 예제를 들을 수 있습니다. 아래 CLI 예제는 별도의 FLEURS 참조 음성을 사용합니다.
고정 seed로 생성한 8-bit CosyVoice3 합성.
Kokoro af_heart 참조 클립에서 복제한 CosyVoice3 샘플.
--cosy-instruct로 밝고 들뜬 톤을 생성.
CLI로 음성 복제하기
참조 음성을 reference.wav로 저장하세요. 명령에는 녹음의 정확한 전사문이 포함됩니다. 자신의 음성 샘플을 쓰려면 녹음과 전사문을 모두 바꾸세요.
speech speak "Hello from the cloned voice." \
--engine cosyvoice \
--cosyvoice-variant bf16 \
--voice-sample reference.wav \
--cosy-reference-transcript "One can only wonder what the keyboard will become when something newer comes along." \
--seed 42 \
--output clone.wav
CosyVoice 3와 3.5 제공 상태
이 가이드와 Soniqo 런타임은 공개된 Fun-CosyVoice3-0.5B(3.0) 계열을 지원합니다. 공식 오픈소스 저장소는 현재 Fun-CosyVoice3-0.5B-2512를 포함한 3.0을 공개·문서화하며 CosyVoice 3.5 가중치나 추론 코드는 제공하지 않습니다. 별도의 cosyvoice-v3.5-plus 이름은 Alibaba Cloud Model Studio의 호스팅 API 모델 ID이며 이 저장소에서 내려받을 수 있는 checkpoint가 아닙니다. 따라서 Soniqo는 로컬 3.5 지원을 표방하지 않습니다.
지원 언어
| 언어 | 코드 |
|---|---|
| 중국어 | chinese |
| 영어 | english |
| 일본어 | japanese |
| 한국어 | korean |
| 독일어 | german |
| 스페인어 | spanish |
| 프랑스어 | french |
| 이탈리아어 | italian |
| 러시아어 | russian |
파이프라인
CosyVoice3는 3단계로 음성을 합성합니다:
- LLM — Qwen2.5-0.5B 백본이 텍스트로부터 FSQ(Finite Scalar Quantization) 음성 토큰을 생성
- DiT 플로우 매칭 — 22 레이어 Diffusion Transformer가 Euler ODE 적분을 통해 음성 토큰을 멜 스펙트로그램으로 변환
- HiFi-GAN — Neural Source Filter 보코더가 멜 스펙트로그램을 24 kHz 파형으로 변환
아키텍처
LLM (Qwen2.5-0.5B)
현재 런타임은 bf16(기본값), 8bit, 8bit-full을 지원합니다. --cosyvoice-variant로 번들을 선택하세요. 언어 모델은 이산 음성 토큰을 자기회귀 방식으로 생성합니다.
| 파라미터 | 값 |
|---|---|
| 레이어 | 24 |
| 은닉 차원 | 896 |
| Query 헤드 | 14 |
| Key/Value 헤드 | 2 (GQA) |
| FSQ 어휘 | 6561 |
| 양자화 | bf16 / 8-bit |
DiT 플로우 매칭
Diffusion Transformer는 classifier-free guidance와 함께 조건부 플로우 매칭을 사용하여 음성 토큰을 멜 스펙트로그램으로 정제합니다.
| 파라미터 | 값 |
|---|---|
| 레이어 | 22 |
| 차원 | 1024 |
| 어텐션 헤드 | 16 |
| 컨디셔닝 | AdaLN (Adaptive Layer Norm) |
| ODE 솔버 | Euler, 10 스텝 |
| CFG 비율 | 0.7 |
HiFi-GAN 보코더
멜 스펙트로그램을 파형으로 변환하는 Neural Source Filter(NSF) 보코더입니다.
| 파라미터 | 값 |
|---|---|
| 하모닉스 | 8 |
| 업샘플 비율 | 480x (8 x 5 x 3 x ISTFT 4) |
| ISTFT | n_fft=16, hop=4 |
| 출력 샘플 레이트 | 24 kHz |
모델 웨이트
| 변형 | LLM | DiT | 크기 | HuggingFace |
|---|---|---|---|---|
8bit | int8, group=64 | bf16 | ~1.4 GB | aufklarer/CosyVoice3-0.5B-MLX-8bit |
8bit-full | int8, group=64 | int8, group=64 | ~1.6 GB | aufklarer/CosyVoice3-0.5B-MLX-8bit-full |
bf16 | bf16 | bf16 | ~2.1 GB | aufklarer/CosyVoice3-0.5B-MLX-bf16 |
모든 번들에는 LLM, DiT 플로우 매칭 디코더, HiFi-GAN 보코더, 그리고 zero-shot 음성 복제에 필요한 S3-Tokenizer 참조 인코더가 포함됩니다. 다운로드/디스크 공간이 작은 번들을 선호하거나, LLM/DiT 양자화 노이즈가 문제일 때(긴 형식 합성, 음성 복제 충실도)는 bf16을 선택하세요.
CLI 사용법
.build/release/speech speak "Hallo Welt" --engine cosyvoice --language german -o output.wav
예제
# 영어
.build/release/speech speak "Hello, how are you?" --engine cosyvoice -o hello_en.wav
# 중국어
.build/release/speech speak "你好世界" --engine cosyvoice --language chinese -o hello_cn.wav
# 스페인어
.build/release/speech speak "Hola, buenos días" --engine cosyvoice --language spanish -o hello_es.wav
# 프랑스어
.build/release/speech speak "Bonjour le monde" --engine cosyvoice --language french -o hello_fr.wav
음성 복제
--voice-sample 플래그를 사용하여 짧은 레퍼런스 오디오 샘플에서 어떤 음성이든 복제할 수 있습니다. CosyVoice3는 CAM++ 화자 인코더를 사용하여 192차원 임베딩을 추출하고 이를 DiT 플로우 모델에 조건으로 전달합니다.
# 음성 복제
.build/release/speech speak "Hello in your voice" --engine cosyvoice --voice-sample reference.wav --cosy-reference-transcript "One can only wonder what the keyboard will become when something newer comes along." -o cloned.wav
# 교차 언어: 음성은 복제하고 독일어로 발화
.build/release/speech speak "Guten Tag" --engine cosyvoice --voice-sample reference.wav --cosy-reference-transcript "One can only wonder what the keyboard will become when something newer comes along." --language german -o german.wav
동작 원리
- CAM++ 화자 인코더는 CoreML(Neural Engine)을 통해 레퍼런스 오디오에서 192차원 임베딩을 추출
- 아핀 투영 (192 → 80)은 타깃 음성에 맞춰 DiT 플로우 매칭 디코더를 조건화
- HiFi-GAN 보코더는 화자로 조건화된 멜 스펙트로그램을 24 kHz 오디오로 변환
화자 인코더
| 속성 | 값 |
|---|---|
| 모델 | CAM++ (Context-Aware Masking++) |
| 임베딩 | 192차원 |
| 백엔드 | CoreML (Neural Engine, FP16) |
| 크기 | 약 14 MB |
| HuggingFace | aufklarer/CamPlusPlus-Speaker-CoreML |
CAM++ 모델은 --voice-sample을 처음 사용할 때 자동으로 다운로드됩니다. 레퍼런스 오디오 팁과 Swift API는 음성 복제 가이드를 참조하세요.
다화자 대화
인라인 화자 태그를 사용하여 여러 화자 간의 대화를 합성합니다. 각 화자는 --speakers 플래그를 통해 레퍼런스 오디오 파일에서 음성이 할당됩니다.
# 음성 복제가 포함된 두 화자 대화
.build/release/speech speak "[S1] Hello there! [S2] Hey, how are you?" \
--engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o dialogue.wav
# 세 명의 화자
.build/release/speech speak "[A] Welcome. [B] Thanks! [C] Glad to be here." \
--engine cosyvoice --speakers a=host.wav,b=guest1.wav,c=guest2.wav -o panel.wav
태그의 화자 이름은 대소문자를 구분하지 않으며 매핑 키와 매치됩니다. 턴 사이에 구성 가능한 침묵 간격(기본값 0.2초)이 삽입됩니다.
| 옵션 | 기본값 | 설명 |
|---|---|---|
--speakers | 화자 매핑: s1=file.wav,s2=file.wav | |
--turn-gap | 0.2 | 턴 사이의 침묵 (초) |
--crossfade | 0.0 | 턴 간의 크로스페이드 오버랩 (초) |
감정 및 스타일 태그
인라인 감정 태그를 사용하여 세그먼트별 발화 스타일을 제어합니다. CosyVoice3는 <|endofprompt|> 토큰 앞의 텍스트 접두사를 스타일 지시로 사용합니다 — 감정 태그는 이 접두사를 대체하는 자연어 지시로 매핑됩니다.
# 감정 태그
.build/release/speech speak "(excited) Wow, amazing! (sad) But I have to go..." \
--engine cosyvoice -o emotion.wav
# 화자와 결합
.build/release/speech speak "[S1] (happy) Great news! [S2] (surprised) Really?" \
--engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o combined.wav
# 자유형 지시를 태그로 사용
.build/release/speech speak "(Speak like a pirate) Ahoy matey!" \
--engine cosyvoice -o pirate.wav
# 전역 지시 (감정 태그가 없는 모든 세그먼트에 적용)
.build/release/speech speak "Hello world" \
--engine cosyvoice --cosy-instruct "Speak cheerfully" -o cheerful.wav
내장 감정 태그
| 태그 | 지시 |
|---|---|
happy / excited | Speak happily and with excitement. |
sad | Speak sadly with a melancholic tone. |
angry | Speak with anger and intensity. |
whispers / whispering | Speak in a soft, gentle whisper. |
laughs / laughing | Speak while laughing. |
calm | Speak calmly and peacefully. |
surprised | Speak with surprise and amazement. |
serious | Speak in a serious, formal tone. |
알 수 없는 태그는 자유형 지시로 통과되므로 (Speak in a slow, dramatic voice)와 같은 표현도 그대로 동작합니다.
모델 제어 토큰 (fl_ 토큰)
내부적으로 CosyVoice3 LLM은 fl_로 시작하는 특수 제어 토큰을 사용하여 모드(제로샷 클로닝, 지시문 합성, 화자 저장 등) 사이를 전환합니다. 이 토큰은 상위 FunAudioLLM 토크나이저의 일부이며, Soniqo 런타임은 사용하는 CLI 플래그나 Swift API 호출에 따라 적절한 토큰을 자동으로 발행하므로 수동으로 작성할 필요가 없습니다.
| 제어 토큰 | 모드 | Soniqo에서 호출하는 방법 |
|---|---|---|
<|fl_speaker_clone|> | 참조 오디오 샘플로부터 제로샷 음성 클로닝 | CLI에서 --voice-sample reference.wav를 전달하거나 Swift API에서 voiceSample:을 설정합니다. |
<|fl_speaker_instruct|> | 기본 음성으로 지시 또는 스타일 조건부 합성 | --voice-sample 없이 --cosy-instruct "Speak cheerfully"를 전달하거나 인라인 (happy) 태그를 사용합니다. |
<|fl_speaker_instruct2|> | 복제된 참조 음성과 결합된 지시 합성 | 같은 호출에서 --voice-sample reference.wav와 --cosy-instruct "..."(또는 인라인 감정 태그)를 결합합니다. |
<|fl_save_speaker|> | 참조 오디오를 호출마다 다시 인코딩하지 않고 화자 임베딩을 지속화 | Soniqo CLI에 직접 노출되지 않음 — 임베딩은 호출마다 계산됩니다. 캐시하려면 화자 임베딩 모듈을 통해 직접 192차원 CAM++ 벡터를 추출하여 전달하세요. |
<|fl_speaker_clone_zh|>, <|fl_speaker_clone_en|>, … | 상위 토크나이저가 사용하는 언어별 제로샷 클로닝 힌트 | --voice-sample을 --language german|spanish|chinese|...과 결합합니다. Soniqo는 --language 플래그에서 올바른 언어 힌트를 선택합니다. |
위 표는 각 상위 fl_ 제어 토큰을 Soniqo의 동등한 항목에 매핑합니다. fl_ 토큰을 프롬프트에 직접 삽입할 필요가 없습니다 — 고수준 CLI 플래그 또는 Swift API 인수를 전달하면 런타임이 올바른 시퀀스(clone → instruct → instruct2 → save_speaker)를 발행합니다.
샘플링
LLM 단계는 다음 샘플링 구성을 사용합니다:
| 파라미터 | 값 |
|---|---|
| Top-k | 25 |
| Top-p | 0.8 |
| 반복 인지 샘플링 | 활성화 (window=10, tau_r=0.1) |
VALL-E 2에서 도입된 반복 인지 샘플링(RAS)은 최근 생성된 10개 토큰에 등장한 토큰에 페널티를 부여합니다. 이는 반복적인 오디오 아티팩트를 방지하고 출력 안정성을 개선합니다.
성능
M2 Max에서 CosyVoice3는 약 0.5의 RTF를 달성합니다 — 실시간보다 빠릅니다.
| 단계 | 지연 시간 |
|---|---|
| LLM (컴파일됨) | 약 13 ms/토큰 |
| DiT 플로우 매칭 | 370 - 520 ms |
| HiFi-GAN | 50 - 170 ms |
LLM 단계는 자동 회귀 루프에 compile(shapeless: true)를 사용하여, 다양한 시퀀스 길이에 걸친 재컴파일 오버헤드를 제거합니다. 배치 더블링된 CFG는 DiT 포워드 패스 횟수를 20에서 10으로 절반으로 줄입니다.