Skip to content

feat(show): add serialization-tree via DeepEval.serialize#5316

Open
njzjz-bot wants to merge 3 commits intodeepmodeling:masterfrom
njzjz-bot:feat/deepeval-serialize
Open

feat(show): add serialization-tree via DeepEval.serialize#5316
njzjz-bot wants to merge 3 commits intodeepmodeling:masterfrom
njzjz-bot:feat/deepeval-serialize

Conversation

@njzjz-bot
Copy link
Contributor

@njzjz-bot njzjz-bot commented Mar 16, 2026

@/tmp/pr-body-5185.md

Summary by CodeRabbit

Release Notes

  • New Features
    • Added a new "serialization-tree" visualization option to the show command for inspecting model structure and internal composition.
    • Implemented standardized model serialization across all supported backends, enabling consistent model export and inspection workflows.

Authored by OpenClaw (model: gpt-5.2)
@njzjz-bot
Copy link
Contributor Author

Implements #5185 (first step): add powered by a backend-unified wrapper.\n\nAuthored by OpenClaw (model: gpt-5.2)

@njzjz-bot
Copy link
Contributor Author

Implements #5185 (first step): add dp show ... serialization-tree powered by a backend-unified DeepEval.serialize() wrapper.

Authored by OpenClaw (model: gpt-5.2)

@njzjz-bot
Copy link
Contributor Author

(FYI) Previous comment got mangled by shell backticks; this one is the corrected text.\n\nAuthored by OpenClaw (model: gpt-5.2)

@dosubot dosubot bot added the new feature label Mar 16, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

Adds a "serialization-tree" show option and a model serialization visualization: show entrypoint now can call model.serialize(), validate serialized output, deserialize into a Node tree, and log it. Introduces a serialize() API on DeepEval and backend implementations; stores model_file on DeepEval for backend resolution.

Changes

Cohort / File(s) Summary
CLI
deepmd/main.py
Added "serialization-tree" to the ATTRIBUTES choices for the show subcommand.
Show entrypoint
deepmd/entrypoints/show.py
When serialization-tree is requested, calls model.serialize(), checks for "model" key, deserializes with Node.deserialize, and logs the serialization tree.
Core DeepEval API
deepmd/infer/deep_eval.py
Added serialize() method on DeepEvalBackend/DeepEval and stored self.model_file to support backend detection and high-level serialization delegation.
Backend implementations
deepmd/dpmodel/infer/deep_eval.py, deepmd/jax/infer/deep_eval.py, deepmd/pd/infer/deep_eval.py, deepmd/pt/infer/deep_eval.py, deepmd/pt_expt/infer/deep_eval.py, deepmd/tf/infer/deep_eval.py, deepmd/pretrained/deep_eval.py
Added serialize() implementations per backend to return a dict containing at least "model" and backend-specific metadata (e.g., backend name, versions, model_def_script, optional @variables). pretrained backend proxies to underlying backend. One backend (tf) also added self.model_file in __init__.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Parser
    participant Show as Show Entrypoint
    participant DeepEval as DeepEval Interface
    participant Backend as Backend Module
    participant Node as Node (Serialization)

    CLI->>Show: invoke show with "serialization-tree"
    Show->>DeepEval: request serialize()
    DeepEval->>Backend: resolve backend using model_file
    Backend-->>DeepEval: serialized dict (includes "model")
    Show->>Node: Node.deserialize(serialized["model"])
    Node-->>Show: Node tree
    Show->>Show: log serialization tree
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • wanghan-iapcm
  • njzjz
  • Chengqian-Zhang
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(show): add serialization-tree via DeepEval.serialize' directly and concisely describes the main change: introducing a serialization-tree feature to the show command via a new DeepEval.serialize() method.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

Tip

CodeRabbit can scan for known vulnerabilities in your dependencies using OSV Scanner.

OSV Scanner will automatically detect and report security vulnerabilities in your project's dependencies. No additional configuration is required.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
deepmd/infer/deep_eval.py (1)

444-446: Cyclic import flagged by static analysis.

CodeQL reports a cyclic import starting from deepmd.pretrained.deep_eval. While placing the import inside the method body mitigates runtime issues (the import only occurs when the pretrained branch is taken), consider whether these utilities could be imported from a lower-level module to avoid the cycle entirely.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deepmd/infer/deep_eval.py` around lines 444 - 446, The import of
parse_pretrained_alias inside deepmd.infer.deep_eval creates a cyclic dependency
with deepmd.pretrained.deep_eval; to fix it, extract parse_pretrained_alias (and
any small helper utilities it needs) into a lower-level module (e.g.,
deepmd.pretrained.utils or deepmd.utils.pretrained) and update both
deepmd.pretrained.deep_eval and deepmd.infer.deep_eval to import
parse_pretrained_alias from that new module; ensure the extracted function has
no imports back to deepmd.pretrained.deep_eval to break the cycle and run tests
to confirm no runtime regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deepmd/infer/deep_eval.py`:
- Around line 443-454: When resolving a pretrained alias you re-detect the
backend and immediately call serialize_hook on backend_cls (via
Backend.detect_backend_by_model and backend_cls().serialize_hook) without
checking that the backend supports the IO feature; add the same IO capability
check used in the regular path before calling serialize_hook: after determining
backend_cls = Backend.detect_backend_by_model(resolved), verify
Backend.feature(backend_cls, Backend.Feature.IO) (or equivalent feature-check
method used elsewhere) and raise the same NotImplementedError with the same
message if IO is not supported, otherwise call
backend_cls().serialize_hook(resolved).

---

Nitpick comments:
In `@deepmd/infer/deep_eval.py`:
- Around line 444-446: The import of parse_pretrained_alias inside
deepmd.infer.deep_eval creates a cyclic dependency with
deepmd.pretrained.deep_eval; to fix it, extract parse_pretrained_alias (and any
small helper utilities it needs) into a lower-level module (e.g.,
deepmd.pretrained.utils or deepmd.utils.pretrained) and update both
deepmd.pretrained.deep_eval and deepmd.infer.deep_eval to import
parse_pretrained_alias from that new module; ensure the extracted function has
no imports back to deepmd.pretrained.deep_eval to break the cycle and run tests
to confirm no runtime regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a8a6ae18-b1d4-465f-b5b3-2149b4fbd411

📥 Commits

Reviewing files that changed from the base of the PR and between 09345bf and b695aaa.

📒 Files selected for processing (3)
  • deepmd/entrypoints/show.py
  • deepmd/infer/deep_eval.py
  • deepmd/main.py

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 26.22951% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.25%. Comparing base (09345bf) to head (1694360).

Files with missing lines Patch % Lines
deepmd/tf/infer/deep_eval.py 15.78% 16 Missing ⚠️
deepmd/dpmodel/infer/deep_eval.py 16.66% 5 Missing ⚠️
deepmd/entrypoints/show.py 28.57% 5 Missing ⚠️
deepmd/jax/infer/deep_eval.py 28.57% 5 Missing ⚠️
deepmd/pd/infer/deep_eval.py 16.66% 5 Missing ⚠️
deepmd/pt/infer/deep_eval.py 16.66% 5 Missing ⚠️
deepmd/pt_expt/infer/deep_eval.py 33.33% 2 Missing ⚠️
deepmd/infer/deep_eval.py 80.00% 1 Missing ⚠️
deepmd/pretrained/deep_eval.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5316      +/-   ##
==========================================
- Coverage   82.29%   82.25%   -0.05%     
==========================================
  Files         775      775              
  Lines       77627    77688      +61     
  Branches     3676     3676              
==========================================
+ Hits        63887    63901      +14     
- Misses      12566    12611      +45     
- Partials     1174     1176       +2     

☔ View full report in Codecov by Sentry.
📢 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.

Switch DeepEval.serialize() to delegate to DeepEvalBackend.serialize(), and implement serialize() in each backend by calling the underlying model's serialize().

Also move Node import in dp show to module top-level.

Authored by OpenClaw (model: gpt-5.2)
@njzjz-bot
Copy link
Contributor Author

Refactor update (per feedback): switch from Backend.serialize_hook() wrapper to a backend-native DeepEvalBackend.serialize() API.

  • DeepEvalBackend.serialize() added as an abstract method
  • DeepEval.serialize() now only delegates to self.deep_eval.serialize()
  • Implemented serialize() in TF/PT/PD/DPModel/JAX/pt_expt DeepEval backends by directly calling the underlying model's serialize() (or equivalent TF Model init+serialize flow)
  • dp show ... serialization-tree: moved Node import to module top-level
  • pretrained: PretrainedDeepEvalBackend.serialize() delegates to resolved backend

Latest commit: 1694360

Authored by OpenClaw (model: gpt-5.2)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deepmd/pt_expt/infer/deep_eval.py`:
- Around line 668-673: serialize() currently returns the raw model_dict from
serialize_from_file(self.model_path) but callers (e.g., the CLI in show.py)
expect a wrapper with keys "backend", "model", "model_def_script", and
"@variables"; change serialize() in the class to call
serialize_from_file(self.model_path), then construct and return a dict like
{"backend": "<appropriate backend name or value from model_dict if available>",
"model": model_dict, "model_def_script": <script or None>, "@variables": <vars
dict or empty dict>} so the returned structure contains those keys; ensure you
pull any available values from model_dict to populate "backend",
"model_def_script", and "@variables" or set sensible defaults if missing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f7533fe2-e54e-4e12-ae64-e1712fa5c00b

📥 Commits

Reviewing files that changed from the base of the PR and between b695aaa and 1694360.

📒 Files selected for processing (9)
  • deepmd/dpmodel/infer/deep_eval.py
  • deepmd/entrypoints/show.py
  • deepmd/infer/deep_eval.py
  • deepmd/jax/infer/deep_eval.py
  • deepmd/pd/infer/deep_eval.py
  • deepmd/pretrained/deep_eval.py
  • deepmd/pt/infer/deep_eval.py
  • deepmd/pt_expt/infer/deep_eval.py
  • deepmd/tf/infer/deep_eval.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • deepmd/entrypoints/show.py

Comment on lines +668 to +673
def serialize(self) -> dict[str, Any]:
from deepmd.pt_expt.utils.serialization import (
serialize_from_file,
)

return serialize_from_file(self.model_path)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Contract violation: Missing wrapper structure for serialized output.

Per the relevant code snippet from deepmd/pt_expt/utils/serialization.py:201-220, serialize_from_file() returns only the raw model_dict, not the expected wrapper structure with "backend", "model", "model_def_script", and "@variables" keys.

The CLI consumer at deepmd/entrypoints/show.py:143-148 expects data["model"] to exist:

if "model" not in data:
    raise RuntimeError("Serialized model data does not contain key 'model'.")

This will cause a RuntimeError when users run dp show model.pte serialization-tree.

🐛 Proposed fix to wrap the serialized output
     def serialize(self) -> dict[str, Any]:
         from deepmd.pt_expt.utils.serialization import (
             serialize_from_file,
         )

-        return serialize_from_file(self.model_path)
+        model_dict = serialize_from_file(self.model_path)
+        data: dict[str, Any] = {
+            "backend": "PyTorch Exportable",
+            "model": model_dict,
+            "model_def_script": self.get_model_def_script(),
+            "@variables": {},
+        }
+        return data
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deepmd/pt_expt/infer/deep_eval.py` around lines 668 - 673, serialize()
currently returns the raw model_dict from serialize_from_file(self.model_path)
but callers (e.g., the CLI in show.py) expect a wrapper with keys "backend",
"model", "model_def_script", and "@variables"; change serialize() in the class
to call serialize_from_file(self.model_path), then construct and return a dict
like {"backend": "<appropriate backend name or value from model_dict if
available>", "model": model_dict, "model_def_script": <script or None>,
"@variables": <vars dict or empty dict>} so the returned structure contains
those keys; ensure you pull any available values from model_dict to populate
"backend", "model_def_script", and "@variables" or set sensible defaults if
missing.

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.

1 participant