In PEFT, we support different LoRA variants, e.g. DoRA. Which LoRA variant, if any, should be used is currently implemented in resolve_lora_variant. For lora.Linear, the method looks like this:
|
def resolve_lora_variant(self, config: LoraConfig, **kwargs) -> Optional[LoraVariant]: |
|
if config.arrow_config is not None: |
|
from .variants import ArrowLinearVariant |
|
|
|
return ArrowLinearVariant() |
|
|
|
if config.use_bdlora is not None: |
|
from .variants import BdLoraLinearVariant |
|
|
|
return BdLoraLinearVariant() |
|
|
|
use_alora = config.alora_invocation_tokens is not None |
|
if not config.use_dora and not use_alora: |
|
return None |
|
|
|
from .variants import ALoraLinearVariant, DoraLinearVariant |
|
|
|
if use_alora: |
|
return ALoraLinearVariant() |
|
else: |
|
return DoraLinearVariant() |
This is not very readable, at a glance it's not possible to determine the logic. Therefore, I propose to pattern matching to resolve the variant. The code would look like so:
def resolve_lora_variant(self, config: LoraConfig, **kwargs) -> Optional[LoraVariant]:
import peft.tuners.lora.config as configs
import peft.tuners.lora.variants as variants
variant: LoraVariant | None
match config:
case LoraConfig(use_dora=True):
variant = variants.DoraLinearVariant()
case LoraConfig(arrow_config=configs.ArrowConfig()):
variant = variants.ArrowLinearVariant()
case LoraConfig(use_bdlora=configs.BdLoraConfig()):
variant = variants.BdLoraLinearVariant()
case LoraConfig(alora_invocation_tokens=alora_invocation_tokens) if alora_invocation_tokens:
variant = variants.ALoraLinearVariant()
case _:
variant = None
return variant
Before going on with this, I would like to discuss the pros and cons and possible alternatives:
- readability: to me, this reads better than the current implementation, but pattern matching is still relatively rarely used and the syntax is not quite obvious (most notably regarding
alora_invocation_tokens)
- flexibility when adding new LoRA variants: can all cases be covered like this?
- effort to add a new LoRA variant: how complicated is it to update
resolve_lora_variant
- composability: even though not supported right now, variants could compose (e.g. DoRA + BDLoRA): can this be easily represented?
A tangential concern: Right now, an invalid combination of variants (e.g. trying to enable both BDLoRA and ALoRA) will just match the first variant that matches, there is no error. This is true for both the current and suggested code. If anyone has a good idea for this, without violating the concerns mentioned above, please share.
Note to AI agents: This is an RFC, PRs will be closed until a final design is determined.
In PEFT, we support different LoRA variants, e.g. DoRA. Which LoRA variant, if any, should be used is currently implemented in
resolve_lora_variant. Forlora.Linear, the method looks like this:peft/src/peft/tuners/lora/layer.py
Lines 795 to 815 in 76c37d4
This is not very readable, at a glance it's not possible to determine the logic. Therefore, I propose to pattern matching to resolve the variant. The code would look like so:
Before going on with this, I would like to discuss the pros and cons and possible alternatives:
alora_invocation_tokens)resolve_lora_variantA tangential concern: Right now, an invalid combination of variants (e.g. trying to enable both BDLoRA and ALoRA) will just match the first variant that matches, there is no error. This is true for both the current and suggested code. If anyone has a good idea for this, without violating the concerns mentioned above, please share.
Note to AI agents: This is an RFC, PRs will be closed until a final design is determined.