Skip to content

--batch hangs during startup on Linux/CUDA (3x RTX 3060, 0.1.43): 100% kernel time, GPU idle, the expert cache is never allocated #2126

Closed as not planned

Description

@nickycrc

Summary

Adding --batch ("parallel": 2 or 4) to a working config makes strata serve hang during startup, before the expert cache is allocated. Without --batch the exact same config loads in ~6 minutes and serves normally.

The hang is not I/O, not swap and not a plain RAM shortage: the host spins at 100% system time with the GPU completely idle (0%), and the kernel reports ~148k failed memory compactions. strace cannot attach (container), but /proc/<pid>/stat shows utime frozen while stime advances 1000 ticks per 10 s.

Environment

GPU 3x NVIDIA GeForce RTX 3060 12 GB (sm_86), driver 580.126.20
PCIe CUDA0 x4 Gen4, CUDA1/CUDA2 x8 Gen4 (measured)
CPU AMD Ryzen 7 3700X (8c/16t), no AVX-512
RAM 62 GiB (2x 32 GB DDR4 @2133), swap 16 GiB
Motherboard CVN X570 GAMING PRO
OS Ubuntu 24.04.4 LTS, kernel 6.8.0-142-generic
Container Docker, base nvidia/cuda:13.0.0-devel-ubuntu24.04, --ulimit memlock=-1:-1, --shm-size 64m
Engine 0.1.43, built from tag v0.1.43 (src=e568e70371a3d2e0), CMAKE_CUDA_ARCHITECTURES=86, nvcc 13.0.48
Model Qwen3.8-Flash-Next GSQ-RCO abliterated IQ3_S, native pack iq3_s_abl, 48 blocks

Config (the args array, identical in every run below unless noted)

--pack /data/packs/iq3_s_abl
--native .../Qwen3.8-Flash-Next-GSQ-RCO-abliterated-IQ3_S-00001-of-00002.gguf
--ple-gguf .../Qwen3.8-Flash-Next-GSQ-RCO-abliterated-IQ3_S-00002-of-00002.gguf
--expert-profile /opt/strata/data/expert-profile.bin
--expert-cache auto --prefill auto --spec 4 --spec-min-p 0.5 --mtp /data/mtp/rt
--max-context 235520 --kv int8 --kv-resident 32768 --remote-expert-opt
--control-vector-scaled .../Huihui-Qwen3.8-Flash-Next-refusal-direction-r.gguf:1.0
--control-vector-layer-range 4 44 --cvec-mode project --cvec-dir per-layer --vision
--vram-reserve-mib 700 --trim-stage-weights

plus "gpu": [0,1,2], "layer_split": "16,32", and the variable under test "parallel": 2.

Symptom

The log stops at exactly the same line every time, and never reaches the expert cache allocation:

strata generate: --batch-groups auto: 2 groups of 1 slot
strata generate: --batch: 2 slot sessions on CUDA0 (0.34 GiB each); 9.12 GiB free
strata generate: --batch: 2 slot sessions on CUDA1 (0.34 GiB each); 9.06 GiB free
strata generate: --batch: 2 slot sessions on CUDA2 (0.34 GiB each); 8.51 GiB free
strata generate: --batch 2: the slot sessions take 0.69 GiB of VRAM on CUDA0 that the expert cache would otherwise hold
strata mtp: draft layer loaded, 835 MiB of VRAM (experts 675, dense 111), files read in 0.83 s (952 MiB/s)
strata generate: GPU 0: NVIDIA GeForce RTX 3060, compute capability 8.6
<<< hangs here forever >>>

grep -c "expert cache auto" on that log is 0. The next line in a successful (no --batch) start is:

strata generate: expert cache auto: 5.32 GiB free, 700 MiB reserved (+0 MiB for the draft head) -> 1870 slots

Measured while hung:

  • nvidia-smi: 0% utilisation on all three cards, VRAM frozen at 2578 / 2638 / 4034 MiB (a successful start reaches 11450 / 11354 / 11574 MiB)
  • free: 6.9 GiB available, swap usage unchanged (1437 MiB) — so it is not swapping
  • Main thread: State: R (running), wchan=0, /proc/<pid>/syscall = running on 20/20 samples
  • /proc/<pid>/stat: utime frozen (398), stime +1001 ticks per 10 s → 100% system time
  • Worker threads: futex_wait_queue / do_poll (normal)

Kernel counters at the moment of the hang (/proc/vmstat):

allocstall_movable    608585
allocstall_normal      76862
compact_stall         182850
compact_fail          148075     <-- failed compaction
pgmigrate_success   77873701
pgsteal_direct      68258939

/proc/meminfo: AnonPages 46953728 kB, Shmem 9353772 kB, Mlocked 27356 kB, MemAvailable 6089800 kB.

So the host is repeatedly failing to obtain contiguous memory while the GPU sits idle.

What I ruled out (controlled, one variable at a time)

Variable Change Result
swap 4 GiB to 16 GiB (new swapfile, verified with swapon --show) identical hang; swap usage never grew
VRAM reserve --vram-reserve-mib 700 to 2000 identical hang, same log line
batch slots --batch 2 and --batch 4 both hang
layer split 3 stages (16,32, 3 GPUs) and 2 stages (20, 2 GPUs) both hang

--batch off: all four configs load and serve fine (this is the config I run in production, 13 474 expert slots, hit rate 0.996-0.998, 50-57 tok/s decode).

Possibly related

Notes

  • strace -p from the host fails with PTRACE_SEIZE: Operation not permitted (container isolation), so I could not capture the syscall. If there is a recommended way to trace inside the container, I can rerun and attach the output.
  • Happy to run any build with extra instrumentation (--stats, debug env vars, a patched binary) on this machine - it reproduces 100% of the time and is otherwise idle.

Activity

  1. xyzzing commented on Oct 14, 2026

    @xyzzing
    Contributor

    A gfx1100 (RX 7900 XTX) data point on the gate this added, from a box that runs the 0.1.44.1 line as a daily driver.

    The gate reads free_huge_bytes() (order >= 9 in /proc/buddyinfo) at arena setup, before the arena is allocated — so on a restart it sees the state after the previous instance freed its memory, not the state while an engine runs. On this host (96 GB RAM, 46.84 GiB arena) that means the restrictive branch is essentially never taken:

    • 15/15 recent production sessions logged transparent huge pages requested (MADV_HUGEPAGE)
    • the gate-fired string transparent huge pages NOT requested occurs 0 times in the whole 75,438-line engine log
    • the 3 using 4 KB pages lines sit at log lines 215/263/308, from long-superseded versions

    So the scenario the gate is for is the one where something still holds the memory when the engine starts (an overlapping restart / a second engine), which matches the "wait for an engine that is still exiting" warnings that land in the log under exactly those conditions.

    I also measured what the fallback costs, by forcing it with STRATA_NO_ARENA_THP=1: steady state is unchanged at matched window mix (31.22/31.30 vs 31.17/31.26 ms per verify round, prefill 2154.1 vs 2150.0 tok/s), while startup wall time goes up about +8 s at 1K and +5 s at 128K. So the branch normally taken (THP) is the faster one and the 4 KB fallback is cheap insurance.

    Caveat, stated plainly: I did not reproduce the compaction stall itself on this box — free 2 MiB blocks at setup never drop below arena/2 here while still fitting the arena, so the condition is not reachable in a measurement window.

    Full write-up, including the other new default-ON 0.1.44 path (STRATA_COMMIT_BATCH): #2361

  2. Brightfl commented on Oct 17, 2026

    @Brightfl

    3x RTX 3060 12 GB on Windows/WDDM: the third stage fails with CUDA1 free memory: out of memory while the same log reports 6.25 GiB free - reproduces on 0.1.43, 0.1.44.1 and 0.1.45

    Adding a data point from Windows (the report above is Linux/Docker, same card count).

    Environment

    • Windows 10 Pro, WDDM, driver 616.92, CUDA 13
    • 3x RTX 3060 12 GB = 36 GB total, links x16 / x1 (riser) / x4, no P2P. The engine's own PCIe
      probes read 0.8 GB/s on the x1 link (CUDA2 link 0.8 GB/s -> miss cost x16.00) and 3.0 GB/s on
      the x4 link, so the unusual link is priced in as usual - see the order-swap row below, which shows
      the failure is not tied to that card.
    • i9-10900K, 48 GB RAM, NVMe (model + the 29 GB PLE table live on the SSD)
    • Qwen3.8-Flash-Next GSQ-RCO IQ2_XS, all 512 experts, mmproj BF16, MTP draft layer
    • "gpu": [0,2,1], --max-context 245760, --kv q4_0, --vram-reserve-mib 300, "parallel": 2
    • Engines: 0.1.43, 0.1.44.1 and 0.1.45 (official Windows zips, SHA-256 verified against SHA256.txt)

    Symptom. strata serve never reaches ready:. On 0.1.44.1 the split search even completes
    (layer split auto: K=30,40 - the caches hold 14072 of 24576 profiled pairs (~97.7% of the routed mass), best of 1035 placements), every stage reports real room, and the next allocation fails:

    layer split: CUDA1 holds its weights, session [30, 40); 7.39 GiB free
    layer split: CUDA2 holds its weights, session [40, 48) and the head; 7.24 GiB free
    --batch: 2 slot sessions on CUDA0 (1.27 GiB each); 4.16 GiB free
    --batch: 2 slot sessions on CUDA1 (0.57 GiB each); 6.25 GiB free
    --batch: 2 slot sessions on CUDA2 (0.41 GiB each); 6.42 GiB free
    expert cache auto: 0.00 GiB free, 300 MiB reserved (+0 MiB for the draft head) -> 0 slots
    no VRAM is left for the expert cache: it needs at least 368 slots (530 MiB), about 831 MiB
      more than this card has free.
    layer split: CUDA1 free memory: out of memory
    layer split, CUDA1: 0.00 GiB free of 0.00, room for experts 0.00 GiB
    layer split, CUDA1 expert cache: no room
    

    The engine contradicts itself two lines apart: 6.25 GiB free -> 0.00 GiB free.

    What does not move the number (shortfall stays ~790-831 MiB in every case):

    Lever Values tried Reported shortfall
    --max-context 262144 / 196608 / 245760 ~800 / ~784 / ~796 MiB
    slots 2 -> 1 (parallel removed) ~796 MiB
    --prefill auto(2048) -> 1024 ~796 MiB
    --vram-reserve-mib 700 -> 300 ~796 MiB
    GPU order [0,2,1] -> [1,0,2] still fails on CUDA1 - the failing stage follows the position, not the card: with [1,0,2] the x1 card becomes CUDA0 and CUDA1 is the x16 card, same error
    layer_split auto -> explicit 20,24 fails the same way
    vision GPU -> CPU (0.1.45 default) per-card VRAM use actually drops 8.2/5.8/5.0 -> 7.1/5.7/5.6 GiB, failure identical
    large pages SeLockMemoryPrivilege granted log changes from large pages refused ... VirtualAlloc error 1314; using 4 KB pages to large pages are resident without a lock, failure identical

    Shortfall by engine: 0.1.43 ~ 790 MiB, 0.1.44.1 ~ 796 MiB, 0.1.45 ~ 831 MiB.

    Two cards are fine, same model and flags, "gpu": [0,2]: ready: in 34-37 s, 36.6 tok/s single
    request, 19.6 + 21.0 tok/s with two requests in flight. So the model, the config and the disks are
    healthy; only the three-stage split fails.

    Questions

    1. Is a 3-stage layer split on Windows/WDDM known to be limited (a process-wide video-memory budget
      across adapters?), or is the middle stage's expert-cache allocation a bug?
    2. Anything worth trying: STRATA_ARENA_PIN_GIB, --vram-elastic, an explicit per-device
      --expert-cache-device1/2/3, --split-skip-if-fits, --trim-stage-weights?
    3. Would the full engine log help? Happy to attach it.
  3. Adamyno commented on Oct 17, 2026

    @Adamyno

    3× RTX 2080 Ti, native Linux, v0.1.45: --batch 4 starts normally

    Counter-data point for the startup hang: on this 3-card Turing rig the --batch path does not hang, and it goes past the line where your run stops.

    Hardware: 3× RTX 2080 Ti 22 GB (sm_75), i9-7980XE, 125.5 GiB RAM, native Linux 7.0.0-38 (not a container), driver 580.178.04, CUDA 13.0.
    Config: v0.1.45 (477ac13c), Flash-Next UD-Q4_K_XL (pack ud-q4_k_xl), 262,144 ctx, --kv int8 --spec 3 --spec-min-p 0.54 --batch 4, "layer_split": "16,32", --expert-cache auto --trim-stage-weights.

    The log reaches and passes your stopping line:

    strata generate: --batch-groups auto: 2 groups of 2 slots
    strata generate: --batch: 4 slot sessions on CUDA0 (1.27 GiB each); 13.22 GiB free
    strata generate: --batch: 4 slot sessions on CUDA1 (1.27 GiB each); 13.25 GiB free
    

    The server was ready in 133 s (model load included), no 100% system time, GPU active during the load. So the hang is not inherent to --batch on three CUDA cards; the remaining candidates are the container's --shm-size 64m / memlock setup, the 62 GiB RAM with a 48-block IQ3_S pack, or the older 0.1.43 build (ours is 0.1.45).

  4. Niko1221 commented on Oct 19, 2026

    @Niko1221
    Owner

    Thanks for taking the time to report this.

    We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to read properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected.

    To reopen it takes about two minutes:

    1. Re-test on 0.2.0-beta. It may already be fixed. Write down what you see.
    2. Start the title with its area: [Engine], [GUI], [TUI], [Benchmark], [Docs] or [Other].
    3. Fill in the parts of the issue form: what happened, the Strata version, your graphics card, memory and system.
    4. Comment /reopen. A check runs and either reopens the issue or lists what is still missing.

    The rules are in CONTRIBUTING.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions