Skip to content

chore: support python 3.12, torch 2.6.0, clean up build/deps #7873

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 60 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
6c91650
upgrade pytorch and unpin some of the strict dependency pins to facil…
ebr Mar 24, 2025
0bd6f02
use uv.lock to pin dependencies
ebr Mar 24, 2025
6df5614
refactor Dockerfile; get rid of multi-stage build; upgrade to python …
ebr Mar 24, 2025
68845f4
update uv.lock
ebr Mar 25, 2025
04b0e65
update nodes schema / typegen
ebr Mar 26, 2025
f0a4d7a
modify docs for python 3.12
ebr Mar 26, 2025
d6ac822
remove obsoleted depenencies that were used by the CLI
ebr Mar 26, 2025
c28e685
reintroduce GPU_DRIVER build arg in CI container build, as it has app…
ebr Mar 26, 2025
aaf042d
resolve conflict between timm version needed by LLaVA and controlnet-aux
ebr Mar 26, 2025
31681f4
fix(app): add trusted classes to torch safe globals to prevent errors…
psychedelicious Mar 26, 2025
f28b054
tests: update tests/test_object_serializer_disk.py
psychedelicious Mar 26, 2025
a5966c3
chore(ui): typegen
psychedelicious Mar 26, 2025
bcd50ed
chore: remove pydantic pin
psychedelicious Mar 31, 2025
e6b366f
chore: typegen
psychedelicious Mar 31, 2025
5f3d398
fix(ui): handle updated schema structure during invocation parsing
psychedelicious Mar 31, 2025
cd873f1
chore: update `uv.lock` for latest pydantic
psychedelicious Mar 31, 2025
f6f33b5
chore: bump version to v5.10.0dev1
psychedelicious Apr 2, 2025
b97cc51
experiment: add pins.json to repo
psychedelicious Apr 2, 2025
402758d
ci: use py3.12 to build installer
psychedelicious Apr 2, 2025
9e70d8e
build: restore prev setuptools config to fix wheel build
psychedelicious Apr 2, 2025
5d3fb82
build: downgrade python to 3.11 in pins
psychedelicious Apr 3, 2025
f3402b6
chore: bump version to v5.10.0dev2
psychedelicious Apr 3, 2025
0a49463
fix(backend): remove mps_fixes
psychedelicious Apr 4, 2025
2cde86b
build: update uv.lock
psychedelicious Apr 4, 2025
06abc1d
build: upgrade python to 3.12 in pins
psychedelicious Apr 4, 2025
0a7cf6c
tidy(nodes): remove deprecated controlnet "processor" nodes
psychedelicious Apr 4, 2025
2cca339
tidy(nodes): remove unused old dw openpose detector class
psychedelicious Apr 4, 2025
13cc44a
tidy(nodes): rename `controlnet_image_processors.py` -> `controlnet.py`
psychedelicious Apr 4, 2025
eefbcd2
build: remove controlnet_aux dependency, remove pin for timm
psychedelicious Apr 4, 2025
5e14545
tidy: delete unused file
psychedelicious Apr 4, 2025
6cf88a6
build: remove unused albumentations dependency
psychedelicious Apr 4, 2025
30def6a
build: move humanize to test deps
psychedelicious Apr 4, 2025
c591478
tidy(nodes): remove matplotlib dependency
psychedelicious Apr 4, 2025
e990afb
build: remove unused matplotlib dep
psychedelicious Apr 4, 2025
380a41b
chore: update uv.lock
psychedelicious Apr 4, 2025
d8df31a
chore(ui): typegen
psychedelicious Apr 4, 2025
525a899
build: remove unused timm dependency
psychedelicious Apr 4, 2025
f14d079
build: remove unused facexlib dependency
psychedelicious Apr 4, 2025
b5be81b
build: remove unused omegaconf dependency
psychedelicious Apr 4, 2025
26cbecc
build: remove unused click dependency
psychedelicious Apr 4, 2025
19f0bf8
build: remove unused datasets dependency
psychedelicious Apr 4, 2025
8609b98
build: remove unused torchmetrics dependency
psychedelicious Apr 4, 2025
fe88012
build: remove unused npyscreen dependency
psychedelicious Apr 4, 2025
6ce5277
build: remove unused scikit-image dependency
psychedelicious Apr 4, 2025
5aa08ab
build: remove unused pympler dependency
psychedelicious Apr 4, 2025
1253ad5
build: remove unused pyperclip dependency
psychedelicious Apr 4, 2025
5967d4e
build: remove unused pyreadline3 dependency
psychedelicious Apr 4, 2025
77f2249
build: remove unused pytorch-lightning dependency
psychedelicious Apr 4, 2025
a34383d
build: remove unused clip_anytorch dependency
psychedelicious Apr 4, 2025
2756c53
build: remove pin on gguf dependency
psychedelicious Apr 4, 2025
6c36b05
build: add comment about torchsde to pyproject
psychedelicious Apr 4, 2025
b3b3dbd
build: remove pin on spandrel dependency
psychedelicious Apr 4, 2025
4610b55
chore: update uv.lock
psychedelicious Apr 4, 2025
3e200a2
chore: bump version to v5.10.0dev3
psychedelicious Apr 4, 2025
12ca9df
build: remove installer & convert installer build script to only buil…
psychedelicious Apr 4, 2025
db57204
ci: update workflows to use revised build scripts
psychedelicious Apr 4, 2025
fcde1d8
chore: bump version to v5.10.0dev4
psychedelicious Apr 4, 2025
49db3d8
ci: fix name of build hweel workflow
psychedelicious Apr 4, 2025
8a0ae8c
build: fix path in build script
psychedelicious Apr 4, 2025
3127959
docs: update README.md
psychedelicious Apr 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
*
!invokeai
!pyproject.toml
!uv.lock
!docker/docker-entrypoint.sh
!LICENSE

**/dist
**/node_modules
**/__pycache__
**/*.egg-info
**/*.egg-info
2 changes: 2 additions & 0 deletions .github/workflows/build-container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ jobs:
context: .
file: docker/Dockerfile
platforms: ${{ env.PLATFORMS }}
build-args: |
GPU_DRIVER=${{ matrix.gpu-driver }}
push: ${{ github.ref == 'refs/heads/main' || github.ref_type == 'tag' || github.event.inputs.push-to-registry }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Builds and uploads the installer and python build artifacts.
# Builds and uploads python build artifacts.

name: build installer
name: build wheel

on:
workflow_dispatch:
Expand All @@ -17,7 +17,7 @@ jobs:
- name: setup python
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.12'
cache: pip
cache-dependency-path: pyproject.toml

Expand All @@ -27,19 +27,12 @@ jobs:
- name: setup frontend
uses: ./.github/actions/install-frontend-deps

- name: create installer
id: create_installer
run: ./create_installer.sh
working-directory: installer
- name: build wheel
id: build_wheel
run: ./scripts/build_wheel.sh

- name: upload python distribution artifact
uses: actions/upload-artifact@v4
with:
name: dist
path: ${{ steps.create_installer.outputs.DIST_PATH }}

- name: upload installer artifact
uses: actions/upload-artifact@v4
with:
name: installer
path: ${{ steps.create_installer.outputs.INSTALLER_PATH }}
path: ${{ steps.build_wheel.outputs.DIST_PATH }}
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
always_run: true

build:
uses: ./.github/workflows/build-installer.yml
uses: ./.github/workflows/build-wheel.yml

publish-testpypi:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.12.0
v22.14.0
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ help:
@echo "frontend-build Build the frontend in order to run on localhost:9090"
@echo "frontend-dev Run the frontend in developer mode on localhost:5173"
@echo "frontend-typegen Generate types for the frontend from the OpenAPI schema"
@echo "installer-zip Build the installer .zip file for the current version"
@echo "wheel Build the wheel for the current version"
@echo "tag-release Tag the GitHub repository with the current version (use at release time only!)"
@echo "openapi Generate the OpenAPI schema for the app, outputting to stdout"
@echo "docs Serve the mkdocs site with live reload"
Expand Down Expand Up @@ -64,13 +64,13 @@ frontend-dev:
frontend-typegen:
cd invokeai/frontend/web && python ../../../scripts/generate_openapi_schema.py | pnpm typegen

# Installer zip file
installer-zip:
cd installer && ./create_installer.sh
# Tag the release
wheel:
cd scripts && ./build_wheel.sh

# Tag the release
tag-release:
cd installer && ./tag_release.sh
cd scripts && ./tag_release.sh

# Generate the OpenAPI Schema for the app
openapi:
Expand Down
189 changes: 69 additions & 120 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,77 +1,6 @@
# syntax=docker/dockerfile:1.4

## Builder stage

FROM library/ubuntu:24.04 AS builder

ARG DEBIAN_FRONTEND=noninteractive
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt update && apt-get install -y \
build-essential \
git

# Install `uv` for package management
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
# 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} && \
chmod -R a+w /opt && \
mkdir ~ubuntu/.cache && chown ubuntu: ~ubuntu/.cache
USER ubuntu

# Install python
RUN --mount=type=cache,target=/home/ubuntu/.cache/uv,uid=1000,gid=1000 \
uv python install ${PYTHON_VERSION}

WORKDIR ${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/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 \
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 \
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


#### Build the Web UI ------------------------------------
#### Web UI ------------------------------------

FROM docker.io/node:22-slim AS web-builder
ENV PNPM_HOME="/pnpm"
Expand All @@ -85,69 +14,89 @@ RUN --mount=type=cache,target=/pnpm/store \
pnpm install --frozen-lockfile
RUN npx vite build

#### Runtime stage ---------------------------------------
## Backend ---------------------------------------

FROM library/ubuntu:24.04 AS runtime
FROM library/ubuntu:24.04

ARG DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

RUN apt update && apt install -y --no-install-recommends \
git \
curl \
vim \
tmux \
ncdu \
iotop \
bzip2 \
gosu \
magic-wormhole \
libglib2.0-0 \
libgl1 \
libglx-mesa0 \
build-essential \
libopencv-dev \
libstdc++-10-dev &&\
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="$VIRTUAL_ENV/bin:$INVOKEAI_SRC:$PATH"
ENV CONTAINER_UID=${CONTAINER_UID:-1000}
ENV CONTAINER_GID=${CONTAINER_GID:-1000}
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
RUN --mount=type=cache,target=/var/cache/apt \
--mount=type=cache,target=/var/lib/apt \
apt update && apt install -y --no-install-recommends \
ca-certificates \
git \
gosu \
libglib2.0-0 \
libgl1 \
libglx-mesa0 \
build-essential \
libopencv-dev \
libstdc++-10-dev

ENV \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
VIRTUAL_ENV=/opt/venv \
INVOKEAI_SRC=/opt/invokeai \
PYTHON_VERSION=3.12 \
UV_PYTHON=3.12 \
UV_COMPILE_BYTECODE=1 \
UV_MANAGED_PYTHON=1 \
UV_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=/opt/venv \
UV_INDEX="https://download.pytorch.org/whl/cu124" \
INVOKEAI_ROOT=/invokeai \
INVOKEAI_HOST=0.0.0.0 \
INVOKEAI_PORT=9090 \
PATH="/opt/venv/bin:$PATH" \
CONTAINER_UID=${CONTAINER_UID:-1000} \
CONTAINER_GID=${CONTAINER_GID:-1000}

ARG GPU_DRIVER=cuda

# 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.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
COPY --from=ghcr.io/astral-sh/uv:0.6.9 /uv /uvx /bin/

# Link amdgpu.ids for ROCm builds
# contributed by https://github.com/Rubonnek
RUN mkdir -p "/opt/amdgpu/share/libdrm" &&\
ln -s "/usr/share/libdrm/amdgpu.ids" "/opt/amdgpu/share/libdrm/amdgpu.ids"
# Install python & allow non-root user to use it by traversing the /root dir without read permissions
RUN --mount=type=cache,target=/root/.cache/uv \
uv python install ${PYTHON_VERSION} && \
# chmod --recursive a+rX /root/.local/share/uv/python
chmod 711 /root

WORKDIR ${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=/root/.cache/uv \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
--mount=type=bind,source=uv.lock,target=uv.lock \
# this is just to get the package manager to recognize that the project exists, without making changes to the docker layer
--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 UV_INDEX="https://download.pytorch.org/whl/rocm6.2"; \
fi && \
uv sync --frozen

# build patchmatch
RUN cd /usr/lib/$(uname -p)-linux-gnu/pkgconfig/ && ln -sf opencv4.pc opencv.pc
RUN python -c "from patchmatch import patch_match"

# Link amdgpu.ids for ROCm builds
# contributed by https://github.com/Rubonnek
RUN mkdir -p "/opt/amdgpu/share/libdrm" &&\
ln -s "/usr/share/libdrm/amdgpu.ids" "/opt/amdgpu/share/libdrm/amdgpu.ids"

RUN mkdir -p ${INVOKEAI_ROOT} && chown -R ${CONTAINER_UID}:${CONTAINER_GID} ${INVOKEAI_ROOT}

COPY docker/docker-entrypoint.sh ./
ENTRYPOINT ["/opt/invokeai/docker-entrypoint.sh"]
CMD ["invokeai-web"]

# --link requires buldkit w/ dockerfile syntax 1.4, does not work with podman
COPY --link --from=web-builder /build/dist ${INVOKEAI_SRC}/invokeai/frontend/web/dist

# add sources last to minimize image changes on code changes
COPY invokeai ${INVOKEAI_SRC}/invokeai
13 changes: 4 additions & 9 deletions docs/RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,11 @@ Next, these jobs run and must pass. They are the same jobs that are run for ever
- **`frontend-checks`**: runs `prettier` (format), `eslint` (lint), `dpdm` (circular refs), `tsc` (static type check) and `knip` (unused imports)
- **`typegen-checks`**: ensures the frontend and backend types are synced

#### `build-installer` Job
#### `build-wheel` Job

This sets up both python and frontend dependencies and builds the python package. Internally, this runs `installer/create_installer.sh` and uploads two artifacts:
This sets up both python and frontend dependencies and builds the python package. Internally, this runs `./scripts/build_wheel.sh` and uploads `dist.zip`, which contains the wheel and unarchived build.

- **`dist`**: the python distribution, to be published on PyPI
- **`InvokeAI-installer-${VERSION}.zip`**: the legacy install scripts

You don't need to download either of these files.

> The legacy install scripts are no longer used, but we haven't updated the workflow to skip building them.
You don't need to download or test these artifacts.

#### Sanity Check & Smoke Test

Expand All @@ -79,7 +74,7 @@ It's possible to test the python package before it gets published to PyPI. We've

But, if you want to be extra-super careful, here's how to test it:

- Download the `dist.zip` build artifact from the `build-installer` job
- Download the `dist.zip` build artifact from the `build-wheel` job
- Unzip it and find the wheel file
- Create a fresh Invoke install by following the [manual install guide](https://invoke-ai.github.io/InvokeAI/installation/manual/) - but instead of installing from PyPI, install from the wheel
- Test the app
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing/dev-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ If you just want to use Invoke, you should use the [launcher][launcher link].
With the modifications made, the install command should look something like this:

```sh
uv pip install -e ".[dev,test,docs,xformers]" --python 3.11 --python-preference only-managed --index=https://download.pytorch.org/whl/cu124 --reinstall
uv pip install -e ".[dev,test,docs,xformers]" --python 3.12 --python-preference only-managed --index=https://download.pytorch.org/whl/cu124 --reinstall
```

6. At this point, you should have Invoke installed, a venv set up and activated, and the server running. But you will see a warning in the terminal that no UI was found. If you go to the URL for the server, you won't get a UI.
Expand Down
8 changes: 4 additions & 4 deletions docs/installation/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ The following commands vary depending on the version of Invoke being installed a
3. Create a virtual environment in that directory:

```sh
uv venv --relocatable --prompt invoke --python 3.11 --python-preference only-managed .venv
uv venv --relocatable --prompt invoke --python 3.12 --python-preference only-managed .venv
```

This command creates a portable virtual environment at `.venv` complete with a portable python 3.11. It doesn't matter if your system has no python installed, or has a different version - `uv` will handle everything.
This command creates a portable virtual environment at `.venv` complete with a portable python 3.12. It doesn't matter if your system has no python installed, or has a different version - `uv` will handle everything.

4. Activate the virtual environment:

Expand Down Expand Up @@ -88,13 +88,13 @@ The following commands vary depending on the version of Invoke being installed a
8. Install the `invokeai` package. Substitute the package specifier and version.

```sh
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.11 --python-preference only-managed --force-reinstall
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.12 --python-preference only-managed --force-reinstall
```

If you determined you needed to use a `PyPI` index URL in the previous step, you'll need to add `--index=<INDEX_URL>` like this:

```sh
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.11 --python-preference only-managed --index=<INDEX_URL> --force-reinstall
uv pip install <PACKAGE_SPECIFIER>==<VERSION> --python 3.12 --python-preference only-managed --index=<INDEX_URL> --force-reinstall
```

9. Deactivate and reactivate your venv so that the invokeai-specific commands become available in the environment:
Expand Down
Loading
Loading