Skip to content

Conversation

@zucchini-nlp
Copy link
Member

@zucchini-nlp zucchini-nlp commented Nov 12, 2025

What does this PR do?

As per title, blocked by #41589 for VLMs! We should be able to use get_decoder() to get the LM part of any model after this and have much less duplicate code. Same foes for the get_encoder() to get the encoder if the model has a separate encoding module. In comparison to decoder, we can have specific encoder per modality so the helper will accept modality as arg

Universal helper first reduces duplicate code, nudges us to use standardized names for major modules and can be used by 3rd party libraries. Right now we have 5 ways to name a vision encoder!

🚨 Breaking changes, ig we can break helpers for v5:

  • VLMs now will not have a property to get self.language_model directly from task-model and users will need to call self.get_decoder()
  • Deleted get_text_encoder and get_audio_encoder in some audio models because functionality is covered now by the get_encoder()

@HuggingFaceDocBuilderDev

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@zucchini-nlp zucchini-nlp changed the title [WIP] Generalize get_decoder() for multimodal and delete redundant code 🔪 🚨 Generalize get_decoder() for multimodal and delete redundant code 🔪 Nov 13, 2025
@github-actions
Copy link
Contributor

[For maintainers] Suggested jobs to run (before merge)

run-slow: aria, autoformer, aya_vision, bart, bigbird_pegasus, blenderbot, blenderbot_small, blip_2, cohere2_vision, conditional_detr, d_fine, dab_detr, deformable_detr, detr, dia, emu3

model = GPT2LMHeadModel(cfg)
dec = model.get_decoder()

assert dec is model, f"GPT2 get_decoder() should return self (fallback), got {type(dec)}"
Copy link
Member Author

@zucchini-nlp zucchini-nlp Nov 13, 2025

Choose a reason for hiding this comment

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

prev helper didn't cover all edge cases! This should be the base model, if we compare with other LLMs (e.g. llama)

Copy link
Contributor

@molbap molbap left a comment

Choose a reason for hiding this comment

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

Very nice unbloating 🔪
OK for me, just would be cool to add to the make style/ruff rules/quality check to reduce cognitive load

Symmetric setter. Mirrors the lookup logic used in `get_encoder`.
"""

# NOTE: new models need to use existing names for layers if possible, so this list doesn't grow infinitely
Copy link
Contributor

Choose a reason for hiding this comment

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

To note, this should be enforced in make fixup in code consistency part to save ourselves the hassle

Copy link
Member Author

Choose a reason for hiding this comment

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

hmm, isn't it going to be a huge limitation for contributors if we force it and auto-renam with fix-copies? Imo we need to communicate it when reviewing and explain why it's important. It's only a few ppl reviewing VLMs currently, so it might be easier

):
# 1. get audio encoder
encoder = self.get_audio_encoder()
encoder = self.get_encoder(modality="audio")
Copy link
Contributor

Choose a reason for hiding this comment

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

ah I see now, ok, it's a good thing it's decoupled from the kwargs actually. So, the logic is

  • if I don't set the modality: defaults to text encoder
  • If I set the modality, checks possible module names
  • If I override get_encoder it's whatever I want

Not 100% sure about the modality arg but I see the motivation, understood

Copy link
Member Author

@zucchini-nlp zucchini-nlp Nov 14, 2025

Choose a reason for hiding this comment

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

Yep, the idea is to allow users to ask for modality encoder through single interface, instead of having each as self.get_vision_encoder/self.get_audio_encoder etc.

Just added tests to make sure it works

@zucchini-nlp
Copy link
Member Author

Merge conflicts after a big refactor 😢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants