Skip to content

Releases: devnen/qwen3.6-windows-server

qwen3.6-windows-server v1.3.11, portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 14 May 17:10

qwen3.6-windows-server v1.3.11

Bugfix release: third pass on the LOADING-stuck dashboard (issue #12).
v1.3.8 added a 60-second grace before the runtime-manifest GC could
fire, v1.3.9 removed a separate silent-unlink path. Reporter still hit
it on v1.3.9: their cold Ampere boot takes ~135 seconds from click to
Application startup complete, longer than the 60-second grace, so the
GC fired during boot with port_up=False wrapper_up=False and wiped
the manifest mid-boot.

What changed

  • launcher/app/runtime.py: grace bumped from 60s to 300s. Cold
    Ampere boots with torch.compile + warmup + weight load run 120-180s,
    and a slow tasklist call can flap wrapper_up to False for one
    poll. 300s covers any realistic boot window without leaving truly
    dead manifests around for long.
  • Per-poll diag log line. Every poll that sees a not-listening,
    not-alive manifest now writes one line to
    logs\launcher.diag.log summarizing port_up, wrapper_up, age, and
    the keep / GC decision. Makes future diagnosis a one-line paste.
  • snapshots/_common.py: clear_manifest (called from each
    snapshot's finally block when the wrapper python exits) now writes
    a diag-log line too, so we can tell from logs whether the wrapper
    ever exited and when.

Who is affected

  • Anyone whose Ampere or Blackwell snapshot boot takes longer than 60
    seconds (any cold boot does) and hit the LOADING-stuck card despite
    v1.3.9 / v1.3.10.

Upgrading

update.bat

The launcher zip is replaced; venv\, models\, logs\,
cuda13_shim\ and user_config.json are preserved. The bundled wheel
is unchanged from v1.3.7, so the runtime install is not rerun.

Verification

After upgrading, launch any snapshot from the TUI and let it sit
through the full vLLM compile / autotune window. The card should
progress LOADING -> RUNNING and logs\runtime\<port>.json should
remain on disk for the whole session. If the card still sticks, paste
the contents of logs\launcher.diag.log in the issue.

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

qwen3.6-windows-server v1.3.10, portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 14 May 16:35

qwen3.6-windows-server v1.3.10

Bugfix release: launcher could loop for 2-3 hours on every boot when the
NVIDIA CUDA 13 Toolkit was installed at its default location (C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.x). The space in the path
broke FlashInfer's JIT build, so trtllm_utils.dll never compiled and
vLLM never reached Application startup complete. Reported in issue #18.

What changed

  • snapshots/_common.py: clean_cuda_env() now prefers a real
    system-installed CUDA 13.x toolkit at a space-free path. When the
    toolkit is found at the default C:\Program Files\... location, the
    launcher creates a junction at C:\cuda13<minor> (no admin required)
    and points CUDA_PATH / CUDA_HOME there so FlashInfer's ninja build
    works. Falls back to the existing bundled cu13 shim when no system
    toolkit is installed, the same as before.

Who is affected

  • Anyone on a Blackwell GPU (5090) who installed the CUDA 13 Toolkit and
    saw boot loop on Tuning fp4_gemm for hours.
  • Drivers-only users are unaffected, the bundled cu13 shim still ships
    and still works for them.

Boot time expectations

Cold first boot on a fresh install is 10-20 minutes on the 5090 NVFP4
snapshot. That's autotune running once per unique GEMM shape and is
unavoidable on the current FlashInfer wheel. Subsequent boots can still
take that long because per-shape tactic selection isn't yet cached on
sm_120; that's gated on upstream FlashInfer work and not something this
release can fix. Keep the server running between requests.

Upgrading

update.bat

venv\, models\, logs\, cuda13_shim\ and user_config.json are
preserved. The bundled wheel is unchanged from v1.3.7, so the runtime
install is not rerun.

Verification

Launch the rtx5090_nvfp4 snapshot. If you previously hit the
hours-long Tuning fp4_gemm loop, the log should now show normal
autotune progress and reach Uvicorn running on http://0.0.0.0:5001
within 10-20 minutes.

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

Credits

Issue #18 reported and diagnosed by @hiraghi.

qwen3.6-windows-server v1.3.9, portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 14 May 15:23

qwen3.6-windows-server v1.3.9

Bugfix release: a follow-up to the v1.3.8 fix for the LOADING-stuck
dashboard. v1.3.8 added a 60-second grace before the runtime-manifest
GC could fire, but a second deletion path in the manifest reader
bypassed that grace and silently unlinked the file on any read error.
Issue #12 reporter on Russian Windows 11 still hit it.

What changed

  • launcher/app/runtime.py: _read_manifests no longer unlinks a
    manifest when the read fails. Read errors (Windows file-sharing race
    against the snapshot's os.replace write, partial JSON read,
    transient OSError) are skipped and retried on the next 2-second
    poll. Snapshots clean up their own manifest on exit, and the
    launcher's Unload path clears it via clear_manifest_for_port. The
    reader has no business deleting a file it failed to read this poll.
  • Diagnostic log file at logs\launcher.diag.log. The Textual TUI
    takes over the terminal so print() from the runtime poll is
    invisible in scrollback. Diagnostics now append to a file:
    manifest-read failures land here with the exception type, and the
    post-grace GC line lands here too. If the dashboard sticks again, a
    single type logs\launcher.diag.log reproduces the full poll
    history.

Who is affected

  • Anyone who hit the LOADING-stuck dashboard on v1.3.8 despite the
    60-second grace. The new path is hardened against the read-error
    unlink and the diagnostic log makes future debugging a one-line
    paste.

Upgrading

update.bat

The launcher zip is replaced; venv\, models\, logs\,
cuda13_shim\ and user_config.json are preserved. The bundled wheel
is unchanged from v1.3.7, so the runtime install is not rerun.

Verification

After upgrading, launch any snapshot from the TUI and let it sit
through the full vLLM compile / autotune window. The card should
progress LOADING -> RUNNING and logs\runtime\<port>.json should
remain on disk for the whole session. If the card sticks on LOADING
again, paste the contents of logs\launcher.diag.log in the issue.

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

qwen3.6-windows-server v1.3.8, portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 13 May 21:46

qwen3.6-windows-server v1.3.8

Bugfix release: the launcher TUI's dashboard could get stuck on
LOADING while vLLM was actually up and serving requests, because the
runtime-manifest GC was too aggressive during the snapshot's boot
window.

What changed

  • launcher/app/runtime.py: detect_running no longer GC's a
    manifest younger than 60 seconds, even when both _port_listening
    and _pid_alive momentarily return False. Those signals can flap
    during vLLM's compile window (port bound but accept loop not yet
    running, slow tasklist returns under load) and a single bad poll
    used to delete the manifest. Once deleted, the dashboard had no way
    to associate the running engine with its card, so the LOADING banner
    stuck forever.
  • Diagnostic log when GC fires. After the grace period, if both
    signals still say the snapshot is gone, the reader now prints
    [runtime] GC manifest <path> port=<port> wrapper_pid=<pid> port_up=<bool> wrapper_up=<bool> to the launcher's stdout before
    unlinking. If anyone hits this again, that line tells us which
    signal failed.
  • windows_tools/wipe_caches.py: prints a clear "recovery tool,
    not pre-launch cleanup" banner up front before the cache scan, so
    users do not run it before every boot and trip the 11-25 min cold
    FlashInfer rebuild. Related: issue #15.

Who is affected

  • All users who launch snapshots via the TUI on hosts where the
    vLLM boot window is long enough for the polling loop to fire before
    the engine accepts connections, that is, anyone on Blackwell NVFP4
    (FlashInfer fp4_gemm autotune) and anyone with a long
    torch.compile first-boot. Reported on Russian Windows 11 with the
    Ampere zip on issue #12.
  • Direct snapshot launches (snapshots\start_*.bat) were
    unaffected, the bug was in the launcher reader only. If you have
    been working around the problem by running the bat directly, you can
    go back to using the TUI after this update.

Upgrading

update.bat

The launcher zip is replaced; venv\, models\, logs\,
cuda13_shim\ and user_config.json are preserved. The bundled wheel
is unchanged from v1.3.7, so the runtime install is not rerun.

Verification

After upgrading, launch any snapshot from the TUI and let it sit
through the full vLLM compile / autotune window. The card should
progress LOADING -> RUNNING and logs\runtime\<port>.json should
remain on disk for the whole session. If the card sticks on LOADING
again, the launcher stdout will now contain a [runtime] GC manifest ... line, please paste it in a fresh issue.

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip (and the unsuffixed
    alias for legacy in-place updates from pre-v1.2.3 installs)
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

qwen3.6-windows-server v1.3.7 — portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 12 May 22:04

qwen3.6-windows-server v1.3.7

Blackwell-only cleanup release. The two AutoRound INT4 snapshots for the
RTX 5090 are gone; NVFP4 is now the sole 5090 path. Ampere/Ada
(3090/4090) are unaffected, AutoRound stays the recommended quant
there.

What changed

  • Removed snapshots: rtx5090 (240k ctx, MTP n=6, AutoRound INT4)
    and rtx5090_max (280k ctx, MTP n=3, AutoRound INT4). The matching
    snapshots/start_5090.{py,bat} and snapshots/start_5090_max.{py,bat}
    files are deleted.
  • Reason: on Blackwell sm_120 the AutoRound (Marlin INT4) FFN GEMMs
    hit the ~170W prefill ceiling documented in
    docs/SM120_GDN_CEILING.md, capping
    prefill at ~1.1k tok/s. The NVFP4 path routes FFN/QKV/proj through
    FlashInfer's native sm_120 fp4_gemm tensor cores and runs at full
    TDP: ~5,300-7,460 tok/s prefill, ~92 tok/s decode. The AutoRound
    configs booted and ran on the 5090, but the prefill cap made them too
    slow to keep shipping as user-facing options.
  • 5090 dashboard now exposes two cards: rtx5090_nvfp4 (200k ctx,
    MTP n=6, default) and rtx5090_nvfp4_vision (180k ctx, experimental,
    image/video input). Both use the Peutlefaire NVFP4 weights.
  • Compatibility matrix updated: Blackwell sm_120 + Marlin AutoRound INT4 is now flagged warn with a note about the prefill ceiling.
    Added a separate Blackwell sm_120 + NVFP4 row marked ok.
  • Docs swept: README and 16 docs under docs/ updated so every
    forward-looking 5090 recommendation points at NVFP4. Historical
    AutoRound bench numbers retained in BLACKWELL.md, HARDWARE.md, and
    TUNING.md as reference, labeled "removed in v1.3.7" or "historical".
  • Boot-time clarification added to TROUBLESHOOTING.md, BLACKWELL.md,
    and the rtx5090_nvfp4 notes: the FlashInfer fp4_gemm "Tuning"
    progress bars appear on every boot. First-ever boot takes ~9 min
    (JIT-compiles kernels + autotunes tactics). Every subsequent boot
    finishes in ~1-2 min because the compiled kernel binaries are cached
    under ~/.cache/flashinfer/, only the tactic selection re-runs. This
    is expected, not a regression.

Who is affected

  • 5090 users: if you had been booting rtx5090 or rtx5090_max,
    those cards are gone. Use rtx5090_nvfp4 (or _vision) instead.
    You will need the Peutlefaire NVFP4 weights on disk; set
    VLLM_NVFP4_MODEL_DIR if they're not at the default location
    (models/Qwen3.6-27B-NVFP4). See
    docs/MODELS.md for the download path.
  • 3090 / 4090 users: no behaviour change. AutoRound stays the
    recommended quant on Ampere/Ada. Wheel is unchanged
    (vllm-0.19.0+devnen.3).
  • Wheels: Ampere stays on vllm-0.19.0+devnen.3, Blackwell stays
    on vllm-0.20.0+cu132.devnen.2. Inference behaviour for surviving
    snapshots is identical to v1.3.6.

Upgrading

update.bat

The launcher zip is replaced; venv\, models\, logs\,
cuda13_shim\ and user_config.json are preserved. The runtime
install is not rerun because the bundled wheel did not change. If you
created a custom snapshot named start_5090.py or start_5090_max.py,
keep your local copy: the launcher reads any start_*.py in
snapshots/, the deletion only removes the in-zip files.

Verification

After upgrading, the Blackwell zip's dashboard should show only two
5090 cards: rtx5090_nvfp4 and rtx5090_nvfp4_vision. Launching
rtx5090_nvfp4 should boot in ~1-2 min on a host that has booted NVFP4
before (kernel binaries cached), ~9 min the first time. After
Application startup complete, python windows_tools\bench.py should
report ~92 tok/s steady decode at ~580W.

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip (and the unsuffixed
    alias for legacy in-place updates from pre-v1.2.3 installs)
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

qwen3.6-windows-server v1.3.6 — portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 08 May 20:43

qwen3.6-windows-server v1.3.6

Bug-fix release. Fixes the launcher staying on the LOADING banner forever
on hosts running a TUN-mode VPN (sing-box / Nekobox TUN whitelist /
v2rayN TUN / Clash TUN), even after vLLM is up and serving.

What changed

  • launcher/app/runtime.py:probe_ready() no longer issues an HTTP
    request to 127.0.0.1.
    It now reads the snapshot's log file
    (logs/vllm_server.<port>.log, truncated on each boot) and looks
    for the uvicorn Application startup complete marker. Reading a
    local file is immune to network-layer interception.

    v1.3.5 added urllib.request.ProxyHandler({}) to bypass IE/registry
    HTTP proxies, but TUN-mode VPN clients intercept TCP at the network
    adapter layer below urllib. When the launcher's python.exe is in
    a TUN whitelist (or when sing-box strict_route covers 127.0.0.0/8),
    the kernel still routes loopback traffic through the TUN driver —
    the HTTP probe hangs or returns wrong content, and the launcher
    never moves the snapshot from running_ids into ready_ids. Symptom:
    vLLM logs Application startup complete and Uvicorn running on http://0.0.0.0:5001, but the launcher's LOADING banner stays up and
    Test / Unload remain disabled. Reported in
    issue #12
    (second report after v1.3.5 didn't fully resolve it).

Who is affected

  • Anyone running a TUN-mode VPN (sing-box / Nekobox TUN whitelist /
    v2rayN TUN / Clash TUN) on the same Windows host as the launcher
    and who saw the LOADING banner stay up after upgrading to v1.3.5.
  • Wheels are unchanged: Ampere stays on vllm-0.19.0+devnen.3,
    Blackwell stays on vllm-0.20.0+cu132.devnen.2. Inference behaviour
    is identical to v1.3.5.

Upgrading

update.bat

The launcher zip is replaced; venv\, models\, logs\, cuda13_shim\
and user_config.json are preserved. The runtime install is not rerun
because the bundled wheel didn't change.

Verification

After upgrading, launch any single-GPU snapshot. Once vLLM logs
Application startup complete, the LOADING banner in the launcher's
detail screen should clear within ~5s and Unload / Test should
re-enable, regardless of whether a TUN VPN is active.

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip (and the unsuffixed
    alias for legacy in-place updates from pre-v1.2.3 installs)
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

qwen3.6-windows-server v1.3.5 — portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 08 May 19:18

qwen3.6-windows-server v1.3.5

Bug-fix release. Fixes the launcher staying on the LOADING banner forever
on hosts that have a system HTTP proxy configured, even after vLLM is up
and serving.

What changed

  • launcher/app/runtime.py:probe_ready() no longer routes localhost
    through the system proxy.
    The probe used urllib.request.urlopen(),
    which honors http_proxy / https_proxy env vars and the Windows IE /
    registry proxy settings. On any box with a proxy configured, the GET to
    http://127.0.0.1:5001/v1/models got routed through it, the proxy
    returned non-200 (or hung), and the launcher never moved the snapshot
    from running_ids into ready_ids. The LOADING banner stayed up
    forever even though the engine logged Application startup complete
    and all routes were registered. The fix builds a urllib opener with an
    empty ProxyHandler({}) so localhost is never proxied. Probe timeout
    also bumped from 0.8s to 1.5s. Reported in
    issue #12.
  • windows_tools/verify_install.py default --venv resolution.
    Defaulted to <repo>/venv/, which doesn't exist on portable installs
    (vLLM is installed directly into the embedded Python at python/).
    The verifier reported [ERR] vllm no python.exe at venv\Scripts\python.exe
    on every working portable install. Now falls back to the embedded
    Python layout, and check_vllm looks for python.exe at both
    <root>/Scripts/python.exe (developer venv) and <root>/python.exe
    (embedded Python).

Who is affected

  • Anyone whose Windows box has an HTTP proxy configured (corporate
    network, VPN that injects one, manually set IE proxy) and who saw
    the launcher stay on ⏳ LOADING vLLM on port 5001... even after the
    engine was clearly serving. Symptom in the wild: vLLM's own log shows
    Application startup complete and Uvicorn running on http://0.0.0.0:5001, but the launcher's Test / Unload buttons stay
    disabled.
  • Anyone running python\python.exe windows_tools\verify_install.py on
    a portable install and seeing a red vllm row.
  • Wheels are unchanged: Ampere stays on vllm-0.19.0+devnen.3,
    Blackwell stays on vllm-0.20.0+cu132.devnen.2. Single-card / Multi-
    card / Blackwell behavior is identical to v1.3.4.

Upgrading

update.bat

The launcher zip is replaced; venv\, models\, logs\, cuda13_shim\
and user_config.json are preserved. The runtime install is not rerun
because the bundled wheel didn't change.

Verification

After upgrading, launch any single-GPU snapshot (e.g. start_speed).
Once vLLM logs Application startup complete, the LOADING banner in
the launcher's detail screen should clear within ~5s and Unload / Test
should re-enable.

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip (and the unsuffixed
    alias for legacy in-place updates from pre-v1.2.3 installs)
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

qwen3.6-windows-server v1.3.4 — portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 08 May 18:48

qwen3.6-windows-server v1.3.4

Bug-fix release. Closes the second wave of pp2_160k boot failures on the
public Ampere zip, surfaced after v1.3.3 unblocked the prior ZMQError: Protocol not supported crash.

What changed

  • New Ampere wheel: vllm-0.19.0+devnen.3. Adds a one-line Windows
    guard to vllm/distributed/utils.py so the sched_yield() wrapper
    takes the time.sleep(0) fallback on Windows instead of calling the
    POSIX-only os.sched_yield(). The bug only fires on multi-worker
    paths (PP>1 / TP>1) via shm_broadcast.acquire_read's spin-wait, so
    single-card snapshots are unaffected. See
    devnen/vllm-windows v0.19.0-devnen.3
    for the patched wheel and diff.
  • Blackwell wheel unchanged at vllm-0.20.0+cu132.devnen.2. The
    upstream v0.20.0 source already inherited the same Windows guard from
    vllm-project/vllm master, so 50-series users were never exposed.
  • pp2_160k boots cleanly on the public Ampere zip. Verified on a
    2× RTX 3090 box: Application startup complete, KV pool 169,344
    tokens, all 3 coherence tiers pass, decode 41.4 tok/s (95 % of the
    documented 43.5 tok/s).

Who is affected

  • 2-GPU users on the Ampere zip who clicked pp2_160k and hit
    AttributeError: module 'os' has no attribute 'sched_yield' (the
    most recent crash, after v1.3.3 fixed the previous ZMQError).
    Reported in
    issue #14.
  • Single-GPU users see no functional change. Blackwell users see no
    functional change.

Upgrading

update.bat

The Ampere variant pulls the new +devnen.3 wheel and re-runs
setup.ensure_runtime() automatically.

Verification

After upgrading, on a 2× GPU box:

snapshots\start_pp2_160k.bat

Wait for Application startup complete, then:

python windows_tools\check_coherence.py --port 5002

Expect COHERENT (3/3 tiers).

Files

  • qwen3.6-windows-server-portable-x64-ampere.zip (and the unsuffixed
    alias for legacy in-place updates from pre-v1.2.3 installs)
  • qwen3.6-windows-server-portable-x64-blackwell.zip
  • SHA256SUMS.txt

qwen3.6-windows-server v1.3.3 — portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 07 May 18:56

qwen3.6-windows-server v1.3.3

Bug-fix release. Unblocks pipeline-parallel (PP=2) on the Ampere wheel,
fixes the embedded bench_summarize.py import path, and ships a real
~25 k-token long-prompt fixture so documented decode_tps numbers are
reproducible from a stock install.

What changed

  • New patched wheels: vllm-0.19.0+devnen.2 (Ampere) and
    vllm-0.20.0+cu132.devnen.2 (Blackwell).
    Both add a Windows-only
    ZMQ ipc:// -> tcp:// fallback so get_open_zmq_ipc_path() works
    on Windows (pyzmq has no ipc:// transport). The Ampere wheel
    additionally widens a worker-pipe isinstance check to
    _ConnectionBase so PP=2 boots past the wait_for_ready assert. See
    devnen/vllm-windows v0.19.0-devnen.2
    for the diff.
  • pp2_160k snapshot is functional again on the public Ampere
    release.
    Verified on a 2× RTX 3090 reference box — boots, is
    coherent, decodes within ~10 % of the documented 40.3 tok/s. Prior
    releases shipped the wheel without those Windows fixups, so any user
    clicking the "Both-GPU big-ctx" card hit a ZMQError: Protocol not supported immediately.
  • bench_summarize.py now runs from a stock install without a
    wrapper. windows_tools/build_launcher_zip.py adds ..\windows_tools
    to the embedded python312._pth, so bench_summarize.py's
    import bench (its sibling module) resolves correctly. Embedded
    Python ignores cwd and PYTHONPATH, so the _pth line was the only
    fix.
  • bench_prompt_sample.py is now a real ~130 KB / ~25 k-token
    fixture
    (verbatim copy of CPython 3.12's Lib/inspect.py under the
    PSF Agreement). Replaces the 670-token stub. Documented decode_tps
    numbers are now reproducible from a clean install instead of being
    artificially fast on a placeholder prompt.

Who is affected

  • 2-GPU users who clicked pp2_160k on the launcher dashboard — those
    setups are usable again.
  • Anyone running windows_tools\bench_summarize.py against the
    documented decode_tps figures — the regime now matches.
  • Single-GPU users see no functional change; the new wheel is a strict
    superset of the +devnen.1 patch set.

Upgrading

update.bat — automatic from v1.3.2. The Ampere variant pulls the new
+devnen.2 wheel and re-runs setup.ensure_runtime(). Blackwell
variant likewise.

Verification

After upgrading, a quick smoke test:

cd C:\<install>\windows_tools
..\python\python.exe bench_summarize.py --label v1.3.3-test

Expect TSV-appended bench output in windows_tools/runs.tsv, no
ModuleNotFoundError, and a long-prompt prefill / decode comparable
to (or exceeding) the snapshot's documented numbers.

qwen3.6-windows-server v1.3.2 — portable Windows launcher

Choose a tag to compare

@github-actions github-actions released this 07 May 06:23

qwen3.6-windows-server v1.3.2

Hotfix release. Hardens the RTX 5090 NVFP4 boot path against a class
of cache poisoning that caused a 7x prefill regression (~750 vs ~5300
tok/s on 47k NVFP4 prompts) when system CUDA installs or conda
cudatoolkit leaked into the launch env.

What changed

  • clean_cuda_env() in snapshots/_common.py — the NVFP4
    snapshot now builds its subprocess env from scratch, not from
    os.environ.copy(). Strips every CUDA_* / NVCC_* /
    NVTOOLSEXT* / CUDNN_* key inherited from the host, filters
    NVIDIA-toolkit dirs and conda Library/bin out of PATH, and pins
    PATH + CUDA_PATH / CUDA_HOME at the bundled cu13 shim.
    Protects against four user environment classes uniformly — pure
    inference users, devs with system CUDA 12.x, devs with system CUDA
    13.x, and Conda/Mamba users with cudatoolkit on PATH.
  • preflight_sm120a_or_die() — a 5-second subprocess probe runs
    before the ~11-minute warmup. Hard-exits with a diagnostic message
    if FlashInfer can't dispatch to sm_120a under the cleaned env,
    instead of silently running degraded.
  • windows_tools/wipe_caches.py — single-command recovery
    utility for the four caches that, when poisoned, cause the
    fingerprint above (~/.cache/vllm/, the torchinductor temp dir,
    ~/.cache/torch/, ~/.cache/flashinfer/). Defaults to
    move-to-.bak.<timestamp> for forensic safety.
  • cache_env_stamp_check() — every boot writes / verifies an env
    fingerprint at ~/.cache/vllm/.env_stamp.json and prints a loud
    [preflight WARN] block on mismatch (e.g. wheel upgrade that
    changes the dispatch surface).

Who is affected

Only the rtx5090_nvfp4 snapshot. Ampere/Ada paths keep the legacy
cuda_env() add-only semantics — they don't run on the cu13 wheel
and aren't exposed to this class of bug.

Upgrading

Use update.bat from inside an existing v1.3.x install. No model
re-download is needed; NVFP4 weights at D:\models\Qwen3.6-27B-NVFP4
remain valid.

If you still see slow prefill after upgrading

If after upgrade you observe prefill below ~3,000 tok/s on a 30k+
NVFP4 prompt, the cache from before the upgrade may already be
poisoned. Recover with:

python windows_tools/wipe_caches.py
python snapshots/stop_vllm.py
python snapshots/start_5090_nvfp4.py    # ~11 min cold rebuild

After the rebuild expect ~5,300 tok/s prefill at 580W on a 47k unique
prompt with max_tokens=1.