DeepSeek-V4-Flash on RTX PRO 6000 Blackwell (sm_120), vLLM jasl PR #41834.
3.9K
DeepSeek-V4-Flash inference on SM12x (RTX PRO 6000 Blackwell, sm_120) via a snapshot of jasl's vLLM fork.
This image bundles a torch 2.11+cu130 venv with a from-source build of jasl/vllm against the PR that adds sparse-MLA + MTP self-speculation support for Blackwell workstation GPUs. Built on the nvidia/cuda:13.0.0-devel-ubuntu24.04 base.
pr41834-2026-05-13 — latest. Built from jasl/vllm branch codex/ds4-sm120-min-enable @ 8f0d8b630 (vLLM PR #41834, 2026-05-12 head). Includes:
nvidia-cutlass-dsl 4.5.0cute.nvgpu.LoadCacheMode → cpasync.LoadCacheMode in deepseek_v4_ops/dequant_gather_k_cutedsl.py:106 (the PR head referenced a path that exists only inside the cpasync submodule)--speculative-config '{"method":"mtp","num_speculative_tokens":2}')tmp-2026-05-05-snap — earlier snapshot at jasl/vllm@843fe9eb6 (pre-PR-rebase). No MTP=2 support; kept as rollback.deepseek-ai/DeepSeek-V4-Flash weightsMeasured with voipmonitor/llm-inference-bench v0.4.13 (--duration 30 --max-tokens 512, unique-prompt mode → no prefix-cache benefit).
| ctx \ conc | 1 | 2 | 4 |
|---|---|---|---|
| 0 (chat) | 74.0 | 109.3 | 98.7 |
| 16K | 73.0 | 107.6 | 24.5 ★ |
| 32K | 68.6 | 101.9 | 23.8 ★ |
| 64K | 58.8 | 87.1 | 23.3 ★ |
| 128K | 49.6 | 80.7 | 23.9 ★ |
★ Scheduling falls over at concurrency ≥ 3 with long context + MTP=2 on --max-num-seqs=4. Raise that knob if you need c=4 long-context.
| ctx \ conc | 1 | 2 | 4 |
|---|---|---|---|
| 0 | 74.0 | 54.6 | 24.7 |
| 16K | 73.0 | 53.8 | 6.1 |
| 32K | 68.6 | 50.9 | 6.0 |
| 64K | 58.8 | 43.5 | 5.8 |
| 128K | 49.6 | 40.3 | 6.0 |
| ctx | tokens | TTFT s | tok/s |
|---|---|---|---|
| 8K | 8,191 | 5.8 | 1,410 |
| 16K | 16,249 | 12.1 | 1,341 |
| 32K | 32,341 | 26.7 | 1,213 |
| 64K | 64,558 | 62.8 | 1,028 |
| 128K | 128,991 | 162.2 | 795 |
Acceptance rate during the matrix: 64.5% (pos0 81%, pos1 48%) — MTP is doing real work.
PR #41834's own claim is 148.86 tok/s mt-bench mixed-context average on the Workstation variant. PR comments flag a ~20% regression on Max-Q, which is what this image was benched on. With prefix-cache hits (e.g. typical chat workloads with shared system prompts) the c=1 30K cell rises to 130–145 tok/s.
# ~150 GB. HF_HUB_ENABLE_HF_TRANSFER=1 uses the fast Rust downloader.
mkdir -p /path/to/models/deepseek-ai
HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download \
deepseek-ai/DeepSeek-V4-Flash \
--local-dir /path/to/models/deepseek-ai/DeepSeek-V4-Flash
Save this in a folder, set MODEL_DIR and the two GPU indices, then docker compose up -d.
services:
vllm-dsv4-flash:
image: orthozany/vllm-jasl-dsv4:pr41834-2026-05-13
container_name: vllm-dsv4-flash
init: true
runtime: nvidia
privileged: true
ipc: host
shm_size: "32g"
restart: unless-stopped
# The image's ENTRYPOINT is the venv's `vllm` binary, but the venv needs
# to be `source activate`d so its env (PYTHONPATH for editable install,
# LD_LIBRARY_PATH for cuda libs in /home/user/jasl-dsv4/.venv) is set.
entrypoint:
- "/bin/bash"
- "-c"
- |
set -euo pipefail
source /home/user/jasl-dsv4/.venv/bin/activate
exec vllm serve "$$@"
- "--"
environment:
# ----- GPU pinning -----------------------------------------------------
# IMPORTANT: NVIDIA_VISIBLE_DEVICES alone does not always restrict on
# every docker / nvidia-container-runtime combination. Also set
# CUDA_VISIBLE_DEVICES to the in-container indices you want CUDA to use.
# Do NOT additionally set deploy.resources.reservations.devices — it
# can conflict and accidentally select a non-Blackwell GPU as cuda:0.
- NVIDIA_VISIBLE_DEVICES=0,1
- CUDA_VISIBLE_DEVICES=0,1
- CUDA_DEVICE_ORDER=PCI_BUS_ID
# ----- SM 12.0 workarounds (required) ----------------------------------
# FlashInfer JIT mis-parses TORCH_CUDA_ARCH_LIST=12.0a; fall back to
# the PyTorch sampler.
- VLLM_USE_FLASHINFER_SAMPLER=0
# Sparse-MLA warmup adds many seconds to startup with no benefit.
- VLLM_ENABLE_DEEPSEEK_V4_SPARSE_MLA_WARMUP=0
# Wide timeout: the v1 engine compiles many TileLang sparse-MLA kernels
# on first start; 3600 s comfortably covers cold start.
- VLLM_ENGINE_READY_TIMEOUT_S=3600
# ----- NCCL: PCIe-only Blackwell, no NVLink ----------------------------
# LL + Ring + 8 channels + 512 threads is the small-message tuning that
# keeps TTFT low on Blackwell workstation cards. Safe because we
# disable custom-allreduce (see --disable-custom-all-reduce in command:).
- NCCL_DEBUG=WARN
- NCCL_P2P_DISABLE=1
- NCCL_SHM_DISABLE=0
- NCCL_IB_DISABLE=1
- NCCL_PROTO=LL
- NCCL_ALGO=Ring
- NCCL_MIN_NCHANNELS=8
- NCCL_NTHREADS=512
# ----- Standard --------------------------------------------------------
- PYTHONUNBUFFERED=1
- VLLM_WORKER_MULTIPROC_METHOD=spawn
volumes:
# Read-only mount for the downloaded weights.
- /path/to/models/deepseek-ai/DeepSeek-V4-Flash:/model:ro
# Persistent caches so torch.compile, TileLang, triton don't re-JIT on
# every container restart. Local subdirectories OK.
- ./cache/huggingface:/root/.cache/huggingface
- ./cache/vllm:/root/.cache/vllm
- ./cache/torch:/root/.cache/torch
- ./cache/triton:/root/.cache/triton
- ./cache/torchinductor:/root/.cache/torchinductor
- ./cache/flashinfer:/root/.cache/flashinfer
ports:
- "8000:8000"
command:
# Positional: the model directory inside the container.
- "/model"
# ----- Names the API responds to ---------------------------------------
- "--served-model-name"
- "deepseek-v4-flash"
- "deepseek-v4-flash-mtp"
- "deepseek-ai/DeepSeek-V4-Flash"
# ----- Parallelism + quant ---------------------------------------------
- "--tensor-parallel-size=2"
- "--kv-cache-dtype=fp8"
- "--block-size=256"
# ----- Context window --------------------------------------------------
# 131072 (128K) is a safe default with --gpu-memory-utilization=0.93.
# For the model's native max (524288) bump to 0.95.
- "--max-model-len=131072"
- "--max-num-seqs=4"
- "--max-num-batched-tokens=8192"
- "--gpu-memory-utilization=0.93"
# ----- DeepSeek-V4 tokenizer + parsers (required) ----------------------
- "--tokenizer-mode=deepseek_v4"
- "--tool-call-parser=deepseek_v4"
- "--enable-auto-tool-choice"
- "--reasoning-parser=deepseek_v4"
- "--trust-remote-code"
# ----- Custom all-reduce off (no NVLink on workstation Blackwell) ------
- "--disable-custom-all-reduce"
# ----- MTP self-speculation: ~+40% decode throughput -------------------
# Set num_speculative_tokens=1 instead if you see acceptance below 25%.
- "--speculative-config={\"method\":\"mtp\",\"num_speculative_tokens\":2}"
- "--host=0.0.0.0"
- "--port=8000"
ulimits:
memlock: -1
stack: 67108864
docker compose up -d
# Cold start takes 2–4 minutes (weight load + warmup + TileLang JIT).
# Wait for "Application startup complete" in the logs.
docker compose logs -f vllm-dsv4-flash | grep -E "Application startup|ERROR"
# Smoke test
curl -sS -X POST http://localhost:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"deepseek-v4-flash","stream":false,"max_tokens":64,
"temperature":0.0,"messages":[{"role":"user","content":"Say OK."}]}'
The deepseek_v4 reasoning parser splits output into content and reasoning_content; clients that read only content will see "" on thinking responses. Either read both fields or strip the reasoning prefix on the client side.
--max-model-len=131072 → 524288 and --gpu-memory-utilization=0.93 → 0.95. The KV cache budget grows to ~1.8 M tokens.--max-num-seqs=1 lets the scheduler hand all KV memory to one request.--max-num-seqs (e.g. 8) and --max-num-batched-tokens (e.g. 16384).--speculative-config=…. Expect ~−30 to −40% decode tok/s vs MTP=2.DEEPSEEK_SPARSE_SWA for DSV4 on sm_120; the --attention-backend flag is logged but ignored by jasl's path.The image is a tarball snapshot of a known-good bare-metal build at:
/home/user/jasl-dsv4/ ← venv + vllm-jasl/ + DeepGEMM-jasl/
/home/user/.local/share/uv/python/ ← uv-managed cpython-3.13.13
The editable install was performed on a host where /home/user/jasl-dsv4 was a symlink to /mnt/raid0-…/builds/jasl-dsv4-epyc01, so the editable finder hardcodes that resolved path. The Dockerfile recreates the path as a symlink inside the container so the editable resolution still works.
The image bundles vLLM (Apache-2.0). The DeepSeek-V4-Flash weights are not redistributed; download them separately from Hugging Face.
Content type
Image
Digest
sha256:3155da95a…
Size
7.5 GB
Last updated
6 months ago
docker pull orthozany/vllm-jasl-dsv4:pr41834-2026-05-13