การแปลเสียงพูด Hibiki Zero-3B (FR / ES / PT / DE → EN)
Hibiki Zero-3B เป็นโมเดล การแปลคำพูดสู่คำพูดแบบสตรีมมิ่ง ของ Kyutai — อินพุตคือสตรีมเสียงความถี่ 24 kHz ในภาษาฝรั่งเศส สเปน โปรตุเกส หรือเยอรมัน เอาต์พุตคือสตรีมเสียงภาษาอังกฤษ 24 kHz พร้อมกับข้อความถอดความภาษาอังกฤษคู่ขนานที่อัตราเฟรม 12.5 Hz เดียวกัน สร้างขึ้นบนสถาปัตยกรรมมัลติสตรีมของ Moshi/Mimi โดยที่ทรานส์ฟอร์เมอร์แบบดีโคเดอร์อย่างเดียวเพียงตัวเดียวจะจำลองสตรีมโคเดกของเสียงต้นทางและสตรีมข้อความ+เสียงปลายทางร่วมกัน จึงไม่มีไปป์ไลน์ ASR + MT + TTS แยกกัน เวอร์ชันของ Soniqo ทำงานเป็น safetensors แบบ MLX ที่ถูก quantize แล้ว (INT4 เป็นค่าเริ่มต้น มี INT8 ให้เลือก) ทั้งหมดบน Apple Silicon CC-BY-4.0
การใช้ไปป์ ASR + MADLAD (speech transcribe | speech translate) ให้คุณได้ภาษา 400+ ภาษา แต่เพิ่มเวลาแฝงไป-กลับของโมเดลสามตัว Hibiki เป็นโมเดลเดียวแบบครบวงจรและรักษาทำนองเสียงไว้ — เลือกใช้เมื่อคุณต้องการ เสียงพูดสดในภาษาปลายทาง ไม่ใช่แค่ข้อความ
เริ่มต้นอย่างรวดเร็ว
import HibikiTranslate
import AudioCommon
let model = try await HibikiTranslateModel.fromPretrained()
let pcm = try AudioFileLoader.load(url: input, targetSampleRate: 24000)
let (englishAudio, textTokens) = model.translate(
sourceAudio: pcm,
sourceLanguage: .fr // .fr / .es / .pt / .de — ตรวจจับอัตโนมัติ แต่ส่งเข้ามาเพื่อเก็บเป็นเมตาดาตา
)
try WAVWriter.write(samples: englishAudio, sampleRate: 24000, to: output)
CLI
speech audio-translate input_fr.wav -o out_en.wav --source-lang fr
speech audio-translate input_es.wav -o out_en.wav --source-lang es --quantization 8bit
speech audio-translate input_pt.wav -o out_en.wav --source-lang pt --verbose
# โหมดดีเทอร์มินิสติก (ใช้โดย CI regression canary)
HIBIKI_GREEDY=1 speech audio-translate input_fr.wav -o out_en.wav --source-lang fr
# Token ID ของข้อความ inner-monologue (แบบดิบ — การถอดรหัส SPM เป็นงานต่อเนื่อง)
speech audio-translate input.wav -o out.wav --transcript
สถาปัตยกรรม
Hibiki Zero-3B เป็นทรานส์ฟอร์เมอร์มัลติสตรีมแบบดีโคเดอร์อย่างเดียวขนาด 3.1B พารามิเตอร์ โมเดลให้ความสนใจ 33 สตรีม ต่อเฟรมพร้อมกัน คือ สตรีมข้อความหนึ่งสตรีม โค้ดบุ๊กเสียงปลายทาง 16 ตัว (เอาต์พุตของเอเจนต์) และโค้ดบุ๊กเสียงต้นทาง 16 ตัว (อินพุตของผู้ใช้) ที่แต่ละเฟรม 80 มิลลิวินาที โมเดลจะสุ่มตัวอย่างโทเค็นข้อความหนึ่งตัวพร้อมกับโค้ดเสียง 16 ตัว ผ่าน depformer ขนาดเล็ก 6 เลเยอร์ที่ทำงาน 16 sub-step ต่อเฟรม หนึ่งครั้งต่อโค้ดบุ๊กปลายทาง พร้อมการฉาย MultiLinear แบบ 9 ส่วนที่กำหนดเวลาไว้
โคเดกเสียงคือ Mimi ที่ 12.5 Hz / 16 โค้ดบุ๊ก เสียงต้นทางถูกเข้ารหัสเป็นโค้ดบุ๊กของสตรีมต้นทาง 16 ตัว (ดีเลย์ [0, 2, 2, …, 2]) เสียงปลายทางที่สร้างขึ้นจะเติมโค้ดบุ๊กสตรีมปลายทาง 16 ตัว (รูปแบบดีเลย์เดียวกัน) มีการ un-shift ต่อโค้ดบุ๊กก่อนที่ Mimi จะถอดรหัสเสียงปลายทางกลับเป็น PCM ภาษาอังกฤษ 24 kHz กระดูกสันหลังเชิงเวลาคือ 28 เลเยอร์ GQA (dim = 2048, query head 16 ตัว, KV head 8 ตัว, kv_repeat = 2, RoPE แบบแบ่งครึ่ง rope_concat ไม่มี conditioner — Zero เป็นเวอร์ชันแบบไม่มีเงื่อนไข)
ลูปการถอดรหัส
Hibiki ปล่อยโทเค็น padding ของ SPM (id 3) ในขณะที่กำลังสะสมบริบทต้นทางที่เพียงพอสำหรับการแปล จากนั้นจึงปล่อยโทเค็นเนื้อหาข้อความพร้อมกับเสียงปลายทางที่สอดคล้อง และสุดท้าย text-EOS (id 2) ตัวขับ Swift ทำงาน จนกว่าจะสุ่มตัวอย่าง EOS ได้เกินช่วงต้นทาง โดยจำกัดที่ max(tSrc × 5/2, tSrc + 20) ขั้นเป็นขีดจำกัดเพื่อความปลอดภัย เอาต์พุตจะมีความยาวประมาณ 1.0–1.6× ของความยาวอินพุตในคลิปแบบ FLEURS ผู้เรียกใช้ไม่ควรสันนิษฐานว่า output_duration == input_duration
เส้นทาง feedback แบบ autoregressive ไม่ชัดเจน ที่ขั้นตอน t ทรานส์ฟอร์เมอร์อ่านโทเค็นที่ดัชนีแคช step (สม่ำเสมอตลอดทั้ง 33 สตรีม โดยมีการแทนที่ init-token เมื่อ step ≤ delays[k]) ข้อความที่สุ่มได้ + โค้ดปลายทาง 16 ตัวจะถูกเขียนที่ดัชนี step + 1 สิ่งนี้สะท้อน Moshi lm.py ต้นทางที่ state.offsets += 1 เกิดขึ้นก่อนการ scatter แคช แถว text_emb สำหรับ EOS (id 2) ถูก alias ไปยังแถว 3 (PAD) ในเวลาโหลดน้ำหนัก ซึ่งสะท้อน patch ของ Kyutai ใน loaders.py:312 "implicitly replace early EOS with PAD" — EOS ใดๆ ที่สุ่มได้ระหว่างหน้าต่างการสตรีมเสียงไม่เป็นอันตราย มีเพียง EOS หลังจากต้นทางเท่านั้นที่ยุติลูป
เวอร์ชันของโมเดล
| เวอร์ชัน | Quantization | ขนาด | การประมวลผล | HuggingFace |
|---|---|---|---|---|
| Hibiki Zero-3B | INT4 | ~2.7 GB | Metal GPU (MLX) | aufklarer/Hibiki-Zero-3B-MLX-4bit |
| Hibiki Zero-3B | INT8 | ~3.9 GB | Metal GPU (MLX) | aufklarer/Hibiki-Zero-3B-MLX-8bit |
การรองรับภาษา
Hibiki Zero-3B ถูกฝึกบน ฝรั่งเศส สเปน โปรตุเกส และเยอรมัน → อังกฤษ ตัวขับ Swift ตรวจจับภาษาต้นทางโดยอัตโนมัติ ส่วนแฟล็ก --source-lang เป็นเพียงเมตาดาตาเท่านั้น
| ต้นทาง | สถานะ | ตัวอย่างเอาต์พุต greedy |
|---|---|---|
| FR | E2E canary แบบเข้มงวด | "so it's a ski route." (จาก "Pensez à l'itinéraire de ski…") |
| ES | E2E canary แบบเข้มงวด | "gentlemen, the data is worrying." (ตัวอย่าง europarl ของ Hibiki) |
| PT | เตือนเท่านั้น (ตรงตามเนื้อหา การจดจำคำสำคัญต่ำกว่า) | "the fifth c is p of the martyr." (FLEURS PT) |
| DE | เตือนเท่านั้น (ตรงตามเนื้อหา การจดจำคำสำคัญต่ำกว่า) | "that didn't seem to me to be useful." (FLEURS DE) |
คลิป FLEURS ภาษาสเปนที่บันทึกจากมนุษย์ที่ 16 kHz กระตุ้นให้เกิดการสร้างที่ผิดปกติทั้งใน Python ต้นทางและ Swift port (Python ปล่อย 1643 ขั้น / ~131 วินาทีของเสียงที่เสียโดยไม่มีการสุ่ม EOS) ES regression canary ของ Swift ใช้คลิปที่ตัดสั้นเป็น 5 วินาทีจาก samples space ของ Kyutai เอง (kyutai/hibiki-zero-samples) ที่เสียงสร้างจาก TTS 24 kHz ซึ่งตรงกับการกระจายของการฝึกและให้ผลเป็นภาษาอังกฤษที่สะอาด หากคุณป้อน Hibiki ภาษาสเปนในการใช้งานจริง โปรด resample ล่วงหน้าเป็น 24 kHz และยึดติดกับคลิปที่ยาวกว่า (5 วินาทีขึ้นไป)
ตัวแปรสภาพแวดล้อม
| ตัวแปร | ผลกระทบ |
|---|---|
HIBIKI_GREEDY=1 | บังคับการถอดรหัสแบบ argmax สำหรับทั้งข้อความและเสียงปลายทาง สามารถทำซ้ำได้ — ใช้โดย canary ที่เข้มงวดของ CI |
HIBIKI_E2E=1 | เปิดใช้งานกรณีทดสอบ E2E (ต้องการดาวน์โหลดโมเดล ~2.7 GB) |
HIBIKI_STRICT_ALL=1 | เลื่อนการทดสอบ PT/DE จากเตือนเท่านั้นให้เป็นแบบเข้มงวด |
HIBIKI_LENIENT=1 | ลดระดับการทดสอบ FR/ES จากเข้มงวดให้เป็นเตือนเท่านั้น (สำหรับการดีบักเท่านั้น) |
HIBIKI_MODEL_ID=<repo> | เขียนทับ id โมเดลเริ่มต้น aufklarer/Hibiki-Zero-3B-MLX-4bit |
ประสิทธิภาพ (M2 Max, MLX 4-bit)
| ตัวชี้วัด | Greedy | Sampled |
|---|---|---|
| เวลาแฝงต่อขั้น | ~75 มิลลิวินาที | ~95 มิลลิวินาที |
| เวลานาฬิกาสำหรับต้นทาง FR 3.54 วินาที | ~5 วินาที | ~7 วินาที |
| ระยะเวลาเอาต์พุต | 1.0–1.6× ต้นทาง | 1.0–1.6× ต้นทาง |
ข้อจำกัดที่ทราบ
translateStream()ปล่อย chunk สุดท้ายเพียงตัวเดียว จุดเข้าใช้งานสตรีมมิ่งในปัจจุบันห่อหุ้มtranslate()แบบออฟไลน์ การถอดรหัสสตรีมมิ่ง Mimi ต่อ chunk จริงเป็นงานต่อเนื่องของ v2- ไม่มีตัวถอดรหัสข้อความ SentencePiece แฟล็ก
--transcriptพิมพ์ ID โทเค็นแบบดิบ การเดินสายถอดรหัส SPM เป็นงานต่อเนื่อง - โหมด sampled มีสัญญาณรบกวนมากกว่า greedy อย่างเห็นได้ชัด ใช้
HIBIKI_GREEDY=1สำหรับการรันที่ทำซ้ำได้ - Quantization เท่านั้น ปัจจุบันรีโพส่ง Zero-3B 4-bit และ 8-bit เวอร์ชัน Hibiki 1B และ 2B มีอยู่ในตัวแปลง (
models/hibiki/export/convert.py) แต่ตัวขับ Swift มุ่งเป้าไปที่เลย์เอาต์ GQA + rope_concat + non-conditioned ของ Zero-3B
เอกสารอ้างอิง
- เปเปอร์: High-Fidelity Simultaneous Speech-to-Speech Translation (Kyutai, 2025)
- โค้ดต้นทาง: kyutai-labs/hibiki
- ตัวอย่าง: kyutai/hibiki-zero-samples
- ไลเซนส์: CC-BY-4.0