Conversation
Add archivers for HuggingFace transformers models and processors: - HuggingFaceModelArchiver: handles all PreTrainedModel subclasses - Dynamic architecture detection from config.json - PEFT/LoRA adapter save/load support - Auto-registers for PreTrainedModel base class - HuggingFaceProcessorArchiver: handles tokenizers and processors - Supports AutoProcessor, AutoTokenizer, AutoImageProcessor - Auto-detects processor type on load - Registers for PreTrainedTokenizerBase, ProcessorMixin, etc. Includes unit tests for both archivers. Tested with ViT, Mask2Former, and BERT models.
- Add TimmModelArchiver for PyTorch Image Models (timm) library - Saves model config (architecture, num_classes, etc.) and state_dict - Loads models using timm.create_model() with saved configuration - Add optional dependencies in pyproject.toml for ML frameworks: - timm, huggingface (transformers+peft), ultralytics, ml (all) - Add unit tests with full coverage
- Add OnnxModelArchiver for ONNX models (ModelProto) - Saves model.onnx file and metadata.json with opset info - Extracts input/output names, producer info, graph metadata - Add onnx + onnxruntime to optional dependencies - Add unit tests with full coverage
- Add TensorRTEngineArchiver for TensorRT inference engines - Saves engine.trt file and metadata.json with binding info - Extracts input/output tensor names, shapes, dtypes - Add CUDA-specific optional deps: tensorrt-cu11, tensorrt-cu12 - Remove generic 'ml' extra (too hardware-specific) - Add unit tests (skip when TensorRT unavailable)
- Use fallback ASSOCIATED_TYPES when optional libs not installed - HuggingFace: use nn.Module as fallback, add ImportError checks - ONNX/TensorRT: use object as fallback to prevent ZenML errors - All archivers now raise ImportError with clear message if lib missing
Add module-level pytest.mark.skipif decorators to skip tests when optional dependencies (transformers, timm, onnx, tensorrt) are not installed. This fixes CI failures where tests attempted to patch modules that don't exist. Also applied ruff formatting to archiver source files.
There was a problem hiding this comment.
missing archiver registration at the end
There was a problem hiding this comment.
missing archiver registration
There was a problem hiding this comment.
missing archiver registration
| def _register_timm_archiver(): | ||
| """Register the timm archiver if timm is available.""" | ||
| if not _TIMM_AVAILABLE: | ||
| return | ||
|
|
||
| # We can't easily get a base class for all timm models, | ||
| # so we register a custom type checker | ||
| # For now, users need to import this module to enable timm archiving | ||
| # The archiver will be selected based on _is_timm_model check |
There was a problem hiding this comment.
register archiver not doing anything.
the check happens in save() here, but registry needs to know beforehand so that we can reach save()
mindtrace/registry/pyproject.toml
Outdated
| tensorrt-cu11 = ["tensorrt-cu11>=8.6"] | ||
| tensorrt-cu12 = ["tensorrt-cu12>=10.0"] |
There was a problem hiding this comment.
uv sync (without extras) ended up spending ~10 mins to build the tensorrt packages and not installing.
|
@Yasserelhaddar @JeremyWurbs , given that these archivers introduce very "models"-related dependencies, does it make sense to move them to the |
| """ | ||
|
|
||
| # HuggingFace models are nn.Module subclasses | ||
| ASSOCIATED_TYPES: ClassVar[Tuple[Type[Any], ...]] = (nn.Module,) |
There was a problem hiding this comment.
HF Model archiver associated with all nn.Modules.
Should be for PreTrainedModel?
| def __init__(self, uri: str, **kwargs): | ||
| super().__init__(uri=uri, **kwargs) | ||
|
|
||
| def _is_hf_model(self, model: Any) -> bool: |
There was a problem hiding this comment.
function not used anywhere
| """ | ||
|
|
||
| # timm models are nn.Module but we identify them via pretrained_cfg attribute | ||
| ASSOCIATED_TYPES: ClassVar[Tuple[Type[Any], ...]] = (nn.Module,) |
There was a problem hiding this comment.
also associating with nn.Module.
Let's add integration tests that test with minimal but real models (can be skipped when deps not installed, like the unit tests). e.g. What happens when a generic nn.Module is saved in registry, which archiver would be selected?
| self.logger.debug(f"Saved PEFT adapter to {adapter_dir}") | ||
|
|
||
| except ImportError: | ||
| # PEFT not installed, skip adapter saving |
There was a problem hiding this comment.
this should be an error. otherwise we are silently saving an incomplete model. confusing behaviour for users.
| config["architecture"] = model.pretrained_cfg.get("architecture", "unknown") | ||
| # Store full pretrained_cfg for reference | ||
| config["pretrained_cfg"] = { | ||
| k: v for k, v in model.pretrained_cfg.items() if isinstance(v, (str, int, float, bool, list, tuple)) | ||
| } | ||
| elif hasattr(model, "default_cfg") and model.default_cfg: | ||
| config["architecture"] = model.default_cfg.get("architecture", "unknown") |
There was a problem hiding this comment.
what happens on loading a model that got saved with architecture "unknown"?
| self.logger.debug(f"Loaded HuggingFace processor from {self.uri}") | ||
| return processor | ||
| except Exception: | ||
| pass |
There was a problem hiding this comment.
logging the exception can help in debugging.
the RuntimeError raised at the end might not have the relevant details.
…spatch Archiver modules must be imported after register_default_materializers() so their _register_*_archiver() functions populate the dispatch table. Without this, models fell through to ZenML generic materializers.
- Register PeftModel for correct dispatch (MRO skips PreTrainedModel) - Save PeftModel via deep-copy + merge_and_unload for clean state dict - Preserve adapter config/weights in adapter/ dir for provenance - Skip adapter re-injection on load when weights were already merged - Minor fixes to optional dependency guards in other ML archivers
…ion tests - 10 new unit tests for PeftModel detection, merge-and-save, merged-load skip, dispatch routing, and PeftModel registration - Integration dispatch tests verify all ML archivers resolve correctly
Covers 24 roundtrip tests across timm, HuggingFace, PEFT, processors, ONNX, TensorRT, and Ultralytics with output verification.
Summary
Adds archivers for popular ML frameworks to the mindtrace-registry, enabling seamless save/load of models via the Registry system.
Why We Need This
The Registry currently supports basic types and Ultralytics models. ML workflows commonly use models from other frameworks that require manual serialization:
These archivers provide:
registry.save()/registry.load()for all model typesUsage Examples
HuggingFace Model
timm Model
ONNX Model
TensorRT Engine
What's Included
HuggingFaceModelArchiverPreTrainedModel+ PEFTadapter/dirHuggingFaceProcessorArchiverTimmModelArchiverconfig.json+model.ptOnnxModelArchiveronnx.ModelProtomodel.onnx+metadata.jsonTensorRTEngineArchivertrt.ICudaEngineengine.trt+metadata.jsonDependencies
pyproject.toml:huggingface: transformers, pefttimm: timmonnx: onnxtensorrt: tensorrtNotes