Skip to content
Draft
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
7 changes: 7 additions & 0 deletions deployments/glm52-sparse-ckv/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
IMAGE_NAME=fujitsupolycom/glm52-sparse-ckv:v19-20260721
MODEL_PATH=/srv/ai/models/GLM-5.2-MXFP8-NVFP4-NF3-Hybrid
HF_CACHE_PATH=/srv/ai/huggingface
CACHE_PATH=/srv/ai/cache/glm52-sparse-ckv-v19
TMP_PATH=/srv/ai/tmp/glm52-sparse-ckv-v19
PORT=5802
CUDA_VISIBLE_DEVICES=0,1,2,3
106 changes: 106 additions & 0 deletions deployments/glm52-sparse-ckv/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
ARG BASE_IMAGE=voipmonitor/vllm@sha256:41078d5fac36b802e0f3798057a4b383c24296cb8570f6f4fc138c34d8cfa303

FROM ${BASE_IMAGE} AS sources

ARG VLLM_REPOSITORY=https://github.com/FujitsuPolycom/vllm.git
ARG VLLM_BASE_REF=7ea567a2458a4800a6a0e3e0a6ba41fcbd00d146
ARG VLLM_REF=a81a0811314e23bc6b2baa69f34247aacea71e23
ARG SPARKINFER_REPOSITORY=https://github.com/FujitsuPolycom/sparkinfer.git
ARG SPARKINFER_REF=a82fc76f9a2321e3cfd3065a9fa78452a27ddf9f

USER root

RUN set -eux; \
git clone --filter=blob:none "${VLLM_REPOSITORY}" /src/vllm; \
git -C /src/vllm checkout --detach "${VLLM_REF}"; \
test "$(git -C /src/vllm rev-parse HEAD)" = "${VLLM_REF}"; \
git -C /src/vllm cat-file -e "${VLLM_BASE_REF}^{commit}"; \
mkdir -p /src/vllm-overlay; \
git -C /src/vllm diff --name-only --diff-filter=ACMRTUXB \
"${VLLM_BASE_REF}..${VLLM_REF}" -- vllm \
| while IFS= read -r path; do \
mkdir -p "/src/vllm-overlay/$(dirname "${path}")"; \
cp "/src/vllm/${path}" "/src/vllm-overlay/${path}"; \
done; \
test "$(find /src/vllm-overlay/vllm -type f | wc -l)" = "39"; \
git clone --filter=blob:none "${SPARKINFER_REPOSITORY}" /src/sparkinfer; \
git -C /src/sparkinfer checkout --detach "${SPARKINFER_REF}"; \
test "$(git -C /src/sparkinfer rev-parse HEAD)" = "${SPARKINFER_REF}"; \
python -m pip wheel --no-cache-dir --no-deps \
--wheel-dir /dist /src/sparkinfer

FROM ${BASE_IMAGE}

ARG VLLM_REF=a81a0811314e23bc6b2baa69f34247aacea71e23
ARG SPARKINFER_REF=a82fc76f9a2321e3cfd3065a9fa78452a27ddf9f
ARG RUN_CPU_TESTS=1

USER root

COPY --from=sources /dist/ /opt/release/dist/
COPY --from=sources /src/vllm-overlay/vllm/ /opt/release/vllm/
COPY --from=sources /src/vllm/tests/ /opt/release-tests/vllm-tests/
COPY --from=sources /src/sparkinfer/tests/ /opt/release-tests/sparkinfer-tests/

RUN set -eux; \
python -m pip install --no-cache-dir --upgrade \
nvidia-cutlass-dsl==4.6.0 \
nvidia-cutlass-dsl-libs-base==4.6.0 \
nvidia-cutlass-dsl-libs-core==4.6.0 \
nvidia-cutlass-dsl-libs-cu12==4.6.0 \
nvidia-cutlass-dsl-libs-cu13==4.6.0 \
quack-kernels==0.6.1 \
pytest==8.4.2; \
python -m pip install --no-cache-dir --no-deps --force-reinstall \
/opt/release/dist/sparkinfer-*.whl; \
for root in \
/opt/venv/lib/python3.12/site-packages/vllm \
/opt/vllm/vllm; do \
test -d "${root}"; \
cp -a /opt/release/vllm/. "${root}/"; \
done; \
python -c 'from sparkinfer.comm.pcie import SelectedRecordCopyExchange, SelectedRecordExchange, SelectedRecordExchangeInitializationError; assert SelectedRecordCopyExchange and SelectedRecordExchange and SelectedRecordExchangeInitializationError'; \
test -x /usr/local/bin/serve-gilded-gnosis.sh; \
test -x /usr/local/bin/serve-glm52-hybrid-v19.sh; \
python -m compileall -q \
/opt/venv/lib/python3.12/site-packages/sparkinfer \
/opt/venv/lib/python3.12/site-packages/vllm; \
mkdir -p /opt/sparkinfer/comm/pcie; \
cp /opt/venv/lib/python3.12/site-packages/sparkinfer/comm/pcie/*.cu \
/opt/sparkinfer/comm/pcie/; \
cp /opt/venv/lib/python3.12/site-packages/sparkinfer/comm/pcie/pcie_selected_records*.py \
/opt/sparkinfer/comm/pcie/; \
mkdir -p /opt/release-tests/sparkinfer/comm/pcie; \
cp /opt/venv/lib/python3.12/site-packages/sparkinfer/comm/pcie/pcie_selected_records*.cu \
/opt/venv/lib/python3.12/site-packages/sparkinfer/comm/pcie/pcie_selected_records*.py \
/opt/release-tests/sparkinfer/comm/pcie/; \
if [ "${RUN_CPU_TESTS}" = "1" ]; then \
python -m pytest -q -p no:cacheprovider \
/opt/release-tests/sparkinfer-tests/comm/test_pcie_selected_records.py \
/opt/release-tests/sparkinfer-tests/comm/test_pcie_selected_records_ce.py \
/opt/release-tests/sparkinfer-tests/comm/test_pcie_selected_records_gpu.py \
/opt/release-tests/sparkinfer-tests/comm/test_pcie_selected_records_ce_gpu.py \
/opt/release-tests/sparkinfer-tests/comm/test_pcie_dcp_a2a.py; \
python -m pytest -q -p no:cacheprovider \
/opt/release-tests/vllm-tests/v1/attention/test_b12x_sparse_ckv_decode_policy.py \
/opt/release-tests/vllm-tests/v1/attention/test_b12x_ckv_prefetch_policy.py \
/opt/release-tests/vllm-tests/v1/attention/test_indexer_dcp_localize.py \
/opt/release-tests/vllm-tests/v1/worker/test_workspace.py; \
python -m pytest -q -p no:cacheprovider \
/opt/release-tests/vllm-tests/v1/core/test_kv_cache_utils.py \
-k 'lockstep_mla or mixed_dcp_replicated_groups'; \
fi; \
rm -rf /opt/release /opt/release-tests /opt/sparkinfer

COPY --chmod=0755 serve.sh /usr/local/bin/serve-glm52-sparse-ckv.sh

LABEL org.opencontainers.image.source="https://github.com/FujitsuPolycom/vllm" \
org.opencontainers.image.revision="${VLLM_REF}" \
ai01.hardware="ASUS WRX90E-SAGE SE; Threadripper PRO 9965WX; 128 GiB RAM; 4x RTX PRO 6000 Blackwell 96GB at 400W" \
ai01.base="voipmonitor/vllm@sha256:41078d5fac36b802e0f3798057a4b383c24296cb8570f6f4fc138c34d8cfa303" \
ai01.vllm="FujitsuPolycom/vllm@${VLLM_REF}" \
ai01.sparkinfer="FujitsuPolycom/sparkinfer@${SPARKINFER_REF}" \
ai01.features="replicated indexer; depth-3 CKV prefetch; selected-record sparse decode; bulk copy-engine transport" \
local-inference.cutlass_dsl.version="4.6.0" \
local-inference.vllm.commit="${VLLM_REF}" \
local-inference.vllm.repo="https://github.com/FujitsuPolycom/vllm.git"
155 changes: 155 additions & 0 deletions deployments/glm52-sparse-ckv/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# GLM-5.2 Sparse CKV Integration Release

This folder reproduces the validated GLM-5.2 sparse-CKV stack from immutable
commits on the FujitsuPolycom forks. It is intended as an experimental release
and review target, not as a general vLLM distribution.

## Validated Host

- ASUS WRX90E-SAGE SE
- AMD Ryzen Threadripper PRO 9965WX
- 128 GiB system RAM
- 4x RTX PRO 6000 Blackwell 96GB, 400 W each
- TP4, DCP4, MTP3
- Full CUDA peer access; ACS and IOMMU disabled on the validated host

The four GPUs are attached through separate CPU root ports rather than a Gen5
P2P switch. Transport results are therefore specific to this host topology.

The selected-record transports require CUDA IPC peer access between every GPU.
Check topology before launch:

```bash
nvidia-smi topo -m
nvidia-smi topo -p2p r
./preflight.sh
```

## Pinned Sources

| Component | Pin |
| --- | --- |
| Base image | `voipmonitor/vllm@sha256:41078d5fac36b802e0f3798057a4b383c24296cb8570f6f4fc138c34d8cfa303` |
| vLLM | `FujitsuPolycom/vllm@a81a0811314e23bc6b2baa69f34247aacea71e23` |
| Sparkinfer | `FujitsuPolycom/sparkinfer@a82fc76f9a2321e3cfd3065a9fa78452a27ddf9f` |
| Model | `madeby561/GLM-5.2-MXFP8-NVFP4-NF3-Hybrid@68babde27a97a4c980c2494e830dd424975cd5a3` |

The Docker build verifies both Git SHAs before installing anything. It also
runs the focused CPU policy and transport tests used for the validated image.
The runtime toolchain is pinned to CUTLASS DSL 4.6.0 and QuACK 0.6.1, matching
the validated image rather than the older packages in the v19 base.
The base vLLM package metadata still declares CUTLASS DSL 4.5.3, so `pip check`
reports the intentional 4.6.0 override; startup and focused tests use 4.6.0.

This is an overlay build, not a source-only CUDA stack build. It intentionally
inherits the pinned `voipmonitor/vllm` image for CUDA, NCCL, FlashInfer,
and InstantTensor, and requires separate access to the pinned Hugging Face
checkpoint. The release installs its own small launcher so the fixed KV budget
and NCCL all-reduce mode cannot be silently dropped by a base-image launcher.

## Included Features

- Lockstep allocation for mixed MLA KV-cache groups
- Replicated sparse-indexer KV with DCP-sharded main CKV
- Native 432-byte CKV history gather and depth-3 Shared-layer prefetch
- Per-sequence MTP union and deduplication
- Selected-record sparse CKV decode for C1-C8
- Direct CUDA-IPC P2P and copy-engine transports
- One-shot bulk transfer for the three Shared layers

The default Compose selects the copy-engine transport because it won the TP4
A/B on the validated host. The direct transport remains available by changing
`VLLM_B12X_MLA_SPARSE_DECODE_TRANSPORT` from `ce` to `direct`.

## Build And Launch

```bash
git clone --branch codex/glm52-sparse-ckv-release-20260721 \
https://github.com/FujitsuPolycom/vllm.git
cd vllm/deployments/glm52-sparse-ckv

# Skip this download when the pinned model revision is already local.
hf download madeby561/GLM-5.2-MXFP8-NVFP4-NF3-Hybrid \
--revision 68babde27a97a4c980c2494e830dd424975cd5a3 \
--local-dir /srv/ai/models/GLM-5.2-MXFP8-NVFP4-NF3-Hybrid

cp .env.example .env
# Edit MODEL_PATH and the cache paths in .env.
./preflight.sh
docker compose config --quiet
docker compose build --pull
docker compose up -d
docker compose logs -f glm52-sparse-ckv
```

Keep the Compose entrypoint set to `serve-glm52-sparse-ckv.sh`. The inherited
v19 launcher does not accept this release's fixed `KV_CACHE_MEMORY_BYTES` or
`ALLREDUCE_MODE` controls; using it changes memory allocation and can OOM.

The first startup performs model loading, JIT compilation, warmup, and CUDA
graph capture. Do not benchmark the first request. The API is ready when this
returns the served model:

```bash
curl -fsS http://127.0.0.1:5802/v1/models
python validate-api.py
```

Confirm that the intended format and features activated:

```bash
docker compose logs glm52-sparse-ckv 2>&1 | \
grep -E 'kv_gmem_stride=432|replicat|prefetch|sparse.*CKV|transport=ce'
```

The validated profile uses a fixed 3,426,112,942-byte KV allocation per GPU,
`max-model-len=300000`, batch 2048, graph 32, and eight active sequences. The
reported logical KV pool was 302,047 tokens.

The image assembled only from the public pins in this folder also completed a
four-GPU startup, CUDA-graph capture, and the two-run deterministic API probe at
that exact 302,047-token capacity.

## Feature Controls

| Variable | Default | Purpose |
| --- | ---: | --- |
| `VLLM_DCP_REPLICATE_INDEXER_CACHE` | `1` | Replicate the small indexer cache while keeping main CKV DCP-sharded |
| `VLLM_B12X_MLA_CKV_GATHER` / `DCP_CKV_GATHER` | `1` | Gather full CKV for the prefill path |
| `VLLM_B12X_MLA_CKV_PREFETCH_DEPTH` | `3` | Prefetch all three Shared layers after each Full layer |
| `VLLM_B12X_MLA_SPARSE_DECODE_CKV_GATHER` | `1` | Enable selected-record sparse decode |
| `VLLM_B12X_MLA_SPARSE_DECODE_TRANSPORT` | `ce` | Select copy-engine or direct P2P transport |
| `VLLM_B12X_MLA_SPARSE_DECODE_BULK_PREFETCH` | `1` | Transfer S1/S2/S3 together with one synchronization |
| `VLLM_B12X_MLA_SPARSE_DECODE_MAX_SEQS` | `8` | Enable the pooled fast path through C8 |

## Current Boundaries

- Sparse selected-record decode is validated only with
`KV_CACHE_DTYPE=nvfp4_ds_mla`, `KV_FP8_ROPE=0`, and the native 432-byte
NVFP4 + BF16-RoPE record.
- TP4/DCP4/MTP3 is the production-tested topology. DCP1 and DCP4 were A/B
tested; TP6/TP8 and DCP6/DCP8 still need physical validation.
- Both explicit `ce` and `direct` transports fail closed when peer
initialization is unavailable. `auto` may fall back from CE to direct, but
this release defaults to strict `ce` and requires full peer access.
- LMCache is not part of this release.
- FP8-RoPE support, calibrated MLA outer scales, and the newer absorbed-QBMM
memory optimization are intentionally excluded until separately validated.

See [RESULTS.md](RESULTS.md) for the configuration and performance matrix.
Machine-readable source and runtime pins are in
[VERSION_LOCK.json](VERSION_LOCK.json).

## Security

The validated Compose uses host networking and `privileged: true` to preserve
the known-working GPU/P2P environment. Run it only on a trusted, isolated host.
Do not expose the unauthenticated vLLM port directly to an untrusted network.

## Credits

The scheduling design builds on Koush's sparse-CKV, shared-layer lookahead, and
MTP-deduplication work. The transport and kernel integration builds on Luke
Alonso's Sparkinfer/B12X infrastructure. Implementation, testing, benchmarking,
and documentation were developed with OpenAI Codex assistance and manually
reviewed on the validated host.
115 changes: 115 additions & 0 deletions deployments/glm52-sparse-ckv/RESULTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Validation Results

## Daily Profile

Validated on ai01 with TP4/DCP4/MTP3, copy-engine sparse decode, replicated
indexer, depth-3 prefetch, 300,000 maximum model length, batch 2048, graph 32,
and the 432-byte NVFP4 + BF16-RoPE cache format.

| Metric | Result |
| --- | ---: |
| Coding peak, five-run median | 105.2 tok/s |
| Coding peak, five-run mean | 104.5 tok/s |
| Coding peak range | 101.6-108.0 tok/s |
| Reported KV capacity | 302,047 tokens |

Cold prefill on the same final image:

| Context | Prefill |
| ---: | ---: |
| 8K | 3,326 tok/s |
| 32K | 3,139 tok/s |
| 64K | 2,966 tok/s |
| 128K | 2,719 tok/s |
| 256K | 2,356 tok/s |

Deterministic temperature-zero outputs matched byte-for-byte across two runs
at 8,095, 64,032, and 127,998 prompt tokens.

## Public Image Gate

On 2026-07-21, the Dockerfile was rebuilt on ai01 using only the public source
pins in this folder. Build-time focused tests reported:

- Sparkinfer transport/policy: 56 passed, 4 GPU-only skipped
- vLLM attention/workspace policy: 120 passed, 18 skipped
- Mixed-DCP KV allocation: 3 passed, 75 deselected

The resulting image then completed a four-GPU TP4/DCP4/MTP3 startup with the
exact daily profile. Runtime logs confirmed:

- `--disable-custom-all-reduce` and the 3,426,112,942-byte KV pin
- 302,047 logical KV tokens
- replicated sparse-indexer KV
- selected-record CKV decode through C8 with MTP3 and depth 3
- one bulk CKV exchange for S1/S2/S3
- successful CUDA graph capture

`validate-api.py` returned `sparse-ckv-ready` identically twice. Historical
performance numbers below were produced by the same pinned source stack before
the public packaging layer was added; the release-image gate verifies startup
and correctness, not a fresh performance rerun.

## Matched 90K Coding Matrix

These arms used the same fixed 3,426,112,942-byte KV allocation, model, graph
size, batch size, temperature zero, reasoning disabled, one warmup, and five
measured coding runs. The shorter model limit lets DCP1 and DCP4 use an
identical request profile.

| Topology | MTP | Sparse decode | Coding median | KV tokens |
| --- | ---: | --- | ---: | ---: |
| DCP1 | 0 | Off/no-op | 56.7 tok/s | 93,888 |
| DCP1 | 3 | Off/no-op | 135.7 tok/s | 92,480 |
| DCP4 | 0 | Off | 44.4 tok/s | 305,920 |
| DCP4 | 0 | CE | 45.4 tok/s | 305,920 |
| DCP4 | 3 | Off | 82.9 tok/s | 302,080 |
| DCP4 | 3 | CE | 99.2 tok/s | 302,080 |

Sparse selected-record decode adds about 2.4% at MTP0 and 19.6% at MTP3 in
this matched coding test. The daily 300K profile is configuration-sensitive and
is reported separately rather than mixed into the DCP gap calculation.

In the matched bulk-prefetch A/B, enabling the one-shot three-layer exchange
improved the 64K+ geometric mean by 8.5%, moved the coding median from 99.63 to
103.79 tok/s, and left the 302,047-token KV capacity unchanged.

## Interpretation

- MTP3 is the intended deployment regime and receives the largest sparse-gather
benefit because candidate rows share one per-sequence union.
- DCP4 provides roughly 3.3x the logical KV capacity of DCP1 with this fixed
per-GPU allocation.
- Sparse decode recovers a meaningful portion of the DCP4 decode penalty, but
the strict DCP4 coding result does not fully match DCP1.
- Results are for one 4-GPU PCIe host. Treat TP8/DCP8 projections as hypotheses
until measured on that topology.

## Benchmark Reproduction

The development runs used `llm-inference-bench` v0.4.29. The exact benchmark
script used on ai01 has SHA-256
`0591b2cfe7767b8a048cfd57011526ca5fc64ea29415362c9ab1204c6c5d55e9`.
Representative commands for the measured request shapes are:

```bash
BENCH=/opt/llm-inference-bench
PY="$BENCH/.venv/bin/python"

# Sustained decode matrix plus five sequential coding-peak requests.
$PY "$BENCH/llm_decode_bench.py" --host 127.0.0.1 --port 5802 \
--skip-prefill --contexts 8k,32k,64k --concurrency 1,2,4,8 \
--duration 8 --max-tokens 512 --temperature 0 \
--coding-peak --coding-peak-runs 5 --coding-peak-temperature 0 \
--display-mode screen --output benchmark-results.json

# One-sample cold-prefill ladder used to check long-context scaling.
$PY "$BENCH/llm_decode_bench.py" --host 127.0.0.1 --port 5802 \
--prefill-only --prefill-contexts 8k,32k,64k,128k,256k \
--temperature 0 --display-mode screen --output prefill-results.json
```

Coding peak uses the harness's built-in `/mnt/test.py`-compatible coding
prompt and 2,000-token output budget. Results above are historical validation
of the pinned source stack; the Docker build and public-image gate run
correctness tests, not performance benchmarks.
Loading
Loading