基于 NNCF 和 Optimum 面向 Intel CPU 对 Stable Diffusion 优化

news2024/10/7 4:32:50

基于隐空间的扩散模型 (Latent Diffusion Model),是解决文本到图片生成问题上的颠覆者。Stable Diffusion 是最著名的一例,广泛应用在商业和工业。Stable Diffusion 的想法简单且有效: 从噪声向量开始,多次去噪,以使之在隐空间里逼近图片的表示。

但是,这样的方法不可避免地增加了推理时长,使客户端的体验大打折扣。众所周知,一个好的 GPU 总能有帮助,确实如此,但其损耗大大增加了。就推理而言,在 2023 年上半年 (H1’23),一个好 CPU 实例 (r6i.2xlarge,8 vCPUs ,64 GB 内存) 价格是 0.504 $/h,同时,类似地,一个好 GPU 实例 (g4dn.2xlarge,NVIDIA T4,16 GB 内存) 价格是 0.75 $/h ,是前者的近 1.5 倍。

这就使图像生成的服务变得昂贵,无论持有者还是用户。该问题在面向用户端部署就更突出了: 可能没有 GPU 能用!这让 Stable Diffusion 的部署变成了棘手的问题。

在过去五年中,OpenVINO 集成了许多高性能推理的特性。 其一开始为计算机视觉模型设计,现今仍在许多模型的推理性能上取得最佳表现,包括 Stable Diffusion。然而,对资源有限型的应用,优化 Stable Diffusion 远不止运行时的。这也是 OpenVINO NNCF(Neural Network Compression Framework) 发挥作用的地方。

在本博客中,我们将理清优化 Stable Diffusion 模型的问题,并提出对资源有限的硬件 (比如 CPU) 减负的流程。尤其是和 PyTorch 相比,我们速度提高了 5.1 倍,内存减少了 4 倍。

Stable Diffusion 的优化

在 Stable Diffusion 的 管线 中,UNet 的运行是最计算昂贵的。因此,对模型的推理速度,针对 UNet 的优化能带来足够的效益。

然而事实表明,传统的模型优化方法如 8-bit 的后训练量化,对此不奏效。主要原因有两点: 其一,面向像素预测的模型,比如语义分割、超分辨率等,是模型优化上最复杂的,因为任务复杂,参数和结构的改变会导致无数种变数; 其二,模型的参数不是很冗余,因为其压缩了其数以千万计的 数据集 中的信息。这也是研究者不得不用更复杂的量化方法来保证模型优化后的精度。举例而言,高通 (Qualcomm) 用分层知识蒸馏 (layer-wise Knowledge Distillation) 方法 (AdaRound) 来 量化 Stable Diffusion。这意味着,无论如何,模型量化后的微调是必要的。既然如此,为何不用 量化感知的训练 (Quantization-Aware Trainning, QAT),其对原模型的微调和参数量化是同时进行的?因此,我们在本工作中,用 token 合并 (Token Merging) 方法结合 NNCF, OpenVINO 和 Diffusers 实践了该想法。

优化流程

我们通常从训练后的模型开始优化。在此,我们从宝可梦数据集 (Pokemons dataset,包含图片和对应的文本描述) 上微调的 模型。

我们对 Stable Diffusion 用 Diffusers 中的 图片 - 文本微调之例,结合 NNCF 中的 QAT (参见训练的 脚本)。我们同时改变了损失函数,以同时实现从源模型到部署模型的知识蒸馏。该方法与通常的知识蒸馏不同,后者是把源模型蒸馏到小些的模型。我们的方法主要将知识整理作为附加的方法,帮助提高最后优化的模型的精度。我们也用指数移动平均方法 (Exponential Moving Average, EMA) 让我们训练过程更稳定。我们仅对模型做 4096 次迭代。

基于一些技巧,比如梯度检查 (gradient checkpointing) 和 保持 EMA 模型 在内存 (RAM) 而不是虚拟内存 (VRAM) 中。整个优化过程能用一张 GPU 在一天内完成。

量化感知的训练之外呢 ?

量化模型本身就能带来模型消耗、加载、内存、推理速度上的显著提高。但量化模型蛮大的优势在能和其他模型优化方法一起,达到加速的增益效果。

最近,Facebook Research 针对视觉 Transformer 模型,提出了一个 Token Merging 方法。该方法的本质是用现有的方法 (取平均、取最大值等) 把冗余的 token 和重要的 token 融合。这在 self-attention 块之前完成,后者是 Transformer 模型最消耗算力的部分。因此,减小 token 的跨度能减少 self-attention 块消耗的时间。该方法也已被 Stable Diffusion 模型 采用,并在面向 GPU 的高分辨率优化上有可观的表现。

我们改进了 Token Merging 方法,以便用 OpenVINO,并在注意力 UNet 模型上采用 8-bit 量化。这包含了上述含知识蒸馏等的所有技术。对量化而言,其需要微调,以保证数值精度。我们也从 宝可梦数据集 上训练的 模型 开始优化和微调。下图体现了总体的优化工作流程。

结果的模型在有限资源的硬件上是高度有效的,如客户机或边缘 CPU。如上文所述,把 Token Merging 方法和量化方法叠加能带来额外的推理增益。

PyTorch FP32,推理时长:230.5 秒,内存消耗:3.44 GB

OpenVINO FP32,推理时长:120 秒 (1.9 倍),内存消耗:3.44 GB

OpenVINO 8-bit,推理市场:59 秒 (3.9 倍),内存消耗:0.86 GB(0.25 倍)

ToMe + OpenVINO 8-bit, 推理速度:44.6 秒 (5.1 倍),内存消耗:0.86 GB (0.25 倍)

用不同模型优化方法的图片生成的结果 展示。输入提示词为 “cartoon bird”,随机种子为 42。模型用 OpenVINO 2022.3,来自 Hugging Face Space,用“CPU 升级”的实例: 第三代 Intel® Xeon® Scalable Processors,和 Intel® 深度学习加速技术。

结果

我们用优化模型不完整的流程以得到两种模型: 基于 8-bit 量化的和基于 Token Merging 量化的,并和 PyTorch 作为基准比较。我们也把基准先转化成 vanilla OpenVINO (FP32) 的模型,以用以分析性比较。

上面的结果图展示了图像生成和部分模型的特性。如你所见,仅转化成 OpenVINO 就带来大的推理速度提高 ( 1.9 倍)。用基于 8-bit 的量化加速和 PyTorch 相比带来了 3.9 倍的推理速度。量化的另外一个重要提高在于内存消耗减少,0.25 倍之于 PyTorch,同时也提高了加载速度。在量化之上应用 Token Merging (ToME) (融合比为 0.4) 带来了 5.1 倍 的提速,同时把模型内存消耗保持在原水平上。我们不提供输出结果上的质量改变,但如你所见,结果还是有质量的。

下面我们展示将最终优化结果部署在 Intel CPU 上代码。

from optimum.intel.openvino import OVStableDiffusionPipeline

# Load and compile the pipeline for performance.
name = "OpenVINO/stable-diffusion-pokemons-tome-quantized-aggressive"
pipe = OVStableDiffusionPipeline.from_pretrained(name, compile=False)
pipe.reshape(batch_size=1, height=512, width=512, num_images_per_prompt=1)
pipe.compile()

# Generate an image.
prompt = "a drawing of a green pokemon with red eyes"
output = pipe(prompt, num_inference_steps=50, output_type="pil").images[0]
output.save("image.png")

在 Hugging Face Optimum Intel 库中你可以找到训练和量化 代码。比较优化过的和原模型的 notebook 代码在 这里。你可以在 Hugging Face Hub 上找到 OpenVINO 下的 许多模型。另外,我们在 Hugging Face Spaces 上建了一个 demo,以运行 [带第三代 Intel Xeon Scalable 的 r6id.2xlarge 实例]。

一般的 Stable Diffusion 模型呢?

正如我们在宝可梦图像生成任务中展现的一样,仅用小量的训练资源,对 Stable Diffusion 管线实现高层次的优化是可能的。同时,众所周知,训练一般的 Stable Diffusion 模型是一个 昂贵的任务。但是,有充足的资金和硬件资源,用上述方法优化一般的模型生成高分辨率的模型是可能的。我们唯一的警告是关于 Token Merging 方法,其会减弱模型容忍性。这里衡量标准是,训练数据越复杂,优化模型时的融合比就该越小。

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

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

相关文章

HTML元素中有中文、英文、符号、数字。第一行没排满就自动换行的解决办法:word-break:break-all的使用

word-break: break-all 是一个CSS属性,用于控制文本在容器中的换行方式。它的作用是强制在任意字符之间进行换行,即使这样可能会导致单词被分割。 具体来说,word-break 属性有以下几个取值: normal(默认值&#xff09…

火伞云WAF产品的主要特点

Web应用程序防火墙(WAF)是抵御所有DDoS攻击的绝佳防御措施。它阻止恶意流量试图阻止应用程序中的漏洞。火伞云WAF通过安全专家的全天候监控支持DDoS保护解决方案,以识别虚假流量激增并在不影响合法流量的情况下阻止它们。 您可以在互联网和原…

win10系统切换到macOS,开发环境与软件资源,目录清单

文章目录 1、生活2、文书3、开发4、算法5、美术6、科研 1、因为考研自习室或学校图书馆,随身携带游戏本(全能本)受限于不插电源就不续航和掉性能,以及风扇噪音非常大,以及发热很烫等问题。 2、所以想考虑给主力机换个…

海外市场营销必备!八大技巧助力品牌出海

1、建立品牌故事和品牌形象:创造一个独特而有吸引力的品牌故事,通过品牌形象和价值观来吸引目标受众。这将帮助你在竞争激烈的市场中脱颖而出,并与消费者建立情感连接。 2、本地化和文化适应:理解并尊重目标市场的文化、习惯和价值…

智能仪表在光伏系统中的应用 安科瑞 许敏

光伏储能逆变器 应用场景 户用储能,小型工商业储能,微电网储能 功能 1.对电能参数进行采样计量和监测,逆变器或者能量管理系统(EMS)与之进行通讯,根据实时功率及累计电能实现防逆流、调节发电量、电池充…

操作Eureka出现Cannot execute request on any known server

操作Eureka出现Cannot execute request on any known server 客户端操作Eureka出现Cannot execute request on any known server 这可能是因为你没有在application.yml中配置 spring.application.name 导致注册到eureka上的状态名称不对。通常注册到Eureka默认为 ip:服务名:端…

Java字符串比较的方法(3种)

1.equals()方法 equals()方法将两个字符串每个字符是否相同进行逐一比较,若相同返回true反之返回false,对于字符的大小写也在检查范围内,equals()方法格式如下:str1.equals(str2); 程序实例 public class Demo {public static voi…

熬夜敲代码不伤眼,选好灯具很重要

文章目录 一、引言1.1 程序员的痛点:长时间使用电脑对眼睛的损害1.2 保护眼睛的重要性 二、明基ScreenBar Halo的保护眼睛功能2.1 自动调光:根据环境光调整亮度2.2 非对称光学设计:减少反光和刺眼2.3 沉浸式灯光:照亮全场视野&…

物流RFID设备在实际中的应用如何?

随着现代物流行业的快速发展,传统条码技术信息量少,易脏污损毁,耐用性不高等问题很难满足物流企业多样化的需求,物流RFID设备的应用也越来越广泛。下面我们就跟大家一起来分析一下,物流RFID设备可以在哪些场景中应用。…

电机和驱动器的简介

电机和驱动器的简介 按照工作电源种类划分:直流电机、交流电机。 按照结构和工作原理划分:永磁同步电动机、感应电动机。 常见的电机:直流电机(直流有刷电机和直流无刷电机)、步进电机、伺服电机和舵机。 直流电机 步…

了解 Python 设计模式

Python🐍设计模式 Python 是一种功能强大的、基于对象的高级编程语言,具有动态类型和绑定功能。由于其灵活性和强大功能,开发人员经常采用某些规则或 Python 设计模式。究竟是什么让设计模式如此重要,这对普通的Python开发人员意味…

基于51单片机和proteus的水质水位检测系统

此系统是基于51单片机和proteus的仿真设计,功能如下: 1. LCD1602实时显示水质和水位状态。 2. 按键可设定水质检测阈值并通过LCD显示。 3. LED指示水质水位和系统运行状态。 4. 水质差超过阈值后自动启动排水泵。 5. 水位过低时自动启动进水泵。 6…

BI如何对接金蝶云星空数据源?奥威BI SaaS平台有绝招

传统BI部署时需要大量硬件和软件支持,而SaaS BI不仅不需要,还能让企业的数据可视化分析变得更加简单便捷,因此已经渐渐成为数字化时代的BI新趋势。那么,SaaS BI平台是如何快速接入数据完成数据可视化分析的?下面就以奥…

基于Python制作一个简单的文章搜索工具

这篇文章主要为大家详细介绍了如何基于Python制作一个简单的文章搜索工具,都是一些基础的应用,文中的示例代码讲解详细,感兴趣的可以了解一下 前言 今天,我无聊的时候做了一个搜索文章的软件,有没有更加的方便快捷不知…

R和python中dataframe读取方式总结

首先我有一个如图所示的文件 如果在python中读取 import pandas as pd df pd.read_csv("./6group_count.csv",index_col0) df而在R中读取的方式如下 df read.csv("./6group_count.csv",row.names 1)

springboot 集成Druid的监控数据库连接池的最佳实践

免费的chatgpt福利送上 http://124.220.104.235:31105/web/chatgpt 1.数据库连接池介绍 1.1JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤 在主程序(如servlet、beans)中建立数据库连接 进行sql…

Mybatis-plus通用查询方法封装

定义DTO package com.lbdj.user.service.dto;import com.lbdj.toolkit.utils.ReturnField; import com.lbdj.toolkit.utils.SFunction; import lombok.Data;/*** 用户DTO** author 作者* since 2023-06-27*/ Data public class LbdjUserDTO {/*** 主键*/private Long id;priva…

Oracle表设计

设计原则 为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规 则。在关系型数据库中这种规则就称为范式。 范式是符合某一种设计要求的总结。 要想设计一个结构合理的关系型数据库,必须满足一定的范式。在实际开发中最为 常见的设计范式…

Auto.js 填充布局 layout_weight=“1“

当我在编写界面布局时&#xff0c;遇到了一个需求&#xff1a; 顶部和底部有按钮&#xff0c;而中间部分需要填满剩余空间且高度未知。 我通过使用layout_weight"1"完美解决我的问题&#xff0c;在这里记录一下。 "ui"; ui.layout(<vertical><te…

STM32——关于GPIO口的输出方式和输入方式

在STM32中&#xff0c;我们会要使用程序来对I/O口进行控制&#xff0c;当我们使用I/O口时&#xff0c;我们就需要知道在程序中我们需要这个I/O口来实现什么功能&#xff0c;是输入还是输出。 1、使用输出模式 I/O口常用的输出方式有推挽输出和开漏输出。 &#xff08;1&#…