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.txt
和 checksums.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
基础镜像开始。 - 安装必要的工具(
parallel
和aria2
)。 - 复制当前目录的内容到镜像内的
/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
目录是构建上下文目录,包含Dockerfile
、download.sh
、links.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.ckpt
, echo -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
字段中包含 download
的 download
服务,构建并启动相应的 Docker 容器。容器启动后,挂载卷 ./data:/data
,将 stable diffusion webui 所需的模型文件下载到容器中的 /data
,即主机中的 project/data
。在离线部署时,可以在一台联网的机器上执行此命令,将模型文件下载到 project/data
路径,然后将这些文件转移到无法联网的机器上。
关于部署的第二条命令, docker compose --profile [ui] up --build
,我们下篇文章继续分析。
微信公众号「padluo」,分享数据科学家的自我修养,既然遇见,不如一起成长。关注【老罗说AI】公众号,后台回复【文章】,获得整理好的【老罗说AI】文章全集。
标签:diffusion,v1,--,离线,models,webui,download,docker,data From: https://blog.csdn.net/padluo/article/details/141098384