fix: handle missing gradients in remove_additive for mixed datasets - #1140
fix: handle missing gradients in remove_additive for mixed datasets#1140ChaitanyaParate wants to merge 4 commits into
Conversation
|
Hi, since I don't use gradients I don't fully understand what this PR solves, could you provide a zip file with an example that would fail before this PR but works once this is implemented? Thanks! |
Hi! The zip contains a self-contained script (reproduce_bug.py) that demonstrates the crash and the fix with no dataset or model checkpoint needed. Setup: pip install metatrain metatensor-operations RuntimeError: invalid parameter: can not find gradients with respect to 'strain' in this block |
|
Thanks, actually I wanted an example with a dataset and an options file to understand when is this a problem in real life. It is hard for me to understand how the script relates to a real-life case. Is this a problem that you are facing when trying to use metatrain? |
|
Hi! I attempted to reproduce it end-to-end with a real dataset and options.yaml, and I want to be transparent about what I found. The real-life scenario is: training with two datasets simultaneously, one with stress and one without: yaml
However, the defensive fix in remove_additive is still valid and valuable — any future additive model that genuinely doesn't produce a gradient (e.g. a non-energy additive, or a model returning a pre-computed output without grad_fn) would hit this path. The reproduce_bug.py in the zip demonstrates the exact failing metatensor call (_add_block_block) from the original traceback with the exact error message — that part is real and version-independent. |
Fixes #867
Root cause
When training on mixed datasets (some structures with stress, some without), the additive model does not compute
straingradients for samples from the no-stress subset._add_block_blockrequires structural parity between both blocks, so it crashed withRuntimeError: invalid parameter: can not find gradients with respect to 'strain' in this block.Fix
When a gradient exists in the target block but not in the additive block, a zero-valued placeholder is inserted (same shape and metadata as the target gradient). The additive model's contribution to that gradient is zero, so subtracting zero leaves the target unchanged. A
warnings.warnis emitted so the user is aware a placeholder was inserted.Additional fix
The
.to(device=device)call was missing in the else branch for gradient values. This is corrected here.Self-introduced regression corrected
An earlier iteration of this PR accidentally switched the else branch to use
target_gradient.components/properties. Git history confirms the original code always usedadditive_gradient.components/propertieswith onlysamplescoming from the target. This is restored.Testing
A unit test
test_remove_additive_missing_gradientis added totests/utils/test_additive.py. It uses a stub model that guarantees nostraingradient in the additive output, verifies the warning fires, and checks the target gradient values are unchanged after subtraction.Note: I did not test on the MAD dataset directly. The test uses a synthetic TensorMap that reproduces the structural mismatch. Maintainer verification on real data would be appreciated.
📚 Documentation preview 📚: https://metatrain--1140.org.readthedocs.build/en/1140/