Fastest gpt-oss-120b inference on DGX Spark - 72 tok/s decode with TP=2, beating all competitors.
Based on: https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch
| Context | Prefill (t/s) | Decode tg32 (t/s) | Decode tg128 (t/s) |
|---|---|---|---|
| 2048 | 6,329 | 72.71 | 71.43 |
| Context | Prefill (t/s) | Decode tg32 (t/s) | Decode tg128 (t/s) |
|---|---|---|---|
| Short (512) | 1,854 | 60.02 | 60.07 |
| Medium (2048) | 4,573 | 59.36 | 59.47 |
| Long (8192) | 6,628 | 57.52 | 57.81 |
| Engine | Decode (t/s) | Status |
|---|---|---|
| SGLang | 52 | ✅ Beat by 38% (TP=2) |
| llama.cpp | 58 | ✅ Beat by 24% (TP=2) |
| vLLM TP=1 | 57-60 | Previous best |
| vLLM TP=2 RDMA | 72 | New Champion |
See the discussion on NVIDIA Developer Forums for more details.
--mxfp4-backend - Single flag to select CUTLASS, MARLIN, TRITON, or auto--mxfp4-layers - Fine-grained control over which layers to quantizedocker build -t vllm-mxfp4-spark .
Note: First build takes ~30 minutes (compiling CUDA kernels). Subsequent builds are faster due to ccache.
# Install uv (fast Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.local/bin/env
# Install huggingface hub CLI
uv tool install huggingface_hub
# Download gpt-oss-120b (~240GB)
hf download openai/gpt-oss-120b
# Start the server
docker compose up -d
# View logs
docker compose logs -f
# Enter the container
docker compose exec vllm-mxfp4 bash
# Stop
docker compose down
docker run --gpus all -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-v ./.cache/flashinfer:/root/.cache/flashinfer \
vllm-mxfp4-spark
The volume mounts persist the model cache and JIT-compiled kernels between runs.
Once the server is running, run the benchmark:
docker compose exec vllm-mxfp4 llama-benchy \
--base-url http://localhost:8000/v1 \
--model gpt-oss-120b \
--tokenizer openai/gpt-oss-120b \
--pp 512 2048 8192 \
--tg 32 128 \
--runs 5
# Health check
curl http://localhost:8000/health
# Chat completion
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-oss-120b",
"messages": [{"role": "user", "content": "Are we fast yet?"}]
}'
The server starts with optimized settings for gpt-oss-120b:
| Setting | Value |
|---|---|
| Quantization | MXFP4 with CUTLASS backend |
| Attention | FlashInfer with FP8 KV cache |
| Max context | 131072 tokens |
| GPU memory | 70% utilization |
See docker-compose.yml for full configuration.
To achieve 72 tok/s with two-node tensor parallelism:
/dev/infiniband devices available on both nodesThe key fix is exposing InfiniBand devices to Docker:
# docker-compose.yml already includes:
devices:
- /dev/infiniband:/dev/infiniband
cap_add:
- IPC_LOCK
# Find your network interface and RoCE device
ip addr show # e.g., enp1s0f1np1
ibdev2netdev # e.g., rocep1s0f1 port 1 ==> enp1s0f1np1
# Set on both nodes
export NCCL_SOCKET_IFNAME=enp1s0f1np1
export NCCL_IB_DISABLE=0
export NCCL_IB_HCA=rocep1s0f1
On head node:
docker compose -f docker-compose.dev.yml exec dev bash
ray start --head --port=6379
On worker node:
docker compose -f docker-compose.dev.yml exec dev bash
ray start --address=<head-ip>:6379
vllm serve openai/gpt-oss-120b \
--quantization mxfp4 \
--mxfp4-backend CUTLASS \
--mxfp4-layers moe,qkv,o,lm_head \
--tensor-parallel-size 2 \
--attention-backend FLASHINFER \
--kv-cache-dtype fp8
Check NCCL logs for RoCE transport:
# Good (RDMA):
NCCL INFO NET/IB : Using [0]rocep1s0f1:1/RoCE...
# Bad (falling back to TCP):
NCCL INFO NET/Socket : Using [0]enp1s0f1np1...
See docs/NCCL_TUNING_TP2.md for advanced tuning options.
For development with local FlashInfer/vLLM repos:
# Clone the repos (one-time setup)
mkdir -p ~/projects && cd ~/projects
git clone -b mxfp4_v2 https://github.com/christopherowen/vllm.git
git clone -b mxfp4_v2 https://github.com/christopherowen/flashinfer.git
# Initialize submodules and switch CUTLASS to our fork
cd flashinfer
git submodule update --init --recursive
cd 3rdparty/cutlass
git remote set-url origin https://github.com/christopherowen/cutlass.git
git fetch origin
git checkout mxfp4_v2
cd ~/projects
# Start development container
cd ~/projects/ai/mxfp4
docker compose -f docker-compose.dev.yml up -d
docker compose -f docker-compose.dev.yml exec dev bash
The Dockerfile uses Docker BuildKit cache mounts to speed up rebuilds:
First build takes ~30 minutes. Subsequent builds are much faster.
To clear caches:
# Clear Docker BuildKit caches (git repos, ccache, pip)
docker builder prune --filter type=exec.cachemount
# Clear FlashInfer JIT cache (volume mount)
sudo rm -rf .cache/
Upstreaming
--mxfp4-layers) and SM121 fixes to vLLM upstreamPerformance Optimizations
mxf4.block_scale instruction, we use FP8×FP4)Multi-Node / Ray Cluster
enable_asyncio=False. The Ray executor already has max_concurrent_batches=2 logic; enabling async would allow batch pipelining (schedule next batch while current executes). Requires: (1) change enable_asyncio=True in ray_executor.py, (2) add "ray" to executor_supports_async_sched in vllm/config/vllm.py, (3) test for deadlocks/race conditions in multi-node settingray[default] in container for full dashboard/metrics support (currently using minimal Ray without aiohttp_cors)New Features
Numerical Accuracy
"Rare sightings of forbidden ISA" -- inspired by sandsifter.
SASSquatch systematically probes the SM121 GPU instruction set to discover what the hardware actually supports versus what is documented. It operates in three phases:
# Run inside the dev container
docker exec -it vllm-dev python3 scripts/sasquatch/sasquatch.py --phase 1 --target sm_121a
PTX probes target PTX ISA 9.1 (CUDA 13.1). See scripts/sasquatch/ for source.
| Component | SHA | Repository |
|---|---|---|
| vLLM | 045293d82b832229560ac4a13152a095af603b6e | christopherowen/vllm |
| FlashInfer | f349e52496a72a00d8c4ac02c7a1e38523ff7194 | christopherowen/flashinfer |
| CUTLASS | fede53000a962b46e05bafe0c86311778caeb380 | christopherowen/cutlass |
155 commits
Python
77.3%
Shell
19.6%
Cuda
1.8%
Dockerfile
1.3%
Fastest gpt-oss-120b inference on DGX Spark - 72 tok/s decode with TP=2, beating all competitors.
Based on: https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch
| Context | Prefill (t/s) | Decode tg32 (t/s) | Decode tg128 (t/s) |
|---|---|---|---|
| 2048 | 6,329 | 72.71 | 71.43 |
| Context | Prefill (t/s) | Decode tg32 (t/s) | Decode tg128 (t/s) |
|---|---|---|---|
| Short (512) | 1,854 | 60.02 | 60.07 |
| Medium (2048) | 4,573 | 59.36 | 59.47 |
| Long (8192) | 6,628 | 57.52 | 57.81 |
| Engine | Decode (t/s) | Status |
|---|---|---|
| SGLang | 52 | ✅ Beat by 38% (TP=2) |
| llama.cpp | 58 | ✅ Beat by 24% (TP=2) |
| vLLM TP=1 | 57-60 | Previous best |
| vLLM TP=2 RDMA | 72 | New Champion |
See the discussion on NVIDIA Developer Forums for more details.
--mxfp4-backend - Single flag to select CUTLASS, MARLIN, TRITON, or auto--mxfp4-layers - Fine-grained control over which layers to quantizedocker build -t vllm-mxfp4-spark .
Note: First build takes ~30 minutes (compiling CUDA kernels). Subsequent builds are faster due to ccache.
# Install uv (fast Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.local/bin/env
# Install huggingface hub CLI
uv tool install huggingface_hub
# Download gpt-oss-120b (~240GB)
hf download openai/gpt-oss-120b
# Start the server
docker compose up -d
# View logs
docker compose logs -f
# Enter the container
docker compose exec vllm-mxfp4 bash
# Stop
docker compose down
docker run --gpus all -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-v ./.cache/flashinfer:/root/.cache/flashinfer \
vllm-mxfp4-spark
The volume mounts persist the model cache and JIT-compiled kernels between runs.
Once the server is running, run the benchmark:
docker compose exec vllm-mxfp4 llama-benchy \
--base-url http://localhost:8000/v1 \
--model gpt-oss-120b \
--tokenizer openai/gpt-oss-120b \
--pp 512 2048 8192 \
--tg 32 128 \
--runs 5
# Health check
curl http://localhost:8000/health
# Chat completion
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-oss-120b",
"messages": [{"role": "user", "content": "Are we fast yet?"}]
}'
The server starts with optimized settings for gpt-oss-120b:
| Setting | Value |
|---|---|
| Quantization | MXFP4 with CUTLASS backend |
| Attention | FlashInfer with FP8 KV cache |
| Max context | 131072 tokens |
| GPU memory | 70% utilization |
See docker-compose.yml for full configuration.
To achieve 72 tok/s with two-node tensor parallelism:
/dev/infiniband devices available on both nodesThe key fix is exposing InfiniBand devices to Docker:
# docker-compose.yml already includes:
devices:
- /dev/infiniband:/dev/infiniband
cap_add:
- IPC_LOCK
# Find your network interface and RoCE device
ip addr show # e.g., enp1s0f1np1
ibdev2netdev # e.g., rocep1s0f1 port 1 ==> enp1s0f1np1
# Set on both nodes
export NCCL_SOCKET_IFNAME=enp1s0f1np1
export NCCL_IB_DISABLE=0
export NCCL_IB_HCA=rocep1s0f1
On head node:
docker compose -f docker-compose.dev.yml exec dev bash
ray start --head --port=6379
On worker node:
docker compose -f docker-compose.dev.yml exec dev bash
ray start --address=<head-ip>:6379
vllm serve openai/gpt-oss-120b \
--quantization mxfp4 \
--mxfp4-backend CUTLASS \
--mxfp4-layers moe,qkv,o,lm_head \
--tensor-parallel-size 2 \
--attention-backend FLASHINFER \
--kv-cache-dtype fp8
Check NCCL logs for RoCE transport:
# Good (RDMA):
NCCL INFO NET/IB : Using [0]rocep1s0f1:1/RoCE...
# Bad (falling back to TCP):
NCCL INFO NET/Socket : Using [0]enp1s0f1np1...
See docs/NCCL_TUNING_TP2.md for advanced tuning options.
For development with local FlashInfer/vLLM repos:
# Clone the repos (one-time setup)
mkdir -p ~/projects && cd ~/projects
git clone -b mxfp4_v2 https://github.com/christopherowen/vllm.git
git clone -b mxfp4_v2 https://github.com/christopherowen/flashinfer.git
# Initialize submodules and switch CUTLASS to our fork
cd flashinfer
git submodule update --init --recursive
cd 3rdparty/cutlass
git remote set-url origin https://github.com/christopherowen/cutlass.git
git fetch origin
git checkout mxfp4_v2
cd ~/projects
# Start development container
cd ~/projects/ai/mxfp4
docker compose -f docker-compose.dev.yml up -d
docker compose -f docker-compose.dev.yml exec dev bash
The Dockerfile uses Docker BuildKit cache mounts to speed up rebuilds:
First build takes ~30 minutes. Subsequent builds are much faster.
To clear caches:
# Clear Docker BuildKit caches (git repos, ccache, pip)
docker builder prune --filter type=exec.cachemount
# Clear FlashInfer JIT cache (volume mount)
sudo rm -rf .cache/
Upstreaming
--mxfp4-layers) and SM121 fixes to vLLM upstreamPerformance Optimizations
mxf4.block_scale instruction, we use FP8×FP4)Multi-Node / Ray Cluster
enable_asyncio=False. The Ray executor already has max_concurrent_batches=2 logic; enabling async would allow batch pipelining (schedule next batch while current executes). Requires: (1) change enable_asyncio=True in ray_executor.py, (2) add "ray" to executor_supports_async_sched in vllm/config/vllm.py, (3) test for deadlocks/race conditions in multi-node settingray[default] in container for full dashboard/metrics support (currently using minimal Ray without aiohttp_cors)New Features
Numerical Accuracy
"Rare sightings of forbidden ISA" -- inspired by sandsifter.
SASSquatch systematically probes the SM121 GPU instruction set to discover what the hardware actually supports versus what is documented. It operates in three phases:
# Run inside the dev container
docker exec -it vllm-dev python3 scripts/sasquatch/sasquatch.py --phase 1 --target sm_121a
PTX probes target PTX ISA 9.1 (CUDA 13.1). See scripts/sasquatch/ for source.
| Component | SHA | Repository |
|---|---|---|
| vLLM | 045293d82b832229560ac4a13152a095af603b6e | christopherowen/vllm |
| FlashInfer | f349e52496a72a00d8c4ac02c7a1e38523ff7194 | christopherowen/flashinfer |
| CUTLASS | fede53000a962b46e05bafe0c86311778caeb380 | christopherowen/cutlass |
155 commits
Python
77.3%
Shell
19.6%
Cuda
1.8%
Dockerfile
1.3%