Skip to content

feat(controlnet): add Qwen Image Fun-ControlNet-Union with canvas control layers - #9914

Open
Pfannkuchensack wants to merge 3 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/qwen-image-fun-controlnet
Open

Pfannkuchensack wants to merge 3 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/qwen-image-fun-controlnet

Conversation

@Pfannkuchensack

@Pfannkuchensack Pfannkuchensack commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

Summary

Qwen-Image had no ControlNet. This adds alibaba-pai's Fun-ControlNet-Union (Canny, HED, depth, pose, MLSD, scribble, gray, plus inpainting) as a Qwen Image ControlNet: a model config/loader, the qwen_image_control node, control and inpaint conditioning in qwen_image_denoise (hints injected through forward hooks on the diffusers transformer), a canvas control-layer kind with inpaint/outpaint feeding, a grayscale filter, a starter model and docs. The denoise now reserves working memory for its activations and materialized attention scores.

Related Issues / Discussions

Part of the Fun-ControlNet series (Qwen-Image 2.1, FLUX.2 dev, InstantX and the Z-Image migration follow).

QA Instructions

  • Parity on the real model (RTX 4090, Qwen-Image 2512 Q4_K_M + Union 2602, 1024²): the hooked forward is torch.equal to an independent reference through diffusers' controlnet_block_samples path; scale 0 and inactive hooks equal the plain forward.
  • API runs: control at 0.85 and a 0–50 % window steer the composition (control-edge coverage 0.66–0.93 vs 0.23–0.55 without); pure inpaint keeps everything outside the mask (mean |Δ| ≈ 3) and regenerates inside; combined mode works; a missing VAE is refused with a clear message.
  • Canvas: a control layer defaults to the kind and the union model, Canny filter applied, generation follows the edges; a second Qwen Image ControlNet layer blocks Invoke with the limit reason; Edit models are refused.
  • uv run --no-sync pytest -n 4 tests/backend/fun_controlnet tests/backend/model_manager tests/backend/architectures tests/model_identification tests/backend/z_image tests/app/invocations: 5316 passed. Ruff clean.
  • pnpm lint clean; pnpm test: 10486 passed, 3 known German-locale failures; browser tests for the layer settings pass.

Review

Resolved: a materialized-score term was added to the working-memory estimate for builds without fused masked attention; the control chain runs in the branch dtype and hands hints back in the base dtype; compiled canvas graphs (txt2img, inpaint, outpaint) are validated against the backend invocations; docs cover the grayscale filter and tiled control encodes. Remaining: the working-memory constants are estimates pending calibration; on 16 GB cards the 3.5 GB branch streams beside the transformer; control is refused for Edit models and with reference latents.

Compatibility / Rollout

New node and config class; qwen_image_denoise 1.1.0 adds optional control and vae inputs. openapi.json/schema.ts and the capabilities fixture are regenerated. Canvas documents gain an additive adapter kind (no schema bump). No database migration.

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.

…trol layers

Add alibaba-pai's VACE-style control branch for Qwen-Image: identification, loader, the qwen_image_control node and control/inpaint conditioning in the denoise, injected through forward hooks on the diffusers transformer. The canvas gets a Qwen Image ControlNet layer kind with inpaint/outpaint feeding and a grayscale filter; the denoise now reserves working memory for its activations.
@github-actions github-actions Bot added python PRs that change python files 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 Oct 18, 2026

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

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants