Manual · Custom Engine

Rust inference engine

Built and running on B200. A Rust-based inference engine for disaggregated setups, with CUDA kernels in Rust.

Why write an inference engine in Rust? Because Rust gives you C++ performance with memory safety, and for a serving engine, that's the whole game. No garbage collector, no interpreter, no runtime surprises. The engine compiles to a single binary that loads a model and serves tokens.

This is the story of building one, and running it on B200 in disaggregated setups.

Why Rust for inference

The architecture

The components

The Rust + CUDA pattern

The canonical architecture for high-performance Rust inference is Rust orchestration over raw CUDA kernels, via the cudarc crate (safe Rust bindings for the entire CUDA toolkit: cuBLASLt, NCCL, cuDNN, NVRTC, cuFILE/GDS, CUPTI). Candle's kernel library demonstrates the exact pattern: hand-written .cu files for matmul, attention, quantized GEMM, and MoE dispatch, wrapped in safe Rust.

Key pieces for B200 disaggregated serving: NCCL bindings for inter-GPU KV-cache transfer, cuBLASLt for Blackwell's FP4/FP8 tensor core GEMMs, cuFILE/GDS for zero-copy KV-cache persistence, and dynamic loading so the same binary runs across CUDA 12.x and 13.x.

What running on B200 means

B200's FP4 and dual-die architecture are the reason a Rust engine makes sense. The engine compiles to native code that drives the tensor cores directly, no framework in between. In disaggregated setups, the engine runs on decode nodes, streaming tokens while the KV cache pool holds the context.

The proof it works: mistral.rs (a production Rust engine) benchmarks on B200 show 27,706 TPS prefill (Q8) vs llama.cpp's 11,992, and 43,548 TPS BF16 prefill vs vLLM's 39,431. A Rust engine can match or beat the established C++/Python engines on Blackwell. The result: frontier models served from a single binary, with the latency and throughput of a hand-tuned C++ engine and the safety of Rust.

Sources

Back to the manual