网站开发 百度编辑器,wordpress+爱情主题公园,wordpress用户数据,做电脑系统的网站多重LoRA权重激发稳定扩散 稳定扩散控制网络流水线步骤1#xff1a;环境准备步骤2#xff1a;模型转换步骤3#xff1a;运行时流水线测试 启用稳定扩散的LoRA权重步骤4-1#xff1a;通过pytorch_lora_weights.bin启用LoRA步骤4-2#xff1a;通过safetensors类型的权重启用… 多重LoRA权重激发稳定扩散 稳定扩散控制网络流水线步骤1环境准备步骤2模型转换步骤3运行时流水线测试 启用稳定扩散的LoRA权重步骤4-1通过pytorch_lora_weights.bin启用LoRA步骤4-2通过safetensors类型的权重启用LoRA步骤4-3通过MatcherPass在运行时启用LoRA合并步骤4-4启用多个LoRA权重 低秩适应LoRA技术是一种创新的方法用于解决微调扩散器和大型语言模型LLMs的问题。在稳定扩散微调中LoRA可应用于图像表示的交叉注意层其中包含描述的潜在信息。为了理解模型微调的基本概念和方法您可以参考Hugging Face扩散器的文档https://huggingface.co/docs/diffusers/training/lora
在这篇博客中我们旨在介绍如何使用OpenVINO™优化构建Stable Diffusion ControlNet管道并启用LoRA权重以便通过Stable Diffusion的Unet模型生成具有不同风格的图像。演示源代码基于https://github.com/FionaZZ92/OpenVINO_sample/tree/master/SD_controlnet
稳定扩散控制网络流水线
步骤1环境准备
首先按照以下步骤准备开发环境。您可以选择从Hugging Face下载模型以获得更好的运行时体验。在本例中我们选择了ControlNet用于canny图像任务。
# 安装所需的依赖和下载模型
$ mkdir ControlNet cd ControlNet
$ wget https://huggingface.co/lllyasviel/ControlNet/resolve/main/annotator/ckpts/body_pose_model.pth
$ conda create -n SD python3.10
$ conda activate SD
$ pip install opencv-contrib-python
$ pip install -q diffusers0.14.0 githttps://github.com/huggingface/accelerate.git controlnet-aux gradio
$ pip install openvino openvino-dev onnx
$ pip install torch1.13.1 # 重要确保使用torch1.13.1
$ git lfs install
$ git clone https://huggingface.co/lllyasviel/sd-controlnet-canny
$ git clone https://huggingface.co/runwayml/stable-diffusion-v1-5
$ git clone https://huggingface.co/openai/clip-vit-large-patch14
$ wget https://huggingface.co/takuma104/controlnet_dev/blob/main/gen_compare/control_images/vermeer_512x512.png 请注意如果您的torch版本大于等于2.0则扩散器将开始使用torch.nn.functional.scaled_dot_product_attention。由于ONNX不支持“Aten::scaled_dot_product_attention”的op转换为了避免在模型转换时出现错误请确保您使用的是torch1.13.1。
步骤2模型转换
使用提供的两个程序之一将模型转换为OpenVINO™ IR。使用get_model.py脚本通过以下方式检查脚本的选项
$ python get_model.py -h在这个例子中我们选择多个批次大小以生成多个图像。视觉生成的常见应用有两个批次的概念
batch_size指定输入提示或负提示的长度用于生成N图像。num_images_per_prompt指定每个提示生成的图像数量用于生成M图像。
因此对于常见的用户应用可以在扩散器中使用这两个属性通过N提示生成 N ∗ M N*M N∗M图像。例如基本种子是42要生成 N ( 2 ) ∗ M ( 2 ) N(2)*M(2) N(2)∗M(2)图像实际生成如下
N1M1prompt_list[0]seed42N1M2prompt_list[0]seed43N2M1prompt_list[1]seed42N2M2prompt_list[1]seed43
在这种情况下以N2M1作为快速演示的示例因此使用–batch 2。此脚本将默认生成一个静态形状模型。如果您使用不同的N和M值请指定–dynamic。
$ python get_model.py -b 2 -sd stable-diffusion-v1-5/请检查您当前的路径并确保您已经生成了以下模型。其他ONNX文件可以删除以节省空间。
controlnet-canny.xml|bintext_encoder.xml|binunet_controlnet.xml|binvae_decoder.xml|bin
如果您的本地路径已经存在ONNX或IR模型脚本将生成ONNX/IR。如果您更新了pytorch模型或想生成具有不同形状的模型请记得删除现有的ONNX和IR模型。。
步骤3运行时流水线测试
提供的run_pipe.py程序是手动构建的用于StableDiffusionControlNet的流水线参考了diffusers.StableDiffusionControlNetPipeline的源代码。您可以在GitHub查看源代码。
不同之处在于通过OpenVINO™运行时API简化了流水线通过该API可以确保在Intel® CPU和GPU平台上加速模型推断。
默认迭代次数为20图像形状为 512 ∗ 512 512*512 512∗512种子为42输入图像和提示为“戴珍珠耳环的女孩”。您可以调整或自定义您的流水线属性以进行测试。
$ python run_pipe.py在 batch_size2 的情况下生成的图像如下 启用稳定扩散的LoRA权重
正常的LoRA权重有两种类型一种是 pytorch_lora_weights.bin另一种是使用safetensors。在这种情况下我们为这两种LoRA权重介绍两种方法。
启用LoRA权重的主要思想是将权重附加到稳定扩散的原始Unet模型上然后导出保留LoRA权重的Unet的IR模型。
在https://civitai.com/tag/lora上有各种LoRA模型我们选择了HuggingFace上的一些公共模型作为示例您可以考虑用自己的模型替换它们。
步骤4-1通过pytorch_lora_weights.bin启用LoRA
此步骤介绍了通过 pipe.unet.load_attn_procs(…) 函数将LoRA权重添加到稳定扩散的Unet模型的方法。通过使用这种方式LoRA权重将被加载到稳定扩散的Unet模型的注意力层中。
$ git clone https://huggingface.co/TheUpperCaseGuy/finetune-lora-stable-diffusion
$ rm unet_controlnet.* unet_controlnet/unet_controlnet.onnx
$ python get_model.py -b 2 -sd stable-diffusion-v1-5/ -lt bin -lw finetune-lora-stable-diffusion/切记删除现有的 Unet 模型以生成带有 LoRA 权重的新 IR。
然后运行管道推理程序检查结果。
$ python run_pipe.pyLoRA 权重加上稳定扩散模型和 controlNet 管道可以生成如下图像
步骤4-2通过safetensors类型的权重启用LoRA
此步骤介绍了通过 diffusers/scripts/convert_lora_safetensor_to_diffusers.py’将LoRA权重添加到稳定扩散的Unet模型的方法。Diffusers提供了使用safetensors类型的LoRA模型启用新的稳定扩散模型的脚本。通过此方法您将需要将加权路径替换为具有LoRA的新生成的StableDiffusion模型。您可以调整 alpha 选项的值以更改注意力层中 W W 0 a l p h a ∗ d e l t a W W W_0 alpha * deltaW WW0alpha∗deltaW 的合并比率。
$ git clone https://huggingface.co/ntc-ai/fluffy-stable-diffusion-1.5-lora-trained-without-data
$ git clone https://github.com/huggingface/diffusers.git cd diffusers
$ python scripts/convert_lora_safetensor_to_diffusers.py --base_model_path ../stable-diffusion-v1-5/ --checkpoint_path ../fluffy-stable-diffusion-1.5-lora-trained-without-data/fluffySingleWordConcept_v10.safetensors --dump_path ../stable-diffusion-v1-5-fluffy-lora --alpha1.5
$ cd .. rm unet_controlnet.* unet_controlnet/unet_controlnet.onnx
$ python get_model.py -b 2 -sd stable-diffusion-v1-5-fluffy-lora/ -lt safetensors然后运行管道推理程序检查结果。
$ python run_pipe.py使用控制网管道的 LoRA 权重附加 SD 模型可以生成如下图像
步骤4-3通过MatcherPass在运行时启用LoRA合并
此步骤介绍了在Unet或text_encoder模型编译之前在运行时添加LoRA权重的方法。对于具有多个不同LoRA权重的客户端应用通过重用相同的Unet/text_encoder结构可以更改图像样式这将非常有帮助。
此方法是在safetensors文件中提取LoRA权重找到Unet模型中的相应权重并插入LoRA权重偏差。添加LoRA权重的通用方法如下 W W 0 W b i a s ( a l p h a ∗ t o r c h . m m ( l o r a u p , l o r a d o w n ) ) W W_0 W_{bias}(alpha * torch.mm(lora_{up}, lora_{down})) WW0Wbias(alpha∗torch.mm(loraup,loradown))
本文打算通过OpenVINO™ opset10.add(W0, W_bias) 为Unet的注意力权重插入Add操作。Unet模型中的原始注意力权重是通过Const操作加载的通常的处理路径是 Const-Convert-Matmul-…如果我们添加LoRA权重我们应该插入计算得到的LoRA权重偏差如 Const-Convert-Add-Matmul-…。在这个函数中我们采用openvino.runtime.passes.MatcherPass 以迭代方式插入 opset10.add()并使用 call_back() 函数。
其中转换操作将首先插入 opset.Add()然后在使用设备进行模型编译期间。图将执行常量折叠以将Add操作与接下来的MatMul操作合并以优化模型的运行时推断。因此这是将LoRA权重合并到原始模型的有效方法。
您可以查看实现源代码并找到称为 InsertLoRA(MatcherPass) 的MatcherPass函数的定义。
class InsertLoRA(MatcherPass):def __init__(self,lora_dict_list):MatcherPass.__init__(self)self.model_changed Falseparam WrapType(opset10.Convert)def callback(matcher: Matcher) - bool:root matcher.get_match_root()root_output matcher.get_match_value()for y in lora_dict_list:if root.get_friendly_name().replace(.,_).replace(_weight,) y[name]:consumers root_output.get_target_inputs()lora_weights ops.constant(y[value],Type.f32,namey[name])add_lora ops.add(root,lora_weights,auto_broadcastnumpy)for consumer in consumers:consumer.replace_source_output(add_lora.output(0))# Use new operation for additional matchingself.register_new_node(add_lora)# Root node wasnt replaced or changedreturn Falseself.register_matcher(Matcher(param,InsertLoRA), callback)InsertLoRA(MatcherPass) 函数将通过 manager.register_pass(InsertLoRA(lora_dict_list))进行注册并通过 ‘manager.run_passes(ov_unet)’ 被调用。在此运行时MatcherPass操作之后使用设备插件编译的图已准备好进行推断。
运行一个流水线推断程序来检查结果。结果与步骤4-2相同。
python run_pipe.py -lp fluffy-stable-diffusion-1.5-lora-trained-without-data/fluffySingleWordConcept_v10.safetensors -a 1.5LoRA 权重加上稳定扩散模型和 controlNet 管道可以生成如下图像 步骤4-4启用多个LoRA权重
有许多不同的方法可以添加多个LoRA权重。我在这里列出两种方法。假设您有两个LoRA权重LoRA A和LoRA B。您可以简单地按照步骤4-3的方法循环使用MatcherPass函数将其插入到原始Unet Convert层和LoRA A的添加层之间。这很容易实现。但是这样的性能不够好。 请考虑MatcherPass函数的逻辑。此函数需要过滤出所有具有Convert类型的层然后通过条件判断确定每个由权重Constant连接的Convert层是否已在LoRA权重文件中进行了微调和更新。LoRA启用的主要成本由InsertLoRA()函数耗费因此主要思想是只调用InsertLoRA()函数一次但附加多个LoRA文件的权重。 通过上述方法添加多个LoRA附加2个或更多LoRA权重的成本几乎与添加1个LoRA权重相同。
现在让我们将稳定扩散与dreamlike-anime-1.0一起更改以生成具有动画风格的图像。我从 https://civitai.com/tag/lora 中挑选了两个SD 1.5的LoRA权重。
soulcard: https://civitai.com/models/67927?modelVersionId72591epi_noiseoffset: https://civitai.com/models/13941/epinoiseoffset
您可能需要进行提示工程工作以生成如下有用的提示
prompt: “1girl, cute, beautiful face, portrait, cloudy mountain, outdoors, trees, rock, river, (soul card:1.2), highly intricate details, realistic light, trending on cgsociety, neon details, ultra-realistic details, global illumination, shadows, octane render, 8k, ultra sharp”Negativate prompt: “3D, cartoon, low-res, bad anatomy, bad hands, text, error”Seed: 0num_steps: 30canny low_threshold: 100
$ python run_pipe.py -lp soulcard.safetensors -a 0.7 -lp2 epi_noiseoffset2.safetensors -a2 0.7
您可以获得一个美妙的图像生成一个带有灵魂卡典型边框的动画女孩如下图所示 这样您已经学到了如何在Stable Diffusion和ControlNet管道中使用LoRA权重并且可以生成具有不同风格的图像。希望这能满足您的需求