以下文章來源于谷歌云服務,作者 Google Cloud
背景
現如今隨著 AIGC 這個話題越來越熱,越來越多優秀的開源項目基于文生圖的 AI 模型如 MidJourney,Stable Diffusion 等應運而生。Stable Diffusion 是一個文字生成圖像的 Diffusion 模型,它能夠根據給定任何文本輸入生成逼真的圖像。我們在 GitHub Repo 中提供了三種不同的解決方案 (可參考https://github.com/nonokangwei/Stable-Diffusion-on-GCP),可以快速地分別在 GCP Vertex AI,GKE,和基于 Agones 的平臺上部署 Stable Diffusion,以提供彈性的基礎設施保證 Stable Diffusion 提供穩定的服務。本文將重點討論 Stable Diffusion 模型在 GKE 上的實踐。
提出問題
在實踐中,我們也遇到了一些問題,例如 Stable Diffusion 的容器鏡像較大,大約達到 10-20GB,導致容器在啟動過程中拉取鏡像的速度變慢,從而影響了啟動時間。在需要快速擴容的場景下,啟動新的容器副本需要超過 10 分鐘的時間,嚴重影響了用戶體驗。

我們看到容器的啟動過程,按時序排列:
●觸發 Cluster Autoscaler 擴容 + Node 啟動并調度 Pod: 225s
●啟動 Pull Image:4s
●拉取鏡像: 5m 23s
●啟動 Pod:1s
●能夠提供 sd-webui 的服務 (大約): > 2m
在這段時序分析中,我們可以看到,在 Stable Diffusion WebUI 運行在容器上啟動慢主要面臨的問題是由于整個 runtime 依賴較多,導致容器鏡像太大從而花費了很長時間拉取下載、也造成了 pod 啟動初始化加載時間過長。于是,我們考慮優化啟動時間從以下三個方面入手:
●優化 Dockerfile,選擇正確的 base image,精簡 runtime 的依賴安裝,減小鏡像大小。
●借助基礎環境與 runtime 依賴分離方式,通過磁盤復制方式加速運行環境的創建。
●通過 GKE Image Streaming 優化鏡像加載時間,利用 Cluster Autoscaler 提升彈性擴縮容速度。
本文著重為大家介紹通過基礎環境與 runtime 依賴分離方式,借助磁盤復制的高性能來優化 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 runtime 之外,還安裝了大量的庫和擴展等。

▲調優之前容器鏡像大小為 16.3GB
在 Dockerfile 優化方面,我們對 Dockerfile 進行分析后,發現 nvidia runtime 約占 2GB,而 PyTorch 庫是一個非常大的包,約占 5GB。另外 Stable Diffusion 及其擴展等也占據了一定的空間。因此,我們按照最小可用環境為原則,去除環境中不必要的依賴。將 nvidia runtime 作為基礎鏡像,然后把 PyTorch、Stable Diffusion 的庫和擴展等從原始鏡像中分離出來,單獨存放在文件系統中。
以下是初始的 Dockerfile 的片段。
我們在移除 Pytorch 的庫和 Stable Diffusion 之后,我們只保留了基礎鏡像 nvidia runtime 在新的 Dockerfile 中。

▲基礎鏡像變成了 2GB
其余的運行時類庫和 extension 等存放在磁盤鏡像中,磁盤鏡像的大小為 6.77GB。采用磁盤鏡像的好處是,它可以最多支持同時恢復 1,000 塊磁盤,完全能滿足大規模擴縮容的使用場景。

掛載磁盤到 GKE 節點
然而,問題來了,如何將這個單獨的文件系統掛載到容器運行時中呢?一種想法是使用 Persistent VolumeClaim (PVC) 進行掛載,但由于 Stable Diffusion WebUI 在運行時既需要讀取又需要寫入磁盤,而 GKE 的 PD CSI 驅動程序目前不支持多寫入 ReadWriteMany,只有像 Filestore 這樣的 NFS 文件系統才能支持,但是通過網絡掛載的 Filestore 就延遲來說仍然無法達到快速啟動的效果。同時,由于 GKE 目前不支持在創建或更新 Nodepool 時掛載磁盤,所以我們考慮使用 DaemonSet 在 GKE 節點啟動時掛載磁盤。具體做法如下:

那么如何將磁盤掛載到 GKE 的節點上呢?可以直接調用 Cloud SDK,創建基于磁盤鏡像的磁盤。
利用 GKE Image Streaming
和 Cluster Autoscaler
另外,正如我們前面提到的那樣,在優化鏡像下載和加載時間方面,我們還啟用了 GKE Image Streaming 來加速鏡像的拉取速度。它的工作原理是使用網絡掛載將容器數據層掛載到 containerd 中,并在網絡、內存和磁盤上使用多個緩存層對其進行支持。一旦我們準備好 Image Streaming 掛載,您的容器就會在幾秒鐘內從 ImagePulling 狀態轉換為 Running (無論容器大小);這有效地將應用程序啟動與容器映像中所需數據的數據傳輸并行化。因此,您可以看到更快的容器啟動時間和更快速的自動縮放。
我們開啟了 Cluster Autoscaler 功能,讓有更多的請求到來時,GKE 節點自動進行彈性擴展。通過 Cluster Autoscaler 觸發并決定擴展到多少個節點來接收新增的請求。當 CA 觸發了新的一輪擴容,新的 GKE 節點注冊到集群以后,Daemonset 就會開始工作,幫助掛載存儲了 runtime 依賴的磁盤鏡像,而 Stable Diffusion Deployment 則會通過 HostPath 來訪問這個掛載在節點上的磁盤。
我們還使用了 Cluster Autoscaler 的 Optimization Utilization Profile 來縮短擴縮容時間、節省成本并提高機器利用率。
最后的啟動效果如下:

按時序排列
●觸發 Cluster Autoscaler 擴容:38s
●Node 啟動并調度 Pod:89s
●掛載 PVC:4s
●啟動 Pull Image:10s
●拉取鏡像:1s
●啟動 Pod:1s
●能夠提供 sd-webui 的服務 (大約): 65s
總共經歷了大約 3 分鐘的時間,就完成了啟動一個新的 Stale Diffusion 容器實例,并在一個新的 GKE 節點上進行正常服務的過程。相比于之前的 12 分鐘,可以看見,明顯的提升啟動速度改善了用戶體驗。
完整代碼: https://github.com/nonokangwei/Stable-Diffusion-on-GCP/tree/main/Stable-Diffusion-UI-Agones/optimizated-init
通過 VolumeSnapshot
除了掛載 Disk 到 GKE 節點上,還有一種嘗試,我們可以使用 StatefulSet 來掛載 PVC。
具體做法如下:先定義一個 storageclass,注意我們使用DiskImageType: images來指定 PVC從 Disk Image 來恢復,而不是 Snapshot。
●Snapshot 每 10 分鐘只能恢復一次,一小時以內恢復 6 次 Disk 的限制。
●而 Image 可以支持每 30 秒恢復一次,最多 1,000 個 Disk。
再定義一個 VoluemSnapShotContent,它指定了 source 為一個 Disk Image sd-image。
接下來,我們再創建一個 VolumeSnapShot,指定它的 source 是剛剛定義的VoluemSnapShotContent。
最后,我們創建一個 StatefulSet 來掛載這個 VolumeSnapShot。
我們嘗試擴容更多的副本。
可見 GKE 可以支持并行的啟動這些 Pod,并且分別掛載相應的磁盤。

PersistentVolumeClaims

完整代碼:
https://github.com/Leisureroad/volumesnapshot-from-diskimage
最終,我們可以看見如下的 Stable Diffusion 的 WebUI。


原文標題:優化 Stable Diffusion 在 GKE 上的啟動體驗
文章出處:【微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。
-
谷歌
+關注
關注
27文章
6223瀏覽量
107524
原文標題:優化 Stable Diffusion 在 GKE 上的啟動體驗
文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
系統啟動時間優化方案--基于米爾MYD-YG2LX開發板
?Diffusion生成式動作引擎技術解析
優化模式下低啟動低消耗的充電器ic U6018

使用OpenVINO GenAI和LoRA適配器進行圖像生成

使用OpenVINO?進行優化后,為什么DETR模型在不同的硬件上測試時顯示不同的結果?
安裝OpenVINO?工具包穩定擴散后報錯,怎么解決?
EE-359:ADSP-CM40x啟動時間優化和器件初始化

在主板上優化PCIe通道設置
優化 FPGA HLS 設計
實操: 如何在AirBox上跑Stable Diffusion 3

評論