Strojový překlad · Anglický originál
Speech Server
Původní Apple runtime · PocketTTS
PocketTTS přidává nativní syntézu CoreML do speech-swift. Všechny fáze jsou výchozí pouze pro CPU- provedení. Anglické Alba preset streams 1,920-výběrové rámy na 24 kHz (80 ms na snímek).
Použijte pocket-tts s hlasem alba. Streaming HTTP vyžaduje PCM; WebSocket emituje audio deltas. Stávající výchozí modely jsou nezměněny.
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 je lokální HTTP + WebSocket server, který vystavuje každý Soniqo model pomocí jednoduchého REST API, plus OpenAI Realtime API- kompatibilní WebSocket v /v1/realtime. To přepravuje ve stejné Homebrew láhev jako speech CLI - brew install speech Oba kapky na váš PATH.
Nainstalovat a spustit
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)
Příkazové vlajky
| Vlajka | Výchozí | Popis |
|---|---|---|
--host | 127.0.0.1 | Svázaná adresa. 0.0.0.0 k odhalení na LAN. |
--port | 8080 | TCP port. |
--preload | vypnuto | Při startu načíst všechny modely dychtivě. Pomalejší bota (~ 30-60 s), ale nula první požadavek latence. |
Modely jsou staženy při prvním použití a cachovány v ~/Library/Caches/qwen3-speech/. První žádost o daný model zaplatí náklady na stahování + zatížení (30 s - 2 min v závislosti na velikosti modelu); následující požadavky jsou teplé.
Endpointy REST
POST /transcribe - Speech- to- text
Akceptuje buď syrové WAV tělo nebo JSON obálku s base64-encoded audio.
# 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"}'
Odpověď: {"text": "…", "language": "en", "confidence": 0.93}.
POST /speak - Test- to - řeč
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 is a WAV blob. Podporováno engine hodnoty: qwen3 (přednastaveno), cosyvoice, kokoro.
POST /respond - Proslov-k-proslovu
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
Běží PersonaPlex 7B - projev v, projev ven. Transcript je vrácen jako X-Response-Text Hlavička. PersonaPlex průvodce pro hlasová přednastavená jména.
POST /enhance - Vylepšení řeči
curl -X POST http://127.0.0.1:8080/enhance \
-H "Content-Type: audio/wav" \
--data-binary @noisy.wav \
--output clean.wav
DeepFilterNet3 na 48 kHz. Vstup se v případě potřeby přetvoří.
GET /health - Sonda lehkosti
curl http://127.0.0.1:8080/health
# {"status":"ok"}
HTTP a Real Time WebSocket testy čekají na /health vrátit HTTP 200 s {"status":"ok"},, s 10- druhý spouštěcí termín. Chyby spuštění selže nastavení testu, a teardown čeká na vypnutí serveru před opětovným použitím jeho portu.
WebSocket: /v1/realtime
Drop- v souladu s OpenAI Realtime API - stejné schéma událostí JSON (session.update, input_audio_buffer.append, response.create, response.audio.delta,...) se base64-encoded PCM16 audio na 24 kHz. Klienti napsali proti OpenAI Realtime SDK pracovat proti speech-server bez změn kódu (stačí přepnout URL WebSocket).
Automatické otáčky se serverem VAD
Ruční input_audio_buffer.commit zůstává výchozí. Set session.turn_detection do server_vad spustit Silero VAD na serveru a automaticky přepsat každý dokončený slovní obrat. Prefix audio je zachován, neaktivní buffering zůstává ohraničen, a kontinuálně aktivní turn je silně uzavřen na nastaveném maximu.
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 příklad
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 příklad
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())
Poznámky k umístění
- No auth ve výchozím nastavení.
speech-serverpojiva127.0.0.1a věří každému volajícímu. Dejte to za obrácenou proxy (Caddy, Nginx, tail scale), pokud to odhalíte mimo localhost. - Modelky jsou lazy. První žádost
/transcribeSpustí stahování ASR + zatížení (~ 700 MB, 30-60 s).--preloadpro nulovou chlad-start, ale pomalejší bota. - Zatím žádný transgramiátor.
POST /transcribeočekává plný WAV vpředu./v1/realtimena streaming. - Systemd / launchd. Dnes žádné služební lodě.
nohup speech-server &nebo váš obvyklý vedoucí procesů funguje.
Zdroj
- Zdroje / AudioServer - HTTP router na bázi kolibříka, líný registr modelů,
/v1/realtimeWebSocket. - Zdroje / AudioServerCLI —
@mainVstupní bod, argument parser. - Vnější proud: OpenAI Realtime API reference.
Místní rodný odvod
Pro 12B jsou s tímto voláním konzumovány opakované přilehlé uzavírací značky tool- call bezprostředně po úplném, ověřeném volání. Nevytvářejí další volání ani nemění své argumenty. Samostatné markery a vadné argumenty zůstávají chybami; E4B si zachovává přísné zacházení.
Chcete-li zachovat nezdařené rodné žádosti chatu, nastavte failureCaptureDirectory v inference manifestu. Zachycení je vypnuto ve výchozím nastavení. Adresář musí odepřít skupinový a jiný přístup; nové adresáře používají 0700 a použití souborů selhání 0600. Soubory zahrnují přesné tělo požadavku, ID požadavku a chybu. Dokončené generace 12B si také zachovají proklamované okamžité, token ID, surový výstup a konec důvod před rozchodem. E4B selhání nemají žádný záznam o surové generaci. Tyto lokální soubory obsahují obsah konverzace a nástroje; HTTP chyby a úspěšné požadavky je nezahrnují.
Volitelné agentDirectory načítá zinscenované Gemma 4 12B Jednotná INT4 vedle textového modelu E4B Model: ".gemma4-12b-it"pro chat s nativní nástroje, historie výsledků, a zrušení. E4B zůstává k dispozici pro další žádosti. Gemma4UnifiedChat používá přišpendlené MLX implementace textů a uvolnění KV cache každého požadavku. Odezva parsing odstraňuje deimitery kanálů z vráceného textu. Opuštěné koncovky tool- call jsou odmítnuty jako chybná odpověď. Selhání non-streamingu žádosti logovat jejich ID, provoz, a základní chyba v procesu serveru. Pro Gemma 4 12B, obsah tool- message uchovává JSON jako text, odpovídající šabloně checkpoint chat.
Zdroj buduje akceptovat --inference-manifest models.json nahrát zinscenované Gemma 4 E4B INT4, VoxCPM2, plné Whisper Large-v3, a Silero VAD. Tato služba začíná off-line a odmítá neslučitelné identity modelu.
Individuální služba serializuje chat, syntézu a transkripci; lehký VAD má samostatný stream stav. Gemma předvyplní každé 256-token šarže před zahájením dalšího, požadavek KV stav je uvolněn, a MLX cache je omezena na 128 MiB s 20 GiB allocator limit.
Proslov s proudem: pravda vrací NDJSON audio události na 48 kHz, následováno dokončením nebo chybou. Zrušit requestID na /v1/ odvod / zrušit. GET /v1/ inference / schopnosti a /v1/ inference / provenance report model identity, parametr dtypes, spony aktiv, a paměťové čítače.
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"
}Nepovinné vlastnictví modelu
SpeechRuntime poskytuje sdílené zatížení, zrušitelné FIFO přijetí a serializovaný výkon. Qwen3ASRRuntime vybere MLX nebo plný CoreML prostřednictvím explicitních deskriptorů; Nativní API a CLI vlajky zůstávají k dispozici.
Audio server má jedno povolení k provedení přes každý kompletní požadavek, včetně streamovaného výstupu, s až 32 požadavky čekání. ASR selhání produkují HTTP chyby nebo WebSocket chybové události; platné prázdné přepisy zůstávají úspěšné. Přehrávání uchovává přetečení vzorků. Cached modely a čeká přehrávání audio stále zabírá paměť.
Voxtral TTS
Voxtral 4B TTS 2603 běží lokálně na Apple Silicon přes modul Voxtral TTS: 20 přednastavené hlasy, devět jazyků a 24 KHz mono řeč.
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.wavPouze přednastavené hlasy; reference-audio klonování je nedostupné. Audio výstupy proudí přes SDK, CLI, WebSocket a HTTP PCM. Dodávejte kompletní vstupní text vpředu. Modelové váhy používají CC BY-NC 4.0.
Gemma 4 12B předvyplnění
Individuální inference služba načte modelovaný Gemma 4 12B Unified INT4 model pomocí agentDirectory. Vyberte ji pro chat s ID modelu gemma4-12b-it.
Gemma 4 12B předvyplní stav KV v šaržích až do žetonů 256 a vypočítají první záznamy odběru vzorků z posledního tokenu. Intermediate slovní výhledy jsou vynechány. Žádost je KV cache je uvolněna po dokončení nebo zrušení.
Jeden nezměněný systém / nástroj prefix může zůstat cached v kompletních 256-token bloky. Každý požadavek rozšiřuje samostatnou pracovní kopii. Uživatelské zprávy, historie konverzace a výsledky nástroje nikdy vstoupit zachované snímek. Set SPEECH_SWIFT_GEMMA4_PREFIX_CACHE_MB omezit zachovanou MiB, nebo 0 zakázat opětovné použití. clearPrefixCache() uvolňuje snímek. HTTP reports reputed tokens in cachedPrefixTokens; záznamy o původu gemma4_12b_prefix_cache_budget_bytes. Studené požadavky stále zpracovávají plnou rychlost.
Původní historie nástroje Gemma udržuje odpovědi na nástroje a pomocné pokračování uvnitř stejného modelu. Následující uživatelská zpráva zavře tento model před otevřením dalšího uživatelského otočení. toolCallID.