Summary
In router mode (--models-preset / --models-max), the parent llama-server no longer forwards most of its own command-line flags to the per-model child instances it spawns. Flags that are only set on the parent's CLI (not derivable from the preset .ini) silently disappear from the child's argument list, so children fall back to defaults.
The most damaging case is --parallel: its default changed to -1 = auto, which resolves to n_parallel = 4 on a multi-core host. A child sized for a single slot then allocates ~4× the KV cache and OOMs.
- Good:
server-cuda-b9641 (also the floating tag prior to this) — parent CLI flags are forwarded to children.
- Bad:
server-cuda-b9692 — parent CLI flags are dropped; only preset-derived keys reach the child.
Environment
- Image:
ghcr.io/ggml-org/llama.cpp:server-cuda-b9692 (CUDA 12.8.1)
- 2× NVIDIA Quadro P5000 (Pascal), router mode,
--models-max 1
- Parent command line (note
--parallel 1, --cache-type-k/v q8_0, --flash-attn on, --n-gpu-layers 999):
/app/llama-server --models-preset /models.ini --models-max 1 --parallel 1 \
--n-gpu-layers 999 --flash-attn on --cache-type-k q8_0 --cache-type-v q8_0 \
--jinja --metrics --host 0.0.0.0 --port 8080 --threads 40 --numa distribute
Reproduction
- Run a router (
--models-preset preset.ini --models-max 1) with --parallel 1 (and --cache-type-k/v q8_0 --flash-attn on -ngl 999) on the parent CLI.
- Request any model whose
ctx-size was tuned to fit at exactly one slot.
- The child is spawned without
--parallel, defaults to n_parallel = 4, and OOMs on the KV cache.
Observed: child spawn argument lists differ between versions
b9692 — the child's spawning server instance with args: list is missing --parallel, --cache-type-k, --cache-type-v, --flash-attn, --n-gpu-layers (only preset-derived keys survive):
load: /app/llama-server
load: --host 127.0.0.1
load: --port 57803
load: --alias granite4.1:30b
load: --ctx-size 79872
load: --model /models/granite-4.1-30b-UD-Q4_K_XL.gguf
load: --main-gpu 0
load: --split-mode layer
load: --tensor-split 1,1
Child then logs the fallback and OOMs:
I srv llama_server: n_parallel is set to auto, using n_parallel = 4 and kv_unified = true
E ggml_backend_cuda_buffer_type_alloc_buffer: allocating 10296.00 MiB on device 0: cudaMalloc failed: out of memory
E llama_init_from_model: failed to initialize the context: failed to allocate buffer for kv cache
b9641 — same preset, same parent CLI — the child does receive --parallel 1 (and --cache-type-k/v, --flash-attn on, --n-gpu-layers 999):
load: /app/llama-server
load: --host 127.0.0.1
load: --jinja
load: --metrics
load: --numa distribute
load: --port 59289
load: --alias granite4.1:30b
load: --ctx-size 79872
load: --cache-type-k q8_0
load: --cache-type-v q8_0
load: --flash-attn on
load: --model /models/granite-4.1-30b-UD-Q4_K_XL.gguf
load: --main-gpu 0
load: --n-gpu-layers 999
load: --parallel 1
load: --split-mode layer
load: --threads 40
load: --tensor-split 1,1
The b9641 child never logs n_parallel is set to auto (because --parallel 1 was passed), loads cleanly, and serves requests.
Expected
Parent CLI flags that configure spawned children (--parallel, --cache-type-k/v, --flash-attn, --n-gpu-layers, --threads, --numa, …) should continue to be forwarded to child instances, as they were in b9641 — or the change in forwarding behavior should be documented, with a preset-level equivalent for each.
Workaround
Moving --parallel 1 from the parent CLI into the preset [*] section as parallel = 1 does forward to children on b9692 (preset-derived keys still propagate). But the same isn't ergonomic for every dropped CLI flag, and it's a behavior change from b9641 either way.
Likely cause
Somewhere in the b9641…b9692 range; the router rework server: (router) add model management API (#23976) is the most likely candidate that touches how child argument lists are constructed.
Summary
In router mode (
--models-preset/--models-max), the parentllama-serverno longer forwards most of its own command-line flags to the per-model child instances it spawns. Flags that are only set on the parent's CLI (not derivable from the preset.ini) silently disappear from the child's argument list, so children fall back to defaults.The most damaging case is
--parallel: its default changed to-1 = auto, which resolves ton_parallel = 4on a multi-core host. A child sized for a single slot then allocates ~4× the KV cache and OOMs.server-cuda-b9641(also the floating tag prior to this) — parent CLI flags are forwarded to children.server-cuda-b9692— parent CLI flags are dropped; only preset-derived keys reach the child.Environment
ghcr.io/ggml-org/llama.cpp:server-cuda-b9692(CUDA 12.8.1)--models-max 1--parallel 1,--cache-type-k/v q8_0,--flash-attn on,--n-gpu-layers 999):Reproduction
--models-preset preset.ini --models-max 1) with--parallel 1(and--cache-type-k/v q8_0 --flash-attn on -ngl 999) on the parent CLI.ctx-sizewas tuned to fit at exactly one slot.--parallel, defaults ton_parallel = 4, and OOMs on the KV cache.Observed: child spawn argument lists differ between versions
b9692 — the child's
spawning server instance with args:list is missing--parallel,--cache-type-k,--cache-type-v,--flash-attn,--n-gpu-layers(only preset-derived keys survive):Child then logs the fallback and OOMs:
b9641 — same preset, same parent CLI — the child does receive
--parallel 1(and--cache-type-k/v,--flash-attn on,--n-gpu-layers 999):The b9641 child never logs
n_parallel is set to auto(because--parallel 1was passed), loads cleanly, and serves requests.Expected
Parent CLI flags that configure spawned children (
--parallel,--cache-type-k/v,--flash-attn,--n-gpu-layers,--threads,--numa, …) should continue to be forwarded to child instances, as they were in b9641 — or the change in forwarding behavior should be documented, with a preset-level equivalent for each.Workaround
Moving
--parallel 1from the parent CLI into the preset[*]section asparallel = 1does forward to children on b9692 (preset-derived keys still propagate). But the same isn't ergonomic for every dropped CLI flag, and it's a behavior change from b9641 either way.Likely cause
Somewhere in the b9641…b9692 range; the router rework
server: (router) add model management API (#23976)is the most likely candidate that touches how child argument lists are constructed.