Awtomatikong salin · Orihinal sa Ingles

Speech Server

Katutubong Apple runtime · PocketTTS

Ang PocketTTS ay nagdaragdag ng katutubong CoreML speech synthesis sa speech-swift. lahat ng mga yugto ay default sa CPU-lamang pagpatay. Ang Ingles na Alba preseted streams 1,920-sample frames sa 24 kHz (80 ms kada frame).

Ginamit ang Swift at CLI

Gumamit ng pocket-tts na may voice alba. Streaming HTTP ay nangangailangan ng PCM; WebSocket ay naglalabas ng audio deltas. Ang mga umiiral na default models ay hindi nagbabago.

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.pcm

speech-server ay isang lokal na HTTP + WebSocket server na naglalantad sa bawat Soniqo model sa pamamagitan ng isang simpleng REST API, at isang pantelebisyon na pang-XZ OpenAI Realtime API-compatible WebSocket sa /v1/realtime. Ito ay barko sa parehong boteng Homebrew na katulad ng boteng ZAXZ speech CLI — brew install speech ay kapuwa nakalagay sa iyong KATOTOHANAN.

Iluklok at patakbuhin

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)

Mga bandilang kondado-line

Bandila Pagkawasak Paglalarawan
--host127.0.0.1Band address. Palitan sa 0.0.0.0 para mailantad sa LAN.
--port8080TCP port.
--preloadoffIsakay ang lahat ng modelo nang may pananabik sa start-up. slower boot (ifter-jock30–60 s) ngunit sero first-request latency.

Ang mga modelo ay na-download sa unang gamit at cached sa ~/Library/Caches/qwen3-speech/. Ang unang kahilingan para sa isang ibinigay na modelo ay nagbabayad sa download + load na halaga (30 s – 2 mi – depende sa modelong sukat); ang mga kasunod na kahilingan ay mainit.

REST endpoints

POST /transcribe — Talasalitaang-to-ext

Tinatanggap ang alinman sa hilaw na WAV na katawan o isang sobreng JON na may 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"}'

Sagot: {"text": "…", "language": "en", "confidence": 0.93}.

POST /speak — Text-to-speech

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

Ang tugong katawan ay isang WAV blob. Suportadong engine value: qwen3 (default), cosyvoice, kokoro.

POST /respond — Pananalita-to-speech

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

Runs PersonaPlex 7B — pagsasalita sa, pagsasalita sa. Transcript ay ibinalik bilang isang X-Response-Text header. Tingnan ang PersonaPlex para sa mga pangalan ng boses preset.

POST /enhance — Pagpapaganda sa Pagsasalita

curl -X POST http://127.0.0.1:8080/enhance \
  -H "Content-Type: audio/wav" \
  --data-binary @noisy.wav \
  --output clean.wav

DeepFilterNet3 sa 48 kHz. Ang Iniput ay muling tinatampukan kung kinakailangan.

GET /health — Liveness probe

curl http://127.0.0.1:8080/health
# {"status":"ok"}

Naghihintay ang HTTP at realtime WebSocket tests /health upang ibalik ang HTTP 200 kasama ang {"status":"ok"}, na may 10-second startup deadline. Ang mga pagkakamali sa startup ay nabibigo sa test settup, at ang breakdown ay naghihintay ng servation bago muling gamitin ang port nito.

WebSocket: /v1/realtime

Ang drop-in ay tumutugma sa OpenAI Realtime API — ang pangyayari ring iyon na JSON na schema (skema)session.update, input_audio_buffer.append, response.create, response.audio.delta, ...) kasama base64-encoded PCM16 audio sa 24 Mga Client na isinulat laban sa mga kHz. OpenAI'Tunay na Panahon ' SDK tutol speech-server walang mga pagbabagong kodigo (iba lamang ang WebSocket URL).

Awtomatikong lumiko sa server VAD

Manual input_audio_buffer.commit ay nananatiling default. session.turn_detection hanggang sa server_vad Upang patakbuhin ang Silero VAD sa server at awtomatikong i-record ang bawat nakumpletong pag-ikot ng pagsasalita. fix audio ay pinananatili, ang mga walang trabahong neutraling ay nananatiling nakatali, at ang isang patuloy na aktibong pag-iikot ay pwersa-malapit sa nakaayos na sukdulan.

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 halimbawa

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);
  }
};

Halimbawang Python

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

Mga nota ng pag - aalis ng tubig

Pinagmumulan

Ang lokal na katutubong pahiwatig

Para sa 12B, ang paulit-ulit na katabing mga kasangkapan-tawag na pagsasara ng mga marker pagkatapos ng isang kumpleto, regulatoryong tawag ay nakukwenta sa pamamagitan ng tawag na iyon. Hindi sila lumilikha ng ibang tawag o pagbabago sa mga argumento nito. Ang mga stagealone marker at mga argumentong diperensiyal ay nananatiling mga pagkakamali; E4B ay nagpapanatili ng mahigpit na paghawak.

Upang mapanatili ang bigong katutubong mga kahilingan sa chat, set failureCaptureDirectory Ang direktor ay hindi naka - default, at dapat na hindi ito kasama ng iba pang mga direktor; ang mga bagong direktory ay gumagamit ng mga bagong direktor 0700 at ang mga talaksang bigo ay gumagamit 0600. Ang mga talaksan ay kinabibilangan ng eksaktong request body, request ID at error. Completed 12B generations ay nagpapanatili rin ng iginawad na advanced, token IDs, hilaw output at top katwiran bago ang parps. E4B fails ay walang hilaw na rekord ng henerasyon. Ang mga lokal na file na ito ay naglalaman ng mga pagkakamali sa pag-uusap at kagamitan; ang HTTTP ay hindi kasama ang mga ito.

Ipinintang ng ahenteng opsyonal na Direktoryo ang isang nakadispley Gemma 4 12Ipinakilala INT4 modelo ng teksto sa tabi E4B. Gumamit ng modelo: "gemma4-12b-it" para makipag - usap sa katutubong mga kagamitan, ang resulta'y kasaysayan, at pagpapawalang - bisa. E4B ay maaari pang makuha para sa iba pang mga kahilingan. Gemma4UnifiedChat ginagamit ang pindutan MLX Ang pagpapatupad ng teksto at paglalabas ng bawat request features KV cache. Ang tugon parsing ay nag-aalis ng channel deliters mula sa ibinalik na teksto. ang mga overpled tool-call revisions. Bigo non-streaming requests log ang kanilang request ID, operasyon, at saligang error sa proseso ng server. Gemma 4 12B, ang mga tool-message content ay nag-iingat sa JSON bilang teksto, na nagtutugma sa checkpoint chat template.

Ang pinagmumulan ay tumatanggap --inference-manifest mga modelo.json upang ikarga ang nakatanghal Gemma 4 E4B INT4, VoxCPM2, buo Whisper Large-v3, at Silero VAD. Ang serbisyong ito ay nagsisimula at tumatanggi sa hindi katugmang huwarang pagkakakilanlan.

Ang katutubong serbisyo serializes chat, synthesis, at transcription; lightight VAD ay may hiwalay na stream state. Gemma prefill reviews ang bawat 256-token pupped bago simulan ang susunod, hilingin ang KV state ay inilabas, at ang MLX cache ay naka-crefer sa 128 MiB na may isang 20 GiB allyplocator na limitasyon.

Pagsasalita na may kasamang agos: tunay na nagbabalik ang NDJSON audio na mga pangyayari sa 48 KHz, sinundan ng ginawa o pagkakamali. Cancel by requestID sa /v1/inference/cancel. HAT /v1/ kawalang - galang/kabisayaan at /v1/inference/provence report model proccious, parameter dtypes, asset pins, at 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"
}

API mga detalye

Optional model pagmamay-ari

Nagbibigay ang SpeechRuntime ng kabahaging pagkarga, cancellable FIFO accounted at serialized kill. ang Qwen3ASRRuntime ay pumipili ng MLX o buong CoreML sa pamamagitan ng mga detalyadong direksyon; ang mga katutubong bandilang API at CLI ay nananatiling makukuha.

Ang audio server ay humahawak ng isang bitayan sa pamamagitan ng bawat kumpletong kahilingan, kabilang ang streeted output, na may hanggang 32 requests naghihintay. ang ASR failures ay gumagawa ng mga pagkakamaling HTTP o WebSocket error events; ang mga tanggap na walang laman na transcription ay nananatiling matagumpay.Ang mga playback reservement ay nag-apaw ng mga sampol.Ang mga modelong creached at ang mga champling playback audio ay sumasakop pa rin sa memorya.

Voxtral TTS

Voxtral 4B TTS 2603 ay lokal na tumatakbo sa Apple Silicon sa pamamagitan ng Voxtral TTS module: 20 preseted voices, siyam na wika, at 24 kHz mono speech.

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.wav

Ang mga preset voices lamang; reference-audio cloning ay hindi makuha. Ang audio output ay dumadaloy sa SDK, CLI, WebSocket at HTTP PCM. Isumite ang kumpletong input text up front. Ang mga model weights ay gumagamit ng CC BY-NC 4.0.

Basahin ang Voxtral TTS guide

Gemma 4 12B agarang prefill

Ang katutubong serbisyong aksesorya ay may kargang Gemma 4 12B Unified INT4 model gamit ang agentDirectory. Piliin ito para sa pakikipag-usap sa modelong ID gemma4-12b-it.

Ang Gemma 4 12B prefill ay pumuno sa KV estado sa mga talaksan ng hanggang 256 na mga token at mga comut ang unang mga halimbawa na mga logit mula sa pangwakas na hudyat.Ang mga bukabularyong propositions ay hindi na makuha.Ang request na mga cardiologist na KV cache ay inilalabas pagkatapos makumpleto o i - reconstruct.

Ang isang hindi nagbabagong sistema/tool unlapi ay maaaring manatiling bakterya sa kumpletong 256-token blocks. Ang bawat kahilingan ay naggagawad ng isang hiwalay na gumaganang kopya. User na mga mensahe, kasaysayan ng pag-uusap, at mga resulta ng kasangkapan ay hindi kailanman pumapasok sa direktibong speciation. SPEECH_SWIFT_GEMMA4_PREFIX_CACHE_MB Upang limitahan ang MiB, o ang natitirang MiB 0 upang sirain ang muling paggamit. clearPrefixCache() ay naglalabas ng litrato. cachedPrefixTokens; Pinatutunayan ang mga rekord gemma4_12b_prefix_cache_budget_bytes. Malamig pa rin ang mga kahilingan na gawin ang lahat ng bagay.

Ang katutubong Gemma na kagamitang pang-ekonomiya ay nagpapanatili ng mga tugong kasangkapan at isang katulong na pagpapatuloy sa loob ng parehong modelong pag-ikot. Ang isang sumusunod na mensaheng user ay nagsasara ng modelong liliko bago buksan ang susunod na pag-ikot ng gumagamit. Padalhan ang bawat resulta ng orihinal na toolCallID