Skip to content

fix(hidiffusion): correct ratio presets and denoising transitions - #10105

Open
DustyShoe wants to merge 9 commits into
invoke-ai:mainfrom
DustyShoe:fix/hidiffusion-v7-upstream
Open

DustyShoe wants to merge 9 commits into
invoke-ai:mainfrom
DustyShoe:fix/hidiffusion-v7-upstream

Conversation

@DustyShoe

@DustyShoe DustyShoe commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes ratio overrides and denoising transitions in the existing HiDiffusion integration. Automatic ratios use the original model- and resolution-specific presets, while disabled sliders retain their manual values for restoration after automatic mode is turned off or the project is reopened.

HiDiffusion now follows logical denoising steps and the sampler's actual partial-denoise step range, including nonlinear schedules, handles regional masks and residual shapes during RAU-Net, and excludes the separate SDXL refiner stage. Window attention reuses its shift within a step and falls back to global attention for incompatible feature-map sizes.

QA Instructions

  1. With SD 1.5 or SDXL, set manual ratios to T1 0.7 and T2 0.2. Enable automatic ratios, confirm the disabled sliders retain their positions, then disable automatic mode and confirm the values return. Repeat with explicit zero and after saving and reopening the project.
  2. Recall images generated with automatic and manual ratios. Confirm the active mode and values match their metadata. An invalid manual T2 greater than T1 should block generation with an explanation in Advanced.
  3. Compare SDXL generation at 2048px using the same seed with automatic ratios and manual T1 0.4/T2 0.16. Exercise img2img, inpainting, regional guidance, ControlNet and T2I-Adapter. Enable the SDXL refiner and confirm HiDiffusion affects only the base stage.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Meaningful regression coverage added / updated where needed; obsolete tests/code removed
  • Persisted-state and API changes include required migrations / compatibility validation
  • Relevant performance/efficiency opportunities considered; material claims have evidence
  • Material review findings resolved and relevant checks rerun
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Preserve manual ratios and apply RAU-Net phases against actual scheduler step ranges.

Restore regional guidance compatibility and keep HiDiffusion off the SDXL refiner.
@github-actions github-actions Bot added python PRs that change python files Root invocations PRs that change invocations backend PRs that change backend files frontend PRs that change frontend files python-tests PRs that change python tests docs PRs that change docs labels Nov 2, 2026
@lstein lstein self-assigned this Nov 2, 2026
@lstein lstein added the 7.0.0 label Nov 2, 2026
@lstein lstein moved this to 7.0.0: UX overhaul in Invoke - Community Roadmap Nov 2, 2026

@lstein lstein left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at fd4c34d9ba. Code-read review; no GPU generation was run.

1. Manual T1 + automatic T2 passes validation, then fails mid-generation (medium)

validate_hidiffusion_ratio_order (denoise_latents.py) and the UI check in baseGenerationPolicies.ts compare T1/T2 only when both are numbers. When one is None, the backend resolves the preset inside the UNet forward, and _get_resolution_aware_switching_threshold_ratio raises if the resolved T2 exceeds T1.

Repro: SD1.5 denoise node in the workflow editor at 2048px with hidiffusion_t1_ratio=0.2, hidiffusion_t2_ratio unset. Automatic T2 resolves to 0.3 (sd15_2048), so the node is accepted, the model loads and text encoding runs, then the first forward fails with "T2 ratio must be less than or equal to the T1 ratio".

The UI can reach the same state through recall: getHiDiffusionPatch sets T2 to null when metadata has hidiffusion but no hidiffusion_t2_ratio, while T1 recalls as a number. The automatic toggle shows off, the T2 slider is disabled, and no issue is shown.

Possible fixes: require both ratios or neither (node validator + settings normalization), or clamp the automatic T2 to the manual T1 instead of raising.

2. img2img / inpainting now often skip RAU-Net entirely (behavior change worth documenting)

Phase boundaries are now measured on the full schedule and shifted by start_step_index. With strength 0.5 (denoising_start=0.5) and T1=0.4, the RAU-Net range is empty; on main, 40% of the remaining steps used it. This matches the stated intent, but it visibly changes high-resolution img2img/upscale output, so please call it out in QA and release notes. A family E2E A/B on SD1.5 and SDXL would quantify it.

3. Existing projects never get the automatic presets (low; product decision)

Projects saved before this PR store hiDiffusionT1Ratio: 0.4 / T2: 0, and normalizeGenerateSettings keeps those as manual values. Existing users therefore stay on 0.4/0 at all resolutions (e.g. SD1.5 at 2048px, where the preset is 0.7/0.3); only new projects default to automatic. No regression versus main, but the preset fix doesn't reach current users unless they toggle automatic on. A one-time normalization of exactly 0.4/0 to null would, if that's the intent.

4. Resetting either slider resets both (minor UX)

Both context-menu onReset handlers call setHiDiffusionRatiosAutomatic(true), so resetting T1 also switches T2 to automatic.

Checked and fine

  • Step-index units are consistent: t_start_idx is scaled by scheduler.order, full_timestep_count is taken before slicing, and the loop's step_index counts the same sub-steps.
  • Ceil-mode mask pooling matches the stride-4/dilation-2 conv (ceil(H/4)), so sequence-length lookups hold at 32x; levels shrink monotonically to 1×1, so keys can't collide.
  • The window-shift cache attributes are in _HIDIFFUSION_RUNTIME_ATTRIBUTES and are cleared on removal.
  • Removing the deepcopy/restore of the global preset dicts closes a cross-request race that exists on main.
  • The refiner node now falls back to hidiffusion=False; the adaptive_avg_pool2d residual fallback is lossy but safe.

Pre-existing, not from this PR: under USE_MODULAR_DENOISE, HiDiffusionExt passes the UNet as pipeline, and _get_max_timesteps finds neither _num_timesteps nor .scheduler on it.

Preserve legacy workflows and validate manual ratio order before model loading.

Keep resets field-specific and align node and generation controls.
@DustyShoe

Copy link
Copy Markdown
Collaborator Author

Thanks for the review.

  1. Fixed. The node now has an explicit Auto switch controlling both ratios. Numeric inputs remain numeric (null normalizes to 0), and manual mode enforces T2 ≤ T1 before model loading. Workflow validation, recall and Generate UI follow the same mode rules.
  2. Intentional behavior change. RAU-Net phases remain anchored to the full scheduler sequence. This is documented; an explicit QA/release-note callout and GPU family A/B remain outstanding.
  3. Preserved intentionally. Existing numeric 0.4/0 settings stay manual. Reinterpreting them as Auto could change deliberately saved settings. New Generate settings default to Auto.
  4. Fixed. Reset affects only the selected ratio and does not toggle Auto. The reset value respects the valid range—for example, resetting T1 with T2 at 0.6 yields T1 0.6, leaving T2 unchanged.

Backend regressions were added for CI. The pre-existing modular-denoise issue remains separate.

@joshistoast joshistoast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potential validation issue to address

DustyShoe and others added 4 commits November 2, 2026 12:07
Preserve assignment context while inputs resolve and validate the final pair before inference.
Allow connected ratio inputs to resolve in either assignment order. Reject invalid active pairs before accessing invocation context.
Keep HiDiffusion field helpers in the existing workflow core chunk so editor request and source-owner budgets remain unchanged.
Enable whole-UNet patching for adapter-only generation and resize residuals at each consumer. Cover all four adapter residuals with a whole-UNet regression.

@joshistoast joshistoast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consequences unknown, lgtm.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

7.0.0 backend PRs that change backend files docs PRs that change docs frontend PRs that change frontend files invocations PRs that change invocations python PRs that change python files python-tests PRs that change python tests Root

Projects

Status: 7.0.0: UX overhaul

Development

Successfully merging this pull request may close these issues.

3 participants