【复现】FreeU以及结合stable diffusion

  code:GitHub - ChenyangSi/FreeU: FreeU: Free Lunch in Diffusion U-Net

才发现AnimateDiff更新v3了,以及又发了篇CVPR的改进工作:

在这个版本中,我们通过域适配器LoRA对图像模型进行了微调,以便在推理时具有更大的灵活性。

实现了两个(RGB图像/scribble) SparseCtrl编码器,可以采用固定数量的条件映射来控制生成过程。

域适配器是一个在训练视频数据集的静态帧上进行训练的LoRA模块。这个过程是在训练运动模块之前完成的,并帮助运动模块专注于运动建模,如下图所示。在推理时,通过调整域适配器的LoRA尺度,可以去除训练视频的一些视觉属性,如水印。为了利用SparseCtrl编码器,有必要在管道中使用全域适配器。

明天读一下

整了半天发现目前的FreeU好像只支持SD2.1和SDXL啊。。而AnimateDiff​ v1, v2 and v3 都是用的 Stable Diffusion V1.5。而且AnimateDiff用的diffusers==0.11.1,而FreeU用的0.16.0,尝试了一下,各种不适配。那把他俩结合的尝试之后再说吧

代码分析

import torch
from torch.fft import fftn, ifftn, fftshift, ifftshiftdef Fourier_filter(x, threshold, scale):# FFTx_freq = fftn(x, dim=(-2, -1))  # 对输入进行二维快速傅里叶变换(FFT)x_freq = fftshift(x_freq, dim=(-2, -1))  # 平移频域结果,使低频部分位于中心B, C, H, W = x_freq.shapemask = torch.ones((B, C, H, W)).cuda()  # 创建与输入形状相同的掩码,初始化为全1crow, ccol = H // 2, W // 2mask[..., crow - threshold:crow + threshold, ccol - threshold:ccol + threshold] = scale  # 将掩码中心区域设为指定的缩放值x_freq = x_freq * mask  # 将掩码应用于频域结果,得到滤波后的频域结果# IFFTx_freq = ifftshift(x_freq, dim=(-2, -1))  # 逆平移操作x_filtered = ifftn(x_freq, dim=(-2, -1)).real  # 对滤波后的频域结果进行逆傅里叶变换(IFFT),并取实部return x_filteredclass Free_UNetModel(UNetModel):""":param b1: decoder第一个阶段的骨干因子。:param b2: decoder第二个阶段的骨干因子。:param s1: decoder第一个阶段的跳跃因子。:param s2: decoder第二个阶段的跳跃因子。"""def __init__(self,b1,b2,s1,s2,*args,**kwargs):super().__init__(*args, **kwargs)self.b1 = b1 self.b2 = b2self.s1 = s1self.s2 = s2def forward(self, x, timesteps=None, context=None, y=None, **kwargs):"""Apply the model to an input batch.:param x: 输入的[N x C x ...]张量。:param timesteps: 一个包含时间步长的一维批次。:param context: 通过交叉注意力插入的条件。:param y: 一个[N]张量的标签,如果是类别条件。:return: 输出的[N x C x ...]张量。"""assert (y is not None) == (self.num_classes is not None), "must specify y if and only if the model is class-conditional"hs = []t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False)emb = self.time_embed(t_emb)if self.num_classes is not None:assert y.shape[0] == x.shape[0]emb = emb + self.label_emb(y)h = x.type(self.dtype)for module in self.input_blocks:h = module(h, emb, context)hs.append(h)h = self.middle_block(h, emb, context)for module in self.output_blocks:hs_ = hs.pop()# --------------- FreeU code -----------------------# 只对前两个阶段进行操作if h.shape[1] == 1280:hidden_mean = h.mean(1).unsqueeze(1)B = hidden_mean.shape[0]hidden_max, _ = torch.max(hidden_mean.view(B, -1), dim=-1, keepdim=True) hidden_min, _ = torch.min(hidden_mean.view(B, -1), dim=-1, keepdim=True)hidden_mean = (hidden_mean - hidden_min.unsqueeze(2).unsqueeze(3)) / (hidden_max - hidden_min).unsqueeze(2).unsqueeze(3)h[:,:640] = h[:,:640] * ((self.b1 - 1 ) * hidden_mean + 1)hs_ = Fourier_filter(hs_, threshold=1, scale=self.s1)if h.shape[1] == 640:hidden_mean = h.mean(1).unsqueeze(1)B = hidden_mean.shape[0]hidden_max, _ = torch.max(hidden_mean.view(B, -1), dim=-1, keepdim=True) hidden_min, _ = torch.min(hidden_mean.view(B, -1), dim=-1, keepdim=True)hidden_mean = (hidden_mean - hidden_min.unsqueeze(2).unsqueeze(3)) / (hidden_max - hidden_min).unsqueeze(2).unsqueeze(3)h[:,:320] = h[:,:320] * ((self.b2 - 1 ) * hidden_mean + 1)hs_ = Fourier_filter(hs_, threshold=1, scale=self.s2)# ---------------------------------------------------------h = th.cat([h, hs_], dim=1)h = module(h, emb, context)h = h.type(x.dtype)if self.predict_codebook_ids:return self.id_predictor(h)else:return self.out(h)

Fourier_filter函数用于对输入进行傅里叶变换滤波。具体步骤如下:

  1. 对输入进行二维快速傅里叶变换(FFT)。
  2. 对频域结果进行平移操作,使低频部分位于中心。
  3. 创建一个与输入形状相同的掩码,初始化为全1。
  4. 根据给定的阈值和缩放因子,将掩码中心区域设为指定的缩放值。
  5. 将掩码应用于频域结果,得到滤波后的频域结果。
  6. 对滤波后的频域结果进行逆平移操作。
  7. 对逆平移后的结果进行二维逆傅里叶变换(IFFT)。
  8. 返回滤波后的实部结果。

Free_UNetModel类是基于UNet模型的扩展,具有自定义的前向传播方法。具体功能如下:

  1. 接收输入x、时间步长timesteps、上下文context和标签y。
  2. 根据是否有标签,计算时间嵌入向量并与标签嵌入向量相加。
  3. 通过输入块和中间块的循环,逐层处理输入数据,并将每一层的输出保存在列表hs中。
  4. 对输出块进行处理,其中包括对特定阶段的FreeU代码的应用。
  5. 将处理后的输出与上一层的输出拼接起来,并通过输出块进行最终处理。
  6. 根据模型设置,返回预测结果或编码器输出。

总体而言,这段代码实现了一个具有傅里叶滤波和自定义前向传播的UNet模型扩展。

free_lunch_utils.py

主要有三个函数:Fourier_filter,register_free_upblock2d,register_free_crossattn_upblock2d。后两者定义了FreeU的Unet框架

register_upblock2d 函数:

  • 该函数注册的是普通的上采样块(UpBlock2D)的自定义前向传播方法。
  • 在 up_forward 函数中,通过循环遍历模型中的每个上采样块(UpBlock2D对象),将其前向传播方法重写为自定义的 forward 函数。
  • 无需设置其他属性或参数。

register_free_upblock2d 函数:

  • 该函数注册的是自由上采样块(FreeU UpBlock2D)的自定义前向传播方法。
  • 在 up_forward 函数中,与 register_upblock2d 函数类似,通过循环遍历模型中的每个上采样块,并将其前向传播方法重写为自定义的 forward 函数。
  • 此外,还设置了一些额外的属性 b1b2s1 和 s2,分别表示两个阶段的放大因子和两个阶段的 Fourier 滤波器阈值。

模型复现

SDV2-1下载:stabilityai/stable-diffusion-2-1 at main (huggingface.co)

 FreeU Code:https://github.com/ChenyangSi/FreeU/tree/main?ref=blog.hinablue.me#freeu-code 

问题1:torch.cuda.OutOfMemoryError

FreeU中没设置生成图片的大小,用的默认值多少也看不出来,手动设一下

    print("Generating SD:")# sd_image = pip(prompt, num_inference_steps=25).images[0]  sd_image = pip(prompt, num_inference_steps=25, width=256, height=256).images[0]print("Generating FreeU:")# freeu_image = pip(prompt, num_inference_steps=25).images[0]  freeu_image = pip(prompt, num_inference_steps=25, width=256, height=256).images[0]

结果报错:TypeError: Transformer2DModel.forward() got an unexpected keyword argument 'cross_attention_kwargs'

尝试注释掉所有cross_attention_kwargs,结果:

生成的东西意义不明,不能省略cross_attention_kwargs(包含与交叉注意力相关的配置信息)

FreeU + Diffusers

GitHub - lyn-rgb/FreeU_Diffusers: "FreeU: Free Lunch in Diffusion U-Net" for Huggingface Diffusers

来源:FreeU | 增强图像生成质量的插件 - 掘金 (juejin.cn)

webui插件:GitHub - ljleb/sd-webui-freeu: a1111 implementation of https://github.com/ChenyangSi/FreeU

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/590724.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用 PyTorch 训练 LLM

一、引言 语言模型(LLM)是一种重要的自然语言处理(NLP)技术,它通过对大量文本数据进行训练,学习语言的内在结构和语义信息。PyTorch作为一种流行的深度学习框架,具有灵活性和易用性&#xff0c…

MySQL 高级(进阶) SQL 语句

目录 一、实验环境准备 二、MySQL高阶查询 1、语句与命令 2、实验实操 三、MySQL函数 1、语句与命令 2、实验操作 一、实验环境准备 #创建两个数据表,为实验提供环境: use kgc; #选择数据库,有则直接使用 无则按照以下步骤自建即可…

WPF+Halcon 培训项目实战(8-9):WPF+Halcon初次开发

文章目录 前言相关链接项目专栏运行环境匹配图片WPF Halcon组件HSmartWindowControlWPF绑定读取图片运行代码运行结果 抖动问题解决运行结果 绘制矩形绘制图像会消失 绘制对象绑定事件拖动事件 前言 为了更好地去学习WPFHalcon,我决定去报个班学一下。原因无非是想…

nginx安装和配置

目录 1.安装 2.配置 3.最小配置说明 4. nginx 默认访问路径 1.安装 使用 epel 源安装 先安装 yum 的扩展包 yum install epel-release -y 再安装 nginx yum install nginx -y 在启动nginx 前先关闭防火墙 systemctl stop firewalld 取消防火墙开机自启 systemctl di…

Self-attention学习笔记(Self Attention、multi-head self attention)

李宏毅机器学习Transformer Self Attention学习笔记记录一下几个方面的内容 1、Self Attention解决了什么问题2、Self Attention 的实现方法以及网络结构Multi-head Self Attentionpositional encoding 3、Self Attention 方法的应用4、Self Attention 与CNN以及RNN对比 1、Se…

基于grpc从零开始搭建一个准生产分布式应用(8) - 01 - 附:GRPC公共库源码

开始前必读&#xff1a;​​基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart​​ common包中的源码&#xff0c;因后续要用所以一次性全建好了。 一、common工程完整结构 二、引入依赖包 <?xml version"1.0" encoding"UTF-8"?> <p…

【linux】cat的基本使用

cat是一个常用的命令&#xff0c;用来显示文本的内容&#xff0c;合并和创建文本文件 类似命令还有显示文件开头的内容&#xff1a; 【linux】head的用法 输出文件开头的内容-CSDN博客 显示文件末尾的内容&#xff1a; 【linux】tail的基本使用-CSDN博客 当我们想到了想要…

Zookeeper-Zookeeper选举源码

看源码方法&#xff1a; 1、先使用&#xff1a;先看官方文档快速掌握框架的基本使用 2、抓主线&#xff1a;找一个demo入手&#xff0c;顺藤摸瓜快速静态看一遍框架的主线源码&#xff0c;画出源码主流程图&#xff0c;切勿一开始就陷入源码的细枝末节&#xff0c;否则会把自…

Vue3 用户认证:如何检查用户是否已登录

&#x1f9d9;‍♂️ 诸位好&#xff0c;吾乃诸葛妙计&#xff0c;编程界之翘楚&#xff0c;代码之大师。算法如流水&#xff0c;逻辑如棋局。 &#x1f4dc; 吾之笔记&#xff0c;内含诸般技术之秘诀。吾欲以此笔记&#xff0c;传授编程之道&#xff0c;助汝解技术难题。 &…

Primavera Unifier 项目控制延伸:Phase Gate理论:3/3

继续上一篇阶段Gate的具体内容 https://campin.blog.csdn.net/article/details/127827681https://campin.blog.csdn.net/article/details/127827681 阶段 3 研发 前述阶段的计划和安排都要在研发阶段执行起来&#xff0c;同时&#xff0c;最重要的产品设计和开发部分也需要在…

系统学习Python——装饰器:函数装饰器-[对方法进行装饰:基础知识]

分类目录&#xff1a;《系统学习Python》总目录 我们在前面的文章中编写了第一个基于类的tracer函数装饰器的时候&#xff0c;我们简单地假设它也应该适用于任何方法一一一被装饰的方法应该同样地工作&#xff0c;并且自带的self实例参数应该直接包含在*args的前面。但这一假设…

7-2 换硬币

将一笔零钱换成5分、2分和1分的硬币&#xff0c;要求每种硬币至少有一枚&#xff0c;有几种不同的换法&#xff1f; 输入格式: 输入在一行中给出待换的零钱数额x∈(8,100)。 输出格式: 要求按5分、2分和1分硬币的数量依次从大到小的顺序&#xff0c;输出各种换法。每行输出…

计算机基础面试题 |04.精选计算机基础面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

python打开文件的方式比较

open(addr,w) 打开之后文件无论以前有什么&#xff0c;打开后都要清空 /// open(addr,r) 文件打开后&#xff0c;不删除以前内容

Ubuntu连接xshell

安装ssh服务器 sudo apt-get install openssh-server​ 重启ssh sudo service ssh restart 3.启动ssh服务 /etc/init.d/ssh start4.修改文件&#xff0c;允许远程登陆 sudo vi /etc/ssh/sshd_config PermitRootLogin prohibit-password #默认为禁止登录 PermitRootLogin y…

JAVA Web 期末复习

期末复习 填空题简答题&#xff1a;一、数据库连接池的工作机制是什么&#xff1a;二、javabean的规范&#xff1a;三、POST和GET请求的区别四、请求转发和重定向的区别五、简述pageContext的作用&#xff1a;六、什么是重定向七、简述一下MVC及作用八、cookie和session九、简述…

多人协同开发git flow,创建初始化项目版本

文章目录 多人协同开发git flow&#xff0c;创建初始化项目版本1.gitee创建组织模拟多人协同开发2.git tag 打标签3.git push origin --tags 多人协同开发git flow&#xff0c;创建初始化项目版本 1.gitee创建组织模拟多人协同开发 组织中新建仓库 推送代码到我们组织的仓库 2…

国家开放大学形成性考核 统一考试 资料参考

试卷代号&#xff1a;11130 卫生法学 参考试题&#xff08;开卷&#xff09; 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 1.省、自治区、直辖市及省会所在地的市人大及其常委会&#xff0c;或经国务院批准的较大的市的人大及其常委会&#xff0c;依法…

STM32与TB6612电机驱动器的基础入门教程

TB6612是一款常用的双路直流电机驱动芯片&#xff0c;适用于小型机器人以及其他需要控制电机方向和转速的应用。在STM32微控制器的配合下&#xff0c;可以实现对TB6612电机驱动器的控制&#xff0c;进而实现电机的控制。本文将带领读者一步步了解如何搭建基于STM32与TB6612的电…

Python基础-03(算数运算符、赋值运算符)

文章目录 前言一、算数运算符二、赋值运算符&#xff08;&#xff09;1.赋值运算符&#xff08;&#xff09;2.复合赋值运算符 总结 前言 两种非常基础的运算符&#xff0c;看一下就懂&#xff0c;不需要过多的去深究细节 一、算数运算符 稍微着重看下 除法/ &#xff08;不要…