From 3848e1926bb3dcdf4ced15676b58066e50c67283 Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Sat, 18 Jan 2025 09:10:54 -0800 Subject: [PATCH 1/3] chore(docker): reduce size between docker builds by adding a layer with all the pytorch dependencies that don't change most of the time. --- docker/Dockerfile | 56 +++++++++++++++++++++++++++-------------------- pyproject.toml | 3 +-- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 657cf1d30db..60d2095a7da 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -13,52 +13,62 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ git # Install `uv` for package management -COPY --from=ghcr.io/astral-sh/uv:0.5.5 /uv /uvx /bin/ +COPY --from=ghcr.io/astral-sh/uv:0.5.21 /uv /uvx /bin/ -ENV VIRTUAL_ENV=/opt/venv -ENV PATH="$VIRTUAL_ENV/bin:$PATH" ENV INVOKEAI_SRC=/opt/invokeai ENV PYTHON_VERSION=3.11 +ENV UV_PYTHON=3.11 ENV UV_COMPILE_BYTECODE=1 ENV UV_LINK_MODE=copy +ENV UV_INDEX="https://download.pytorch.org/whl/cu124" ARG GPU_DRIVER=cuda -ARG TARGETPLATFORM="linux/amd64" # unused but available ARG BUILDPLATFORM # Switch to the `ubuntu` user to work around dependency issues with uv-installed python -RUN mkdir -p ${VIRTUAL_ENV} && \ - mkdir -p ${INVOKEAI_SRC} && \ +RUN mkdir -p ${INVOKEAI_SRC} && \ chmod -R a+w /opt USER ubuntu -# Install python and create the venv -RUN uv python install ${PYTHON_VERSION} && \ - uv venv --relocatable --prompt "invoke" --python ${PYTHON_VERSION} ${VIRTUAL_ENV} +# Install python +RUN --mount=type=cache,target=/home/ubuntu/.cache/uv,uid=1000,gid=1000 \ + uv python install ${PYTHON_VERSION} WORKDIR ${INVOKEAI_SRC} -COPY invokeai ./invokeai -COPY pyproject.toml ./ -# Editable mode helps use the same image for development: -# the local working copy can be bind-mounted into the image -# at path defined by ${INVOKEAI_SRC} +# Install project's dependencies as a separate layer so they aren't rebuilt every commit. +# bind-mount instead of copy to defer adding sources to the image until next layer. +# # NOTE: there are no pytorch builds for arm64 + cuda, only cpu # x86_64/CUDA is the default RUN --mount=type=cache,target=/home/ubuntu/.cache/uv,uid=1000,gid=1000 \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ + --mount=type=bind,source=invokeai,target=invokeai \ + if [ "$TARGETPLATFORM" = "linux/arm64" ] || [ "$GPU_DRIVER" = "cpu" ]; then \ + UV_INDEX="https://download.pytorch.org/whl/cpu"; \ + elif [ "$GPU_DRIVER" = "rocm" ]; then \ + UV_INDEX="https://download.pytorch.org/whl/rocm6.1"; \ + fi && \ + uv sync --no-install-project + +# Now that the bulk of the dependencies have been installed, copy in the project files that change more frequently. +COPY invokeai invokeai +COPY pyproject.toml . + +RUN --mount=type=cache,target=/home/ubuntu/.cache/uv,uid=1000,gid=1000 \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ if [ "$TARGETPLATFORM" = "linux/arm64" ] || [ "$GPU_DRIVER" = "cpu" ]; then \ - extra_index_url_arg="--extra-index-url https://download.pytorch.org/whl/cpu"; \ + UV_INDEX="https://download.pytorch.org/whl/cpu"; \ elif [ "$GPU_DRIVER" = "rocm" ]; then \ - extra_index_url_arg="--extra-index-url https://download.pytorch.org/whl/rocm6.1"; \ - else \ - extra_index_url_arg="--extra-index-url https://download.pytorch.org/whl/cu124"; \ + UV_INDEX="https://download.pytorch.org/whl/rocm6.1"; \ fi && \ - uv pip install --python ${PYTHON_VERSION} $extra_index_url_arg -e "." + uv sync + #### Build the Web UI ------------------------------------ -FROM node:20-slim AS web-builder +FROM docker.io/node:20-slim AS web-builder ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack use pnpm@8.x @@ -97,26 +107,24 @@ RUN apt update && apt install -y --no-install-recommends \ apt-get clean && apt-get autoclean ENV INVOKEAI_SRC=/opt/invokeai -ENV VIRTUAL_ENV=/opt/venv ENV PYTHON_VERSION=3.11 ENV INVOKEAI_ROOT=/invokeai ENV INVOKEAI_HOST=0.0.0.0 ENV INVOKEAI_PORT=9090 -ENV PATH="$VIRTUAL_ENV/bin:$INVOKEAI_SRC:$PATH" +ENV PATH="$INVOKEAI_SRC/.venv/bin:$INVOKEAI_SRC:$PATH" ENV CONTAINER_UID=${CONTAINER_UID:-1000} ENV CONTAINER_GID=${CONTAINER_GID:-1000} # Install `uv` for package management # and install python for the ubuntu user (expected to exist on ubuntu >=24.x) # this is too tiny to optimize with multi-stage builds, but maybe we'll come back to it -COPY --from=ghcr.io/astral-sh/uv:0.5.5 /uv /uvx /bin/ +COPY --from=ghcr.io/astral-sh/uv:0.5.21 /uv /uvx /bin/ USER ubuntu RUN uv python install ${PYTHON_VERSION} USER root # --link requires buldkit w/ dockerfile syntax 1.4 COPY --link --from=builder ${INVOKEAI_SRC} ${INVOKEAI_SRC} -COPY --link --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} COPY --link --from=web-builder /build/dist ${INVOKEAI_SRC}/invokeai/frontend/web/dist # Link amdgpu.ids for ROCm builds diff --git a/pyproject.toml b/pyproject.toml index 1a989e93f17..cc86a7e5ff7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,8 +101,7 @@ dependencies = [ "xformers" = [ # Core generation dependencies, pinned for reproducible builds. "xformers>=0.0.28.post1; sys_platform!='darwin'", - # Auxiliary dependencies, pinned only if necessary. - "triton; sys_platform=='linux'", + # torch 2.4+cu carries its own triton dependency ] "onnx" = ["onnxruntime"] "onnx-cuda" = ["onnxruntime-gpu"] From 22362350dc2a7e93167a8f920164cb7288ae089b Mon Sep 17 00:00:00 2001 From: Kevin Turner <566360-keturn@users.noreply.gitlab.com> Date: Sun, 16 Feb 2025 11:26:06 -0800 Subject: [PATCH 2/3] chore(docker): revert to keeping venv in /opt/venv --- docker/Dockerfile | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index a88688bb584..12f2c09a0fc 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -13,13 +13,16 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ git # Install `uv` for package management -COPY --from=ghcr.io/astral-sh/uv:0.5.21 /uv /uvx /bin/ +COPY --from=ghcr.io/astral-sh/uv:0.6.0 /uv /uvx /bin/ +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:$PATH" ENV INVOKEAI_SRC=/opt/invokeai ENV PYTHON_VERSION=3.11 ENV UV_PYTHON=3.11 ENV UV_COMPILE_BYTECODE=1 ENV UV_LINK_MODE=copy +ENV UV_PROJECT_ENVIRONMENT="$VIRTUAL_ENV" ENV UV_INDEX="https://download.pytorch.org/whl/cu124" ARG GPU_DRIVER=cuda @@ -27,8 +30,10 @@ ARG GPU_DRIVER=cuda ARG BUILDPLATFORM # Switch to the `ubuntu` user to work around dependency issues with uv-installed python -RUN mkdir -p ${INVOKEAI_SRC} && \ - chmod -R a+w /opt +RUN mkdir -p ${VIRTUAL_ENV} && \ + mkdir -p ${INVOKEAI_SRC} && \ + chmod -R a+w /opt && \ + mkdir ~ubuntu/.cache && chown ubuntu: ~ubuntu/.cache USER ubuntu # Install python @@ -107,24 +112,27 @@ RUN apt update && apt install -y --no-install-recommends \ apt-get clean && apt-get autoclean ENV INVOKEAI_SRC=/opt/invokeai +ENV VIRTUAL_ENV=/opt/venv +ENV UV_PROJECT_ENVIRONMENT="$VIRTUAL_ENV" ENV PYTHON_VERSION=3.11 ENV INVOKEAI_ROOT=/invokeai ENV INVOKEAI_HOST=0.0.0.0 ENV INVOKEAI_PORT=9090 -ENV PATH="$INVOKEAI_SRC/.venv/bin:$INVOKEAI_SRC:$PATH" +ENV PATH="$VIRTUAL_ENV/bin:$INVOKEAI_SRC:$PATH" ENV CONTAINER_UID=${CONTAINER_UID:-1000} ENV CONTAINER_GID=${CONTAINER_GID:-1000} # Install `uv` for package management # and install python for the ubuntu user (expected to exist on ubuntu >=24.x) # this is too tiny to optimize with multi-stage builds, but maybe we'll come back to it -COPY --from=ghcr.io/astral-sh/uv:0.5.21 /uv /uvx /bin/ +COPY --from=ghcr.io/astral-sh/uv:0.6.0 /uv /uvx /bin/ USER ubuntu RUN uv python install ${PYTHON_VERSION} USER root # --link requires buldkit w/ dockerfile syntax 1.4 COPY --link --from=builder ${INVOKEAI_SRC} ${INVOKEAI_SRC} +COPY --link --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV} COPY --link --from=web-builder /build/dist ${INVOKEAI_SRC}/invokeai/frontend/web/dist # Link amdgpu.ids for ROCm builds From 80d38c0e477e40dd1d6e6fc603914eb911bf93f3 Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Sun, 16 Feb 2025 12:31:14 -0800 Subject: [PATCH 3/3] chore(docker): include fewer files while installing dependencies including just invokeai/version seems sufficient to appease uv sync here. including everything else would invalidate the cache we're trying to establish. --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 12f2c09a0fc..bd10db84177 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -49,7 +49,7 @@ WORKDIR ${INVOKEAI_SRC} # x86_64/CUDA is the default RUN --mount=type=cache,target=/home/ubuntu/.cache/uv,uid=1000,gid=1000 \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ - --mount=type=bind,source=invokeai,target=invokeai \ + --mount=type=bind,source=invokeai/version,target=invokeai/version \ if [ "$TARGETPLATFORM" = "linux/arm64" ] || [ "$GPU_DRIVER" = "cpu" ]; then \ UV_INDEX="https://download.pytorch.org/whl/cpu"; \ elif [ "$GPU_DRIVER" = "rocm" ]; then \