You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
serving: the L4 presets (qwen3-4b-instruct, qwen3-8b-fp8) did not fit the smallest L4 instance (g6.xlarge) and nothing warned before the predictor sat Pending #502
The small serving preset qwen3-4b-instruct (the "one g6.xlarge" preset of bumblebee-plans#46 D10) did not fit the smallest L4 instance. On gazelle, with pool gpu-l4 (accelerator: nvidia-l4, sizes: [xlarge], Karpenter NodePool g6 × xlarge), the predictor the llmisvc controller composed from the preset requested cpu: 4, memory: 16Gi (limits 8 / 24Gi); Karpenter refused to launch a node for it for ten minutes:
could not schedule pod … no instance type has enough resources, requirements=… instance-family In [g6], instance-size In [xlarge] …,
resources={"cpu":"4403m","memory":"18788310351", …}
A g6.xlarge has 4 vCPU and 16 GiB; the pool had to be widened to 2xlarge (8 vCPU, 32 GiB, ~50 % more per hour) before a node came (giantswarm/giantswarm#37714). Neither check_fit nor the portal's Add GPU node pool dialog warned that the chosen size cannot host the chosen preset.
Root cause
The preset's requests were sized to the GPU alone, not to the node. A Giant Swarm node of the g6.xlarge shape reports 3.4 vCPU / 13.4 GiB allocatable (the hypervisor's ~5 % of the memory, the kubelet's 0.6 vCPU / ~1.8 GiB), and the DaemonSets that follow a GPU pool's taint (Cilium, the exporters, Alloy, the DNS cache, the GPU operator's operands) request ~0.4 vCPU / ~1.5 GiB more — Karpenter's 4403m / 18788310351 is exactly the preset's 4 vCPU / 16 GiB plus those. So the smallest L4 instance leaves a predictor about 3 vCPU / 11.9 GiB, and 4 / 16Gi could never be placed. qwen3-8b-fp8, the other L4 preset, carried the same requests. No tool knew a pool's instance shapes, so nothing could say so before Karpenter did.
Decision and fix
Both halves, sized to the node model above:
The presets fit a g6.xlarge — fix(connectivity): the two L4 presets fit the smallest L4 instance (g6.xlarge) — requests 2 vCPU / 10 GiB (#502) #503: qwen3-4b-instruct and qwen3-8b-fp8 request 2 vCPU / 10 GiB, limits 4 vCPU / 12 GiB. The predictor's host memory is the runtime and the weights passing through the page cache (the KV cache lives on the GPU; vLLM V1 has no CPU swap), so this covers an 8–9 GiB checkpoint. Each description names the instance it is sized for; tests/verify-serving-slice.py holds every L4 preset's requests within what a g6.xlarge leaves (4 - 1.0 vCPU, 16 * 0.95 - 3.3 GiB); the README's presets paragraph states the budget an installation's own L4 preset should stay within. No minInstanceSize schema key: the presets fit the smallest instance of their accelerator instead.
The tools say when a pool's sizes cannot host a preset — the smaller change is cluster-manager's, feat: create_node_pool answers with the pool's sizes and which of them hosts each serving preset; a preset no size hosts is a warning (agent-platform#502) cluster-manager#27: an instance-shape table per accelerator family (L4 → g6, A10G → g5, T4 → g4dn, L40S → g6e; every size's vCPU / memory / GPUs / GPU memory, and what a node of it leaves a predictor after the reservations and daemonsets above), create_node_pool refusing a size the family does not have, and its answer carrying sizes, presetFit (the serving presets published on the cluster, each with the smallest size that hosts it or why none does) and warnings (a preset the accelerator could serve but no size of the pool hosts — its predictor would sit Pending while Karpenter refuses every size). A first create that brings the slice release sees no preset yet and says so; a dryRun re-run judges them.
The check_fit half is filed and sequenced, since the fit check is what a person asks at load time: giantswarm/model-manager#97 (the kserve backend document's gpuPool block gains the pool's instance shapes; check_fit at a pool's scale-from-zero judges the preset's requests and GPU memory against them instead of answering "unverified"; load_model refuses a preset no size hosts) and giantswarm/cluster-manager#26 (cluster-manager writes the shapes into the document once model-manager declares the field). Both are sub-issues of giantswarm/giantswarm#37639.
changed the title [-]serving: the small preset qwen3-4b-instruct (cpu 8, memory 24Gi) does not fit the smallest L4 instance (g6.xlarge); nothing warns before the predictor sits Pending[/-][+]serving: the L4 presets (qwen3-4b-instruct, qwen3-8b-fp8) did not fit the smallest L4 instance (g6.xlarge) and nothing warned before the predictor sat Pending[/+]on Sep 16, 2026
Tools: feat: create_node_pool answers with the pool's sizes and which of them hosts each serving preset; a preset no size hosts is a warning (agent-platform#502) cluster-manager#27 → cluster-manager 0.6.0, live on gazelle 18:10Z. Read-only proof as a person through muster — create_node_pool {cluster: gazelle, name: proof502, accelerator: nvidia-l4, sizes: [xlarge], dryRun: true} — answered sizes: [g6.xlarge: usableVcpu 3, usableMemoryGiB 11.9], presetFit over the nine presets the (still 4.28.8-pinned) slice publishes, and two warnings: serving preset qwen3-4b-instruct fits no size of pool proof502: requests 4 vCPU / 16 GiB; xlarge leaves a predictor 3 vCPU / 11.9 GiB after the node's kubelet reservations and daemonsets — 2xlarge (8 vCPU / 32 GiB) would host it … (the same for qwen3-8b-fp8); the seven 128 GB presets got a GPU-memory reason and no warning; sizes: [xlarge, xlage] was refused naming the g6 sizes.
Problem
The small serving preset
qwen3-4b-instruct(the "one g6.xlarge" preset of bumblebee-plans#46 D10) did not fit the smallest L4 instance. On gazelle, with poolgpu-l4(accelerator: nvidia-l4, sizes: [xlarge], Karpenter NodePoolg6×xlarge), the predictor the llmisvc controller composed from the preset requestedcpu: 4, memory: 16Gi(limits 8 / 24Gi); Karpenter refused to launch a node for it for ten minutes:A
g6.xlargehas 4 vCPU and 16 GiB; the pool had to be widened to2xlarge(8 vCPU, 32 GiB, ~50 % more per hour) before a node came (giantswarm/giantswarm#37714). Neithercheck_fitnor the portal's Add GPU node pool dialog warned that the chosen size cannot host the chosen preset.Root cause
The preset's requests were sized to the GPU alone, not to the node. A Giant Swarm node of the
g6.xlargeshape reports 3.4 vCPU / 13.4 GiB allocatable (the hypervisor's ~5 % of the memory, the kubelet's 0.6 vCPU / ~1.8 GiB), and the DaemonSets that follow a GPU pool's taint (Cilium, the exporters, Alloy, the DNS cache, the GPU operator's operands) request ~0.4 vCPU / ~1.5 GiB more — Karpenter's4403m/18788310351is exactly the preset's 4 vCPU / 16 GiB plus those. So the smallest L4 instance leaves a predictor about 3 vCPU / 11.9 GiB, and 4 / 16Gi could never be placed.qwen3-8b-fp8, the other L4 preset, carried the same requests. No tool knew a pool's instance shapes, so nothing could say so before Karpenter did.Decision and fix
Both halves, sized to the node model above:
g6.xlarge— fix(connectivity): the two L4 presets fit the smallest L4 instance (g6.xlarge) — requests 2 vCPU / 10 GiB (#502) #503:qwen3-4b-instructandqwen3-8b-fp8request 2 vCPU / 10 GiB, limits 4 vCPU / 12 GiB. The predictor's host memory is the runtime and the weights passing through the page cache (the KV cache lives on the GPU; vLLM V1 has no CPU swap), so this covers an 8–9 GiB checkpoint. Each description names the instance it is sized for;tests/verify-serving-slice.pyholds every L4 preset's requests within what ag6.xlargeleaves (4 - 1.0vCPU,16 * 0.95 - 3.3GiB); the README's presets paragraph states the budget an installation's own L4 preset should stay within. NominInstanceSizeschema key: the presets fit the smallest instance of their accelerator instead.create_node_poolrefusing a size the family does not have, and its answer carryingsizes,presetFit(the serving presets published on the cluster, each with the smallest size that hosts it or why none does) andwarnings(a preset the accelerator could serve but no size of the pool hosts — its predictor would sit Pending while Karpenter refuses every size). A first create that brings the slice release sees no preset yet and says so; adryRunre-run judges them.The
check_fithalf is filed and sequenced, since the fit check is what a person asks at load time: giantswarm/model-manager#97 (the kserve backend document'sgpuPoolblock gains the pool's instance shapes;check_fitat a pool's scale-from-zero judges the preset's requests and GPU memory against them instead of answering "unverified";load_modelrefuses a preset no size hosts) and giantswarm/cluster-manager#26 (cluster-manager writes the shapes into the document once model-manager declares the field). Both are sub-issues of giantswarm/giantswarm#37639.Acceptance criteria
qwen3-4b-instruct(andqwen3-8b-fp8) schedule onto ag6.xlarge: requests 2 vCPU / 10 GiB fit the 3 vCPU / 11.9 GiB a Giant Swarm node of that shape leaves a predictor after daemonsets; the descriptions name the instance (fix(connectivity): the two L4 presets fit the smallest L4 instance (g6.xlarge) — requests 2 vCPU / 10 GiB (#502) #503).create_node_pool(feat: create_node_pool answers with the pool's sizes and which of them hosts each serving preset; a preset no size hosts is a warning (agent-platform#502) cluster-manager#27) lists the sizes with what each leaves a predictor and warns per preset no size hosts; a size the family lacks is refused.check_fit/load_modeljudge the same at a pool's scale-from-zero — check_fit: at a GPU pool's scale-from-zero, judge the preset's CPU/memory requests and GPU memory against the pool's instance shapes instead of answering unverified model-manager#97, create_node_pool: publish the pool's instance shapes in the kserve backend document (spec.kserve.gpuPool.instances) for model-manager's fit check at scale-from-zero cluster-manager#26 (follow-ups).Plan bumblebee-plans#46 (D5/D10), epic giantswarm/giantswarm#37639.