Landing-zone spec: DyPE as a diffusers hook - #27
Closed
github-actions[bot] wants to merge 1 commit into
Closed
Conversation
Owner
|
Superseded by #28 — same change on a conventionally-named branch ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test results
ℹ️ Tests could not run in CI — the runner lacks this repo's dependencies (a collection/import error, not a code failure). Run the suite locally to validate.
License & code availability
MIT(permissive)Drafted from a design brief supplied at dispatch time. No arXiv anchor — the brief IS the spec.
Design brief
Implementation by: Claude Code as autonomous agent
Brief
Landing-zone spec: DyPE as a diffusers hook
Goal
Add a diffusers-native
DyPEHookthat runs DyPE (Dynamic Position Extrapolation) on thestock
FluxTransformer2DModelvia the existingsrc/diffusers/hooks/framework — training-freeultra-high-resolution text-to-image (up to 4096×4096) on off-the-shelf FLUX, no fork of the transformer,
no new weights, no
src/diffusers/models/**changes. The upstream DyPE release ships a vendored fork ofdiffusers' Flux; the missing piece this PR provides is the clean, model-general hook form.
Scope this PR to FLUX + the
yarn(YaRN/NTK-by-parts) path — DyPE's default. Mention (in the PRnarrative only) that the technique generalizes to other RoPE DiTs; do not build speculative
multi-model abstraction or extra config surface for callers that don't exist yet.
References (read these)
flux/transformer_flux.py:get_1d_rotary_pos_embed(the YaRN/NTK-by-parts + DyPEκ=t²schedule), theFluxPosEmbedclass(
set_timestep, per-axisforward), and the transformerforwardlineself.pos_embed.set_timestep(timestep.item()).src/diffusers/hooks/hooks.py(ModelHook:initialize_hook/pre_forward/deinitialize_hook;HookRegistry.register_hook). Mirror the style ofsrc/diffusers/hooks/faster_cache.pyand
layer_skip.py(anapply_*entrypoint that registers the hook).src/diffusers/models/transformers/transformer_flux.py— stockFluxPosEmbed,the transformer
forward(..., timestep=...), andimage_rotary_emb = self.pos_embed(ids).Landing zone (where the code goes)
src/diffusers/hooks/dype.pyDyPEHookandapply_dypefromsrc/diffusers/hooks/__init__.pytests/hooks/test_dype.py(CPU-only unit tests — schedule helpers + no-op-at-trained-res)src/diffusers/models/**.The schedule (reproduce exactly from the MIT reference)
Port these verbatim (add
# Adapted from https://github.com/guyyariv/DyPE (MIT)):find_correction_factor(n_rot,dim,base,max_pe) = dim*ln(max_pe/(n_rot*2π))/(2*ln base);find_correction_range(floor/ceil, clamp to[0, dim-1]);linear_ramp_mask = clamp((arange-min)/(max-min),0,1);find_newbase_ntk(dim,base,scale) = base*scale**(dim/(dim-2))._dype_rotary_pos_embed(...)— YaRN path whenmax_pe_len > ori_max_pe_len(=64):scale = clamp_min(max_pe_len/64, 1.0); buildfreqs_base,freqs_linear(PI,1/(scale*θ**...)),freqs_ntk(1/find_newbase_ntk(...)**...). DyPE modulation:κ = current_timestep**2; scaleβ0=1.25, β1=0.75byκ→ correction range → blendfreqs_linear↔freqs_ntk; then scaleγ0=16, γ1=2byκ→ blend result↔freqs_base. YaRN attention temperaturemscale = where(scale<=1, 1.0, 0.1*log(scale)+1.0)applied to cos/sin. Non-yarn path:θ_ntk = θ*ntk_factor._DyPEPosEmbed(nn.Module)— mirrors stockFluxPosEmbed.forwardper axis:base_patches = 1024//16 = 64;axis 0 = plain RoPE; spatial axes only, and the scheduled path engages only when
current_patches (= max_pos+1) > base_patches. Holdscurrent_timestep(default 1.0),method='yarn',dype=True.Integration shape
DyPEHook(ModelHook):initialize_hook(transformer): construct_DyPEPosEmbedcopying the transformer's existingpos_embed.theta/.axes_dim; swaptransformer.pos_embedto it; stash the original.pre_forward(module, *args, **kwargs): readtimestepfrom kwargs/args (stock FLUX passes it alreadynormalized
/1000 ∈ [0,1], 1=noise); setmodule.pos_embed.current_timestep = float(timestep.flatten()[0]).Return
(args, kwargs)unchanged.deinitialize_hook(transformer): restore the originalpos_embed.apply_dype(transformer, method="yarn", dype=True): registerDyPEHookviaHookRegistry.current_patches ≤ 64) output must be byte-identical to stock.Constraints
src/diffusers/models/**edits.faster_cache.py);make style && make qualitymust pass; add the unit test.Validation (out of scope for the draft; maintainer runs on GPU)
On
black-forest-labs/FLUX.1-Krea-dev(DyPE's validated checkpoint),guidance_scale=4.5, 4096²:apply_dype(pipe.transformer)on the stock diffusers pipeline must reproduce DyPE's official-fork output;naive (no hook) shows extrapolation collapse; at 1024² the hook is a no-op. (Note: plain FLUX.1-dev is NOT
DyPE-validated — use Krea-dev.)
Opened by the Remyx Recommendation orchestrator.
Co-Authored-By: remyx-ai[bot] <289541483+remyx-ai[bot]@users.noreply.github.com>