Nodes/ComfyUI-DyPE/HAP (HRDiT)
ComfyUI Node

HAP (HRDiT)

Prune attention heads to win back high-res speed

By wildminder·Created 11 months ago·Updated a day ago· 625
HAP (HRDiT)
  • model
  • scope_plan
  • Patched Model
scope_plan_pathconfigs/scope_plan_flux.json
model_typeauto
enable_haptrue
anchor_stride32
text_len512
proportional_attentionfalse

Here's the wall you hit pushing FLUX past native resolution: attention cost scales with the square of the token count, so a 2K latent isn't twice as slow to sample - it's four times. HAP (Head-Adaptive attention Pruning) is the speed half of HRDiT, and it attacks that wall directly: each attention head only attends to the keys it actually needs, per a pre-calibrated scope plan, executed as block-sparse attention. The result is that a model that got slow when you made it big gets some of its speed back. The paper reports roughly 2.9× faster attention at 2K and ~5.5× at 4K at the default 0.1 budget - for FLUX, anyway.

How it works

Every head's job at high resolution is mostly local: nearby tokens matter, distant ones barely do. HAP encodes that as a per-layer, per-head scope - a local band around each query plus the leading text tokens and a few periodic anchor blocks that stay globally visible so the image doesn't lose coherence. That scope plan is a JSON file, and the pack ships a ready-made reference FLUX plan at configs/scope_plan_flux.json (57 layers × 24 heads). At runtime the node masks each query's keys to that scope; a fast backend runs it through block-sparse attention when you have CUDA + PyTorch ≥ 2.5, and otherwise falls back to a dense-mask backend that's correct but slower. Either way, this is deliberate pruning, not an approximation of attention scores - some keys simply never get attended.

The inputs that matter

Required: model, scope_plan_path (defaults to the shipped FLUX plan; relative paths resolve against the pack folder), model_type (auto), and enable_hap. Then the optional knobs:

  • scope_plan - a linked plan from the HAP Calibrate node. When connected it overrides scope_plan_path, so you don't need a file on disk at all.
  • anchor_stride (default 32) - every Nth image key block stays visible to all queries. This is your global-coherence knob; drop it toward 0 only if you're seeing pruning artifacts.
  • text_len (default 512) - leading text tokens always fully attended. FLUX convention; leave it.
  • proportional_attention (off) - logit scaling for long sequences, exact no-op below 1024px, off by default.

Output is a single Patched Model. Wire it loader → HAP → (optionally SPA) → KSampler; SPA and HAP compose in any order.

Where it bites

The shipped plan is FLUX-only. Run Qwen, Z-Image or Anima and you need a plan for that model - either the in-graph HAP Calibrate node or the pack's calibration/calibrate_hap.py CLI. Nunchaku is unsupported and just logs a warning, returning the model unchanged. And be honest about the value proposition: HAP is pointless at native resolution, where attention isn't your bottleneck - it's specifically the restore-speed companion for high-res generation. If you prune too aggressively (a lower budget_ratio at calibration time), you can lose coherence; that's what anchor_stride exists to counter.

Installing it

HAP ships inside ComfyUI-DyPE - install the pack, not the node. ComfyUI Manager: search "ComfyUI-DyPE" and install, or:

cd ComfyUI/custom_nodes
git clone https://github.com/wildminder/ComfyUI-DyPE.git

Restart. No extra pip dependencies beyond what ComfyUI already has (torch, numpy), no model downloads - the FLUX scope plan is in the repo. This is also the newest, least-battle-tested corner of the pack (HAP landed in v2.7), so expect to calibrate and iterate rather than plug-and-play perfection.

CategoryWMNodes/image

Inputs (8)

NameTypeDefaultDescription
modelMODELThe model to patch with HAP.
scope_plan_pathSTRINGconfigs/scope_plan_flux.jsonPath to the scope-plan JSON (per-layer, per-head alpha/beta). Relative paths resolve against the ComfyUI-DyPE folder. Default ships the reference FLUX plan (57 layers x 24 heads). Generate a plan for your model/resolution with the 'HAP Calibrate' node or calibration/calibrate_hap.py. Ignored when a scope_plan is linked.
model_typeCOMBOautoSpecify the model architecture. 'auto' usually works.
enable_hapBOOLEANtrueEnable or disable HAP. When disabled, the model is returned unchanged.
scope_planoptSCOPE_PLANCalibrated scope plan linked from the 'HAP Calibrate' node. When connected, it OVERRIDES scope_plan_path — no file needed.
anchor_strideoptINT320–1024Global anchor blocks: every N-th image block is visible to all queries (keeps global coherence under pruning). 32 = HRDiT default. 0 = off.
text_lenoptINT5120–4096Number of leading text tokens (always fully attended). 512 = FLUX convention. When SPA is also active, the boundary is derived from the position ids and this is only a fallback.
proportional_attentionoptBOOLEANfalseHRDiT proportional attention scaling: scales the attention logits by sqrt(ln(seq_len)/ln(train_seq_len)) to compensate entropy dilution on long sequences. Exact no-op at/below the trained extent (1024px). Off by default (bit-identical to previous behaviour). Either the SPA or the HAP node may enable it.

Outputs (1)

NameTypeDescription
Patched ModelMODELThe model patched with HAP.