【复现】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,一经查实,立即删除!

相关文章

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;否则会把自…

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的前面。但这一假设…

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

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

python打开文件的方式比较

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

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

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

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

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

我从来不理解JavaScript闭包,但我用了它好多年

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热衷分享有趣实用的文章&#xff0c;希望大家多多支持&#xff0c;一起进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 你是否学习了很久JavaScript但还没有搞懂闭包呢&#xff1f;今天就来聊一下…

SpringBoot解决前后端分离跨域问题:状态码403拒绝访问

最近在写和同学一起做一个前后端分离的项目&#xff0c;今日开始对接口准备进行 登录注册 的时候发现前端在发起请求后&#xff0c;抓包发现后端返回了一个403的错误&#xff0c;解决了很久发现是【跨域问题】&#xff0c;第一次遇到&#xff0c;便作此记录✍ 异常描述 在后端…

Java---网络编程

文章目录 1. 网络编程概述2. InetAddress3. 端口和协议4. Java网络API5. URL6. URLConnection类 1. 网络编程概述 1. 计算机网络&#xff1a;是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统、网络管理软…

2024年Mac专用投屏工具AirServer 7 .27 for Mac中文版

AirServer 7 .27 for Mac中文免费激活版是一款Mac专用投屏工具&#xff0c;能够通过本地网络将音频、照片、视频以及支持AirPlay功能的第三方App&#xff0c;从 iOS 设备无线传送到 Mac 电脑的屏幕上&#xff0c;把Mac变成一个AirPlay终端的实用工具。 目前最新的AirServer 7.2…

Matlab技巧[绘画逻辑分析仪产生的数据]

绘画逻辑分析仪产生的数据 逻分上抓到了ADC数字信号,一共是10Bit,12MHZ的波形: 这里用并口协议已经解析出数据: 导出csv表格数据(这个数据为补码,所以要做数据转换): 现在要把这个数据绘制成波形,用Python和表格直接绘制速度太慢了,转了一圈发现MATLAB很好用,操作方法如下:…

逗号表达式与赋值表达式

逗号表达式和赋值表达式是C语言中常用的表达式类型。它们可以用于各种目的&#xff0c;包括计算和评估表达式、初始化变量、为函数调用提供参数以及将值分配给变量。 逗号表达式 逗号表达式允许在单个语句中计算和评估多个表达式。逗号分隔每个表达式&#xff0c;并且表达式从…

Spring Cloud Gateway + Nacos 灰度发布

前言 本文将会使用 SpringCloud Gateway 网关组件配合 Nacos 实现灰度发布&#xff08;金丝雀发布&#xff09; 环境搭建 创建子模块服务提供者 provider&#xff0c;网关模块 gateway 父项目 pom.xml 配置 <?xml version"1.0" encoding"UTF-8"?…