PersonaPlex

Moshi mimarisine (Kyutai) dayanan çift yönlü speech-to-speech diyalog modeli. PersonaPlex 7B, konuşulan girdiden doğrudan konuşulan yanıtlar üretir — ara metin pipeline'ı gerekmez. Model 18 ses preset'i ile birlikte gelir ve 8-bit (önerilen) ile 4-bit niceleme olarak sunulur. Varsayılan 8-bit'tir — %30 daha hızlıdır ve tutarlı yanıtlar üretir; 4-bit ise çıktı kalitesini düşürür.

Mimari

PersonaPlex, üç temel bileşene sahip çok akışlı otoregresif bir modeldir:

BileşenDetaylar
Temporal Transformer32 katman, dim=4096, 32 head, SwiGLU (hidden_scale=4.125), RoPE, 8-bit nicelenmiş (varsayılan)
Depformer6 katman, dim=1024, 16 head, MultiLinear (weights_per_step=true), dep_q=16
Mimi Codec16 codebook, 12,5 Hz frame oranı, 24 kHz ses çıktısı

Model aynı anda 17 akış işler: 1 metin akışı + 8 kullanıcı ses akışı + 8 ajan ses akışı. Bu mimari, modelin aynı anda dinleyip konuşabildiği çift yönlü konuşmayı mümkün kılar.

Ses preset'leri

PersonaPlex, doğal ve çeşitli stillerde 18 yerleşik ses preset'i içerir:

KategoriPreset'ler
Doğal KadınNATF0, NATF1, NATF2, NATF3
Doğal ErkekNATM0, NATM1, NATM2, NATM3
Çeşitli KadınVARF0, VARF1, VARF2, VARF3, VARF4
Çeşitli ErkekVARM0, VARM1, VARM2, VARM3, VARM4

İç monolog

PersonaPlex her adımda iki paralel akış üretir: Mimi codec için 8 audio codebook token'ı ve modelin iç monoloğu için bir metin token'ı. Metin akışı, modelin konuşurken “düşündüğü” şeydir — nihai sesten hafifçe sapabilir ama pratikte konuşulan yanıtı, canlı bir transkript olarak kullanmaya yetecek kadar yakından yansıtır.

Metin token'ları ham SentencePiece piece ID'leri olarak geri döner. Onları PersonaPlex'in sunduğu SentencePieceDecoder ile çözün:

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

Streaming modunda respondStream, textTokens chunk'larını üretildikçe yayar — ses hâlâ üretilmekteyken bir canlı altyazı görünümünü sürmek için bunları artımlı olarak çözün. --transcript CLI bayrağı tam olarak bunu perde arkasında yapar.

Neden önemli: SentencePieceDecoder, paylaşılan AudioCommon.SentencePieceModel protobuf okuyucusu üzerine inşa edilmiştir; bu nedenle PersonaPlex, OmnilingualASR ve gelecekteki tüm SentencePiece tabanlı modeller aynı tokenizer uygulaması üzerinden çözer. SentencePieceModel referansına bakın.

System prompt'ları

Herhangi bir özel system prompt'u düz bir string olarak iletin — harici tokenize gerekmez:

let response = model.respond(
    userAudio: audio,
    voice: .NATM0,
    systemPrompt: "You enjoy having a good conversation."
)

Veya yerleşik bir preset kullanın:

CLI kullanımı

Bir ses girdisinden konuşulan yanıt üretin:

# Temel speech-to-speech
.build/release/speech respond --input question.wav

# Bir ses preset'i seç
.build/release/speech respond --input question.wav --voice NATM0

# Üretim sırasında ses çıktısını streaming
.build/release/speech respond --input question.wav --stream

# Özel system prompt metni
.build/release/speech respond --input question.wav --system-prompt-text "You enjoy having a good conversation."

# Preset system prompt kullan
.build/release/speech respond --input question.wav --system-prompt customer-service

# Sesle birlikte transkript al
.build/release/speech respond --input question.wav --transcript

# Metadata ile JSON çıktısı
.build/release/speech respond --input question.wav --json

Seçenekler

SeçenekAçıklama
--inputGiriş ses dosyası (WAV, gerekli)
--voiceSes preset adı (örn. NATM0, VARF2)
--system-promptSystem prompt preset'i: assistant, focused, customer-service, teacher
--system-prompt-textÖzel system prompt metni (--system-prompt'u geçersiz kılar)
--max-stepsMaksimum üretim adımı
--streamÜretim sırasında ses chunk'larını yay
--compileDaha hızlı üretim için MLX derlenmiş çıkarımı kullan
--transcriptSesle birlikte metin transkriptini çıkar
--jsonMetadata ile JSON çıktısı

Örnekleme parametreleri de geçersiz kılınabilir:

SeçenekVarsayılanAçıklama
--audio-temp0.8Ses token örnekleme sıcaklığı
--audio-top-k250Ses token top-k örnekleme
--text-temp0.7Metin token örnekleme sıcaklığı
--text-top-k25Metin token top-k örnekleme

Streaming

--stream bayrağı gerçek zamanlı ses çıktısını etkinleştirir. Ses chunk'ları üretildikçe yayılır; böylece tam yanıt tamamlanmadan önce çalma başlayabilir. Bu, düşük gecikmenin önemli olduğu etkileşimli uygulamalar için özellikle yararlıdır.

Performans

MetrikDeğer
Gerçek zaman katsayısı (RTF)~1,4 (8-bit, gerçek zamana yakın)
Adım gecikmesiM2 Max'ta ~112 ms/adım (8-bit)
Model boyutu (8-bit)~9,1 GB
Tepe RAM (8-bit)~11 GB
Model boyutu (4-bit)~4,9 GB
Tepe RAM (4-bit)~7 GB
Önemli

PersonaPlex 7B (8-bit) en az 24 GB RAM gerektirir. 4-bit varyant 16 GB cihazlara sığar ancak düşük kaliteli çıktı üretir. 8 GB cihazlarda hiçbir varyant sığmaz. Desteklenen donanımda en iyi performans için --compile kullanın.

Model varyantları

ModelBoyutHuggingFace
PersonaPlex-7B (8-bit) önerilen9,1 GBaufklarer/PersonaPlex-7B-MLX-8bit
PersonaPlex-7B (4-bit)4,9 GBaufklarer/PersonaPlex-7B-MLX-4bit

Swift API

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")