Skip to content

Added Model.from_pretrained method to load a pretrained model - #169

Merged
copybara-service[bot] merged 1 commit into
jax-ml:mainfrom
vfdev-5:model-from_pretrained
Mar 4, 2026
Merged

Added Model.from_pretrained method to load a pretrained model#169
copybara-service[bot] merged 1 commit into
jax-ml:mainfrom
vfdev-5:model-from_pretrained

Conversation

@vfdev-5

@vfdev-5 vfdev-5 commented Feb 17, 2026

Copy link
Copy Markdown
Member

Description:

  • added classmethod from_pretrained to models
  • added/renamed model's attribute cfg into config
  • replaced the code to load pretrained weights with the new API
  • exposed qwen3vl as from bonsai.models import Qwen3VLForConditionalGeneration

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @vfdev-5, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a standardized from_pretrained class method across several model architectures, including ConvNeXt, DenseNet, Dinov3ViTModel, and EfficientNet. This enhancement simplifies the process of loading pre-trained weights from external sources like Hugging Face Hub or timm, directly into the model instances. The changes aim to improve usability and streamline the integration of pre-trained models within the framework.

Highlights

  • Standardized Pre-trained Model Loading: Added from_pretrained class methods to ConvNeXt, DenseNet, Dinov3ViTModel, and EfficientNet models, enabling direct loading of pre-trained weights from Hugging Face Hub or timm.
  • Expanded DenseNet Configurations: Introduced densenet_169 and densenet_201 configurations to the DenseNet model, providing more architectural options.
  • Refactored Parameter Mapping: Improved parameter mapping logic for Dinov3ViTModel and EfficientNet to support different weight sources and ensure correct weight assignment.
  • Updated Example Usage: Modified example run_model.py scripts for ConvNeXt, DenseNet, and EfficientNet to demonstrate the new, simplified from_pretrained functionality.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • bonsai/models/convnext/modeling.py
    • Added from_pretrained class method to ConvNeXt for loading models from Hugging Face Hub.
  • bonsai/models/convnext/tests/run_model.py
    • Updated model loading to use the new ConvNeXt.from_pretrained method.
    • Adjusted comment numbering for execution steps.
  • bonsai/models/densenet121/modeling.py
    • Added densenet_169 and densenet_201 class methods to ModelConfig.
    • Added from_pretrained class method to DenseNet for loading models from Hugging Face Hub.
  • bonsai/models/densenet121/params.py
    • Modified the regex for the final batch normalization layer in _get_key_and_transform_mapping to be more dynamic.
  • bonsai/models/densenet121/tests/run_model.py
    • Updated model loading to use the new DenseNet.from_pretrained method.
  • bonsai/models/dinov3/modeling.py
    • Added from_pretrained class method to Dinov3ViTModel for loading models from Hugging Face Hub.
  • bonsai/models/dinov3/params.py
    • Modified _get_key_and_transform_mapping to accept a mapping_type argument, supporting 'original' and 'timm' mappings.
  • bonsai/models/efficientnet/modeling.py
    • Added from_pretrained class method to EfficientNet for loading models from timm.
  • bonsai/models/efficientnet/params.py
    • Imported timm locally within get_timm_pretrained_weights.
    • Added mapping_version argument to _get_key_and_transform_mapping to handle different mapping structures.
    • Introduced _create_model_from_timm function to encapsulate the logic for loading and converting timm weights.
  • bonsai/models/efficientnet/tests/run_model.py
    • Updated model loading to use the new EfficientNet.from_pretrained method.
Activity
  • The pull request is currently marked as Work In Progress (WIP).
  • No specific review comments or activities have been recorded yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@vfdev-5
vfdev-5 force-pushed the model-from_pretrained branch from 7a5f8fc to 5f091d3 Compare February 17, 2026 16:52

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a from_pretrained method across several models, which is a fantastic enhancement for usability. The implementation is largely consistent and simplifies model loading from external sources like Hugging Face Hub and timm. My review focuses on improving docstrings and code structure for maintainability. I've also identified a few significant issues in the dinov3 model implementation related to loading weights from timm, which will need to be addressed for the feature to work correctly.

I am having trouble creating individual review comments. Click here to see my feedback.

bonsai/models/dinov3/params.py (59-93)

critical

The weight name mapping for timm models appears to be incorrect and incomplete.

  • Many regex patterns (e.g., for k_proj, v_proj, o_proj) seem to be copy-pasted from the original mapping and use layer... instead of the timm convention blocks....
  • The mapping for blocks.([0-9]+).attn.proj.weight to q_proj.kernel is likely wrong. In timm, proj is the output projection, so it should map to o_proj.kernel.
  • There is no mapping for timm's qkv.weight, which combines query, key, and value weights. This tensor would need to be split and mapped to q_proj, k_proj, and v_proj in the bonsai model.

This is a critical issue that will prevent timm models from being loaded correctly.

bonsai/models/dinov3/modeling.py (352)

high

There's an issue with loading timm models like timm/vit_small_patch16_dinov3.lvd1689m. The create_model_from_safe_tensors function is called without specifying the mapping_type, so it defaults to "original". This will use the wrong weight name mapping for a timm model, causing loading to fail.

You should detect the model source (e.g., by checking if model_name starts with "timm/") and pass the appropriate mapping_type to create_model_from_safe_tensors.

bonsai/models/convnext/modeling.py (145-161)

medium

There are a couple of improvements that can be made here:

  1. Docstring: The docstring could be more descriptive, following a standard format (e.g., Google style) to explain the method's purpose, arguments, and return value.
  2. config_map: This dictionary is redefined on every method call. It would be more efficient to define it as a class-level constant.

Here is an example of how you could refactor this:

class ConvNeXt(nnx.Module):
    _PRETRAINED_CONFIGS = {
        "facebook/convnext-tiny-224": ModelConfig.convnext_tiny_224,
        "facebook/convnext-small-224": ModelConfig.convnext_small_224,
        "facebook/convnext-base-224": ModelConfig.convnext_base_224,
        "facebook/convnext-large-224": ModelConfig.convnext_large_224,
    }

    # ... other methods

    @classmethod
    def from_pretrained(cls, model_name: str, config: ModelConfig | None = None):
        """Loads a pretrained ConvNeXt model from a Hugging Face Hub repository.

        Args:
            model_name: The *model id* of a pretrained model on huggingface.co.
            config: An optional `ModelConfig` to override the default configuration.

        Returns:
            A `ConvNeXt` model instance with pretrained weights.
        """
        from huggingface_hub import snapshot_download
        from bonsai.models.convnext import params

        if config is None:
            if model_name not in cls._PRETRAINED_CONFIGS:
                raise ValueError(f"Model name '{model_name}' is unknown, please provide config argument")
            config = cls._PRETRAINED_CONFIGS[model_name]()

        # ... rest of the method

bonsai/models/densenet121/modeling.py (139-154)

medium

Similar to other models in this PR, the docstring could be more descriptive, and the config_map could be defined as a class-level constant for efficiency and better organization.

Here's an example of how you could apply this pattern:

class DenseNet(nnx.Module):
    _PRETRAINED_CONFIGS = {
        "keras/densenet_121_imagenet": ModelConfig.densenet_121,
        "keras/densenet_169_imagenet": ModelConfig.densenet_169,
        "keras/densenet_201_imagenet": ModelConfig.densenet_201,
    }

    # ... other methods

    @classmethod
    def from_pretrained(cls, model_name: str, config: ModelConfig | None = None):
        """Loads a pretrained DenseNet model from a Hugging Face Hub repository.

        Args:
            model_name: The *model id* of a pretrained model on huggingface.co.
            config: An optional `ModelConfig` to override the default configuration.

        Returns:
            A `DenseNet` model instance with pretrained weights.
        """
        from huggingface_hub import snapshot_download
        from bonsai.models.densenet121 import params

        if config is None:
            if model_name not in cls._PRETRAINED_CONFIGS:
                raise ValueError(f"Model name '{model_name}' is unknown, please provide config argument")
            config = cls._PRETRAINED_CONFIGS[model_name]()

        # ... rest of the method

bonsai/models/dinov3/modeling.py (329-349)

medium

For consistency and maintainability, consider improving the docstring and moving the config_map to a class-level constant. This avoids redefining the dictionary on each call.

Here's a suggested refactoring:

class Dinov3ViTModel(nnx.Module):
    _PRETRAINED_CONFIGS = {
        "facebook/dinov3-vits16-pretrain-lvd1689m": ModelConfig.dinov3_vits16,
        "timm/vit_small_patch16_dinov3.lvd1689m": ModelConfig.dinov3_vits16,
        # ... other models
    }

    # ... other methods

    @classmethod
    def from_pretrained(cls, model_name: str, config: ModelConfig | None = None):
        """Loads a pretrained DINOv3 model from a Hugging Face Hub repository.

        Args:
            model_name: The *model id* of a pretrained model on huggingface.co.
            config: An optional `ModelConfig` to override the default configuration.

        Returns:
            A `Dinov3ViTModel` instance with pretrained weights.
        """
        # ... implementation using cls._PRETRAINED_CONFIGS

bonsai/models/efficientnet/modeling.py (330-353)

medium

Similar to other models in this PR, the config_map is redefined on every call. It would be more efficient to define it as a class-level constant. The docstring is good, but for consistency with other models, I'm suggesting a similar refactor.

class EfficientNet(nnx.Module):
    _PRETRAINED_CONFIGS = {
        "efficientnet_b0": ModelConfig.b0,
        "efficientnet_b1": ModelConfig.b1,
        "efficientnet_b2": ModelConfig.b2,
        "efficientnet_b3": ModelConfig.b3,
        "efficientnet_b4": ModelConfig.b4,
        "efficientnet_b5": ModelConfig.b5,
        "efficientnet_b6": ModelConfig.b6,
        "efficientnet_b7": ModelConfig.b7,
    }

    # ... other methods

    @classmethod
    def from_pretrained(cls, model_name: str, config: ModelConfig | None = None):
        # ...
        if config is not None:
            raise ValueError("config must be None when using EfficientNet.from_pretrained")

        if model_name not in cls._PRETRAINED_CONFIGS:
            raise ValueError(f"Model name '{model_name}' is unknown, please provide config argument")

        config = cls._PRETRAINED_CONFIGS[model_name]()
        return params._create_model_from_timm(model_name, config)

@vfdev-5
vfdev-5 force-pushed the model-from_pretrained branch 6 times, most recently from f5f2901 to 5ce1a9d Compare February 18, 2026 01:02
@vfdev-5
vfdev-5 marked this pull request as ready for review February 18, 2026 17:51
@vfdev-5 vfdev-5 changed the title [WIP] Added Model.from_pretrained method to load a pretrained model Added Model.from_pretrained method to load a pretrained model Feb 18, 2026
@jenriver

Copy link
Copy Markdown
Member

@vfdev-5 Hi Victor, could you fix the merge conflicts above?

@vfdev-5
vfdev-5 force-pushed the model-from_pretrained branch 2 times, most recently from c802c48 to 585ca40 Compare February 20, 2026 17:34
@vfdev-5

vfdev-5 commented Feb 23, 2026

Copy link
Copy Markdown
Member Author

@jenriver Hi Jen, I fixed the conflict, we can move forward with this PR, thanks!

@vfdev-5
vfdev-5 force-pushed the model-from_pretrained branch from b0e06cf to 0cdb0e2 Compare March 3, 2026 09:45
@copybara-service
copybara-service Bot merged commit d2f340a into jax-ml:main Mar 4, 2026
5 checks passed
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.

3 participants