Skip to content

fix: accept a PipelineVariable for HyperparameterTuner random_seed - #6320

Open
mohamedzeidan2021 wants to merge 2 commits into
aws:masterfrom
mohamedzeidan2021:fix/issue-5614-random-seed-pipeline-variable
Open

mohamedzeidan2021 wants to merge 2 commits into
aws:masterfrom
mohamedzeidan2021:fix/issue-5614-random-seed-pipeline-variable

Conversation

@mohamedzeidan2021

Copy link
Copy Markdown
Collaborator

Issue

Fixes #6171. Addresses the random_seed half of #5614.

Passing a pipeline variable (e.g. a ParameterInteger) as HyperparameterTuner(random_seed=...) raises:

ValidationError: 1 validation error for HyperParameterTuningJobConfig
random_seed
  Input should be a valid integer [type=int_type, input_value=ParameterInteger(...)]

Note on the other half of #5614 (ModelTrainer(environment={...}) rejecting pipeline-variable values): that was already fixed on master by #5608 (the field is now Optional[Dict[str, StrPipeVar]]). This PR covers the remaining random_seed part, which is the same root cause as #6171.

Root cause

HyperparameterTuner._build_tuning_job_config assigns config.random_seed = self.random_seed on a HyperParameterTuningJobConfig core shape, whose Base model sets validate_assignment=True. That field was typed Optional[int], so a PipelineVariable fails validation — even though sibling fields in the same shape (strategy: StrPipeVar, instance_count: IntPipeVar, ...) already accept pipeline variables.

Fix

Type HyperParameterTuningJobConfig.random_seed as Optional[IntPipeVar] (IntPipeVar = Union[int, PipelineVariable]), matching the sibling fields. shapes.py is code-generated, so the change is made in both:

  • sagemaker-core/src/sagemaker/core/tools/constants.py — the codegen PIPE_VAR_OVERRIDES source of truth (HyperParameterTuningJobConfig.RandomSeed -> IntPipeVar), so a regen stays consistent.
  • sagemaker-core/src/sagemaker/core/shapes/shapes.py — the generated line (verified identical to what the override emits).

Also broadened the HyperparameterTuner random_seed signature/docstrings to Optional[Union[int, PipelineVariable]] for consistency with its other pipeline-variable params.

Testing

sagemaker-train/tests/unit/train/test_tuner.py::test_random_seed_accepts_pipeline_variable: builds a tuner with random_seed=ParameterInteger(...) and calls _build_tuning_job_config() (the validate_assignment path). Fails on master (exact issue error), passes with the fix. A PipelineVariable random_seed serializes to its pipeline expression ({'Get': 'Parameters.RandomState'}), and a plain int is still accepted.

All 44 tuner unit tests pass; sagemaker-core shape/serialize tests green; black (100) and flake8 (120) clean.

Backwards compatibility

Widening only (int → int | PipelineVariable); plain ints are unaffected. No public signature narrowed.

Follow-up (out of scope)

ResourceLimits.{max_parallel_training_jobs, max_number_of_training_jobs, max_runtime_in_seconds} are still bare ints, though HyperparameterTuner types max_jobs/max_parallel_jobs/max_runtime_in_seconds as Union[int, PipelineVariable] — so parameterizing those would hit the same error. Not required by this issue's repro; worth a follow-up with the same PIPE_VAR_OVERRIDES treatment.

Mohamed Zeidan added 2 commits September 24, 2026 14:28
HyperParameterTuningJobConfig.random_seed was typed Optional[int]; assigning a
pipeline variable (e.g. ParameterInteger) raised ValidationError under the
shape's validate_assignment. Type it Optional[IntPipeVar] (via the codegen
PIPE_VAR_OVERRIDES source of truth + the generated shapes.py), matching sibling
fields like instance_count. Also broaden the ModelTrainer-facing tuner
random_seed signature to Optional[Union[int, PipelineVariable]].

Fixes aws#5614 (random_seed part), aws#6171
@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Claude finished @mohamedzeidan2021's task in 1m 12s —— View job


Review: PR #6320 — accept a PipelineVariable for HyperparameterTuner.random_seed

  • Read PR diff
  • Verify shapes.py change matches codegen override
  • Verify tuner.py signature/docstring consistency
  • Check test adequacy
  • Post review

Verdict: LGTM. This is a correct, minimal, backward-compatible widening. I checked each claim in the PR body against the code and it holds up.

What I verified

  • Codegen source of truth is consistent with the generated line. shapes_extractor.py:247 resolves simple-typed members through PIPE_VAR_OVERRIDES.get(shape, {}).get(member_name, ...), so the new constants.py entry HyperParameterTuningJobConfig.RandomSeed -> "IntPipeVar" produces exactly random_seed: Optional[IntPipeVar] = Unassigned() — matching the hand-edited shapes.py:7441. A future regen won't drift. Good practice editing both.
  • IntPipeVar is already imported in shapes.py:19 (from sagemaker.core.helper.pipeline_variable import StrPipeVar, IntPipeVar), and the change mirrors sibling fields in the same shape (strategy: StrPipeVar, HyperParameterTuningJobConfig's neighbors, ResourceConfig.instance_count: IntPipeVar, etc.), so this is squarely in the established pattern.
  • tuner.py is internally consistent: __init__ signature (tuner.py:109) is widened to Optional[Union[int, PipelineVariable]], stored verbatim (:255), and assigned to the core shape under validate_assignment=True (:1363-1364). Both docstrings updated. The create() classmethod param is untyped (random_seed=None, :1014), so the docstring wording there is cosmetic only — no signature mismatch.
  • Test exercises the real failure path. test_random_seed_accepts_pipeline_variable calls _build_tuning_job_config(), which is where the ValidationError fired on master, and asserts the PipelineVariable survives onto config.random_seed. That's the right regression guard.

Minor observations (non-blocking, out of scope)

  • Pre-existing truthiness gotcha at tuner.py:1363: if self.random_seed: means random_seed=0 is silently dropped and never written to the config. A ParameterInteger is truthy, so this PR's path is unaffected — but 0 is a legitimate seed. Not introduced here; worth a separate fix if you touch this again.
  • The ResourceLimits.{max_*} follow-up you flagged in the PR body is the right call — same root cause, same PIPE_VAR_OVERRIDES treatment. Reasonable to leave out of this PR.

No correctness, security, or backward-compatibility concerns: this is a pure type widening (int → int | PipelineVariable); plain-int callers are unaffected.

(Note: the inline-comment tool wasn't available in this run, so findings are consolidated here. The one actionable item — the if self.random_seed: truthiness case — is pre-existing and out of scope for this PR.)

This branch was successfully deployed

1 active deployment
auto-approve — 4d3b913e Deployed Sep 24, 2026 by mohamedzeidan2021 via wait-for-approval #1804
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HyperparameterTuner does not accept Pipeline Variable for random_seed argument

1 participant