Skip to content

Having a "scale" parameter for text encoder lora layers #3480

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

Closed
abhijitpal1247 opened this issue May 18, 2023 · 9 comments
Closed

Having a "scale" parameter for text encoder lora layers #3480

abhijitpal1247 opened this issue May 18, 2023 · 9 comments

Comments

@abhijitpal1247
Copy link

Is your feature request related to a problem? Please describe.
No, not related to a problem

Describe the solution you'd like
A similar parameter to "scale" of unet lora layers, in case of text encoder lora layers

Additional context
This is an inference parameter that will determine the influence of text encoder lora layers on generation

@patrickvonplaten
Copy link
Contributor

cc @sayakpaul

@sayakpaul
Copy link
Member

This question has come before a few times.

I am wondering about what would be the best option to support this currently. Here are some thoughts:

  • Pass an additional parameter called text_encoder_scale to load_lora_weights() as a kwarg. Note that we cannot do it during the runtime (e.g., pipe("A pokemon with blue eyes.", cross_attention_kwargs={"scale": 0.5}) because of the way LoRA is implemented for the text encoder (using monkey-patching).
  • If the text_encoder_scale is passed, then the monkey patch call will be modified maybe like so:
...
text_encoder_scale = kwargs.pop("text_encoder_scale", 1.0)

def new_forward(x):
    return old_forward(x) + lora_layer(x, scale=text_encoder_scale)

^ should be fine since LoRAAttnProcessor supports the scale argument in its call().

WDYT @patrickvonplaten?

@patrickvonplaten
Copy link
Contributor

Hmm yeah good question! I wonder whether we could do something ugly here:

def new_forward(x):

                def new_forward(x):
                    return old_forward(x) + lora_layer(x)

                # Monkey-patch.
                module.forward = new_forward

could be changed to

                def new_forward(x):
                    return old_forward(x) + self.scale * lora_layer(x)

                # Monkey-patch.
                module.forward = new_forward

and then we add a scale property to:

class LoraLoaderMixin:

@property
def scale(self):
    return self._scale

and a scale setter function that we need to call from the _encode_prompt method. Could this make sense?

@sayakpaul
Copy link
Member

Where does self._scale come from? The pipeline call?

@patrickvonplaten
Copy link
Contributor

Yes self._scale is overwritten when calling the pipeline

@sayakpaul
Copy link
Member

@patrickvonplaten sorry still a bit unclear to me.

Yes self._scale is overwritten when calling the pipeline

To enable this we still need to expose an argument corresponding to the text encoder LoRA scale, no?

@patrickvonplaten
Copy link
Contributor

@sayakpaul would this help: #3626 (comment)

@sayakpaul
Copy link
Member

Thanks @patrickvonplaten! I left some comments there.

@sayakpaul
Copy link
Member

sayakpaul commented Jun 7, 2023

Closing with #3626

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

No branches or pull requests

3 participants