This repository contains a small patch to benchmarks/kernels/benchmark_moe.py that makes the MoE Triton tuner practical for single-GPU setups and older vLLM APIs (tested with vLLM 0.10.1.1).
It narrows the search space, avoids API mismatches, and writes the tuned config JSON directly into vLLM’s built-in configs/ directory so vLLM will auto-load it at model startup.
Target version
- The script matches vLLM 0.10.1.1 APIs. We avoid newer helpers (
FusedMoEQuantConfig.make,_get_config_dtype_str, etc.) that don’t exist in 0.10.1.1 and instead use the functions and call sites available in this release.
Safer dtype handling
- Older configs don’t expose
config.dtype. We useconfig.torch_dtype(ortorch.float16on ROCm) when benchmarking to avoidAttributeError.
Minimal tuning space (fast)
- Reduced CUDA search ranges (BLOCK_M/N/K, warps, stages) and optional “tiny” space to cut total configs from ~1900 down to 8–64 (minutes vs. many hours). This still finds good kernels for common MoE sizes.
Writes to the right place
- Saves the resulting JSON to the installed vLLM package directory, e.g.
/usr/local/lib/python3.11/dist-packages/vllm/model_executor/layers/fused_moe/configs/so the runtime can find it automatically (you’ll see “Using default MoE config” disappear in logs).
No Ray dashboard
- Avoids slow/failed dashboard startup noise in containers.
Single-GPU friendly
- Defaults to one Ray worker bound to one GPU so the JIT is compiled exactly where the kernel will run.
DeepGEMM off by default
- Focuses the tuner on Triton kernels (DeepGEMM can be toggled if you really need it, but was a source of confusion/OOR in this environment).
- A file named like:
E=<experts>,N=<intermediate/2>,device_name=<autodetected>.jsonappears in vLLM’sconfigs/directory when tuning completes. - Subsequent vLLM startups for that model+GPU print no “Using default MoE config” warning; throughput and queueing behavior should improve noticeably for MoE models.
- In our tests this change unlocked stable multi-request concurrency and ~tens of tokens/s on problematic prompts.
Edit (or replace) this file in your local vLLM checkout:
benchmarks/kernels/benchmark_moe.py
⚠️ Keep the file path the same; the CLI invocation expects it.
Clone the vLLM repo and check out the branch/tag that matches your runtime (here we use v0.10.1.1 as an example):
git clone https://github.com/vllm-project/vllm.git
cd vllm
git checkout v0.10.1.1Now apply/overwrite benchmarks/kernels/benchmark_moe.py with the patched version from this repo.
These examples assume:
- Python at
/usr/bin/python3- You’re inside a container/host that’s already running vLLM 0.10.1.1
- You want the tuned JSON to land in vLLM’s installed package directory
export PYTHONNOUSERSITE=1
export RAY_DISABLE_DASHBOARD=1
CFG_DIR="/usr/local/lib/python3.11/dist-packages/vllm/model_executor/layers/fused_moe/configs"
mkdir -p "$CFG_DIR"/usr/bin/python3 benchmarks/kernels/benchmark_moe.py \
--model /var/lib/gpustack/cache/huggingface/cerebras/Qwen3-Coder-REAP-25B-A3B \
--tp-size 1 \
--dtype auto \
--tune \
--batch-size 1 2 4 8 16 32 64 \
--save-dir "$CFG_DIR"What you should see
- A line like
Start tuning over 8 configurations...(or another small number, depending on GPU) - Per-batch “Completed tuning…” lines
- A final
Writing best config to .../configs/E=...,N=...,device_name=....json
/usr/bin/python3 benchmarks/kernels/benchmark_moe.py \
--model /var/lib/gpustack/cache/huggingface/ibm-granite/granite-4.0-h-tiny \
--tp-size 1 \
--dtype auto \
--tune \
--batch-size 1 2 4 8 16 32 64 \
--save-dir "$CFG_DIR"After tuning, start vLLM. The startup logs should not contain:
WARNING ... Using default MoE config. Performance might be sub-optimal!
-
Device name The JSON filename embeds
device_name=.... vLLM picks a pretty specific string (e.g.,NVIDIA_RTX_PRO_6000_Blackwell_Server_EditionorNVIDIA_GeForce_RTX_4090). If you move the file between machines with slightly differentdevice_names, duplicate/rename accordingly. -
Batch sizes The script tunes across a small set of batch sizes (
1 2 4 8 16 32 64) that map well to common scheduler choices. You can change--batch-sizeto include the sizes you care about. -
Expert parallel The tuner assumes no EP (
--tp-size 1and--enable-expert-paralleloff). If you use EP at runtime, the MoE shard shapes change; tune again with the same topology you’ll serve. -
FP8 / quantized paths This tuner uses the release-0.10.1.1 call pattern (
use_fp8_w8a8,use_int8_w8a16, per-tensor or block scales) and avoids newerQuantConfighelpers that aren’t present in this tag. -
Ray dashboard noise If Ray prints “Failed to start dashboard”, that’s fine—we disable it and the workers still run. The “Started a local Ray instance.” line indicates success.
-
Where configs are loaded from vLLM searches its own
configs/package directory at runtime. Saving the JSON into:.../vllm/model_executor/layers/fused_moe/configs/ensures the engine finds it automatically.
- No file written / still “Using default MoE config”
Confirm
--save-dirpoints to the installed vLLM packageconfigs/path (not your repo checkout). Also confirm the filename’sE,N, anddevice_namematch your model & GPU.
This patch follows vLLM’s original license headers (Apache-2.0).