Skip to content

feat(finetune): initialize native spin from spin-free models - #6094

Merged
OutisLi merged 6 commits into
deepmodeling:masterfrom
OutisLi:pr/native-spin-finetune
Oct 27, 2026
Merged

OutisLi merged 6 commits into
deepmodeling:masterfrom
OutisLi:pr/native-spin-finetune

Conversation

@OutisLi

@OutisLi OutisLi commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Allow native-spin models to initialize directly from compatible spin-free checkpoints through --finetune, without a manually converted checkpoint. This covers PT DPA4/SeZM and PT-expt DPA4/DPA4C.

The target is constructed from its fine-tuning configuration first. A shared transfer implementation copies compatible geometric weights while preserving target spin configuration, magnetic-element masks, analytical bridging, output-bias/statistics initialization, and fresh optimizer/EMA state. Same-name multitask conversion performs fine-tuning statistics rather than resuming the spin-free branch unchanged.

Implementation

  • Share descriptor-specific transfer rules between PT and PT-expt; initialization does not add work to the training hot path.
  • Preserve DPA4's additive spin routes. For DPA4C, insert spin features between the geometric readout and trailing masses/type embeddings, preserving frame/atomic fitting parameters as well.
  • Support MLP and GLU input projections, including no-hidden-layer fittings, and share expanded tensors across state-dict aliases.
  • Reject incompatible shapes/fitting families and input residuals whose semantics would change on expansion, before loading target state. Explicit random fitting initialization remains supported.
  • Keep native-to-native validation and existing type-map constraints; deprecated virtual-spin conversion is outside this change.

Validation on this branch

Based on master d07c097b; this PR contains one cherry-picked commit, with the same patch as the requested source change. It does not depend on the ASE or grid-pair PRs.

Python 3.13 / PyTorch 2.13.0+cu130, CPU only:

  • 115 tests and 2 subtests passed across test_finetune_native_spin.py, test_finetune.py, test_finetune_utils.py, and test_get_model_bridging.py in the PT-expt/common suites.
  • Checks include initial energy/force/virial preservation, zero initial magnetic force, trainable spin gradients, MLP/GLU layouts, presets, parameter tails, failure without target mutation, serialization, and single/multitask CLI training with plain/ZBL targets.
  • The first restricted run passed 111 tests; four PT CLI cases hit filesystem/IPC sandbox limits. The same four unmodified tests passed with a writable Warp cache and permission to run PyTorch's shared-memory manager. No skips or assertion changes were introduced.
  • Independent source review found no actionable issues. Scoped pre-commit hooks, repository Ruff, formatting checks, patch-identity checks, and whitespace checks passed.

GPU and distributed execution were not rerun for this PR. The original commit's validation record is historical; the results above describe this branch's verification.

Summary by CodeRabbit

  • New Features
    • Native-spin models can now be initialized from compatible spin-free pretrained models, including supported descriptor, fitting-network, multitask, and bridged-model configurations.
    • Fine-tuning can preserve randomly initialized fitting networks while transferring descriptor parameters.
    • Compatible DPA4C fitting widths can be inherited automatically, and spin references can be calibrated from fine-tuning data.
  • Bug Fixes
    • Improved preservation of model outputs and target settings during fine-tuning, with clearer handling of incompatible configurations.
  • Documentation
    • Expanded guidance on compatibility requirements and spin-free-to-native-spin fine-tuning.

Allow --finetune to initialize native-spin DPA4/SeZM models on the
PyTorch and pt-expt backends, and native-spin DPA4C on pt-expt, directly
from spin-free checkpoints without a manually converted checkpoint.

Construct the target from its fine-tuning input and transfer learned
weights after branch selection and type-map alignment. Preserve the
target spin scheme, magnetic element mask, and analytical bridging.
A same-name multi-task branch undergoing spin-free to native-spin
conversion must update its output statistics instead of resuming unchanged.

Keep the conversion rules in a shared tensor-transfer module:
- Dispatch descriptor-specific expansion and fitting input projection
  selection by their concrete network classes.
- Copy DPA4 geometric weights while retaining fresh zero-output spin
  routes and the target's configuration-derived magnetic masks.
- Insert DPA4C spin features between the geometric readout and trailing
  neighborhood masses/type embeddings in descriptor statistics and
  fitting input weights, including trailing frame and atomic parameters.
- Extend the pair-FiLM output columns while retaining initialized spin
  heads and anchors. Keep the spin gate closed and the added fitting rows
  initialized so the geometric function is preserved with a trainable
  gradient into the spin branch.
- Support MLP and GLU fittings, including linear fittings without hidden
  layers. Expand each input projection once and reuse the result for all
  state-dict aliases.
- Reject incompatible tensor shapes, fitting families, and first-layer
  identity or duplicated residuals whose semantics change on expansion.
  Check residuals independently of resnet_dt before loading target state.
- Detach copied values so temporary transfer tensors retain no autograd
  graph. All conversion work runs during initialization.

Leave out_bias, out_std, and bias_atom_e to the target preset_out_bias
and fine-tuning statistics. Start optimizer and EMA state afresh. Retain
native-to-native transfer validation, existing type-map restrictions,
and explicit RANDOM fitting initialization.

Validation:
- 127 CPU tests and 2 subtests passed across fine-tuning and bridging.
- Check initial energy/force/virial parity, zero initial magnetic force,
  trainable magnetic gradients, and checkpoint/serialization round trips.
- Cover all v20260911 DPA4C presets, MLP/GLU input layouts, residual
  rejection without target mutation, and frame/atomic fitting inputs.
- Exercise single-task and multi-task CLI fine-tuning into plain and ZBL
  models, including target bias presets/statistics and fresh optimizer/EMA.
- Repository pre-commit hooks passed. GPU and distributed validation
  were not performed for this change.
Copilot AI balanced review requested due to automatic review settings October 21, 2026 08:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f767d1d3-2b45-418e-b2ff-8e60dea631c4
Commits

Reviewing files that changed from the base of the PR and between 09ddcb0 and 1effe5a.

Files selected for processing: 1
  • deepmd/pt_expt/train/training.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

Fine-tuning rules can request conversion from spin-free pretrained models to native-spin targets. Transfer utilities adapt compatible state, and both PyTorch training paths apply converted parameters and compute native-spin input statistics.

Changes: Native-spin fine-tuning

Layer / File(s) Summary
Conversion rules and learned paths
deepmd/utils/finetune.py, deepmd/pt/utils/finetune.py, doc/train/finetuning.md, source/tests/common/test_finetune_utils.py, source/tests/pt_expt/model/test_get_model_bridging.py
Rules identify when conversion is required and resolve applicable automatic fitting widths. Shared helpers locate learned-model paths and remap descriptor or fitting keys. Documentation and rule tests cover conversion requirements.
Native-spin state conversion
deepmd/pt/utils/spin_finetune.py, source/tests/pt_expt/test_finetune_native_spin.py
The transfer utility validates model compatibility and adapts supported descriptor and fitting state. Tests cover preserved outputs and biases, fitting initialization, descriptor variants, and incompatible layouts.
Trainer integration and end-to-end validation
deepmd/pt/train/training.py, deepmd/pt_expt/train/training.py, source/tests/pt_expt/test_finetune_native_spin.py
Both trainers apply converted state and compute native-spin input statistics before output-bias adjustment. CLI tests cover training modes, saved state, and model reloads.

Priority: Normal

Estimated code review effort: 4 (Complex) | ~50 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant RuleBuilder
  participant Trainer
  participant get_native_spin_finetune_state
  RuleBuilder->>Trainer: provide conversion rule
  Trainer->>get_native_spin_finetune_state: convert pretrained branch state
  get_native_spin_finetune_state-->>Trainer: return converted parameters
Loading

Possibly related issues

  • deepmodeling/deepmd-kit#6101 concerns delta-bias statistics during spin-free DPA4 to native-spin fine-tuning. This change adds that conversion path and initializes statistics, but does not add full-data residual scanning.

Suggested labels: new feature

Suggested reviewers: anyangml

Merge Risk: Minimal · previous review 1effe

No specific issue remains identified for this change; it is mergeable after normal checks.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "feat(finetune): initialize native spin from spin-free models" matches the main change. The PR adds a path that lets native-spin models start from compatible spin-free checkpoints through --…
Docstring Coverage Passed Docstring coverage is inconclusive: files from earlier reviews still need to be rechecked within the check's analysis limits. Not blocking.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "feat(finetune): initialize native spin from spin-free models" matches the main change. The PR adds a path that lets native-spin models start from compatible spin-free checkpoints through --finetune. The changed files cover the training code, the finetune rule (convert_to_native_spin), the new spin_finetune.py transfer helpers, docs, and tests. The title is concise and specific, and it uses a conventional commit prefix. It does not mention the DPA4C-specific transfer rules or the rejection checks, but the title does not need to cover every detail.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@njzjz-bot njzjz-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agent: dot

Reviewed exact head 911ddbb: shared spin-free transfer, both trainer call sites, branch-rule changes and the submitted regression tests. No actionable source defect found in this review.

The transfer is constructed before loading target state; shape/residual incompatibilities fail without partially replacing model parameters. DPA4C inserts spin columns at the geometric readout boundary, shifting masses/type-embedding and fitting-parameter tails together, and expands every state-dict alias of the input projection. It preserves target spin masks, analytical bridging and output bias/scale initialization. MLP/GLU projection selection covers the no-hidden-layer case; rejecting input-width-dependent residuals is appropriate rather than silently changing the inherited function. Same-name multitask spin conversion is correctly kept out of the resuming shortcut, allowing the fine-tuning statistics pass. Existing nonconversion key remapping retains target-owned unmatched state.

Independently executed 13 exact-source backend-neutral tests from test_finetune_utils.py, including single/multitask rules, alias selection, RANDOM fitting, config nonmutation, spin-free acceptance, virtual-spin rejection and magnetic-set constraints; all passed. This isolated run supplied the environment dtype constant and does not execute the tensor transfer or trainers. I inspected the submitted tensor-layout, energy/force/virial, trainable spin-gradient, serialization and CLI tests; the author's reported 115-test CPU result is reused, not claimed as independently rerun. This review environment lacks PyTorch/native DeePMD, so native/GPU/distributed and performance scopes remain unverified here.

Current Python/C++/build CI is still running; actual CUDA test jobs are skipped. No code, branch or merge actions taken.

@codecov

codecov Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.48744% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.05%. Comparing base (4e0b0da) to head (8136bdb).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
deepmd/pt/utils/spin_finetune.py 97.14% 3 Missing ⚠️
deepmd/utils/finetune.py 96.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6094      +/-   ##
==========================================
- Coverage   78.26%   78.05%   -0.22%     
==========================================
  Files        1176     1177       +1     
  Lines      142590   142753     +163     
  Branches     5072     5072              
==========================================
- Hits       111603   111422     -181     
- Misses      29048    29394     +346     
+ Partials     1939     1937       -2     

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@wanghan-iapcm wanghan-iapcm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This PR lets native-spin models be initialized from a compatible spin-free checkpoint through --finetune (PT DPA4/SeZM and PT-expt DPA4/DPA4C). The shared validator now returns convert_to_native_spin instead of rejecting a spin-free pretrained model; both trainers branch on it, and the transfer itself lives in deepmd/pt/utils/spin_finetune.py, which builds a complete target state dict for a strict load, skipping output bias/statistics (left to the normal statistics pass) and, under random_fitting, the non-descriptor keys. DPA4/SeZM need no expansion; DPA4C gets a spin block inserted into descriptor.mean/stddev, the FiLM spin columns and the fitting input projection, with explicit rejection of mismatched families, shapes and residual layouts.

One blocking item and four non-blocking items are attached inline.

Comment thread deepmd/pt/utils/spin_finetune.py
Comment thread deepmd/pt/utils/spin_finetune.py
Comment thread deepmd/pt/train/training.py
Comment thread source/tests/common/test_finetune_utils.py
Comment thread deepmd/pt/utils/spin_finetune.py
@OutisLi
OutisLi requested a review from wanghan-iapcm October 24, 2026 11:35
Comment thread source/tests/pt_expt/test_finetune_native_spin.py

@njzjz-bot njzjz-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agent: dot

Delta review of b982f46 against 911ddbb, after reading the existing review and author replies. No new actionable defect found in the four-file delta.

The spin-reference omission identified in discussion_r4366877946 is addressed for the reported same-elements conversion path. Both trainers now call the spin-only calibration after successful transfer and before output-bias adjustment, inside their existing rank-0 statistics action. DPA4C uses the existing per-type RMS estimator and setter without rerunning geometric calibration; DPA4/SeZM do not invoke the sampler. The same-name conversion remains excluded from the resuming shortcut. Failure synchronization remains intact, as do PT-expt's parameter/buffer broadcast and PT's subsequent distributed-wrapper synchronization. This corrects an omission in my earlier source-only review; that review did not establish descriptor-statistics initialization end to end.

The four coverage requests are now represented in the submitted tests: descriptor-family rejection; independent learned-part/type-map/spin-direction guards; real trainer RANDOM cases with exact fresh-fitting-parameter comparisons before optimization; and pretrain-script cases that deliberately change target width then check the saved pretrained width plus native-spin configuration. The new DPA4C checkpoint assertion checks the nonunit reference, and the isolated statistics test checks zero-moment/missing-type defaults plus unchanged geometry and closed-gate outputs. Not freezing precedence between multiple invalid inputs is reasonable; I do not regard that as a remaining correctness blocker.

Independent validation here: all four changed Python files parse, and nine NumPy-only checks passed using unmodified AST-extracted helper/estimator/setter functions with lightweight model-lookup carriers. These cover the fixture RMS (0.9433981132), per-type estimates, bridged lookup, model_spin alias, zero/missing-type defaults, unchanged geometric arrays, non-DPA4C sampler avoidance, and error propagation. They do NOT execute PyTorch modules, buffer conversion, trainer/CLI, or distributed/GPU behavior. PyTorch/native DeePMD are unavailable here; the author's 97-test/two-subtest result was inspected, not independently reproduced.

CI at this SHA is not all green: Python/C++ jobs and docs remain pending; CodeQL reports initial_fitting at test line 572. Source control flow indicates a false positive: both its sole assignment and sole use are guarded by the same unchanged mode == "random" condition. The existing alert thread is already resolved, but the check still reports failure; I have not changed or dismissed any check/alert. Actual CUDA test jobs are skipped.

@wanghan-iapcm wanghan-iapcm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review of the spin-free -> native-spin initialization at b982f46. Two blocking issues are attached inline: the DPA4C transfer is unusable with the default auto-width fitting configuration, and the spin block inserted into descriptor.mean/descriptor.stddev is never calibrated. One non-blocking follow-up is attached about fine-tuning onto a target type map that adds an element.

Comment thread deepmd/pt/utils/spin_finetune.py
Comment thread deepmd/pt/utils/spin_finetune.py
Comment thread deepmd/utils/finetune.py
@github-actions github-actions Bot added the Docs label Oct 26, 2026
Comment thread deepmd/utils/finetune.py
@OutisLi
OutisLi requested a review from wanghan-iapcm October 26, 2026 02:34

@wanghan-iapcm wanghan-iapcm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One finding from the re-review at 0771e81: the new automatic-width inheritance does not apply to the canonical linear_ener composition spelling, so the documented inheritance is skipped and the transfer aborts on a shape check.

Comment thread deepmd/utils/finetune.py Outdated
@OutisLi
OutisLi requested a review from wanghan-iapcm October 26, 2026 15:24

@wanghan-iapcm wanghan-iapcm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Two findings from the re-review at 1effe5a, both on the DPA4/SeZM transfer path: a fitting-family mismatch silently leaves the target fitting network randomly initialized, and a target fitting with more hidden layers than the pretrained one loads without any diagnostic. The canonical-composition width inheritance raised in the earlier review is fixed for the single-learned-child case; the remaining composition issues are separate and not blocking.

Comment thread deepmd/pt/utils/spin_finetune.py
Comment thread deepmd/pt/utils/spin_finetune.py

@wanghan-iapcm wanghan-iapcm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved at 1effe5a. The earlier blocking items are addressed: the DPA4C spin reference is calibrated before the bias refit in both trainers, the automatic-width inheritance now locates the learned child in a canonical linear_ener composition for the single-learned-child case, and the statistics, type-map and descriptor-family guards have matching tests.

Two non-blocking observations remain on the DPA4/SeZM transfer path and are filed inline in the preceding review: a fitting-family mismatch, or a target fitting with more hidden layers than the pretrained one, leaves part of the target fitting network randomly initialized without a diagnostic. Neither affects the documented workflow and both can be follow-ups.

@OutisLi
OutisLi enabled auto-merge October 27, 2026 08:30
@OutisLi
OutisLi added this pull request to the merge queue Oct 27, 2026
Merged via the queue into deepmodeling:master with commit 51505b8 Oct 27, 2026
57 of 58 checks passed
@OutisLi
OutisLi deleted the pr/native-spin-finetune branch October 27, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants