JetBrains 的 AI 图形发展历程
在 JetBrains 生成图稿
JetBrains 不断完善用作网站元素和发布图形的图稿的创建方式。 我们的使命是将平面设计师从日常任务中解放出来,让他们能够专注于自己的核心能力 – 创造力。 JetBrains 用于生成图稿的内部工具的历史大约开始于十年前。 起初,我们主要使用基于 WebGL 的工具,这些工具可以在浏览器中实时随机生成所有内容(此处提供了交互式归档)。 下面的图像就是用这种方式创建的。
使用 WebGL 创建的启动画面。
2020 年,我们发布了第一款基于深度神经网络的工具。 自那时起,所有内容都在 K8s GPU 集群中使用适用于本地和远程开发的 PyCharm 和 Datalore 生成。 浏览器仅用于输入输出。 通过这种基于神经网络的方式,我们实现了更高程度的个性化,这让我们能够迎合设计师的需求,并且我们一直在努力改进。
以下图片使用组合图案生成网络(CPPN,上图)和 Stable Diffusion(SD,下图)制作而成。 本文将介绍这两种方式的技术细节,以及我们如何结合这两种方式来创造更精彩的设计。
使用神经网络生成的启动画面。
CPPN:概述
CPPN 是最简单的生成网络之一。 它们只是简单地将像素坐标 (x, y) 映射到图像颜色 (r, g, b)。 CPPN 通常使用特定的图像或图像集进行训练。 不过,我们发现,当初始化正确执行时,随机初始化的 CPPN 会生成漂亮的抽象图案。
CPPN 架构:像素坐标为输入,RGB 值为输出。
利用早期内部版本生成器的使用数据,我们改进了算法以提高视觉质量。 除此之外,我们还通过引入多个虚拟参数略微扩展了 CPPN 的经典架构。 因此,现在我们的 CPPN 会将 (x, y, a, b, c, f) 映射到 (r, g, b)。 这个简单的更改允许我们引入一种易于使用(但有些不可预测)的方法来更改图像,如下所示。
通过更新虚拟参数 (a),我们对图片进行了略微更改。
这些虚拟参数不一定是常量。 例如,我们可以将每个像素的虚拟参数 f 的值映射到此像素到图像中心的距离。 这一技巧使我们能够确保图像呈现圆形。 或者我们可以将 f 映射到像素坐标的绝对值之和,这将产生菱形图案。 这就是数学与艺术的真正结合!
不同的函数 f(x,y) 会产生不同的图像图案。
为了确保我们随机初始化的 CPPN 始终产生漂亮的设计,我们训练了一个推荐系统来预测给定的参数集是否会生成具有一定美感的图像。 我们根据内部测试期间收到的用户反馈来训练我们的算法。 下图显示了随机初始化的 CPPN 创建的两个图像示例以及它们对应的“美感”分数。
预测 CPPN 图像的“美感”分数。
CPPN:动画
当我们的 CPPN 生成的图稿被转换成视频图形时,它们真正变得栩栩如生。 通过将虚拟参数 (a, b, c) 映射到任何闭合的参数曲线(在同一点开始和结束的曲线),我们可以创建任何所需长度的无缝循环动画!
CPPN 动画视频的示例帧。
曲线函数的选择至关重要。 在平面圆上对虚拟参数添加动画是最简单的方式。 不过,它有一个缺点:当参数的符号发生变化(例如,从 0.01 变成 -0.01),而它具有较低的一阶导数值(在圆形轨迹的情况下为零)时,生成的动画通常会抖动。 为了解决这个问题,我们使用伯努利双纽线来确保虚拟参数的符号永远不会改变(见下图)。 这解决了动画抖动的问题,但也带来了一个新问题。 对于大多数动画帧,其中一个参数仅以增量方式更新,这使动画看起来过于简单。 我们通过切换到随机样条函数解决了这个问题。 我们使用的轨迹越复杂,动画看起来就越丰富!
CPPN 曲线函数示例。
CPPN:色彩校正
还有一个更重要的细节:色彩校正。 我们的 CPPN(以及由此产生的图像)是随机生成的,但我们需要确保每个图像都使用我们的品牌颜色。 我们尝试了几种不同的方式来实现这一目标。 第一次迭代(在 2020 版本中使用)依赖于浏览器中的 SVG 重新着色(使用 feColorMatrix 和 feComponentTransfer)。 这种方式速度很快,因为重新着色在浏览器中进行,我们可以更新调色板,而无需在服务器端重新呈现图像。 不过,实现起来却很棘手,因为有些调色板对于 feColorMatrix 和 feComponentTransfer 来说太过复杂,而且通常不可靠。 经过大量实验后,我们发现最终的颜色会因浏览器和操作系统而异。 以下是我们在 2020 年初进行的实验的一个示例。 左边是在 macOS 上通过使用 Safari 的设置由早期版本生成器生成的背景的屏幕截图,右边是在 Ubuntu Linux 上通过使用 Google Chrome 的设置由生成器生成的相同背景的屏幕截图。 请注意细微的亮度差异。 我们应用的后期处理效果越多,亮度差异就越明显。
亮度差异示例。
另一个示例是 MDN 的 feComponentTransfer 示例。 这一次,两个图像都在同一台机器上使用 Ubuntu Linux 和 Google Chrome 制作,但在左侧的屏幕截图中,硬件加速被禁用。 存在明显的色彩差异,尤其是在表查找示例之间。 因此,尽管速度非常快,但这种色彩校正的方式非常不一致。
色彩差异的示例。
我们目前的方式(从 2021 年开始使用)更直接。 我们以 32 位灰度来呈现源图像,这意味着我们的 CPPN 只返回单个明亮度值,而不是 RGB。 然后,我们将每个像素映射到具有预计算理想 RGB 值的查找表。 这种方式速度较慢,但会产生像素级精确的结果。
使用灰度图像进行色彩校正的示例。
使用 SVG 重新着色的 2020.1 启动画面。
将我们目前的色彩校正方式与带有虚拟参数和样条动画的 CPPN 一起使用时,就会得到类似下面的视频!
CPPN 的另一个显著特性是,得益于其简单的架构,可以轻松地将其计算图转换为 GLSL 代码。 在动画视频就绪之后,我们可以将其导出为 WebGL 片段着色器,然后直接在浏览器中运行。 这种方式的结果的一个示例是 Qodana 的着陆页。
点击此处查看我们基于 CPPN 的生成器。
要深入了解 CPPN,请查看我们包含代码示例的公共 Datalore Notebook:
驾驭 Stable Diffusion
Stable Diffusion 提供了高水平的广泛应用和视觉保真度,这使其成为我们图稿生成器的完美支柱。 为了使 Stable Diffusion 适合用作发布图形源,我们必须遵守以下标准:
- 图像应遵循品牌调色板。
- 不允许出现伪影或瑕疵(如坏像素)。
- 应该易于使用某种特定风格(抽象平滑线条)。
- 应该需要很少或不需要提示,这意味着它应该提供易于访问且直观的控制。
虽然始终存在改进的空间,但我们已经满足了所有上述要求。 最新的图像已公开,所有技术细节如下。
使用 Stable Diffusion 创建的 2023.1 启动画面。
为了产生始终符合我们所有标准的结果,我们使用设计师提供的各种参考资料对 Stable Diffusion 进行了微调。 下面是一些根据不同风格生成的图像示例。
通过微调 Stable Diffusion 获得的实验风格。
在深入研究微调过程的技术细节之前,我们先来看看 Stable Diffusion 的内部原理。 它在本质上由三部分组成:CLIP 文本编码器(用于将文本编码成多模态嵌入向量空间的微型 Transformer 模型),将图像压缩到隐空间以及从隐空间解压缩的变分自动编码器,以及降噪 UNet。
Stable Diffusion 的架构。 图像来源:www.philschmid.de/stable-diffusion-inference-endpoints。
生成过程大致如下:
- 我们将提示文本编码成一个嵌入向量,即一个 77×768 浮点数组。
- 我们随机生成图像的隐式表示,它可以是纯高斯噪声或初始图像的带噪表示。
- 我们以给定的步数,将编码的隐图像和编码的文本反复传递给降噪 UNet。
- 在对隐图像降噪后,我们将其传递给解码器,从而将其解压缩为标准的 RGB 图像。
降噪过程。 图像来源:jalammar.github.io/illustrated-stable-diffusion/。
对我们来说至关重要的是,Stable Diffusion 的好处在于,可以用很少的数据对其进行微调,并获得很好的结果! 作为“副作用”,数据高效的微调方法在计算上也是高效的,这使它变得更好。
最直接的微调方式是文本反转 (p-tuning)。 我们会冻结所有权重,例如 UNet、VAE 和文本编码器(这意味着我们不会在训练期间更新它们),并且只为文本编码器的每个嵌入向量训练一个新词。 因为我们每个嵌入向量只训练一个新词,只有 768 个可训练参数!
文本嵌入和反转过程概述。 图像来源:textual-inversion.github.io/。
这些自定义嵌入向量是可组合的,这意味着我们最多可以在单个提示中使用 77 个嵌入向量。 最重要的是,它们很容易训练,在单张 RTX 4090 上需要大约 2 个小时。 以下是训练过程的示例。 用于生成以下两个图像的提示均为“digital art in the style of ”,其中“”是我们正在训练的新词嵌入向量。 随着执行的训练步骤的增多,图像会发生演变,新的视觉风格会变得越来越明显。
使用文本反转经过 500 和 3000 个训练步骤后生成的图像。
另一种热门且高效的微调方法是低秩自适应,简称 LoRA。 LoRA 的关键思想类似于文本反转,只是这次除了冻结权重之外,我们还通过在 UNet 内的注意力层中添加小的适配器层来引入新权重。
一个 Transformer 层内的 LoRA 方法示意图。 图像来源:adapterhub.ml/blog/2022/09/updates-in-adapter-transformers-v3-1/。
与文本反转相比,这种方式可以从微调数据中捕获更复杂的图案(例如,“AI 肖像”应用会使用用户的面孔训练适配器层),但它使用的资源略多,最重要的是,多个 LoRA 无法组合。 在我们的具体用例中,我们发现 LoRA 在使用 Stable Diffusion XL 时最有效。 相比之下,在早期版本的 Stable Diffusion(1.4、1.5 或 2.1)中,文本反转可以实现更广泛的应用。
使用 LoRA 经过 200 和 1000 个训练步骤后生成的图像。
结合 Stable Diffusion 和 CPPN 的优点
我们使用 Stable Diffusion 的标准之一是需要确保生成的图像遵循某个特定品牌的调色板,这正是 CPPN 的用武之地! 在使用 Stable Diffusion 生成图像之前,我们使用自己的梯度生成器(如上所述)利用 CPPN 生成图像,以像素级精度应用所需的颜色,然后使用 VAE 对其进行编码并使用高斯噪声进行混合。 UNet 使用生成的隐图像作为其起点,从而保留原始色彩和构图。
CPPN → Stable Diffusion 流水线。
在 CPPN 图像就绪后,我们也可以直接在浏览器中对其进行编辑,以实现我们所能想象的任何形状和设计!
具有手动编辑 CPPN 图像的 CPPN → Stable Diffusion 流水线。
最后,使用我们的“CPPN → Stable Diffusion”流水线生成多个图像后,我们就可以用这些图像来训练另一个 CPPN,并将它们转换为动画,如上面的 CPPN:动画部分所述! 这里有一些示例 GLSL 代码,以及一些示例视频:
JetBrains 对 AI 赋能图形的探索和实现是一次冒险。 多年来,我们的工具不断发展和成熟,从最初使用基于 WebGL 的随机生成方式,到目前使用 CPPN 和 Stable Diffusion 生成时尚且个性化的设计。 展望未来,我们期待更高水平的自定义和广泛应用,我们对这些技术将在图形生成领域释放的潜力感到兴奋。
我们希望这篇关于我们的 AI 图稿发展历程的深入介绍对您有所启发! 我们诚邀您探索我们提供的示例(包括我们的交互式归档)并在下方的评论区或发送电子邮件至 cai@jetbrains.com 来分享您的反馈。 请告诉我们您未来希望从计算艺术团队看到什么样的主题!
本博文英文原作者: