Feature: HiDiffusion integration - #8787
Conversation
|
I might be spoiled by SDXL too much, but SD1.5 did not impress me much. It produces better results than default denoise. Especially when generating whole image. Inpainting is a tricky one. You might want to try different schedulers. Hands are particularly messy at 1.5k px. |
|
I just realised that updated version of HiDiffusion is here: https://github.com/Teriks/dgenerate/tree/master/dgenerate/extras/hidiffusion |
|
You may wish to consider vendoring the code inside the Invoke package, e.g. |
…ps for external dependency
JPPhoto
left a comment
There was a problem hiding this comment.
You need to bump versions of nodes that you've added fields to:
-
invokeai/app/invocations/denoise_latents.py: bumpDenoiseLatentsInvocationfrom1.5.4to a new version, likely1.6.0because new public inputs were added. -
invokeai/app/invocations/metadata_linked.py: bumpDenoiseLatentsMetaInvocationfrom1.1.1to a new version, likely1.2.0for the inherited new inputs and added metadata keys. -
The generated
openapi.jsonmust also be regenerated so the frontend schema advertises the bumped versions.
Very minor, but the license file LICENSE-HiDiffusion.txt at the repository root looks like it's missing a newline at the end.
As soon as you fix these, I'll approve this to merge!
|
JPPhoto
left a comment
There was a problem hiding this comment.
One more that I found:
invokeai/backend/stable_diffusion/hidiffusion_utils.py:114:hidiffusion_patch()never accepts or passes invocation-seededtorch.Generator; vendored window attention therefore reachestorch.rand(1)process-global RNG atinvokeai/backend/hidiffusion/hidiffusion.py:1420. Same seed can produce different images when window attention is enabled. Test by running two identical HiDiffusion window-attention denoises with the same seed while perturbing global Torch RNG between runs.
|
Fixed both modular and legacy denoise paths to create a dedicated torch.Generator seeded from the invocation seed and pass it through hidiffusion_patch() into the vendored window-attention implementation. Added a regression test that runs the real window-attention patch twice with the same seed while perturbing the process-global Torch RNG; both results are identical. |
|
HiDiffusion runtime state could persist on cached UNet modules after the patch was removed. Re-enabling HiDiffusion or changing the bounding-box dimensions could therefore reuse stale Added fix |
JPPhoto
left a comment
There was a problem hiding this comment.
The latest changes have an issue:
invokeai/backend/hidiffusion/hidiffusion.py:2182:remove_hidiffusion()restores classes but never calls_reset_hidiffusion_runtime_state(). If downsampler forward fails after geometry changes at lines 1860-1862 but before restoration, cachedstride,padding, anddilationremain mutated; next HiDiffusion-disabled run uses corrupted convolution geometry. Re-enable reset is too late and skipped when RAU-Net is disabled. Test: forceF.conv2dto raise during patched downsampler forward, exit patch context, then assert geometry is restored before an unpatched forward.
Here's a regression test you can modify and drop in that shows the fault:
from unittest.mock import patch
import pytest
import torch
from invokeai.backend.stable_diffusion.hidiffusion_utils import hidiffusion_patch
class ModelMixin(torch.nn.Module):
"""Minimal cached UNet accepted by HiDiffusion's diffusers type check."""
def __init__(self) -> None:
super().__init__()
self.num_upsamplers = 3
self._num_timesteps = 10
self.block = torch.nn.Conv2d(1, 1, kernel_size=3, stride=2, padding=1)
def test_hidiffusion_teardown_restores_downsampler_geometry_after_forward_error() -> None:
module_keys = {
"down_module_key": ["block"],
"down_module_key_extra": [],
"up_module_key": [],
"up_module_key_extra": [],
"windown_attn_module_key": [],
}
model = ModelMixin()
original_stride = model.block.stride
original_padding = model.block.padding
original_dilation = model.block.dilation
with patch("invokeai.backend.hidiffusion.hidiffusion.sd15_hidiffusion_key", return_value=module_keys):
with hidiffusion_patch(
model,
name_or_path="runwayml/stable-diffusion-v1-5",
apply_window_attn=False,
):
model.info["size"] = (64, 64)
with (
patch(
"invokeai.backend.hidiffusion.hidiffusion.F.conv2d",
side_effect=RuntimeError("injected convolution failure"),
),
pytest.raises(RuntimeError, match="injected convolution failure"),
):
model.block(torch.zeros(1, 1, 16, 16))
# The cached module is now unpatched. A HiDiffusion-disabled generation
# must see its original convolution geometry.
assert model.block.stride == original_stride
assert model.block.padding == original_padding
assert model.block.dilation == original_dilation|
Implemented transactional HiDiffusion teardown. Downsampler geometry is now passed to |
Summary
Added HiDiffusion support across backend and UI. The denoise pipeline can now apply HiDiffusion with optional RAU‑Net and Window Attention toggles, including metadata persistence/recall and graph wiring for SD1/SDXL and the SDXL refiner. The UI exposes aligned advanced switches with informational popovers.
Added HiDiffusion documentation and a “Learn more” link.
Related Issues / Discussions
https://github.com/megvii-research/HiDiffusion
Closes #8780
QA Instructions
Merge Plan
Should merge without issue.
Checklist
What's Newcopy (if doing a release after this PR)