Skip to content

Fix autotuner crash when an experiment produces no metric - #8421

Open
Rakshit-gen wants to merge 3 commits into
deepspeedai:masterfrom
Rakshit-gen:fix/autotuner-none-metric-crash
Open

Fix autotuner crash when an experiment produces no metric#8421
Rakshit-gen wants to merge 3 commits into
deepspeedai:masterfrom
Rakshit-gen:fix/autotuner-none-metric-crash

Conversation

@Rakshit-gen

Copy link
Copy Markdown
Contributor

Fixes #3475

The bug

get_best_space_record picks the best record in a tuning space with:

if best_space_record is None or metric_val > best_space_record[1]:

An experiment that produces no metric (an OOM during autotuning is the
common case) is still recorded, with metric_val set to None. Once a
None-valued record becomes best_space_record, the next comparison
does metric_val > best_space_record[1], and if both sides happen to
be None (or the incoming one is a real number compared against a
None best) this raises:

TypeError: '>' not supported between instances of 'NoneType' and 'NoneType'

This isn't limited to get_best_space_record itself: tune_space
calls it both in fast-tuning mode and after full tuning to pick the
overall best micro batch size, and get_best_space_records calls it
once per tuning space to build the final results table. A single space
where every experiment OOM'd is enough to crash the whole autotuning
run and lose every valid result gathered from the spaces tuned before
it.

The fix

A record with a None metric is no longer eligible to become the
best record. It's still counted toward the space's total number of
experiments (space_num_exps), it just can't win the comparison. This
means get_best_space_record now returns None only when a space has
no experiments with a usable metric at all, which the existing callers
already handle correctly (they fall back to 0 or -1 in that case),
so no other call site needed to change.

Testing

Added test_get_best_space_record_ignores_runs_without_a_metric to
tests/unit/autotuning/test_autotuning.py, covering:

  • every recorded experiment in a space has metric_val=None -> no crash, returns None
  • a mix of None and real metrics -> the real one wins regardless of position, and the experiment count still includes the failed runs

Confirmed this test fails with the exact TypeError above on current
master and passes with the fix. Also ran the full existing
tests/unit/autotuning/test_autotuning.py suite (12 tests) and it
passes. Ran pre-commit on both changed files (yapf, flake8,
check-torchdist, check-license, codespell) with no issues. This is a
pure CPU, no-GPU-needed unit test path, no integration/training-loop
behavior is touched.

cc @loadams (CODEOWNERS for deepspeed/autotuning/)

get_best_space_record compared metric_val > best_space_record[1]
unconditionally. When an experiment produces no metric (for example an
OOM during autotuning), metric_val is None, and once the first record
in a space is None the very next comparison raises TypeError:
'>' not supported between instances of 'NoneType' and 'NoneType'.
This crashes the whole tuning run and throws away every valid result
gathered so far, in both the fast-mode and full-tuning call sites in
tune_space, plus get_best_space_records.

Records with a None metric are no longer eligible to become the best
record. They still count toward the space's total experiment count,
they just cannot win the comparison, which matches how a failed run
should be treated everywhere the function is called from.

Fixes deepspeedai#3475

Signed-off-by: rakshit-gen <sisodiarakshit456@gmail.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c2575122a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +722 to +724
if metric_val is None:
# a run that did not produce a metric (e.g. OOM) is not a valid candidate
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard the caller when every fast metric is absent

When a fast micro-batch pass records only one None metric (for example, a user-specified micro-batch list whose run writes a null metric), this branch now makes get_best_space_record() return None; tune_space() then unconditionally evaluates fast_best_record[0]['name'] at line 586. That turns a case which previously completed with a single such record into a 'NoneType' object is not subscriptable failure, so the caller must avoid dereferencing the missing record.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, this was a real regression. Fixed in 7d770d0: fast_best_record[0]['name'] now goes through the same None-safe ternary as fast_best_mbs and fast_best_metric_val on the lines right above it.

assert expected_num_gpus == tuner.exp_num_gpus


def test_get_best_space_record_ignores_runs_without_a_metric(tmpdir):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required sign-off trailer

Commit 23e6d10f3f945c85542953b0531273181fdf8150 is a non-merge commit, but its message has no Signed-off-by: trailer, violating the repository's mandatory commit requirement; add the author sign-off before this change is merged.

AGENTS.md reference: AGENTS.md:L8-L8

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it's pointing at a commit that isn't part of this PR (23e6d10f3f9...). The actual commit here is 5c25751, which does have a Signed-off-by trailer, you can see it with git log or the commits tab.

tune_space logs fast_best_record[0]['name'] unconditionally right after
computing fast_best_metric_val and fast_best_mbs with a None-safe
ternary. Now that get_best_space_record can return None when every
experiment in a space had no metric, that log line needs the same
guard the other two already have.

Signed-off-by: rakshit-gen <sisodiarakshit456@gmail.com>
@Rakshit-gen

Copy link
Copy Markdown
Contributor Author

cc @tjruwase for visibility as well

@Rakshit-gen

Copy link
Copy Markdown
Contributor Author

@loadams @tohtana @tjruwase can we please review this PR?

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.

Error when comparing full_best_metric_val and fast_best_metric_val in Autotuning

2 participants