CosyVoice3
Fun-CosyVoice3-0.5B เป็นโมเดลการสังเคราะห์เสียงพูดจากข้อความแบบ streaming ที่รองรับ 9 ภาษา ใช้ pipeline สามขั้นตอน — การสร้างโทเค็นด้วย LLM, DiT flow matching และ vocoder HiFi-GAN — เพื่อผลิตเสียงพูดธรรมชาติที่ 24 kHz จากข้อความอินพุต
สถานะ CosyVoice 3 เทียบกับ 3.5
คู่มือนี้และ runtime ของ Soniqo รองรับสายโอเพน Fun-CosyVoice3-0.5B (3.0) ปัจจุบัน repository โอเพนซอร์สอย่างเป็นทางการ เผยแพร่และทำเอกสาร 3.0 รวมถึง Fun-CosyVoice3-0.5B-2512 และยังไม่มี weights หรือโค้ด inference ของ CosyVoice 3.5 ส่วนชื่อ cosyvoice-v3.5-plus เป็น model ID ของ hosted API ใน Alibaba Cloud Model Studio ไม่ใช่ checkpoint ที่ดาวน์โหลดได้จาก repository นี้ ดังนั้น Soniqo จึงไม่ได้อ้างว่ารองรับ 3.5 แบบ local
ตัวอย่างเสียง
ฟังเสียง CosyVoice3 ค่าเริ่มต้น ตัวอย่าง clone เสียง และตัวอย่างตามคำสั่งสไตล์ ซึ่งสร้างด้วย CLI ชุดเดียวกับด้านล่าง
การสังเคราะห์ CosyVoice3 8-bit ด้วย seed คงที่
CosyVoice3 clone จากคลิปอ้างอิง Kokoro af_heart
น้ำเสียงสดใสตื่นเต้นด้วย --cosy-instruct
ภาษาที่รองรับ
| ภาษา | รหัส |
|---|---|
| จีน | 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