Skip to content

fix: skip training with no expanded systems - #377

Open
njzjz-bot wants to merge 1 commit into
deepmodeling:masterfrom
njzjz-bot:fix/issue-371-empty-training-systems
Open

fix: skip training with no expanded systems#377
njzjz-bot wants to merge 1 commit into
deepmodeling:masterfrom
njzjz-bot:fix/issue-371-empty-training-systems

Conversation

@njzjz-bot

Copy link
Copy Markdown

Summary

  • detect when configured artifacts expand to zero DeePMD training systems
  • skip dp train and propagate the supplied initial model in that state
  • keep the generated input on the valid plain prob_sys_size fallback
  • add an end-to-end regression test proving the training command is not called

Tests

  • PYTHONPATH=tests python -m unittest -v tests.op.test_run_dp_train.TestRunDPTrainNullIterData.test_exec_v2_empty_list tests.op.test_run_dp_train.TestRunDPTrainNullIterData.test_exec_v2_empty_dir tests.op.test_run_dp_train.TestRunDPTrainNullIterData.test_exec_v2_fully_empty_training_systems
  • git diff --check

Closes #371

Coding agent: Codex
Codex version: codex-cli 0.149.0
Model: gpt-5.6-sol
Reasoning effort: xhigh

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Aug 23, 2026
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 59 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 689ba30b-7d47-4fd5-92ee-c2b8084c9ebe

📥 Commits

Reviewing files that changed from the base of the PR and between 6b01f29 and fdc8c0e.

📒 Files selected for processing (2)
  • dpgen2/op/run_dp_train.py
  • tests/op/test_run_dp_train.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@wanghan-iapcm wanghan-iapcm 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.

Thanks for taking this on - the bug is real, I confirmed it still reproduces on master (6b01f29), and the approach you chose is one of the two resolutions #371 asked for. The new regression test is a genuine one: reverting only the training_systems_empty logic while keeping the tests gives

AssertionError: Expected 'run_command' to not have been called. Called 2 times.
Calls: [call(['dp','train','--init-frz-model','.../bar.pb','input.json']),
        call(['dp','freeze','-o','frozen_model.pb'])]

with 25 of 26 still passing, and it asserts more than just assert_not_called - it pins out["model"], the train.log reason string, and the persisted systems: []. That is exactly what the issue asked for.

The blocker is not the logic. It is the base.

The branch is 112 commits behind master and currently reverts #368

This branch is built on fa4a4cf ("Add folded mode to resubmit", #198) with a single commit on top, and GitHub reports mergeable: CONFLICTING. Rather than rebasing, the agent appears to have re-derived roughly 400 lines of features that already exist on master - multitask, split_valid, _make_train_command, the pytorch backend, valid_data, optional_files - which is why a targeted fix shows up as +443/-57.

That re-derivation is not faithful, in three ways I verified directly:

1. It reverts #368. Master carries

if numb_old > 0 and numb_new > numb_old:
    auto_prob_str = f"prob_sys_size; 0:{numb_old}:{old_ratio}; ..."
else:
    auto_prob_str = "prob_sys_size"
    logging.warning("Cannot build two non-empty auto_prob ranges ...")

None of that exists at this head. The consequence is concrete: for init_data: [] plus a first labeled iteration that does have data, this branch produces prob_sys_size; 0:0:0.9; 0:1:0.1 where master produces prob_sys_size. That is the ValueError: probabilities do not sum to 1 crash coming back. It is also precisely the P2 - Handle the symmetric empty-old-data case point that njzjz-bot raised on #368 and that was fixed there.

2. It deletes #368's regression tests. test_auto_prob_empty_new_iter_data and test_auto_prob_empty_old_data are both present on master and absent here, so CI would not catch item 1.

3. It reintroduces the bug #376 is fixing. Lines 186-187 are back to ip["config"].get(...), which crashes with AttributeError when config is None.

Please rebase onto current master rather than resolving this by hand. After a rebase the genuinely new contribution should be small: the training_systems_empty computation, the skip_training extension, and the new test. Note that and not training_systems_empty on line 239 becomes redundant once master's guard is restored - training_systems_empty implies numb_old == 0, so master's condition already falls back to "prob_sys_size"; keeping both would only suppress master's warning.

While rebasing, two things worth fixing in the same pass are noted inline.

Not a problem

For the record, since it looks alarming in the diff: dropping shutil.copy(init_model, "frozen_model.pb") and returning "model": init_model is not a regression. That is byte-identical to master - it changed in f2e1d59 (#207, 2024-03-30) so a pytorch model.ckpt.pt is not mislabelled as a .pb. It only appears in this diff because the base predates that commit. Same for the init_data sign change to NestedDict[Path].

Comment thread dpgen2/op/run_dp_train.py
)
auto_prob_str = "prob_sys_size"
if do_init_model:
if do_init_model and not training_systems_empty:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This hunk is where the #368 revert lands. Master has, at the same place:

if numb_old > 0 and numb_new > numb_old:
    auto_prob_str = f"prob_sys_size; 0:{numb_old}:{old_ratio}; ..."
else:
    auto_prob_str = "prob_sys_size"
    logging.warning("Cannot build two non-empty auto_prob ranges ...")

The rebase will conflict here. Please keep master's version. With it restored, and not training_systems_empty on this line is redundant: training_systems_empty implies len_init == 0 and iter_data_exp == [], hence numb_old == 0, so master's guard already yields "prob_sys_size". Keeping both only suppresses the warning that tells the user why the fallback happened.

Comment thread dpgen2/op/run_dp_train.py
valid_data = append_valid_data(config, valid_data, valid_systems)
iter_data_exp = iter_data_old_exp + iter_data_new_exp
if isinstance(init_data, dict):
has_init_training_data = any(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

any() over all heads is the wrong predicate for multitask. write_data_to_input_script gives head k only init_data[k], and gives iter_data only to config["head"] - so a sibling head's data makes training_systems_empty False even when the head actually being trained has none. It is also inconsistent with line 243 just below, which correctly uses len_init = len(init_data[head]).

Reproduced against this head with config={"multitask": True, "head": "B", "init_model_policy": "yes"}, init_data={"A": [dir_with_systems], "B": []}, iter_data=[empty_dir]: dp train is invoked, head B gets systems: [] and auto_prob: prob_sys_size; 0:0:0.9; 0:0:0.1. Both the #371 and #368 failures recur.

Suggest len(init_data.get(head, [])) > 0 for the dict branch, matching line 243. Low urgency - multitask is not wired into the CLI today - but the inconsistency is worth closing while you are here.

Comment thread dpgen2/op/run_dp_train.py
else:
has_init_training_data = len(init_data) > 0
# A non-empty artifact list may still expand to zero DeePMD systems.
# Track the expanded state so an empty training command is never run.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"so an empty training command is never run" is stronger than what the code guarantees. dp train still launches on an empty systems list in two states, both of which I executed against this head:

  • init_model is None with training_systems_empty true: skip_training returns False on the first conjunct, execution falls through, and run_command(['dp','train','input.json']) runs with systems: [].
  • finetune_mode == "finetune": the early return False at the top of skip_training precedes the new condition entirely, giving ['dp','train','input.json','--finetune','<model>'] with systems: []. This is reachable through the do_finetune pre-loop step.

#371 explicitly offered a second acceptable resolution - "fail early with a clear FatalError explaining that there is no data to train on". Since training_systems_empty is already computed here, raising FatalError when it is true and no model is available would close both gaps and make the comment true. Otherwise please soften the comment to describe the actual guarantee.

Comment thread dpgen2/op/run_dp_train.py
mixed_type = ip["optional_parameter"]["mixed_type"]
finetune_mode = ip["optional_parameter"]["finetune_mode"]
config = ip["config"] if ip["config"] is not None else {}
impl = ip["config"].get("impl", "tensorflow")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These two lines read ip["config"] rather than the config fallback assigned on the line above, so config=None raises AttributeError: 'NoneType' object has no attribute 'get'. This is the bug #376 fixes; it is back here as a side effect of the stale base. The rebase should resolve it - just flagging so it is not re-resolved the wrong way in the conflict.

Detect when initial and iteration artifacts expand to no DeePMD systems, preserve the supplied model, and avoid invoking dp train with an empty systems list.

Closes deepmodeling#371

Coding-Agent: Codex
Codex-Version: codex-cli 0.149.1
Model: gpt-5.6-sol
Reasoning-Effort: xhigh
@njzjz-bot
njzjz-bot force-pushed the fix/issue-371-empty-training-systems branch from f46eb4a to fdc8c0e Compare August 26, 2026 11:00
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Aug 26, 2026
@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 84.43%. Comparing base (6b01f29) to head (fdc8c0e).

Files with missing lines Patch % Lines
dpgen2/op/run_dp_train.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #377      +/-   ##
==========================================
- Coverage   84.43%   84.43%   -0.01%     
==========================================
  Files         104      104              
  Lines        6110     6116       +6     
==========================================
+ Hits         5159     5164       +5     
- Misses        951      952       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wanghan-iapcm
wanghan-iapcm dismissed their stale review August 27, 2026 04:11

Retracted. This review was produced without running the mandated /code-review fan-out (the loop skill's section 2); the substitute process used instead has since been shown to miss findings and, in one case, to state a verified-sounding falsehood. Re-reviewing properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle RunDPTrain when expanded training systems are empty

2 participants