โปรดดูฉบับภาษาอังกฤษสำหรับข้อมูลล่าสุดเกี่ยวกับการเรียกใช้เครื่องมือและประสิทธิภาพของ VoiceChat
โมเดล Speech-to-Speech
Soniqo รองรับโมเดล native MLX สำหรับการสนทนา speech-to-speech สองตระกูล ได้แก่ PersonaPlex 7B และ VoiceChat 11B ทั้งสองรับเสียงพูดและสร้างเสียงของโมเดลโดยตรง แต่ใช้สถาปัตยกรรม duplex และสัญญา runtime ต่างกัน
เลือกโมเดล
| โมเดล | รูปแบบการสนทนา | เหมาะที่สุดสำหรับ |
|---|---|---|
| PersonaPlex 7B | Full duplex พร้อมกันด้วย Moshi, Depformer และ Mimi | การฟังและพูดที่ซ้อนกัน พร้อมเสียงให้เลือก 18 แบบ |
| VoiceChat 11B | Duplex ต่อเนื่องแบบ frame-synchronous ด้วย FastConformer, Nemotron-H, EAR-TTS และ neural codec | Streaming frame 80 ms, event ข้อความ/ฟังก์ชัน และเสียง native ของ checkpoint |
โมเดลเหล่านี้เป็น speech-to-speech สำหรับการสนทนา Hibiki ก็แปลงเสียงพูดเป็นเสียงพูดโดยตรง แต่มีหน้าที่แปลเสียงพูดแบบ streaming จึงแยกเอกสารไว้ต่างหาก
PersonaPlex 7B
โมเดล speech-to-speech บทสนทนาแบบฟูล-ดูเพล็กซ์ ที่ใช้สถาปัตยกรรม Moshi (Kyutai) PersonaPlex 7B สร้างคำตอบที่พูดได้โดยตรงจากอินพุตที่เป็นเสียงพูด — ไม่จำเป็นต้องมี pipeline ข้อความตรงกลาง โมเดลมาพร้อมพรีเซ็ตเสียง 18 ตัวและพร้อมใช้ในรูปแบบที่ลดความละเอียดเป็น 8-bit (แนะนำ) และ 4-bit 8-bit เป็นค่าเริ่มต้น — เร็วกว่า 30% และสร้างคำตอบที่สอดคล้องกัน ในขณะที่ 4-bit จะลดคุณภาพเอาต์พุต
VoiceChat 11B
เอกสารอ้างอิง duplex speech-to-speech: SALM-Duplex: Efficient and Direct Duplex Modeling for Speech-to-Speech Language Model (Interspeech 2025) ซึ่ง model card VoiceChat ต้นทางของ NVIDIA อ้างอิง
M5 Pro, 48 GB, Release, จังหวะ live 80 ms, INT5 แบบ protected-head: การรันแบบควบคุมสามครั้งวัด whole-pipeline RTF ได้ 0.94, 0.92 และ 0.92 โดยมี RSS สูงสุดประมาณ 8.70 GB ข้อความพูดแรกมาใน 44.3–46.7 ms และเสียงแรกที่เล่นได้มาใน 74.0–76.4 ms ตัวเลขเหล่านี้คือเวลา compute หลัง warm-up ไม่ใช่ latency การผลัดกันพูดที่เรียนรู้ และยังไม่ได้วัด performance ของ INT8 หลัง optimize ซ้ำ
VoiceChat คือ runtime เสียงพูดสู่เสียงพูดแบบ native MLX อีกตัวใน speech-swift โดยรวมการรับรู้ FastConformer แบบ causal, ช่องข้อความ/ฟังก์ชัน duplex ของ Nemotron-H, EAR-TTS แบบกำหนดเงื่อนไขด้วยข้อความที่แยกอิสระ และ neural codec 22.05 kHz Session รับเสียง mono 16 kHz อย่างต่อเนื่อง และส่ง text event พร้อม output frame 1,764 samples ทุก 80 ms
โหลดด้วย VoiceChatModel.load(from:) เริ่ม VoiceChatSession และป้อนเสียงผ่าน pushAudio Bundle แบบเต็มต้องมี encoder/, llm/ และ tts/; bundle รุ่นเก่าที่มีเฉพาะส่วนความเข้าใจจะถูกปฏิเสธ
INT5 รักษา throughput รวมต่ำกว่า RTF 1 บน M5 Pro ที่ทดสอบ การรันทั้งสามยังรักษา total/frame p95 ต่ำกว่า 80 ms ที่ 76.2–78.6 ms แต่ deadline headroom ยังแคบ ควรวัดจังหวะเริ่มพูดของโมเดลและ latency การคำนวณของฮาร์ดแวร์แยกกัน
VoiceChat CLI แบบสด
สนทนากับ Soniqo ด้วย bundle INT5 แบบ protected-head ที่สมบูรณ์ ซึ่งขับเคลื่อนโดย NVIDIA Nemotron VoiceChat 11B คำสั่งรวมการจับเสียงและเล่นเสียงไว้ใน AVAudioEngine เดียวเพื่อใช้ Apple AEC, stream คำบรรยายผู้ใช้จาก RNN-T ของ bundle และเล่นเสียงโมเดล 22.05 kHz ขณะยังคงฟังต่อไป
prompt เริ่มต้นของ Soniqo ระบุขอบเขตความสามารถอย่างชัดเจน: CLI นี้สนทนาและตอบคำถามได้ แต่เข้าถึงปฏิทิน การเตือน แอป บัญชี อุปกรณ์ หรือบริการภายนอกไม่ได้ เมื่อได้รับคำขอเหล่านี้ Soniqo จะบอกอย่างชัดเจนว่าไม่สามารถทำได้ ไม่ขอการยืนยันในสิ่งที่ทำให้สำเร็จไม่ได้ และแนะนำสั้น ๆ ว่าผู้ใช้ทำอะไรได้ด้วยตนเอง
speech voice-chat
speech voice-chat --input question.wav --output response.wav
speech voice-chat \\
--mcp-config Examples/VoiceChatMCP/apple-reminders.json
เครื่องมือ MCP ที่กำหนดค่าได้
adapter apple-reminders-eventkit ที่ให้มาจะแสดงต่อโมเดลเฉพาะ list_reminders, create_reminder และ update_reminder เท่านั้น การค้นหารายการจะอยู่ภายใน adapter แบบ private สำหรับการแก้ไข ผู้ใช้พูดชื่อ reminder แล้ว runtime จะจับคู่กับ EventKit ID ที่เชื่อถือได้และเก็บเป็นความลับ โดย ID นี้จะไม่อยู่ในผลลัพธ์ที่โมเดลเห็น การสร้างและกำหนดเวลายังคงบันทึกด้วย EventKit ครั้งเดียว การเริ่ม server ครั้งแรกมีเวลาอย่างน้อย 60 วินาที ส่วน tool call ปกติมีค่าเริ่มต้น 15 วินาที
MCP จะเปิดใช้เฉพาะเมื่อระบุ --mcp-config ไฟล์ JSON ที่ไม่ผูกกับผู้ให้บริการสามารถเริ่ม MCP server แบบ stdio ใดก็ได้ และเลือกเครื่องมืออย่างชัดเจนได้สูงสุดห้ารายการผ่าน enabledTools เครื่องมือที่ไม่อยู่ใน readOnlyTools จะถือว่าเป็นการเขียนทั้งหมด นโยบายเริ่มต้นคือ confirm: การเรียกครั้งแรกจะถูกพักไว้ เสียงยืนยันแบบกำหนดตายตัวของ Soniqo จะทวนอาร์กิวเมนต์ที่ตีความได้และบอกว่ายังไม่มีสิ่งใดเปลี่ยนแปลง จากนั้นคำยืนยันใหม่จากผู้ใช้เท่านั้นที่เรียกทำงานได้หนึ่งครั้ง การเรียกเดิมจะทำซ้ำไม่ได้หากไม่มีคำพูดใหม่จากผู้ใช้ แม้ใช้ allow นอกจากนี้ยังมี deny และการอนุญาตชัดเจนแบบ allow ผลจริงจะส่งกลับผ่าน function channel ของโมเดล และการรายงานว่าสำเร็จต้องมีคำตอบ ok
อาร์กิวเมนต์การเขียนจะถูกตรวจเทียบกับ transcript ของผู้ใช้ก่อนยืนยัน วันที่สัมพัทธ์อิงวันที่ท้องถิ่นปัจจุบัน และจะไม่รันชื่อรายการที่แต่งขึ้น วันที่ล้าสมัย ลำดับความสำคัญ หรือค่าที่ยังไม่ยืนยัน คำพูด RNN-T ใหม่ตามด้วยจุดจบของข้อความจะจัดการคำยืนยันได้แม้ transcript ถูกรีเซ็ต Soniqo จะบอกว่าสำเร็จเมื่อ MCP server ส่ง ok: true จริงเท่านั้น มิฉะนั้นจะแจ้งว่าไม่สามารถยืนยันการทำงานได้
คำถาม “ฉันมี reminder อะไรบ้าง” จะเรียก list_reminders แบบแบนเพียงครั้งเดียวครอบคลุมทุก EventKit list และ cache ชื่อ list, เวลา, สถานะเสร็จสิ้น และ stable ID ที่ใช้ภายในเท่านั้น จึงตอบรายละเอียดและแก้ไขอย่างปลอดภัยได้โดยไม่อ่านทีละ list ซ้ำ dashboard แสดงเวลาที่ใช้, จำนวน token step และ token/s ของ function decoding แยกจาก audio RTF ซึ่งยังวัดเฉพาะเฟรมเสียง 80 ms ที่ประมวลผลด้านหน้า
คำยืนยันด้วยเสียงจะถามว่าผู้ใช้ต้องการ “ดำเนินการต่อ” หรือไม่ และจงใจหลีกเลี่ยงวลียืนยันทั้งหมดใน allow-list เพื่อไม่ให้เสียงสะท้อนจาก playback อนุญาตการทำงานที่รออยู่ได้
Child MCP server จะรับเฉพาะ PATH, HOME, ตัวแปร temporary directory และ locale เท่านั้น ต้องส่ง credentials อย่างชัดเจนใน env map ของ server และจะไม่ส่งต่อ secret อื่นจาก parent process
function projection แบบ 8-bit มีขนาดประมาณ 518 MB ระหว่างการพูดทั่วไป VoiceChat จะประเมินเพียง probe PAD/tool-start ขนาด 36 KB ที่ cache ไว้เท่านั้น head เต็ม 131,072 แถวจะทำงานเมื่อ tool-start ชนะ PAD ก่อน จากนั้นตรวจสอบ global argmax และทำงานต่อระหว่างสร้าง JSON call ที่เปิดอยู่ เมื่อทราบผล MCP แล้ว VoiceChat จะ replay ด้วย chunk causal-prefill ที่จำกัดไว้ครั้งละ 16 token โดยคง function feedback ที่ฝึกมาและสถานะ cache ของภาษาและเสียงไว้ โดยไม่ต้องทำ 11B decode แยกสำหรับทุก result token วิธีนี้ทำให้การสนทนา MCP คง realtime โดยไม่ลดความแม่นยำของการตัดสินใจเริ่ม tool
ค่าเริ่มต้น buffer frame 80 ms จำนวนสาม frame ก่อนเล่น รวม 240 ms หลังเกิดช่องว่าง ระบบจะรอ recovery buffer แปด frame เมื่อ callback แรกใช้เวลา 88 ms หรือมีคิวสาม frame การปรับเสียงจะลดจากแปดเหลือสองขั้น; ที่ 120 ms, หก frame หรือ input resync จะลดตรงเหลือหนึ่งขั้น หากคิวยังถึงแปด frame (640 ms) ระบบจะทิ้งเฉพาะ audio เก่าขั้นต่ำที่จำเป็นเพื่อรับอินพุตใหม่ ภาวะ overload ต่อเนื่องจะนับเป็น recovery episode เดียว และ user turn ที่ RNN-T ยืนยันแล้วจะยังทำงานแทนที่จะถูกลบด้วยการ reset ซ้ำ คำที่ข้ามยังถูกทำเครื่องหมายและอาจต้องพูดซ้ำ
Metrics อธิบายประสบการณ์โดยตรง: behind 0.3 s คือเสียงไมโครโฟนที่รออยู่, RTF 0.93× คือเวลาคำนวณหารด้วยเวลา audio (ต่ำกว่า 1 ตามทัน สูงกว่า 1 ช้าลง) และ last 74 ms for 80 ms audio เปรียบเทียบเวลาคำนวณล่าสุดกับ audio 80 ms ที่แต่ละ model frame แทนค่า ค่าเฉลี่ยเคลื่อนที่ใช้ 120 microphone callback ล่าสุด และไม่นับ replay event เป็นเวลา audio เพิ่มเติม
โหมดไมโครโฟนใช้การควบคุมผลัดสนทนา RNN-T แบบ NVIDIA เป็นค่าเริ่มต้น โดยการตัดสิน BOS/EOS ที่โมเดลเรียนรู้ยังเป็นเส้นทางปกติที่ latency ต่ำ prediction แรกของทุก frame 80 ms ถือเป็น blank หรือ non-blank; หลังยืนยันเสียงผู้ใช้แล้ว blank ต่อเนื่อง 40 frame (3.2 วินาที) ทำหน้าที่เป็น safety fallback สำหรับเริ่มคำตอบเท่านั้น และ non-blank ใหม่ 40 frame เป็น fallback ที่ตรงกันสำหรับการขัดจังหวะ ตัวนับ speech จะ reset เมื่อ Soniqo เริ่มพูด ทำให้กิจกรรมจากผลัดผู้ใช้ที่จบแล้วไม่ตัดคำตอบทันที ทุก audio frame ยังถูกส่งเข้าโมเดล duplex อย่างต่อเนื่อง ใช้ --no-rnnt-turn-taking เพื่อปิด fallback เหล่านี้และให้ learned language head ตัดสิน BOS/EOS เองทั้งหมด Dashboard แสดง RNN-T barge-in แยกจากช่องว่างในการเล่นเสียง
ในโหมดปกติ ระบบจะระงับ BOS จากโมเดลไว้จนยืนยันเสียงผู้ใช้แล้ว ดังนั้น Soniqo จะไม่พูดก่อน --greet อนุญาตคำทักทายแรกอย่างชัดเจน หลังเนื้อหาคำตอบที่ได้ยิน blank PAD จะยังอยู่ในผลัดที่เปิดอยู่อย่างน้อย 16 frame หรือสาม frame ต่อ content token โดยเลือกค่าที่นานกว่า blank PAD แรกที่เกินงบนี้จะปิดผลัดเชิงตรรกะ ช่วงหางเสียงที่ปรับตามเนื้อหานี้ช่วยรักษาคำที่สร้างช้าและอาจถูกตัดเสียงด้วยขีดจำกัดคงที่ 1.28 วินาที
โหมด interactive ใช้แดชบอร์ดคงที่ใน alternate screen ของ terminal จึงวาดสถานะใหม่ที่เดิมโดยไม่เติม scrollback ใช้ --plain สำหรับเอาต์พุตแบบต่อท้าย
สำหรับการวินิจฉัยในเครื่อง --debug-timeline จะใส่เวลาให้ทุกวลีของผู้ใช้และ Soniqo พร้อมแทรกอาร์กิวเมนต์ของ native call ที่แยกแล้ว การเริ่ม/จบ MCP และการซิงค์ result cache ลงในลำดับเวลาเดียวกัน อีกทั้งทำเครื่องหมาย pronunciation ended ที่หน้าต่าง PCM ที่สร้างขึ้นและได้ยินเป็นช่วงสุดท้าย ซึ่งเป็นเวลาเอาต์พุตของโมเดล ไม่ใช่เวลาที่ลำโพงเล่นจบ เดโมจะไม่แสดงบล็อกเวลาเฟสย้อนหลัง โดยเก็บเมตริก native decode, provider, cache และแรงกดดันของไมโครโฟนไว้ใน JSON ของ voicechat-bench โหมดนี้อาจเปิดเผยอาร์กิวเมนต์ของเครื่องมือ จึงไม่ควรใช้ใน log ที่แชร์ ตัวจับเวลาของเฟสจะรีเซ็ตระหว่าง native decode กับการรอ provider
เซสชันสดเก็บ speaker prompt คงที่ 37 frame และประวัติ EAR-TTS ล่าสุด 20 วินาที ส่วน Nemotron-H เก็บบริบทการสนทนาเชิงความหมายแยกต่างหาก PAD ภายในช่วงหางเสียงที่ปรับตามเนื้อหาจะถูกสร้างตามปกติ มีเพียง PAD เงียบหลังจากนั้นที่เดินสถานะแบบ causal ทีละชุดละแปด จึงไม่ตัดคำตอบที่พูดและยังจำกัดต้นทุน attention ของ TTS กับงานช่วงว่าง ใช้ --live-speech-context-seconds 0 เพื่อเก็บประวัติ TTS ทั้งหมด; โหมดไฟล์ยังใช้ประวัติเต็มแบบตรงตามต้นฉบับเป็นค่าเริ่มต้น
ในการวัด 63.6 วินาทีบน M5 Pro ด้วยช่วงหางเสียงที่ปลอดภัย เส้นทางสดวัด RTF รวม 0.87, RTF ช่วงสุดท้าย 0.71, การสังเคราะห์ช่วงสุดท้าย 4.1 ms/frame, peak RSS 8.72 GB และ peak physical footprint 23.67 GB ช่วงที่กำลังสร้างเสียงด้วยแปดขั้นตอนมี RTF 1.05 และ 1.12 ดังนั้น CLI แบบโต้ตอบยังลดลงเป็นสองขั้นแบบย้อนกลับได้และใช้หนึ่งขั้นในโหมดฉุกเฉินเมื่ออินพุตเริ่มค้าง ค่า cosine similarity ต่ำสุดระหว่างสถานะ idle cache แบบลำดับกับแบบ batch คือ 0.9999999
ตัวตรวจจับเสียงป๊อปช่วงเริ่มต้นของ voicechat-bench ตรวจส่วนเกริ่นและ 50 ms แรกของเสียงพูดต่อเนื่อง โดยทำเครื่องหมายเฉพาะ sample jump ที่เกินแอมพลิจูด 0.05 และหกเท่าของค่า p99 ของเสียงพูดคงที่ และตั้ง maximum_suspect_onset_transients เป็นศูนย์ได้
การรัน Release สามครั้งบน M5 Pro 48 GB วัด RTF ได้ 0.92 ทุกครั้ง, total-frame p95 74.8–75.8 ms, เสียงแรกที่เล่นได้ 74.2–74.9 ms และ peak RSS ประมาณ 8.74 GB ข้อความถอดเสียงและคำตอบเหมือนกันทั้งสามครั้ง
สถาปัตยกรรมและการใช้งาน PersonaPlex
PersonaPlex เป็นโมเดล autoregressive แบบหลายสตรีมที่มีส่วนประกอบหลัก 3 ส่วน:
| ส่วนประกอบ | รายละเอียด |
|---|---|
| Temporal Transformer | 32 layers, dim=4096, 32 heads, SwiGLU (hidden_scale=4.125), RoPE, 8-bit quantized (default) |
| Depformer | 6 layers, dim=1024, 16 heads, MultiLinear (weights_per_step=true), dep_q=16 |
| Mimi Codec | 16 codebooks, 12.5 Hz frame rate, 24 kHz audio output |
โมเดลประมวลผล 17 สตรีม พร้อมกัน: 1 สตรีมข้อความ + 8 สตรีมเสียงผู้ใช้ + 8 สตรีมเสียงเอเจนต์ สถาปัตยกรรมนี้รองรับบทสนทนาแบบฟูล-ดูเพล็กซ์ที่โมเดลสามารถฟังและพูดได้ในเวลาเดียวกัน
พรีเซ็ตเสียง
PersonaPlex มาพร้อมพรีเซ็ตเสียง 18 ตัวในสไตล์ที่เป็นธรรมชาติและหลากหลาย:
| หมวดหมู่ | พรีเซ็ต |
|---|---|
| หญิงธรรมชาติ | NATF0, NATF1, NATF2, NATF3 |
| ชายธรรมชาติ | NATM0, NATM1, NATM2, NATM3 |
| หญิงหลากหลาย | VARF0, VARF1, VARF2, VARF3, VARF4 |
| ชายหลากหลาย | VARM0, VARM1, VARM2, VARM3, VARM4 |
ความคิดภายใน (Inner Monologue)
PersonaPlex สร้างสตรีมขนานสองสตรีมในทุกขั้นตอน: 8 codebook token เสียงสำหรับ codec Mimi และ 1 text token สำหรับ inner monologue ของโมเดล สตรีมข้อความคือสิ่งที่โมเดล “กำลังคิด” ขณะพูด — อาจเบี่ยงเบนเล็กน้อยจากเสียงสุดท้าย แต่ในทางปฏิบัติจะสะท้อนคำตอบที่พูดได้ใกล้พอที่จะใช้เป็นบทถอดความสด
Text token จะกลับมาเป็น raw SentencePiece piece ID ถอดรหัสด้วย SentencePieceDecoder ที่ PersonaPlex ปล่อยมาด้วย:
import PersonaPlex
import AudioCommon
let model = try await PersonaPlexModel.fromPretrained()
let decoder = model.tokenizer // SentencePieceDecoder?
let result = model.respond(userAudio: userSamples, voice: .NATM0)
let transcript = decoder?.decode(result.textTokens) ?? ""
print(transcript) // "Sure, I can help with that..."
playAudio(result.audio) // 24 kHz mono Float32
ในโหมด streaming, respondStream จะปล่อย textTokens chunk ทีละชุดเมื่อถูกสร้างขึ้น — ถอดรหัสทีละขั้นเพื่อขับเคลื่อนหน้า caption แบบสดในขณะที่เสียงยังคงสร้างอยู่ แฟล็ก --transcript CLI ทำสิ่งนี้เบื้องหลังพอดี
เหตุใดเรื่องนี้จึงสำคัญ: SentencePieceDecoder สร้างขึ้นบน protobuf reader ของ AudioCommon.SentencePieceModel ที่ใช้ร่วมกัน ดังนั้น PersonaPlex, OmnilingualASR และโมเดลที่ใช้ SentencePiece อนาคตจึงถอดรหัสผ่าน tokenizer แบบเดียวกัน ดู เอกสารอ้างอิง SentencePieceModel
System Prompt
ส่ง system prompt แบบกำหนดเองใด ๆ เป็นสตริงธรรมดา — ไม่จำเป็นต้องใช้ tokenization ภายนอก:
let response = model.respond(
userAudio: audio,
voice: .NATM0,
systemPrompt: "You enjoy having a good conversation."
)
หรือใช้พรีเซ็ตในตัว:
assistant— ผู้ช่วยอเนกประสงค์ที่เป็นประโยชน์ (ค่าเริ่มต้น)focused— คำตอบที่กระชับและตรงไปตรงมาcustomer-service— เจ้าหน้าที่สนับสนุนที่สุภาพและเน้นการแก้ปัญหาteacher— สไตล์การสอนที่อดทนและอธิบายชัดเจน
การใช้งาน CLI
สร้างคำตอบเป็นเสียงพูดจากอินพุตเสียง:
# Basic speech-to-speech
.build/release/speech respond --input question.wav
# Choose a voice preset
.build/release/speech respond --input question.wav --voice NATM0
# Stream audio output during generation
.build/release/speech respond --input question.wav --stream
# Custom system prompt text
.build/release/speech respond --input question.wav --system-prompt-text "You enjoy having a good conversation."
# Use a preset system prompt
.build/release/speech respond --input question.wav --system-prompt customer-service
# Get transcript alongside audio
.build/release/speech respond --input question.wav --transcript
# JSON output with metadata
.build/release/speech respond --input question.wav --json
ตัวเลือก
| ตัวเลือก | คำอธิบาย |
|---|---|
--input | ไฟล์เสียงอินพุต (WAV, ต้องระบุ) |
--voice | ชื่อพรีเซ็ตเสียง (เช่น NATM0, VARF2) |
--system-prompt | พรีเซ็ต system prompt: assistant, focused, customer-service, teacher |
--system-prompt-text | ข้อความ system prompt แบบกำหนดเอง (เขียนทับ --system-prompt) |
--max-steps | ขั้นตอนการสร้างสูงสุด |
--stream | ปล่อย chunk เสียงระหว่างการสร้าง |
--compile | ใช้ MLX compiled inference เพื่อการสร้างที่เร็วขึ้น |
--transcript | เอาต์พุตบทถอดความข้อความพร้อมกับเสียง |
--json | เอาต์พุต JSON พร้อม metadata |
พารามิเตอร์การสุ่มสามารถเขียนทับได้:
| ตัวเลือก | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|
--audio-temp | 0.8 | อุณหภูมิการสุ่ม audio token |
--audio-top-k | 250 | การสุ่ม top-k ของ audio token |
--text-temp | 0.7 | อุณหภูมิการสุ่ม text token |
--text-top-k | 25 | การสุ่ม top-k ของ text token |
Streaming
แฟล็ก --stream เปิดใช้งานเอาต์พุตเสียงแบบเรียลไทม์ Chunk เสียงจะถูกปล่อยออกมาเมื่อถูกสร้างขึ้น ดังนั้นการเล่นจึงเริ่มต้นได้ก่อนที่คำตอบจะเสร็จสมบูรณ์ มีประโยชน์อย่างยิ่งสำหรับแอปพลิเคชันแบบโต้ตอบที่หน่วงต่ำเป็นสิ่งสำคัญ
ประสิทธิภาพ
| เมตริก | ค่า |
|---|---|
| Real-time factor (RTF) | ~1.4 (8-bit, ใกล้เรียลไทม์) |
| หน่วงของขั้นตอน | ~112 ms/step บน M2 Max (8-bit) |
| ขนาดโมเดล (8-bit) | ~9.1 GB |
| RAM สูงสุด (8-bit) | ~11 GB |
| ขนาดโมเดล (4-bit) | ~4.9 GB |
| RAM สูงสุด (4-bit) | ~7 GB |
PersonaPlex 7B (8-bit) ต้องการ RAM อย่างน้อย 24 GB รุ่น 4-bit พอดีบนอุปกรณ์ 16 GB แต่ผลลัพธ์จะเสื่อมคุณภาพ บนอุปกรณ์ 8 GB จะไม่มีรุ่นใดพอดี ใช้ --compile เพื่อประสิทธิภาพที่ดีที่สุดบนฮาร์ดแวร์ที่รองรับ
รุ่นย่อยของโมเดล
| โมเดล | ขนาด | HuggingFace |
|---|---|---|
| PersonaPlex-7B (8-bit) แนะนำ | 9.1 GB | aufklarer/PersonaPlex-7B-MLX-8bit |
| PersonaPlex-7B (4-bit) | 4.9 GB | aufklarer/PersonaPlex-7B-MLX-4bit |
API Swift
import PersonaPlex
import AudioCommon
let model = try await PersonaPlexModel.fromPretrained()
let response = model.respond(
userAudio: userSamples,
voice: .NATM0,
systemPrompt: "You are a helpful assistant."
)
try WAVWriter.write(samples: response.audio, sampleRate: 24000, to: URL(filePath: "answer.wav"))