PersonaPlex
Modèle de dialogue parole-à-parole full-duplex basé sur l'architecture Moshi (Kyutai). PersonaPlex 7B génère des réponses parlées directement à partir d'une entrée parlée — sans pipeline texte intermédiaire. Le modèle est livré avec 18 préréglages de voix et est disponible en quantification 8 bits (recommandée) et 4 bits. Le 8 bits est la valeur par défaut — il est 30 % plus rapide et produit des réponses cohérentes, tandis que le 4 bits dégrade la qualité de sortie.
Architecture
PersonaPlex est un modèle autorégressif multi-flux avec trois composants principaux :
| Composant | Détails |
|---|---|
| Temporal Transformer | 32 couches, dim=4096, 32 têtes, SwiGLU (hidden_scale=4.125), RoPE, quantifié 8 bits (par défaut) |
| Depformer | 6 couches, dim=1024, 16 têtes, MultiLinear (weights_per_step=true), dep_q=16 |
| Mimi Codec | 16 codebooks, taux de trame 12,5 Hz, sortie audio 24 kHz |
Le modèle traite 17 flux simultanément : 1 flux texte + 8 flux audio utilisateur + 8 flux audio agent. Cette architecture permet une conversation full-duplex où le modèle peut écouter et parler en même temps.
Préréglages de voix
PersonaPlex inclut 18 préréglages de voix intégrés dans des styles naturels et variés :
| Catégorie | Préréglages |
|---|---|
| Femme naturelle | NATF0, NATF1, NATF2, NATF3 |
| Homme naturel | NATM0, NATM1, NATM2, NATM3 |
| Femme variée | VARF0, VARF1, VARF2, VARF3, VARF4 |
| Homme varié | VARM0, VARM1, VARM2, VARM3, VARM4 |
Monologue intérieur
PersonaPlex génère deux flux parallèles à chaque étape : 8 tokens de codebook audio pour le codec Mimi et un token de texte pour le monologue intérieur du modèle. Le flux de texte est ce que le modèle « pense » pendant qu'il parle — il peut diverger légèrement de l'audio final, mais en pratique il reflète suffisamment la réponse parlée pour être utilisé comme transcription en direct.
Les tokens de texte reviennent sous forme d'IDs de pièces SentencePiece bruts. Décodez-les avec le SentencePieceDecoder fourni par PersonaPlex :
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) // Float32 mono 24 kHz
En mode streaming, respondStream émet des chunks textTokens à mesure qu'ils sont produits — décodez-les de façon incrémentale pour piloter une vue de sous-titres en direct pendant que l'audio est encore en génération. L'option CLI --transcript fait exactement cela en coulisses.
Pourquoi c'est important : SentencePieceDecoder est construit sur le lecteur protobuf partagé AudioCommon.SentencePieceModel, donc PersonaPlex, OmnilingualASR et tout futur modèle basé sur SentencePiece décodent via la même implémentation de tokenizer. Voir la référence SentencePieceModel.
Prompts système
Passez n'importe quel prompt système personnalisé sous forme de chaîne simple — aucune tokenisation externe n'est nécessaire :
let response = model.respond(
userAudio: audio,
voice: .NATM0,
systemPrompt: "You enjoy having a good conversation."
)
Ou utilisez un préréglage intégré :
assistant— Assistant utile polyvalent (par défaut)focused— Réponses concises et directescustomer-service— Agent de support poli et orienté solutionteacher— Style d'enseignement patient et explicatif
Utilisation en CLI
Générer une réponse parlée à partir d'une entrée audio :
# Parole-à-parole basique
.build/release/audio respond --input question.wav
# Choisir un préréglage de voix
.build/release/audio respond --input question.wav --voice NATM0
# Streamer la sortie audio pendant la génération
.build/release/audio respond --input question.wav --stream
# Texte de prompt système personnalisé
.build/release/audio respond --input question.wav --system-prompt-text "You enjoy having a good conversation."
# Utiliser un prompt système préréglé
.build/release/audio respond --input question.wav --system-prompt customer-service
# Obtenir la transcription avec l'audio
.build/release/audio respond --input question.wav --transcript
# Sortie JSON avec métadonnées
.build/release/audio respond --input question.wav --json
Options
| Option | Description |
|---|---|
--input | Fichier audio d'entrée (WAV, requis) |
--voice | Nom de préréglage de voix (ex. NATM0, VARF2) |
--system-prompt | Préréglage de prompt système : assistant, focused, customer-service, teacher |
--system-prompt-text | Texte de prompt système personnalisé (prime sur --system-prompt) |
--max-steps | Étapes de génération maximum |
--stream | Émettre des chunks audio pendant la génération |
--compile | Utiliser l'inférence compilée MLX pour une génération plus rapide |
--transcript | Afficher la transcription textuelle avec l'audio |
--json | Sortie JSON avec métadonnées |
Les paramètres d'échantillonnage peuvent également être surchargés :
| Option | Par défaut | Description |
|---|---|---|
--audio-temp | 0,8 | Température d'échantillonnage des tokens audio |
--audio-top-k | 250 | Échantillonnage top-k des tokens audio |
--text-temp | 0,7 | Température d'échantillonnage des tokens texte |
--text-top-k | 25 | Échantillonnage top-k des tokens texte |
Streaming
L'option --stream active la sortie audio en temps réel. Les chunks audio sont émis à mesure qu'ils sont générés, donc la lecture peut commencer avant que la réponse complète ne soit terminée. C'est particulièrement utile pour les applications interactives où une faible latence compte.
Performance
| Métrique | Valeur |
|---|---|
| Facteur temps réel (RTF) | ~1,4 (8 bits, proche du temps réel) |
| Latence par étape | ~112 ms/étape sur M2 Max (8 bits) |
| Taille du modèle (8 bits) | ~9,1 Go |
| RAM en pic (8 bits) | ~11 Go |
| Taille du modèle (4 bits) | ~4,9 Go |
| RAM en pic (4 bits) | ~7 Go |
PersonaPlex 7B (8 bits) requiert au moins 24 Go de RAM. La variante 4 bits tient sur des appareils 16 Go mais produit une sortie dégradée. Sur des appareils 8 Go, aucune variante ne tiendra. Utilisez --compile pour de meilleures performances sur le matériel pris en charge.
Variantes du modèle
| Modèle | Taille | HuggingFace |
|---|---|---|
| PersonaPlex-7B (8 bits) recommandé | 9,1 Go | aufklarer/PersonaPlex-7B-MLX-8bit |
| PersonaPlex-7B (4 bits) | 4,9 Go | 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")