本文以部署HuggingFace上的Stable Diffusion為例,演示如何使用數據緩存。通過數據緩存提前拉取Stable Diffusion相關模型數據,然后在創建Stable Diffusion應用實例時直接掛載模型數據,可以免去在實例中拉取模型數據的等待時間,加速Stable Diffusion應用部署。
背景信息
Stable Diffusion是一個可以根據文字描述生成和修改圖像的模型。Stable Diffusion分為文字理解和圖片生成兩個部分。文字理解部分使用CLIP模型對文本進行Encoding,圖片生成采用Diffusion模型。
阿里云不對第三方模型的合法性、安全性、準確性進行任何保證,阿里云不對由此引發的任何損害承擔責任。
您應自覺遵守第三方模型的用戶協議、使用規范和相關法律法規,并就使用第三方模型的合法性、合規性自行承擔相關責任。
前提條件
您使用的VPC已綁定公網NAT網關,并配置SNAT條目允許該VPC或下屬交換機的資源可以訪問公網。
如果VPC沒有綁定公網NAT網關,您需要在創建數據緩存和部署應用時綁定EIP,以便可以拉取公網數據。
準備運行環境
部署Stable Diffusion應用需要準備好包含Stable Diffusion運行所需環境的容器鏡像,環境需求包括CUDA、Diffusers庫,以及其他的基礎依賴等。ECI已經準備好了能運行大多數模型的穩定環境的容器鏡像。如果您的應用沒有特殊依賴,可以直接使用。
啟動HTTP服務的鏡像
GPU版:registry.cn-hangzhou.aliyuncs.com/eci_open/ubuntu:cuda11.7.1-cudnn8-ubuntu20.04
CPU版:registry.cn-hangzhou.aliyuncs.com/eci_open/ubuntu:hf-ubuntu20.04
鏡像相關信息參考如下:
以下Dockerfile可以構建一個基于Ubuntu和Python的開發環境,并預安裝一些常用依賴。在啟動容器后,可以使用命令
python3 http-server.py
啟動一個HTTP服務。FROM nvidia/cuda:11.7.1-cudnn8-runtime-ubuntu20.04 LABEL maintainer="Alibaba Cloud Serverless Container" ENV DEBIAN_FRONTEND=noninteractive RUN apt update && \ apt install -y bash \ vim \ build-essential \ git \ git-lfs \ curl \ ca-certificates \ libsndfile1-dev \ libgl1 \ python3.8 \ python3-pip \ python3.8-venv && \ rm -rf /var/lib/apt/lists # make sure to use venv RUN python3 -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" RUN mkdir -p /workspace/pic/ WORKDIR /workspace COPY http-server.py http-server.py # pre-install the heavy dependencies (these can later be overridden by the deps from setup.py) RUN python3 -m pip install --no-cache-dir --upgrade pip && \ python3 -m pip install --no-cache-dir \ torch \ torchvision \ torchaudio \ invisible_watermark && \ python3 -m pip install --no-cache-dir \ accelerate \ datasets \ hf-doc-builder \ huggingface-hub \ Jinja2 \ librosa \ numpy \ scipy \ tensorboard \ transformers \ omegaconf \ pytorch-lightning \ xformers \ safetensors \ diffusers CMD ["/bin/bash"]
http-server.py腳本是一個簡單的HTTP服務,用于接收輸入的文本,生成對應的圖片,并返回圖片路徑。
import os import hashlib import torch from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler from http.server import BaseHTTPRequestHandler from http.server import HTTPServer from urllib.parse import urlparse, parse_qs MODEL_DIR_NEV = "MODEL_DIR" APP_PORT_ENV = "APP_PORT" def text2image(input): model_id = os.getenv(MODEL_DIR_NEV, default="/data/model/") pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16) pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config) pipe = pipe.to("cuda") image = pipe(input).images[0] name = "/workspace/pic/" + hashlib.md5(input.encode('utf8')).hexdigest() + ".png" image.save(name) return name class GetHandler(BaseHTTPRequestHandler): def do_GET(self): query = parse_qs(urlparse(self.path).query) # 獲取參數值 input = query.get('input')[0] print("get user input:%s, try generate image" % input) picName = text2image(input) # 構造響應 self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(bytes("<html><head><title>Stable Diffusion</title></head>", "utf-8")) self.wfile.write(bytes("<body><p>Success generate image:%s</p>" % picName, "utf-8")) self.wfile.write(bytes("</body></html>", "utf-8")) if __name__ == '__main__': server = HTTPServer(('', int(os.getenv(APP_PORT_ENV, default="8888"))), GetHandler) server.serve_forever() print('Starting server')
支持WebUI的鏡像
鏡像地址:registry.cn-hangzhou.aliyuncs.com/eci_open/stable-diffusion:1.0.0
說明該鏡像對于Stable Diffusion模型是通用的,只需將創建好的模型數據緩存掛載到
/stable-diffusion-webui/models/Stable-diffusion/
目錄即可使用不同的模型。
操作步驟
使用啟動HTTP服務的鏡像
創建數據緩存
訪問HuggingFace,獲取模型ID。
本示例使用stabilityai/stable-diffusion-2-1模型。在HuggingFace找到目標模型后,在模型詳情頁面頂部可以復制模型ID。
創建數據緩存。
說明如果您的業務部署在中國內地地域,建議您在中國香港地域創建數據緩存,然后拷貝數據緩存到您需要的地域。
調用CreateDataCache接口創建數據緩存所采用的參數示例如下,表示從HuggingFace拉取指定模型數據,保存到名為test的Bucket的
/model/stable-diffusion/
目錄。數據緩存名為stable-diffusion,保留時長為1天。重要如果您通過SDK創建數據緩存,DataSource.Options中的各個參數前無需添加參數名的長度,例如
#10#repoSource
直接寫成repoSource
,#6#repoId
直接寫成repoId
即可。{ "RegionId": "cn-beijing", "SecurityGroupId": "sg-2ze63v3jtm8e6syi****", "VSwitchId": "vsw-2ze94pjtfuj9vaymf****", "Bucket": "test", "Path": "/model/stable-diffusion/", "Name": "stable-diffusion", "DataSource": { "Type": "URL", "Options": { "#10#repoSource": "HuggingFace/Model", "#6#repoId": "stabilityai/stable-diffusion-2-1" } }, "RetentionDays": 1 }
查詢數據緩存狀態。
根據返回的數據緩存ID調用DescribeDataCaches接口查詢數據緩存信息,當數據緩存的狀態(DataCaches.Status)為Available時,表示可以使用該數據緩存。
部署Stable Diffusion應用
使用數據緩存創建ECI實例,部署Stable Diffusion應用。
調用CreateContainerGroup接口創建ECI實例所采用的參數示例如下,該ECI實例使用GPU規格,并掛載了Stable Diffusion v2-1模型數據。實例內容器使用GPU版鏡像,容器啟動后會運行
python3 http-server.py
,啟動一個HTTP服務。{ "RegionId": "cn-beijing", "SecurityGroupId": "sg-2ze63v3jtm8e6syi****", "VSwitchId": "vsw-2ze94pjtfuj9vaymf****", "ContainerGroupName": "stable-diffusion", "InstanceType": "ecs.gn6i-c16g1.4xlarge", "DataCacheBucket": "test", "Container": [ { "Arg": [ "python3 http-server.py" ], "VolumeMount": [ { "MountPath": "/data/model/", "Name": "model" } ], "Command": [ "/bin/sh", "-c" ], "Gpu": 1, "Name": "stable-diffusion", "Image": "registry.cn-hangzhou.aliyuncs.com/eci_open/ubuntu:cuda11.7.1-cudnn8-ubuntu20.04" } ], "Volume": [ { "Type": "HostPathVolume", "HostPathVolume.Path": "/model/stable-diffusion/", "Name": "model" } ] }
確認應用部署狀態。
根據返回的實例ID調用DescribeContainerGroupStatus查詢實例和容器狀態。當實例狀態(Status)和容器狀態(ContainerStatuses.State)為Running,表示實例已經創建成功,容器正在運行。
對外開放應用。
在ECI實例所屬VPC已綁定NAT網關的前提下,您需要創建DNAT條目,使得ECI實例可以對外提供公網訪問服務。具體操作,請參見創建和管理DNAT條目。
說明如果VPC沒有綁定NAT網關,則需要您在創建ECI實例時為其綁定一個EIP,此時可以跳過本步驟。
創建DNAT條目采用的配置項示例如下:
公網IP地址:選擇NAT網關綁定的EIP地址。
私網IP地址:選擇部署了Stable Diffusion應用的ECI實例。
端口設置:使用具體端口,公網端口配置為80,私網端口配置為8888,協議為TCP。
測試模型效果
傳入文本,測試是否可以生成圖片。
在ECI實例所屬安全組中添加入方向規則,開放應用對外端口(本文以80端口為例)。
打開瀏覽器,訪問Stable Diffusion應用,并傳入文本描述。
在配置了DNAT的情況下,請輸入DNAT條目中配置的公網IP地址和公網端口,以及文本描述,例如
47.94.XX.XX:80?input=xxx
。其中,input=xxx
表示要傳入的文本描述,Stable Diffusion應用會基于該文本描述生成圖片,并將圖片保存到容器的/workspace/pic
目錄下。示例如下:
查看生成的圖片。
在容器內部啟動一個新的HTTP服務,用于查看圖片。
連接容器后執行以下命令:
python3 -m http.server 7777 --directory /workspace/pic/ &
在ECI實例所屬安全組中添加入方向規則,開放用于查看圖片的端口(本文以70端口為例)。
創建一條新的DNAT條目,以便外部可以訪問新的HTTP服務。
新的DNAT條目采用的端口示例為:公網端口配置為70,私網端口配置為7777,協議為TCP。
查看生成的圖片。
輸入新的DNAT條目中配置的公網IP地址和公網端口,例如
47.94.XX.XX:70
。示例如下:
使用支持WebUI的鏡像
創建數據緩存
訪問HuggingFace,獲取模型ID。
本示例使用hanafuusen2001/BeautyProMix模型。在HuggingFace找到目標模型后,在模型詳情頁面頂部可以復制模型ID。
創建數據緩存。
說明如果您的業務部署在中國內地地域,建議您在中國香港地域創建數據緩存,然后拷貝數據緩存到您需要的地域。
調用CreateDataCache接口創建數據緩存所采用的參數示例如下,表示從HuggingFace拉取指定模型數據,保存到名為test的Bucket的
/model/BeautyProMix/
目錄。數據緩存名為beautypromix,保留時長為1天。{ "RegionId": "cn-beijing", "SecurityGroupId": "sg-2ze63v3jtm8e6syi****", "VSwitchId": "vsw-2ze94pjtfuj9vaymf****", "Bucket": "test", "Path": "/model/BeautyProMix/", "Name": "beautypromix", "DataSource": { "Type": "URL", "Options": { "#10#repoSource": "HuggingFace/Model", "#6#repoId": "hanafuusen2001/BeautyProMix" } }, "RetentionDays": 1 }
查詢數據緩存狀態。
根據返回的數據緩存ID調用DescribeDataCaches接口查詢數據緩存信息,當數據緩存的狀態(DataCaches.Status)為Available時,表示可以使用該數據緩存。
部署Stable Diffusion應用
使用數據緩存創建ECI實例,部署Stable Diffusion應用。
調用CreateContainerGroup接口創建ECI實例所采用的參數示例如下,該ECI實例使用GPU規格,并掛載了BeautyProMix模型數據。實例內的容器使用GPU版鏡像,容器啟動后會運行
python3 launch.py --listen --skip-torch-cuda-test --port 8888 --no-half
,啟動一個WebUI。{ "RegionId": "cn-beijing", "SecurityGroupId": "sg-2ze63v3jtm8e6syi****", "VSwitchId": "vsw-2ze94pjtfuj9vaymf****", "ContainerGroupName": "stable-diffusion", "InstanceType": "ecs.gn6i-c16g1.4xlarge", "DataCacheBucket": "test", "Container": [ { "Arg": [ "python3 launch.py --listen --skip-torch-cuda-test --port 8888 --no-half" ], "VolumeMount": [ { "MountPath": "/stable-diffusion-webui/models/Stable-diffusion/", "Name": "model" } ], "Command": [ "/bin/sh", "-c" ], "Gpu": 1, "Name": "stable-diffusion", "Image": "registry.cn-hangzhou.aliyuncs.com/eci_open/stable-diffusion:1.0.0" } ], "Volume": [ { "Type": "HostPathVolume", "HostPathVolume.Path": "/model/BeautyProMix/", "Name": "model" } ] }
確認應用部署狀態。
根據返回的實例ID調用DescribeContainerGroupStatus查詢實例和容器狀態。當實例狀態(Status)和容器狀態(ContainerStatuses.State)為Running,表示實例已經創建成功,容器正在運行。
對外開放應用。
在ECI實例所屬VPC已綁定NAT網關的前提下,您需要創建DNAT條目,使得ECI實例可以對外提供公網訪問服務。具體操作,請參見創建和管理DNAT條目。
說明如果VPC沒有綁定NAT網關,則需要您在創建ECI實例時為其綁定一個EIP,此時可以跳過本步驟。
創建DNAT條目采用的配置項示例如下:
公網IP地址:選擇NAT網關綁定的EIP地址。
私網IP地址:選擇部署了Stable Diffusion應用的ECI實例。
端口設置:使用具體端口,公網端口配置為80,私網端口配置為8888,協議為TCP。
測試模型效果
在ECI實例所屬安全組中添加入方向規則,開放應用對外端口。
打開瀏覽器,訪問Stable Diffusion應用。
在配置了DNAT的情況下,請輸入DNAT條目中配置的公網IP地址和公網端口,例如
47.94.XX.XX:80
。說明如果ECI實例單獨綁定了EIP,請輸入EIP地址和容器開放的端口,例如
47.94.XX.XX:8888
。輸入文本描述,測試圖片生成。
示例如下: