Stable Diffusion动态加载Lora过程中的实验、原理与说明

这篇具有很好参考价值的文章主要介绍了Stable Diffusion动态加载Lora过程中的实验、原理与说明。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

对比实验

显存占用情况

Stable Diffusion动态加载Lora过程中的实验、原理与说明,AIGC,stable diffusion,人工智能,AIGC
使用StableDiffusionXLPipeline.from_pretrained() 方法SDXL半精度加载显存占用约7G左右。

Stable Diffusion动态加载Lora过程中的实验、原理与说明,AIGC,stable diffusion,人工智能,AIGC
使用load_lora_weights()加载了5个Lora模型后显存提升到8G,平均每个Lora的大小在200M左右。
使用unload_lora_weights()后显存没有发生变化,还是8G,说明该方法不会清空已经加载到显存的Lora模型,但这时候再调用模型生成图片已经丢失Lora的效果了

推理耗时

Lora数量 耗时(秒)
0 15
1 20
2 24
7 45

这里使用的Lora平均每个的大小在200M左右,从上表不难发现单个Lora耗时约增加4秒左右。

代码分析与原理说明

1)加载Lora

通过调用load_lora_weights()来加载不同的Lora权重,这些权重的张量都会加载到显存中,但注意只有第一次调用该方法的Lora才会生效,可通过get_active_adapters()查看。

def load_lora_weights(
        self, pretrained_model_name_or_path_or_dict: Union[str, Dict[str, torch.Tensor]], adapter_name=None, **kwargs
    ):
    
        ...
        # lora_state_dict 实际执行把tensor加载到显存中,同时返回2个字典记录所添加的lora的名称和配置信息
        state_dict, network_alphas = self.lora_state_dict(pretrained_model_name_or_path_or_dict, **kwargs)
        
       
        # state_dict 和 network_alphas 是上面返回的2个参数
        # 加载后默认调用的lora是第一次load进来的lora
        self.load_lora_into_unet(
            state_dict,
            network_alphas=network_alphas,
            unet=getattr(self, self.unet_name) if not hasattr(self, "unet") else self.unet,
            low_cpu_mem_usage=low_cpu_mem_usage,
            adapter_name=adapter_name,
            _pipeline=self,
        )
        self.load_lora_into_text_encoder(
            state_dict,
            network_alphas=network_alphas,
            text_encoder=getattr(self, self.text_encoder_name)
            if not hasattr(self, "text_encoder")
            else self.text_encoder,
            lora_scale=self.lora_scale,
            low_cpu_mem_usage=low_cpu_mem_usage,
            adapter_name=adapter_name,
            _pipeline=self,
        )

Stable Diffusion动态加载Lora过程中的实验、原理与说明,AIGC,stable diffusion,人工智能,AIGC

用一张图来表示load_lora_weights()加载过程,蓝色表示生效的张量。
Stable Diffusion动态加载Lora过程中的实验、原理与说明,AIGC,stable diffusion,人工智能,AIGC

因此如果不特别指定调用哪个Lora的话,默认输入的张量需要跟Base和第一个Lora的权重分别相乘再叠加

2)卸载Lora

卸载Lora时需要调用unload_lora_weights()方法,关键是把config删除,并不清显存,如代码中的del self.unet.peft_config操作。如果后续需要再调用Lora的话,则需要重头开始加载Lora权重

  def unload_lora_weights(self):
        
        if not USE_PEFT_BACKEND:
            if version.parse(__version__) > version.parse("0.23"):
                logger.warn(
                    "You are using `unload_lora_weights` to disable and unload lora weights. If you want to iteratively enable and disable adapter weights,"
                    "you can use `pipe.enable_lora()` or `pipe.disable_lora()`. After installing the latest version of PEFT."
                )

            for _, module in self.unet.named_modules():
                if hasattr(module, "set_lora_layer"):
                    module.set_lora_layer(None)
        else:
            recurse_remove_peft_layers(self.unet)
            if hasattr(self.unet, "peft_config"):
            # 关键是把config删除,并不清显存
            # 因此执行unload_lora_weights 会丢失所有记载的lora的config信息,但不会释放显存
                del self.unet.peft_config

3)指定Lora

在拥有多个Lora加载后,如果需要指定某个或者某几个Lora,则需要用set_adapters()方法。该方法对Unet和Text Encoder都执行set_adapter()操作,间接调用了peft_utils模块中的set_weights_and_activate_adapters() 方法为Unet或者Text Encoder的某些层指定Lora类型和权重。

 def set_adapters(
        self,
        adapter_names: Union[List[str], str],
        adapter_weights: Optional[List[float]] = None,
    ):
        # 对unet和text encoder都执行set adapter操作。间接调用 set_weights_and_activate_adapters 方法
        self.unet.set_adapters(adapter_names, adapter_weights)

        # Handle the Text Encoder
        if hasattr(self, "text_encoder"):
            self.set_adapters_for_text_encoder(adapter_names, self.text_encoder, adapter_weights)
        if hasattr(self, "text_encoder_2"):
            self.set_adapters_for_text_encoder(adapter_names, self.text_encoder_2, adapter_weights)
# src/diffusers/utils/peft_utils.py
def set_weights_and_activate_adapters(model, adapter_names, weights):
    from peft.tuners.tuners_utils import BaseTunerLayer

    # iterate over each adapter, make it active and set the corresponding scaling weight
    for adapter_name, weight in zip(adapter_names, weights):
        for module in model.modules():
            if isinstance(module, BaseTunerLayer):
                # For backward compatbility with previous PEFT versions
                if hasattr(module, "set_adapter"):
                    module.set_adapter(adapter_name)
                else:
                    module.active_adapter = adapter_name
                module.set_scale(adapter_name, weight)

如果已经执行过set_adapter(),而下次又需要使用不同的Lora,则重新执行set_adapter()选择需要的Lora即可

4)解除Lora

如果不需要Lora,想用Base模型直接生成图片,这时候可以通过disable_lora()方法来解除已经指定好的Lora。这时候再生成图片,输入的张量只会跟Base的矩阵张量相乘

注意:后续如果需要重新使用Lora,必须先执行 enable_lora() 方法!

# src/diffusers/utils/peft_utils.py#L227
# disable_lora底层调用了该方法
# 会把Unet和Text Encoder的某些层注释掉Lora,因此达到解除Lora的效果
# 可以看到效果和指定Lora时刚好是相反的

def set_adapter_layers(model, enabled=True):
    from peft.tuners.tuners_utils import BaseTunerLayer

    for module in model.modules():
        if isinstance(module, BaseTunerLayer):
            # The recent version of PEFT needs to call `enable_adapters` instead
            if hasattr(module, "enable_adapters"):
            # false的时候注释掉 lora适配器
                module.enable_adapters(enabled=enabled)
            else:
                module.disable_adapters = not enabled

Stable Diffusion动态加载Lora过程中的实验、原理与说明,AIGC,stable diffusion,人工智能,AIGC

5)查看Lora

通过get_active_adapters()方法即可查看指定的Lora,即前面示例图中蓝色的Lora模块。

    def get_active_adapters(self) -> List[str]:
     
        if not USE_PEFT_BACKEND:
            raise ValueError(
                "PEFT backend is required for this method. Please install the latest version of PEFT `pip install -U peft`"
            )

        from peft.tuners.tuners_utils import BaseTunerLayer

        active_adapters = []

        for module in self.unet.modules():
            if isinstance(module, BaseTunerLayer):
                active_adapters = module.active_adapters
                break

        return active_adapters

6)融合Lora

前面已经实验过,当有多个Lora调用时,推理时间几乎会线性增加,这是因为输入的张量除了与Base的模型相乘外,还需要与每个Lora相乘再叠加,因此推理时间会变长。一种解决方案是将需要的Lora与Base进行合并,即通过fuse_lora()来实现,这样推理时间可与Base单独使用时一致。下图中深蓝色表示Base的权重已经叠加了需要的Lora的权重,因此输入张量无需再经过Lora。但是缺点是多次融合Lora后,Base将无法恢复,需要后续需要单独使用Base,只能重新加载Base!

Stable Diffusion动态加载Lora过程中的实验、原理与说明,AIGC,stable diffusion,人工智能,AIGC文章来源地址https://www.toymoban.com/news/detail-763322.html

到了这里,关于Stable Diffusion动态加载Lora过程中的实验、原理与说明的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Stable Diffusion训练Lora模型

    以下内容参考:https://www.bilibili.com/video/BV1Qk4y1E7nv/?spm_id_from=333.337.search-card.all.clickvd_source=3969f30b089463e19db0cc5e8fe4583a 第一步,准备训练要使用的图片,即优质的图片 第二部,为这些图片打标,即精准的tag 数量建议20-50张,最多100张图片 不好的图片:模糊的,动作扭曲的,脸部被

    2024年02月12日
    浏览(70)
  • Stable Diffusion XL训练LoRA

    主要包括SDXL模型结构,从0到1训练SDXL以及LoRA教程,从0到1搭建SDXL推理流程。  【一】SDXL训练初识 Stable Diffusion系列模型的训练主要分成一下几个步骤,Stable Diffusion XL也不例外: 训练集制作:数据质量评估,标签梳理,数据清洗,数据标注,标签清洗,数据增强等。 训练文

    2024年02月07日
    浏览(44)
  • 【Stable Diffusion】基本概念之lora

    1.基本概念 Lora,英文全称“Low-Rank Adaptation of Large Langurage Models”,直译为大语言模型的低阶适应,这是微软的研究人员为了解决大语言模型微调而开发的一项技术 2.作用 只要是图片上的特征都可以提取并训练 (1)对人物/物品的脸部特征进行复刻 (2)生成某一特定风格的图

    2024年02月08日
    浏览(40)
  • Stable Diffusion(SD) Lora模型

    还有一个重要的点,就是你想固化的特征不要去打tag,打的tag不是单纯的对图片进行描述,还要考虑到是否是变量, tag尽量都是变量,也就是说是你期望模型生成的时候可以根据你的文字改变的。举个例子,一个红头发女孩,如果tag里面有red hair,AI会认为这个是可变量,后

    2024年02月02日
    浏览(58)
  • Stable diffusion WebUI LoRA使用教学

    在Stable Diffusion网络中,通常会下载社区中的LoRA模型,并对CLIP模型和Unet的CrossAttention的线性层进行微调。相应的被微调的层会有 \\\'lora_up\\\' 和 \\\'lora_down\\\' 两组参数,分别对应上述的 A 和 B 矩阵。参考高手的代码,只需根据LoRA保存的层的名称找到Stable Diffusion对应的参数,然后对原

    2024年02月11日
    浏览(49)
  • Stable Diffusion Lora模型训练详细教程

    通过Lora小模型可以控制很多特定场景的内容生成。 但是那些模型是别人训练好的,你肯定很好奇,我也想训练一个自己的专属模型(也叫炼丹~_~)。 甚至可以训练一个专属家庭版的模型(family model),非常有意思。 将自己的训练好的Lora模型放到stableDiffusion lora 目录中,

    2024年02月02日
    浏览(51)
  • LoRa模型训练教程(炼丹,Stable Diffusion)

    何为LoRA?LoRA并不是扩散模型专有的技术,而是从隔壁语言模型(LLM)迁移过来的,旨在解决避免将整个模型参数拷贝下来才能对模型进行调校的问题。因为大型语言模型的参数量过于恐怖,比如最近新出的GPT-4参数量约为100 万亿。 LoRA采用的方式是向原有的模型中插入新的数

    2024年02月10日
    浏览(43)
  • Stable diffusion 训练lora出现报错

    今天使用kohya_ss训练lora时出现三个报错,下面是解决办法。 一: 报错 UnboundLocalError: local variable \\\'pipe\\\' referenced before assignment 这个应该是项目的BUG,现在的版本还没修复,但是可以绕过它。方法如下:去 huggingface 下载预训练的基础模型到本地,复制模型的地址到红色框内并把

    2024年02月13日
    浏览(71)
  • 基于LoRA进行Stable Diffusion的微调

    本次微调使用的数据集为: LambdaLabs的Pokemon数据集 使用git clone命令下载数据集 数据集一共883条样本,包含两个部分:image(图)和 text(文),如下图所示。 微调时只需要使用以下命令运行 train_text_to_image_lora.py 文件即可。需要根据下载的路径文件地址对相应的参数进行修改

    2024年02月15日
    浏览(53)
  • Stable Diffusion 使用lora-scripts WebUI训练LoRA模型

    如果对代码使用有困难的小伙伴可以直接使用WebUI版的LoRA模块进行训练操作。不管是训练人物,场景,风格,还是服装都是一套通用的模式,仅仅是使用不同的数据集得到的结果不同。 使用 git clone --recurse-submodules https://gi

    2024年02月17日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包