Repository navigation
Conversation
…pdate inferenceClusters, servingStack Signed-off-by: Christopher Haar <christopher.haar@upbound.io>
Signed-off-by: Christopher Haar <christopher.haar@upbound.io>
Signed-off-by: Christopher Haar <christopher.haar@upbound.io>
Signed-off-by: Christopher Haar <christopher.haar@upbound.io>
There was a problem hiding this comment.
I think this needs another look at the design before it's close. The draDrivers mechanism matches design/multi-accelerator.md, but the CPU pools built on it raise questions the design didn't settle.
The open points are the source of a pool's role, dra-driver-cpu's grouped mode on the GKE, AKS and Nebius default versions, and CPU requests for a dra.cpu claim. Apart from the design, the new UnsupportedDevices gate looks like it could delete running clusters, which is the most urgent question here. I've held back other test and style points until the design settles.
The commit messages need bodies and CONTRIBUTING's subject format, without typed prefixes, and the Vale fixup commit should fold into the commit it fixes.
| # label and taint composed by compose-gke-cluster. | ||
| node_pool = gkev1alpha1.NodePool( | ||
| name=pool.name, | ||
| role="GPU" if prov.accelerator else "CPU", |
There was a problem hiding this comment.
Should a pool's role follow the drivers its class claims, rather than whether it sets accelerator? The design says taints follow the stack, but here accelerator alone decides. An EKS class with a gpu.nvidia.com device and no accelerator becomes a CPU pool with a standard AMI and the CPU taint, while schedulablePools still advertises its GPUs. A class with accelerator that claims dra.cpu misses the label dra-driver-cpu selects on. Its claims never allocate. Could we derive the role from the claimed drivers, or tie the two with CEL? (Here and in the other five clouds.)
| composition from the claim: DRA devices of the cluster's | ||
| referenced InferenceClasses. A component tagged with a | ||
| driver installs only when that driver is listed; untagged | ||
| components always install. When the field is absent no |
There was a problem hiding this comment.
Do we need the absent-means-unfiltered case? compose-inference-cluster always stamps draDrivers, so the None path only serves ServingStacks from before this PR, and AGENTS.md rules out compatibility paths like that. It also gives unset and empty different meanings. What if absent meant no drivers, and the None branches in join and compose-serving-stack's fn.py went along with the "When the field is absent" sentence?
| # tolerate nothing, which strands the daemonsets off the very nodes | ||
| # they serve. | ||
| Chart( | ||
| key="amd-gpu-operator", |
There was a problem hiding this comment.
Should the existing-cluster requirements in docs/content/platform/inference-cluster.md cover the new stacks? Besides covering only the NVIDIA driver and nvidia.com/gpu taint, the page says Modelplane doesn't install a GPU exporter, though the AMD operator now brings device-metrics-exporter. AMD pools need the amdgpu kernel driver and mustn't already run AMD's operator, which would clash with this one. CPU pools need the modelplane.ai/cpu=true label dra-driver-cpu's nodeSelector reads. telemetry.md still says "An existing cluster provides its own" exporter too.
Description of your changes
Design: modelplaneai#432
The serving stack installed NVIDIA's device stack on every cluster and no other vendor's anywhere: every component list pinned the NVIDIA operator or DRA driver unconditionally, nothing checked that the devices a class declares match the stack its cluster gets, and a pool without a GPU couldn't be provisioned at all.
This implements the multi-accelerator design. The cluster composition collects the DRA drivers claimed across a cluster's referenced classes (
claim: DRAonly; Synthetic devices describe placement, not a stack) ontoServingStack spec.draDrivers; components carry the drivers they serve asdra_driverstags - hand-written in place, fail-closed throughALLOWfor the generated clouds and the join installs a tagged component only when one of its drivers is claimed. The supported-drivers table is derived from the tags (plus EKS's declared-externaldra.net), mirrored by hand incompose-inference-cluster, which gates
ClusterReady=False / UnsupportedDevicesbefore anything is provisioned.On top of the mechanism:
CPU inference (Docs: Add design for CPU inference class support modelplaneai/modelplane#509, rebased onto the mechanism): dra-driver-cpu is one chart tagged
dra.cpu, pinned once in common.py for every cloud including Existing, with scoped tolerations,acceleratorbecomes optional in every provisioning block; a class without one composes aCPU-role pool with themodelplane.ai/cpulabel and taint on all six cloudsstatus.gpuPoolsbecomesstatus.schedulablePools: nothing in it was GPU-specific.AMD on BYO clusters: the AMD GPU operator (DRA mode, driver management off) is pinned on the Existing list tagged
gpu.amd.com- the pin validated on 8x MI325X bare metal in Provision Vultr bare metal servers into k3s inference clusters, composing multi-vendor GPU serving stacks modelplaneai/modelplane#434, which rebases onto this mechanism. NFD carries both GPU drivers' tags there; engine pods tolerate the per-driver taint list (the pool nodeSelector is what places them).The cloud e2e legs shape one KWOK pool per claimed device stack, an NVIDIA and a CPU pool on every leg, an AMD pool on Existing and stamp
spec.draDrivers, so the placement and toleration audits now check the filter itself: each stack must reach its own pool and stay off the othersAMD GPU metrics: the collector's GPU job also discovers the AMD operator's device-metrics-exporter (label
metrics-exporter, portexporter-port), and amodelplane-gpu-amdbuiltin maps its series onto the samemodelplane_gpu_*names - VRAM MiB to bytes, activity percent to ratio, and energy through a newMicrojoulesfromUnit.modelplane_gpu_tensor_active_ratiostays NVIDIA-only.Two recipes: Qwen2.5-0.5B on a single MI325X on a bring-your-own cluster and Qwen2.5-0.5B on CPUs alone on a Civo
g4p.kube.mediumpool with vLLM's CPU image.The recipe site needs two follow-ups in its repo: the
gpusdata key the ayouts read is nowaccelerators, andpartials/icons.htmlneedsbrand-amd,brand-civoandcpusymbols. https://github.com/modelplaneai/docs-site/blob/main/themes/geekboot/layouts/partials/icons.html -> modelplaneai/docs-site#5I have:
nix flake check(or./nix.sh flake check) and made sure it passes.git commit -s.