我与Stable Diffusion的“缘” 主赛道 | 社区征文

大模型2023总结
我与Stable Diffusion的“缘”

写在前面

Stable Diffusion是一种潜在的文本到图像扩散模型,能够生成逼真的图像,只需任何文本输入,就可以自主自由创造漂亮的图像,使众多不会拍照的人在几秒钟内创造出惊人的图片。StableDiffusion可以生成不同的图片风格,比如:Anime 动画,realistic 写实,Landscape 风景,Fantasy 奇幻,Artistic 艺术。 还有很多其他的风格的,大家都可以在网上看到。

picture.image

缘起

2022年,Stable Diffusion模型横空出世,其成为AI行业从传统深度学习时代走向AIGC时代的标志性模型之一,并为工业界,投资界,学术界以及竞赛界都注入了新的AI想象空间,让AI再次性感。在当时我对它的了解仅限于耳闻其名。

要说我与Stable Diffusion的真正的“缘”,不得说一次偶然的机会,一场恰逢的比赛,让我陷入了对Stable Diffusion的深度研究,尝试多点优化AI生图模型在端侧设备上的 Pipeline性能,以求得”最优解“。

回顾那场比赛,我仿佛置身于Stable Diffusion的神秘迷雾之中,追随着技术的脉络,寻找着隐藏在其背后的奥秘。我如同一位探险者,悄然踏上了揭示Stable Diffusion真实面目的旅程。

比赛的一个月中,我仿佛踏上了一场技术“修炼”之旅,将自己沉浸在Stable Diffusion的算法世界中。如同一位艺术家对待自己的作品一样,我反复推敲,试图揭示这个技术的真正精髓。我以各种算法的武器武装自己,试图解锁Stable Diffusion的“密码”。这一过程中,每一次尝试都如同对抗一位强大的BOSS,让整个冒险变得惊心动魄。

现在比赛以拉开谢幕,但这段与Stable Diffusion的“缘分”如同一场艺术画,每一笔勾勒都是对技术探索的独特贡献。或许,未来还有更多的发现等待着我,让我在技术的海洋中不断前行,发现更多未知的宝藏。接下来我就比赛中的优化方向、思路和心得以文字的形式呈现出来,分享给大家!

原理讲解

Stable Diffusion(SD)模型是由Stability AI和LAION等公司共同开发的生成式模型,总共有1B左右的参数量,可以用于文生图,图生图,图像inpainting,ControlNet控制生成,图像超分等丰富的任务。而文生图任务是指将一段文本输入到SD模型中,经过一定的迭代次数,SD模型输出一张符合输入文本描述的图片。比如按照赛题要求输入关键字:

  1. Prompt输入:"a photo of an astronaut riding a horse on mars" 
  2. Negative Prompt输入:"low resolution, blurry"

picture.image

其本质就是给SD模型一个文本信息与机器数据信息之间互相转换的“桥梁”——CLIP Text Encoder模型。如下图所示,我们使用CLIP Text Encoder模型作为SD模型的前置模块,将输入的人类文本信息进行编码,输出特征矩阵,这个特征矩阵与文本信息相匹配,并且能够使得SD模型理解:完成对文本信息的编码后,就会输入到SD模型的“图像优化模块”中对图像的优化进行“控制”。

首先,“图像优化模块”是由一个U-Net网络和一个Schedule算法共同组成,U-Net网络负责预测噪声,不断优化生成过程,在预测噪声的同时不断注入文本语义信息。而schedule算法对每次U-Net预测的噪声进行优化处理(动态调整预测的噪声,控制U-Net预测噪声的强度) ,从而统筹生成过程的进度。在SD中,U-Net的迭代优化步数大概是50或者100次,在这个过程中Latent Feature的质量不断的变好(纯噪声减少,图像语义信息增加,文本语义信息增加)。整个过程如下图所示:

picture.image

U-Net网络和Schedule算法的工作完成以后,SD模型会将优化迭代后的Latent Feature输入到图像解码器(VAE Decoder)中,将Latent Feature重建成像素级图像、迭代去噪。

picture.image

我的优化思路分享

我们是通过利用 OpenVINO 的异步推理功能,实现了预处理、推理和后处理阶段的并行执行,从而提高了整体图像生成 Pipeline 的并行性。具体使用 OpenVINO 异步推理功能创建独立的推理请求,将每个图像处理阶段异步化,使其在硬件上并行执行,最大程度发挥多核心处理器的优势,显著提升了整体性能。

在提升SD文生图推理程序的性能前,先要理解评估AI推理程序性能的指标是什么。我们常用时延(Latency)和吞吐量(Throughput)来衡量AI推理程序的性能。

  • 时延具体指讲数据输入AI模型后,多长时间可以从AI模型拿到输出结果
  • 吞吐量具体指在单位时间能完成多少数据的AI推理计算

对于图像处理,吞吐量可以用单位时间内能完成多少张图片的AI推理计算来衡量,即FPS(Frame Per Second),如下图所示。

picture.image

OpenVINO自带的性能评测工具的benchmark_app,主要用于单纯评价AI模型推理性能的场景。

这种优化方式主要有这几种优点,在保证生图效果的情况下,降低pipeline端到端延迟,降低pipeline峰值内存占用:

  • 使得预处理、推理和后处理能够在硬件上并行执行,最大化利用多核心处理器的优势,提高整体 Pipeline 的效率。
  • 减少等待时间: 异步化图像输入和输出处理,减少了数据传输的等待时间,降低了整体端到端的延迟,尤其在大规模推理任务中具有显著优势。
  • 资源充分利用: 通过异步推理和异步化处理,确保硬件资源充分利用,提高了整个图像生成任务的吞吐量。
  • 保持图像生成效果: 该优化方案在提高性能的同时,确保了生成图像的质量和一致性

首先需要准备训练和测试数据集,并定义一个适合该任务的神经网络结构,可以采用卷积神经网络(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 tp

BATCH_SIZE = 100

def 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)
  #...

总结:

预测推理性能很困难,需要进行直接测量实验,才能找到最佳执行参数。 我们在此次大赛的硬件支持下和开发范围内进行了多次的性能测试,来确保验证应用的整体(端到端)性能。

针对于不同的参数和优化逻辑,设备的表现根据批次大小而异。总结任务最佳批次大小取决于模型、推理精度等因素。 同样 在某些情况下,可能需要将流和批处理结合起来才能尽力提高吞吐量。

还有一种可能的吞吐量优化策略是设置延迟上限,然后增加批次大小和/或流数,直到出现长尾延迟问题(即吞吐量不再增加)为止。这个我们会在之后对模型的推理优化继续深究。

这次大赛给我带来了许多的收获,包括技术学习和实践机会,英特尔技术和AI组件的深入学习了解,更多的是对自己能力的查漏补缺,认知到自己还有许多的不足,会加倍努力,自我锻炼,期待与大赛的下一次交手,我也会”王者归来“!也很高兴把自己的拙劣思路分享出来供大家参考。

InfoQ 文章链接:https://xie.infoq.cn/article/4e8980512d1a380959171387a

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论