fix: vision/audio argv builders silently drop or duplicate transform flags - #30
Conversation
…flags Two independent bugs in the vision/audio ai_modules' train/test argv builders: 1. image_base.py's train argv rendered data_proc_transforms through an f-string (stringified list, e.g. "['BINARIZE']"), while test argv passed the real list object -- the two builders disagreed on the wire format for the same parameter. prepare_transforms() (tinyml-tinyverse's train_base.py) only combines data_proc_transforms into args.transforms when isinstance(args.data_proc_transforms, list) is true, with no else branch, so the stringified form silently skipped it during training while testing still applied it -- pure train/test skew for anyone customizing this parameter, with no error or warning. timeseries_base.py already passes the raw list on both sides correctly; image_base.py's train side now matches it. feat_ext_transform/augmentation_transform don't have this defect (parsed via _normalize_transform_list's literal_eval fallback, which tolerates both forms) and were left untouched. 2. audio_base.py's train and test argv builders each declared --data-proc-transforms/--feat-ext-transform twice: once correctly as a raw list, and again later as a stringified f-string. argparse's last-occurrence-wins semantics meant the later, stringified declaration always won, making the earlier, correct one dead code -- the same underlying defect as (1), just duplicated instead of split across two methods. Removed the dead duplicate declarations in both methods, keeping the single correct raw-list version each already had. Verified with unit tests against the argv-building methods directly (no full ModelRunner instance needed -- these only read self.params). All 4 tests fail on the unmodified code with the exact symptoms described above (stringified list where a real list was expected; --data-proc-transforms appearing twice in the argv) and pass after the fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
An independent Opus peer review caught that fixing --data-proc-transforms
(making it a raw list, matching test-time argv) introduced a new crash:
prepare_transforms() (tinyml-tinyverse/references/common/train_base.py)
does
args.transforms = args.data_proc_transforms + args.feat_ext_transform
whenever args.data_proc_transforms is a list. image_base.py's train argv
builder still stringified --feat-ext-transform (and
--augmentation-transform), so once --data-proc-transforms became a real
list, this became `list + str`, raising:
TypeError: can only concatenate list (not "str") to list
on every image-classification training run (the vision default for
data_proc_transforms is [], and even an empty list still enters this
branch, so this wasn't conditional on the user setting anything).
An earlier comment in this file claimed feat_ext_transform "doesn't have
this defect: it's parsed via _normalize_transform_list's literal_eval
fallback, which tolerates both string and list forms" -- that's true of a
different consumer (image_dataset.py's Dataset construction, later in the
pipeline) but not of prepare_transforms(), which runs first and reads
feat_ext_transform directly with no such tolerance. Fixed by passing
--feat-ext-transform and --augmentation-transform as raw lists too,
matching _build_common_test_argv (which already did this) and
timeseries_base.py's reference implementation.
Adds a test that drives the REAL prepare_transforms() against the argv
builder's actual output, rather than only asserting argv shape (which is
exactly why the previous test suite didn't catch this -- MagicMock-based
shape checks never fed the argv through the function that actually
crashes). Verified to fail on the pre-this-commit code with the exact
TypeError above and pass post-fix.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
An independent peer review caught that this PR's own fix broke every image-classification training run. Pushed a follow-up commit (72196d6): Making My earlier comment claiming Fixed by passing both flags as raw lists too, matching Added a test that drives the real |
Summary
Two independent bugs in the vision/audio
ai_modules' train/test argv builders — both variations of the same underlying defect: the train-time and test-time argv construction for the same parameter disagreeing with each other.image_base.py: train/test disagree ondata_proc_transforms's wire formatTrain argv rendered it through an f-string (stringified list, e.g.
"['BINARIZE']"), while test argv passed the real list object.prepare_transforms()(tinyml-tinyverse'strain_base.py) only combinesdata_proc_transformsintoargs.transformswhenisinstance(args.data_proc_transforms, list)is true, with noelsebranch — so the stringified form silently skipped it during training while testing still applied it. Pure train/test skew for anyone customizing this parameter, with no error or warning.timeseries_base.pyalready passes the raw list on both sides correctly;image_base.py's train side now matches it.feat_ext_transform/augmentation_transformdon't have this defect — they're parsed via_normalize_transform_list'sliteral_evalfallback, which tolerates both string and list forms — and were left untouched (not a real bug, no need to change working code).audio_base.py:--data-proc-transforms/--feat-ext-transformdeclared twiceBoth the train and test argv builders declared these two flags twice: once correctly as a raw list, and again later as a stringified f-string.
argparse's last-occurrence-wins semantics meant the later, stringified declaration always won — making the earlier, correct declaration dead code. Same underlying defect as above, just duplicated instead of split across two methods.Removed the dead duplicate declarations in both
_build_common_train_argvand_build_common_test_argv, keeping the single correct raw-list version each already had.Verification
Unit tests against the argv-building methods directly (constructed via
unittest.mock.MagicMockforself— these methods only readself.params, no fullModelRunnerinstance needed). All 4 tests fail on the unmodified code with the exact symptoms described above (stringified list where a real list was expected;--data-proc-transformsappearing twice in the argv) and pass after the fix.🤖 Generated with Claude Code