Repository navigation
feat: add args field to SourceCode for command-based training (#5226) - #6356
mohamedzeidan2021 merged 2 commits into
Conversation
|
Claude finished @mohamedzeidan2021's task in 1m 40s —— View job Code Review —
|
The `args` shell-quoting introduced with SourceCode.args did not actually hold,
because EXECUTE_BASE_COMMANDS interpolated the already-quoted command inside a
double-quoted assignment:
CMD="{base_command}"
eval $CMD
Single quotes are inert inside double quotes, so bash expanded the contents at
assignment time and the quoting was gone before `eval` ever ran. Verified
against real bash, an arg of:
$HOME arrived as /Users/... (expected literal $HOME)
$(id -u) arrived as 503 (expected literal $(id -u))
`id -u` arrived as 503 (expected literal `id -u`)
a"b aborted the script with `syntax error: unexpected end of file`
it's aborted the script likewise
a\tb, a\nb collapsed to a b
So the docstring promise that values "may contain spaces or special characters"
held only for whitespace, which is the one case the original tests covered --
that is why all nine of them passed against a broken implementation.
The command is now carried through a quoted heredoc, which performs no
expansion whatsoever, and `eval "$CMD"` parses it exactly once:
CMD=$(cat <<'SAGEMAKER_BASE_COMMAND_EOF'
{base_command}
SAGEMAKER_BASE_COMMAND_EOF
)
eval "$CMD"
All 15 metacharacter cases now round-trip verbatim. `eval` is deliberately
retained so `command` keeps its existing semantics: env vars in the command
still expand and shell operators like `&&` still chain. Only the spurious
*second* expansion -- the one that defeated the quoting -- is removed.
Tests now assert on behavior instead of on the text of the generated script:
they execute the generated command block under bash against a stub that reports
its argv, which is the only way to pin a quoting contract. Two graded negative
controls confirm they do the work:
- reverting to CMD="..." -> 23 of 28 fail
- keeping the heredoc but unquoting
the delimiter (expansion only) -> exactly the 4 expansion cases fail
The five assertions that string-matched `CMD="..."` are rewritten against a
helper that tolerates either delimiter form, so a future regression fails on
semantics rather than on a parse error in the test.
No regressions: 2282 passed in the sagemaker-train unit suite.
The unused copy in sagemaker-core/src/sagemaker/core/modules/templates.py has
the same flaw but is imported by nothing, so it is left out of scope here.
|
Claude finished @mohamedzeidan2021's task in 1m 7s —— View job Code Review —
|
Problem
With
ModelTrainer, whenSourceCode.commandis used (e.g.python launcher.py -e train.py), the command is executed verbatim and top-levelhyperparametersare NOT passed to the training script. This is intended ("what you see is what you get"), but there was no supported way to pass extra CLI arguments to acommand, and no signal to users about where their hyperparameters went.Fix
args: Optional[List[Union[str, int, float]]] = Nonefield toSourceCode(kept in sync across both definitions:sagemaker/core/training/configs.pyandsagemaker/core/modules/configs.py). Whencommandis used,argsare shell-quoted (shlex.quote) and appended to the executed base command, so values with spaces or special characters are passed through as single literal arguments.hyperparametersare combined withcommand, pointing users to theSM_HPSenvironment variable (hps = json.loads(os.environ["SM_HPS"])) and to the newargsfield. Matches the maintainer's proposed API in the issue thread.argsdefaults toNone; behavior is unchanged when it is not set.Testing
New
sagemaker-train/tests/unit/train/test_sourcecode_args.py(9 tests): field defaults, config sync, numeric args accepted + stringified, args appended to command, shell-quoting of args with spaces, no-args regression, warning fires with hyperparameters+command, and no warning otherwise. Existingtest_model_trainer.pyandsagemaker-core/tests/unit/test_fw_utils.pystill pass.black+flake8clean.Fixes #5226