← all projects

Hardware project · August 2026 – ongoing

The X99 Build

One secondhand Huananzhi X99-BD4 board turned into a roughly $200 inference server that I keep extending: soldering its PCIe lanes, flashing its BIOS, waking it over the network, unlocking the mining GPUs, and running two NVIDIA cards on two different drivers at once, pooled for one model.

The second GPU slot now holds an AMD Radeon VII on ROCm, next to the unlocked CMP 40HX. The Tesla V100 goes back into that slot when I want the pooled VFIO setup, and the Radeon comes out.

~$200secondhand board, CPU and mining GPUs 0.98 → 54FP16 TFLOPS on the CMP 40HX after the unlock 24 tok/sQwen3 32B pooled across the CMP and V100 54 s → 0.27 sGemma 4 time to first token with KV snapshots

Current setup

The X99 inference box An Orange Pi Zero wakes the X99 host over Tailscale. The host runs the patched NVIDIA 610 open driver with the unlocked CMP 40HX on PCIe Gen2, and an AMD Radeon VII on amdgpu and ROCm 6.3.3, capped at 200 watts. The Radeon VII shares its slot with a Tesla V100: when the V100 is installed it is passed through with vfio-pci to a KVM/QEMU guest running the closed 580 driver, and llama.cpp RPC pools it with the CMP to serve Qwen3 32B at 24 tokens per second. Orange Pi Zero — WoL listener + relay laptop Tailscale power on Huananzhi X99-BD4 — Ubuntu host host · patched NVIDIA 610 open (cmpunlocker) + amdgpu NVIDIA 610 open · patched CMP 40HX — TU106 FP16 unlocked · 54 TFLOPS PCIe Gen2 x16 (5 GT/s) BAR1 8 GiB · ReBAR amdgpu · ROCm 6.3.3 Radeon VII — Vega 20 16 GB HBM2 · gfx906 PCIe 3.0 x16 (8 GT/s) capped at 200 W swap slot VFIO guest (when the V100 is in) KVM/QEMU · OVMF · libvirt NVIDIA 580 closed Tesla V100 — GV100 16 GB HBM2 vfio-pci passthrough llama.cpp RPC pools the CMP + guest V100 Qwen3 32B · 24 tok/s with the V100 · Ubuntu 22.04 / Linux 5.15
The host runs the unlocked CMP 40HX on the patched 610 driver and a Radeon VII on ROCm, capped at 200 W. The Radeon VII and the Tesla V100 share a slot: with the V100 in, it lives in a VFIO guest on the closed 580 driver, and llama.cpp pools it with the CMP over RPC to serve Qwen3 32B. An Orange Pi Zero wakes the whole thing over Tailscale.

Build log

Each chapter is a write-up of one change to the machine, in the order it happened.

Two CMP 40HX mining GPUs mounted on the Huananzhi X99 BD4 motherboard

200 Bucks Inference Machine

Where the build started: mining GPUs turned into a local inference server, with a PCIe x16 capacitor mod, patched CUDA kernels, and KV cache reuse on Gemma 4 cutting time to first token from 54 s to 0.27 s.

Linux PCIe firmware
Bar chart of time to first token on a 15.6k-token Gemma 4 E4B prompt: llama.cpp cold 85 s, mistral.rs cold 54.4 s, mistral.rs cached 0.27 s

kvsnap: mistral.rs vs llama.cpp

Gemma 4 time to first token from 54 s to 0.27 s on this box, with a 17-line KV cache snapshot patch to mistral.rs.

Rust mistral.rs llama.cpp
Bar chart of extraction precision: Gemma 4 E4B 95%, Qwen3.5 4B 83%, Qwen3 8B 63%, Qwen2.5 3B 43%

Four Small LLMs on One 8GB Card

Gemma 4 E4B and three Qwen models on schema-constrained extraction over 78 hand-labeled documents, run on the CMP. Gemma led at 95% precision.

Ollama Gemma 4 Qwen
Orange Pi Zero wired to a relay module next to the X99 BD4 motherboard

Wake on LAN Retrofit

A BIOS with no Wake on LAN, on Wi-Fi that isolates clients: a Python listener on an Orange Pi Zero validates magic packets over Tailscale and presses the X99's power button with a relay.

Python systemd GPIO Tailscale
Arc B580 mounted on the Huananzhi X99-BD4 test bench

Resizable BAR on X99

Inserting ReBarDxe into the X99-BD4 BIOS, and catching a 16-byte corruption UEFITool left in a volume I never touched.

UEFI ReBarDxe firmware
Terminal showing the CMP 40HX link retrained to 5GT/s x16

CMP 40HX: PCIe 2.0, ReBAR and FP16 Unlock

Patched NVIDIA kernel modules lift the mining card's limits. FP16 went from 0.98 to 54 TFLOPS, generation doubled, and a manual root port retrain got Gen2 working on X99.

NVIDIA drivers PCIe setpci
Tesla V100 on a PCIe adapter with a blower shroud, power cables connected, installed in the X99 machine

V100 + CMP 40HX: Two Drivers, One Box

A Tesla V100 passed through to a KVM guest with vfio-pci so it can run the closed 580 driver, while the host keeps the patched 610 for the CMP. llama.cpp RPC pools both GPUs to serve Qwen3 32B at 24 tok/s.

VFIO KVM/QEMU libvirt llama.cpp
Terminal showing the Ansible roles, a verify warning about the next-boot kernel, and a passing dry run

X99 Recreation (Ansible)

The whole box as code: 7 Ansible roles distilled from 1,661 lines of shell history. It pins the NVIDIA open driver, rebuilds the patched CMP 40HX modules for every new kernel, and retrains the PCIe link to Gen2 at boot. Its verify step caught a kernel update that would have booted the stock driver.

Ansible systemd Linux NVIDIA drivers

Documentation

Hardware

PartWhat’s in it
BoardHuananzhi X99-BD4, AMI Aptio V 5.11 BIOS with ReBarDxe inserted
CPUIntel Xeon E5-2678 v3 (Haswell-EP, 12 cores)
OSUbuntu 24.04, Linux 7.0 (HWE)
NetworkWi-Fi + Tailscale; powered on by an Orange Pi Zero relay

GPU slots

SlotCardDriverLinkNotes
Root port 3CMP 40HX (TU106, 8 GB)NVIDIA 610.57.04 open, patched by cmpunlockerPCIe Gen2 x16, retrained at bootFP16 unlocked, 8 GiB BAR1
Root port 2Radeon VII (Vega 20, 16 GB HBM2)amdgpu + ROCm 6.3.3PCIe 3.0 x16capped at 200 W (stock 250 W), 16 GiB BAR0
Root port 2 (swap)Tesla V100 SXM2 (16 GB HBM2)NVIDIA 580 closed, inside a KVM guestvfio-pci passthroughreplaces the Radeon VII for the pooled llama.cpp setup

Rebuilding it

The whole box is described in X99-Recreation, an Ansible playbook that rebuilds it from a fresh Ubuntu install:

What happens at boot

  1. The patched NVIDIA modules load and try their own Gen2 retrain, which fails on this board’s root port.
  2. cmp40hx-gen2-retrain reprobes the driver so the card advertises Gen2, then retrains the link from the root port: 2.5 → 5 GT/s. It checks the PCI ID first, so it won’t touch a different card if the slots change.
  3. cap-cmp40hx locks the CMP’s idle clock to 300 MHz (cmp40hx-uncap releases it for inference).
  4. amdgpu-power-cap finds the Radeon VII by PCI ID and sets its cap to 200 W.

The unlock is volatile and the patched modules are built per kernel, so a kernel hook rebuilds cmpunlocker for every new kernel before it’s booted.

Key terms for the V100 setup

IOMMU VFIO vfio-pci GPU passthrough KVM/QEMU libvirt OVMF (UEFI) Above 4G Decoding llama.cpp RPC