Model Packaging¶
The NequIP packaging system creates portable, version-independent model archives using PyTorch’s torch.package infrastructure.
Overview¶
Packaging converts checkpoint files (.ckpt) into package files (.nequip.zip) that solve the portability problem inherent in checkpoint files. While checkpoint files are tied to specific software versions and may not load in different environments, package files bundle both the model and the code needed to run it, making them largely version-independent.
A package file contains:
Model weights and architecture
Snapshot of the implementation code
Metadata and configuration
Example data for compilation
For user-facing information on packaging workflows and CLI usage, see the packaging workflow and package files overview in the user guide.
Developer Notes¶
Package Format Versioning¶
The packaging system uses _CURRENT_NEQUIP_PACKAGE_VERSION to track when the packaging mechanism has changed. This counter is incremented whenever breaking changes are made to the package format, as these changes represent the main barrier to maintaining backwards compatibility of packaged models. The ModelFromPackage() loader includes logic to handle different package format versions based on this counter.
Dependency Management¶
The packaging system handles dependencies by categorizing Python modules into three types:
Internal: Core NequIP code (
nequip,e3nn) - gets packaged with the modelExternal: Large libraries (
numpy,triton) - expected to be available in the target environmentMock: Optional dependencies (
matplotlib) - imports are allowed but runtime usage raises errors
Developers of NequIP extension packages can register custom dependencies using the module registration system. This function allows extension packages to properly categorize their dependencies, ensuring they are handled correctly during packaging. Libraries with custom C++/CUDA ops or large stable third-party libraries should typically be registered as external, while optional dependencies can be mocked.
- nequip.scripts._package_utils.register_libraries_as_external_for_packaging(extern_modules: Iterable[str] | None = None, mock_modules: Iterable[str] | None = None) None[source]¶
Register a library as “external” or mocked for packaging.
Registers an entire top-level library as “extern” for packaging. This prevents any code from that library from being included in the package file.
Two primary types of libraries should be registered as external:
Libraries that provide custom C++ or CUDA ops in PyTorch, for example OpenEquivariance.
Large and stable third-party, non-PyTorch libraries like NumPy.
NequIP extension packages should never be registered as extern, and issues that seem to suggest that doing so is necessary should almost certainly be solved through refactoring the code to make it compatible with being interned.
Warning
Registering a library as extern means that a compatible version of that library must be installed in the environment where the package is run or used. This significantly complicates dependency management for packaged models and should be avoided as much as possible.
Mocking libraries is useful for libraries that are not required to run the model, but are used in the code that is packaged. This allows code that imports the mocked module to be packaged, but if any code actually tries to use the mocked module, it will raise an error. For example, we mock
matplotlibby default.Tip
Refactoring code to avoid unnecessary imports in packaged code is always preferred over registering libraries as external or mock modules.
See
_DEFAULT_EXTERNAL_MODULESand_DEFAULT_MOCK_MODULESfor the defaults.
Repackaging Support¶
The system includes complex logic to handle creating packages from other packages while maintaining proper importer chains. During repackaging, shared importers ensure all models come from the same source, which is required by PyTorch’s packaging infrastructure.