diff --git a/.github/workflows/build-push-auto.yml b/.github/workflows/build-push-auto.yml index 357b306..41d6714 100644 --- a/.github/workflows/build-push-auto.yml +++ b/.github/workflows/build-push-auto.yml @@ -49,7 +49,7 @@ concurrency: env: IMAGE_REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} + IMAGE_NAMESPACE: ${{ github.repository }} IMAGE_PLATFORMS: "linux/amd64" jobs: @@ -118,7 +118,7 @@ jobs: uses: docker/metadata-action@v4 with: images: | - ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }} + ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }} tags: ${{ matrix.tags }} - name: Build and Push Versioned Tags diff --git a/.github/workflows/build-push-vlad.yml b/.github/workflows/build-push-vlad.yml deleted file mode 100644 index e31429b..0000000 --- a/.github/workflows/build-push-vlad.yml +++ /dev/null @@ -1,124 +0,0 @@ -name: WebUI (vladmandic) -run-name: vladmandic (via ${{ github.event_name }}) - -on: - push: - branches: - - "main" - - "release" - paths: - - "docker-bake.hcl" - - "docker-compose.yml" - - "docker/Dockerfile.base" - - "docker/Dockerfile.vlad" - - "docker/entrypoint_vlad.sh" - - "docker/*vlad*" - - "docker/config.json" - - ".github/workflows/build-push-vlad.yml" - - "!**.md" - schedule: - - cron: "0 0 * * *" - - workflow_dispatch: - inputs: - force-push: - description: "push to GHCR" - type: boolean - required: true - default: false - - pull_request: - paths: - - "docker-bake.hcl" - - "docker-compose.yml" - - "docker/Dockerfile.base" - - "docker/Dockerfile.vlad" - - "docker/entrypoint_vlad.sh" - - "docker/*vlad*" - - "docker/config.json" - - ".github/workflows/build-push-vlad.yml" - - "!**.md" - -defaults: - run: - shell: bash - -concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} - cancel-in-progress: true - -env: - IMAGE_REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - IMAGE_PLATFORMS: "linux/amd64" - -jobs: - build: - name: Build - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - - strategy: - fail-fast: false - max-parallel: 1 - matrix: - include: - - name: "Latest" - target: "vlad-latest" - tags: | - type=raw,value=vlad,enable={{is_default_branch}} - type=raw,value=vlad-{{date 'YYYYMMDD'}},enable={{is_default_branch}} - type=sha,prefix=vlad-,format=short - type=ref,event=branch,prefix=vlad- - type=ref,event=tag,prefix=vlad- - type=ref,event=pr,prefix=vlad- - - steps: - - name: Free disk space - id: free-disk-space - run: | - df -h . - sudo find /usr/share/dotnet -delete - sudo find /usr/local/lib/android -delete - df -h . - - - name: Checkout - id: checkout - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - with: - platforms: ${{ env.IMAGE_PLATFORMS }} - - - name: Login to GHCR - uses: docker/login-action@v2 - with: - registry: ${{ env.IMAGE_REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Docker meta - id: meta - uses: docker/metadata-action@v4 - with: - images: | - ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }} - tags: ${{ matrix.tags }} - - - name: Build and Push Versioned Tags - id: build-push - uses: docker/bake-action@v3 - with: - targets: ${{ matrix.target }} - files: | - ./docker-bake.hcl - ${{ steps.meta.outputs.bake-file }} - push: ${{ ((github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/main') || inputs.force-push }} - set: | - *.cache-from=type=gha diff --git a/docker-bake.hcl b/docker-bake.hcl index 499d7ae..b8393ae 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -1,46 +1,68 @@ # docker-bake.hcl for stable-diffusion-webui group "default" { - targets = ["auto-latest", "auto-edge", "vlad-latest"] + targets = ["local"] } variable "IMAGE_REGISTRY" { default = "ghcr.io" } -variable "IMAGE_NAME" { +variable "IMAGE_NAMESPACE" { default = "neggles/sd-webui-docker" } variable "AUTO_LATEST_REF" { - default = "origin/master" + default = "master" } variable "AUTO_EDGE_REF" { - default = "origin/dev" + default = "dev" } -variable "VLAD_LATEST_REF" { - default = "origin/master" +variable "CUDA_VERSION" { + default = "12.1" } -variable "KOHYA_SS_REF" { - default = "63657088f4c35a376dd8a936f53e9b9a3b4b1168" +variable "TORCH_PACKAGE" { + default = "torch==2.2.0" } -variable "KOHYA_EDGE_REF" { - default = "ad76b1cddfae460372262cb44043701fe1aec96e" +variable "TORCH_INDEX" { + default = "https://pypi.org/simple" } -variable "CUDA_VERSION" { - default = "12.1" +# convert a CUDA version number into a shortname (e.g. 11.2.1 -> cu112) +function cudaName { + params = [version] + result = regex_replace(version, "^(\\d+)\\.(\\d).*", "cu$1$2") } -variable "TORCH_VERSION" { - default = "2.0.1+cu118" +# convert a CUDA version number into a release number (e.g. 11.2.1 -> 11-2) +function cudaRelease { + params = [version] + result = regex_replace(version, "^(\\d+)\\.(\\d).*", "$1-$2") } -variable "TORCH_INDEX" { - default = "https://download.pytorch.org/whl/cu118" +# torch version to torch name +function torchName { + params = [version] + # this is cursed, but if i try to do torch$1$20 it will interpret "$2 0" as $20 + result = join("", [regex_replace(version, "^(\\d+)\\.(\\d+)\\.(\\d+).*", "torch$1$2"), "0"]) +} +# torch version to torch name +function torchSpec { + params = [version] + result = regex_replace(version, "^(\\d+)\\.(\\d+)\\.(\\d+).*", "torch==$1.$2.$3") +} + +# build a tag for an image from this repo +function repoImage { + params = [imageName] + variadic_params = extraVals + result = join(":", [ + join("/", [IMAGE_REGISTRY, IMAGE_NAMESPACE]), + join("-", concat([imageName], extraVals)) + ]) } # docker-metadata-action will populate this in GitHub Actions @@ -56,12 +78,9 @@ target "common" { CUDA_RELEASE = "${regex_replace(CUDA_VERSION, "\\.", "-")}" TORCH_INDEX = TORCH_INDEX - TORCH_VERSION = TORCH_VERSION + TORCH_PACKAGE = TORCH_PACKAGE CUDNN_VERSION = "8.9.3.28-1" - XFORMERS_VERSION = "0.0.21" - BNB_VERSION = "0.41.1" - TRITON_VERSION = "2.0.0.post1" - LION_VERSION = "0.0.7" + XFORMERS_PACKAGE = "xformers>=0.0.23.post1" } platforms = ["linux/amd64"] @@ -79,12 +98,12 @@ target "base" { CUDA_RELEASE = "${regex_replace(CUDA_VERSION, "\\.", "-")}" TORCH_INDEX = TORCH_INDEX - TORCH_VERSION = TORCH_VERSION + TORCH_PACKAGE = TORCH_PACKAGE } } -# AUTOMATIC1111 on latest git commit -target "auto-edge" { +# AUTOMATIC1111 on master +target "auto-latest" { inherits = ["common", "docker-metadata-action"] dockerfile = "Dockerfile.auto" target = "webui" @@ -92,31 +111,24 @@ target "auto-edge" { base = "target:base" } args = { - SD_WEBUI_VARIANT = "edge" + SD_WEBUI_VARIANT = "latest" SD_WEBUI_REPO = "https://github.com/AUTOMATIC1111/stable-diffusion-webui.git" - SD_WEBUI_REF = AUTO_EDGE_REF + SD_WEBUI_REF = AUTO_LATEST_REF REQFILE_NAME = "requirements_versions.txt" - TRITON_VERSION = "2.1.0" - XFORMERS_VERSION = "0.0.21" - STABLE_DIFFUSION_REF = "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf" STABLE_DIFFUSION_XL_REF = "45c443b316737a4ab6e40413d7794a7f5657c19f" - TAMING_TRANSFORMERS_REF = "24268930bf1dce879235a7fddd0b2355b84d7ea6" K_DIFFUSION_REF = "ab527a9a6d347f364e3d185ba6d714e22d80cb3c" - CODEFORMER_REF = "c5b4593074ba6214284d6acd5f1719b6c5d739af" BLIP_REF = "48211a1594f1321b00f14c9f7a5b4813144b2fb9" + SD_WEBUI_ASSETS_REF = "6f7db241d2f8ba7457bac5ca9753331f0c266917" - CLIP_INTERROGATOR_REF = "08546eae22d825a23f30669e10025098bb4f9dde" - GFPGAN_PKG_REF = "8d2447a2d918f8eba5a4a01463fd48e45126a379" - CLIP_PKG_REF = "d50d76daa670286dd6cacf3bcd80b5e4823fc8e1" - OPENCLIP_PKG_REF = "bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b" + CLIP_PKG_REF = "d50d76daa670286dd6cacf3bcd80b5e4823fc8e1" + OPENCLIP_PKG_REF = "bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b" } } - -# AUTOMATIC1111 on latest known-good commit -target "auto-latest" { +# AUTOMATIC1111 on dev +target "auto-edge" { inherits = ["common", "docker-metadata-action"] dockerfile = "Dockerfile.auto" target = "webui" @@ -124,79 +136,38 @@ target "auto-latest" { base = "target:base" } args = { - SD_WEBUI_VARIANT = "latest" + SD_WEBUI_VARIANT = "edge" SD_WEBUI_REPO = "https://github.com/AUTOMATIC1111/stable-diffusion-webui.git" - SD_WEBUI_REF = AUTO_LATEST_REF + SD_WEBUI_REF = AUTO_EDGE_REF REQFILE_NAME = "requirements_versions.txt" STABLE_DIFFUSION_REF = "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf" STABLE_DIFFUSION_XL_REF = "45c443b316737a4ab6e40413d7794a7f5657c19f" - TAMING_TRANSFORMERS_REF = "24268930bf1dce879235a7fddd0b2355b84d7ea6" - K_DIFFUSION_REF = "ab527a9a6d347f364e3d185ba6d714e22d80cb3c" - CODEFORMER_REF = "c5b4593074ba6214284d6acd5f1719b6c5d739af" - BLIP_REF = "48211a1594f1321b00f14c9f7a5b4813144b2fb9" - - CLIP_INTERROGATOR_REF = "08546eae22d825a23f30669e10025098bb4f9dde" - GFPGAN_PKG_REF = "8d2447a2d918f8eba5a4a01463fd48e45126a379" - CLIP_PKG_REF = "d50d76daa670286dd6cacf3bcd80b5e4823fc8e1" - OPENCLIP_PKG_REF = "bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b" - } -} - -# vladmandic/automatic on latest git commit -target "vlad-latest" { - inherits = ["common", "docker-metadata-action"] - dockerfile = "Dockerfile.vlad" - target = "vlad" - contexts = { - base = "target:base" - } - args = { - SD_WEBUI_VARIANT = "vlad" - SD_WEBUI_REPO = "https://github.com/vladmandic/automatic.git" - SD_WEBUI_REF = VLAD_LATEST_REF - REQFILE_NAME = "requirements.txt" - - TRITON_VERSION = "2.1.0" - XFORMERS_VERSION = "0.0.21" - - STABLE_DIFFUSION_REF = "cf1d67a6fd5ea1aa600c4df58e5b47da45f6bdbf" - STABLE_DIFFUSION_XL_REF = "45c443b316737a4ab6e40413d7794a7f5657c19f" - TAMING_TRANSFORMERS_REF = "24268930bf1dce879235a7fddd0b2355b84d7ea6" K_DIFFUSION_REF = "ab527a9a6d347f364e3d185ba6d714e22d80cb3c" - CODEFORMER_REF = "c5b4593074ba6214284d6acd5f1719b6c5d739af" BLIP_REF = "48211a1594f1321b00f14c9f7a5b4813144b2fb9" + SD_WEBUI_ASSETS_REF = "6f7db241d2f8ba7457bac5ca9753331f0c266917" - CLIP_PKG_REF = "d50d76daa670286dd6cacf3bcd80b5e4823fc8e1" - } -} - -# bmaltais/kohya_ss training repo -target "kohya-latest" { - inherits = ["common", "docker-metadata-action"] - context = "./kohya" - dockerfile = "Dockerfile.kohya" - target = "kohya" - contexts = { - base = "target:base" - } - args = { - KOHYA_SS_REPO = "https://github.com/bmaltais/kohya_ss.git" - KOHYA_SS_REF = KOHYA_SS_REF + CLIP_PKG_REF = "d50d76daa670286dd6cacf3bcd80b5e4823fc8e1" + OPENCLIP_PKG_REF = "bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b" } } -# bmaltais/kohya_ss training repo -target "kohya-edge" { - inherits = ["common", "docker-metadata-action"] - context = "./kohya" - dockerfile = "Dockerfile.kohya" - target = "kohya" - contexts = { - base = "target:base" - } - args = { - KOHYA_SS_REPO = "https://github.com/neggles/kohya_ss.git" - KOHYA_SS_REF = KOHYA_EDGE_REF - } +target "local" { + inherits = ["auto-latest"] + target = "webui" + tags = [ + repoImage(cudaName("12.1.1"), torchName("2.2.0")), + repoImage("latest"), + ] + args = {} +} + +target "local-dev" { + inherits = ["auto-edge"] + target = "webui" + tags = [ + repoImage("edge", cudaName("12.1.1"), torchName("2.2.0")), + repoImage("edge"), + ] + args = {} } diff --git a/docker-compose.yml b/docker-compose.yml index 42a8997..4b97f8c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: dockerfile: Dockerfile target: webui environment: - CLI_ARGS: "--allow-code --enable-insecure-extension-access --api --xformers --opt-channelslast" + CLI_ARGS: "--skip-version-check --allow-code --enable-insecure-extension-access --api --xformers --opt-channelslast" # make TQDM behave a little better PYTHONUNBUFFERED: "1" TERM: "${TERM}" diff --git a/docker/Dockerfile.auto b/docker/Dockerfile.auto index 1e5fada..64e41d0 100644 --- a/docker/Dockerfile.auto +++ b/docker/Dockerfile.auto @@ -13,37 +13,50 @@ SHELL [ "/bin/bash", "-ceuxo", "pipefail" ] # This isn't strictly necessary as it's set upstream, but it's here for clarity WORKDIR /git -# Add clone script -COPY --chown=root:root --chmod=0755 ./clone.sh /root/clone.sh - # Clone repositories ARG STABLE_DIFFUSION_REF -RUN mkdir -p stable-diffusion-stability-ai && \ - /root/clone.sh stable-diffusion-stability-ai "https://github.com/Stability-AI/stablediffusion.git" "${STABLE_DIFFUSION_REF}" \ - && cd stable-diffusion-stability-ai \ - && rm -fr ./assets ./data/**/*.png ./data/**/*.jpg ./data/**/*.gif - -ARG TAMING_TRANSFORMERS_REF -RUN mkdir -p taming-transformers && \ - /root/clone.sh taming-transformers "https://github.com/CompVis/taming-transformers.git" "${TAMING_TRANSFORMERS_REF}" \ - && cd taming-transformers \ - && rm -fr data assets **/*.ipynb - -ARG CODEFORMER_REF -RUN mkdir -p CodeFormer && \ - /root/clone.sh CodeFormer https://github.com/sczhou/CodeFormer.git ${CODEFORMER_REF} \ - && cd CodeFormer \ - && rm -fr data assets **/*.ipynb +RUN rm -fr "stable-diffusion-stability-ai" \ + && git clone --recursive --depth=1 \ + "https://github.com/Stability-AI/stablediffusion.git" "stable-diffusion-stability-ai" \ + && cd "stable-diffusion-stability-ai" \ + && git fetch origin "${STABLE_DIFFUSION_REF}" \ + && git reset --hard FETCH_HEAD \ + && rm -fr ./assets ./data/**/*.png ./data/**/*.jpg ./data/**/*.gif ARG BLIP_REF -RUN /root/clone.sh BLIP https://github.com/salesforce/BLIP.git ${BLIP_REF} +RUN rm -fr "BLIP" \ + && git clone --recursive --depth=1 \ + "https://github.com/salesforce/BLIP.git" "BLIP" \ + && cd "BLIP" \ + && git fetch origin "${BLIP_REF}" \ + && git reset --hard FETCH_HEAD ARG K_DIFFUSION_REF -RUN /root/clone.sh k-diffusion https://github.com/crowsonkb/k-diffusion.git ${K_DIFFUSION_REF} +RUN rm -fr "k-diffusion" \ + && git clone --recursive --depth=1 \ + "https://github.com/crowsonkb/k-diffusion.git" "k-diffusion" \ + && cd "k-diffusion" \ + && git fetch origin "${K_DIFFUSION_REF}" \ + && git reset --hard FETCH_HEAD ARG STABLE_DIFFUSION_XL_REF -RUN mkdir -p generative-models && \ - /root/clone.sh generative-models "https://github.com/Stability-AI/generative-models.git" "${STABLE_DIFFUSION_XL_REF}" +RUN rm -fr "generative-models" \ + && git clone --recursive --depth=1 \ + "https://github.com/Stability-AI/generative-models.git" "generative-models" \ + && cd "generative-models" \ + && git fetch origin "${STABLE_DIFFUSION_XL_REF}" \ + && git reset --hard FETCH_HEAD + +ARG SD_WEBUI_ASSETS_REF +RUN rm -fr "stable-diffusion-webui-assets" \ + && git clone --recursive --depth=1 \ + "https://github.com/AUTOMATIC1111/stable-diffusion-webui-assets.git" "stable-diffusion-webui-assets" \ + && cd "stable-diffusion-webui-assets" \ + && git fetch origin "${SD_WEBUI_ASSETS_REF}" \ + && git reset --hard FETCH_HEAD + +# print out the contents of the git directory for debugging +RUN ls -l && sleep 5 FROM base AS webui @@ -51,7 +64,6 @@ FROM base AS webui ARG DEBIAN_FRONTEND ARG DEBIAN_PRIORITY ARG PIP_PREFER_BINARY -ARG SD_WEBUI_VARIANT ENV LC_ALL=C.UTF-8 ENV PYTHONUNBUFFERED=1 @@ -60,9 +72,6 @@ ENV PYTHONIOENCODING=utf-8 # make pip STFU about being root ENV PIP_ROOT_USER_ACTION=ignore -# variant for later use -ENV SD_WEBUI_VARIANT=${SD_WEBUI_VARIANT} - # CUDA-related ENV CUDA_MODULE_LOADING=LAZY ENV TORCH_ALLOW_TF32_CUBLAS_OVERRIDE=1 @@ -73,52 +82,46 @@ ENV NVIDIA_REQUIRE_CUDA="cuda>=11.8 driver>=450" # Where we should put everything ENV ROOT_DIR=/stable-diffusion-webui +# Install GFPGAN, CLIP, OPENCLIP and pyngrok +ARG CLIP_PKG_REF +ARG OPENCLIP_PKG_REF +RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ + pip install \ + pyngrok \ + "git+https://github.com/openai/CLIP.git@${CLIP_PKG_REF}" \ + "git+https://github.com/mlfoundations/open_clip.git@${OPENCLIP_PKG_REF}" + # Clone actual repo ARG SD_WEBUI_REF ARG SD_WEBUI_REPO RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - git clone ${SD_WEBUI_REPO} ${ROOT_DIR} \ - && cd ${ROOT_DIR} \ - && git reset --hard ${SD_WEBUI_REF} - -# copy the dep repos from the download stage -COPY --from=download /git/* ${ROOT_DIR}/repositories/ - -# Install requirements -ARG REQFILE_NAME -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - cd ${ROOT_DIR} \ - && pip install -r ${REQFILE_NAME} - -# Install requirements for CodeFormer -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install -r ${ROOT_DIR}/repositories/CodeFormer/requirements.txt - -# Install GFPGAN, CLIP, OPENCLIP and pyngrok -ARG GFPGAN_PKG_REF -ARG CLIP_PKG_REF -ARG OPENCLIP_PKG_REF -RUN pip install \ - pyngrok \ - "git+https://github.com/TencentARC/GFPGAN.git@${GFPGAN_PKG_REF}" \ - "git+https://github.com/openai/CLIP.git@${CLIP_PKG_REF}" \ - "git+https://github.com/mlfoundations/open_clip.git@${OPENCLIP_PKG_REF}" + git clone ${SD_WEBUI_REPO} ${ROOT_DIR} \ + && cd ${ROOT_DIR} \ + && git fetch origin ${SD_WEBUI_REF} \ + && git reset --hard ${SD_WEBUI_REF} +# set workdir +WORKDIR ${ROOT_DIR} # fix an issue in A1111 ENV LD_PRELOAD=libtcmalloc.so -ENV TCMALLOC_AGGRESSIVE_DECOMMIT=1 +ENV TCMALLOC_AGGRESSIVE_DECOMMIT=t # Reupdate the repo to target hash and install deps RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - cd ${ROOT_DIR} \ - && git fetch \ - && git reset --hard ${SD_WEBUI_REF} \ - && git submodule update --init --recursive \ - && pip install -r ${REQFILE_NAME} + git fetch origin ${SD_WEBUI_REF} \ + && git reset --hard ${SD_WEBUI_REF} \ + && git submodule sync \ + && git submodule update --init --recursive \ + && pip install -r requirements_versions.txt + +# copy the dep repos from the download stage +RUN --mount=type=bind,from=download,source=/git,target=/git \ + mkdir -p ${ROOT_DIR}/repositories \ + && cp -rp /git/* ${ROOT_DIR}/repositories/ # Install extra packages needed for extensions RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install \ + pip install \ accelerate \ diffusers \ ffmpeg-python \ @@ -132,15 +135,15 @@ RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ # Install moviepy and up-to-date tqdm RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install 'moviepy>=1.0.3' 'tqdm>=4.65.0' 'imageio-ffmpeg' + pip install 'moviepy>=1.0.3' 'tqdm>=4.65.0' 'imageio-ffmpeg' -# Install xformers and triton (we do this after the above to make sure we get the versions we want) -ARG XFORMERS_VERSION -ARG TRITON_VERSION +# Install xformers (we do this after the above to make sure we get the versions we want) +# Install xformers +ARG XFORMERS_PACKAGE="xformers" +ARG XFORMERS_PIP_ARGS="" RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install --no-deps --pre \ - xformers==${XFORMERS_VERSION} \ - triton==${TRITON_VERSION} + python -m pip install ${XFORMERS_PIP_ARGS} "${XFORMERS_PACKAGE}" \ + || python -m pip install --pre ${XFORMERS_PIP_ARGS} "${XFORMERS_PACKAGE}" # Add the rest of the files COPY . /docker @@ -159,4 +162,4 @@ ENV GID=1000 EXPOSE ${WEBUI_PORT} ENTRYPOINT [ "/docker/entrypoint.sh" ] -CMD python -u webui.py --listen --port ${WEBUI_PORT} ${CLI_ARGS} +CMD python -u webui.py --listen --port ${WEBUI_PORT} --skip-version-check ${CLI_ARGS} diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 2bef498..92ee9b7 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -101,12 +101,31 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ python3 -m pip install -U pip wheel +# add the nVidia python index +RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ + python -m pip install nvidia-pyindex + # Install PyTorch -ARG TORCH_VERSION ARG TORCH_INDEX +ARG TORCH_PACKAGE="torch" +ARG EXTRA_PIP_ARGS=" " RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - python3 -m pip install torch==${TORCH_VERSION} torchvision --extra-index-url ${TORCH_INDEX} - -# add the nVidia python index + python -m pip install ${EXTRA_PIP_ARGS:-} \ + "${TORCH_PACKAGE}" \ + triton \ + torchaudio \ + torchvision \ + --index-url "${TORCH_INDEX}" + +# save and enforce a constraint file to lock the torch and triton versions RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - python3 -m pip install nvidia-pyindex + python -m pip freeze | grep -E '(^torch|triton)' > /torch-constraints.txt \ + && echo "-----------------------------" \ + && echo "Created torch constraint file:" \ + && cat /torch-constraints.txt \ + && echo "-----------------------------" +ENV PIP_CONSTRAINT=/torch-constraints.txt + +# we do a little entrypoint setup +WORKDIR /workspace +CMD ["/bin/bash", "-l"] diff --git a/docker/Dockerfile.vlad b/docker/Dockerfile.vlad deleted file mode 100644 index 87478d4..0000000 --- a/docker/Dockerfile.vlad +++ /dev/null @@ -1,170 +0,0 @@ -# syntax=docker/dockerfile:1 - -ARG DEBIAN_FRONTEND=noninteractive -ARG DEBIAN_PRIORITY=critical -ARG PIP_PREFER_BINARY=1 - -FROM alpine/git:2.36.2 as download - -# Get bash, set shell -RUN apk add --no-cache bash -SHELL [ "/bin/bash", "-ceuxo", "pipefail" ] - -# Set working directory -WORKDIR /git - -# Clone repositories -ARG STABLE_DIFFUSION_REPO=https://github.com/Stability-AI/stablediffusion.git -ARG STABLE_DIFFUSION_REF -RUN git clone --depth=1 "${STABLE_DIFFUSION_REPO}" "stablediffusion" \ - && cd "stablediffusion" \ - && git fetch --depth=1 origin "${STABLE_DIFFUSION_REF}" \ - && git reset --hard "${STABLE_DIFFUSION_REF}" \ - && git submodule update --init --recursive \ - && rm -fr assets data/**/*.png data/**/*.jpg data/**/*.gif - -ARG TAMING_TRANSFORMERS_REPO=https://github.com/CompVis/taming-transformers.git -ARG TAMING_TRANSFORMERS_REF -RUN git clone --depth=1 "${TAMING_TRANSFORMERS_REPO}" "taming-transformers" \ - && cd "taming-transformers" \ - && git fetch --depth=1 origin "${TAMING_TRANSFORMERS_REF}" \ - && git reset --hard "${TAMING_TRANSFORMERS_REF}" \ - && git submodule update --init --recursive \ - && rm -fr data assets **/*.ipynb - -ARG K_DIFFUSION_REPO=https://github.com/crowsonkb/k-diffusion.git -ARG K_DIFFUSION_REF -RUN git clone --depth=1 "${K_DIFFUSION_REPO}" "k-diffusion" \ - && cd "k-diffusion" \ - && git fetch --depth=1 origin "${K_DIFFUSION_REF}" \ - && git reset --hard "${K_DIFFUSION_REF}" \ - && git submodule update --init --recursive - -ARG CODEFORMER_REPO=https://github.com/sczhou/CodeFormer.git -ARG CODEFORMER_REF -RUN git clone --depth=1 "${CODEFORMER_REPO}" "CodeFormer" \ - && cd "CodeFormer" \ - && git fetch --depth=1 origin "${CODEFORMER_REF}" \ - && git reset --hard "${CODEFORMER_REF}" \ - && git submodule update --init --recursive \ - && rm -fr data assets **/*.ipynb - -ARG BLIP_REPO=https://github.com/salesforce/BLIP.git -ARG BLIP_REF -RUN git clone --depth=1 "${BLIP_REPO}" "BLIP" \ - && cd "BLIP" \ - && git fetch --depth=1 origin "${BLIP_REF}" \ - && git reset --hard "${BLIP_REF}" \ - && git submodule update --init --recursive - -FROM base AS vlad - -# set up some important environment variables -ARG DEBIAN_FRONTEND -ARG DEBIAN_PRIORITY -ARG PIP_PREFER_BINARY -ARG SD_WEBUI_VARIANT - -ENV LC_ALL=C.UTF-8 -ENV PYTHONUNBUFFERED=1 -ENV PYTHONIOENCODING=utf-8 -ENV SD_WEBUI_VARIANT=${SD_WEBUI_VARIANT} - -# CUDA-related -ENV CUDA_MODULE_LOADING=LAZY -ENV SAFETENSORS_FAST_GPU=1 -ENV TORCH_ALLOW_TF32_CUBLAS_OVERRIDE=1 -ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility,graphics -ENV NVIDIA_REQUIRE_CUDA="cuda>=11.6 driver>=450" - -# Where we should put everything -ENV ROOT_DIR=/stable-diffusion-webui - -# Clone actual repo -ARG SD_WEBUI_REF -ARG SD_WEBUI_REPO -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - git clone ${SD_WEBUI_REPO} ${ROOT_DIR} \ - && cd ${ROOT_DIR} \ - && git reset --hard ${SD_WEBUI_REF} - -# Install xformers and triton -ARG XFORMERS_VERSION -ARG TRITON_VERSION -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install --no-deps --pre \ - xformers==${XFORMERS_VERSION} \ - triton==${TRITON_VERSION} - -# Install requirements -ARG REQFILE_NAME -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - cd ${ROOT_DIR} \ - && pip install -r ${REQFILE_NAME} - -# Grab repositories from download stage -COPY --from=download /git/ ${ROOT_DIR}/repositories/ - -# Install requirements for CodeFormer -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install -r ${ROOT_DIR}/repositories/CodeFormer/requirements.txt - -# Install CLIP and pyngrok -ARG CLIP_PKG_REF -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install \ - pyngrok \ - "git+https://github.com/openai/CLIP.git@${CLIP_PKG_REF}" - -# fix an issue in A1111 -ENV LD_PRELOAD=libtcmalloc.so - -# Reupdate the repo to target hash and install deps -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - cd ${ROOT_DIR} \ - && git fetch \ - && git reset --hard ${SD_WEBUI_REF} \ - && git submodule update --init --recursive \ - && pip install -r ${REQFILE_NAME} - -# Install extra packages needed for extensions -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install \ - accelerate \ - diffusers \ - ffmpeg-python \ - imageio_ffmpeg \ - moviepy \ - natsort \ - onnxruntime-gpu \ - opencv-contrib-python-headless \ - scenedetect \ - scikit-learn \ - segment-anything \ - segmentation-refinement - -# Install moviepy and up-to-date tqdm -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - pip install 'moviepy==1.0.3' 'tqdm>=4.65.0' 'imageio-ffmpeg' - -# Add the rest of the files -COPY . /docker -COPY ./entrypoint_vlad.sh /docker/entrypoint.sh - -# Run the vlad installer -RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \ - cd ${ROOT_DIR} \ - && python -u installer.py - -# Commit high treason -RUN sed -i 's/in_app_dir = .*/in_app_dir = True/g' /usr/local/lib/python3.10/site-packages/gradio/routes.py - -# Set up the entrypoint -WORKDIR ${ROOT_DIR} -ENV CLI_ARGS="" -ENV DATA_DIR=/data -ENV WEBUI_PORT=7860 - -EXPOSE ${WEBUI_PORT} -ENTRYPOINT [ "/docker/entrypoint.sh" ] -CMD python -u launch.py --listen --port ${WEBUI_PORT} ${CLI_ARGS} diff --git a/docker/clone.sh b/docker/clone.sh deleted file mode 100755 index 95f3ae9..0000000 --- a/docker/clone.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -set -exuo pipefail - -repo_dir=${1:?"repo_dir is required"} -repo_url=${2:?"repo_url is required"} -repo_ref=${3:?"repo_ref is required"} - -repo_path="/git/repositories/${repo_dir}" - -# give git a default branch name so it's happy -git config --global init.defaultBranch main - -# make dir -mkdir -p "${repo_path}" - -# go into dir -pushd "${repo_path}" >/dev/null - -# clone repo, reusing existing files if possible -git init . -git remote add origin "${repo_url}" -git fetch --depth 1 origin "${repo_ref}" -git reset --hard FETCH_HEAD - -# clean up git dir -rm -fr .git - -# restore old CWD just to be safe -popd >/dev/null diff --git a/docker/entrypoint_auto.sh b/docker/entrypoint_auto.sh index f50ed5d..a1b6fc6 100755 --- a/docker/entrypoint_auto.sh +++ b/docker/entrypoint_auto.sh @@ -129,7 +129,7 @@ done # Copy scripts individually to avoid purging the directory echo 'Copying scripts (if present): ' -cp -vrfTs "${config_dir}"/scripts/*.py "${repo_root}/scripts/" || true +cp -vr ${config_dir}/scripts/*.py "${repo_root}/scripts/" || true # Set git config so it won't warn and confuse the webui git config --system pull.rebase true diff --git a/docker/entrypoint_vlad.sh b/docker/entrypoint_vlad.sh deleted file mode 100755 index 01766ab..0000000 --- a/docker/entrypoint_vlad.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -# Set up our directory mapping table -repo_root=${ROOT_DIR:-'/stable-diffusion-webui'} -data_dir=${DATA_DIR:-'/data'} -declare -A path_map - -path_map["${repo_root}/models/Stable-diffusion"]="${data_dir}/StableDiffusion" -path_map["${repo_root}/models/VAE"]="${data_dir}/VAE" -path_map["${repo_root}/models/Codeformer"]="${data_dir}/Codeformer" -path_map["${repo_root}/models/ControlNet"]="${data_dir}/ControlNet" -path_map["${repo_root}/models/GFPGAN"]="${data_dir}/GFPGAN" -path_map["${repo_root}/models/ESRGAN"]="${data_dir}/ESRGAN" -path_map["${repo_root}/models/BSRGAN"]="${data_dir}/BSRGAN" -path_map["${repo_root}/models/RealESRGAN"]="${data_dir}/RealESRGAN" -path_map["${repo_root}/models/SwinIR"]="${data_dir}/SwinIR" -path_map["${repo_root}/models/ScuNET"]="${data_dir}/ScuNET" -path_map["${repo_root}/models/LDSR"]="${data_dir}/LDSR" -path_map["${repo_root}/models/hypernetworks"]="${data_dir}/Hypernetworks" -path_map["${repo_root}/models/torch_deepdanbooru"]="${data_dir}/Deepdanbooru" -path_map["${repo_root}/models/BLIP"]="${data_dir}/BLIP" -path_map["${repo_root}/models/midas"]="${data_dir}/MiDaS" -path_map["${repo_root}/models/Lora"]="${data_dir}/Lora" -path_map["${repo_root}/models/LyCORIS"]="${data_dir}/Lora" -path_map["${repo_root}/models/openpose"]="${data_dir}/openpose" - -# extra hack for CodeFormer -path_map["${repo_root}/repositories/CodeFormer/weights/facelib"]="${data_dir}/.cache" - -# add pip cache path to path_map -if [[ -d ${HOME} ]]; then - echo "Using ${HOME}/.cache for pip cache" - path_map["${HOME}/.cache"]="${data_dir}/.cache" -else - echo "Warning: No home directory found, using /tmp/.cache for pip cache" - path_map["/tmp/.cache"]="${data_dir}/.cache" -fi - -# add other paths to path_map -path_map["${repo_root}/embeddings"]="${data_dir}/embeddings" - -if [[ "${SD_WEBUI_VARIANT}" == "vlad" ]]; then - echo "Running vladmandic webui variant" - config_dir="${data_dir}/config/vlad" - if [[ ! -d ${config_dir} ]]; then - echo "vlad config folder not found, creating..." - mkdir -p "${config_dir}" - if [[ -d "${data_dir}/config/auto" ]]; then - echo "Found existing AUTOMATIC1111 config, copying to vlad config" - cp -au "${data_dir}/config/auto" "${data_dir}/config/vlad" - echo "Purging extensions from vlad config (most are built-in and copying breaks them)" - rm -fr "${data_dir}/config/vlad/extensions" - fi - echo "Configuration ready." - fi -else - echo "Running AUTOMATIC1111 webui variant" - config_dir="${data_dir}/config/auto" -fi - -path_map["${repo_root}/extensions"]="${config_dir}/extensions" -path_map["${repo_root}/.vscode"]="${config_dir}/.vscode" -# scripts we can't symlink because of gradio security reasons -#path_map["${repo_root}/scripts"]="${config_dir}/auto/scripts" - -### Execution begins here ### - -# create path maps and symlink them -for tgt_path in "${!path_map[@]}"; do - echo -n "link ${tgt_path#"/${repo_root}"}" - # get source path and create it if it doesn't exist - src_path="${path_map[${tgt_path}]}" - [[ -d ${src_path} ]] || mkdir -vp "${src_path}" 2>&1 > /dev/null - - # ensure target parent directory exists - tgt_parent="$(dirname "${tgt_path}")" - [[ -d ${tgt_parent} ]] || mkdir -vp "${tgt_parent}" 2>&1 > /dev/null - - # clean out target directory and symlink it to source path - rm -rf "${tgt_path}" - ln -sT "${src_path}" "${tgt_path}" - echo " -> ${src_path} (directory)" -done - -# Map config and script files to their target locations -declare -A file_map -# add files to file_map -file_map["${repo_root}/config.json"]="${config_dir}/config.json" -file_map["${repo_root}/ui-config.json"]="${config_dir}/ui-config.json" -file_map["${repo_root}/user.css"]="${config_dir}/user.css" - -# copy default config.json if there isn't one -if [ ! -f "${config_dir}/config.json" ]; then - cp -n "/docker/config.json" "${config_dir}/config.json" -fi -# create empty ui-config.json if none provided -if [ ! -f "${config_dir}/ui-config.json" ]; then - echo '{}' > "${config_dir}/ui-config.json" -fi -# create empty user.css if none provided -if [ ! -f "${config_dir}/user.css" ]; then - echo '' > "${config_dir}/user.css" -fi - -# merge system config.json with default config.json -jq '. * input' "${config_dir}/config.json" "/docker/config.json" \ - | sponge "${config_dir}/config.json" - -# symlink files -for tgt_path in "${!file_map[@]}"; do - echo -n "link ${tgt_path#"/${repo_root}"}" - - # get source path - src_path="${file_map[${tgt_path}]}" - - # ensure target parent directory exists - tgt_parent="$(dirname "${tgt_path}")" - [[ -d ${tgt_parent} ]] || mkdir -vp "${tgt_parent}" 2>&1 > /dev/null - - # delete target if it exists and symlink it to source path - rm -rf "${tgt_path}" - ln -sT "${src_path}" "${tgt_path}" - echo " -> ${src_path} (file)" -done - -# Copy scripts individually to avoid purging the directory -echo 'Copying scripts (if present): ' -cp -vrfTs "${config_dir}"/scripts/*.py "${repo_root}/scripts/" || true - -# Set git config so it won't warn and confuse the webui -git config --system pull.rebase true -git config --system rebase.autostash true - -# Run startup script if it exists -if [ -f "${config_dir}/startup.sh" ]; then - pushd "${repo_root}" > /dev/null - echo "Running startup script..." - # shellcheck source=/dev/null - . "${config_dir}/startup.sh" - popd > /dev/null -fi - -exec "$@"