HAP (HRDiT)
Prune attention heads to win back high-res speed
- model
- scope_plan
- Patched Model
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 overridesscope_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.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | The model to patch with HAP. | |
| scope_plan_path | STRING | configs/scope_plan_flux.json | Path 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_type | COMBO | auto | Specify the model architecture. 'auto' usually works. |
| enable_hap | BOOLEAN | true | Enable or disable HAP. When disabled, the model is returned unchanged. |
| scope_planopt | SCOPE_PLAN | Calibrated scope plan linked from the 'HAP Calibrate' node. When connected, it OVERRIDES scope_plan_path — no file needed. | |
| anchor_strideopt | INT | 320–1024 | Global anchor blocks: every N-th image block is visible to all queries (keeps global coherence under pruning). 32 = HRDiT default. 0 = off. |
| text_lenopt | INT | 5120–4096 | Number 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_attentionopt | BOOLEAN | false | HRDiT 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)
| Name | Type | Description |
|---|---|---|
| Patched Model | MODEL | The model patched with HAP. |