Skip to content

Commit ddd8135

Browse files
committed
feat(recipes): add GKE GB200 (A4X) recipe with NVLS NCCL validation
Add the gb200-gke-cos-{training,training-kubeflow,training-slurm, inference,inference-dynamo} recipe leaves, covering GB200 (A4X) on GKE with COS. New gke-gb200-rdma component wires the NCCL gIB ARM64 plugin installer needed for GPUDirect-RDMA over RoCE, plus its health check and BOM/tuning docs. The GKE multi-networking objects (GKENetworkParamSet/Network: gvnic-1, rdma-0..rdma-3) are provisioned with the cluster before the node pool exists, not by this component: AICR treats them as a prerequisite and validates all 5 objects, including deviceMode and parametersRef linkage, via health check. GB200 on GKE is NVLS-only: MNNVL across the A4X nodes' IMEX domain is the fabric that actually carries all-reduce traffic, so nccl-all-reduce-bw-nvls (not the plain check) is wired into the training leaves' performance phase, backed by a new runtime-nvls.yaml TrainingRuntime template with IMEX ComputeDomain wiring. GPU NIC discovery in the NCCL validator is skipped for this accelerator/service pair since it uses the gke-gb200-rdma Network CRs instead of the TCPXO gpu-nic-* fabric. GB200 already has a Kubeflow leaf overlay on EKS and OKE; adds the same kubeflow-trainer component here so GKE isn't the only GB200 platform missing one, giving robust-controller conformance a supported operator to validate instead of always skipping. Also adds a gb200-gke-cos-inference-dynamo leaf (grove + dynamo-platform, DRA-gated to Kubernetes 1.34+), mirroring the GB200 EKS/OKE Dynamo overlays' performance-gate thresholds until a GKE-specific baseline is published. This turns the bare gb200-gke-cos-inference overlay from a leaf into a base shared by both the plain and Dynamo inference leaves, the same base/platform-variant pattern already used above for training/training-kubeflow. And a gb200-gke-cos-training-slurm leaf (Slinky operator + a Slinky-managed Slurm cluster), mirroring gb200-eks-ubuntu-training-slurm's GPU GRES, task isolation, and NVLS/IMEX ComputeDomain wiring for the same 4-GPU-per-node accelerator shape. Unlike the Kubeflow Trainer/JobSet controllers above, Slinky's controller/restapi/nodeset Deployments already go through AICR's ordinary nodeScheduling tolerationPaths, so this leaf needs no Trainer-style toleration workaround. Floor calibrated on a4x-highgpu-4g (4x GB200/node): 2-node/8-GPU all_reduce_perf measured 281.936 GB/s avg bus bandwidth. Validated on a live A4X cluster across conformance, deployment, and NVLS performance for the training and training-kubeflow leaves. gb200-gke-cos-inference-dynamo is validated across all three phases on the same cluster: deployment, conformance, and performance (103,971 tokens/sec throughput, 1388.55ms TTFT p99). gb200-gke-cos-training-slurm is validated through deployment and conformance, including the GB200-specific slinky-slurm-imex-channel health check; its NVLS performance phase has not yet been run. Signed evidence bundles for both (Sigstore/Rekor, keyless OIDC) are pushed to ghcr.io/mikecook/aicr-evidence with pointers committed under recipes/evidence/, and the signer is added to the community allowlist. Signed-off-by: Mike Cook <micook@nvidia.com>
1 parent cd3d50c commit ddd8135

35 files changed

Lines changed: 2267 additions & 15 deletions

File tree

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ For pipelines and platforms that call AICR programmatically or host
4646
| Add or modify recipe metadata | [Recipe Development](integrator/recipe-development.md) |
4747
| Verify artifacts (SLSA, SBOM, attestations) | [Supply Chain Verification](integrator/supply-chain-verification.md) |
4848
| Ship custom validators via `--data` | [Validator Extension](integrator/validator-extension.md) |
49-
| Cloud-specific GPU setup | [AKS](integrator/aks-gpu-setup.md), [GKE](integrator/gke-gpu-setup.md), [EKS networking](integrator/eks-dynamo-networking.md), [GKE networking](integrator/gke-tcpxo-networking.md), [Talos](integrator/talos-integration.md) |
49+
| Cloud-specific GPU setup | [AKS](integrator/aks-gpu-setup.md), [GKE](integrator/gke-gpu-setup.md), [EKS networking](integrator/eks-dynamo-networking.md), [GKE TCPXO networking](integrator/gke-tcpxo-networking.md), [GKE GB200 networking](integrator/gke-gb200-networking.md), [Talos](integrator/talos-integration.md) |
5050

5151
### Contributor Guide
5252

docs/contributor/validator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ default** (`Qwen/Qwen3-8B` at 256/GPU). A non-positive / non-integer
804804
| `AICR_INFERENCE_PERF_WORKLOAD_READY_TIMEOUT` | `10m` | Wait for the `DynamoGraphDeployment` to become ready (image pull + model load + worker health). Large models load slower — raise this **and** the catalog entry's `timeout` in tandem, or the parent deadline caps it. |
805805
| `AICR_INFERENCE_PERF_HEALTH_TIMEOUT` | `5m` | Wait for the endpoint to serve a real chat-completion *after* the workload reports Ready. Concurrent first-load from one RWO cache PVC can push first-serve past 5m; raise it (bounded by the catalog `timeout`). |
806806
| `AICR_INFERENCE_PERF_MODEL_CACHE_SIZE` | `100Gi` (on) | The PVC-backed model-weights cache is **on by default**. Set a different K8s quantity to resize, or a disable sentinel (`off`/`0`/`none`/`disabled`) to turn it off and download from HF directly. |
807-
| `AICR_INFERENCE_PERF_MODEL_CACHE_STORAGE_CLASS` | cluster default | StorageClass for the cache PVC. On a cluster with **no default SC and no value here**, the check **fails fast** with guidance rather than leaving the PVC `Pending` until timeout. AICR-deployed EKS gets a default `gp3` SC from `aws-ebs-csi-driver`; GKE has `standard-rwo`. |
807+
| `AICR_INFERENCE_PERF_MODEL_CACHE_STORAGE_CLASS` | cluster default | StorageClass for the cache PVC. On a cluster with **no default SC and no value here**, the check **fails fast** with guidance rather than leaving the PVC `Pending` until timeout. AICR-deployed EKS gets a default `gp3` SC from `aws-ebs-csi-driver`; GKE has `standard-rwo`, **except A4X/GB200 nodes**, which reject `standard-rwo`'s `pd-balanced` disks and need a Hyperdisk-backed class (see [GKE GB200 Storage Prerequisites](../integrator/gke-gb200-networking.md#storage-prerequisites)). |
808808
| `AICR_INFERENCE_PERF_MODEL_CACHE_POPULATE_TIMEOUT` | `13m` | Wait for the one-time model-cache populate Job (cold image pull + first-ever Hugging Face download into the PVC). Separate from — and larger than — `AICR_INFERENCE_PERF_WORKLOAD_READY_TIMEOUT` because the populate Job pays a cold pull *and* a multi-GB download; provide the optional HF-token secret to remove anonymous-download throttling. Raise it (and the catalog `timeout`) for very large models. **Migration:** the cache-populate wait no longer honors `AICR_INFERENCE_PERF_WORKLOAD_READY_TIMEOUT` (which now bounds only the DynamoGraphDeployment readiness wait) — set this knob instead to widen the populate budget. |
809809

810810
For gated models, or to lift Hugging Face rate limits on large downloads,

docs/index.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ navigation:
7575
path: integrator/eks-dynamo-networking.md
7676
- page: GKE TCPXO Networking
7777
path: integrator/gke-tcpxo-networking.md
78+
- page: GKE GB200 Networking
79+
path: integrator/gke-gb200-networking.md
7880
- page: OpenShift Deployment
7981
path: integrator/openshift.md
8082
- page: Talos Integration

docs/integrator/components/nodewright.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ The table below is generated from the recipes by `make tuning-docs` — **do not
8787
| eks | rtx-pro-6000 | generic | - | nvidia-tuned 0.3.2 |
8888
| gke | a100 | h100 | - | nvidia-tuning-gke 0.1.2 |
8989
| gke | b200 | - | - | nvidia-tuning-gke 0.1.2 |
90+
| gke | gb200 | - | - | nvidia-tuning-gke 0.1.2 |
9091
| gke | h100 | - | - | nvidia-tuning-gke 0.1.2 |
9192

9293
{/* END AICR-TUNING */}
Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
# GKE GB200 (A4X) Networking Prerequisites
2+
3+
For the **GB200 GKE COS** recipes (`gb200-gke-cos-training`,
4+
`gb200-gke-cos-training-kubeflow`, `gb200-gke-cos-training-slurm`,
5+
`gb200-gke-cos-inference`, and `gb200-gke-cos-inference-dynamo`, all on
6+
`a4x-highgpu-4g` nodes),
7+
GPUDirect-RDMA over RoCE enables high-speed inter-node GPU communication on
8+
GKE. The recipe's NCCL workloads set `NCCL_NET=gIB` explicitly (see
9+
`recipes/components/gke-gb200-rdma/manifests/nccl-gib-installer-arm64.yaml`)
10+
rather than letting NCCL auto-select a plugin, so a missing or
11+
misconfigured RDMA fabric doesn't silently fall back to a slower network
12+
path: it fails outright.
13+
14+
GPUDirect RDMA on `a4x-highgpu-4g` is also incompatible with NCCL Fast
15+
Socket and the GPUDirect TCPX/TCPXO plugin (see
16+
[GKE TCPXO Networking](gke-tcpxo-networking.md) for that alternative,
17+
non-RDMA path); don't enable either on a cluster that uses RDMA.
18+
19+
## Infrastructure Prerequisites
20+
21+
GKE clusters must have multi-networking configured before deploying AICR bundles:
22+
23+
- Multi-networking enabled (1 gVNIC + 4 RDMA NICs per `a4x-highgpu-4g` node)
24+
- `Network` + `GKENetworkParamSet` CRs for the gVNIC and 4 RDMA NICs (cluster-specific
25+
VPC/subnet values, but fixed object names; see below, not managed by AICR)
26+
- `nccl-rdma-installer` DaemonSet on GPU nodes (included in the AICR bundle)
27+
- Each GPUDirect-RDMA workload Pod must request all 4 GPUs and use all 4 RDMA NICs
28+
on a single node; RDMA can't be shared between Pods on the same node (a GKE
29+
`a4x-highgpu-4g` constraint, not an AICR-specific one). AICR's own recipes
30+
already request whole nodes this way; a custom workload built against this
31+
component must too.
32+
33+
The `nccl-rdma-installer` DaemonSet ships in the AICR bundle. The `Network`/
34+
`GKENetworkParamSet` CRs and the multi-networking/VPC fabric underneath them
35+
are **cluster provisioning**: AICR's `gke-gb200-rdma` health check detects
36+
them but does not create them.
37+
38+
### Provisioning multi-networking
39+
40+
These steps are ordered, following Google's
41+
[A4X custom setup guide](https://docs.cloud.google.com/ai-hypercomputer/docs/create/gke-ai-hypercompute-custom-a4x):
42+
43+
1. **Create the VPCs and subnets**: two VPCs in the cluster's region, one for
44+
the gVNIC (with one subnet) and one RDMA VPC (with four subnets, one per
45+
RDMA NIC); five subnets total across the two VPCs, not five separate VPCs.
46+
2. **Create the cluster** with multi-networking enabled (HIPPO's `GKECluster` CR
47+
does this via `spec.networks.managed.gb200NetworkStrategy`).
48+
3. **Create the GPU node pool** on an `a4x-highgpu-4g` machine type, attaching
49+
the five network/subnet pairs as `additionalNodeNetworkConfigs` (the RDMA
50+
VPC repeated across its four subnets, plus the gVNIC VPC/subnet).
51+
4. **Apply the `Network` and `GKENetworkParamSet` CRs**: one pair per NIC,
52+
binding each additional node network into the cluster so pods can reference
53+
it. Unlike TCPXO (see [GKE TCPXO Networking](gke-tcpxo-networking.md)), the
54+
**object names are fixed, not cluster-specific**: `gvnic-1` for the gVNIC and
55+
`rdma-0` through `rdma-3` for the RDMA NICs. Only the `vpc`/`vpcSubnet` fields
56+
inside each `GKENetworkParamSet` vary per cluster (they name the VPC/subnet
57+
your cluster actually has):
58+
59+
```yaml
60+
apiVersion: networking.gke.io/v1
61+
kind: GKENetworkParamSet
62+
metadata:
63+
name: gvnic-1
64+
spec:
65+
vpc: "PREFIX-gvnic"
66+
vpcSubnet: "PREFIX-gvnic"
67+
deviceMode: NetDevice
68+
---
69+
apiVersion: networking.gke.io/v1
70+
kind: Network
71+
metadata:
72+
name: gvnic-1
73+
spec:
74+
type: "Device"
75+
parametersRef:
76+
group: networking.gke.io
77+
kind: GKENetworkParamSet
78+
name: gvnic-1
79+
```
80+
81+
Repeat for `rdma-0` through `rdma-3`, pointing `vpc` at the single RDMA VPC
82+
from step 1 (the same value for all four) and `vpcSubnet` at that VPC's
83+
four subnets (`PREFIX-rdma-sub-0` through `PREFIX-rdma-sub-3`, or whatever
84+
names your subnets were given in step 1, with `PREFIX` replaced by your
85+
own), and set **`deviceMode: RDMA`** on all four, not `NetDevice` (that
86+
value is only correct for `gvnic-1` above).
87+
88+
> **The fixed naming is a requirement, not a convention.** AICR's
89+
> `checks/gke-gb200-rdma/health-check.yaml` asserts these five objects by exact
90+
> name (`gvnic-1`, `rdma-0`..`rdma-3`), including `spec.deviceMode` and
91+
> `spec.parametersRef` linkage. A cluster provisioned with different `Network`
92+
> names passes Google's own setup guide but fails this check; rename to match
93+
> before running `aicr validate`.
94+
95+
AICR installs the `nccl-rdma-installer` DaemonSet and detects the CRs; it does
96+
not provision the networking itself. These steps are a summary of the
97+
prerequisite AICR depends on, not a complete provisioning runbook; follow
98+
Google's guide above for the full procedure, including firewall rules and
99+
supported GKE version floors.
100+
101+
Separately from GKE's own networking version floor, all AICR GB200 GKE
102+
recipes (including `gb200-gke-cos-training-slurm`, which inherits it from
103+
`gb200-gke-cos-training`) enforce `K8s.server.version >= 1.34`: NVLS
104+
provisions the IMEX channel through a DRA `ComputeDomain`, which requires
105+
the GA `resource.k8s.io/v1` API. `aicr validate` fails readiness on an
106+
older control plane with this constraint by name.
107+
108+
### Verifying
109+
110+
```shell
111+
kubectl get network.networking.gke.io \
112+
-o custom-columns='NAME:.metadata.name,PARAMETERS-REF:.spec.parametersRef.name'
113+
kubectl get gkenetworkparamset.networking.gke.io \
114+
-o custom-columns='NAME:.metadata.name,DEVICE-MODE:.spec.deviceMode'
115+
```
116+
117+
Expect `gvnic-1` and `rdma-0` through `rdma-3` (the five prerequisite
118+
`Network`s from step 4), each bound to its `GKENetworkParamSet` via
119+
`spec.parametersRef` (shown in the `PARAMETERS-REF` column above). Fewer
120+
than five, or a `GKENetworkParamSet` with the wrong `DEVICE-MODE`, means
121+
the prerequisite is incomplete or misconfigured; `aicr validate` (via the
122+
`gke-gb200-rdma` health check) reports the shortfall by name.
123+
124+
You'll also see a `default` network/`GKENetworkParamSet` pair in the same
125+
output; that one is GKE-managed (created automatically once
126+
multi-networking is enabled), not part of this prerequisite, and isn't
127+
checked by name.
128+
129+
## Driver Installer
130+
131+
`a4x-highgpu-4g` recipes generated with `--profile gpuStack=driver-installer`
132+
(see [GKE GPU Setup](gke-gpu-setup.md#alternative-let-gpu-operator-manage-the-device-plugin))
133+
need Google's standalone `nvidia-driver-installer` DaemonSet applied before
134+
GPU workloads can schedule; this presumes the node-pool prerequisite
135+
(pools created with `gpu-driver-version=disabled` plus the
136+
`gke-no-default-nvidia-gpu-device-plugin=true` label) is already in place.
137+
The manifest below is Google's generic upstream COS driver-installer
138+
DaemonSet (`daemonset-preloaded.yaml`, including its `partition-gpus`
139+
init container, Google's `nvidia-partition-gpu` MIG tool, carried over
140+
unchanged and a no-op here since this recipe allocates whole GPUs per
141+
node rather than configuring MIG), adapted two ways for GB200: the
142+
`nodeAffinity` also requires the `gke-no-default-nvidia-gpu-device-plugin`
143+
label (the `driver-installer` profile's node-pool prerequisite, which the
144+
plain upstream manifest doesn't check), and the install step pins an
145+
explicit
146+
[COS-qualified driver version](https://cloud.google.com/kubernetes-engine/docs/how-to/gpus#cos)
147+
instead of letting `cos-gpu-installer` pick its own default:
148+
149+
```yaml
150+
apiVersion: apps/v1
151+
kind: DaemonSet
152+
metadata:
153+
name: nvidia-driver-installer
154+
namespace: kube-system
155+
labels:
156+
k8s-app: nvidia-driver-installer
157+
spec:
158+
selector:
159+
matchLabels:
160+
k8s-app: nvidia-driver-installer
161+
updateStrategy:
162+
type: RollingUpdate
163+
template:
164+
metadata:
165+
labels:
166+
name: nvidia-driver-installer
167+
k8s-app: nvidia-driver-installer
168+
spec:
169+
priorityClassName: system-node-critical
170+
affinity:
171+
nodeAffinity:
172+
requiredDuringSchedulingIgnoredDuringExecution:
173+
nodeSelectorTerms:
174+
- matchExpressions:
175+
- key: cloud.google.com/gke-accelerator
176+
operator: Exists
177+
- key: cloud.google.com/gke-gpu-driver-version
178+
operator: DoesNotExist
179+
- key: gke-no-default-nvidia-gpu-device-plugin
180+
operator: In
181+
values: ["true"]
182+
- key: cloud.google.com/gke-confidential-nodes-instance-type
183+
operator: DoesNotExist
184+
tolerations:
185+
- operator: Exists
186+
hostNetwork: true
187+
hostPID: true
188+
volumes:
189+
- name: dev
190+
hostPath:
191+
path: /dev
192+
- name: vulkan-icd-mount
193+
hostPath:
194+
path: /home/kubernetes/bin/nvidia/vulkan/icd.d
195+
- name: nvidia-install-dir-host
196+
hostPath:
197+
path: /home/kubernetes/bin/nvidia
198+
- name: root-mount
199+
hostPath:
200+
path: /
201+
- name: cos-tools
202+
hostPath:
203+
path: /var/lib/cos-tools
204+
- name: nvidia-config
205+
hostPath:
206+
path: /etc/nvidia
207+
initContainers:
208+
- image: "cos-nvidia-installer:fixed"
209+
imagePullPolicy: Never
210+
name: nvidia-driver-installer
211+
resources:
212+
requests:
213+
cpu: 150m
214+
securityContext:
215+
privileged: true
216+
env:
217+
- name: NVIDIA_INSTALL_DIR_HOST
218+
value: /home/kubernetes/bin/nvidia
219+
- name: NVIDIA_INSTALL_DIR_CONTAINER
220+
value: /usr/local/nvidia
221+
- name: VULKAN_ICD_DIR_HOST
222+
value: /home/kubernetes/bin/nvidia/vulkan/icd.d
223+
- name: VULKAN_ICD_DIR_CONTAINER
224+
value: /etc/vulkan/icd.d
225+
- name: ROOT_MOUNT_DIR
226+
value: /root
227+
- name: COS_TOOLS_DIR_HOST
228+
value: /var/lib/cos-tools
229+
- name: COS_TOOLS_DIR_CONTAINER
230+
value: /build/cos-tools
231+
volumeMounts:
232+
- name: nvidia-install-dir-host
233+
mountPath: /usr/local/nvidia
234+
- name: vulkan-icd-mount
235+
mountPath: /etc/vulkan/icd.d
236+
- name: dev
237+
mountPath: /dev
238+
- name: root-mount
239+
mountPath: /root
240+
- name: cos-tools
241+
mountPath: /build/cos-tools
242+
command:
243+
- bash
244+
- -c
245+
- |
246+
echo "Checking for existing GPU driver modules"
247+
if lsmod | grep nvidia; then
248+
echo "GPU driver is already installed, skipping installation"
249+
exit 0
250+
else
251+
echo "No GPU driver module detected, installing 580.126.20"
252+
/cos-gpu-installer install --version=580.126.20 || exit 1
253+
chmod 755 /root/home/kubernetes/bin/nvidia
254+
fi
255+
- image: "gcr.io/gke-release/nvidia-partition-gpu@sha256:de12f85ebfb4fb6c1893cd30c23aab662a72fa0448f97ef74fccb82d7522ef17"
256+
name: partition-gpus
257+
env:
258+
- name: LD_LIBRARY_PATH
259+
value: /usr/local/nvidia/lib64
260+
resources:
261+
requests:
262+
cpu: 150m
263+
securityContext:
264+
privileged: true
265+
volumeMounts:
266+
- name: nvidia-install-dir-host
267+
mountPath: /usr/local/nvidia
268+
- name: dev
269+
mountPath: /dev
270+
- name: nvidia-config
271+
mountPath: /etc/nvidia
272+
containers:
273+
- image: "gke.gcr.io/pause:3.8@sha256:880e63f94b145e46f1b1082bb71b85e21f16b99b180b9996407d61240ceb9830"
274+
name: pause
275+
```
276+
277+
Re-pin the driver version (`580.126.20` above) and the `partition-gpus` image
278+
digest to whatever your GKE version's COS driver table and Google's release
279+
notes currently list; both drift over time and are not managed by AICR.
280+
281+
### Validate before deploying the rest of the bundle
282+
283+
Once the driver installer and the RDMA `Network`/`GKENetworkParamSet` CRs
284+
are applied, confirm both before running the bundle's full `deploy.sh`:
285+
286+
```shell
287+
aicr validate --recipe recipe.yaml --phase deployment --fail-fast
288+
```
289+
290+
`check-nvidia-smi` and the `gke-gb200-rdma` health check only need the GPU
291+
nodes to exist, not the rest of the bundle deployed, so this catches a
292+
missing driver or un-applied CRs in seconds instead of surfacing them deep
293+
into a 20-component deploy, for example as a DRA-driver pod stuck
294+
`Init:0/1` waiting on a driver that was never installed. `--fail-fast`
295+
stops there instead of continuing on to conformance and performance (see
296+
[Validation](../user/validation.md)).
297+
298+
## Storage Prerequisites
299+
300+
`a4x-highgpu-4g` nodes can't attach Persistent Disk at all (regional or
301+
zonal, any type, including `pd-balanced`); only Hyperdisk. On a stock GKE
302+
Standard cluster the default StorageClass is `standard-rwo`
303+
(`pd.csi.storage.gke.io`, `pd-balanced`), but "default" isn't inherent to
304+
GKE Standard itself: a cluster admin can repoint the
305+
`storageclass.kubernetes.io/is-default-class` annotation to any
306+
StorageClass. Run `kubectl get storageclass` first and check which one is
307+
annotated `(default)`, its `PROVISIONER`, and (via `kubectl get
308+
storageclass -o yaml`) its `parameters.type`; don't assume it's
309+
`standard-rwo`/`pd-balanced`. Any PVC scheduled onto a GB200 node with no
310+
`storageClassName` set (which binds it to the cluster default) fails
311+
this way unless that default's `parameters.type` is already
312+
Hyperdisk-backed: `pd-balanced disk type cannot be used by
313+
a4x-highgpu-4g machine type` (or the equivalent for whatever `pd-*` type
314+
the default actually provisions).
315+
316+
This includes the `inference-perf` validator's model-weights cache PVC
317+
when `AICR_INFERENCE_PERF_MODEL_CACHE_STORAGE_CLASS` (see
318+
[Validation](../user/validation.md)) is left unset, it then falls back
319+
to the cluster default too. Set that variable to name a Hyperdisk-backed
320+
StorageClass explicitly (for example `hyperdisk-balanced`, applied below)
321+
and the cache PVC uses it directly via `storageClassName`, independent of
322+
whatever the cluster default resolves to.
323+
324+
If the cluster default isn't already Hyperdisk-backed, apply one. Like
325+
the RDMA CRs above, this is a cluster prerequisite AICR does not
326+
provision:
327+
328+
```yaml
329+
apiVersion: storage.k8s.io/v1
330+
kind: StorageClass
331+
metadata:
332+
name: hyperdisk-balanced
333+
provisioner: pd.csi.storage.gke.io
334+
parameters:
335+
type: hyperdisk-balanced
336+
volumeBindingMode: WaitForFirstConsumer
337+
allowVolumeExpansion: true
338+
```
339+
340+
Apply it once per cluster, then point the validator's model cache at it via
341+
an `AICR_INFERENCE_PERF_MODEL_CACHE_STORAGE_CLASS=hyperdisk-balanced` entry
342+
on the `inference-perf` catalog entry's `env` (or a catalog overlay in the
343+
`aicr validate --data <dir>` directory).
344+
345+
## Running the NCCL Benchmark
346+
347+
The GB200 GKE training recipe (`gb200-gke-cos-training`) selects the
348+
NVLS-variant performance check (`nccl-all-reduce-bw-nvls`): MNNVL across the
349+
A4X nodes' IMEX domain is the fabric that carries all-reduce traffic; gIB is the
350+
transport driver underneath, not the NCCL algorithm itself. Run it via:
351+
352+
```shell
353+
aicr validate --recipe recipes/overlays/gb200-gke-cos-training.yaml \
354+
--phase performance
355+
```
356+
357+
## References
358+
359+
- [GKE A4X custom setup guide](https://docs.cloud.google.com/ai-hypercomputer/docs/create/gke-ai-hypercompute-custom-a4x)
360+
- [Component Catalog](../user/component-catalog.md)
361+
- [Validation readiness gate](../user/validation.md)
362+
- [GKE TCPXO Networking](gke-tcpxo-networking.md)

0 commit comments

Comments
 (0)