【diffusers 进阶之 PEFT 入门(二)】LoraConfig 如何处理 lora_config 参数的?

系列文章目录



以 ominicontrol 中的 lora 设置为例:

{‘r’: 4, ‘lora_alpha’: 4, ‘init_lora_weights’: ‘gaussian’,
‘target_modules’:
‘(.x_embedder|.(?<!single_)transformer_blocks\.[0-9]+\.norm1\.linear|.(?<!single_)transformer_blocks\.[0-9]+\.attn\.to_k|.(?<!single_)transformer_blocks\.[0-9]+\.attn\.to_q|.(?<!single_)transformer_blocks\.[0-9]+\.attn\.to_v|.(?<!single_)transformer_blocks\.[0-9]+\.attn\.to_out\.0|.*(?<!single_)transformer_blocks\.[0-9]+\.ff\.net\.2|.*single_transformer_blocks\.[0-9]+\.norm\.linear|.*single_transformer_blocks\.[0-9]+\.proj_mlp|.*single_transformer_blocks\.[0-9]+\.proj_out|.*single_transformer_blocks\.[0-9]+\.attn.to_k|.*single_transformer_blocks\.[0-9]+\.attn.to_q|.*single_transformer_blocks\.[0-9]+\.attn.to_v|.*single_transformer_blocks\.[0-9]+\.attn.to_out)’}

LoraConfig 如何处理 **lora_config 参数

当调用 self.transformer.add_adapter(LoraConfig(**lora_config)) 时,**lora_config 会将字典中的键值对作为参数传递给 LoraConfig 类的构造函数。下面我详细解释这个过程:

参数解析过程

  1. 字典解包

    • **lora_config 将字典解包为关键字参数
    • 例如 {'r': 4, 'lora_alpha': 4, ...} 变成 r=4, lora_alpha=4, ...
  2. 参数初始化

    • LoraConfig 类接收这些参数并设置相应的属性
    • 对于您提供的配置,主要设置了以下属性:
      • r=4:LoRA 的秩
      • lora_alpha=4:LoRA 的缩放因子
      • init_lora_weights='gaussian':使用高斯分布初始化权重
      • target_modules=...:复杂的正则表达式,指定要应用 LoRA 的模块
  3. __post_init__ 处理

    • 初始化后,__post_init__ 方法会执行额外的验证和处理
    • 设置 peft_type = PeftType.LORA
    • 处理 target_modules(如果是列表,转换为集合)
    • 验证参数组合的有效性

正则表达式处理

对于您提供的复杂正则表达式 target_modules,处理流程如下:

  1. 正则表达式保存

    • 配置对象保存这个正则表达式字符串
    • 不会在配置阶段解析或匹配模块
  2. 后续模块匹配

    • add_adapter 方法执行时,PEFT 库会遍历模型的所有模块
    • 使用正则表达式匹配每个模块的名称
    • 对于匹配的模块,应用 LoRA 适配器

特殊处理

  1. 高斯初始化

    • 由于设置了 init_lora_weights='gaussian',LoRA 权重将使用高斯分布初始化
    • 这会在 LoraLayer 类的 update_layer 方法中处理
  2. 参数验证

    • 代码中有多处验证逻辑,确保参数组合有效
    • 例如,检查 layers_to_transformtarget_modules 的兼容性
  3. 警告处理

    • 某些参数组合会触发警告而非错误
    • 例如,当 init_lora_weights 不是 ‘loftq’ 但提供了 loftq_config

实际应用流程

当执行 add_adapter 时,完整流程是:

  1. 创建 LoraConfig 实例并初始化所有参数
  2. 调用 __post_init__ 进行验证和处理
  3. 将配置传递给 BaseTuner 的子类(如 LoraModel
  4. LoraModel 遍历模型的所有模块,使用正则表达式匹配模块名称
  5. 对匹配的模块,创建并注入 LoRA 适配器层
  6. 根据 init_lora_weights 参数初始化 LoRA 权重(在该例子中是高斯初始化)

这种设计允许用户通过简单的配置字典灵活地控制 LoRA 适配器的行为,而不需要直接修改模型代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值