欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > [Tools: LoRA] Diffusers中Stable Diffusion的实现

[Tools: LoRA] Diffusers中Stable Diffusion的实现

2024/10/24 23:17:55 来源:https://blog.csdn.net/qq_40731332/article/details/141677811  浏览:    关键词:[Tools: LoRA] Diffusers中Stable Diffusion的实现

实现底层原理

  • Diffusers中的Attention操作实现在AttnProcessor类(diffusers.models.attention_processor.py),里面定义了单次Attention操作。
  • 添加LoRA,本质上是用LoRAAttnProcessor类替换AttnProcessor类。
  • LoRAAttnProcessor中新增了四个线性层,分别是to_q_lora、to_k_lora、to_v_lora、to_out_lora,并在执行AttnProcessor前分配给attn,然后再嵌套执行AttnProcessor:

  • 修改的attn是Attention类,其中的to_q、to_k、to_v和to_out是LoRACompatibleLinear(diffusers.models.lora.py),在增加lora_layer后,计算如下。其中,scale是用来控制LoRA强度,如果为0则不添加LoRA。

具体实现

  • 参考:threestudio中的LoRA实现
lora_attn_procs = {}
for name, processor in self.unet_lora.attn_processors.items():cross_attention_dim = (Noneif name.endswith("attn1.processor")else self.unet_lora.config.cross_attention_dim)if name.startswith("mid_block"):hidden_size = self.unet_lora.config.block_out_channels[-1]elif name.startswith("up_blocks"):block_id = int(name[len("up_blocks.")])hidden_size = list(reversed(self.unet_lora.config.block_out_channels))[block_id]elif name.startswith("down_blocks"):block_id = int(name[len("down_blocks.")])hidden_size = self.unet_lora.config.block_out_channels[block_id]processor_name = type(processor).__name__if processor_name == 'AttnProcessor':lora_attn_procs[name] = LoRAAttnProcessor(hidden_size=hidden_size, cross_attention_dim=cross_attention_dim)elif processor_name == 'AttnProcessor2_0':lora_attn_procs[name] = LoRAAttnProcessor2_0(hidden_size=hidden_size, cross_attention_dim=cross_attention_dim)else:raise ValueError(f"Unknown processor type {processor_name}")self.unet_lora.set_attn_processor(lora_attn_procs)
self.lora_layers = AttnProcsLayers(self.unet_lora.attn_processors).to(self.device
)
self.lora_layers._load_state_dict_pre_hooks.clear()
self.lora_layers._state_dict_hooks.clear()

SD的整体结构

  • diffusers中的SD实现为StableDiffusionPipeline,其中UNet为UNet2DConditionModel,包含down_block -> mid_block -> up_block。

  • 以down_block_types为例,包含3个CrossAttnDownBlock2D和1个DownBlock2D。对于CrossAttnDownBlock2D包含多组ResnetBlock2DTransformer2DModel,以及最后的Downsample2D。从下面代码中可以看到,LoRA的scale系数可以同时嵌入到上述三个加粗模块中:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com