Skip to content

Commit d8ab8be

Browse files
authored
Merge branch 'main' into lstein/fix/multigpu-shared-weights-collect
2 parents 46e660c + 7b82f29 commit d8ab8be

192 files changed

Lines changed: 26210 additions & 2251 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-container.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ jobs:
110110
build-args: |
111111
GPU_DRIVER=${{ matrix.gpu-driver }}
112112
push: ${{ github.ref == 'refs/heads/main' || github.ref_type == 'tag' || github.event.inputs.push-to-registry }}
113+
provenance: mode=max
114+
sbom: true
113115
tags: ${{ steps.meta.outputs.tags }}
114116
labels: ${{ steps.meta.outputs.labels }}
115117
# cache-from: |

.github/workflows/python-tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ jobs:
8383
- 'invokeai/**'
8484
- '!invokeai/frontend/web/**'
8585
- 'tests/**'
86+
# tests/ covers a few of these (e.g. test_check_pins.py, test_docs_json_export.py)
87+
- 'scripts/**'
88+
- 'pins.json'
8689
8790
- name: setup uv
8891
if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}

.github/workflows/uv-lock-checks.yml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
# Check the `uv` lockfile for consistency with `pyproject.toml`.
1+
# Check the `uv` lockfile and `pins.json` for consistency with `pyproject.toml`.
22
#
3-
# If this check fails, you should run `uv lock` to update the lockfile.
3+
# If the lockfile check fails, you should run `uv lock` to update the lockfile.
4+
# If the pins check fails, update the torch index URLs in `pins.json` to match
5+
# the `[[tool.uv.index]]` entries in `pyproject.toml` (see scripts/check_pins.py).
6+
#
7+
# Also checks that the lockfile keeps working for linux/aarch64, which no test job covers.
8+
# This reads the lockfile only - no ARM hardware or extra resolution needed.
49

510
name: 'uv lock checks'
611

@@ -54,9 +59,13 @@ jobs:
5459
uvlock-pyprojecttoml:
5560
- 'pyproject.toml'
5661
- 'uv.lock'
62+
- 'pins.json'
63+
- 'scripts/check_pins.py'
64+
aarch64check:
65+
- 'scripts/check_aarch64_lock.py'
5766
5867
- name: setup uv
59-
if: ${{ steps.changed-files.outputs.uvlock-pyprojecttoml_any_changed == 'true' || inputs.always_run == true }}
68+
if: ${{ steps.changed-files.outputs.uvlock-pyprojecttoml_any_changed == 'true' || steps.changed-files.outputs.aarch64check_any_changed == 'true' || inputs.always_run == true }}
6069
uses: astral-sh/setup-uv@v8.1.0
6170
with:
6271
version: '0.6.10'
@@ -66,3 +75,20 @@ jobs:
6675
if: ${{ steps.changed-files.outputs.uvlock-pyprojecttoml_any_changed == 'true' || inputs.always_run == true }}
6776
run: uv lock --locked # this will exit with 1 if the lockfile is not consistent with pyproject.toml
6877
shell: bash
78+
79+
- name: check pins.json
80+
if: ${{ steps.changed-files.outputs.uvlock-pyprojecttoml_any_changed == 'true' || inputs.always_run == true }}
81+
run: python3 scripts/check_pins.py # pins.json is consumed by the launcher; keep its torch index URLs in sync with pyproject.toml
82+
shell: bash
83+
84+
- name: check aarch64 support in lockfile
85+
# Also runs when the check itself changes, so edits to it are exercised.
86+
if: ${{ steps.changed-files.outputs.uvlock-pyprojecttoml_any_changed == 'true' || steps.changed-files.outputs.aarch64check_any_changed == 'true' || inputs.always_run == true }}
87+
# On linux/aarch64 torch and torchvision must resolve from PyPI rather than from the PyTorch WHL
88+
# indexes, which have no aarch64 torchvision wheel. Several things in pyproject.toml have to hold
89+
# for that, and breaking most of them leaves a lockfile with no torch at all on aarch64 while
90+
# `uv lock --locked` above still passes. See the script's docstring.
91+
# `--no-project` keeps `uv run` from syncing the whole project just to run this. `packaging` is
92+
# capped so a future release tightening wheel-filename parsing can't change the verdict on its own.
93+
run: uv run --no-project --with 'packaging<26' --python 3.12 scripts/check_aarch64_lock.py ./uv.lock
94+
shell: bash

LICENSE-HiDiffusion.txt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
HiDiffusion - License notice
2+
3+
Original project: https://github.com/megvii-research/HiDiffusion
4+
Vendored from: https://github.com/monofy-org/HiDiffusion
5+
Vendored under: invokeai/backend/hidiffusion/
6+
7+
================================================================================
8+
CODE (Apache License 2.0)
9+
================================================================================
10+
11+
The vendored HiDiffusion source code is licensed under the Apache License,
12+
Version 2.0. The Apache 2.0 license text is available in the root LICENSE file
13+
and at:
14+
15+
https://www.apache.org/licenses/LICENSE-2.0
16+
17+
================================================================================
18+
MODULE KEYS (BSD 3-Clause License)
19+
================================================================================
20+
21+
The SD 1.5 and SDXL module-key lists under
22+
invokeai/backend/hidiffusion/sd_module_key/ were sourced from dgenerate at:
23+
24+
https://github.com/Teriks/dgenerate/tree/d83b839033cc22c5101fb0f987bd4eb2de3d5d12/dgenerate/extras/hidiffusion/sd_module_key
25+
26+
BSD 3-Clause License
27+
28+
Copyright (c) 2023, Teriks
29+
30+
Redistribution and use in source and binary forms, with or without
31+
modification, are permitted provided that the following conditions are met:
32+
33+
1. Redistributions of source code must retain the above copyright notice, this
34+
list of conditions and the following disclaimer.
35+
36+
2. Redistributions in binary form must reproduce the above copyright notice,
37+
this list of conditions and the following disclaimer in the documentation
38+
and/or other materials provided with the distribution.
39+
40+
3. Neither the name of the copyright holder nor the names of its
41+
contributors may be used to endorse or promote products derived from
42+
this software without specific prior written permission.
43+
44+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
45+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
48+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54+
55+
================================================================================
56+
LOCAL MODIFICATIONS
57+
================================================================================
58+
59+
The following changes were applied when integrating HiDiffusion into InvokeAI:
60+
61+
* The code was vendored under the invokeai.backend.hidiffusion package.
62+
* apply_hidiffusion() was extended to accept a torch.Generator, enabling
63+
deterministic image generation from a seed.
64+
* HiDiffusion patching was integrated with InvokeAI's model loading and
65+
generation lifecycle.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Invoke features an organized gallery system for easily storing, accessing, and r
6868
- Flux.1 Krea
6969
- Flux Redux
7070
- Flux Fill
71+
- Flux.2 Dev
7172
- Flux.2 Klein 4B
7273
- Flux.2 Klein 9B
7374
- Z-Image Turbo
@@ -121,6 +122,7 @@ We very much thank the following sponsors:
121122
### Power Users ($50/mo)
122123

123124
* [mickr777](https://github.com/mickr777)
125+
* [Astroburner](https://github.com/Astroburner)
124126

125127
## Thanks
126128

docs/src/content/docs/development/Guides/creating-nodes.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Because the whole node is moved to another device, only mark a node `idle_gpu_of
4949
- **It is encoder-only.** Its sole GPU work is loading one or more encoder models and running their forward pass. It must not load or run the denoise/transformer or VAE, or do any other work tied to the session's own GPU.
5050
- **It stores its result on the CPU before returning.** Move output tensors to the CPU (`tensor.detach().to("cpu")`) and save them as conditioning/tensors. The denoiser picks them up and moves them onto its own GPU later — this is what makes the cross-GPU handoff safe and device-agnostic.
5151
- **It places inputs on the loaded model's device, not a fixed device.** Resolve the device from the model you just loaded (e.g. `get_effective_device(model)` from `invokeai.backend.model_manager.load.model_cache.utils`, or `TorchDevice.choose_torch_device()`), rather than hard-coding `cuda:0`. The built-in `flux_text_encoder` and `compel` nodes are good references.
52+
- **Its runtime is dominated by that forward pass.** The borrow holds the lent GPU's lock for the whole node, and a session dequeued onto that GPU blocks until it is released. Model caches are per-device, so the first borrow of a GPU cold-loads the encoder there — that cost is paid once and then amortizes across later borrows, which hit the cache. Work that recurs on *every* execution does not amortize, so a node that runs something open-ended per call (an autoregressive `generate()` loop, say) will stall the lent GPU again on every generation. If your node has both kinds of work, split them: `ernie_image_prompt_enhancer` was carved out of `ernie_image_text_encoder` for exactly this reason, leaving the encoder offloadable and keeping the enhancer's `generate()` on the session's own GPU.
5253

5354
:::caution[Only mark encoder-only nodes]
5455
If a node that also runs the denoiser, VAE, or other session-GPU work is marked `idle_gpu_offloadable=True`, that work will be re-pinned to the wrong GPU and can misplace tensors or raise device-mismatch errors. When in doubt, leave it unset (the default is `False`) — the node will still work correctly, just without the offload optimization.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
title: Generation Bounding Box
3+
description: Learn how the bounding box defines the Canvas generation area and the image context sent to the model.
4+
lastUpdated: 2026-08-02
5+
sidebar:
6+
order: 0
7+
---
8+
9+
The **generation bounding box** is the rectangle that defines where a Canvas generation takes place. It controls both
10+
the area returned by the model and the portion of the Canvas used as image context for that generation.
11+
12+
## What the Model Sees
13+
14+
When you click **Invoke**, the visible Canvas content inside the bounding box is composited and sent through the
15+
generation pipeline. Content outside the box is not included in that Canvas image input, even though it remains visible
16+
to you on the larger Canvas.
17+
18+
This makes placement important. If the model needs to continue a shape, match a texture, or preserve part of a subject,
19+
include enough of that content inside the bounding box to give the model useful context. Moving the box changes which
20+
part of the image the model can use for the next generation.
21+
22+
:::note
23+
The bounding box defines the generation area; it is not an inpaint mask. Use an **Inpaint Mask** when only selected
24+
parts inside the box should be regenerated.
25+
:::
26+
27+
## Move and Resize the Bounding Box
28+
29+
Select the **Bounding Box** tool in the Canvas toolbar. You can then:
30+
31+
- Drag inside the box to move it.
32+
- Drag its handles to resize it.
33+
- Use the aspect-ratio lock when you need to preserve its current proportions.
34+
35+
The bounding box dimensions determine the generated image's width and height. Invoke constrains these dimensions to
36+
values supported by the selected model.
37+
38+
:::tip[Tap & Hold C]
39+
Tap <kbd>C</kbd> to keep the **Bounding Box** tool selected. Hold <kbd>C</kbd> to use it temporarily, then release the
40+
key to return to your previous tool. The shortcut can be changed in the **Hotkeys** settings.
41+
:::
42+
43+
## Bounding Box Size and Processing Size
44+
45+
The bounding box is the final footprint of the generation on the Canvas. If **Scale Before Processing** is enabled,
46+
Invoke may process that area at a different resolution and then resize the result back to the bounding box dimensions.
47+
48+
For best results, choose a box large enough to include the visual context the model needs, while keeping its dimensions
49+
appropriate for the selected model and your available VRAM.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
title: HiDiffusion
3+
---
4+
5+
# HiDiffusion
6+
7+
HiDiffusion is an optional denoising enhancement that can improve detail and structure at higher resolutions for SD 1.5, SD 2.1, and SDXL. It modifies the UNet during denoising and is most noticeable at 1536px and above.
8+
9+
The vendored implementation includes module-key definitions for SD 1.5 and SDXL. SD 2.1 intentionally reuses the SD 1.5 module-key mapping.
10+
11+
Learn more: https://github.com/megvii-research/HiDiffusion
12+
13+
## Where to find the switches
14+
15+
1. Open the **Canvas** tab.
16+
2. Expand **Advanced Settings**.
17+
3. In the **Advanced** grid, enable **HiDiffusion** and optionally adjust the two sub‑toggles and ratios:
18+
- **HiDiffusion: RAU‑Net**
19+
- **HiDiffusion: Window Attention**
20+
- **HiDiffusion: T1 Ratio**
21+
- **HiDiffusion: T2 Ratio**
22+
23+
## What the switches do
24+
25+
- **HiDiffusion**: Enables the HiDiffusion patch for denoising. Use this for high‑resolution generations; the effect is subtle at lower sizes.
26+
27+
- **HiDiffusion: RAU‑Net**: Enables RAU‑Net blocks. This typically improves structure and mid‑frequency detail, especially at larger resolutions.
28+
29+
- **HiDiffusion: Window Attention**: Enables windowed attention blocks. This can boost local texture/detail, but may slightly affect global coherence in some prompts.
30+
31+
- **HiDiffusion: T1 Ratio**: Controls when HiDiffusion switches into its mid‑stage behavior. Lower values switch earlier; higher values preserve global structure longer.
32+
33+
- **HiDiffusion: T2 Ratio**: Controls when HiDiffusion switches into its late‑stage behavior. Higher values keep window attention active longer and can sharpen local detail.
34+
35+
## Tips
36+
37+
- Try **1536–2048 px** for the clearest benefits (SDXL).
38+
- If results look worse, disable **Window Attention** first, then RAU‑Net.
39+
- Effects vary by scheduler and model; compare with the same seed for a fair test.

docs/src/content/docs/features/krea-2.mdx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,32 @@ transform the text conditioning and are especially useful for the distilled Turb
6464
prompt adherence for variety.
6565

6666
Both are recorded in image metadata and can be recalled.
67+
When enabled on the canvas, the same enhancer chain is applied independently to the global prompt and
68+
each positive regional prompt before their conditionings are collected.
6769

6870
## Multiple conditionings
6971

7072
In the workflow editor, the **Denoise - Krea-2** node accepts one conditioning or a collection for both
7173
its positive and negative conditioning inputs. Multiple independently encoded conditionings are concatenated
72-
after padding tokens are removed. They are global conditionings; spatial masks are not supported.
74+
after padding tokens are removed.
75+
76+
The **Text Encoder - Krea-2** node also accepts an optional mask. A masked conditioning applies to that
77+
image region; an unmasked conditioning applies to the background not covered by any regional mask. If
78+
regional masks cover the full image, an unmasked conditioning falls back to the full image instead of being
79+
ignored. Krea-2 uses restricted attention on alternating main transformer blocks, leaving the other blocks
80+
unrestricted to preserve image-wide coherence. Positive regional prompts are available on the canvas. In
81+
workflows, masked conditioning collections can also be supplied to the negative input when CFG is enabled.
82+
Canvas regional negative prompts, auto-negative, and regional reference images are not supported.
83+
84+
:::caution[Regional prompting memory]
85+
Regional prompting builds a dense boolean attention mask whose memory grows quadratically with the combined
86+
text and image token count. Invoke reserves memory for retained masks, construction scratch space, and the
87+
dtype-sized additive attention bias created by SDPA. Fused memory-efficient attention support for dense masks
88+
still depends on the GPU, PyTorch build, dtype, and sequence shape. When no fused kernel is available, PyTorch
89+
falls back to math attention, which may use substantially more VRAM and can cause an out-of-memory error.
90+
Reducing image resolution or disabling regional prompting is the practical fallback. Automated CUDA coverage
91+
is skipped on unsupported hardware and cannot exercise every GPU/backend combination.
92+
:::
7393

7494
## LoRA
7595

docs/src/content/docs/start-here/manual.mdx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ The following commands vary depending on the version of Invoke being installed a
131131
```sh
132132
--torch-backend=rocm7.1
133133
```
134+
135+
:::caution[ROCm and torch 2.12]
136+
The `rocm7.1` index currently defaults to torch 2.12.x, which has been reported to
137+
break generation on ROCm ([#9410](https://github.com/invoke-ai/InvokeAI/issues/9410)).
138+
Until that issue is closed, also constrain torch when installing:
139+
```sh
140+
uv pip install <PACKAGE_SPECIFIER>==<VERSION> "torch<2.12" --python 3.12 --python-preference only-managed --torch-backend=rocm7.1 --force-reinstall
141+
```
142+
This workaround applies to the reported ROCm case only.
143+
:::
134144
</TabItem>
135145
<TabItem label="All other cases">
136146
Do not use a torch backend.
@@ -181,7 +191,7 @@ The following commands vary depending on the version of Invoke being installed a
181191
</TabItem>
182192
<TabItem label="Linux/MacOS" icon="linux">
183193
```bash
184-
invokeai-web --root $Home/invokeai
194+
invokeai-web --root ~/invokeai
185195
```
186196
</TabItem>
187197
</Tabs>

0 commit comments

Comments
 (0)