Skip to content

feat(api): allow spec.trainer.numNodes to be mutable when TrainJob is suspended #3995

Description

@kapil27

What you would like to be added?

Allow spec.trainer.numNodes to be modified on a suspended TrainJob. Currently,
spec.trainer is fully immutable after creation (added in #3157), which prevents
users from scaling the number of training nodes on a paused job.

Why is this needed?

Before #3157 (Trainer v2.1), spec.trainer was mutable. Users and dashboards
could pause a TrainJob, change numNodes, and resume. The controller would
reconcile the JobSet with the updated replica count on unsuspend.
PR #3157 added blanket self == oldSelf CEL on spec.trainer to prevent mutations
that would conflict with the running JobSet (e.g., changing image or command mid-run).
This was the right call for most fields, but it also blocked the legitimate use case
of scaling numNodes on a suspended job where no pods are running and the JobSet
can safely be rebuilt.

Use case

  1. User creates a TrainJob with numNodes: 1
  2. Training runs, user pauses the job (checkpoints saved)
  3. User wants to scale to numNodes: 2 for faster training
  4. User edits spec.trainer.numNodes on the suspended TrainJob
  5. User resumes → controller rebuilds JobSet with 2 replicas → training resumes from checkpoint

What should stay immutable

All other spec.trainer fields should remain immutable:

  • image, command, args — changing these on a running distributed job would
    cause pod restarts with inconsistent binaries
  • resourcesPerNode — changing resource requests requires pod recreation
  • env — changing environment mid-training can corrupt state
  • numProcPerNode — tied to GPU topology, unsafe to change
    Only numNodes should be exempted, and only when suspended.

References

Love this feature?

Give it a 👍 We prioritize the features with most 👍

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions