将 Google Kubernetes Engine (GKE) 上稳定扩散的启动时间缩短 4 倍

2023-11-19

Cloud Ace 是 Google Cloud 全球战略合作伙伴,在亚太地区、欧洲、南北美洲和非洲拥有二十多个办公室。Cloud Ace 在谷歌专业领域认证及专业知识目前排名全球第一位,并连续多次获得 Google Cloud 各类奖项。作为谷歌云托管服务商,我们提供谷歌云谷歌地图谷歌办公套件谷歌云认证培训等服务。

Cloud Ace - 谷歌云 | 谷歌云全球战略合作伙伴 | 云服务器据点最多经销商​cloud-ace.cn/​编辑

随着人工智能生成内容(AIGC)的日益流行,基于文本到图像的人工智能模型(例如稳定扩散)的开源项目已经出现。稳定扩散是一种扩散模型,可根据给定的文本输入生成逼真的图像。在此 GitHub 存储库中,我们提供了三种不同的解决方案,分别用于在 Google Cloud Vertex AI、Google Kubernetes Engine (GKE) 和基于 Agones 的平台上快速部署 Stable Diffusion,以通过弹性基础设施确保稳定的服务交付。本文将重点介绍 GKE 上的稳定扩散模型,并将启动时间缩短多达 4 倍。

问题陈述

Stable Diffusion 的容器镜像较大,大约达到 10-20GB,这会减慢容器启动时的镜像拉取过程,从而影响启动时间。在需要快速伸缩的场景下,启动新的容器副本可能需要10分钟以上,严重影响用户体验。

在容器启动过程中,我们可以按时间顺序看到以下事件:

  1. 触发Cluster Autoscaler进行伸缩+节点启动和Pod调度:225秒
  2. 图片拉取启动:4秒
  3. 图片拉取:5分23秒
  4. Pod 启动:1 秒
  5. SD-WebUI服务:超过2分钟

分析这个时间序列可以看出,运行在容器中的 Stable Diffusion WebUI 启动缓慢主要是由于整个运行时的依赖较重,导致容器镜像体积过大,拉取镜像和初始化pod的时间变长。

因此,我们从以下三个方面考虑优化启动时间:

  1. 优化Dockerfile:选择合适的基础镜像,尽量减少运行时依赖的安装,以减小镜像大小。
  2. 将基础环境与运行时依赖分离:通过PD磁盘镜像加速运行时环境的创建。
  3. 利用 GKE Image Streaming:利用 GKE Image Streaming 优化图像加载时间,并利用 Cluster Autoscaler 来增强弹性缩放和调整大小的速度。

本文重点介绍一种通过将基础环境与运行时依赖项分离并利用高性能磁盘映像来优化 Stable Diffusion WebUI 容器的启动时间的解决方案。

优化 Dockerfile

首先,这是一个基于 Stable Diffusion WebUI 官方安装说明的参考 Dockerfile:

https://github.com/nonokangwei/Stable-Diffusion-on-GCP/blob/main/Stable-Diffusion-UI-Agones/sd-webui/Dockerfile

在Stable Diffusion的初始构建容器镜像中,我们发现除了基础镜像NVIDIA运行时之外,还安装了大量的库、依赖项和扩展。

优化前,容器镜像大小为16.3GB。

在优化Dockerfile方面,经过对Dockerfile的分析,我们发现nvidia运行时占用了大约2GB,而PyTorch库是一个非常大的包,占用了5GB左右。此外,稳定扩散及其扩展也占据了一些空间。

因此,遵循最小可行环境的原则,我们可以从环境中删除不必要的依赖项。

我们可以使用 NVIDIA 运行时作为基础镜像,将 PyTorch 库、Stable Diffusion 库和扩展从原始镜像中分离出来,分别存储在文件系统中。下面是原始的 Dockerfile 片段,

# Base image
FROM nvidia/cuda:11.8.0-runtime-ubuntu22.04

RUN set -ex && \
    apt update && \
    apt install -y wget git python3 python3-venv python3-pip libglib2.0-0 pkg-config libcairo2-dev && \
    rm -rf /var/lib/apt/lists/*

# Pytorch 
RUN python3 -m pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117

…

# Stable Diffusion
RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
RUN git clone https://github.com/Stability-AI/stablediffusion.git /stable-diffusion-webui/repositories/stable-diffusion-stability-ai
RUN git -C /stable-diffusion-webui/repositories/stable-diffusion-stability-ai checkout cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf

…

# Stable Diffusion extensions
RUN set -ex && cd stable-diffusion-webui \
    && git clone https://gitcode.net/ranting8323/sd-webui-additional-networks.git extensions/sd-webui-additional-networks \
    && git clone https://gitcode.net/ranting8323/sd-webui-cutoff extensions/sd-webui-cutoff \
    && git clone https://github.com/toshiaki1729/stable-diffusion-webui-dataset-tag-editor.git extensions/stable-diffusion-webui-dataset-tag-editor

移出 Pytorch 库和稳定扩散后,我们只在基础映像中保留了 NVIDIA 运行时,这是新的 Dockerfile。

使用PD磁盘镜像来存储库PD 磁盘映像是 Google Cloud 中实例部署的基石。这些虚拟映像通常称为模板或引导磁盘,包含基线操作系统以及实例首次启动时将拥有的所有应用程序软件和配置。这里的想法是将所有运行时库和扩展存储在磁盘映像中,在本例中磁盘映像的大小为 6.77GB。使用磁盘镜像的优点是最多可以支持1000个磁盘同时恢复,适合大规模扩缩容的场景。

gcloud compute disks create sd-lib-disk-$NOW --type=pd-balanced --size=30GB --zone=$ZONE --image=$IMAGE_NAME

gcloud compute instances attach-disk ${MY_NODE_NAME} --disk=projects/$PROJECT_ID/zones/$ZONE/disks/sd-lib-disk-$NOW --zone=$ZONE

我们使用 DaemonSet 在 GKE 节点启动时挂载磁盘。

具体步骤如下:

如前几节所述,为了加快初始启动以获得更好的性能,我们尝试将永久性磁盘挂载到 GKE 节点以放置运行时库以实现稳定扩散。

利用 GKE Image Streaming 和集群自动缩放器

此外,如前所述,我们还启用了 GKE Image Streaming 来加速图像拉取和加载过程。GKE Image Streaming 的工作原理是使用网络挂载将容器的数据层附加到 containerd,并通过网络、内存和磁盘上的多个缓存层来支持它。一旦我们准备好 Image Streaming 挂载,无论容器大小如何,您的容器都会在几秒钟内从 ImagePulling 状态转换为 Running 状态。这有效地将应用程序启动与容器映像中所需数据的数据传输并行化。因此,您可以体验更快的容器启动时间和更快的自动扩展。

我们启用了 Cluster Autoscaler (CS) 功能,该功能允许 GKE 节点在请求增加时自动扩展。Cluster Autoscaler 触发并确定处理额外请求所需的节点数量。当 Cluster Autoscaler 启动新的扩展浪潮并且新的 GKE 节点在集群中注册时,DaemonSet 开始工作以协助挂载包含运行时依赖项的磁盘映像。然后,稳定扩散部署通过 HostPath 访问该磁盘。此外,我们还利用了Cluster Autoscaler 的优化利用率配置文件,这是 GKE CA 上的一个配置文件,它优先考虑优化利用率而不是保留集群中的备用资源,以减少扩展时间、节省成本并提高机器利用率。

最终结果

最终启动结果如下:

按年代顺序:

  1. 触发集群自动缩放器进行缩放:38秒
  2. 节点启动和Pod调度:89秒
  3. 安装PVC:4秒
  4. 图片拉取启动:10秒
  5. 图片拉取:1秒
  6. Pod 启动:1 秒
  7. 能够提供sd-webui服务(大约):65秒

总体而言,启动新的 Stable Diffusion 容器实例并开始在新的 GKE 节点上提供服务大约需要 3 分钟。与之前的12分钟相比,显然启动速度的显著提升,提升了用户体验。

在这里查看完整代码:

https://github.com/nonokangwei/Stable-Diffusion-on-GCP/tree/main/Stable-Diffusion-UI-Agones/optimized-init

注意事项:虽然上述技术分割了依赖关系,使容器大小更小,并且您可以从 PD 磁盘映像加载库,但仍有一些缺点需要考虑。将所有内容打包在一个容器映像中具有其优点,您可以拥有单个不可变且版本化的工件。将基本环境与运行时依赖项分离意味着您需要维护和更新多个工件。您可以通过构建工具来管理 PD 磁盘映像的更新来缓解这种情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Google Kubernetes Engine (GKE) 上稳定扩散的启动时间缩短 4 倍 的相关文章

随机推荐

  • 解决BookxNotePro在linux下无法启动或GLIBC_2.29‘ not found的问题

    问题描述如题 命令行启动出现如下报错 usr local BookxNotePro BookxNotePro usr local BookxNotePro BookxNotePro lib x86 64 linux gnu libm so
  • JS声明二维数组常见办法

    JS声明二维数组常见办法 目录 文章目录 前言 new Array 和 fill fill 灵活插入 for 笨办法 Array from 前言 目前论坛常见的办法代码质量奇差 因此针对这个问题进行整理 new Array和fill con
  • 使用机器学习算法打造一个简单的“微博指数”

    欢迎大家前往腾讯云技术社区 获取更多腾讯海量技术实践干货哦 作者 林浩威 前言 随着人工智能的大热 越来越多的小伙伴们开始投身到机器学习的大潮中 作为其中的一员 我对此也是极有兴趣的 当然我更感兴趣的 是怎么利用这些有趣的算法 来实现脑海里
  • element样式无法修改

    在使用el form组件时 组件中的字体是黑色的 需要显示白色字体就加了个color fff 结果发现修改并没有什么效果 还是原来的黑色 打开F12发现属于 el form item label选择器下面的 我就在css下面修改了该选择器
  • 端口占用查询

    我们做WEB开发 本地调试时 有时出现 Caused by java net BindException Address already in use bind at sun nio ch Net bind0 Native Method a
  • 机械孔与盲孔

    过孔是什么 过孔 Via 电路板上的孔 连接不同层之间的线路 把电路板从平面结构变成立体结构 单层线路想不交叉太难了 双层或更多层线路 必须通过过孔来连接 通过孔壁上的铜 连通上下层的电路铜线 单层PCB 有些时候无法布线 必须通过过孔换层
  • Chisel手册之Types

    本文是Chisel手册第二篇Types Types 表示硬件设计的Chisel图包含原始节点和类型节点 Chisel类型系统与底层Scala类型系统分开维护 因此类型节点散布在原始节点之间 以允许Chisel检查并响应Chisel类型 Ch
  • 微信小程序 实现底部导航栏tabbar

    参考链接 1 微信小程序底部导航Tabbar https www cnblogs com huangjialin p 6278429 html 2 小程序自定义tabbar实现中间图标突出效果 附带wx hideTabBar不生效的bug解
  • Spring Boot 启动报错解决:No active profile set, falling back to default profiles: default

    在SpringBoot启动时 控制台打印出来的信息有这么一条 No active profile set falling back to default profiles default 如下图 这句话的意思是 没有指定项目的配置文件 使用
  • Skyfire: 一种用于Fuzzing的数据驱动的种子生成工具

    Skyfire Data Driven Seed Generation for Fuzzing 作者 杨鑫 清华大学 论文发表于 IEEE S P 2017 原文作者 Junjie Wang Bihuan Chen Lei Wei and
  • C# 使用SignalR实现消息通知

    背景 Web端需要能实时接收到消息推送 当客户有新消息来时 在客户端的右下角进行弹框提醒 什么是signalR Asp net SignalR是微软为实现实时通信的一个类库 一般情况下 signalR会使用JavaScript的长轮询 lo
  • 【Android -- UI 开发】WebView 的基本使用

    一 简介 WebView 在 Android 平台上是一个特殊的 View 基于 webkit 引擎 展现 web 页面的控件 这个类可以被用来在你的 app 中仅仅显示一张在线的网页 还可以用来开发浏览器 WebView 内部实现是采用渲
  • GitHub pages 如何搭建一个个人博客

    搭建一个 GitHub Pages 个人博客的步骤如下 在 GitHub 上创建一个名为 username github io 的仓库 其中 username 是你的 GitHub 用户名 在仓库里创建一个 index html 文件 用于
  • 刚学JavaWeb如何创建一个简单的Servlet项目(保姆级!!!)

    idea如何创建一个简单的Servlet项目 一 准备步骤 1 创建一个工程 2 添加Web application支持 3 部署Tomcat服务器 4 向服务器中添加项目 5 向项目中导入所需要的JAR包 二 编写一个简单的Servlet
  • java动态加载jar包,并运行其中的类和方法

    flink 相关 https www toutiao com article 6883793897495986691 动态加载jar包 在实际开发中经常会需要用到 尤其涉及平台和业务的关系的时候 业务逻辑部分可以独立出去交给业务方管理 业务
  • Bugku题目Reverse逆向部分wp(持续更新)

    目录 入门逆向 Easy Re 游戏过关 sign in Easy vb Next 入门逆向 题目链接 丢入DIE PEID看过 没有壳 32位 直接IDA 汇编代码直接看到 flag Re 1s S0 C0OL Easy Re 题目链接
  • 查看淘宝镜像

    win R 打开输入cmd打开 查看node是否安装输入命令 node v 安装淘宝镜像输入命令 npm install g cnpm registry https registry npm taobao org 查看淘宝镜像输入命令 np
  • 场景题

    场景题 1 场景题汇总 1 情景题 如果一个外卖配送单子要发布 现在有200个骑手都想要接这一单 如何保证只有一个骑手接到单子 2 场景题 美团首页每天会从10000个商家里面推荐50个商家置顶 每个商家有一个权值 你如何来推荐 第二天怎么
  • 用Calendar.getInstance()后,set月份被加一问题

    一 问题描述 今天查询一个bug发现了这个问题 使用Calendar 中的before 和after方法比较日期是否在范围内 实际与代码不符 我就去查明原因 首先说下这两个方法吧 日期1 before 日期2 第一个日期在第二个日期之前的意
  • 将 Google Kubernetes Engine (GKE) 上稳定扩散的启动时间缩短 4 倍

    Cloud Ace 是 Google Cloud 全球战略合作伙伴 在亚太地区 欧洲 南北美洲和非洲拥有二十多个办公室 Cloud Ace 在谷歌专业领域认证及专业知识目前排名全球第一位 并连续多次获得 Google Cloud 各类奖项