Maskinoversættelse · Engelsk original
Tale-til-tale modeller
Soniqo understøtter to indfødte MLX model familier for konversationel speech- to- tale: PersonaPlex 7B og VoiceChat 11B. Både forbruge tale og generere model lyd direkte, men de bruger forskellige duplex arkitekturer og runtime kontrakter.
Vælg en model
| Model | Samtalemodel | Bedste pasform |
|---|---|---|
| PersonaPlex 7B | Samtidig fuld duplex med Moshi, Depformer og Mimi | Overlappende lytte / tale adfærd og 18 valgbare stemmer |
| VoiceChat 11B | Kontinuerlig, frame- synkron duplex med FastConformer, Nemotron- H, EAR- TTS, og neuralcodec | 80 ms streaming rammer, tekst / funktion begivenheder, og checkpoint- native tale |
Det er konversationelle talemodeller. Hibiki Formand også kort tale direkte til tale, men dens opgave er streaming tale oversættelse, så det er dokumenteret separat.
PersonaPlex 7B
Full- duplex speech- to- tale dialog model baseret på Moshi arkitektur (Kyutai). PersonaPlex 7B genererer talte svar direkte fra talt input - ingen mellemliggende tekstrørledning kræves. Modellerne skibe med 18 stemme presets og er tilgængelig i 8- bit (anbefalet) og 4-bit kvantisering. 8- bit er standard - det er 30% hurtigere og producerer sammenhængende svar, mens 4- bit nedbryder output kvalitet.
VoiceChat 11B
Duplex speech- to- tale reference: SALM- Duplex: Effektiv og direkte Duplex-modellering til tale- to- tale- sprogmodel (Intertaly 2025), citeret ved NVIDIA 's opstrømsmodel VoiceChat-kort.
M5 Pro, 48 GB, Release 80 ms live kadence, protected-head INT5: tre kontrollerede køreledninger målt som helrørsstrøm RTF 0.94, 0.92, og 0.92, med ca. 8.70 GB peak RSS. Første talte tekst ankom i 44.3–46.7 ms og første spilbar lyd i 74.0–76.4 ms. Det er varme computertal, ikke lært turn- tage latency; optimeret INT8 Præstationen er endnu ikke blevet genmålt.
VoiceChat er den anden indfødt MLX speech- to- tale runtime in speech-swift. Det kombinerer kausal FastConformer opfattelse, Nemotron- H duplex tekst / funktion kanaler, standalone lære- konditioneret EAR- TTS, og en 22.05 kHz neuralcodec. En session accepterer 16 kHz mono audio kontinuerligt og returnerer tekstbegivenheder plus en 1,764-prøve output ramme hver 80 ms.
Anvendelse VoiceChatModel.load(from:), start en VoiceChatSession, og feed audio med pushAudio. En komplet bundt skal indeholde encoder/, llm/, og tts/; ældre forståelse-kun bundter afvises.
INT5 vedligeholder den samlede kapacitet nedenfor RTF 1 på den afprøvede prøve M5 Pro. Alle tre kørsler også holdt total / ramme p95 Nedenfor 80 ms, at 76.2–78.6 ms; deadline headroom derfor forbliver smal. Behandl model turn debut og hardware beregne latency som separate målinger.
Live VoiceChat CLI
Tal med Soniqo ved hjælp af det komplette beskyttelseshoved INT5 bundt, drevet af NVIDIA Nemotron VoiceChat 11B. Kommandoen holder fange og afspilning på en AVAudioEngine til Apple AEC, strømmer bundets RNN-T brugerbilleder, og spiller 22.05 kHz model lyd, mens du fortsætter med at lytte.
Standard Soniqo prompt er capability- bundtet: denne CLI kan konversere og besvare spørgsmål, men det kan ikke få adgang til kalendere, påmindelser, apps, konti, enheder eller eksterne tjenester. For disse anmodninger Soniqo klart siger, at det ikke kan udføre handlingen, ikke bede om en bekræftelse, det ikke kan opfylde, og kort foreslår, hvad brugeren kan gøre i stedet.
speech voice-chat
speech voice-chat --input question.wav --output response.wav
Konfigurerbare MCP værktøjer
MCP er deaktiveret, medmindre --mcp-config leveres. Leverandør- neutral JSON-fil kan starte enhver stdio MCP server og eksplicit vælger hvilke opdagede værktøjer når VoiceChat. Den bevidst smal Apple Reminders eksempel udsætter liste, oprette og opdatere workflows; brugerdefinerede konfigurationer kan aktivere andre serverværktøjer:
speech voice-chat \
--mcp-config Examples/VoiceChatMCP/apple-reminders.json
Den bundtet eksempel pins en EventKit- backed udbyder bag en apple-reminders-eventkit adapter. VoiceChat udsætter kun den kanoniske list_reminders, create_reminder, og update_reminder Operationer - ikke udbyderens slette, list- mutation, kalender eller subtask handlinger. Listeopdagelse forbliver privat til adapteren. En påmindelse og dens forfaldsdato er forpligtet i én EventKit gemme, undgå den tidligere partial- skrive fiasko, der kunne efterlade en forældet påmindelse bag. Udbyderen kan kompilere sin lille Swift hjælper ved første brug, så start har en separat 60- andet fradrag; normale værktøjskald holde 15-anden standard.
Kun enabledTools er vist til modellen, med et maksimum på fem per session. Værktøjer er skriver, medmindre konfigurationen udtrykkeligt lister dem i readOnlyTools. Skriver standard til --mcp-write-policy allow, så en komplet indfødte opkald udfører straks og dens virkelige udbyder resultat driver svaret; påmindelser demo ikke tilføje en anden bekræftelse drejning. En identisk afsluttet skrive er stadig undertrykt indtil frisk akustisk aktivitet. Brug confirm for eksplicit model- medieret bekræftelse eller deny at deaktivere skriver.
Der er ingen udskrift router, regular- expression matcher, slot ekstraktor, påmindelse udkast stat, argument reparation, spoken- navn resolver, eller scripted assisterende tale. Checkpoint alene vælger værktøjet og argumenter. Koordinatoren validerer mulighed- tool medlemskab og JSON typer, anvender politik, kalder MCP, og returnerer struktureret succes eller fiasko gennem den trænede funktion-svar kanal. Fejlede udbyderens resultater, ugyldige argumenter, nægtet skriver, og utilgængelige værktøjer suspenderer nye funktioner starter indtil checkpoint åbner en talt assisterende vending; dette forhindrer en tavs-forsøg loop, mens forlader senere model- kontrolleret. Reminders facade kræver kun name til oprettelse og udlægning af alle EventKit-lister i én list_reminders read. Det præsenterer lang udbyder UUID 'er som stabil, session- scoped referencer såsom r1, løser derefter en nøjagtig model- returneret reference før update_reminder udførelse. Dette er tabsfri ID-komprimering, ikke udskrift eller intention matching. Manglende eller ugyldige værdier gå tilbage til modellen for en naturlig afklaring; de er aldrig tavst udledt fra den viste udskrift.
Model- native opkald JSON kører asynkront på en cached stilhed indlejring. Når et opkald er åbent, kraft- PAD tekst kanal springer sin ubrugte 131,072-række projektion. Efter EOTC, den tofasede sti fryser det delte sprog og EAR- TTS tidslinje, mens det eksterne resultat venter, matchende NVIDIA's reference wrapper; mikrofon rammer fortsætte gennem opfattelse og RNN-T, men er ikke indsat som syntetisk PAD positioner. Kendt resultat tokens spil i afgrænset 16-token causal- prefill stykker. Sessionen giver mellem opkald tokens og resultat batches, eksterne MCP I / O kører i en separat opgave, og live mikrofon opfattelse plus RNN-T billedtekster forbliver støtteberettigede i hele. Tilbageholdt brugertale re- indtaster den delte tidslinje på højst én gammel semantisk ramme pr live callback; den nuværende ramme forbliver i kø, forløbet replay lyd er dæmpet, og tomgang EAR- TTS positioner synkronisere senere i afgrænset oight- frame stykker. Den levende løkke læser sammenhængende funktion og MCP status snapshots hver 160 ms i stedet for at gøre flere skuespillere opkald efter hver mikrofon ramme. Det interaktive instrumentbræt rapporterer den aktive værktøjsserie; den strukturerede benchmark registrerer native dekode, MCP rundtur, resultat synkronisering, model / cache beregne, og live interleave resterende separat. Almindelig samtale og barge- in holde NVIDIA 's 40- frame sikkerhed fallback; en allerede foreslået indfødte værktøj kandidat kan forpligte efter otte blanke rammer.
På tomgang M5 Pro med 48 GB, tre indfødte påmindelser-liste sætninger nået model- forfattet post- tool tale 3.56–4.00 sekunder efter afslutning af inddata med fast 200 ms udbyder. Native JSON tog 1.15–1.28 sekunder til 27–31 trin; 67-token resultat tog 0.58–0.72 sekunder i fem foretrækker. En fokuseret opdatering regression kræves 67 native trin / 5.25 sekunder, hvor modellen gentog en realistisk EventKit UUID, versus 37 trin / om 2.29 sekunder med løst løst r1 reference -45% færre symbolske trin og omkring 56% mindre afkodningstid. En separat to-sekunders-udbyder stress holdt provider- vent mikrofon arbejde på 19.6 ms p95 og 19.8 ms maksimum, så eksterne I / O tilføjer svar forsinkelse uden at holde fange. En endelig ren løb målt 118 ms microphone- service p95 og 139 ms p95 Forsinkelse 80 ms input deadlines; sidstnævnte udsætter korte resultater- sync queuing sprængninger skjult af forgrund RTFDen lokale EventKit læste sig selv målt 358 ms efter one-time MCP start. En testet kreation sætning blev transskriberet korrekt, men valgt almindelig tale snarere end en native opkald; dette forbliver model værktøj- udvælgelse kvalitet, ikke en skjult runtime router.
Den concurrency grænse er den delte Nemotron- H KV cache: almindelige resultater- betinget tale kan ikke danne en anden uafhængig årsagssammenhæng fremtid, mens funktion tokens bliver genereret eller genspillet. Soniqo genoptager sammenhængende, model- forfattet tale efter <SPECIAL_22> lukker værktøjet svar. Fuldt overlappende vilkårlig tale ville kræve en spekulativ anden cache og fletning politik, eller en separat uddannet funktion dekoder.
Barn MCP servere arve kun PATH, HOME, temporary- directory, og locale variabler. Valgret skal være udtrykkeligt vedtaget i serverens env kort; ikke-relaterede parente- proces- hemmeligheder videresendes ikke. Den indstillede kommando kører stadig lokalt med den nuværende brugers filsystem og programtilladelser, så brug kun betroede MCP konfigurationsfiler og serverpakker.
Den 8-bit funktion projektion er omkring 518 MB. Under almindelig tale, VoiceChat evaluerer kun en cache 36 KB PAD / tool- start probe. Hvis værktøjs- start vinder før drejningsgrænsen, kun dens 4,096-value hidden- state kandidat er bevaret; full-ordforrådsverificering kører, når lært BOS ankommer eller den endelige RN- T sikkerhedsendpoint udløber. For en generisk native opkald, verificeret opkald JSON derefter kører på fuld language- model hastighed på en opfattelse indlejret fra et sekund af tavshed i stedet for en gang 80 ms mikrofon ramme. MCP resultat er kendt, VoiceChat gengiver det i afgrænset 16-token causal- prefill stykker, bevare den uddannede funktion feedback og sprog / tale cache tilstand uden en 11B dekodere per resultat token. Sessionen giver mellem genererede opkald tokens og response- prefill stykker så live mikrofon opfattelse, RNN-T billedtekster, og bæredygtig-tale afbrydelse detektion fortsætte; separate opkald og svar grænser konvertere misdannede PAD-kun arbejde i en eksplicit gentry snarere end en permanent stall.
Playback prebuffere tre 80 ms frames (240 ms) som standard. Efter en højttaler mellemrum, venter det på en otte- frame recovery pude før genstart. Kun akustisk raffinement falder fra otte til to trin efter de første 88 ms callback, eller når tre rammer kø; en 120 ms callback- ramme, seks queued rammer, eller input resynchronization går direkte til et nødtrin. Kun akustiske raffinement ændringer - opfattelse, RNT, og sprogtilstand forbliver intakt. Hvis køen stadig når sin standard Eight- frame / 640 ms grænse, kun den mindste ældste mikrofon lyd til at indrømme frisk input er kasseret. Vedvarende overbelastning behandles som en episode allerede, vende og bekræftet af NT er stadig bekræftet ved at blive bekræftet ved ip.
Dashboardet bruger menneskelige-vender målinger: behind er i kø med mikrofonlyd RTF 0.93× er den rullende middelværdi over den seneste 120 mikrofon callbacks af vægtid divideret med 80 ms af lyd (under 1 holder op; over 1 falder bag), og last 74 ms for 80 ms audio betyder den seneste callback tog 74 ms. Replay begivenheder er ikke tælles som ekstra lydnævnere. Fordi RTF er et vindue, kan det forblive højt kort efter en dyr operation, selv når last er kommet sig. Under samtalen speaker gaps, old-audio skips, og microphone audio skipped gøre inddrivelse eksplicit. PLEASE REPEAT vises kun, når mikrofon lyd faktisk blev sprunget.
Mikrofontilstand bruger NVIDIA- stil RNN- T turn- take som standard. Udskriftshovedet behandler sin første forudsigelse på hver 80 ms ramme som blank eller ikke-blank. To indledende tale rammer og tre på senere drejninger forbliver bæredygtig-aktivitet fallbacks, mens en anerkendt leksical token straks arme en tomgang så en komplet "ja" eller "hvem er du?" kan ikke vises i billedtekst og derefter vente på mere tale. Punktuation og ukendte etiketter ikke bruge denne genvej. VoiceChater lært BOS / EOS forudsigelser forbliver de normale lav- latency beslutninger. Fyrre blanke rammer (3.2 sekunder) kraft BOS kun, hvis den lærde hoved aldrig åbner en reaktion, og fyrre friske ikke-blanke rammer giver den matchende RNN-T EOS sikkerhed fallback. Soniqo starter, så aktivitet fra den afsluttede brugervending kan ikke straks skære svaret. Hver lydramme stadig når duplex model; brug --no-rnnt-turn-taking at forlade BOS / EOS beslutninger helt til den lærde sproghoved. Dashboard rapporterer RNN-T barge- ins adskilt fra afspilning underkørsler.
Den RN- T frontend matcher NeMo 's refleksion polstring på hver rullende microphone- vindue kant. Dette fjerner en zero-polstring mismatch, der kunne ændre marginale grådige token beslutninger; det erstatter ikke checkpoint kompakte 1,024- token udskrift hoved med en generel large- ordforråd ASR.
I normal tilstand, model- native BOS undertrykkes indtil brugertalen er bekræftet, så Soniqo ikke taler først. --greet udtrykkeligt tillader den første hilsen. Efter hørbart svar indhold, blank PAD forbliver inde i det åbne sving for mindst 16 rammer og for tre rammer per indhold token, når det er længere. Den første overskydende blank PAd lukker den logiske drejning. Denne indhold- skaleret hale bevarer forsinkede ord, som en fast 1.28- anden cutoff kan slå.
Interaktiv tilstand bruger et fast instrumentbræt i terminalens alternative skærm, så statusopdateringer gentegne på plads i stedet for at fylde rulletilbage. Brug --plain for vedhæng-kun output.
Til lokal diagnose, --debug-timeline tidsstempler hver bruger og Soniqo sætning og indsætter de fortolkede indfødte call argumenter, MCP start / fuldførelse, og result- cache synkronisering i samme kronologi. pronunciation ended ved den endelige audible generated- PCM vindue; dette er model- output tid, ikke taler-enhed afslutning. Demo bevidst udelader historiske fase- timing blokke; detaljeret native- decode, udbyder, cache, og microphone- tryk målinger forbliver i voicechat-bench JSON. Tidslinjen kan afsløre værktøj argumenter, så brug det ikke i delte logs. Fase timere nulstilles mellem indfødte dekode og udbyder vente.
Tre M5 Pro 48 GB-udgivelsesforløb målt RTF 0.92, total- frame p95 74.8–75.8 ms, første spilbar lyd 74.2–74.9 ms, og om 8.74 GB peak RSS. Udskrift og svar var identiske på tværs af løbene.
Live sessioner holder den uforanderlige 37- frame højttaler prompt plus 20 sekunder af den seneste EAR- TTS historie, mens Nemotron- H holder semantisk samtale tilstand separat. PAD inde i indholdskaleret akustisk hale er normalt renderes; kun senere stille PAD forskud kausalt i partier på otte. Dette forhindrer TTS opmærksomhed og tomgang arbejde fra at vokse uden bundet uden at skære den talte svar; --live-speech-context-seconds 0 genopretter fuld TTS historie, og filtilstand forbliver præcis full- historie som standard.
I et 63.6- anden M5 Pro profil med indhold- sikker hale, den levende sti målt aggregat RTF 0.87, slut- vindue RTF 0.71, 4.1 ms / frame final- window synthesis 8.72 GB peak RSS, og 23.67 GB toppe fysisk fodaftryk. Speech- aktive eight- step vinduer nået RTF 1.05 og 1.12, så den interaktive CLI bruger en reversibel to-trins fallback og et-trins nødtilstand. Onetrins syntese tildeler alle 31 RVQ kodebøger i et enkelt pass; det beskytter live capture, men er ikke akustisk paritet med eight- step tidsplan. Sekventiel og bøjet idle- cache stater havde minimum cosin 0.9999999.
For lyd diagnose, benchmarket sammenligner den afgrænset levende codec- vindue rende med en kontinuerlig full-kontekst rende. En lang pause til stede i begge blev genereret af EAR- TTS eller codec, ikke af højttaleren kø; en diskontinuitet fundet kun i de levende render punkter mod codec- window syning. Talerens huller forbliver en separat afspilnings- underflow metrisk. En dedikeret onset- pop detektor scanner den genererede lead-in plus den første 50 ms af vedvarende tale og flag prøve hopper over både 0.05 amplitude og seks gange standy- tale p99 baseline. Scenarios kan sætte Scenarier maximum_suspect_onset_transients til nul, mens oplevelseslytning forbliver den endelige kvalitetskontrol.
PersonaPlex arkitektur og brug
PersonaPlex er en multi- stream autoregressiv model med tre centrale komponenter:
| Komponent | Detaljer |
|---|---|
| Tidsmæssig transformator | 32 lag, dim = 4096, 32 hoveder, SwiGLU (skjult _ skala = 4.125), RoPE, 8-bit kvantiseret (standard) |
| Depformer | 6 lag, dim = 1024, 16 hoveder, MultiLinear (vægte _ per _ step = true), dep _ q = 16 |
| Mimi Codec | 16 kodebooks, 12,5 Hz frame rate, 24 kHz lydudgang |
Modelprocesserne 17-strømme samtidig: 1 tekststrøm + 8 bruger audio streams + 8 agent audio streams. Denne arkitektur gør det muligt full-duplex samtale, hvor modellen kan lytte og tale på samme tid.
Stemmeretspresets
PersonaPlex omfatter 18 building- i stemme presets på tværs af naturlige og varierede stilarter:
| Kategori | Præstebeløb |
|---|---|
| Naturlig kvinde | NATF0, NATF1, NATF2, NATF3 |
| Naturlig mand | NATM0, NATM1, NATM2, NATM3 |
| Varieret kvinde | VARF0, VARF1, VARF2, VARF3, VARF4 |
| Varieret mand | VARM0, VARM1, VARM2, VARM3, VARM4 |
Indre monolog
PersonaPlex genererer to parallelle strømme på hvert trin: 8 audio codebook tokens til Mimi codec og en tekst token til modellens interne monolog. Tekststrømmen er, hvad modellen er "tænkning", som den taler - den kan afvige lidt fra den endelige lyd, men i praksis det afspejler den talte respons tæt nok til at bruge som en levende udskrift.
Teksten tokens kommer tilbage som rå SentencePiece stykke id 'er. Decode dem med SentencePieceDecoder at PersonaPlex skibe:
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
I streaming-tilstand, respondStream Udledninger textTokens chunks som de er produceret - afkode dem trinvist at drive en live billedtekst visning, mens lyden er stadig generere. --transcript CLI flag gør præcis dette bag kulisserne.
Hvorfor det betyder noget: SentencePieceDecoder er bygget på den delte AudioCommon.SentencePieceModel protobuf læser, så PersonaPlex, OmnilingualASR og eventuelle fremtidige SentencePiece- baserede model afkode gennem den samme implementering af Medicinizer. Se SentencePieceModel reference.
Systemprompter
Pass enhver brugerdefineret systemprompt som en almindelig streng - ingen ekstern additionalisering nødvendig:
let response = model.respond(
userAudio: audio,
voice: .NATM0,
systemPrompt: "You enjoy having a good conversation."
)
Eller brug en bygning-i forudindstillet:
assistant- General-formål hjælpsom assistent (standard)focused- Koncise, direkte svarcustomer-service- Polat, opløsnings-orienteret hjælpemiddelteacher- Patient, forklarende undervisning stil
CLI-brug
Generér et talt svar fra et lydinput:
# 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
Indstillinger
| Valgmulighed | Varebeskrivelse |
|---|---|
--input | Input lydfil (WAV, påkrævet) |
--voice | Stemmeforudindstillet navn (f.eks.: NATM0, VARF2) |
--system-prompt | System prompt forudindstillet: assistent, fokuseret, customer-service, lærer |
--system-prompt-text | Brugerdefineret systemprompt tekst (tilsidesætter --system-prompt) |
--max-steps | Maksimal generering trin |
--stream | Emit lydstykker under generationen |
--compile | Brug MLX kompileret inferens til hurtigere generation |
--transcript | Udskriv teksten ved siden af lyd |
--json | JSON output med metadata |
Prøveudtagningsparametre kan også tilsidesættes:
| Valgmulighed | Standard | Varebeskrivelse |
|---|---|---|
--audio-temp | 0.8 | Prøvetagningstemperatur for lydtoken |
--audio-top-k | 250 | Lydtoken top- k prøvetagning |
--text-temp | 0.7 | Teksttokammerens prøvetagningstemperatur |
--text-top-k | 25 | Teksttoken top- k-prøvetagning |
Streaming
Den --stream flag gør det muligt real- time lyd output. Audio stykker er udsendt, som de er genereret, så afspilning kan begynde, før den fulde respons er færdig. Dette er især nyttigt for interaktive programmer, hvor lav latency betyder noget.
Præstation
| Metric | Værdi |
|---|---|
| Realtidsfaktor (RTF) | ~ 1.4 (8-bit, nær real- tid) |
| Step latency | ~ 112 ms / trin på M2 Max (8- bit) |
| Model størrelse (8-bit) | ~ 9,1 GB |
| Peak RAM (8- bit) | ~ 11 GB |
| Model størrelse (4-bit) | ~ 4,9 GB |
| Peak RAM (4- bit) | ~ 7 GB |
PersonaPlex 7B (8- bit) kræver mindst 24 GB af RAM. 4-bit varianten passer på 16 's enheder, men producerer degraderet output. På 8 GB- enheder, vil ingen af varianterne passe. Brug --compile for bedste ydeevne på understøttet hardware.
Model Variants
| Model | Størrelse | HuggingFace |
|---|---|---|
| PersonaPlex-7B (8- bit) anbefales | 9.1 GB | aufklarer / PersonaPlex-7B-MLX-8bit |
| PersonaPlex-7B (4- bit) | 4.9 GB | aufklarer / 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"))