技术背景
Stable Diffusion 是一种深度学习的文本到图像模型,由 Runway 和慕尼黑大学合作构建,第一个版本于2021年发布。目前主流版本包含 v1.5、v2和v2.1。它主要用于生成基于文本描述的详细图像,也应用于其他任务,如修复图像、生成受文本提示引导的图像到图像的转换等。Stable Diffusion 示例图如下:
应用场景
AI 绘图在互联网行业领域会起到革命性的作用,目前多数是加快现有工作的效率和质量。以下是几个典型的应用场景:
插画:无论是游戏 CG 还是概念插画,使用 AI 绘图都能起到很好的效果。一般来说,在商用环境下不会直接使用结果上线,而是在这个基础上使用 PS 等软件进行修改,或以此作为灵感重绘。
游戏 UI:过去游戏界面的绘制,一般需要对单个物品(如宝箱、装备、武器)进行多个版本的绘制。使用 AI 绘图大量生产图片或图标,然后进行修改或者临摹,在缩短出图时间的同时,减少出图成本。
平面包装:平面包装是一个依赖抽象图形的领域方向,整体上对图片精确率要求不高,只需要模糊的方向和概念,并且接受随机生成的样式结果。这一特性刚好符合 AI 绘图的特性,通过外部轮廓设定后,使用 AI 对内容图案进行绘制。
服装设计及模特拍摄:在服装设计领域,很多时候都依赖一些抽象的灵感和思路,采用 AI 出图后,服装设计师可以根据图片进行灵感设计,根据服装材料、流行程度和季节,针对图片进行重新调整。另外,拍摄模特图片非常耗费时间和成本,采用 AI 方式进行试穿,也是 AI 绘图的发展方向。
建筑效果图:利用 ControlNet 的能力,建筑领域也开始尝试使用 AI 绘图进行效果图生成,为建筑设计师提供灵感,未来结合 3D 模型生成,所写即所得,提高建筑设计师和客户的沟通效率。
行业客户普遍基于上述场景做 AI 绘图业务尝试:Stable Diffusion 预训练模型,加上各种微调插件,如 LoRA 进行风格定制,ControlNet 控制图像,能有效输出符合业务场景定义的图片素材。
部署Stable Diffusion 架构图
搭建步骤
1. 准备需使用 Stable Diffusion 容器镜像
1. 从 GitHub 下载 Stable Diffusion web UI 代码,制作 Docker 镜像。也可使用以下命令获取:
docker pull gpulab.tencentcloudcr.com/ai/stable-diffusion:1.0.7
2. 将准备好的 Stable Diffusion 容器镜像上传到容器镜像仓库 TCR,具体操作可参见 TCR 企业版指南。
3. 如果您需要对仓库权限进行细粒度控制,例如在镜像内打包模型文件的使用场景,推荐使用 CAM 对命名空间或仓库进行访问控制,具体操作可参见 容器镜像服务权限管理。另外,由于模型文件加上推理服务,镜像体积可能达到几十GB,而企业版容器仓库支持按需加载,提升应用分发效率,具体操作可参见 按需加载容器镜像。
2. 准备待部署 Stable Diffusion 的 TKE 集群
1. 开通并创建 TKE 集群,操作步骤详情可参见 创建容器服务集群。在创建集群时,Kubernetes 版本选择最新的1.26.1,容器网络插件选择 Global Router,其他选项默认即可。
2. 集群选择托管类型,Worker 节点选择 GPU 计算型PNV4 - A10,安装 GPU470驱动,CUDA 版本11.4.3,cuDNN 版本 8.2.4。如下图所示:
3. 根据部署对 GPU 共享的需求,您可以选择开启 qGPU,详情见 Stable Diffusion 使用 qGPU。
3. 通过 TKE+CFS 快速部署 Stable Diffusion Web UI
1. 创建存放模型的文件存储 CFS
1. 开通 CFS 服务,创建文件系统及挂载点时选择与集群相同的 VPC 和子网。在 CFS 远程挂载点,新建 /models/Stable-diffusion 目录。挂载点和文件操作,详情可参见 创建文件系统及挂载点。
2. 下载 v1-5-pruned-emaonly.safetensors 模型文件至 /models/Stable-diffusion,地址见:runwayml/stable-diffusion-v1-5。
3. 如需更大的带宽和读写 IOPS,建议选择 CFS Turbo,容器环境使用可参见 在 TKE 上使用 CFS Turbo。
2. 创建静态 PV/PVC
1. 在 容器服务控制台 中创建 CFS 类型 StorageClass,并选择共享实例。操作步骤可参见 通过控制台创建 StorageClass。
2. 使用 CFS 中新建的 /models/Stable-diffusion 目录以及已创建的 StorageClass,静态创建 PV/PVC。
创建 PV 如下图所示:
创建 PVC
如下图所示:
3. 如果您有其他模型目录挂载的需求,同样需要在 CFS 挂载点中新建子目录,并进行 PV/PVC 的静态创建。Stable Diffusion Web UI 服务的 models 子目录结构如下:
3. 创建 Stable Diffusion Web UI 工作负载
1. 在 容器服务控制台 中,选择左侧导航中的集群。
2. 在集群详情页,选择工作负载 > Deployment,单击新建,开始部署 stable-diffusion-webui 镜像。
3. 在新建 Deployment 页,填写 Deployment 基本信息,其中数据卷选择添加数据卷。
4. 在新增数据卷页,数据卷类型选择使用已有 PVC,添加 已创建的 PVC,完成后单击确认。
5. 在实例内容器中,单击选择镜像,选择已保存在 TCR 中的 stable-diffusion-webui 镜像。
6. 将新建的数据卷进行挂载点配置。挂载点与 CFS 远程目录对应关系如表格所示:
PVC | 容器挂载点 | 对应的CFS目录 |
sd-model-pvc | /dockerx/stable-diffusion-webui/models/Stable-diffusion | /models/Stable-diffusion |
7. 展开显示高级设置,添加运行参数
--listen
,将 stable-diffusion-webui 进程监听在0.0.0.0上。更多参数选项参见 Command Line Arguments and Settings。
8. 将 GPU 资源的卡数设置为1,如果开启了 qGPU,您还可以填写0.1-1之间的数值,对 GPU 卡进行虚拟化切分。
9. 创建 Deployment 对应的 Service,并选择公网 LB 访问,对外暴露7860端口访问。
10. 通过 CLB 公网 IP 地址,您就可以成功访问 Stable Diffusion Web UI 服务了。如果您有限流或访问控制的需求,我们推荐您选择云原生网关充当 Ingress Controller。在本文的 通过云原生 API 网关对外提供 Stable Diffusion 服务 部分中,我们会介绍云原生网关的使用。
(进阶)Stable Diffusion 使用 qGPU
Stable Diffusion Web UI 服务以串行方式处理请求,如果您希望增加推理服务的并发性能,可以考虑扩展 Deployment 的 Pod 数量,以轮询的方式响应请求。在这里,我们采用 TKE qGPU 能力,将多个实例 Pod 运行在同一张 A10 卡上。在保障业务稳定性的前提下,切分显卡资源,降低部署成本。
采用 qGPU 方式,您需要先将 Pod 的资源申请方式进行修改。例如,如果您计划在单卡上部署2个 Pod,您需要在 YAML 文件中将 tke.cloud.tencent.com/qgpu-core 从100更改为50,也就是将50%的算力分配给每个 Pod。同时,您还需要将 tke.cloud.tencent.com/qgpu-memory 的数值设置为 A10 显存的一半。
resources:limits:cpu: "20"memory: 50Gitke.cloud.tencent.com/qgpu-core: "50"tke.cloud.tencent.com/qgpu-memory: "10"
Deployment YAML 文件更新完成后,调整 Pod 数量为2个,即可实现负载均衡的 Stable Diffusion 轮询模式。
注意:
在 tke.cloud.tencent.com/qgpu-core 为100的整倍数时,您可以不写 qgpu-memory,系统会默认分配整卡显存。但是,当 tke.cloud.tencent.com/qgpu-core 小于100时,也就是按比例切分 GPU 资源时,您必须显式指定 tke.cloud.tencent.com/qgpu-memory。如需了解更多关于 qGPU 的详情,请参见 容器服务使用 qGPU。
(进阶)通过云原生 API 网关对外提供 Stable Diffusion 服务
1. 开通云原生网关,选择和 TKE 集群、CFS 同 VPC 的实例。更多关于如何新建网关的信息,可参见 微服务引擎 TSE 新建网关。
2. 在 腾讯云微服务引擎控制台 上,选择实例名称,进入实例详情页。
3. 选择路由管理 > 服务来源,单击新建,在新建服务来源中选择容器服务,绑定 TKE 集群。
4. 选择路由管理 > 服务,单击新建,新建网关服务。选择服务列表时,选择部署 Deployment 时启用的 Service 进行映射。云原生网关会自动拉取 TKE Service 关联的 Pod IP。当 Pod IP 变化时,动态更新网关服务里的 Upstream 配置项。如需了解更多关于如何创建 TKE 服务的路由的信息,可参见 微服务引擎 TSE 创建 TKE 服务的路由。
5. 单击服务名,新建访问路由。在基本信息配置中,将请求方法设置为 ANY,Host 填写云原生网关的公网 IP。如果后期绑定域名使用,Host 还需要加上域名地址。如下图所示:
6. 根据资源用量和计划访问请求数,您可以选择配置网关限流策略,并自定义限流响应内容,更多关于如何配置限流策略的信息,可参见 微服务引擎 TSE 配置限流策略。
7. Stable Diffusion Web UI 出图时会进行多轮请求,将 Deployment 的 Pod 副本数量修改为大于1时,您还需要配置 Session 会话保持,以保证同一 IP 的客户请求落在相同的 Pod 里。选择路由管理 > Konga 控制台,找到 Konga 公网访问地址,在 Konga 控制台里找到 UPSTREAM,单击 DETAILS,如下图所示:
在 HASH ON 下拉框里,选择 IP,完成基于客户端 IP 的会话保持配置。
(进阶)优化 Stable Diffusion 推理性能
Stable Diffusion 是一个多模型组成的扩散 Pipeline,主要由三个部分组成:变分自编码器 VAE、U-Net 和文本编码器 CLIP。推理耗时主要集中在 UNet 部分,我们选择对这部分进行模型优化,以加速推理速度。
1. 下载 A10 GPU 优化的 stable-diffusion-v1.5 UNet 模型文件,以及 sd_v1.5_demo 镜像,该镜像里的 Web UI 修改了模型加载代码,UNet 部分会加载独立优化模型。镜像及 UNet 优化模型获取,可参见 TACO Infer 部署 Stable Diffusion web UI。
2. 将 sd_v1.5_demo 镜像服务部署在 TKE 上:按前述步骤进行操作,其中替换镜像为 sd_v1.5_demo,并额外为 UNet 优化模型创建 CFS /data 目录和 PV/PVC。
3. 在相同的参数配置下,生成10张猫的图片。在优化前,推理耗时为16.14s。在加载 TACO 优化的 UNet 模型后,10张图片仅耗时11.56s,端到端性能提高30%。
4. TACO 可以对 Stable Diffusion 系列模型进行优化。如果您希望对其他 Stable Diffusion 微调模型进行推理优化,并部署在上述环境中,可以按照以下步骤操作:
4.1 参见 TACO Infer 优化 Stable Diffusion 模型,拉取预置库环境的 sd_taco:v3 镜像。
4.2 Stable Diffusion 模型主要有两种存储方式:单文件和 diffusers 目录结构。其中 diffusers 结构按照 Stable Diffusion 的模型结构组织,包含unet、vae、text-encoder 等。在 TACO 优化过程中,会使用 diffusers 结构读取模型。您可以在 HuggingFace 上找到这种格式的模型文件进行下载。
4.3 如果 HuggingFace 速度较慢,也可以使用官方的转换脚本,将单文件格式(ckpt 或 safetensors)转化成 diffusers 格式使用。脚本见diffusers/scripts at main · huggingface/diffusers · GitHub。
python convert_original_stable_diffusion_to_diffusers.py --checkpoint_path [single_file_model_name] --dump_path [diffusers_model_directory] --from_safetensors
4.4 选择一台 A10 GPU CVM,使用 -v 命令挂载上面的 diffusers 模型目录,交互式启动容器,在容器内部对挂载好的模型进行优化。
docker run -it --gpus=all --network=host -v /[diffusers_model_directory]:/[custom_container_directory] sd_taco:v3 bash
4.5 使用 diffusers 加载模型权重,从中导出 UNet 模型进行优化。运行脚本请参见 TACO Infer 优化 Stable Diffusion 模型。
4.6 完成后将优化后的模型放入 CFS 挂载的 /data 目录。UNet 从优化文件中加载,而单文件格式模型(ckpt 或 safetensors)仍然放入 CFS 挂载的 /models/Stable-diffusion 目录,Stable Diffusion 其他部分从原始文件里加载。
4.7 重启 stable-diffusion-webui 界面,选择新模型使用。
结论
本文介绍了 Stable Diffusion 模型在互联网行业的应用场景,并展示了如何利用腾讯云云原生产品能力,进行高可用部署的工程化实践。
在生产环境中,推理服务需要考虑并发请求下服务的可用性和扩展性,同时也需要考虑多模型文件管理的便利性,以及配合当前业务架构的灵活性;Stable Diffusion 的前向推理过程是一个比较耗时的过程,GPU 应用部署对比 CPU 应用部署成本也较高,在控制成本的前提下,如何有效地提高推理速度,也是企业需要重点考虑的因素;另外,作为在线业务,推理服务需要合理设计限流熔断,避免流量激增造成整体业务不可用。
利用腾讯云云原生能力,能够轻松满足上述需求。在此基础上,可以考虑将前端 Web 应用和后端推理服务进行解耦,提高架构吞吐能力;当业务访问具有明显潮汐现象时,还可以通过 TKE GPU HPA 的弹性能力,进一步降低资源部署成本。
相关文档
容器服务 TKE
容器镜像服务
文件存储 CFS