switchyard · mixture-of-experts serving
OLMoE-1B-7B sends every token to 8 of the 64 experts in each layer. switchyard gives each GPU half of every layer's experts and moves tokens between GPUs with its own kernels, so the output matches one GPU bit for bit. Everything below the model is written from scratch, including the measurement of what load balancing is worth.
OLMoE-1B-7B on two Tesla T4s, decode tokens per second at batch 8; 823 tokens/s at batch 64. Peak memory 7.6 GiB per GPU for a 13.8 GB model.
Higher is better (bench/serve.py). Greedy output identical to transformers on 7 of 8 prompts over 32 tokens.
Each GPU is driven by its own thread; getting that right meant finding two cross-stream races that only appeared without CUDA_LAUNCH_BLOCKING.
Each token routed in one warp; rows sorted by expert with a block-wide prefix scan and no atomics.
A tensor-core grouped GEMM with SwiGLU fused into its epilogue; for decode, a grouped GEMV at 73% of memory bandwidth.
A kernel writes rows straight into the other GPU's memory, ordered by CUDA events: 1.25× NCCL's all-to-all at 256 tokens per GPU, level at 16–64, slower at 1 and 1,024.
WikiText-2, 2,048 tokens per GPU. The busiest expert gets 4.0× the mean load; the GPUs stay within 6%. Capacity limits drop the tokens an expert has no room for:
| Capacity factor | Tokens dropped | Perplexity |
|---|---|---|
| dropless (switchyard) | 0% | 12.85 |
| 2.0 | 9.6% | 20.19 |
| 1.0 | 28.6% | 92.14 |
Even a generous capacity factor of 2 raises perplexity from 12.9 to 20.2, so switchyard never drops a token (bench/balance.py).
How mixture-of-experts models are served at scale, rebuilt on two free GPUs, with the costs measured rather than assumed.
All 64 experts in one launch, SwiGLU fused, 5.4–7× a per-expert loop.
Peer-to-peer dispatch whose output is bit-identical to one GPU.
112 vs 52 tokens/s decoding OLMoE-1B-7B on two T4s.
Capacity factor 2 drops 9.6% of tokens and raises perplexity 12.9 → 20.2.
Over PCIe, splitting the experts is never faster than keeping all 64 on one GPU; here expert parallelism buys memory (7.6 GiB per GPU for a 13.8 GB model), not speed.
@software{kundu2026switchyard,
author = {Kundu, Sankur},
title = {switchyard: mixture-of-experts serving across GPUs},
year = {2026},
url = {https://github.com/Shakhtar-Sankur/switchyard},
license = {Apache-2.0}
}