stable diffusion webui docker 离线部署

AI 绘图工具 Stable Diffusion

Stable Diffusion 是一种基于扩散技术的深度学习文本到图像模型,于 2022 年发布,该项目由 Stability AI 、 CompVis 、 Runway 合作开发,它主要用于文生图,但也可以应用于其他任务,如 Inpainting(补画 、Outpainting(扩画)、图生图等。 Inpainting 称为图像修复,用于修复或恢复图像中的损坏或缺失部分。 Outpainting 称为图像扩展,通过智能地在图像的边缘添加新的像素来扩展图像的边界。

Stability 提供了名为 DreamStudio 的在线图像生成服务,开源版本名为 StableStudio 。除了 Stability 的接口之外,还存在许多第三方开源接口,其中最流行的是 AUTOMATIC1111 Stable Diffusion Web UI 和 ComfyUI 。

Stable Diffusion 是核心的图像生成模型,负责根据输入的文本描述生成图像。
Stable Diffusion WebUI 是 Stable Diffusion 的一个前端界面,为用户提供了一个易于使用的 Web 界面,简化了与模型交互的过程。
Stable Diffusion WebUI Docker 是用于部署 Stable Diffusion WebUI 的容器化解决方案,简化了安装和配置过程,使用户能够快速在不同平台上运行 Stable Diffusion WebUI。

相关的 GitHub 仓库有两个:
https://github.com/AUTOMATIC1111/stable-diffusion-webui
https://github.com/AbdBarho/stable-diffusion-webui-docker

离线部署流程分析

在 stable-diffusion-webui-docker 仓库,参考 wiki ,确保您安装了最新版本的 docker 和 docker compose ,分析两条部署的命令,

docker compose --profile download up --build
# wait until its done, then:
docker compose --profile [ui] up --build
# where [ui] is one of: auto | auto-cpu | comfy | comfy-cpu

第一步,先看 docker compose --profile download up --build ,分析启动流程,

读取 docker-compose.yml 文件内容,

x-base_service: &base_service
    ports:
      - "${WEBUI_PORT:-7860}:7860"
    volumes:
      - &v1 ./data:/data
      - &v2 ./output:/output
    stop_signal: SIGKILL
    tty: true
    deploy:
      resources:
        reservations:
          devices:
              - driver: nvidia
                device_ids: ['0']
                capabilities: [compute, utility]

name: webui-docker

services:
  download:
    build: ./services/download/
    profiles: ["download"]
    volumes:
      - *v1

  auto: &automatic
    <<: *base_service
    profiles: ["auto"]
    build: ./services/AUTOMATIC1111
    image: sd-auto:78
    environment:
      - CLI_ARGS=--allow-code --medvram --xformers --enable-insecure-extension-access --api
    privileged: true

  auto-cpu:
    <<: *automatic
    profiles: ["auto-cpu"]
    deploy: {}
    environment:
      - CLI_ARGS=--no-half --precision full --allow-code --enable-insecure-extension-access --api

  comfy: &comfy
    <<: *base_service
    profiles: ["comfy"]
    build: ./services/comfy/
    image: sd-comfy:7
    environment:
      - CLI_ARGS=

  comfy-cpu:
    <<: *comfy
    profiles: ["comfy-cpu"]
    deploy: {}
    environment:
      - CLI_ARGS=--cpu
  • 解析配置文件:Docker Compose 读取并解析 docker-compose.yml 文件,识别出所有定义的服务和配置。
  • 选择配置文件:根据 --profile download ,只选择 profiles: ["download"] 的服务。
  • 构建镜像:因为使用了 --build 标志,Compose 会先构建 download 服务所需要的 Docker 镜像。构建过程根据 ./services/download/ 目录下的 Dockerfile 进行。
  • 启动服务:一旦镜像构建完成,Compose 会创建并启动 download 服务的容器,同时挂载定义的卷 ./data:/data*v1 表示引用了先前定义的卷挂载 v1 。在 YAML 中,&v1 定义了一个锚点,而 *v1 则是这个锚点的引用。
    网络配置:Compose 配置好网络,使得各个服务之间能够相互通信。
    端口映射:根据定义的 ports 配置,执行端口映射。对于 download 服务,没有单独定义端口映射,也没有显式地定义继承(使用 <<: *base_service ),它不会继承 base_service 的配置。
    资源限制和权限:如果配置中定义了资源限制和权限(如 GPU 设备的访问权限), Compose 会应用这些配置到容器中。

第二步,构建 download 服务所需要的 Docker 镜像。构建过程根据 ./services/download/ 目录下的 Dockerfile 进行,分析 Dockerfile 文件内容,

FROM bash:alpine3.19

RUN apk update && apk add parallel aria2
COPY . /docker
RUN chmod +x /docker/download.sh
ENTRYPOINT ["/docker/download.sh"]

Dockerfile 中用到 download.sh ,内容如下:

#!/usr/bin/env bash

set -Eeuo pipefail

# TODO: maybe just use the .gitignore file to create all of these
mkdir -vp /data/.cache \
  /data/embeddings \
  /data/config/ \
  /data/models/ \
  /data/models/Stable-diffusion \
  /data/models/GFPGAN \
  /data/models/RealESRGAN \
  /data/models/LDSR \
  /data/models/VAE

echo "Downloading, this might take a while..."

aria2c -x 10 --disable-ipv6 --input-file /docker/links.txt --dir /data/models --continue

echo "Checking SHAs..."

parallel --will-cite -a /docker/checksums.sha256 "echo -n {} | sha256sum -c"

cat <<EOF
By using this software, you agree to the following licenses:
https://github.com/AbdBarho/stable-diffusion-webui-docker/blob/master/LICENSE
https://github.com/CompVis/stable-diffusion/blob/main/LICENSE
https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/master/LICENSE.txt
https://github.com/invoke-ai/InvokeAI/blob/main/LICENSE
And licenses of all UIs, third party libraries, and extensions.
EOF

download.sh 用到 links.txtchecksums.sha256

links.txt 的内容如下,

https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt
  out=Stable-diffusion/v1-5-pruned-emaonly.ckpt
https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.ckpt
  out=VAE/vae-ft-mse-840000-ema-pruned.ckpt
https://huggingface.co/runwayml/stable-diffusion-inpainting/resolve/main/sd-v1-5-inpainting.ckpt
  out=Stable-diffusion/sd-v1-5-inpainting.ckpt
https://github.com/TencentARC/GFPGAN/releases/download/v1.3.4/GFPGANv1.4.pth
  out=GFPGAN/GFPGANv1.4.pth
https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth
  out=RealESRGAN/RealESRGAN_x4plus.pth
https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth
  out=RealESRGAN/RealESRGAN_x4plus_anime_6B.pth
https://heibox.uni-heidelberg.de/f/31a76b13ea27482981b4/?dl=1
  out=LDSR/project.yaml
https://heibox.uni-heidelberg.de/f/578df07c8fc04ffbadf3/?dl=1
  out=LDSR/model.ckpt

checksums.sha256 的内容如下,

cc6cb27103417325ff94f52b7a5d2dde45a7515b25c255d8e396c90014281516  /data/models/Stable-diffusion/v1-5-pruned-emaonly.ckpt
c6bbc15e3224e6973459ba78de4998b80b50112b0ae5b5c67113d56b4e366b19  /data/models/Stable-diffusion/sd-v1-5-inpainting.ckpt
c6a580b13a5bc05a5e16e4dbb80608ff2ec251a162311590c1f34c013d7f3dab  /data/models/VAE/vae-ft-mse-840000-ema-pruned.ckpt
e2cd4703ab14f4d01fd1383a8a8b266f9a5833dacee8e6a79d3bf21a1b6be5ad  /data/models/GFPGAN/GFPGANv1.4.pth
4fa0d38905f75ac06eb49a7951b426670021be3018265fd191d2125df9d682f1  /data/models/RealESRGAN/RealESRGAN_x4plus.pth
f872d837d3c90ed2e05227bed711af5671a6fd1c9f7d7e91c911a61f155e99da  /data/models/RealESRGAN/RealESRGAN_x4plus_anime_6B.pth
c209caecac2f97b4bb8f4d726b70ac2ac9b35904b7fc99801e1f5e61f9210c13  /data/models/LDSR/model.ckpt
9d6ad53c5dafeb07200fb712db14b813b527edd262bc80ea136777bdb41be2ba  /data/models/LDSR/project.yaml

分析整体流程,

一,构建镜像:

  • bash:alpine3.19 基础镜像开始。
  • 安装必要的工具( parallelaria2 )。
  • 复制当前目录的内容到镜像内的 /docker 目录。
  • 设置 download.sh 脚本的可执行权限。
  • 定义容器启动时执行 download.sh 脚本。

二,启动容器:

  • 容器启动后, download.sh 脚本将执行:
  • 创建需要的目录结构。
  • 使用 aria2c 并行下载 links.txt 中定义的模型文件。
  • 使用 parallel 校验下载的文件。
  • 输出许可信息。

问题一: COPY . /docker 这里复制的当前目录是指哪个目录?
COPY . /docker 将当前构建上下文(context)中的所有内容复制到镜像内的 /docker 目录。构建上下文是指运行 docker build 命令时指定的目录。通常,这个目录是 Dockerfile 所在的目录,但也可以在 docker build 命令中显式指定。如果你的 docker-compose.yml 文件中有如下定义:

download:
  build: ./services/download/
  profiles: ["download"]
  volumes:
    - *v1

那么,./services/download/ 目录就是构建上下文。在构建镜像时,这个目录中的所有内容都会被复制到 Docker 镜像的 /docker 目录中。

问题二: download.sh 脚本定义的具体操作是在容器中还是在物理机上创建目录?
download.sh 脚本中的操作是在容器中执行的。因此,脚本中创建的目录(例如 /data/.cache 等)都是在容器内部创建的,而不是在物理机上。

问题三:下载模型文件时, aria2c -x 10 --disable-ipv6 --input-file /docker/links.txt --dir /data/models --continue ,输入的路径和输出的路径是容器内的路径还是物理机的路径?
输入的路径: /docker/links.txt 是指容器内的路径。在构建镜像时, links.txt 文件已经被复制到容器内的 /docker 目录。
输出的路径:--dir /data/models 是指容器内的路径。下载的文件将会存储在容器内的 /data/models 目录中。
然而,由于在 docker-compose.yml 中定义了卷挂载:

volumes:
  - ./data:/data

所以容器内的 /data 目录实际上是映射到物理机的 ./data 目录。这意味着模型文件将被下载到物理机的 ./data/models 目录中。

这里的 ./data 是指 docker-compose.yml 文件所在目录的 data 目录,而不是构建上下文的那个指定目录的 data

假设文件结构如下,

project/
├── docker-compose.yml
├── data/
│   ├── ...(下载的模型文件将存放在这里)
└── services/
    └── download/
        ├── Dockerfile
        ├── download.sh
        ├── links.txt
        └── checksums.sha256

在这个结构中:

  • docker-compose.yml 文件位于 project 目录中。
  • data 目录也位于 project 目录中。
  • services/download 目录是构建上下文目录,包含 Dockerfiledownload.shlinks.txt 等文件。

在运行 docker compose --profile download up --build 命令时:

  • Docker Compose 会读取 docker-compose.yml 文件。
  • 挂载卷 ./data:/data 会将 project 目录中的 data 目录映射到容器内的 /data 目录。
  • download.sh 脚本在容器内运行时,所有下载的文件将存储在容器内的 /data/models 目录中,但由于卷挂载,这些文件实际存储在 project/data/models 目录中。

所以,最终下载的模型文件会在 project/data/models 目录中找到。

问题五:在 links.txt 中,下载链接和输出文件是分两行的, aric2c 怎么知道它们分别是下载链接和输出文件路径,并把输出文件路径和 /data/models 合并为完整的保存路径?
aria2c 支持一种特殊的输入文件格式,其中每个下载链接可以有多行参数。具体来说,每个下载链接都可以附带一些附加的选项,如输出文件路径、文件名等。这些选项可以通过缩进(通常是两个空格或一个制表符)来表示。
我们看一下 links.txt 文件中的一个示例:

https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt
  out=Stable-diffusion/v1-5-pruned-emaonly.ckpt

在这个例子中:
第一行:包含下载链接 https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt
第二行:包含下载选项 out=Stable-diffusion/v1-5-pruned-emaonly.ckpt ,这行前面有两个空格。
aria2c 通过行首的空格或制表符来识别这些选项行,并将它们与前面的下载链接关联起来。

下载和保存过程如下,

  • 读取下载链接: aria2c 识别第一行作为下载链接。
  • 读取附加选项:发现下一行以空格开头,识别为下载链接的附加选项。
  • 解析输出文件路径: out=Stable-diffusion/v1-5-pruned-emaonly.ckpt ,指定了输出文件的相对路径。
  • 构建完整的保存路径: aria2c 将指定的相对路径与命令行参数中的目录( --dir /data/models )合并,构建完整的保存路径 /data/models/Stable-diffusion/v1-5-pruned-emaonly.ckpt

问题六: parallel --will-cite -a /docker/checksums.sha256 "echo -n {} | sha256sum -c" ,分析命令的执行流程。

  • parallel :一个用于并行执行任务的工具。
  • --will-cite :表示用户同意在使用 parallel 时引用该工具。
  • -a /docker/checksums.sha256 :表示从指定的文件 /docker/checksums.sha256 中读取输入行。
  • "echo -n {} | sha256sum -c" :这是 parallel 要执行的命令。 {} 是一个占位符,表示每行输入。

执行流程如下,

  • 读取输入文件: parallel/docker/checksums.sha256 文件中逐行读取输入,每行都包含一个 SHA256 校验和和文件路径。
  • 并行执行校验:对于文件中的每一行,parallel 会执行如下命令:
echo -n "d4c3b4c3c3e5e2e5f0f9f4f5f7f8f5f4f5e4e5e6d6f7f6f5f5e6f7e8  /data/models/Stable-diffusion/v1-5-pruned-emaonly.ckpt" | sha256sum -c

具体步骤如下: echo -n {}{} 是占位符,表示当前处理的那一行。例如,第一行是:d4c3b4c3c3e5e2e5f0f9f4f5f7f8f5f4f5e4e5e6d6f7f6f5f5e6f7e8 /data/models/Stable-diffusion/v1-5-pruned-emaonly.ckptecho -n 命令会输出这一行的内容,但不添加换行符。 | sha256sum -c:管道符号 | 将前面的输出传递给 sha256sum -c 命令。 sha256sum -c 读取输入并验证文件的 SHA256 校验和是否正确。

  • 校验和检查: sha256sum -c 会对每个文件路径计算实际的 SHA256 校验和,并与提供的校验和进行比较。如果校验和匹配,输出类似如下:
/data/models/Stable-diffusion/v1-5-pruned-emaonly.ckpt: OK

如果校验和不匹配,输出类似如下:

/data/models/Stable-diffusion/v1-5-pruned-emaonly.ckpt: FAILED

如果文件不存在,则输出类似如下的结果:

/data/models/Stable-diffusion/v1-5-pruned-emaonly.ckpt: No such file or directory

因此,通过分解 docker compose --profile download up --build 命令的执行流程,Docker Compose 解析 docker-compose.yml 文件,读取所有定义的服务和配置,选择 profiles 字段中包含 downloaddownload 服务,构建并启动相应的 Docker 容器。容器启动后,挂载卷 ./data:/data ,将 stable diffusion webui 所需的模型文件下载到容器中的 /data ,即主机中的 project/data 。在离线部署时,可以在一台联网的机器上执行此命令,将模型文件下载到 project/data 路径,然后将这些文件转移到无法联网的机器上。

关于部署的第二条命令, docker compose --profile [ui] up --build ,我们下篇文章继续分析。


微信公众号「padluo」,分享数据科学家的自我修养,既然遇见,不如一起成长。关注【老罗说AI】公众号,后台回复【文章】,获得整理好的【老罗说AI】文章全集。

数据分析二维码.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值