Repository navigation
Slurm on TPU: Add support for Slurm on TPU 7x - #6351
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces native support for Cloud TPU VMs (specifically the tpu7x-standard-4t family) within Slurm clusters managed by the Cluster Toolkit. By implementing a dedicated configuration generator for Slurm 26.05+ and leveraging GCE Managed Instance Groups combined with Workload Policies, the changes allow for the automated provisioning and teardown of TPU slices. The update includes robust support for both static and dynamic nodes, along with new blueprints and validation tests to ensure cluster stability and performance. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
81f7e91 to
3c12e14
Compare
|
/gemini review |
3c485d8 to
7b04481
Compare
c9fea61 to
989e69a
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces native support for GCE TPU compute nodes (such as TPU 7x) in Slurm 26.05 clusters, updating Terraform modules, Slurm configuration generators, and node scaling scripts (resume/suspend/sync) to handle TPU topologies and workload policies. Feedback on the changes highlights a critical missing import of the math module in util.py that would cause a runtime crash, a case-sensitivity issue when parsing accelerator topologies in Terraform, and potential resource leaks from silently ignoring HTTP 400 errors during TPU MIG deletion.
cdef509
into
GoogleCloudPlatform:develop
Add support for TPUs on Slurm (
tpu7x-standard-4t)Summary
Adds support for running Cloud TPU VMs as Slurm compute nodes through the
schedmd-slurm-gcp-v6-nodesetmodule. A TPU slice is declared like any other nodeset by settingmachine_typeandaccelerator_topology, and the cluster brings the nodes up, schedules jobs on them, and tears them down.TPU VMs are created as a GCE Managed Instance Group attached to a Workload Policy that pins the slice topology, so the VMs come up as one wired TPU slice instead of unrelated VMs.
Supports both static and dynamic (autoscaled) nodes (through
schedmd-slurm-gcp-v6-nodeset).Scope
schedmd-slurm-gcp-v6-nodeset-tpumodule is not touched. Existing deployments on it keep working.conf_v2605.py, used only on Slurm 26.05+. Older versions keep the existing generators.What's supported
tpu7x-standard-4t(4 chips per VM)Only machine types ending in
-4tare accepted. A TPU machine type that does not end in-4tfails atgcluster deploywith a clear error, before any VMs are created.Four preconditions added (three in the nodeset module, one in the partition module):
-4taccelerator_topology, andnode_count_staticmust be an integer multiple of the slice VM count (total_chips / 4)Usage
--layouttells Slurm the slice shape.How provisioning works
Chips, Cores, and Slice Sizing:
tpu7x-standard-4tVM has 4 physical TPU chips (Gres=tpu:tpu7x:4), where each dual-core chip exposes 2 TensorCores (8 VFIO devices/dev/vfio/devices/vfio0..7per VM).2x4x4= 32 chips) count physical chips (32 / 4 = 8 VMs per slice) socli_filter/tpucan validate that-Nmatches--layout. SettingConstrainDevices=noincgroup.confthen allows JAX to open all 8 VFIO TensorCore devices (vfio0..7).targetSizePolicy=BULK) attached to a regionalHIGH_THROUGHPUTWorkload Policy (acceleratorTopology). Ifnode_count_staticspans multiple slices (e.g., 16 VMs with2x4x4= 8 VMs/slice),resume.pychunks the nodes into two separate 8-VM MIGs ([0-7]and[8-15]) and registers each slice as a block incloud_topology.yaml(tpu-block-topo).Static vs. Dynamic Partitions:
node_count_static > 0): Nodes get a fixed topology feature (Feature=tpu7x_2x4x4) andPowerDownOnIdle=NO.slurmsync.pypowers up all static slices automatically at controller boot and keeps themidlebetween jobs.node_count_dynamic_max > 0): Nodes start powered down (idle~) withFeature=tpu_dynamicandPowerDownOnIdle=YES. When a job is submitted with--layout=tpu7x=<topology>,job_submit/tpupasses that topology toresume.pyviaRESUME_FILE, which provisions an on-demand MIG of that shape and deletes it as soon as the job finishes.Resiliency & Failure Handling
resume.py,mig_flex.py):POWER_DOWN_FORCErather than booting a partial slice.POWER_DOWN_FORCE.--layout(resume.py&mig_flex.py):--layoutor with an incompatible topology shape (e.g.,1x2x4ontpu7x-standard-4t),resume.pyextracts the human-readable GCE error message, delivers it directly to the activesrun/sbatchjob viascontrol notifyandadmincommentbefore node teardown, cancels the invalid job (scancel), and immediately resets the dynamic TPU nodes (state=down->state=power_down) back toidle~instead of hanging untilResumeTimeout.mig_flex.py):createInstancesfails after the MIG is created (e.g., Spot stockout),_resume_single_tpu_nodedeletes the MIG (_delete_tpu_mig) before re-raising, so a failed slice does not leave a MIG behind and block subsequent retries._resume_single_tpu_nodedetects and deletes any leftover stale MIG from previously cancelled or interrupted jobs instead of skipping provisioning.mig_flex.py,conf_v2605.py):slurm_nodes:cluster-nodeset-[0-7]) rather than a comma-separated list, to stay under GCE's 2048-character limit. Each slice gets a deterministicblock_uuidincloud_topology.yaml.Key Changes
Nodeset module
schedmd-slurm-gcp-v6-nodeset/main.tflocal.is_tpuandlocal.tpu_slice_vms(slice VM count derived from the 3D topology), used by the preconditions below.schedmd-slurm-gcp-v6-nodeset/outputs.tfaccelerator_topologyprecondition, which assumed a GPU machine type and failed for TPUs, and add the three TPU preconditions above.schedmd-slurm-gcp-v6-partition/main.tfSuspendTimeout(240s) /ResumeTimeout(600s) defaults to cover GCE TPU nodesets. Previously these applied only to legacynodeset_tpu. Non-TPU partitions keep 120s / 300s.schedmd-slurm-gcp-v6-partition/outputs.tfController scripts
conf_v2605.py(new)conf.pyutil.pyis_tpu_*helpers that gate every new path.mig_flex.pyresume.py,suspend.py,slurmsync.py--layoutwhen there is one, and clean up orphaned TPU MIGs and workload policies.slurm_files/main.tfconf_v2605.pyto the nodes.cleanup_compute.sh-wp-*Workload Policies and-copy-*Instance Templates duringgcluster destroy.Examples and docs
tpu7x-standard-4t/tpu7x-slurm-blueprint.yaml/home, login and controller. Also used by the integration test.tpu7x-slurm-deployment.yaml,README.mdexamples/machine-learning/README.mdTests
tests/test_util.py,test_conf.py,test_resume.pydaily-tests/builds/ml-tpu7x-onspot-slurm.yaml,tests/ml-tpu7x-onspot-slurm.yml2x2x1slice to keep it cheap: builds the image, deploys, validates, destroys.test-validation/test-tpu-slurm.ymlscontrol show config, static partition (tpu-block-topo,PowerDownOnIdle=NO), dynamic partition (PowerDownOnIdle=YES), node GRES and features, VFIO devices visible inside ansrunjob, on-demand MIG creation on the dynamic partition via--layout, power-down after the job, and a JAX job throughsbatch.test-infra-kueue/configs/kueue-setup.yaml,dummy-device-plugin.yamlVerification
Deployed an 8 node
2x4x4slice (32 chips) oftpu7x-standard-4t.The MIG and Workload Policy are created from the topology, from the controller
resume.log:The TPU plugins are loaded and the partition uses TPU block topology:
Generated config on the controller:
Nodes register with the GRES and the topology feature:
A distributed JAX job across the whole slice, from a shared venv on Filestore
/home:All 8 ranks joined one job and each sees the full slice. The numbers printed are JAX devices (TensorCores), 8 per VM across 8 VMs, on 32 physical chips. That matches the
tpu7x-64accelerator type GCE reports.TPU devices are visible inside the job on every node. This run also shows the warning when
--layoutis left out:GCE metadata on
tpu7xslurm-tpunodeset-1confirms the VMs are one slice:For Static nodeset, we can have multiple slices per partition, but fails if total partition limit is not a multiple of Slice VMs.
If static capacity is unavailable for a slice, will reuse the same MIG when slurmsync retries resuming the slice.
For Dynamic nodes the topology is taken at runtime during job submission, fails if
--layoutflag is not specified.When
--layout=tpu7x=2x2x2is provided ontpu-dyn, the slice MIG is created on demand, runs the job, and tears down automatically when idle (PowerDownOnIdle=YES).Across the 8-node
2x4x4slice (64TPU7xTensorCores), we also verifiedJAX distributed matrix multiplication, 3D ICIpmean/ All-Reduce collectives, and 10-step 64-way FSDP MaxText (llama3-8b) pre-training with loss convergence.