Pull requests / #3128

#3128 Bound Qwen3.6 Windows CUDA placement by dedicated VRAM headroom

open · draft · @kbc20f11 · 0 commentaires · Sur GitHub

BenchmarksSetup & installAMD / HIPNVIDIA / CUDAModels & quantsDocumentationWindowsLinux

Description

Qwen3.6 currently uses `cudaMemGetInfo` directly when sizing prompt chunks, admitting session caches and placing routed Experts. Under Windows/WDDM, the reported allocation budget can exceed the dedicated VRAM available on the adapter, so an automatic configuration can put Experts in CUDA allocations that require OS paging instead of the intended CPU/GPU hybrid placement.

An instrumented process using the same Qwen3.6 placement logic reported CUDA free memory of **12.85 GiB** while its simultaneous NVML reading showed only **0.91 GiB** of dedicated VRAM free. This was on an RTX PRO 4000 Blackwell SFF 24 GB with another process holding a touched 16 GiB allocation. The counters have different meanings; this change does not treat the CUDA API itself as defective.

The Windows CUDA path now bounds each startup free-memory estimate by `min(CUDA free, NVML dedicated free)`. NVML is loaded dynamically from System32 and the active adapter is selected by its CUDA PCI bus address, avoiding assumptions about CUDA/NVML device numbering. Missing NVML, failed queries and inconsistent counters fall back to the previous CUDA estimate. `STRATA_Q36_PLACE_DEBUG` prints the two readings and the selected value. Linux/HIP retain their existing query behavior.

The existing Expert placement algorithm, packed-weight release, MTP-only CPU placement, 768 MiB default reserve and conditional 256 MiB near-fit reserve remain unchanged. This is a startup budget correction; it cannot guarantee future residency or reserve VRAM against other applications.

Related: #1911 addresses the same Windows memory-accounting problem in the common Expert-cache path. This change covers the separate Qwen3.6 path, which that PR does not modify.

Draft status: the Windows CUDA build and the checks below passed. Other GPU backends have not been compiled, and a successful upstream real-model run remains outstanding because the installed mixed-quant GGUF is rejected by upstream before these queries. This is not ready for a final merge decision on the evidence available here.

Validation:

- Built the actual `strata-q36` target successfully with CUDA 13.2, sm120, portable AVX2 and Release configuration on Windows.
- Passed 42 host cases using the actual helper extracted from this source: clamp and zero-free handling, active-device PCI selection, driver/query failures and invalid counters, CUDA error preservation, and unchanged Linux/HIP preprocessor paths. These are deterministic host mocks, not actual Linux/HIP hardware tests.
- Attempted a bounded upstream native model probe with the installed Unsloth UD-IQ3_XXS file, context 8192, chunk 512, MTP 0, no warmup and 16 GiB external pressure. Upstream rejected the file's existing mixed IQ2_S/IQ3_S Expert format during loading, before reaching the changed budget queries. **No successful upstream real-model generation or speed result is claimed.**
- Compiled and exercised the identical helper in TinyStrata with the installed Unsloth model. With a separate touched 16 GiB allocation on the 24 GB GPU, the previous CUDA-only policy placed all 10,496 routed Expert slots (11.40 GiB) on the GPU. The corrected automatic policy used 451 slots (501 MiB) in a diagnostic run and processed the remainder through the CPU pool.
- Two further TinyStrata runs retained GPU Vision at 4,096 image tokens, MTP 3 and production sampling defaults. Automatic selection kept context 64K and chunk 512. INT8 used 410 GPU slots / 455 MiB and generated at 66.30 tok/s; FP8 used 328 slots / 364 MiB and generated at 63.85 tok/s. Each run generated 768 tokens across three inputs repeated twice and recorded over 1.2 million CPU Expert entries. Available VRAM changed between fresh starts, so this is not a fixed-cache INT8-versus-FP8 comparison or an upstream performance result.
- Untimed retouching of the entire live external allocation after generation changed physical free memory by 64 MiB and 32 MiB respectively. This ruled out a large hidden eviction in that check, while not proving exact residency or emulating a physical 8 GB GPU. The 768 MiB reserve remains a placement target; later warmup allocations can reduce observed free memory below it.

Reproduction on Windows with an upstream-supported Qwen3.6 GGUF:

1. Use an NVIDIA GPU in WDDM mode and keep another GPU application actively using enough VRAM to make dedicated memory scarce. An idle allocation alone may be paged out by Windows and is insufficient to establish persistent pressure.
2. Build `strata-q36` using the project's normal Windows CUDA build procedure. Run the same supported GGUF with and without this patch. Keep the context, chunk, MTP and other options identical; leave `--expert-vram` and `--expert-slots` unset so Expert placement remains automatic.
3. In PowerShell, enable the diagnostics and run a short native generation, replacing the executable and GGUF paths with your local files:

```powershell
$env:STRATA_Q36_PLACE_DEBUG = '1'
& '.\build\strata-q36.exe' --model 'C:\models\supported-qwen36.gguf' --max-context 8192 --chunk 512 --mtp 0 --no-warmup --tokens '1,2,3' --n 16
```

4. The patched `resident VRAM budget` lines print CUDA free memory, device-wide dedicated free memory and the selected value. The selected value must not exceed either reading. The existing Expert placement log shows whether the result is all-GPU or CPU/GPU hybrid. NVML must be available for the clamp to apply; otherwise the diagnostic explicitly reports the CUDA fallback.
5. Check device-wide free memory in another terminal with `nvidia-smi --query-gpu=pci.bus_id,memory.free,memory.total --format=csv`. Keep the other GPU workload live throughout the test. A separate allocation on a larger card is not a fixed physical smaller-card profile, and this correction does not prevent WDDM from paging other allocations later.

The source change introduces no external SDK or test-file dependency. Driver-failure and counter-edge cases were tested with a separate deterministic host harness; those tests are described above rather than being required to reproduce the real Windows memory-accounting discrepancy.

References:

- [CUDA Driver API: cuMemGetInfo](https://docs.nvidia.com/cuda/cuda-driver-api/cuda_driver_api/group__CUDA__MEM.html)
- [NVIDIA explanation of WDDM CUDA memory accounting and paging](https://forums.developer.nvidia.com/t/cudamemgetinfo-not-reporting-the-actual-gpu-memory-stats/161335)
- [Microsoft video-memory budgeting documentation](https://learn.microsoft.com/en-us/windows/win32/api/dxgi1_4/ns-dxgi1_4-dxgi_query_video_memory_info)

Sur le site

Liens install, modèles, releases.