PersonaPlex
Mô hình hội thoại speech-to-speech song công dựa trên kiến trúc Moshi (Kyutai). PersonaPlex 7B tạo phản hồi nói trực tiếp từ đầu vào nói — không cần pipeline văn bản trung gian. Mô hình đi kèm 18 preset giọng nói và có sẵn ở dạng lượng tử hóa 8-bit (khuyến nghị) và 4-bit. 8-bit là mặc định — nó nhanh hơn 30% và tạo ra phản hồi mạch lạc, trong khi 4-bit làm suy giảm chất lượng đầu ra.
Kiến trúc
PersonaPlex là một mô hình tự hồi quy đa luồng với ba thành phần cốt lõi:
| Thành phần | Chi tiết |
|---|---|
| Temporal Transformer | 32 lớp, dim=4096, 32 head, SwiGLU (hidden_scale=4.125), RoPE, lượng tử hóa 8-bit (mặc định) |
| Depformer | 6 lớp, dim=1024, 16 head, MultiLinear (weights_per_step=true), dep_q=16 |
| Mimi Codec | 16 codebook, tần số khung 12,5 Hz, đầu ra âm thanh 24 kHz |
Mô hình xử lý đồng thời 17 luồng: 1 luồng văn bản + 8 luồng âm thanh người dùng + 8 luồng âm thanh tác nhân. Kiến trúc này cho phép hội thoại song công, mô hình có thể nghe và nói cùng lúc.
Preset giọng nói
PersonaPlex bao gồm 18 preset giọng tích hợp sẵn với các phong cách tự nhiên và đa dạng:
| Danh mục | Preset |
|---|---|
| Giọng nữ tự nhiên | NATF0, NATF1, NATF2, NATF3 |
| Giọng nam tự nhiên | NATM0, NATM1, NATM2, NATM3 |
| Giọng nữ đa dạng | VARF0, VARF1, VARF2, VARF3, VARF4 |
| Giọng nam đa dạng | VARM0, VARM1, VARM2, VARM3, VARM4 |
Độc thoại nội tâm
PersonaPlex tạo hai luồng song song ở mỗi bước: 8 token audio codebook cho codec Mimi và một token văn bản cho độc thoại nội tâm của mô hình. Luồng văn bản là điều mô hình đang “suy nghĩ” khi nói — nó có thể lệch nhẹ so với âm thanh cuối cùng, nhưng trên thực tế nó phản chiếu phản hồi nói đủ sát để dùng như một transcript trực tiếp.
Các token văn bản quay về dưới dạng ID piece SentencePiece thô. Giải mã chúng bằng SentencePieceDecoder mà PersonaPlex cung cấp:
import PersonaPlex
import AudioCommon
let model = try await PersonaPlexModel.fromPretrained()
let decoder = try model.makeTextDecoder() // SentencePieceDecoder
let result = model.respondWithTranscript(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
Ở chế độ streaming, respondStream phát ra các chunk textTokens khi chúng được tạo ra — giải mã chúng tăng dần để điều khiển một view phụ đề trực tiếp trong khi âm thanh vẫn đang được tạo. Cờ CLI --transcript thực hiện chính xác điều này phía sau hậu trường.
Tại sao điều đó quan trọng: SentencePieceDecoder được xây dựng trên bộ đọc protobuf chia sẻ AudioCommon.SentencePieceModel, vì vậy PersonaPlex, OmnilingualASR và mọi mô hình dựa trên SentencePiece trong tương lai đều giải mã qua cùng một triển khai tokenizer. Xem tham chiếu SentencePieceModel.
System prompt
Truyền bất kỳ system prompt tùy chỉnh nào dưới dạng chuỗi thuần — không cần tokenize bên ngoài:
let response = model.respond(
userAudio: audio,
voice: .NATM0,
systemPrompt: "You enjoy having a good conversation."
)
Hoặc dùng preset có sẵn:
assistant— Trợ lý hữu ích mục đích chung (mặc định)focused— Phản hồi ngắn gọn, trực tiếpcustomer-service— Tác nhân hỗ trợ lịch sự, hướng giải phápteacher— Phong cách giảng dạy kiên nhẫn, giải thích
Sử dụng CLI
Tạo phản hồi nói từ đầu vào âm thanh:
# Speech-to-speech cơ bản
.build/release/speech respond --input question.wav
# Chọn một preset giọng
.build/release/speech respond --input question.wav --voice NATM0
# Streaming đầu ra âm thanh trong khi sinh
.build/release/speech respond --input question.wav --stream
# Văn bản system prompt tùy chỉnh
.build/release/speech respond --input question.wav --system-prompt-text "You enjoy having a good conversation."
# Dùng một preset system prompt
.build/release/speech respond --input question.wav --system-prompt customer-service
# Lấy transcript kèm âm thanh
.build/release/speech respond --input question.wav --transcript
# Đầu ra JSON với metadata
.build/release/speech respond --input question.wav --json
Tùy chọn
| Tùy chọn | Mô tả |
|---|---|
--input | Tệp âm thanh đầu vào (WAV, bắt buộc) |
--voice | Tên preset giọng (ví dụ NATM0, VARF2) |
--system-prompt | Preset system prompt: assistant, focused, customer-service, teacher |
--system-prompt-text | Văn bản system prompt tùy chỉnh (ghi đè --system-prompt) |
--max-steps | Số bước sinh tối đa |
--stream | Phát các chunk âm thanh trong khi sinh |
--compile | Dùng suy luận compile của MLX để sinh nhanh hơn |
--transcript | Đầu ra transcript văn bản kèm âm thanh |
--json | Đầu ra JSON với metadata |
Các tham số lấy mẫu cũng có thể được ghi đè:
| Tùy chọn | Mặc định | Mô tả |
|---|---|---|
--audio-temp | 0.8 | Nhiệt độ lấy mẫu token âm thanh |
--audio-top-k | 250 | Lấy mẫu top-k token âm thanh |
--text-temp | 0.7 | Nhiệt độ lấy mẫu token văn bản |
--text-top-k | 25 | Lấy mẫu top-k token văn bản |
Streaming
Cờ --stream bật đầu ra âm thanh thời gian thực. Các chunk âm thanh được phát ra khi chúng được tạo, vì vậy việc phát lại có thể bắt đầu trước khi phản hồi đầy đủ hoàn tất. Điều này đặc biệt hữu ích cho các ứng dụng tương tác mà độ trễ thấp là quan trọng.
Hiệu năng
| Chỉ số | Giá trị |
|---|---|
| Hệ số thời gian thực (RTF) | ~1,4 (8-bit, gần thời gian thực) |
| Độ trễ mỗi bước | ~112 ms/bước trên M2 Max (8-bit) |
| Kích thước mô hình (8-bit) | ~9,1 GB |
| RAM đỉnh (8-bit) | ~11 GB |
| Kích thước mô hình (4-bit) | ~4,9 GB |
| RAM đỉnh (4-bit) | ~7 GB |
PersonaPlex 7B (8-bit) yêu cầu tối thiểu 24 GB RAM. Biến thể 4-bit chạy được trên thiết bị 16 GB nhưng tạo ra đầu ra suy giảm. Trên thiết bị 8 GB, không biến thể nào chạy được. Dùng --compile để có hiệu năng tốt nhất trên phần cứng hỗ trợ.
Biến thể mô hình
| Mô hình | Kích thước | HuggingFace |
|---|---|---|
| PersonaPlex-7B (8-bit) khuyến nghị | 9,1 GB | aufklarer/PersonaPlex-7B-MLX-8bit |
| PersonaPlex-7B (4-bit) | 4,9 GB | aufklarer/PersonaPlex-7B-MLX-4bit |
API Swift
import PersonaPlex
let model = try await PersonaPlexModel.loadFromHub()
let response = try await model.respond(
audioFile: "question.wav",
voice: .NATM0,
systemPrompt: .assistant
)
try response.audio.write(to: "answer.wav")