CosyVoice3
Fun-CosyVoice3-0.5B เป็นโมเดลการสังเคราะห์เสียงพูดจากข้อความแบบ streaming ที่รองรับ 9 ภาษา ใช้ pipeline สามขั้นตอน — การสร้างโทเค็นด้วย LLM, DiT flow matching และ vocoder HiFi-GAN — เพื่อผลิตเสียงพูดธรรมชาติที่ 24 kHz จากข้อความอินพุต โมเดลนี้ — บางครั้งเขียนว่า CosyVoice 3 — เป็นรุ่นล่าสุดในตระกูล CosyVoice ของ FunAudioLLM
ภาษาที่รองรับ
| ภาษา | รหัส |
|---|---|
| จีน | chinese |
| อังกฤษ | english |
| ญี่ปุ่น | japanese |
| เกาหลี | korean |
| เยอรมัน | german |
| สเปน | spanish |
| ฝรั่งเศส | french |
| อิตาลี | italian |
| รัสเซีย | russian |
Pipeline
CosyVoice3 สังเคราะห์เสียงพูดในสามขั้นตอน:
- LLM — Backbone Qwen2.5-0.5B สร้างโทเค็นเสียงพูด FSQ (Finite Scalar Quantization) จากข้อความ
- DiT Flow Matching — Diffusion Transformer 22 ชั้นแปลงโทเค็นเสียงพูดเป็น mel spectrogram ผ่านการอินทิเกรต ODE แบบ Euler
- HiFi-GAN — Vocoder Neural Source Filter แปลง mel spectrogram เป็นรูปคลื่น 24 kHz
สถาปัตยกรรม
LLM (Qwen2.5-0.5B)
โมเดลภาษาสร้าง speech token แบบไม่ต่อเนื่องในลักษณะ autoregressive รันไทม์มาในสี่เวอร์ชันการ quantize — 4-bit, 8-bit, 8-bit-full (int8 LLM + int8 DiT) และ bf16 (ไม่ quantize) — เลือกได้ในแต่ละครั้งผ่าน --cosyvoice-variant
| พารามิเตอร์ | ค่า |
|---|---|
| จำนวนชั้น | 24 |
| มิติ hidden | 896 |
| หัว query | 14 |
| หัว key/value | 2 (GQA) |
| คำศัพท์ FSQ | 6561 |
| การ quantize | 4-bit |
DiT Flow Matching
Diffusion Transformer ปรับโทเค็นเสียงพูดให้เป็น mel spectrogram โดยใช้ conditional flow matching ร่วมกับ classifier-free guidance
| พารามิเตอร์ | ค่า |
|---|---|
| จำนวนชั้น | 22 |
| มิติ | 1024 |
| หัว attention | 16 |
| การกำหนดเงื่อนไข | AdaLN (Adaptive Layer Norm) |
| Solver ODE | Euler, 10 ขั้น |
| อัตรา CFG | 0.7 |
Vocoder HiFi-GAN
Vocoder Neural Source Filter (NSF) แปลง mel spectrogram เป็นรูปคลื่น
| พารามิเตอร์ | ค่า |
|---|---|
| Harmonic | 8 |
| อัตรา upsample | 480x (8 x 5 x 3 x ISTFT 4) |
| ISTFT | n_fft=16, hop=4 |
| อัตราการสุ่มเอาต์พุต | 24 kHz |
น้ำหนักโมเดล
| เวอร์ชัน | LLM | DiT | ขนาด | HuggingFace |
|---|---|---|---|---|
4bit (ค่าเริ่มต้น) | int4, group=64 | bf16 | ~1.2 GB | aufklarer/CosyVoice3-0.5B-MLX-4bit |
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 |
ทุก bundle ประกอบด้วย LLM, ดีโคเดอร์ DiT flow matching, vocoder HiFi-GAN และตัวเข้ารหัสอ้างอิง S3-Tokenizer ที่จำเป็นสำหรับการโคลนเสียงแบบ zero-shot เลือก bundle ที่เล็กกว่าเพื่อลดการดาวน์โหลด/พื้นที่ดิสก์ เลือก bf16 เมื่อ noise จากการ quantize ของ LLM/DiT กลายเป็นปัญหา (การสังเคราะห์รูปแบบยาว, ความเที่ยงของการโคลนเสียง)
การใช้งาน CLI
.build/release/speech speak "Hallo Welt" --engine cosyvoice --language german -o output.wav
ตัวอย่าง
# English
.build/release/speech speak "Hello, how are you?" --engine cosyvoice -o hello_en.wav
# Chinese
.build/release/speech speak "你好世界" --engine cosyvoice --language chinese -o hello_cn.wav
# Spanish
.build/release/speech speak "Hola, buenos días" --engine cosyvoice --language spanish -o hello_es.wav
# French
.build/release/speech speak "Bonjour le monde" --engine cosyvoice --language french -o hello_fr.wav
การโคลนเสียง
โคลนเสียงใดๆ จากคลิปอ้างอิงเสียงสั้นๆ ด้วย flag --voice-sample CosyVoice3 ใช้ speaker encoder CAM++ เพื่อสกัด embedding 192 มิติที่กำหนดเงื่อนไขให้กับโมเดล DiT flow
# Voice cloning
.build/release/speech speak "Hello in your voice" --engine cosyvoice --voice-sample reference.wav -o cloned.wav
# Cross-language: clone voice, speak in German
.build/release/speech speak "Guten Tag" --engine cosyvoice --voice-sample reference.wav --language german -o german.wav
วิธีการทำงาน
- Speaker encoder CAM++ สกัด embedding 192 มิติจากเสียงอ้างอิงผ่าน CoreML (Neural Engine)
- การฉาย affine (192 → 80) กำหนดเงื่อนไขให้ตัวถอดรหัส DiT flow matching ตามเสียงเป้าหมาย
- Vocoder HiFi-GAN แปลง mel spectrogram ที่กำหนดเงื่อนไขตามผู้พูดเป็นเสียง 24kHz
Speaker encoder
| คุณสมบัติ | ค่า |
|---|---|
| โมเดล | CAM++ (Context-Aware Masking++) |
| Embedding | 192 มิติ |
| Backend | CoreML (Neural Engine, FP16) |
| ขนาด | ~14 MB |
| HuggingFace | aufklarer/CamPlusPlus-Speaker-CoreML |
โมเดล CAM++ จะถูกดาวน์โหลดอัตโนมัติเมื่อใช้ --voice-sample ครั้งแรก ดูคู่มือ การโคลนเสียง สำหรับเคล็ดลับเกี่ยวกับเสียงอ้างอิงและ API Swift
สนทนาหลายผู้พูด
สังเคราะห์การสนทนาระหว่างผู้พูดหลายคนโดยใช้แท็กผู้พูดแบบ inline ผู้พูดแต่ละคนได้รับเสียงจากไฟล์เสียงอ้างอิงผ่าน flag --speakers
# Two-speaker dialogue with voice cloning
.build/release/speech speak "[S1] Hello there! [S2] Hey, how are you?" \
--engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o dialogue.wav
# Three speakers
.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
ชื่อผู้พูดในแท็กไม่แยกแยะตัวพิมพ์ใหญ่/เล็กและถูกจับคู่กับ key ในแผนที่ ระหว่างแต่ละผลัดมีการแทรกช่องเงียบที่กำหนดค่าได้ (ค่าเริ่มต้น 0.2 วินาที)
| ตัวเลือก | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|
--speakers | แผนที่ผู้พูด: s1=file.wav,s2=file.wav | |
--turn-gap | 0.2 | ช่องเงียบระหว่างผลัด (วินาที) |
--crossfade | 0.0 | ช่วง crossfade ทับซ้อนระหว่างผลัด (วินาที) |
แท็กอารมณ์และสไตล์
ควบคุมสไตล์การพูดของแต่ละส่วนโดยใช้แท็กอารมณ์แบบ inline CosyVoice3 ใช้คำนำหน้าข้อความก่อนโทเค็น <|endofprompt|> เป็นคำสั่งสไตล์ — แท็กอารมณ์จะถูกจับคู่กับคำสั่งภาษาธรรมชาติที่แทนที่คำนำหน้านี้
# Emotion tags
.build/release/speech speak "(excited) Wow, amazing! (sad) But I have to go..." \
--engine cosyvoice -o emotion.wav
# Combined with speakers
.build/release/speech speak "[S1] (happy) Great news! [S2] (surprised) Really?" \
--engine cosyvoice --speakers s1=alice.wav,s2=bob.wav -o combined.wav
# Freeform instruction as tag
.build/release/speech speak "(Speak like a pirate) Ahoy matey!" \
--engine cosyvoice -o pirate.wav
# Global instruction (applies to all segments without emotion tags)
.build/release/speech speak "Hello world" \
--engine cosyvoice --cosy-instruct "Speak cheerfully" -o cheerful.wav
แท็กอารมณ์ที่มีให้
| แท็ก | คำสั่ง |
|---|---|
happy / excited | พูดอย่างมีความสุขและตื่นเต้น |
sad | พูดอย่างเศร้าด้วยน้ำเสียงหม่นหมอง |
angry | พูดด้วยความโกรธและรุนแรง |
whispers / whispering | พูดกระซิบเบาๆ และนุ่มนวล |
laughs / laughing | พูดพร้อมหัวเราะ |
calm | พูดอย่างสงบและเงียบ |
surprised | พูดด้วยความประหลาดใจและตื่นตะลึง |
serious | พูดด้วยน้ำเสียงจริงจังและเป็นทางการ |
แท็กที่ไม่รู้จักจะส่งผ่านเป็นคำสั่งอิสระ ดังนั้น (Speak in a slow, dramatic voice) จะทำงานได้ตามที่เป็น
โทเค็นควบคุมโมเดล (โทเค็น fl_)
ภายใน LLM ของ CosyVoice3 ใช้โทเค็นควบคุมพิเศษ — มีคำนำหน้า fl_ — เพื่อสลับระหว่างโหมด (zero-shot cloning, การสังเคราะห์ตามคำสั่ง, บันทึกผู้พูด ฯลฯ) โทเค็นเหล่านี้เป็นส่วนหนึ่งของ tokenizer upstream ของ FunAudioLLM; runtime ของ Soniqo จะส่งโทเค็นที่ถูกต้องอัตโนมัติตาม flag CLI หรือการเรียก API Swift ที่คุณใช้ ดังนั้นคุณไม่ต้องเขียนเองด้วยมือ
| โทเค็นควบคุม | โหมด | วิธีเรียกใช้จาก Soniqo |
|---|---|---|
<|fl_speaker_clone|> | การโคลนเสียง zero-shot จากคลิปเสียงอ้างอิง | ส่ง --voice-sample reference.wav บน CLI หรือกำหนด voiceSample: บน API Swift |
<|fl_speaker_instruct|> | การสังเคราะห์ตามคำสั่งหรือตามสไตล์ด้วยเสียงเริ่มต้น | ส่ง --cosy-instruct "Speak cheerfully" หรือใช้แท็กแบบ inline (happy) โดยไม่มี --voice-sample |
<|fl_speaker_instruct2|> | การสังเคราะห์ตามคำสั่งร่วมกับเสียงอ้างอิงที่โคลนมา | รวม --voice-sample reference.wav กับ --cosy-instruct "..." (หรือแท็กอารมณ์แบบ inline) ในการเรียกเดียวกัน |
<|fl_save_speaker|> | เก็บ embedding ของผู้พูดเพื่อใช้ซ้ำโดยไม่ต้องเข้ารหัสเสียงอ้างอิงใหม่ทุกครั้ง | ไม่ได้เปิดเผยโดยตรงใน CLI ของ Soniqo — embedding ถูกคำนวณต่อการเรียก ในการ cache ให้สกัด vector CAM++ 192 มิติด้วยตนเองผ่านโมดูล Embedding ผู้พูด แล้วส่งต่อ |
<|fl_speaker_clone_zh|>, <|fl_speaker_clone_en|>, … | คำใบ้ zero-shot cloning ตามภาษาที่ใช้โดย tokenizer upstream | รวม --voice-sample กับ --language german|spanish|chinese|... Soniqo เลือกคำใบ้ภาษาที่ถูกต้องจาก flag --language |
ตารางข้างบนจับคู่โทเค็นควบคุม fl_ upstream แต่ละตัวกับสิ่งที่เทียบเท่าใน Soniqo คุณไม่ต้องแทรกโทเค็น fl_ เข้าไปใน prompt เอง — แค่ส่ง flag CLI ระดับสูงหรือพารามิเตอร์ API Swift แล้ว runtime จะส่งลำดับที่ถูกต้อง: clone → instruct → instruct2 → save_speaker
Sampling
ขั้นตอน LLM ใช้การตั้งค่า sampling ดังนี้:
| พารามิเตอร์ | ค่า |
|---|---|
| Top-k | 25 |
| Top-p | 0.8 |
| Repetition Aware Sampling | เปิด (window=10, tau_r=0.1) |
Repetition Aware Sampling (RAS) จาก VALL-E 2 ลงโทษโทเค็นที่ปรากฏใน 10 โทเค็นล่าสุดที่สร้าง ช่วยป้องกัน artifact เสียงที่ซ้ำและปรับปรุงความเสถียรของเอาต์พุต
ประสิทธิภาพ
บน M2 Max, CosyVoice3 ทำ RTF ได้ประมาณ 0.5 — เร็วกว่าเวลาจริง
| ขั้นตอน | Latency |
|---|---|
| LLM (compiled) | ~13 ms/token |
| DiT Flow Matching | 370 - 520 ms |
| HiFi-GAN | 50 - 170 ms |
ขั้นตอน LLM ใช้ compile(shapeless: true) สำหรับลูป autoregressive ซึ่งกำจัด overhead ของการ recompile เมื่อความยาวลำดับเปลี่ยน CFG แบบ batch สองเท่าลด forward pass ของ DiT ลงครึ่งหนึ่ง จาก 20 เหลือ 10