Skip to content

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

Description

@teemow

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 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:

  1. 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.
  2. 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.

Acceptance criteria

Plan bumblebee-plans#46 (D5/D10), epic giantswarm/giantswarm#37639.

Activity

  1. 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
  2. teemow commented on Sep 16, 2026

    @teemow
    MemberAuthor

    Shipped both halves (the description carries the decision and the fix); closed by #503's merge.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions