fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: revert preset reward function deletion from hyperparams dict - #6181

Merged
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix
Aug 14, 2026
Merged

fix: revert preset reward function deletion from hyperparams dict#6181
zhaoqizqwang merged 1 commit into
aws:masterfrom
mujtaba1747:master-rlvr-hyperparam-bugfix

Conversation

@mujtaba1747

@mujtaba1747mujtaba1747 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

RLVR training needs a reward signal. The old code accepted preset_reward_function on the hyperparameters object, then silently deleted it during processing — leaving jobs to fail downstream (or run without a valid reward).

This PR:

  1. Preserves the preset_reward_function hyperparameter through _process_hyperparameters so it actually reaches the job.
  2. Fails fast, client-side, with a clear message when no reward source is configured, instead of relying on a later server-side failure.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions

github-actionsBot commented Aug 13, 2026

Copy link
Copy Markdown

Claude finished @mujtaba1747's task in 1m 40s —— View job


Review: PR #6181 — revert preset reward function deletion from hyperparams dict

  • Read PR diff
  • Analyze rlvr_trainer.py changes
  • Check test coverage & other affected paths
  • Post review

The change is small and correct. It stops _process_hyperparameters from stripping preset_reward_function, so a Hub-supplied or user-set preset now actually reaches the training job, and it adds a fail-fast guard in train() requiring at least one reward signal. This is a genuine bug fix (previously a preset was silently deleted before submission).

Observations

✅ Correctness

  • The validation is placed before the compute-type dispatch, so it applies to serverless, SMTJ, and HyperPod paths — good.
  • getattr(self.hyperparameters, "preset_reward_function", None) safely handles both a missing attribute and self.hyperparameters is None (beta-session fallback). Good.
  • The error message is clear and actionable, and the docstring Raises: note is accurate.

⚠️ Backward compatibility (minor, likely intended)

  • train() now raises ValueError when neither custom_reward_function nor preset_reward_function is set. This is stricter than before. It's an improvement (previously such a job would submit with no reward signal and fail server-side), but it is a behavioral change — worth a line in release notes if any consumer relied on Hub defaults populating the preset. If the Hub spec provides a default preset_reward_function, getattr returns it (truthy) and validation passes, so that path is unaffected.

⚠️ Test coverage gap (main feedback)

  • Only an integ test line was added (test_rlvr_trainer_integration.py:96), which is @pytest.mark.gpu_intensive and won't run in normal CI.
  • There's no unit test for the new guard. Note that the existing unit tests in tests/unit/train/test_rlvr_trainer.py set self.hyperparameters to a bare Mock(), so getattr(..., "preset_reward_function", None) returns an auto-created (truthy) Mock, which means the new validation passes only by accident and is effectively untested at the unit level.
  • Suggest adding a unit test that asserts train() raises ValueError when neither reward signal is configured — e.g. a hyperparameters object whose preset_reward_function is None/absent and custom_reward_function=None. This also guards the regression from reappearing:
deftest_train_raises_when_no_reward_signal(self, ...):
mock_hyperparams=Mock(spec=[]) # no preset_reward_function attrmock_hyperparams.to_dict.return_value= {}
mock_finetuning_options.return_value= (mock_hyperparams, "model-arn", False)
trainer=RLVRTrainer(model="test-model", model_package_group="test-group",
training_dataset="s3://bucket/train") # no custom_reward_functionwithpytest.raises(ValueError, match="requires a reward signal"):
trainer.train(wait=False)

Nit

  • test_rlvr_trainer_integration.py:95 introduces a blank line with trailing whitespace; linters may flag it.

Overall this looks good to merge; the only substantive ask is a unit test for the new validation so it's actually exercised in CI.
master-rlvr-hyperparam-bugfix

@zhaoqizqwang
zhaoqizqwang merged commit 51646f5 into aws:masterAug 14, 2026
20 of 27 checks passed
jam-jee added a commit that referenced this pull request Aug 24, 2026
…R cases a reward signal (#6207)
* fix(train): give shallow RLVR cases the reward signal RLVR requires
RLVRTrainer.train() refuses to submit unless custom_reward_function was passed
or hyperparameters.preset_reward_function is set. TestRLVRTrainerSubmission
inherits the shared cases from RecipeTrainerCases, which pass neither -- they
are about recipe rendering and dataset handling, not reward configuration -- so
14 of the class's 17 tests failed: 12 raising the ValueError, and the two
negative cases failing with "rejected, but not for the expected reason" because
the reward error preempted the S3 validation error they assert on.
Set the preset in a build() override rather than repeating it in each test, and
skip it when the test supplies its own custom_reward_function so the three
reward-function variants still exercise exactly what they name. "prime_code" is
one of the values the recipe's preset_reward_function enum accepts ('', gsm8k,
prime_code, prime_math) and is what the deep suite pairs with an ordinary
training dataset on this same model.
This was not a regression from a later change to sagemaker-train. The guard
landed in #6181 on 2026-08-14, five days before the shallow suite merged
(#6176), and rlvr_trainer.py is unchanged since. The suite had simply never run
in CI: the fast-integ-tests job could not check out fork PR code, and because
pull_request_target runs the base branch's workflow it could not have run on
#6176 itself either.
Verified against us-west-2 in the SDK test account: 14 passed in 94s, each
submitting and immediately stopping a real training job.
---
X-AI-Prompt: Fix the failing shallow sagemaker-train RLVR integ tests, which were being rejected at submission for a missing reward signal
X-AI-Tool: claude-code
* ci: run fast-integ-tests in CodeBuild instead of on the runner
Replaces the runner-based shallow suite with a CodeBuild invocation, so the
suite gates fork PRs -- which is nearly all of them.
The job stopped working when actions/checkout began refusing to place fork PR
code in a pull_request_target job. That refusal is correct: the runner holds the
base repo's GITHUB_TOKEN and assumes CI_AWS_ROLE_ARN, so a fork could edit
conftest.py and read those credentials out. On a public repo, overriding it with
allow-unsafe-pr-checkout would be a live credential-exfiltration path.
Guarding the job to same-repo PRs would stop the failure, but 59 of the last 60
merged PRs here are from forks, so that leaves ~2% coverage. This is the real
fix: start CodeBuild with source-version-override, exactly as the
codestyle-doc-tests, unit-tests and integ-tests jobs already do. The build never
sees the runner's token, secrets or default-branch cache, so no same-repo guard
is needed.
Its own project rather than folding into sagemaker-train-integ-tests, so a
shallow failure stays distinguishable from a deep-suite failure and runs
concurrently with it rather than queueing behind it.
Dropped the upload-artifact step: the JUnit XML no longer exists on the runner,
and results are in the CodeBuild logs.
Tradeoff recorded in both the workflow comment and the suite README: the pytest
selection now lives in createCIShallowIntegBuildSpec in
SageMakerMLFPySDKInfraCDK, so changing how the suite is invoked is no longer
reviewable in a PR to this repo. Adding a test file under shallow/ is still
picked up automatically.
The project sagemaker-python-sdk-ci-sagemaker-train-fast-integ-tests is
deployed, so the job resolves on merge.
---
X-AI-Prompt: Instead of the GitHub runner, run the sagemaker-train shallow integ suite in CodeBuild like the other CI workflows, so fork PRs are gated after actions/checkout began refusing fork PR code in pull_request_target
X-AI-Tool: claude-code
Sign up for freeto 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.

4 participants

@mujtaba1747@jam-jee@lucasjia-aws@zhaoqizqwang