OpenVINO异步Stable Diffusion推理优化方案
文章目录
- Stable Diffusion 推理优化
- 背景
- 技术讲解:
- 异步优化方案思路:
- 异步推理优化原理
- OpenVINO异步推理Python API
- 同步和异步实现方式对比
- oneflow分布式调度优化
- 优势:
- 实现思路
- 总结:
Stable Diffusion 推理优化
背景
2022年,Stable Diffusion模型横空出世,其成为AI行业从传统深度学习时代走向AIGC时代的标志性模型之一,并为工业界,投资界,学术界以及竞赛界都注入了新的AI想象空间,让AI再次性感。
Stable Diffusion是计算机视觉领域的一个生成式大模型,能够进行文生图(txt2img)和图生图(img2img)等图像生成任务。与Midjourney不同的是,Stable Diffusion是一个完全开源的项目(模型,代码,训练数据,论文等),这使得其快速构建了强大繁荣的上下游生态(AI绘画社区,基于SD的自训练模型,丰富的辅助AI绘画工具与插件等),并且吸引了越来越多的AI绘画爱好者也加入其中,与AI行业从业者一起不断推动AIGC行业的发展与普惠。
也正是Stable Diffusion的开源属性,繁荣的上下游生态以及各行各业AI绘画爱好者的参与,使得AI绘画火爆出圈,让大部分人都能非常容易地进行AI绘画。可以说,本次AI科技浪潮的ToC普惠在AIGC时代的早期就已经显现,这是之前的传统深度学习时代从未有过的。而这也是最让Rocky振奋的AIGC属性,让Rocky相信未来的十年会是像移动互联网时代那样,充满科技变革与机会的时代。
Stable Diffusion 本质是基于扩散模型的高质量图像生成技术,可根据文本输入生成图像,广泛应用于CG、插画和高分辨率壁纸等领域。然而,由于其计算过程较为复杂,Stable Diffusion 的图像生成速度常常成为遏制其发展的限制因素。
优化AI生图模型在端侧设备上的 Pipeline性能,在保证生图效果的情况下,降低pipeline端到端延迟,降低pipeline峰值内存占用,也成了当下迫在眉前的大难题。契合本次大赛要求,我们团队计划在目标英特尔硬件上完成部署优化及指定的图片生成工作,利用 OpenVINO 的异步推理功能,实现了预处理、推理和后处理阶段的并行执行,从而提高了整体图像生成 Pipeline 的并行性。
技术讲解:
Stable Diffusion(SD)模型是由Stability AI和LAION等公司共同开发的生成式模型,总共有1B左右的参数量,可以用于文生图,图生图,图像inpainting,ControlNet控制生成,图像超分等丰富的任务,本节中我们以**文生图(txt2img)和图生图(img2img)**任务展开对Stable Diffusion模型的工作流程进行通俗的讲解。
文生图任务是指将一段文本输入到SD模型中,经过一定的迭代次数,SD模型输出一张符合输入文本描述的图片。比如按照赛题要求输入关键字:
- Prompt输入:“a photo of an astronaut riding a horse on mars”
- Negative Prompt输入:“low resolution, blurry”
其本质就是给SD模型一个文本信息与机器数据信息之间互相转换的“桥梁”——CLIP Text Encoder模型。如下图所示,我们使用CLIP Text Encoder模型作为SD模型的前置模块,将输入的人类文本信息进行编码,输出特征矩阵,这个特征矩阵与文本信息相匹配,并且能够使得SD模型理解:
完成对文本信息的编码后,就会输入到SD模型的“图像优化模块”中对图像的优化进行“控制”。
“图像优化模块”作为SD模型中最为重要的模块,其工作流程是什么样的呢?
首先,“图像优化模块”是由一个U-Net网络和一个Schedule算法共同组成,U-Net网络负责预测噪声,不断优化生成过程,在预测噪声的同时不断注入文本语义信息。而schedule算法对每次U-Net预测的噪声进行优化处理(动态调整预测的噪声,控制U-Net预测噪声的强度),从而统筹生成过程的进度。在SD中,U-Net的迭代优化步数大概是50或者100次,在这个过程中Latent Feature的质量不断的变好(纯噪声减少,图像语义信息增加,文本语义信息增加)。整个过程如下图所示:
U-Net网络和Schedule算法的工作完成以后,SD模型会将优化迭代后的Latent Feature输入到图像解码器(VAE Decoder)中,将Latent Feature重建成像素级图像、迭代去噪。
异步优化方案思路:
我们是通过利用 OpenVINO 的异步推理功能,实现了预处理、推理和后处理阶段的并行执行,从而提高了整体图像生成 Pipeline 的并行性。具体使用 OpenVINO 异步推理功能创建独立的推理请求,将每个图像处理阶段异步化,使其在硬件上并行执行,最大程度发挥多核心处理器的优势,显著提升了整体性能。
在提升SD文生图推理程序的性能前,先要理解评估AI推理程序性能的指标是什么。我们常用时延(Latency)和吞吐量(Throughput)来衡量AI推理程序的性能。
- 时延具体指讲数据输入AI模型后,多长时间可以从AI模型拿到输出结果
- 吞吐量具体指在单位时间能完成多少数据的AI推理计算
对于图像处理,吞吐量可以用单位时间内能完成多少张图片的AI推理计算来衡量,即FPS(Frame Per Second),如下图所示。
OpenVINO自带的性能评测工具的benchmark_app,主要用于单纯评价AI模型推理性能的场景。
这种优化方式主要有这几种优点,在保证生图效果的情况下,降低pipeline端到端延迟,降低pipeline峰值内存占用:
-
使得预处理、推理和后处理能够在硬件上并行执行,最大化利用多核心处理器的优势,提高整体 Pipeline 的效率。
-
减少等待时间: 异步化图像输入和输出处理,减少了数据传输的等待时间,降低了整体端到端的延迟,尤其在大规模推理任务中具有显著优势。
-
资源充分利用: 通过异步推理和异步化处理,确保硬件资源充分利用,提高了整个图像生成任务的吞吐量。
-
保持图像生成效果: 该优化方案在提高性能的同时,确保了生成图像的质量和一致性
异步推理优化原理
OpenVINO异步推理Python API
在对SD模型优化中,异步运行多个推理请求对于提高常规应用的效率而言很重要。每个设备都会在内部实施一个队列,充当缓冲区,存储推理请求,等待设备以固有速度检索。 设备实际上可能会并行处理多个推理请求,以提高设备利用率和总吞吐量。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
OpenVINOTM Runtime提供了推理请求(Infer Request)机制,来实现在指定的推理设备上以同步或异步方式运行AI模型。
在openvino.runtime.CompiledModel类里面,定义了create_infer_request()方法,用于创建openvino.runtime.InferRequest对象。
infer_request = compiled_model.create_infer_request()
当infer_request对象创建好后,可以用:
- set_tensor(input_node, input_tensor):将数据传入模型的指定输入节点
- start_async():通过**非阻塞(non-blocking)**的方式启动推理计算。
- wait():等待推理计算结束
- get_tensor(output_node):从模型的指定输出节点获取推理结果
同步和异步实现方式对比
同步实现方式伪代码 | 异步实现方式伪代码 |
---|---|
创建一个负责处理当前文生图的推理请求即可… …While True:文生图预处理调用infer(),以阻塞方式启动推理计算对推理结果做后处理显示推理结果,生成图片结果 | 创建一个推理请求负责处理当前文生图请求创建一个推理请求负责处理下一请求模块… …采集当前图像关键字对当前图像做预处理调用start_async(),以非阻塞方式启动当前模型推理计算While True:采集下一次对下一步模型推算做预处理调用start_async(),以非阻塞方式启动下一帧推理计算调用wait()****,等待当前请求推理计算结束对当前推理结果做后处理交换当前推理请求和下一帧推理请求 |
# 创建一个负责处理当前文生图的推理请求
def process_inference_request(image):# 文生图预处理processed_image = preprocess_image(image)# 调用infer(),以阻塞方式启动推理计算inference_result = infer(processed_image)# 对推理结果做后处理postprocessed_result = postprocess_result(inference_result)# 显示推理结果,生成图片结果show_result(postprocessed_result)
# 创建一个推理请求类,负责处理当前文生图请求
class InferenceRequest:def __init__(self, image):self.image = imageself.result = Nonedef process(self):# 对当前文生图做预处理,调用start_async(),以非阻塞方式启动当前模型推理计算processed_image = preprocess_image(self.image)start_async_inference(processed_image, self)# 创建一个推理请求队列
inference_queue = []# 创建一个推理请求负责处理下一请求模块
class NextInferenceRequest:def __init__(self):self.next_image = Nonedef process(self):# 采集下一次文生图self.next_image = capture_image()# 创建一个推理请求,并加入推理请求队列inference_request = InferenceRequest(self.next_image)inference_queue.append(inference_request)# 对下一次模型推算做预处理,调用start_async(),以非阻塞方式启动下一帧推理计算processed_image = preprocess_image(self.next_image)start_async_inference(processed_image, inference_request)# 创建一个下一请求模块
next_request = NextInferenceRequest()
oneflow分布式调度优化
oneflow | 一种基于异步并行计算的深度学习框架,可以实现分布式训练和推理 | 使用类似 PyTorch 的 API对模型进行编程;使用全局张量将模型扩展到 n 维并行执行 |
---|
优势:
- 采用去中心化的流水架构,而非 master 与 worker 架构,最大程度优化节点网络通信效率
- 提供 consistent view ,整个节点网络中只需要逻辑上唯一的输入与输出
- 提供兼容其它框架的mirrored view,熟悉其它框架分布式训练的用户可直接上手
- 极简配置,由单一节点的训练程序转变为分布式训练程序,只需要几行配置代码
实现思路
首先需要准备训练和测试数据集,并定义一个适合该任务的神经网络结构,可以采用卷积神经网络(CNN)和循环神经网络(RNN)等结构。在OneFlow中,使用Parallelizer API配置分布式训练,自动处理任务调度、资源并行等问题。同时,为了进一步优化训练过程,在OneFlow中可以使用AutoMixedPrecision API自动进行混合精度训练,减少显存的使用量,提高训练速度。最后,使用Accuracy API计算模型在测试集上的准确率和Top-K准确率等指标。使用OneFlow框架可以简单、高效地实现Stable Diffusion模型文生图推理效率优化,提高训练速度和效果,加快模型迭代速度,从而更好地服务于实际业务需求。
通过 OneFlow 提供的分布式配置的接口,只需要简单的几行配置(指定分布式计算的节点 ip 以及每个节点使用 gpu 的数量)即可实现分布式的训练网络。例如下面这个例子,直接改写为分布式作业调度,来并行处理,针对于SD模型优化代码展示,请看模型压缩包:
import numpy as np
import oneflow as flow
import oneflow.typing as tpBATCH_SIZE = 100def mlp(data):#构建网络...@flow.global_function(type="train")
def train_job(images: tp.Numpy.Placeholder((BATCH_SIZE, 1, 28, 28), dtype=flow.float),labels: tp.Numpy.Placeholder((BATCH_SIZE,), dtype=flow.int32),
) -> tp.Numpy:#作业函数实现...#配置训练优化方法和参数if __name__ == '__main__':#调用作业函数,开始训练...loss = train_job(images, labels)#...
总结:
预测推理性能很困难,需要进行直接测量实验,才能找到最佳执行参数。 我们在此次大赛的硬件支持下和开发范围内进行了多次的性能测试,来确保验证应用的整体(端到端)性能。
针对于不同的参数和优化逻辑,设备的表现根据批次大小而异。总结任务最佳批次大小取决于模型、推理精度等因素。 同样 在某些情况下,可能需要将流和批处理结合起来才能尽力提高吞吐量。
还有一种可能的吞吐量优化策略是设置延迟上限,然后增加批次大小和/或流数,直到出现长尾延迟问题(即吞吐量不再增加)为止。这个我们会在之后对模型的推理优化继续深究。
总之,使用OpenVINO Runtime的异步推理API,将SD推理程序改造为异步推理的实现方式,可以看到明显的提升SD推理程序的吞吐量。由于本次的时间有限,优化效果并不大,我们之后时间充裕的情况下,还有下面几种优化方向,会一一尝试达到最大效率,
-
使用 NNCF 应用对训练时间压缩
-
模型压缩,通过过滤器剪枝:,逐步减小模型参数,并使用混合精度量化技术,减小模型存储需求。
这次大赛给我带来了许多的收获,包括技术学习和实践机会,英特尔技术和AI组件的深入学习了解,更多的是对自己能力的查漏补缺,认知到自己还有许多的不足,会加倍努力,自我锻炼,期待与大赛的下一次交手,我也会”王者归来“!
的吞吐量。由于本次的时间有限,优化效果并不大,我们之后时间充裕的情况下,还有下面几种优化方向,会一一尝试达到最大效率,
-
使用 NNCF 应用对训练时间压缩
-
模型压缩,通过过滤器剪枝:,逐步减小模型参数,并使用混合精度量化技术,减小模型存储需求。
这次大赛给我带来了许多的收获,包括技术学习和实践机会,英特尔技术和AI组件的深入学习了解,更多的是对自己能力的查漏补缺,认知到自己还有许多的不足,会加倍努力,自我锻炼,期待与大赛的下一次交手,我也会”王者归来“!
相关文章:

OpenVINO异步Stable Diffusion推理优化方案
文章目录 Stable Diffusion 推理优化背景技术讲解:异步优化方案思路:异步推理优化原理OpenVINO异步推理Python API同步和异步实现方式对比 oneflow分布式调度优化优势:实现思路 总结: Stable Diffusion 推理优化 背景 2022年&…...

51单片机的智能加湿器控制系统【含proteus仿真+程序+报告+原理图】
1、主要功能 该系统由AT89C51单片机LCD1602显示模块DHT11湿度传感器模块继电器等模块构成。主要适用于智能自动加湿器、湿度保持、湿度控制等相似项目。 可实现基本功能: 1、LCD1602液晶屏实时显示湿度信息 2、DHT11采集湿度 3、按键可以调节适宜人体湿度的阈值范围࿰…...

NoSql非关系型数据库
前言:Nosql not only sql,意即“不仅仅是sql”,泛指非关系型数据库。这些类型的数据存储不需要固定的模式(当然也有固定的模式),无需多余的操作就可以横向扩展。NoSql数据库中的数据是使用聚合模型来进行处…...

抖音集团面试挂在2面,复盘后,决定二战.....
先说下我基本情况,本科不是计算机专业,现在是学通信,然后做图像处理,可能面试官看我不是科班出身没有问太多计算机相关的问题,因为第一次找工作,字节的游戏专场又是最早开始的,就投递了…...
每个.NET开发都应掌握的C#处理文件系统I/O知识点
上篇文章讲述了C#多线程知识点,本文将介绍C#处理文件的知识点。在.NET开发领域,文件系统I/O是一个至关重要的主题,尤其是在处理文件、目录和数据存储方面。C#作为.NET平台的主要编程语言,提供了丰富而强大的文件系统I/O功能&#…...

vue3 中使用 sse 最佳实践,封装工具
工具 // 接受参数 export interface SSEChatParams {url: string,// sse 连接onmessage: (event: MessageEvent) > void,// 处理消息的函数onopen: () > void,// 建立连接触发的事件finallyHandler: () > void,// 相当于 try_finally 中的 finally 部分,不…...

OpenCV快速入门【完结】:总目录——初窥计算机视觉
文章目录 前言目录1. OpenCV快速入门:初探2. OpenCV快速入门:像素操作和图像变换3. OpenCV快速入门:绘制图形、图像金字塔和感兴趣区域4. OpenCV快速入门:图像滤波与边缘检测5. OpenCV快速入门:图像形态学操作6. OpenC…...

车企数据治理实践案例,实现数据生产、消费的闭环链路 | 数字化标杆
随着业务飞速发展,某汽车制造企业业务系统数量、复杂度和数据量都在呈几何级数的上涨,这就对于企业IT能力和IT架构模式的要求越来越高。加之企业大力发展数字化营销、新能源车等业务,希望通过持续优化客户体验,创造可持续发展的数…...

深入学习锁--Lock各种使用方法
一、什么是Lock Lock是一个接口,通常所说的可重入锁是指Lock的一个实现子类ReentrantLock 二、Lock实现步骤: ①创建锁对象Lock lock new ReentrantLock(); ②加锁lock.lock(); ③释放锁lock.unlock(); import java.util.concurrent.locks.Lock; import java.util…...

计算机毕设:基于机器学习的生物医学语音检测识别 附完整代码数据可直接运行
项目视频讲解: 基于机器学习的生物医学语音检测识别 完整代码数据可直接运行_哔哩哔哩_bilibili 运行效果图: 数据展示: 完整代码: #导入python的 numpy matplotlib pandas库 import pandas as pd import numpy as np import matplotlib.pyplot as plt #绘图 import se…...

VMware安装Ubuntu系统(Server端,Desktop端步骤一样)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

Navicat 与 华为云 GaussDB 合作再升级,赋能 GaussDB 分布式数据库
2023 年第三季度,Navicat 首次支持了华为云 GaussDB 主备版数据库。经过双方团队进一步的深化合作,Navicat 完成了 GaussDB 分布式的研发适配工作,赋能 GaussDB 全域数据库产品。 GaussDB 数据库分为主备版和分布式版两种模式。主备版适用于…...

【Docker】从零开始:13.Docker安装tomcat
Docker】从零开始:13.Docker安装Tomcat 下载Tomcat镜像启动Tomcat镜像新版本Tomcat修改访问Tomact首页 下载Tomcat镜像 [rootdocker ~]# docker pull tomcat Using default tag: latest latest: Pulling from library/tomcat 0e29546d541c: Pull complete 9b829c7…...
风控规则引擎(一):Java 动态脚本
风控规则引擎(一):Java 动态脚本 日常场景 共享单车会根据微信分或者芝麻分来判断是否交押金汽车租赁公司也会根据微信分或者芝麻分来判断是否交押金在一些外卖 APP 都会提供根据你的信用等级来发放贷款产品金融 APP 中会根据很复杂规则来判…...
第五十六天|583. 两个字符串的删除操作 72. 编辑距离
583. 两个字符串的删除操作 可以求出最大子序列然后用字符串长度去减,也可以用删除的思路,如下: class Solution { public:int minDistance(string word1, string word2) {vector<vector<int>> dp(word1.size()1,vector<int…...
java中Lists.newArrayList和new ArrayList的详细区别?
下面是对Lists.newArrayList()和new ArrayList<>()的详细区别进行举例说明: 创建具有初始数据的列表: java Copy code import com.google.common.collect.Lists; List<String> list1 Lists.newArrayList("apple", "banana…...

从图片或PDF文件识别表格提取内容的简单库img2table
img2table是一个基于OpenCV 图像处理的用于 PDF 和图像的表识别和提取 Python库。由于其设计基于神经网络的解决方案,提供了一种实用且更轻便的替代方案,尤其是在 CPU 上使用时。 该库的特点: 识别图像和PDF文件中的表格,包括在表…...
CSV文件中使用insert 函数在指定列循环插入不同数据
文章目录 一、系统、工具要求二、需求三、代码实现:四、核心代码解读五、逐行更改某一列数据六:实现在文件的末尾增加指定内容列 一、系统、工具要求 pandaspythoncsv Windows 系统 二、需求 我有两个文件: 文件一:subject_ma…...

【华为OD题库-064】最小传输时延I-java
题目 某通信网络中有N个网络结点,用1到N进行标识。网络通过一个有向无环图.表示,其中图的边的值表示结点之间的消息传递时延。 现给定相连节点之间的时延列表times[]{u,v, w),其中u表示源结点,v表示目的结点࿰…...

全文检索[ES系列] - 第495篇
历史文章(文章累计490) 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 M…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...