Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/bench-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ on:
- "bench/**"
- "docker/**"
- "Dockerfile.recipes"
- "Dockerfile.sm120-v025"
- "README.md"
- "docs/v025-port.md"
- "docs/benchmarks/**"
- "patch/**"
- "tools/check_patch_files.py"
Expand All @@ -26,8 +28,10 @@ jobs:
with:
python-version: "3.12"
- run: pip install pyyaml
- name: Patch file list matches patch/FILES.txt (lost-line guard)
run: python3 tools/check_patch_files.py
- name: Patch file lists match both frozen release overlays
run: |
python3 tools/check_patch_files.py
python3 tools/check_patch_files.py --version 0.25.0
- name: Lint recipes, boxes, suites, matrix, results
run: python3 bench/runner/lint.py
- name: Verify README table + report match committed results
Expand Down
63 changes: 63 additions & 0 deletions Dockerfile.sm120-v025
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# vLLM-Moet on official vLLM v0.25.0 — SM120 (RTX PRO 6000 / RTX 5090)
#
# This is a side-by-side upgrade candidate. Dockerfile.sm120-v024 remains the
# proven rollback until the v0.25 image passes the baked SM120 and live canary
# gates documented in docs/v025-port.md.
#
# Build (linux/amd64 NVIDIA host, from the repo root):
# DOCKER_BUILDKIT=1 docker build -f Dockerfile.sm120-v025 \
# -t vllm-moet-sm120:v025-w2candidate .

ARG VLLM_BASE=vllm/vllm-openai:v0.25.0@sha256:e1c1ff1af9a15921bfa11d1d95047258c1797392cdbfa296e7639da446b23f97
FROM ${VLLM_BASE}

LABEL org.opencontainers.image.version="v0.25.0-w2candidate" \
ai.kostudios.vllm-moet.base="vllm/vllm-openai:v0.25.0" \
ai.kostudios.vllm-moet.patch-sha256="25ac6fea69d71c1a641b0d6343c01011bca3b481436e29f9f02f8e4c3ce639a4"

# v0.25.0 already vendors the same SM120-capable DeepGEMM commit used by the
# v0.24 recipe (a6b593d2826719dcf4892609af7b84ee23aaf32a), so no replacement
# wheel is built here. git is needed only to apply the source overlay.
RUN apt-get update && apt-get install -y --no-install-recommends git \
&& rm -rf /var/lib/apt/lists/*

# The W2 NVFP4 sparse-MLA patch was validated against FlashInfer 0.6.14's JIT
# source/API layout. vLLM v0.25.0 pins 0.6.13, so preserve the proven 0.6.14
# pair until the hardware canary explicitly qualifies the upstream pin.
RUN pip uninstall -y --break-system-packages flashinfer-cubin || true
RUN pip install --no-cache-dir --break-system-packages flashinfer-python==0.6.14 \
&& pip install --no-cache-dir --break-system-packages \
--index-url https://flashinfer.ai/whl/cu130 \
"flashinfer-jit-cache==0.6.14+cu130"

# Combined v0.25.0 overlay: W2 streaming/recovery and stores, DSpark confidence
# scheduling, NVFP4 KV, and the SM120 fixes not absorbed by the release.
COPY patch/vllm-moet-v0.25.0.patch /tmp/vllm-moet.patch
RUN SP="$(python3 -c 'import vllm, os; print(os.path.dirname(os.path.dirname(vllm.__file__)))')" \
&& cd "$SP" \
&& git apply --check /tmp/vllm-moet.patch \
&& git apply --verbose /tmp/vllm-moet.patch \
&& python3 -m py_compile \
vllm/v1/worker/gpu/spec_decode/dspark/scheduler.py \
vllm/model_executor/layers/quantization/utils/moe_w2_cubit.py \
vllm/model_executor/layers/quantization/utils/moe_w2_store.py \
&& python3 -c "from vllm.model_executor.layers.quantization.utils import moe_w2_cubit; print('moe_w2 hook OK')" \
&& python3 -c "import vllm.v1.worker.gpu.spec_decode.dspark.speculator; print('dspark OK')" \
&& rm /tmp/vllm-moet.patch

# Prebuilt SM120 W2/W4 GEMM cubins, including K=6144 for GLM-5.x.
COPY kernels/cubins-sm120/ /cubit-share/
ENV VLLM_MOE_W2_CUBIT_DIR=/cubit-share

# Bake the NVFP4 sparse-MLA read and packed-write kernels so the first serve
# does not pay JIT compilation. See Dockerfile.sm120-v024 for layout details.
RUN SP="$(python3 -c 'import vllm, os; print(os.path.dirname(os.path.dirname(vllm.__file__)))')" \
&& cd "$SP" \
&& python3 tools/nvfp4_flashinfer_sm120/patch_flashinfer.py \
&& rm -f "$SP/flashinfer_jit_cache/jit_cache/sparse_mla_sm120/sparse_mla_sm120.so" \
&& FLASHINFER_CUDA_ARCH_LIST=12.0f python3 -c \
"from flashinfer.jit.mla import gen_sparse_mla_sm120_module; gen_sparse_mla_sm120_module().build(verbose=False)" \
&& mkdir -p /opt/nvfp4-ds-mla \
&& TORCH_CUDA_ARCH_LIST=12.0a python3 -c \
"from torch.utils.cpp_extension import load; load(name='nvfp4_ds_mla_cache_ext', sources=['$SP/csrc/nvfp4_ds_mla/concat_and_cache_nvfp4_ds_mla.cu'], extra_cuda_cflags=['-O3', '--generate-code=arch=compute_120a,code=sm_120a'], build_directory='/opt/nvfp4-ds-mla')"
ENV VLLM_NVFP4_DS_MLA_EXT_DIR=/opt/nvfp4-ds-mla
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ cannot even fit on. Three ideas carry it:
bit‑deterministic), an **NVFP4 KV cache** (352 B/token), and agent‑ready tool/reasoning
parsing.

> **v0.25.0 upgrade candidate:** [`Dockerfile.sm120-v025`](Dockerfile.sm120-v025)
> and [`docs/v025-port.md`](docs/v025-port.md) carry the rebased 60-file overlay
> on official vLLM v0.25.0. The results below remain v0.24 measurements until
> the candidate passes its own SM120 model-load, 128K, quality, and performance
> gates; the v0.24 image stays the rollback.

---

## GLM‑5.2 (753B) — the headline model
Expand Down Expand Up @@ -250,6 +256,10 @@ git clone https://github.com/kacper-daftcode/vLLM-Moet && cd vLLM-Moet

# official vllm-openai:v0.24.0 image + patch + pins + SM120 cubins
DOCKER_BUILDKIT=1 docker build -f Dockerfile.sm120-v024 -t vllm-moet-sm120:v024 .

# side-by-side v0.25.0 candidate (do not replace the v0.24 live image yet)
DOCKER_BUILDKIT=1 docker build -f Dockerfile.sm120-v025 \
-t vllm-moet-sm120:v025-w2candidate .
```

**Easiest path — run a benchmarked recipe.** The recipes image downloads the
Expand Down Expand Up @@ -424,6 +434,12 @@ Release **`baseline-2026-07-10`** — one row per supported recipe (`bench/recip
<!-- bench:table:end -->

## Repository layout
- **`patch/vllm-moet-v0.25.0.patch`** — the v0.25 candidate delta (60 files,
+13,042/-133 source lines) against exact official tag commit `702f4814`.
- **`Dockerfile.sm120-v025`** — pinned official v0.25.0 image plus the candidate
overlay; built and qualified side-by-side with v0.24.
- **`docs/v025-port.md`** — exact identities, absorbed-upstream inventory,
compatibility decisions, completed source gates, and remaining promotion gates.
- **`patch/vllm-moet-v0.24.0.patch`** — the delta vs official vLLM `v0.24.0` (37 files,
+7.4k lines; applies clean on the tag). Goes with the pins above.
- **`Dockerfile.sm120-v024`** — the image: official `vllm/vllm-openai:v0.24.0` + patch + pins +
Expand Down
145 changes: 145 additions & 0 deletions docs/v025-port.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# The v0.25.0 upgrade candidate

This repository now carries a side-by-side W2 overlay for official vLLM
`v0.25.0`. It is an upgrade candidate, not yet the production default. The
proven v0.24 image, patch, recipes, and benchmark receipts remain intact as the
rollback boundary until the v0.25 candidate passes the SM120 hardware canary.

## Exact source identity

- Official tag: `v0.25.0`
- Official tag commit: `702f4814fe54fabff350d43cb753ae3e47c0c276`
- Linux/amd64 base image manifest: `sha256:e1c1ff1af9a15921bfa11d1d95047258c1797392cdbfa296e7639da446b23f97`
- W2 overlay: `patch/vllm-moet-v0.25.0.patch`
- Overlay SHA-256: `25ac6fea69d71c1a641b0d6343c01011bca3b481436e29f9f02f8e4c3ce639a4`
- Overlay scope: 60 files, 13,042 insertions, 133 deletions

Apply it directly to an official checkout with:

```bash
git clone --branch v0.25.0 https://github.com/vllm-project/vllm && cd vllm
git apply --check /path/to/vLLM-Moet/patch/vllm-moet-v0.25.0.patch
git apply /path/to/vLLM-Moet/patch/vllm-moet-v0.25.0.patch
```

Or build the pinned serving image:

```bash
DOCKER_BUILDKIT=1 docker build -f Dockerfile.sm120-v025 \
-t vllm-moet-sm120:v025-w2candidate .
```

## What v0.25 absorbed

The port was produced by applying the frozen v0.24 overlay to `v0.24.0`, then
rebasing that exact tree onto `v0.25.0` and resolving conflicts against the new
Model Runner V2 paths. Ten old overlay files disappeared because v0.25 now owns
their behavior, including the core DSpark/DFlash model registrations, DeepSeek
V4 DSpark implementation, Gumbel sampling, and SM120 cooperative-top-k guard.
The v0.25 overlay therefore drops those redundant hunks instead of shadowing
upstream.

Exact paths removed from the overlay:

```text
vllm/model_executor/models/qwen3_dflash.py
vllm/model_executor/models/registry.py
vllm/models/deepseek_v4/__init__.py
vllm/models/deepseek_v4/nvidia/dspark.py
vllm/models/deepseek_v4/nvidia/model.py
vllm/transformers_utils/configs/speculators/algos.py
vllm/v1/worker/gpu/sample/gumbel.py
vllm/v1/worker/gpu/spec_decode/__init__.py
vllm/v1/worker/gpu/spec_decode/dspark/__init__.py
vllm/v1/worker/gpu/spec_decode/eagle/eagle3_utils.py
```

The retained delta is the project-specific W2 stack: 2-bit planes, FP4
recovery and confidence gate, tiered/NVMe expert stores, persistent pack-cache
safety, SM120 cubins, NVFP4 KV, pipeline-aware replay, and the optional
hardware-aware DSpark confidence scheduler.

## Compatibility decisions

- **Model Runner V2 stays enabled.** The port preserves v0.25's new default and
composes W2 padded-slot, prefill, replay, Mamba-preprocess, and graph metadata
with it. It does not restore a V1/PagedAttention escape hatch.
- **DeepGEMM uses the release copy.** v0.25 already vendors exact commit
`a6b593d2826719dcf4892609af7b84ee23aaf32a`, the same SM120-capable commit the
v0.24 recipe built separately. The v0.25 Dockerfile removes that duplicate
wheel build.
- **FlashInfer remains 0.6.14 temporarily.** Official v0.25 pins 0.6.13, while
the W2 NVFP4 sparse-MLA source patch and JIT kwargs were hardware-validated on
0.6.14. The candidate preserves the proven pair and makes that deviation
explicit. Qualifying 0.6.13 is a separate canary, not an assumption.
- **SM120 raw FP8 scales remain.** The v0.25 release still uses the SM100 packed
scale recipe in the DeepSeek V4 output projection. Consumer Blackwell needs
the raw row-major scale layout carried by this overlay.
- **The DSpark extensions remain optional.** v0.25 supplies the core DSpark
engine; the overlay adds per-request confidence widths, profiled cost tables,
online calibration, hysteresis, and live dynamic-SD re-derivation.
- **Tier managers stop before interpreter teardown.** The v0.25 stable-libtorch
extension can abort if a daemon manager still owns Torch tensors during
Python shutdown. Each tier now has an explicit stop/join boundary and the
module registers a deduplicated `atexit` shutdown for serving workers.

## Verification completed before image build

The source port passed:

- `git diff --check` against the exact v0.25 tag;
- Python compilation across every changed Python file;
- 22 passed / 1 skipped focused W2 memory, padded-route, step-pin, and manager
shutdown tests;
- 6 passed CPU DSpark scheduling and live-re-derivation regressions;
- clean patch application and a committed 60-file lost-line manifest.

These are source gates only. They do **not** establish CUDA kernel, model-load,
quality, context, or throughput parity.

## Bounded SM120 image receipt (2026-07-12)

The digest-pinned recipe built on taro as
`vllm-moet-sm120:v025-w2candidate-25ac6fea`, local image ID
`sha256:1b3dc4a340a6`. On its RTX 5090 (SM120), the exact image passed:

- stable-libtorch native extension import with zero allocated GPU bytes;
- the baked 22 passed / 1 skipped W2 suite and 6 passed DSpark suite;
- bounded W2/W4 decode (`max_rel` 0.01358 / cosine 0.999911), full-FP4 delta
(`0.01611` / `0.999906`), and split-FP4 delta (`0.01333` / `0.999922`);
- split three-tier mixed dispatch, base-miss zeroing, coupled eviction, and
clean interpreter shutdown;
- byte-identical pinned, pack, reboot, tiered arena, eviction, overflow,
scan-resistance, and preheat store paths;
- baked NVFP4 packed-cache writes and FlashInfer sparse-MLA JIT-cache load.

The first v0.25 candidate exposed the manager teardown abort after its
three-tier assertions passed. The same test exited clean on frozen v0.24; the
explicit stop/join fix then exited clean on corrected v0.25 and is covered by
two CPU regressions. The superseded image tag was removed. Throughout these
bounded checks, taro's live llama-swap Qwen process stayed at 23,114 MiB and
was not restarted or rerouted.

This receipt still does **not** establish a DS4 checkpoint load, 128K context,
quality, or performance result on v0.25.

## Promotion gates

The v0.25 candidate must stay side-by-side with the live v0.24 image. Promotion
requires, in order:

1. build the pinned image on an SM120 host and run the baked import/compile
checks;
2. run CUDA op tests for W2/W4 cubins, raw-scale output projection, NVFP4 cache
write/read, and CUDA-graph capture;
3. cold-start a disposable DS4 canary without replacing the live router lane;
4. prove the 128K serve configuration, exact retrieval, frozen-rule quality,
memory/cgroup safety, and no pack corruption on the real endpoint;
5. compare decode, prefill, MTP acceptance, replay rate, and memory receipts to
the frozen v0.24 baseline;
6. only then move the router lane, retaining the v0.24 image and packs for an
immediate rollback.

No existing seed or benchmark receipt is relabeled as v0.25 evidence. The
upgrade reuses the test definitions, but the candidate must earn its own
runtime receipts because the execution engine and dependency base changed.
64 changes: 64 additions & 0 deletions patch/FILES-v025.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Files touched by patch/vllm-moet-v0.25.0.patch (sorted; generated by
# tools/check_patch_files.py --version 0.25.0 --update, verified by CI
# bench-lint). A file DISAPPEARING from this list means work was dropped by
# regeneration; restore it in the source branch instead of hiding the loss.
csrc/nvfp4_ds_mla/concat_and_cache_nvfp4_ds_mla.cu
tests/model_executor/layers/quantization/test_moe_w2_cgroup_memory.py
tests/model_executor/layers/quantization/test_moe_w2_padded_routes.py
tests/model_executor/layers/quantization/test_moe_w2_step_pins.py
tests/v1/spec_decode/test_dspark_scheduler.py
tools/nvfp4_flashinfer_sm120/README.md
tools/nvfp4_flashinfer_sm120/nvfp4_expand.cuh
tools/nvfp4_flashinfer_sm120/patch_flashinfer.py
vllm/compilation/breakable_cudagraph.py
vllm/compilation/cuda_graph.py
vllm/config/speculative.py
vllm/config/vllm.py
vllm/envs.py
vllm/forward_context.py
vllm/model_executor/layers/attention/mla_attention.py
vllm/model_executor/layers/quantization/fp8.py
vllm/model_executor/layers/quantization/modelopt.py
vllm/model_executor/layers/quantization/mxfp4.py
vllm/model_executor/layers/quantization/utils/fp8_utils.py
vllm/model_executor/layers/quantization/utils/moe_w2_cubit.py
vllm/model_executor/layers/quantization/utils/moe_w2_delta.py
vllm/model_executor/layers/quantization/utils/moe_w2_gate.py
vllm/model_executor/layers/quantization/utils/moe_w2_looka.py
vllm/model_executor/layers/quantization/utils/moe_w2_planes.py
vllm/model_executor/layers/quantization/utils/moe_w2_planes_cache.py
vllm/model_executor/layers/quantization/utils/moe_w2_store.py
vllm/model_executor/layers/quantization/utils/prefill_timers.py
vllm/model_executor/layers/quantization/utils/skinny_fp8_cubit.py
vllm/model_executor/model_loader/__init__.py
vllm/model_executor/model_loader/default_loader.py
vllm/model_executor/model_loader/weight_utils.py
vllm/model_executor/models/deepseek_mtp.py
vllm/model_executor/models/qwen3_dspark.py
vllm/models/deepseek_v4/nvidia/mtp.py
vllm/models/deepseek_v4/nvidia/ops/o_proj.py
vllm/v1/attention/backends/flashinfer.py
vllm/v1/attention/backends/mla/cubit_sparse_mla.py
vllm/v1/attention/backends/mla/flashinfer_mla_sparse.py
vllm/v1/attention/backends/mla/flashinfer_mla_sparse_sm120.py
vllm/v1/attention/backends/mla/nvfp4_ds_mla_cache.py
vllm/v1/attention/backends/mla/sparse_mla_env.py
vllm/v1/attention/backends/mla/sparse_swa.py
vllm/v1/attention/ops/merge_attn_states.py
vllm/v1/attention/ops/triton_decode_attention.py
vllm/v1/core/sched/scheduler.py
vllm/v1/engine/core.py
vllm/v1/kv_cache_interface.py
vllm/v1/spec_decode/dynamic/utils.py
vllm/v1/worker/gpu/cudagraph_utils.py
vllm/v1/worker/gpu/input_batch.py
vllm/v1/worker/gpu/model_runner.py
vllm/v1/worker/gpu/spec_decode/dflash/speculator.py
vllm/v1/worker/gpu/spec_decode/dspark/scheduler.py
vllm/v1/worker/gpu/spec_decode/dspark/speculator.py
vllm/v1/worker/gpu/spec_decode/dspark/utils.py
vllm/v1/worker/gpu/spec_decode/rejection_sampler.py
vllm/v1/worker/gpu/spec_decode/utils.py
vllm/v1/worker/gpu_model_runner.py
vllm/v1/worker/gpu_ubatch_wrapper.py
vllm/v1/worker/gpu_worker.py
Loading