Self-hosted GPU inference platform — 36B MoE, voice AI and a 70-GPU farm
A fully self-hosted AI stack: a 36B MoE model served concurrently with embeddings, ASR and TTS on a single 24 GB GPU — later scaled to a 70-GPU, 10-node farm that a bad VBIOS clock state nearly took down.
- Role
- ML platform engineer
- Timeline
- Ongoing — in production since 2024
- Stack
- ROCm 7.14 / HIP (gfx1100) · llama.cpp · whisper.cpp · qwen3-tts.cpp · VFIO / IOMMU · Proxmox VE · ZFS · Qdrant · FastAPI · systemd · MikroTik RouterOS

A live system in daily operation for waste-management ticket intake — this page embeds the running demo.
What was broken
One 24 GB GPU card had to serve a 36B-parameter MoE model, vector embeddings, speech-to-text and text-to-speech at the same time. On top of that, the farm was being scaled to 70 GPUs across 10 nodes, and a fleet-wide instability was wiping out the value of every extra card.
How it was fixed
Budgeted the entire stack against a single 25.7 GB VRAM ceiling: the 36B MoE quantized to IQ4_XS with a q4 KV cache at 64K context, whisper-small ASR and the embedding model pinned to the same card, TTS alongside — measured at 25.3/25.7 GB with every layer accounted for. When the fleet started crashing, treated the log as a forensic trail: kernel oopses pointed to GPU reset storms, which led to the discovery that a modded VBIOS was running the card at a 3136 MHz state the silicon could not hold. Capped the clock at 2500 MHz, migrated to ROCm 7.14, added ZFS snapshots, and rebuilt the stack so a single process serves LLM, embeddings, ASR and TTS concurrently. The farm grew to 10 nodes and 70 GPUs at ~10 kW with a +35 °C thermal delta.
Constraints
- 24 GB of VRAM is the hard ceiling — every model must fit on one card or fall back to slow CPU inference.
- The farm is fully self-hosted: zero public ports, every service reached through the router.
- Instability had to be root-caused to firmware and hardware, not papered over with software workarounds.
Tools in the system
- ROCm 7.14 / HIP (gfx1100)
- llama.cpp
- whisper.cpp
- qwen3-tts.cpp
- VFIO / IOMMU
- Proxmox VE
- ZFS
- Qdrant
- FastAPI
- systemd
- MikroTik RouterOS
What changed
One 24 GB card now serves a 36B MoE model, embeddings, ASR and TTS simultaneously — at up to 2,426 tok/s prefill and 87–125 tok/s decode across a 10-language voice loop. The 70-GPU farm runs stable 24/7 since the firmware fix: the answer was a clock state in the VBIOS, not the software stack.
What carries forward
- 01When one number goes wrong — decode speed halved, cache thrashing — read the hardware registers before the config file: the root cause was a modded VBIOS clock state, not a software bug.
- 02Budget the whole stack against one ceiling: the 36B model, KV cache, ASR, TTS and embeddings all fit in 25.3/25.7 GB because every layer was sized against the same VRAM budget.
- 03Stability at fleet scale is a firmware and power question first: capping the clock to 2500 MHz did what days of software tuning could not.
Related case studies
All work- AI & Agents · 2026OCR document analyzer — waste-manifest ticket intakeA vision-LLM system that reads ~50 WhatsApp scale-ticket scans a day and replaces manual re-typing with validated extraction and one-click export.
- AI & Agents · 2025Retrieval-augmented support agentAn LLM agent that drafts answers from the company's own docs and hands off when unsure.