Sign inSign up

orthozany/k26-v4-clean

By orthozany

•Updated 5 months ago

Reproducible K2.6 v4 canonical-rebase image (vLLM 0.20.2). 8x RTX PRO 6000.

Image
0

256

orthozany/k26-v4-clean repository overview

⁠orthozany/k26-v4-clean:v1

Reproducible build of K2.6 inference image
voipmonitor/vllm:glm-kimi-canonical-rebase-layered-vllm68b3569f-b12xc929144-flashinfergit1a60071-cutedsl45-20260514
from public sources only (voipmonitor/vllm @ 68b3569f canonical-rebase branch + pinned flashinfer + b12x).

vLLM 0.20.2 + flashinfer + b12x + cute-dsl 4.5 + cuda-tile 1.3 + patched libnccl (PR #2127), built on CUDA 13.0 / Ubuntu 24.04.

⁠Hardware assumption

  • 8x NVIDIA RTX PRO 6000 Blackwell 96 GB (sm_120a)
  • Driver 595.45.04 verified working
  • 1T-param K2.6 weights (~960 GB) on local NVMe

⁠Quickstart

⁠1. Download model
huggingface-cli download moonshotai/Kimi-K2.6 \
  --local-dir /path/to/Kimi-K2.6 --local-dir-use-symlinks=False
⁠2. Save the compose file below as compose.v4-mtp3-fp8draft.yml
⁠3. Run
export KIMI_K26_MODEL_PATH=/path/to/Kimi-K2.6
export CACHE_ROOT=$PWD/cache-v4 && mkdir -p $CACHE_ROOT
docker compose -f compose.v4-mtp3-fp8draft.yml up -d

# Wait ~5-8 min for model load + CUDA graph capture
until curl -fsS http://localhost:8402/v1/models >/dev/null; do sleep 10; done
echo "ready"
⁠4. Sanity check
curl -sS http://localhost:8402/v1/chat/completions -H 'Content-Type: application/json' -d '{
  "model": "Kimi-K2.6", "messages": [{"role": "user", "content": "hi"}], "max_tokens": 20
}'

⁠compose.v4-mtp3-fp8draft.yml

services:
  vllm-k26-v4:
    image: orthozany/k26-v4-clean:v1
    container_name: vllm-k26-v4
    init: true
    ipc: host
    network_mode: host
    privileged: true
    runtime: nvidia
    shm_size: "32g"
    environment:
      - NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES:-all}
      - CUDA_DEVICE_ORDER=PCI_BUS_ID
      - OMP_NUM_THREADS=16
      - CUTE_DSL_ARCH=sm_120a
      - CUDA_DEVICE_MAX_CONNECTIONS=32
      # NCCL via patched libnccl-pr2127 (baked into image)
      - NCCL_IB_DISABLE=1
      - NCCL_P2P_LEVEL=SYS
      - NCCL_PROTO=LL,LL128,Simple
      - USE_NCCL_XML=0
      - NCCL_GRAPH_FILE=
      - VLLM_NCCL_SO_PATH=/opt/libnccl-pr2127.so.2.30.3
      - LD_PRELOAD=/opt/libnccl-pr2127.so.2.30.3
      # PCIe AR (cpp backend with 56KB 1-stage NCCL cutoff)
      - VLLM_ENABLE_PCIE_ALLREDUCE=1
      - VLLM_PCIE_ALLREDUCE_BACKEND=cpp
      - VLLM_CPP_AR_1STAGE_NCCL_CUTOFF=56KB
      - VLLM_CPP_AR_IGNORE_CUTOFF_MAX_ROWS=8
      - VLLM_RTX6K_FUSED_ALLREDUCE_ADD=0
      - VLLM_RTX6K_FUSED_ALLREDUCE_ADD_END_BARRIER=0
      # Misc kernel flags
      - VLLM_USE_B12X_SPARSE_INDEXER=0
      - VLLM_DISABLE_SHARED_EXPERTS_STREAM=0
      - VLLM_MEMORY_PROFILER_ESTIMATE_CUDAGRAPHS=0
      - VLLM_LOG_STATS_INTERVAL=1
      - VLLM_DISABLED_KERNELS=MarlinFP8ScaledMMLinearKernel
      # Server (run-kimi26-vllm reads these envs)
      - PORT=8402
      - MODEL=/model
      - SERVED_MODEL_NAME=Kimi-K2.6
      - TP_SIZE=8
      - DCP_SIZE=8
      - GPU_MEMORY_UTILIZATION=0.90
      - MAX_MODEL_LEN=262144
      - MAX_NUM_BATCHED_TOKENS=8192
      - MAX_NUM_SEQS=128
      - MAX_CUDAGRAPH_CAPTURE_SIZE=512
      - KV_CACHE_DTYPE=fp8
      - ATTENTION_BACKEND=TRITON_MLA
      - KIMI_DISABLE_MTP=0
      - SPEC_CONFIG={"model":"festr2/kimi-k2.6-eagle3-mla-fp8","method":"eagle3","num_speculative_tokens":3,"draft_attention_backend":"TRITON_MLA","draft_kv_cache_dtype":"fp8"}
      # NOTE: this pushed image was built before flashinfer-cubin was pinned.
      # Bypass version check with the env var below. Drop it if you rebuild from Dockerfile (pinned).
      - FLASHINFER_DISABLE_VERSION_CHECK=1
      # JIT caches inside container
      - XDG_CACHE_HOME=/cache/jit
      - CUDA_CACHE_PATH=/cache/jit
      - VLLM_CACHE_DIR=/cache/jit/vllm
      - TVM_FFI_CACHE_DIR=/cache/jit/tvm-ffi
      - FLASHINFER_WORKSPACE_BASE=/cache/jit/flashinfer
      - HF_HOME=/root/.cache/huggingface
    command: ["--compilation-config", "{\"pass_config\":{\"fuse_rope_kvcache_cat_mla\":true},\"splitting_ops\":[]}"]
    volumes:
      - ${KIMI_K26_MODEL_PATH:?Set KIMI_K26_MODEL_PATH to absolute path of Kimi-K2.6 weights}:/model:ro
      - ${CACHE_ROOT:-./cache-v4}/jit:/cache/jit
      - ${CACHE_ROOT:-./cache-v4}/triton:/root/.cache/triton
      - ${CACHE_ROOT:-./cache-v4}/torchinductor:/root/.cache/torchinductor
      - ${CACHE_ROOT:-./cache-v4}/vllm:/root/.cache/vllm
      - ${CACHE_ROOT:-./cache-v4}/cutlass_dsl:/root/.cache/cutlass_dsl
      - ${CACHE_ROOT:-./cache-v4}/huggingface:/root/.cache/huggingface
    ulimits:
      memlock: -1
      stack: 67108864
    restart: "no"

⁠Switching MTP variants

The image reads KIMI_DISABLE_MTP and SPEC_CONFIG/KIMI_SPEC_CONFIG. To change spec-token count or draft model, edit the SPEC_CONFIG env. Example MTP=1 with the same fp8 draft:

- SPEC_CONFIG={"model":"festr2/kimi-k2.6-eagle3-mla-fp8","method":"eagle3","num_speculative_tokens":1,"draft_attention_backend":"TRITON_MLA","draft_kv_cache_dtype":"fp8"}

Default draft (lightseekorg bf16) is used if neither SPEC_CONFIG nor KIMI_SPEC_CONFIG is set and KIMI_DISABLE_MTP=0.

Valid rejection_sample_method on vLLM 0.20.2: "standard" (default = probabilistic-style) or "synthetic" (testing-only). The legacy "probabilistic" string was removed in 0.20 because it became the default — passing it triggers a pydantic validation error.

⁠Dockerfile (full build from public sources)

FROM nvidia/cuda:13.0.0-devel-ubuntu24.04

ARG CUTLASS_DSL_VERSION=4.5.0
ARG NCCL_VERSION=2.29.7
ARG TRITON_VERSION=3.6.0
ARG TORCH_VERSION=2.11.0+cu130
ARG TORCHVISION_VERSION=0.26.0+cu130
ARG CUDA_TILE_VERSION=1.3.0
ARG FLASHINFER_CUBIN_VERSION=0.6.11
ARG VLLM_FORK_COMMIT=68b3569f2bd2e8f6568f25f2144fb648b200d832
ARG FLASHINFER_COMMIT=1a60071db81239d4b0e5f28cd0563acceba2c878
ARG B12X_COMMIT=c929144c7689668b07ca65af10ceadf1c745165d

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \
        python3.12 python3.12-dev python3.12-venv python3-pip \
        git build-essential ninja-build cmake ca-certificates curl wget \
    && rm -rf /var/lib/apt/lists/* \
    && ln -sf /usr/bin/python3.12 /usr/bin/python3 \
    && ln -sf /usr/bin/python3.12 /usr/bin/python

RUN python3 -m venv /opt/venv
ENV PATH=/opt/venv/bin:$PATH

RUN pip install --no-cache-dir --upgrade pip "setuptools>=77.0.3,<81.0.0" setuptools-scm wheel ninja

RUN pip install --no-cache-dir \
        torch==${TORCH_VERSION} torchvision==${TORCHVISION_VERSION} \
        --index-url https://download.pytorch.org/whl/cu130

RUN pip install --no-cache-dir --no-deps \
        nvidia-cutlass-dsl==${CUTLASS_DSL_VERSION} \
        nvidia-cutlass-dsl-libs-base==${CUTLASS_DSL_VERSION} \
        nvidia-cutlass-dsl-libs-cu13==${CUTLASS_DSL_VERSION} \
        nvidia-nccl-cu13==${NCCL_VERSION} \
        triton==${TRITON_VERSION} \
        cuda-tile==${CUDA_TILE_VERSION} \
        apache-tvm-ffi==0.1.10

RUN git clone https://github.com/voipmonitor/vllm /opt/vllm \
    && cd /opt/vllm && git checkout ${VLLM_FORK_COMMIT}
WORKDIR /opt/vllm
RUN pip install --no-cache-dir -e . --no-build-isolation

RUN git clone https://github.com/flashinfer-ai/flashinfer.git /opt/flashinfer-src \
    && cd /opt/flashinfer-src && git checkout ${FLASHINFER_COMMIT} \
    && git submodule update --init --recursive
RUN cd /opt/flashinfer-src && pip install --no-cache-dir -e . --no-build-isolation
RUN pip install --no-cache-dir --force-reinstall flashinfer-cubin==${FLASHINFER_CUBIN_VERSION}

RUN git clone https://github.com/local-inference-lab/b12x.git /opt/b12x \
    && cd /opt/b12x && git checkout ${B12X_COMMIT}
RUN cd /opt/b12x && pip install --no-cache-dir -e . --no-build-isolation

# image-side helper script + patched libnccl (PR #2127) — extracted from upstream image
# Get them via:
#   docker create --name x voipmonitor/vllm:glm-kimi-canonical-rebase-layered-vllm68b3569f-b12xc929144-flashinfergit1a60071-cutedsl45-20260514
#   docker cp x:/opt/vllm/scripts/run-kimi26-vllm .
#   docker cp x:/opt/libnccl-pr2127.so.2.30.3 .
#   docker rm x
COPY run-kimi26-vllm /opt/vllm/scripts/run-kimi26-vllm
RUN chmod +x /opt/vllm/scripts/run-kimi26-vllm
COPY libnccl-pr2127.so.2.30.3 /opt/libnccl-pr2127.so.2.30.3

ENV CUDA_DEVICE_ORDER=PCI_BUS_ID \
    VLLM_NCCL_SO_PATH=/opt/libnccl-pr2127.so.2.30.3

WORKDIR /opt/vllm
ENTRYPOINT ["/bin/bash", "-lc", "rm -f /usr/local/cuda-13.0/targets/x86_64-linux/lib/libcudart.so.12 2>/dev/null; exec /opt/vllm/scripts/run-kimi26-vllm \"$@\"", "--"]

⁠Performance

All measured on 8x RTX PRO 6000 Blackwell, DCP=8, fp8 KV, TRITON_MLA, --skip-prefill --duration 30 --kv-budget 2464640, server-side generation throughput.

⁠Reproduction sanity check: this image vs upstream voipmonitor canonical

For the one config we explicitly re-benched on orthozany/k26-v4-clean:v1 to verify the build:

cornerorthozany/k26-v4-clean:v1upstream voipmonitor canonical
c=1 ctx=0, MTP=3 fp8draft77.478.4
c=1 ctx=128k, MTP=3 fp8draft59.053.9
c=128 ctx=0, MTP=3 fp8draft1180.81163.6

26 of 29 cells within ±5%; the rebuild is +7-9% faster at c=1 long-ctx (likely the flashinfer-cubin version pin difference). The rebuild reproduces the upstream image within bench noise on most cells and slightly outperforms it on long-context single-stream.

⁠8-run variance on this image, MTP=3 fp8draft

c=1, contexts 0 and 128k, 8 sequential runs each on orthozany/k26-v4-clean:v1:

cornernmeanminmaxstdevCV
c=1 ctx=0875.2672.4778.932.593.4%
c=1 ctx=128k857.1952.2464.353.906.8%

For reference, 8-run variance of orthozany/k26-0424-clean:v12 (companion image, MTP=3 fp8draft with probabilistic rejection): 95.59 / 64.39 mean. v4-clean trails by -21.3% (ctx=0) / -11.2% (ctx=128k).

⁠Env-var tuning sweep (4 runs per variant)

Tested 6 v4 env-var combinations to see if any could close the gap to 0424.

variantctx=0 meanctx=128k meanvs v4 defaultvs 0424
noAR (VLLM_ENABLE_PCIE_ALLREDUCE=0)78.7959.57+4.7% / +4.2%-17.6% / -7.5%
AR-pre0510 (drop VLLM_CPP_AR_1STAGE_NCCL_CUTOFF + IGNORE_CUTOFF_MAX_ROWS)75.0559.19-0.3% / +3.5%-21.5% / -8.1%
AR-fusedADD (VLLM_RTX6K_FUSED_ALLREDUCE_ADD=1)75.5659.34+0.4% / +3.8%-21.0% / -7.8%
AR-b12xSparse (VLLM_USE_B12X_SPARSE_INDEXER=1)75.3156.50+0.1% / -1.2%-21.2% / -12.3%
AR-sharedExpDis (VLLM_DISABLE_SHARED_EXPERTS_STREAM=1)73.1955.72-2.8% / -2.6%-23.4% / -13.5%
AR-memprofCG (VLLM_MEMORY_PROFILER_ESTIMATE_CUDAGRAPHS=1)75.2656.95+0.0% / -0.4%-21.3% / -11.6%
v4 default (compose above)75.2657.19—-21.3% / -11.2%
0424-clean v12 reference95.5964.39+27.0% / +12.6%—

Findings:

  • VLLM_ENABLE_PCIE_ALLREDUCE=0 (noAR) is the only knob that meaningfully helps v4 at c=1 (+4-5%). Recommended for c=1 workloads.
  • VLLM_DISABLE_SHARED_EXPERTS_STREAM=1 slows v4 down — don't set it.
  • All other knobs (cpp_ar cutoff settings, fused-add, b12x sparse indexer, memory profiler cudagraphs) produce results within ±1% of v4 default — noise.
  • Even with noAR, v4 is still 17.6% behind 0424 at ctx=0. The v4 c=1 regression is intrinsic to vLLM 0.20.2 spec-decode, not env-var tunable.
⁠Reproduction sanity check (full matrix, MTP=3 fp8draft, this image vs upstream voipmonitor canonical)
cornerorthozany/k26-v4-clean:v1upstream voipmonitor canonical
c=1 ctx=077.478.4
c=1 ctx=128k59.053.9
c=128 ctx=01180.81163.6

26 of 29 cells within ±5%; the rebuild is +7-9% faster at c=1 long-ctx (likely the flashinfer-cubin version pin difference). The rebuild reproduces the upstream image within bench noise on most cells.

⁠Full single-shot matrix, MTP=3/2/1/noMTP (upstream canonical numbers, within ±5% of this image per validation above)
variantc=1 ctx=0c=1 ctx=128kc=128 ctx=0
MTP=3 fp8draft78.453.91163.6
MTP=2 fp8draft79.061.01369.9
MTP=1 fp8draft79.962.31516.2
noMTP78.560.91372.7
MTP=3 lightseekorg bf16 default83.459.41174.5
0424 baseline MTP=3 (probabilistic, festr2 fp8)96.166.71191.6

Bench tool: llm_decode_bench.py from the standard K2.6 wiki recipe.

See the companion image orthozany/k26-0424-clean:v12 for the 0424 baseline and the full v4-vs-0424 head-to-head comparison.

Tag summary

Content type

Image

Digest

sha256:49ad7d35d…

Size

10.8 GB

Last updated

5 months ago

docker pull orthozany/k26-v4-clean:v1