Design note, not live. The working Reachy stack stays the rollback baseline: local Whisper, cloud Grok, streaming ElevenLabs, durable memory, and no act-from-voice. This page is how we could delete the transcript hop. It is not a launch, a merge, or a cutover.

Updated August 13, 11:22 AM CDT: first-party recipes now mapped. Studio path is Unsloth GGUF + llama.cpp. Spark path is SGLang NVFP4 TP=2. Neither has been launched here yet.

We already run speech-to-speech. Hugging Face speech-to-speech is the Realtime backend for Reachy. The stock conversation app stays on the body. The interesting next experiment is not a new robot stack. It is removing Whisper and letting a multimodal model hear the turn.

Live todayVAD → Whisper → Grok → TTS
ProposedVAD → WAV clip → Inkling-Small → TTS
Why botherNames, tone, and half-heard words — not 270 ms
Hard noHosted audio, thinking-on voice, production cutover

What we run today

Reachy is a cascade, not a single speech model. Silero VAD ends the turn. Local Whisper large-v3-turbo writes English. Grok answers in text. ElevenLabs speaks. Kitchen audio stays on the LAN. Only text leaves.

Current Reachy cascade: body to VAD to Whisper to cloud Grok to ElevenLabs. A dashed local-LAN box keeps audio on-site. Only text leaves the house.
Current live path, August 13, 2026. SVG source: skip-stt-cascade-today.svg. Private addresses omitted.

We measured this pipeline on July 27. Soft-end to transcription was a 0.27 s median over 20 turns. Grok time-to-first-token was 2.2–3.1 s, about 68% of the wait to first sound. ElevenLabs first audio was ~0.25 s. Deleting Whisper does not make the robot feel fast. It changes what the brain is allowed to hear.

HopOwnerWhat it emitsWhy it exists
VADLocalA finished 16 kHz clipFar-field turn-taking and barge-in
STTLocal WhisperA transcriptGrok cannot hear audio
LLMCloud GrokReply text + toolsIdentity, memory, short answers
TTSCloud ElevenLabsStreaming PCMA mouth. Local clone is still parked

Why skip STT

Not for latency. For the class of failure Whisper invents: fluent wrong English, “Big Mile,” a laugh turned into words, a name that only exists in audio. The model never sees the evidence. It only sees the guess.

Inkling is a Thinking Machines multimodal model. Audio, image, and text go in. Text comes out. It is not a talker. Official cards put Inkling-Small at 276B total / 12B active. Hugging Face’s own realtime demo is still cascade: mic → Inkling → Qwen3-TTS. Skipping STT means using the audio input they already trained, not pretending we bought Moshi.

What we would not get: native full duplex, spoken tokens, or a private voice. Inkling does not replace the mouth. It does not unlock act-from-voice. Those stay parked.

The skip-STT path

Keep the body, the VAD, the Realtime dialect, the memory layer, and the current TTS handler. Delete the transcript. Send the finished VAD clip to a local Inkling-Small server. Get text back. Speak it with the mouth we already have.

Proposed skip-STT path: same Reachy body and VAD, a new direct-audio hop, local Inkling-Small on the 512 GB Studio or the two Sparks, existing TTS. Whole path stays on the LAN. Marked not live and no cutover.
Proposed side path, not a production launch. SVG source: skip-stt-direct-audio.svg.
PieceChange
Stock conversation appNone. It already speaks OpenAI Realtime.
VAD / barge-inNone. Still the turn owner.
WhisperRemoved on this path only.
BrainLocal Inkling-Small, thinking off, OpenAI-compatible chat completions.
Memory / identity / no-act fenceStay in our speech-to-speech handlers. Do not re-litigate.
TTSUnchanged. Inkling does not synthesize speech.
Audio leaving the houseStill forbidden. Hosted Inkling is a privacy regression.

What the wire looks like

Upstream speech-to-speech now has a first-class switch: --stt none with --llm_backend chat-completions. Each completed VAD segment is posted as audio on the chat-completions message, not as a transcript. Responses-API is the wrong slot; a model can accept audio on /v1/chat/completions and still reject /v1/responses.

speech-to-speech serve \
    --stt none \
    --llm_backend chat-completions \
    --model_name inkling-small \
    --responses_api_base_url http://local-inkling/v1 \
    --responses_api_audio_content_type input_audio

That flag set is conceptual. Our live checkout is a dirty tree with local handlers. It does not have --stt none today. A blind git pull is still forbidden. The first implementation belongs in an isolated worktree, not in the production LaunchAgent.

Safer first experiment, if we only want to test Inkling as a brain: keep Whisper and point the existing chat-completions backend at a local Inkling server. That proves text quality and first-token time without merging upstream. Direct audio is the second experiment, after that server is boring.

Where it can actually run

Two machines are available for the brain: the 512 GB Mac Studio (M3 Ultra) and the two DGX Sparks. The voice Mac is a 64 GB M4 Max and cannot hold this model. Unsloth’s table puts Inkling-Small at 89 GB even in 2-bit and 132–170 GB in 4-bit. Hugging Face lists Inkling-Small NVFP4 at 180 GB — a pair-of-Sparks fit, not a 64 GB box. Full Inkling is still a cluster problem.

HostAvailable?Inkling-SmallFull Inkling
Mac Studio M3 Ultra (512 GB)Yes3/4-bit GGUF2-bit maybe; 4-bit / NVFP4 no
Two DGX SparksYesNVFP4 180 GB on the pairNo
One Spark (128 GB)Tight2-bit maybeNo
Voice Mac (M4 Max, 64 GB)NoNoNo

Voice needs first token with thinking off, not a 1M-context coding model. Official vibe evals show Inkling transcribe-then-reason on audio. If we leave reasoning on, we will pay more than Grok and hear silence. That is an automatic fail.

How we would run it

Two first-party paths fit the machines we actually have. Full Inkling does not. Nothing below has been launched in this lab yet — these are the official recipes, mapped onto our boxes.

BoxEngineCheckpointStatus
Mac Studio M3 Ultra (512 GB)llama.cpp MetalUnsloth Inkling-Small-GGUF UD-Q3_K_XL (3-bit, 128 GB) or UD-Q4_K_XL (4-bit, 132–170 GB)Documented. Not launched here.
Two DGX SparksSGLang NVFP4 TP=2thinkingmachines/Inkling-Small-NVFP4 (official 180 GB)SGLang lists a verified 2× GB10 cell. Not launched here.
Voice Mac (M4 Max, 64 GB)Too small.
Full Inkling (975B)NVFP4 600 GB / BF16 2 TBNeither host.

Studio: llama.cpp + Unsloth GGUF

Unsloth’s documented Inkling-Small quant for a 512 GB Studio is UD-Q3_K_XL. Metal is on by default; their build notes say set -DGGML_CUDA=OFF on a Mac. Inkling reasons by default. For voice, thinking must be off or we will lose to live Grok on first token.

hf download unsloth/Inkling-Small-GGUF \
    --local-dir unsloth/Inkling-Small-GGUF \
    --include "*UD-Q3_K_XL*"

llama-server \
    --model unsloth/Inkling-Small-GGUF/UD-Q3_K_XL/Inkling-Small-UD-Q3_K_XL-00001-of-00004.gguf \
    --temp 1.0 --top-p 1.0 --min-p 0.0 \
    --chat-template-kwargs '{"reasoning_effort":"none"}' \
    --host 127.0.0.1 --port 8080

Unsloth’s published snippet is llama-cli with those same sampling flags. llama-server is the OpenAI-compatible shape speech-to-speech already speaks. Their build also targets llama-mtmd-cli for multimodal; we have not proven audio-in on this GGUF yet. That is a gate, not a given.

Sparks: SGLang NVFP4 TP=2

SGLang’s Inkling-Small cookbook has a dedicated GB10 image and a verified dual-Spark cell: NVFP4, TP=2, one GPU per node, ConnectX-7. Recipes pass --enable-multimodal so the server accepts audio_url as a base64 WAV. Requests that omit reasoning default to high. Voice must send none.

docker pull lmsysorg/sglang:dev-inkling-small-dgx-spark

# Official cell, not a lab-measured launch:
#   thinkingmachines/Inkling-Small-NVFP4
#   TP=2 across two Sparks over ConnectX-7
#   --enable-multimodal
#   --disable-prefill-cuda-graph
#   Triton attention + Marlin FP4/MoE
# Exact sglang serve line comes from their hardware command generator.
# Docker already wants: --ulimit memlock=-1:-1 --cap-add IPC_LOCK --device /dev/infiniband

vLLM also publishes an Inkling-Small NVFP4 recipe (180 GB, --tokenizer-mode inkling, audio extra vllm[audio]), but the listed hardware is B300 / GB200 / H200, not GB10. There is a community dual-Spark vLLM yaml in eugr/spark-vllm-docker. We are not treating that as first-party, and we have not run it.

What the voice client then sends

Once either server answers /v1/chat/completions, skip-STT is an audio content part, not a transcript. SGLang’s documented shape:

{"type": "audio_url",
 "audio_url": {"url": "data:audio/wav;base64,..."}}

That is the same clip our VAD already owns. Thinking stays off. The mouth stays the current TTS handler.

Sources, fetched August 13: Unsloth Inkling run guide (GGUF sizes and llama.cpp flags); SGLang Inkling-Small cookbook (2× GB10 cell, multimodal, reasoning table); vLLM Inkling-Small recipe (180 GB NVFP4, B300/GB200 hardware); Inkling-Small model card and HF announcement (audio in, text out; BF16 600 GB / NVFP4 180 GB for Small). No tok/s in this section is ours.

How we would stage it

No go implied. If we do this, the order is:

  1. Stand up Inkling-Small as a side OpenAI-compatible server: llama.cpp GGUF on the Studio, or SGLang NVFP4 TP=2 on the Spark pair. Text-only smoke first. Do not touch Reachy.
  2. Point a disposable speech-to-speech worktree at that server with Whisper still on. Compare short-turn quality and TTFT against live Grok. Keep thinking off.
  3. Only then enable --stt none in that worktree. Headset first, kitchen later.
  4. Score the same spoken turns both ways: name accuracy, barge-in, first sound, and whether it invents fluent wrong English.
  5. If it wins as a fallback lane, say so. If it does not, leave the live stack alone.
Hard failWhy it stops the experiment
Any household audio to a hosted endpointBreaks the LAN contract we already published
Thinking-on first token worse than live GrokWe already know the budget is the LLM, not STT
Kitchen audio worse than turbo WhisperThen we kept the hard part and lost the easy part
Merge into the dirty production treeThe live robot is the rollback baseline

Still parked: full duplex, private local voice cloning, speaker recognition, guard / code red, and act-from-voice. Direct audio does not earn those.

Companion posts: Reachy Mini: Milo’s Physical Avatar is the live product. One Milo, Many Bodies is the unfinished shared-runtime track. This page is a third thing: a single deleted hop, drawn before anyone types git pull.