diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 241f11b..6fd8686 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,3 +11,4 @@ Closes issue # - auto: https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ - sygil: https://github.com/Sygil-Dev/sygil-webui/commit/ - invoke: https://github.com/invoke-ai/InvokeAI/commit/ +- comfy: https://github.com/comfyanonymous/ComfyUI/commit/ diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 2c7645e..8bb5799 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -14,8 +14,8 @@ jobs: matrix: profile: - auto - - sygil - invoke + - comfy - download runs-on: ubuntu-latest name: ${{ matrix.profile }} diff --git a/.gitignore b/.gitignore index f64b472..2a011a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ /.devcontainer /docker-compose.override.yml + +# VSCode specific +*.code-workspace +/.vscode diff --git a/README.md b/README.md index eacb01d..95e10c3 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This repository provides multiple UIs for you to play around with stable diffusi | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | ![](https://user-images.githubusercontent.com/24505302/189541954-46afd772-d0c8-4005-874c-e2eca40c02f2.jpg) | ![](https://user-images.githubusercontent.com/24505302/189541956-5b528de7-1b5d-479f-a1db-d3f5a53afc59.jpg) | ![](https://user-images.githubusercontent.com/24505302/189541957-cf78b352-a071-486d-8889-f26952779a61.jpg) | -### [InvokeAI (lstein)](https://github.com/invoke-ai/InvokeAI) +### [InvokeAI](https://github.com/invoke-ai/InvokeAI) [Full feature list here](https://github.com/invoke-ai/InvokeAI#features), Screenshots: @@ -26,13 +26,13 @@ This repository provides multiple UIs for you to play around with stable diffusi | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | ![](https://user-images.githubusercontent.com/24505302/195158552-39f58cb6-cfcc-4141-9995-a626e3760752.jpg) | ![](https://user-images.githubusercontent.com/24505302/195158553-152a0ab8-c0fd-4087-b121-4823bcd8d6b5.jpg) | ![](https://user-images.githubusercontent.com/24505302/195158548-e118206e-c519-4915-85d6-4c248eb10fc0.jpg) | -### [Sygil (sd-webui / hlky)](https://github.com/Sygil-Dev/sygil-webui) +### [ComfyUI](https://github.com/comfyanonymous/ComfyUI) -[Full feature list here](https://github.com/Sygil-Dev/sygil-webui/blob/master/README.md), Screenshots: +[Full feature list here](https://github.com/comfyanonymous/ComfyUI#features), Screenshot: -| Text to image | Image to image | Image Lab | -| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| ![](https://user-images.githubusercontent.com/24505302/189541298-f902b021-a1eb-4e4b-b2eb-b6a696a8ec80.jpg) | ![](https://user-images.githubusercontent.com/24505302/189541295-7d7f2162-2189-4e0a-abbd-703f4779e1cd.jpg) | ![](https://user-images.githubusercontent.com/24505302/189541294-aa7f7735-a973-4e17-ada0-1fe3acbb1772.jpg) | +| Workflow | +| -------------------------------------------------------------------------------- | +| ![](https://github.com/comfyanonymous/ComfyUI/raw/master/comfyui_screenshot.png) | ## Contributing @@ -50,6 +50,7 @@ Special thanks to everyone behind these awesome projects, without them, none of - [AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) - [InvokeAI](https://github.com/invoke-ai/InvokeAI) -- [Sygil-webui](https://github.com/Sygil-Dev/sygil-webui) +- [ComfyUI](https://github.com/comfyanonymous/ComfyUI) - [CompVis/stable-diffusion](https://github.com/CompVis/stable-diffusion) +- [Sygil-webui](https://github.com/Sygil-Dev/sygil-webui) - and many many more. diff --git a/data/.gitignore b/data/.gitignore index 5194313..90e640d 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -22,3 +22,7 @@ /Lora /ControlNet /openpose +/ModelScope +/LyCORIS +/GLIGEN +/CLIPEncoder diff --git a/docker-compose.yml b/docker-compose.yml index fed32a4..c5f7dab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ x-base_service: &base_service devices: - driver: nvidia device_ids: ['0'] - capabilities: [gpu] + capabilities: [compute, utility] name: webui-docker @@ -28,7 +28,7 @@ services: <<: *base_service profiles: ["auto"] build: ./services/AUTOMATIC1111 - image: sd-auto:51 + image: sd-auto:58 environment: - CLI_ARGS=--allow-code --medvram --xformers --enable-insecure-extension-access --api @@ -39,27 +39,35 @@ services: environment: - CLI_ARGS=--allow-code --medvram --xformers --enable-insecure-extension-access --api - invoke: + invoke: &invoke <<: *base_service profiles: ["invoke"] build: ./services/invoke/ - image: sd-invoke:26 + image: sd-invoke:29 environment: - PRELOAD=true + - CLI_ARGS=--xformers + + # invoke-cpu: + # <<: *invoke + # profiles: ["invoke-cpu"] + # environment: + # - PRELOAD=true + # - CLI_ARGS=--always_use_cpu + + comfy: &comfy + <<: *base_service + profiles: ["comfy"] + build: ./services/comfy/ + image: sd-comfy:2 + tty: true + environment: - CLI_ARGS= - sygil: &sygil - <<: *base_service - profiles: ["sygil"] - build: ./services/sygil/ - image: sd-sygil:16 + comfy-cpu: + <<: *comfy + profiles: ["comfy-cpu"] + deploy: {} environment: - - CLI_ARGS=--optimized-turbo - - USE_STREAMLIT=0 - - sygil-sl: - <<: *sygil - profiles: ["sygil-sl"] - environment: - - USE_STREAMLIT=1 + - CLI_ARGS=--cpu diff --git a/services/AUTOMATIC1111/Dockerfile b/services/AUTOMATIC1111/Dockerfile index b2d44d8..6ef8fda 100644 --- a/services/AUTOMATIC1111/Dockerfile +++ b/services/AUTOMATIC1111/Dockerfile @@ -1,14 +1,6 @@ -# syntax=docker/dockerfile:1 - FROM alpine/git:2.36.2 as download -SHELL ["/bin/sh", "-ceuxo", "pipefail"] - -RUN < /clone.sh -mkdir -p repositories/"$1" && cd repositories/"$1" && git init && git remote add origin "$2" && git fetch origin "$3" --depth=1 && git reset --hard "$3" && rm -rf .git -EOE -EOF +COPY clone.sh /clone.sh RUN . /clone.sh taming-transformers https://github.com/CompVis/taming-transformers.git 24268930bf1dce879235a7fddd0b2355b84d7ea6 \ && rm -rf data assets **/*.ipynb @@ -26,34 +18,42 @@ RUN . /clone.sh clip-interrogator https://github.com/pharmapsychotic/clip-interr FROM alpine:3.17 as xformers RUN apk add --no-cache aria2 -RUN aria2c -x 5 --dir / --out wheel.whl 'https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/5.0.0/xformers-0.0.17.dev449-cp310-cp310-manylinux2014_x86_64.whl' +RUN aria2c -x 5 --dir / --out wheel.whl 'https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/6.0.0/xformers-0.0.21.dev544-cp310-cp310-manylinux2014_x86_64-pytorch201.whl' + FROM python:3.10.9-slim -SHELL ["/bin/bash", "-ceuxo", "pipefail"] - ENV DEBIAN_FRONTEND=noninteractive PIP_PREFER_BINARY=1 -RUN PIP_NO_CACHE_DIR=1 pip install torch==1.13.1+cu117 torchvision --extra-index-url https://download.pytorch.org/whl/cu117 - -RUN apt-get update && apt install fonts-dejavu-core rsync git jq moreutils -y && apt-get clean +RUN --mount=type=cache,target=/var/cache/apt \ + apt-get update && \ + # we need those + apt-get install -y fonts-dejavu-core rsync git jq moreutils aria2 \ + # extensions needs those + ffmpeg libglfw3-dev libgles2-mesa-dev pkg-config libcairo2 libcairo2-dev -RUN --mount=type=cache,target=/root/.cache/pip < dict|None: + """Load json file into a dictionary. Return None if file does not exist.""" + + if os.path.isfile(config_file): + with open(config_file, 'r') as f: + return json.load(f) + else: + return None + +def replace_if_invalid(value: str, replacement: str, pattern: str|re.Pattern[str]) -> str: + """Returns original value if valid, fallback value if invalid""" + + if re.match(pattern, value): + return value + else: + return replacement + +def check_and_replace_config(config_file: str, target_file: str = None): + """Checks given file for invalid values. Replaces those with fallback values (default: overwrites file).""" + + # Get current user config, or empty if file does not exists + data = json_file_to_dict(config_file) or {} + + # Check and fix output directories + for k, def_val in DEFAULT_OUTDIRS.items(): + if k not in data: + data[k] = def_val + else: + data[k] = replace_if_invalid(value=data[k], replacement=def_val, pattern=RE_VALID_OUTDIR) + + # Check and fix other default settings + for k, def_val in DEFAULT_OTHER.items(): + if k not in data: + data[k] = def_val + + # Write results to file + dict_to_json_file(target_file or config_file, data) + +if __name__ == '__main__': + if len(sys.argv) > 1: + check_and_replace_config(*sys.argv[1:]) + else: + check_and_replace_config(DEFAULT_FILEPATH) + diff --git a/services/AUTOMATIC1111/entrypoint.sh b/services/AUTOMATIC1111/entrypoint.sh index c6df995..337a4d6 100755 --- a/services/AUTOMATIC1111/entrypoint.sh +++ b/services/AUTOMATIC1111/entrypoint.sh @@ -8,13 +8,17 @@ mkdir -p /data/config/auto/scripts/ find "${ROOT}/scripts/" -maxdepth 1 -type l -delete cp -vrfTs /data/config/auto/scripts/ "${ROOT}/scripts/" -cp -n /docker/config.json /data/config/auto/config.json -jq '. * input' /data/config/auto/config.json /docker/config.json | sponge /data/config/auto/config.json +# Set up config file +python /docker/config.py /data/config/auto/config.json if [ ! -f /data/config/auto/ui-config.json ]; then echo '{}' >/data/config/auto/ui-config.json fi +if [ ! -f /data/config/auto/styles.csv ]; then + touch /data/config/auto/styles.csv +fi + declare -A MOUNTS MOUNTS["/root/.cache"]="/data/.cache" @@ -35,13 +39,17 @@ MOUNTS["${ROOT}/models/torch_deepdanbooru"]="/data/Deepdanbooru" MOUNTS["${ROOT}/models/BLIP"]="/data/BLIP" MOUNTS["${ROOT}/models/midas"]="/data/MiDaS" MOUNTS["${ROOT}/models/Lora"]="/data/Lora" +MOUNTS["${ROOT}/models/LyCORIS"]="/data/LyCORIS" MOUNTS["${ROOT}/models/ControlNet"]="/data/ControlNet" MOUNTS["${ROOT}/models/openpose"]="/data/openpose" +MOUNTS["${ROOT}/models/ModelScope"]="/data/ModelScope" MOUNTS["${ROOT}/embeddings"]="/data/embeddings" MOUNTS["${ROOT}/config.json"]="/data/config/auto/config.json" MOUNTS["${ROOT}/ui-config.json"]="/data/config/auto/ui-config.json" +MOUNTS["${ROOT}/styles.csv"]="/data/config/auto/styles.csv" MOUNTS["${ROOT}/extensions"]="/data/config/auto/extensions" +MOUNTS["${ROOT}/config_states"]="/data/config/auto/config_states" # extra hacks MOUNTS["${ROOT}/repositories/CodeFormer/weights/facelib"]="/data/.cache" diff --git a/services/comfy/Dockerfile b/services/comfy/Dockerfile new file mode 100644 index 0000000..ddf60fb --- /dev/null +++ b/services/comfy/Dockerfile @@ -0,0 +1,45 @@ +FROM alpine:3.17 as xformers +RUN apk add --no-cache aria2 +RUN aria2c -x 5 --dir / --out wheel.whl 'https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/5.0.0/xformers-0.0.17.dev449-cp310-cp310-manylinux2014_x86_64.whl' + + +FROM python:3.10.9-slim + +ENV DEBIAN_FRONTEND=noninteractive PIP_PREFER_BINARY=1 + +RUN --mount=type=cache,target=/root/.cache/pip pip install torch==1.13.1 torchvision --extra-index-url https://download.pytorch.org/whl/cu117 + +RUN apt-get update && apt-get install -y git && apt-get clean + +ENV ROOT=/stable-diffusion +RUN --mount=type=cache,target=/root/.cache/pip \ + git clone https://github.com/comfyanonymous/ComfyUI.git ${ROOT} && \ + cd ${ROOT} && \ + git checkout master && \ + git reset --hard 884ea653c8d6fe19b3724f45a04a0d74cd881f2f && \ + pip install -r requirements.txt + + +RUN --mount=type=cache,target=/root/.cache/pip \ + --mount=type=bind,from=xformers,source=/wheel.whl,target=/xformers-0.0.17-cp310-cp310-linux_x86_64.whl \ + pip install triton /xformers-0.0.17-cp310-cp310-linux_x86_64.whl + + +WORKDIR ${ROOT} + +ARG BRANCH=master SHA=884ea653c8d6fe19b3724f45a04a0d74cd881f2f +RUN --mount=type=cache,target=/root/.cache/pip \ + git fetch && \ + git checkout ${BRANCH} && \ + git reset --hard ${SHA} && \ + pip install -r requirements.txt + +# add info +COPY . /docker/ +RUN cp /docker/extra_model_paths.yaml ${ROOT} + +ENV NVIDIA_VISIBLE_DEVICES=all +ENV PYTHONPATH="${PYTHONPATH}:${PWD}" CLI_ARGS="" +EXPOSE 7860 +ENTRYPOINT ["/docker/entrypoint.sh"] +CMD python -u main.py --listen --port 7860 ${CLI_ARGS} diff --git a/services/comfy/entrypoint.sh b/services/comfy/entrypoint.sh new file mode 100755 index 0000000..f5a7430 --- /dev/null +++ b/services/comfy/entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -Eeuo pipefail + +mkdir -vp /data/config/comfy/custom_nodes + +declare -A MOUNTS + +MOUNTS["/root/.cache"]="/data/.cache" +MOUNTS["${ROOT}/input"]="/data/config/comfy/input" +MOUNTS["${ROOT}/output"]="/output/comfy" + +for to_path in "${!MOUNTS[@]}"; do + set -Eeuo pipefail + from_path="${MOUNTS[${to_path}]}" + rm -rf "${to_path}" + if [ ! -f "$from_path" ]; then + mkdir -vp "$from_path" + fi + mkdir -vp "$(dirname "${to_path}")" + ln -sT "${from_path}" "${to_path}" + echo Mounted $(basename "${from_path}") +done + +exec "$@" diff --git a/services/comfy/extra_model_paths.yaml b/services/comfy/extra_model_paths.yaml new file mode 100644 index 0000000..d16dfef --- /dev/null +++ b/services/comfy/extra_model_paths.yaml @@ -0,0 +1,25 @@ +a111: + base_path: /data + + checkpoints: StableDiffusion + configs: StableDiffusion + vae: VAE + loras: Lora + upscale_models: | + RealESRGAN + ESRGAN + SwinIR + GFPGAN + embeddings: embeddings + hypernetworks: Hypernetworks + controlnet: ControlNet + gligen: GLIGEN + clip: CLIPEncoder + + custom_nodes: config/comfy/custom_nodes + + # TODO: I am unsure about these, need more testing + # style_models: config/comfy/style_models + # t2i_adapter: config/comfy/t2i_adapter + # clip_vision: config/comfy/clip_vision + # diffusers: config/comfy/diffusers diff --git a/services/download/download.sh b/services/download/download.sh index 54176d0..68ea540 100755 --- a/services/download/download.sh +++ b/services/download/download.sh @@ -3,7 +3,27 @@ set -Eeuo pipefail # TODO: maybe just use the .gitignore file to create all of these -mkdir -vp /data/.cache /data/StableDiffusion /data/Codeformer /data/GFPGAN /data/ESRGAN /data/BSRGAN /data/RealESRGAN /data/SwinIR /data/LDSR /data/ScuNET /data/embeddings /data/VAE /data/Deepdanbooru /data/MiDaS /data/Lora /data/ControlNet /data/openpose +mkdir -vp /data/.cache \ + /data/StableDiffusion \ + /data/LyCORIS \ + /data/Codeformer \ + /data/ModelScope \ + /data/GFPGAN \ + /data/ESRGAN \ + /data/BSRGAN \ + /data/RealESRGAN \ + /data/SwinIR \ + /data/LDSR \ + /data/ScuNET \ + /data/embeddings \ + /data/VAE \ + /data/Deepdanbooru \ + /data/MiDaS \ + /data/Lora \ + /data/ControlNet \ + /data/openpose \ + /data/GLIGEN \ + /data/CLIPEncoder # this is different from the cached pre-train ViT saved in /data/.cache/clip TODO: find out how echo "Downloading, this might take a while..." diff --git a/services/invoke/Dockerfile b/services/invoke/Dockerfile index f19ef93..3bc90b1 100644 --- a/services/invoke/Dockerfile +++ b/services/invoke/Dockerfile @@ -1,68 +1,53 @@ -# syntax=docker/dockerfile:1 - FROM alpine:3.17 as xformers RUN apk add --no-cache aria2 -RUN aria2c -x 5 --dir / --out wheel.whl 'https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/5.0.0/xformers-0.0.17.dev449-cp310-cp310-manylinux2014_x86_64.whl' +RUN aria2c -x 5 --dir / --out wheel.whl 'https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/6.0.0/xformers-0.0.21.dev544-cp310-cp310-manylinux2014_x86_64-pytorch201.whl' +FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime -FROM python:3.10-slim -SHELL ["/bin/bash", "-ceuxo", "pipefail"] - -ENV DEBIAN_FRONTEND=noninteractive PIP_EXISTS_ACTION=w PIP_PREFER_BINARY=1 - - -RUN --mount=type=cache,target=/root/.cache/pip pip install torch==1.13.1+cu117 torchvision --extra-index-url https://download.pytorch.org/whl/cu117 - -RUN apt-get update && apt-get install git -y && apt-get clean - -RUN git clone https://github.com/invoke-ai/InvokeAI.git /stable-diffusion - -WORKDIR /stable-diffusion - -RUN --mount=type=cache,target=/root/.cache/pip < req.txt -pip install -r req.txt -rm req.txt -EOF - +ENV DEBIAN_FRONTEND=noninteractive PIP_EXISTS_ACTION=w PIP_PREFER_BINARY=1 # patch match: # https://github.com/invoke-ai/InvokeAI/blob/main/docs/installation/INSTALL_PATCHMATCH.md -RUN <=4.24' - -# add info -COPY . /docker/ -RUN <For help and advanced usage guides,', """ -

- Created using stable-diffusion-webui-docker. -

-

For help and advanced usage guides, -""", 1) -) diff --git a/services/sygil/mount.sh b/services/sygil/mount.sh deleted file mode 100755 index cc0dc9d..0000000 --- a/services/sygil/mount.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -set -Eeuo pipefail - -declare -A MOUNTS - -ROOT=/stable-diffusion/src - -# cache -MOUNTS["/root/.cache"]=/data/.cache -# ui specific -MOUNTS["${PWD}/models/realesrgan"]=/data/RealESRGAN -MOUNTS["${PWD}/models/ldsr"]=/data/LDSR -MOUNTS["${PWD}/models/custom"]=/data/StableDiffusion - -# hack -MOUNTS["${PWD}/models/gfpgan/GFPGANv1.3.pth"]=/data/GFPGAN/GFPGANv1.4.pth -MOUNTS["${PWD}/models/gfpgan/GFPGANv1.4.pth"]=/data/GFPGAN/GFPGANv1.4.pth -MOUNTS["${PWD}/gfpgan/weights"]=/data/.cache - - -for to_path in "${!MOUNTS[@]}"; do - set -Eeuo pipefail - from_path="${MOUNTS[${to_path}]}" - rm -rf "${to_path}" - mkdir -p "$(dirname "${to_path}")" - ln -sT "${from_path}" "${to_path}" - echo Mounted $(basename "${from_path}") -done - -# streamlit config -ln -sf /docker/userconfig_streamlit.yaml /stable-diffusion/configs/webui/userconfig_streamlit.yaml diff --git a/services/sygil/run.sh b/services/sygil/run.sh deleted file mode 100755 index 89f7959..0000000 --- a/services/sygil/run.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -Eeuo pipefail - -echo "USE_STREAMLIT = ${USE_STREAMLIT}" -if [ "${USE_STREAMLIT}" == "1" ]; then - python -u -m streamlit run scripts/webui_streamlit.py -else - python3 -u scripts/webui.py --outdir /output --ckpt /data/StableDiffusion/v1-5-pruned-emaonly.ckpt ${CLI_ARGS} -fi diff --git a/services/sygil/userconfig_streamlit.yaml b/services/sygil/userconfig_streamlit.yaml deleted file mode 100644 index 07a20af..0000000 --- a/services/sygil/userconfig_streamlit.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# https://github.com/Sygil-Dev/sygil-webui/blob/master/configs/webui/webui_streamlit.yaml -general: - version: 1.24.6 - outdir: /output - default_model: "Stable Diffusion v1.5" - default_model_path: /data/StableDiffusion/v1-5-pruned-emaonly.ckpt - outdir_txt2img: /output/txt2img - outdir_img2img: /output/img2img - outdir_img2txt: /output/img2txt - optimized: True - optimized_turbo: True