คำสั่งปลุก / Keyword Spotting
โมดูล SpeechWakeWord รัน keyword spotter บนอุปกรณ์: คุณลงทะเบียนรายการวลี ส่ง chunk เสียงเข้า และรับการตรวจจับ ใช้ Streaming Zipformer transducer ของ icefall (3.49M params, Apache-2.0) ที่คอมไพล์เป็น CoreML พร้อม INT8 palettization
checkpoint ที่ปล่อยมาคือ KWS fine-tune ของ gigaspeech คำสั่งที่ไม่ใช่ภาษาอังกฤษต้องการ icefall fine-tune แยกและส่งออกใหม่
สถาปัตยกรรม
| ขั้นตอน | รายละเอียด |
|---|---|
| fbank | เข้ากันได้กับ kaldi (25 ms / 10 ms, Povey window, 80 mel bin, high_freq=-400, ไม่มี CMVN) |
| Encoder | Causal Zipformer2 6 ขั้น (128 มิติ) 45 mel frame เข้า → 8 frame ออก (40 ms / frame) — 3.3 MB INT8 |
| Decoder | Stateless transducer, BPE-500 vocab, context size 2 — 525 KB FP16 |
| Joiner | Linear + tanh output projection — 160 KB INT8 |
| Decode | Modified beam search (beam=4) บน Aho-Corasick ContextGraph ของคำสั่งผู้ใช้ |
ขนาดที่คอมไพล์บนดิสก์: ~4 MB รวม (encoder.mlmodelc + decoder.mlmodelc + joiner.mlmodelc) หน่วยความจำขณะรัน: ~6 MB รวม encoder state cache
ประสิทธิภาพ
| เมตริก | ค่า | หมายเหตุ |
|---|---|---|
| RTF (CPU + Neural Engine) | 0.04 | 26× เรียลไทม์บนชิป M-series |
| Recall (12 คำสั่ง) | 88% | LibriSpeech test-clean, ประโยคบวก 158 ประโยค |
| False positive / ประโยค | 0.27 | ประโยคลบ 60 ประโยค |
| CoreML INT8 vs PyTorch FP32 | 99% | ความสอดคล้องของการปล่อย |
ค่าเริ่มต้นที่ปรับแล้ว: acThreshold=0.15, contextScore=0.5, numTrailingBlanks=1 รองรับการเขียนทับเฉพาะคำสั่ง
การใช้งาน CLI
รูปแบบวลีธรรมดา (greedy BPE — ทำงานได้ดีกับคำทั่วไป):
speech wake recording.wav --keywords "hey soniqo"
speech wake recording.wav --keywords "hey soniqo:0.15:0.5" "cancel"
รูปแบบ pre-tokenized (สไตล์ sherpa-onnx — แนะนำเมื่อคุณรู้การแยกที่แน่นอนที่โมเดลถูกฝึก):
# รูปแบบ: "phrase|piece1 piece2 ...:threshold:boost"
speech wake recording.wav \
--keywords "LIGHT UP|▁ L IGHT ▁UP:0.25:2.0"
# หลายคำสั่ง + เอาต์พุต JSON
speech wake recording.wav \
--keywords "LIGHT UP|▁ L IGHT ▁UP:0.25:2.0" \
"LOVELY CHILD|▁LOVE LY ▁CHI L D:0.25:2.0" \
--json
หรือไฟล์คำสั่ง หนึ่งรายการต่อบรรทัด (# สำหรับคอมเมนต์):
speech wake recording.wav --keywords-file keywords.txt
API Swift
import SpeechWakeWord
// โหลดโมเดลด้วยรายการคำสั่งของคุณ
let detector = try await WakeWordDetector.fromPretrained(
keywords: [
KeywordSpec(phrase: "hey soniqo", acThreshold: 0.15, boost: 0.5),
KeywordSpec(phrase: "cancel")
]
)
// Streaming: ส่ง chunk รับการตรวจจับเมื่อมีการ trigger
let session = try detector.createSession()
for chunk in micAudioChunks { // Float32 @ 16 kHz
for detection in try session.pushAudio(chunk) {
print("[\(detection.time(frameShiftSeconds: 0.04))s] \(detection.phrase)")
}
}
// Batch: รันครั้งเดียวบน buffer ทั้งหมด
let detections = try detector.detect(audio: samples, sampleRate: 16000)
KeywordSpec
| ฟิลด์ | ความหมาย |
|---|---|
phrase | วลีที่แสดง เช่น "hey soniqo" ยังใช้เป็นแหล่งสำหรับการเข้ารหัส greedy BPE เมื่อ tokens เป็น nil |
acThreshold | ความน่าจะเป็นทางเสียงเฉลี่ยที่ต้องการบนช่วงที่จับคู่ 0 → ใช้ค่าเริ่มต้นที่ปรับแล้ว (0.15) |
boost | boost บริบทต่อ token ค่าบวกทำให้ตัววลี trigger ง่ายขึ้น 0 → ใช้ค่าเริ่มต้นที่ปรับแล้ว (0.5) |
tokens | รายการ BPE piece ที่ระบุชัดเจน (ไม่บังคับ) เมื่อไม่เป็น nil detector จะค้นหา piece แต่ละตัวใน tokens.txt ของโมเดลและข้าม greedy BPE encoder |
tokens ที่ pre-tokenizedvocab KWS ของ icefall เป็น BPE ตัวพิมพ์ใหญ่ การ tokenize แบบ greedy ของวลีอาจเลือกการแยก BPE ที่ต่างจากที่โมเดลถูกฝึกให้ปล่อย — "LIGHT UP" greedy-encode เป็น ▁LI GHT ▁UP แต่การแยกสำหรับการฝึกคือ ▁ L IGHT ▁UP เมื่อการตรวจจับบนเสียงที่สังเคราะห์ด้วย TTS หรืออ่านชัดเจนพลาดการจับคู่ที่ชัดเจน ให้ลองรูปแบบ pre-tokenized สไตล์ sherpa-onnx
การดาวน์โหลดโมเดล
| โมเดล | พารามิเตอร์ | ขนาด | HuggingFace |
|---|---|---|---|
| KWS-Zipformer-3M | 3.49M | ~4 MB | aufklarer/KWS-Zipformer-3M-CoreML-INT8 |
การรวมเข้ากับ pipeline
โมดูลเปิดเผยโปรโตคอล WakeWordProvider ที่สะท้อน StreamingVADProvider ดังนั้น voice pipeline สามารถ gate การเปิดใช้งานด้วย VAD, คำสั่งปลุก หรือทั้งสอง WakeWordStreamingAdapter ห่อ detector ที่โหลดแล้ว + session เดียวเป็น provider object ที่นำกลับมาใช้ได้
let adapter = try WakeWordStreamingAdapter(detector: detector)
// pipeline.configure(wakeWord: adapter)
แหล่งที่มา
- Sources/SpeechWakeWord — โมดูล Swift
- docs/models/kws-zipformer.md — โน้ตสถาปัตยกรรม
- docs/inference/wake-word.md — pipeline การอนุมาน
- Upstream: k2-fsa/icefall KWS recipe / pkufool/keyword-spotting-models