Konuşmadan konuşmaya modeller

Soniqo, konuşmadan konuşmaya diyalog için iki native MLX model ailesini destekler: PersonaPlex 7B ve VoiceChat 11B. İkisi de konuşmayı alıp model sesini doğrudan üretir, ancak duplex mimarileri ve runtime sözleşmeleri farklıdır.

Model seçin

ModelDiyalog modeliEn uygun kullanım
PersonaPlex 7BMoshi, Depformer ve Mimi ile eşzamanlı full duplexDinleme ve konuşmanın örtüşmesi, seçilebilir 18 ses
VoiceChat 11BFastConformer, Nemotron-H, EAR-TTS ve neural codec ile sürekli frame-synchronous duplex80 ms streaming frame'leri, metin/işlev event'leri ve checkpoint-native konuşma

Bunlar konuşmadan konuşmaya diyalog modelleridir. Hibiki de konuşmayı doğrudan konuşmaya dönüştürür; ancak görevi streaming konuşma çevirisidir ve ayrı belgelenir.

PersonaPlex 7B

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.

VoiceChat 11B

Duplex speech-to-speech referansı: SALM-Duplex: Efficient and Direct Duplex Modeling for Speech-to-Speech Language Model (Interspeech 2025); NVIDIA'nın upstream VoiceChat model kartında atıf yapılır.

M5 Pro, 48 GB, Release, 80 ms canlı ritim, korumalı head INT5: üç kontrollü çalıştırma tüm pipeline RTF'sini 0.94, 0.92 ve 0.92; tepe RSS'yi yaklaşık 8.70 GB ölçtü. İlk konuşulan metin 44.3–46.7 ms, ilk oynatılabilir ses 74.0–76.4 ms içinde geldi. Bunlar ısınmış hesaplama değerleridir, öğrenilmiş sıra alma gecikmesi değildir; optimize INT8 performansı henüz yeniden ölçülmedi.

VoiceChat, speech-swift'teki diğer native MLX konuşmadan-konuşmaya runtime'ıdır. Nedensel FastConformer algı, Nemotron-H duplex metin/işlev kanalları, bağımsız metin koşullu EAR-TTS ve 22,05 kHz nöral codec'i birleştirir. Session sürekli 16 kHz mono ses alır ve her 80 ms'de metin olaylarıyla 1.764 örneklik bir çıkış frame'i döndürür.

VoiceChatModel.load(from:) ile yükleyin, bir VoiceChatSession başlatın ve sesi pushAudio ile verin. Eksiksiz bundle encoder/, llm/ ve tts/ içermelidir; eski yalnızca-anlama bundle'ları reddedilir.

Güncel performans

INT5, test edilen M5 Pro'da RTF 1'in altında toplam throughput sürdürür. Üç çalıştırmanın tamamında toplam/frame p95 76.2–78.6 ms ile 80 ms'nin altında kaldı; yine de deadline payı dardır. Modelin konuşma başlangıcı ile donanım hesaplama gecikmesini ayrı ölçün.

PersonaPlex mimarisi ve kullanımı

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 = 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 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:

# 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

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