Maskinoversættelse · Engelsk original
Speech Server
Indfødt Apple runtime · PocketTTS
PocketTTS tilføjer indfødt CoreML talesyntesse til speech-swift. Alle trin standard til CPU- kun udførelse. Den engelske Alba forudindstillet streams 1,920- prøvesæt på 24 kHz (80 ms per frame).
Brug pocket- tts med voice alba. Streaming HTTP kræver PCM; WebSocket udsender audio deltas. De eksisterende standardmodeller er uændrede.
curl http://localhost:8080/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{"model":"pocket-tts","voice":"alba","input":"Hello world.","response_format":"pcm","stream":true}' \
-o hello.pcmspeech-server er en lokal HTTP + WebSocket server, der udsætter hver Soniqo model gennem en simpel REST API, plus en OpenAI Realtime API- kompatibel WebSocket på /v1/realtime. Det skibe i samme Homebrew flaske som speech CLI - brew install speech Smid begge på din PATH.
Installere og køre
brew install speech
speech-server --port 8080
# Starting server on http://127.0.0.1:8080
# Endpoints:
# POST /transcribe - Speech-to-text (WAV body or JSON with audio_base64)
# POST /speak - Text-to-speech (JSON: {text, engine?, language?})
# POST /respond - Speech-to-speech (WAV body, voice/max_steps via query)
# POST /enhance - Speech enhancement (WAV body)
# GET /health - Health check
# WS /v1/realtime - OpenAI Realtime API (JSON events, base64 PCM16 audio)
Kommandolinjeflag
| Flag | Standard | Varebeskrivelse |
|---|---|---|
--host | 127.0.0.1 | Bindeadresse. Skift til 0.0.0.0 at afsløre på LAN. |
--port | 8080 | TCP port. |
--preload | af | Indlæs alle modeller ivrigt ved opstart. Lancer boot (~ 30- 60 s), men nul first-request latency. |
Modeller downloades ved første brug og cache i ~/Library/Caches/qwen3-speech/. Den første anmodning om en given model betaler download + belastning omkostninger (30 s - 2 min afhængigt af modelstørrelse); efterfølgende anmodninger er varme.
REST endepunkter
POST /transcribe - Speech- to- tekst
Accepterer enten en rå WAV krop eller en JSON kuvert med base64-encoded lyd.
# WAV body (preferred — lower overhead)
curl -X POST http://127.0.0.1:8080/transcribe \
-H "Content-Type: audio/wav" \
--data-binary @recording.wav
# JSON with base64
curl -X POST http://127.0.0.1:8080/transcribe \
-H "Content-Type: application/json" \
-d '{"audio_base64":"'"$(base64 -i recording.wav)"'","language":"en"}'
Svar: {"text": "…", "language": "en", "confidence": 0.93}.
POST /speak - Tekst- to- tale
curl -X POST http://127.0.0.1:8080/speak \
-H "Content-Type: application/json" \
-d '{"text":"Hello, world!","engine":"kokoro","language":"en"}' \
--output hello.wav
Response body er en WAV blob. Understøttede engine værdier: qwen3 (standard) cosyvoice, kokoro.
POST /respond - Tale-til-tale
curl -X POST "http://127.0.0.1:8080/respond?voice=en_female_calm&max_steps=256" \
-H "Content-Type: audio/wav" \
--data-binary @question.wav \
--output answer.wav
Kører PersonaPlex 7B - tale ind, tale ud. Udskrift returneres som en X-Response-Text header. Se PersonaPlex guide for stemmenavne.
POST /enhance - Ophøjelse af tale
curl -X POST http://127.0.0.1:8080/enhance \
-H "Content-Type: audio/wav" \
--data-binary @noisy.wav \
--output clean.wav
DeepFilterNet3 ved 48 kHz. Input rekompileres om nødvendigt.
GET /health - Liveness probe
curl http://127.0.0.1:8080/health
# {"status":"ok"}
HTTP og realtime WebSocket test venter på /health at returnere HTTP 200 med {"status":"ok"}, med en 10- anden opstartsdeadline. Opstartsfejl mislykkes testopsætning, og toardown venter server nedlukning, før genbruge sin port.
WebSocket: /v1/realtime
Drop-in kompatibel med OpenAI Realtime API - det samme JSON event schema (session.update, input_audio_buffer.append, response.create, response.audio.delta,...) med base64-encoded PCM16 lyd på 24 kHz. Klienter skrevet imod OpenAI Realtime SDK arbejde mod speech-server uden kodeændringer (bare skifte WebSocket URL).
Automatiske drejninger med server VAD
Manual input_audio_buffer.commit forbliver standard. Sæt session.turn_detection til server_vad at køre Silero VAD på serveren og automatisk transskribere hver færdig taletur. Præfiks lyd er bevaret, tomgang buffering forbliver afgrænset, og en kontinuerlig aktiv drejning er kraft- lukket på det indstillede maksimum.
ws.send(JSON.stringify({
type: "session.update",
session: {
turn_detection: {
type: "server_vad",
threshold: 0.5,
prefix_padding_ms: 300,
silence_duration_ms: 500,
max_turn_duration_ms: 120000
}
}
}));
// Event order for each detected turn:
// input_audio_buffer.speech_started
// input_audio_buffer.speech_stopped
// input_audio_buffer.committed
// conversation.item.input_audio_transcription.completed
// Set turn_detection to null (or { type: "none" }) for manual commits.
JavaScript eksempel
const ws = new WebSocket("ws://127.0.0.1:8080/v1/realtime");
ws.onopen = () => {
ws.send(JSON.stringify({
type: "session.update",
session: { modalities: ["audio", "text"] }
}));
// Stream PCM16 mono 24kHz audio from the mic:
const audioBase64 = await capturePCM16Chunk();
ws.send(JSON.stringify({
type: "input_audio_buffer.append",
audio: audioBase64
}));
ws.send(JSON.stringify({ type: "response.create" }));
};
ws.onmessage = ev => {
const msg = JSON.parse(ev.data);
if (msg.type === "response.audio.delta") {
playPCM16Base64(msg.delta);
}
};
Python eksempel
import asyncio, base64, json, wave, websockets
async def main():
async with websockets.connect("ws://127.0.0.1:8080/v1/realtime") as ws:
await ws.send(json.dumps({"type": "session.update",
"session": {"modalities": ["audio", "text"]}}))
with wave.open("question.wav", "rb") as wav:
pcm16 = wav.readframes(wav.getnframes())
await ws.send(json.dumps({"type": "input_audio_buffer.append",
"audio": base64.b64encode(pcm16).decode()}))
await ws.send(json.dumps({"type": "response.create"}))
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "response.audio.delta":
open("answer.pcm", "ab").write(base64.b64decode(msg["delta"]))
elif msg["type"] == "response.done":
break
asyncio.run(main())
Deployeringsnoter
- Ingen auth som standard.
speech-serverbindes127.0.0.1og stoler på hver ringer. Sæt det bag en omvendt proxy (Caddy, nginx, tailskala), hvis du udsætter det ud over localhost. - Modeller er lazy- lastet. Første anmodning om
/transcribeudløser ASR download + belastning (~ 700 MB, 30- 60 s).--preloadfor nul cold- start, men langsommere boot. - Ingen streaming transskription endnu.
POST /transcribeforventer den fulde WAV op foran. Brug/v1/realtimefor streaming. - Systemd / lancering. Ingen service enhed skibe i dag.
nohup speech-server &eller din sædvanlige proces supervisor arbejder.
Kilde
- Kilder / AudioServer - Hummingbird- baseret HTTP router, doven model registreringsdatabasen,
/v1/realtimeWebSocket-kontaktperson. - Kilder / AudioServerCLI —
@mainIndgangssted, argument parser. - Upstream: OpenAI Realtime API reference.
Lokal indfødt inferens
For 12B, gentagne tilstødende værktøjs- call lucking markører umiddelbart efter et komplet, valideret opkald forbruges med dette opkald. De skaber ikke et andet opkald eller ændre sine argumenter. Standalone markører og misdannede argumenter forbliver fejl; E4B bevarer streng håndtering.
For at beholde fejlbehæftede native chat-forespørgsler, sæt failureCaptureDirectory i inferens manifest. Fanget er som standard slukket. Mappen skal nægte gruppe og anden adgang; nye mapper bruges 0700 og fejlfiler bruger 0600. Filer omfatter den nøjagtige anmodning organ, anmode om ID og fejl. Færdiggjort 12B generationer også beholde den afleverede prompt, token id 'er, rå output og stop grund før fortolkning. E4B fejl har ingen rå generation rekord. Disse lokale filer indeholder samtale og værktøj indhold; HTTP fejl og succesfulde anmodninger ikke omfatter dem.
Valgfri agentDirectory indlæser en iscenesat Gemma 4 12B Ensartet INT4 tekstmodel ved siden af E4B. Brug model: "gemma4-12b-it"for chat med indfødte værktøjer, resultat historie, og annullering. E4B forbliver til rådighed for andre anmodninger. Gemma4UnifiedChat bruger den fæstnede MLX tekst implementering og frigiver hver anmodning KV cache. Response parsing fjerner kanal afgrænsere fra returneret tekst. Orphanded tool- call terminatorer afvises som misdannede svar. Mislykkedes ikke-streaming anmodninger log deres anmodning ID, operation, og underliggende fejl i serveren proces. Gemma 4 12B, værktøjs- message indhold bevarer JSON som tekst, der matcher checkpoint chat skabelonen.
Kildeopbygninger accepterer --inference-manifest models.json at indlæse iscenesat Gemma 4 E4B INT4, VoxCPM2, fuld Whisper Large-v3, og Silero VADDenne tjeneste starter offline og afviser uforenelige model identiteter.
Den indfødte service serialiserer chat, syntese og transskription; letvægts VAD har separat stream tilstand. Gemma prefill evaluerer hver 256- token batch, før du starter den næste, anmodning KV tilstand er frigivet, og MLX cache er begrænset på 128 MiB med en 20 GiB tildelingsgrænse.
Tale med stream: true returnerer NDJSON audio events på 48 kHz, efterfulgt af gjort eller fejl. Annullér af request at /v1/ inferens / aflys. GET /v1/ inferens / kapaciteter og /v1/ inferens / herkomst rapport model identiteter, parameter dtypes, aktiv pins, og memory counters.
speech-server --inference-manifest models.json --port 8080{
"runtimeRevision": "your-source-revision",
"gemmaDirectory": "/models/gemma4-e4b-it-int4",
"voxDirectory": "/models/voxcpm2-unquantized",
"whisperDirectory": "/models/whisper-large-v3-coreml",
"vadDirectory": "/models/silero-vad-coreml"
}Valgfri modelejerskab
SpeechRuntime giver delt indlæsning, annullerbar FIFO optagelse og serialiseret udførelse. Qwen3ASRRuntime vælger MLX eller fuld CoreML via eksplicitte deskriptorer; indfødte API 'er og CLI-flag forbliver tilgængelige.
Lydserveren har en udførelsestilladelse gennem hver komplet anmodning, herunder streamet output, med op til 32 anmodninger venter. ASR fejl producerer HTTP fejl eller WebSocket fejlbegivenheder; gyldige tomme udskrifter forbliver vellykket. Playback bevarer overløb prøver. Cached modeller og venter afspilning lyd stadig optager hukommelse.
Voxtral TTS
Voxtral 4B TTS 2603 kører lokalt Apple Silicon gennem Voxtral TTS-modulet: 20 forudindstillet stemmer, ni sprog, og 24 kHz mono tale.
curl http://localhost:8080/v1/audio/speech \
-H 'Content-Type: application/json' \
-d '{"model":"voxtral-tts","input":"Hello, welcome to Voxtral.","voice":"casual_male","response_format":"wav"}' \
-o hello.wavForetag kun stemmer; reference- audio kloning er ikke tilgængelig. Lydoutput strømme gennem SDK, CLI, WebSocket og HTTP PCM. Levere den komplette input tekst op foran. Model vægte bruge CC BY-NC 4.0.
Gemma 4 12B prompt prefill
Den indfødte inference service indlæser den iscenesatte Gemma 4 12B Unified INT4 model ved hjælp af agentDirectory. Vælg det til chat med modellen ID gemma4-12b-it.
Gemma 4 12B prefill fylder KV-tilstand i batcher på op til 256 tokens og beregner de første samplinglogin fra den endelige prompt token. Mellemliggende ordforrådsfremskrivninger sprunges. Forespørgslens KV cache frigives efter afslutning eller annullering.
Et uændret system / værktøj præfiks kan forblive cachet i komplette 256- token blokke. Hver anmodning udvider en separat arbejdskopi. Brugermeddelelser, samtale historie, og værktøj resultater aldrig indtaste den tilbageholdte snapshot. SPEECH_SWIFT_GEMMA4_PREFIX_CACHE_MB at begrænse tilbageholdte MiB, eller 0 at deaktivere genbrug. clearPrefixCache() frigiver snapshot. HTTP rapporter genbrugt tokens i cachedPrefixTokens; Originaloptegnelser gemma4_12b_prefix_cache_budget_bytesKolde anmodninger stadig behandle den fulde prompt.
Native Gemma toolhistorik holder værktøjets respons og en assisterende fortsættelse inde i samme model drejning. En følgende brugermeddelelse lukker denne model drejning, før du åbner den næste bruger tur. Send hvert resultat med sin oprindelige toolCallID.