Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PEFT models in pipelines #29517

Closed
wants to merge 2 commits into from
Closed

Conversation

Rocketknight1
Copy link
Member

@Rocketknight1 Rocketknight1 commented Mar 7, 2024

Our pipelines check for supported classes but aren't PEFT-aware, so they get confused and throw errors for PEFT models. This PR changes the supported class check to use the actual underlying model of a PEFT model.

Fixes #29395

@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.

@Rocketknight1 Rocketknight1 force-pushed the fix_peft_model_in_pipelines branch 2 times, most recently from 3df8ecc to cbf796b Compare March 8, 2024 13:21
@Rocketknight1 Rocketknight1 force-pushed the fix_peft_model_in_pipelines branch from 0d10267 to 0cf09f8 Compare March 11, 2024 14:34
@Rocketknight1
Copy link
Member Author

Hi @B-Step62, this branch should fix the issue now! Try pip install --upgrade git+https://github.com/huggingface/transformers.git@fix_peft_model_in_pipelines and let me know if you have any issues. The example you sent me seems to be working now.

If you don't find any further problems, I'll ping for core maintainer review and merge this soon.

@B-Step62
Copy link
Contributor

Thanks for the quick fix, @Rocketknight1! I have tested my examples and confirmed the error message no longer is printed:)

@Rocketknight1
Copy link
Member Author

cc @amyeroberts for core maintainer review in that case

Copy link
Collaborator

@amyeroberts amyeroberts left a comment

Choose a reason for hiding this comment

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

Thanks for adding this support!

Change looks good - just a request to abstract out the peft model check

@@ -1038,7 +1038,12 @@ def check_model_type(self, supported_models: Union[List[str], dict]):
else:
supported_models_names.append(model.__name__)
supported_models = supported_models_names
if self.model.__class__.__name__ not in supported_models:
if "Peft" in self.model.__class__.__name__ and hasattr(self.model, "base_model"):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm, checking if Peft is in the name seems like a flaky way to check this.

What I'd suggest is adding a more general is_peft_model utility under modeling_utils.py which is tested (and we check with @younesbelkada is correct) which can then be used everywhere. It should also check is_peft_available.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes you can do if the model is an isntance of Peftxxx class, however we do support already peft model inference: https://huggingface.co/docs/transformers/peft , users that pass a Peftxxx class can be considered as bad intent, as they only need to pass a valid path to an adapter model or first load a peft model using AutoModelForxxx and pass that to the pipeline. See for example:

def test_peft_pipeline(self):

Copy link
Contributor

@younesbelkada younesbelkada left a comment

Choose a reason for hiding this comment

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

Thanks for the PR !
IMO we shouldn't support that and rather educate the users properly on how to use PEFT + pipeline --> first load the peft adapter with AutoModelxxx interface then pass that model to the pipeline or pass a valid path to a Peft model!
See my comment here: #29517 (comment)

@younesbelkada
Copy link
Contributor

Also note creating a brand new PEFT model with get_peft_model will lead to having a model with random adapter weights attached on it, therefore you'll mostl likely get gibberish output, I think that's also a bad intent as well :/
The typical workflow should be
1- train your adapters with PEFT
2- push them / save them somewhere after training
3- load them back with AutoModelxxx interface
4- do whatever
What do you think?

@Rocketknight1
Copy link
Member Author

My bad! Your solution sounds good - I guess we can close this PR and just post something in the original issue at #29395

@younesbelkada
Copy link
Contributor

ok ok sounds good! sorry for being responsive late 😭 ok yes the proposed plan sounds good!

@B-Step62
Copy link
Contributor

Thank you for working on this issue @younesbelkada @Rocketknight1 !

2- push them / save them somewhere after training
3- load them back with AutoModelxxx interface

Unfortunately, this solution doesn't work as it is in our case. We want to save/load the adapter (+ the base model and tokenizer) locally as pipeline, without needing to interaction with the hub, to avoid the flakiness of downloading heavy files over network. Let me ask a few follow-up questions with this regards:

  • Is there a way to casting the PEFT model into AutoModelxxx without pushing to the hub?
  • Also vice-versa, once loading the model as AutoModelxxx, can we distinguish it is a PEFT model? It seems is_peft_model uses isinstance so my guess is it doesn't work.

@younesbelkada
Copy link
Contributor

Thanks @B-Step62 for the clarification !
1- Yes you can also save it locally
2- When you load a peft model as AutoModelxxx you can distinguish if it's a peft model by looking into the attribute _hf_peft_config_loaded: getattr(model, "_hf_peft_config_loaded", False)

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.

False-alarm when constructing a pipeline with PEFT models
5 participants