init
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
name: Publish to Comfy registry
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- "pyproject.toml"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-node:
|
||||||
|
name: Publish Custom Node to registry
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.repository_owner == 'wildminder' }}
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
- name: Publish Custom Node
|
||||||
|
uses: Comfy-Org/publish-node-action@v1
|
||||||
|
with:
|
||||||
|
## Add your own personal access token to your Github Repository secrets and reference it here.
|
||||||
|
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
|
||||||
+163
@@ -0,0 +1,163 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.idea
|
||||||
|
.Python
|
||||||
|
__pycache__
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
.rar
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
+92
@@ -0,0 +1,92 @@
|
|||||||
|
import torch
|
||||||
|
from comfy_api.latest import ComfyExtension, io
|
||||||
|
from .src.patch import apply_dype_to_flux
|
||||||
|
|
||||||
|
class DyPE_FLUX(io.ComfyNode):
|
||||||
|
"""
|
||||||
|
Applies DyPE (Dynamic Position Extrapolation) to a FLUX model.
|
||||||
|
This allows generating images at resolutions far beyond the model's training scale
|
||||||
|
by dynamically adjusting positional encodings and the noise schedule.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls) -> io.Schema:
|
||||||
|
return io.Schema(
|
||||||
|
node_id="DyPE_FLUX",
|
||||||
|
display_name="DyPE for FLUX",
|
||||||
|
category="model_patches/unet",
|
||||||
|
description="Applies DyPE (Dynamic Position Extrapolation) to a FLUX model for ultra-high-resolution generation.",
|
||||||
|
inputs=[
|
||||||
|
io.Model.Input(
|
||||||
|
"model",
|
||||||
|
tooltip="The FLUX model to patch with DyPE.",
|
||||||
|
),
|
||||||
|
io.Int.Input(
|
||||||
|
"width",
|
||||||
|
default=1024, min=16, max=8192, step=8,
|
||||||
|
tooltip="Target image width. Must match the width of your empty latent."
|
||||||
|
),
|
||||||
|
io.Int.Input(
|
||||||
|
"height",
|
||||||
|
default=1024, min=16, max=8192, step=8,
|
||||||
|
tooltip="Target image height. Must match the height of your empty latent."
|
||||||
|
),
|
||||||
|
io.Combo.Input(
|
||||||
|
"method",
|
||||||
|
options=["yarn", "ntk", "base"],
|
||||||
|
default="yarn",
|
||||||
|
tooltip="Position encoding extrapolation method (YARN recommended).",
|
||||||
|
),
|
||||||
|
io.Boolean.Input(
|
||||||
|
"enable_dype",
|
||||||
|
default=True,
|
||||||
|
label_on="Enabled",
|
||||||
|
label_off="Disabled",
|
||||||
|
tooltip="Enable or disable Dynamic Position Extrapolation for RoPE.",
|
||||||
|
),
|
||||||
|
io.Float.Input(
|
||||||
|
"dype_exponent",
|
||||||
|
default=2.0, min=0.0, max=4.0, step=0.1,
|
||||||
|
optional=True,
|
||||||
|
tooltip="Controls DyPE strength over time (λt). 2.0=Exponential (best for 4K+), 1.0=Linear, 0.5=Sub-linear (better for ~2K)."
|
||||||
|
),
|
||||||
|
io.Float.Input(
|
||||||
|
"base_shift",
|
||||||
|
default=0.5, min=0.0, max=10.0, step=0.01,
|
||||||
|
optional=True,
|
||||||
|
tooltip="Advanced: Base shift for the noise schedule (mu). Default is 0.5."
|
||||||
|
),
|
||||||
|
io.Float.Input(
|
||||||
|
"max_shift",
|
||||||
|
default=1.15, min=0.0, max=10.0, step=0.01,
|
||||||
|
optional=True,
|
||||||
|
tooltip="Advanced: Max shift for the noise schedule (mu) at high resolutions. Default is 1.15."
|
||||||
|
),
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Model.Output(
|
||||||
|
display_name="Patched Model",
|
||||||
|
tooltip="The FLUX model patched with DyPE.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, model, width: int, height: int, method: str, enable_dype: bool, dype_exponent: float = 2.0, base_shift: float = 0.5, max_shift: float = 1.15) -> io.NodeOutput:
|
||||||
|
"""
|
||||||
|
Clones the model and applies the DyPE patch for both the noise schedule and positional embeddings.
|
||||||
|
"""
|
||||||
|
if not hasattr(model.model, "diffusion_model") or not hasattr(model.model.diffusion_model, "pe_embedder"):
|
||||||
|
raise ValueError("This node is only compatible with FLUX models.")
|
||||||
|
|
||||||
|
patched_model = apply_dype_to_flux(model, width, height, method, enable_dype, dype_exponent, base_shift, max_shift)
|
||||||
|
return io.NodeOutput(patched_model)
|
||||||
|
|
||||||
|
class DyPEExtension(ComfyExtension):
|
||||||
|
"""Registers the DyPE node."""
|
||||||
|
|
||||||
|
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
||||||
|
return [DyPE_FLUX]
|
||||||
|
|
||||||
|
async def comfy_entrypoint() -> DyPEExtension:
|
||||||
|
return DyPEExtension()
|
||||||
@@ -0,0 +1,844 @@
|
|||||||
|
{
|
||||||
|
"id": "908d0bfb-e192-4627-9b57-147496e6e2dd",
|
||||||
|
"revision": 0,
|
||||||
|
"last_node_id": 70,
|
||||||
|
"last_link_id": 119,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": 40,
|
||||||
|
"type": "DualCLIPLoader",
|
||||||
|
"pos": [
|
||||||
|
-320,
|
||||||
|
290
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
270,
|
||||||
|
130
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 0,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "CLIP",
|
||||||
|
"type": "CLIP",
|
||||||
|
"links": [
|
||||||
|
64
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "DualCLIPLoader",
|
||||||
|
"models": [
|
||||||
|
{
|
||||||
|
"name": "clip_l.safetensors",
|
||||||
|
"url": "https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/clip_l.safetensors",
|
||||||
|
"directory": "text_encoders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "t5xxl_fp16.safetensors",
|
||||||
|
"url": "https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/t5xxl_fp16.safetensors",
|
||||||
|
"directory": "text_encoders"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"clip_l.safetensors",
|
||||||
|
"t5xxl_fp16.safetensors",
|
||||||
|
"flux",
|
||||||
|
"default"
|
||||||
|
],
|
||||||
|
"color": "#223",
|
||||||
|
"bgcolor": "#335"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 43,
|
||||||
|
"type": "MarkdownNote",
|
||||||
|
"pos": [
|
||||||
|
-870,
|
||||||
|
110
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
520,
|
||||||
|
390
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 1,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [],
|
||||||
|
"title": "Model links",
|
||||||
|
"properties": {},
|
||||||
|
"widgets_values": [
|
||||||
|
"## Model links\n\n**Diffusion Model**\n\n- [flux1-krea-dev_fp8_scaled.safetensors](https://huggingface.co/Comfy-Org/FLUX.1-Krea-dev_ComfyUI/resolve/main/split_files/diffusion_models/flux1-krea-dev_fp8_scaled.safetensors)\n\nIf you need the original weights, head to [black-forest-labs/FLUX.1-Krea-dev](https://huggingface.co/black-forest-labs/FLUX.1-Krea-dev/), accept the agreement in the repo, then click the link below to download the models:\n\n- [flux1-krea-dev.safetensors](https://huggingface.co/black-forest-labs/FLUX.1-Krea-dev/resolve/main/flux1-krea-dev.safetensors)\n\n**Text Encoder**\n\n- [clip_l.safetensors](https://huggingface.co/comfyanonymous/flux_text_encoders/blob/main/clip_l.safetensors)\n\n- [t5xxl_fp16.safetensors](https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/t5xxl_fp16.safetensors) or [t5xxl_fp8_e4m3fn_scaled.safetensors](https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/t5xxl_fp8_e4m3fn_scaled.safetensors)\n\n**VAE**\n\n- [ae.safetensors](https://huggingface.co/Comfy-Org/Lumina_Image_2.0_Repackaged/resolve/main/split_files/vae/ae.safetensors)\n\n\n```\nComfyUI/\n├── models/\n│ ├── diffusion_models/\n│ │ └─── flux1-krea-dev_fp8_scaled.safetensors\n│ ├── text_encoders/\n│ │ ├── clip_l.safetensors\n│ │ └─── t5xxl_fp16.safetensors # or t5xxl_fp8_e4m3fn_scaled.safetensors\n│ └── vae/\n│ └── ae.safetensors\n```\n"
|
||||||
|
],
|
||||||
|
"color": "#432",
|
||||||
|
"bgcolor": "#653"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 39,
|
||||||
|
"type": "VAELoader",
|
||||||
|
"pos": [
|
||||||
|
-320,
|
||||||
|
470
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
270,
|
||||||
|
58
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 2,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "VAE",
|
||||||
|
"type": "VAE",
|
||||||
|
"links": [
|
||||||
|
77,
|
||||||
|
85
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "VAELoader",
|
||||||
|
"models": [
|
||||||
|
{
|
||||||
|
"name": "ae.safetensors",
|
||||||
|
"url": "https://huggingface.co/Comfy-Org/Lumina_Image_2.0_Repackaged/resolve/main/split_files/vae/ae.safetensors",
|
||||||
|
"directory": "vae"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"FLUX1\\ae.safetensors"
|
||||||
|
],
|
||||||
|
"color": "#223",
|
||||||
|
"bgcolor": "#335"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"type": "VAEDecode",
|
||||||
|
"pos": [
|
||||||
|
391.97558139331176,
|
||||||
|
122.95473372107558
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
319.2356335124862,
|
||||||
|
46
|
||||||
|
],
|
||||||
|
"flags": {
|
||||||
|
"collapsed": false
|
||||||
|
},
|
||||||
|
"order": 13,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "samples",
|
||||||
|
"type": "LATENT",
|
||||||
|
"link": 52
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vae",
|
||||||
|
"type": "VAE",
|
||||||
|
"link": 85
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "IMAGE",
|
||||||
|
"type": "IMAGE",
|
||||||
|
"slot_index": 0,
|
||||||
|
"links": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "VAEDecode"
|
||||||
|
},
|
||||||
|
"widgets_values": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 55,
|
||||||
|
"type": "VAEDecodeTiled",
|
||||||
|
"pos": [
|
||||||
|
391.97558139331176,
|
||||||
|
226.612614517858
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
322.89304359551966,
|
||||||
|
150
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 14,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "samples",
|
||||||
|
"type": "LATENT",
|
||||||
|
"link": 112
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vae",
|
||||||
|
"type": "VAE",
|
||||||
|
"link": 77
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "IMAGE",
|
||||||
|
"type": "IMAGE",
|
||||||
|
"links": [
|
||||||
|
91
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.66",
|
||||||
|
"Node name for S&R": "VAEDecodeTiled"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
256,
|
||||||
|
64,
|
||||||
|
64,
|
||||||
|
8
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 53,
|
||||||
|
"type": "ModelPatchTorchSettings",
|
||||||
|
"pos": [
|
||||||
|
30.020388325880088,
|
||||||
|
958.5302639048878
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
280,
|
||||||
|
58
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 11,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "model",
|
||||||
|
"type": "MODEL",
|
||||||
|
"link": 71
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "MODEL",
|
||||||
|
"type": "MODEL",
|
||||||
|
"links": [
|
||||||
|
73
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfyui-kjnodes",
|
||||||
|
"ver": "5dcda71011870278c35d92ff77a677ed2e538f2d",
|
||||||
|
"Node name for S&R": "ModelPatchTorchSettings",
|
||||||
|
"ue_properties": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"widget_ue_connectable": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
true
|
||||||
|
],
|
||||||
|
"color": "#432",
|
||||||
|
"bgcolor": "#653"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 38,
|
||||||
|
"type": "UNETLoader",
|
||||||
|
"pos": [
|
||||||
|
-320,
|
||||||
|
150
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
270,
|
||||||
|
82
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 3,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "MODEL",
|
||||||
|
"type": "MODEL",
|
||||||
|
"links": [
|
||||||
|
118
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "UNETLoader",
|
||||||
|
"models": [
|
||||||
|
{
|
||||||
|
"name": "flux1-krea-dev_fp8_scaled.safetensors",
|
||||||
|
"url": "https://huggingface.co/Comfy-Org/FLUX.1-Krea-dev_ComfyUI/resolve/main/split_files/diffusion_models/flux1-krea-dev_fp8_scaled.safetensors",
|
||||||
|
"directory": "diffusion_models"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"FLUX1\\flux1-krea-dev.safetensors",
|
||||||
|
"default"
|
||||||
|
],
|
||||||
|
"color": "#223",
|
||||||
|
"bgcolor": "#335"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 27,
|
||||||
|
"type": "EmptySD3LatentImage",
|
||||||
|
"pos": [
|
||||||
|
-320,
|
||||||
|
630
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
270,
|
||||||
|
120
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 4,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "LATENT",
|
||||||
|
"type": "LATENT",
|
||||||
|
"slot_index": 0,
|
||||||
|
"links": [
|
||||||
|
51
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "EmptySD3LatentImage"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
2048,
|
||||||
|
3072,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"color": "#223",
|
||||||
|
"bgcolor": "#335"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"type": "SaveImage",
|
||||||
|
"pos": [
|
||||||
|
757.2214793721178,
|
||||||
|
123.42500709283193
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
640,
|
||||||
|
660
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 15,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "images",
|
||||||
|
"type": "IMAGE",
|
||||||
|
"link": 91
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "SaveImage"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"flux_krea/flux_krea"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 45,
|
||||||
|
"type": "CLIPTextEncode",
|
||||||
|
"pos": [
|
||||||
|
7.045080197257759,
|
||||||
|
159.16529405661166
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
330,
|
||||||
|
210
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 7,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "clip",
|
||||||
|
"type": "CLIP",
|
||||||
|
"link": 64
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "CONDITIONING",
|
||||||
|
"type": "CONDITIONING",
|
||||||
|
"links": [
|
||||||
|
66,
|
||||||
|
111
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.47",
|
||||||
|
"Node name for S&R": "CLIPTextEncode"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"A muscular, bald man holds a flower above his head with both arms, set against a soft circular background in black and white."
|
||||||
|
],
|
||||||
|
"color": "#232",
|
||||||
|
"bgcolor": "#353"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 42,
|
||||||
|
"type": "ConditioningZeroOut",
|
||||||
|
"pos": [
|
||||||
|
151.75751860615074,
|
||||||
|
416.7514387263594
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
200,
|
||||||
|
30
|
||||||
|
],
|
||||||
|
"flags": {
|
||||||
|
"collapsed": true
|
||||||
|
},
|
||||||
|
"order": 9,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "conditioning",
|
||||||
|
"type": "CONDITIONING",
|
||||||
|
"link": 66
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "CONDITIONING",
|
||||||
|
"type": "CONDITIONING",
|
||||||
|
"links": [
|
||||||
|
110
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "ConditioningZeroOut"
|
||||||
|
},
|
||||||
|
"widgets_values": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 52,
|
||||||
|
"type": "PathchSageAttentionKJ",
|
||||||
|
"pos": [
|
||||||
|
30.97067656870301,
|
||||||
|
849.9776697194811
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
280,
|
||||||
|
58
|
||||||
|
],
|
||||||
|
"flags": {
|
||||||
|
"collapsed": false
|
||||||
|
},
|
||||||
|
"order": 10,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "model",
|
||||||
|
"type": "MODEL",
|
||||||
|
"link": 119
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "MODEL",
|
||||||
|
"type": "MODEL",
|
||||||
|
"links": [
|
||||||
|
71
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfyui-kjnodes",
|
||||||
|
"ver": "5dcda71011870278c35d92ff77a677ed2e538f2d",
|
||||||
|
"Node name for S&R": "PathchSageAttentionKJ",
|
||||||
|
"ue_properties": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"widget_ue_connectable": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"auto"
|
||||||
|
],
|
||||||
|
"color": "#432",
|
||||||
|
"bgcolor": "#653"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 68,
|
||||||
|
"type": "DyPE_FLUX",
|
||||||
|
"pos": [
|
||||||
|
34.378266361112125,
|
||||||
|
592.0845558725733
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
273.70012497212906,
|
||||||
|
202
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 8,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "model",
|
||||||
|
"type": "MODEL",
|
||||||
|
"link": 118
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "Patched Model",
|
||||||
|
"type": "MODEL",
|
||||||
|
"links": [
|
||||||
|
119
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Node name for S&R": "DyPE_FLUX"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
1024,
|
||||||
|
1024,
|
||||||
|
"yarn",
|
||||||
|
true,
|
||||||
|
3,
|
||||||
|
0.1,
|
||||||
|
0.8
|
||||||
|
],
|
||||||
|
"color": "#322",
|
||||||
|
"bgcolor": "#533"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 70,
|
||||||
|
"type": "Note",
|
||||||
|
"pos": [
|
||||||
|
370.8346374838202,
|
||||||
|
962.8353927340362
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
210,
|
||||||
|
88
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 5,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [],
|
||||||
|
"properties": {},
|
||||||
|
"widgets_values": [
|
||||||
|
"DyPE width/height - Keep the values below 1024x1024; doing so won’t affect your output.\n"
|
||||||
|
],
|
||||||
|
"color": "#322",
|
||||||
|
"bgcolor": "#533"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 69,
|
||||||
|
"type": "MarkdownNote",
|
||||||
|
"pos": [
|
||||||
|
-866.3440753786277,
|
||||||
|
557.8510364476188
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
519.2421649643175,
|
||||||
|
338.01057378012047
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 6,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [],
|
||||||
|
"title": "DyPE",
|
||||||
|
"properties": {
|
||||||
|
"ue_properties": {
|
||||||
|
"widget_ue_connectable": {},
|
||||||
|
"version": "7.1",
|
||||||
|
"input_ue_unconnectable": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"### Node Inputs\n\n* **`model`**: The FLUX model to be patched.\n* **`width` / `height`**: The target image resolution. **This must match the resolution set in your `Empty Latent Image` node.**\n* **`method`**: The core position encoding extrapolation method. `yarn` is the recommended default, as it forms the basis of the paper's best-performing \"DY-YaRN\" variant.\n* **`enable_dype`**: Enables or disables the **dynamic, time-aware** component of DyPE.\n* **`dype_exponent`**: Controls the \"strength\" of the dynamic effect over time. This is the most important tuning parameter.\n * `2.0` (Exponential): Recommended for **4K+** resolutions. It's an aggressive schedule that transitions quickly.\n * `1.0` (Linear): A good starting point for **~2K-3K** resolutions.\n * `0.5` (Sub-linear): A gentler schedule that may work best for resolutions just above the model's native 1K.\n* **`base_shift` / `max_shift`** (Advanced): Adjust only if you are an advanced user experimenting with the noise schedule.\n\n\n\n## Join\n\n### [TokenDiffusion](https://t.me/TokenDiff) - AI for every home, creativity for every mind!\n\n### [TokenDiff Community Hub](https://t.me/TokenDiff_hub) - Questions, help, and thoughtful discussion. "
|
||||||
|
],
|
||||||
|
"color": "#322",
|
||||||
|
"bgcolor": "#533"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 31,
|
||||||
|
"type": "KSampler",
|
||||||
|
"pos": [
|
||||||
|
395.5510343546297,
|
||||||
|
433.7293334706151
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
315,
|
||||||
|
474.00000000000006
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 12,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "model",
|
||||||
|
"type": "MODEL",
|
||||||
|
"link": 73
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "positive",
|
||||||
|
"type": "CONDITIONING",
|
||||||
|
"link": 111
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "negative",
|
||||||
|
"type": "CONDITIONING",
|
||||||
|
"link": 110
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "latent_image",
|
||||||
|
"type": "LATENT",
|
||||||
|
"link": 51
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "LATENT",
|
||||||
|
"type": "LATENT",
|
||||||
|
"slot_index": 0,
|
||||||
|
"links": [
|
||||||
|
52,
|
||||||
|
112
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"cnr_id": "comfy-core",
|
||||||
|
"ver": "0.3.40",
|
||||||
|
"Node name for S&R": "KSampler"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
42,
|
||||||
|
"fixed",
|
||||||
|
30,
|
||||||
|
1,
|
||||||
|
"euler",
|
||||||
|
"beta",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
[
|
||||||
|
51,
|
||||||
|
27,
|
||||||
|
0,
|
||||||
|
31,
|
||||||
|
3,
|
||||||
|
"LATENT"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
52,
|
||||||
|
31,
|
||||||
|
0,
|
||||||
|
8,
|
||||||
|
0,
|
||||||
|
"LATENT"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
64,
|
||||||
|
40,
|
||||||
|
0,
|
||||||
|
45,
|
||||||
|
0,
|
||||||
|
"CLIP"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
66,
|
||||||
|
45,
|
||||||
|
0,
|
||||||
|
42,
|
||||||
|
0,
|
||||||
|
"CONDITIONING"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
71,
|
||||||
|
52,
|
||||||
|
0,
|
||||||
|
53,
|
||||||
|
0,
|
||||||
|
"MODEL"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
73,
|
||||||
|
53,
|
||||||
|
0,
|
||||||
|
31,
|
||||||
|
0,
|
||||||
|
"MODEL"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
77,
|
||||||
|
39,
|
||||||
|
0,
|
||||||
|
55,
|
||||||
|
1,
|
||||||
|
"VAE"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
85,
|
||||||
|
39,
|
||||||
|
0,
|
||||||
|
8,
|
||||||
|
1,
|
||||||
|
"VAE"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
91,
|
||||||
|
55,
|
||||||
|
0,
|
||||||
|
9,
|
||||||
|
0,
|
||||||
|
"IMAGE"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
110,
|
||||||
|
42,
|
||||||
|
0,
|
||||||
|
31,
|
||||||
|
2,
|
||||||
|
"CONDITIONING"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
111,
|
||||||
|
45,
|
||||||
|
0,
|
||||||
|
31,
|
||||||
|
1,
|
||||||
|
"CONDITIONING"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
112,
|
||||||
|
31,
|
||||||
|
0,
|
||||||
|
55,
|
||||||
|
0,
|
||||||
|
"LATENT"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
118,
|
||||||
|
38,
|
||||||
|
0,
|
||||||
|
68,
|
||||||
|
0,
|
||||||
|
"MODEL"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
119,
|
||||||
|
68,
|
||||||
|
0,
|
||||||
|
52,
|
||||||
|
0,
|
||||||
|
"MODEL"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"groups": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "Step 1 - Load Models Here",
|
||||||
|
"bounding": [
|
||||||
|
-330,
|
||||||
|
80,
|
||||||
|
300,
|
||||||
|
460
|
||||||
|
],
|
||||||
|
"color": "#3f789e",
|
||||||
|
"font_size": 24,
|
||||||
|
"flags": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"title": "Step 2 - Image Size",
|
||||||
|
"bounding": [
|
||||||
|
-330,
|
||||||
|
560,
|
||||||
|
300,
|
||||||
|
200
|
||||||
|
],
|
||||||
|
"color": "#3f789e",
|
||||||
|
"font_size": 24,
|
||||||
|
"flags": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"title": "Step 3 - Prompt",
|
||||||
|
"bounding": [
|
||||||
|
-10,
|
||||||
|
80,
|
||||||
|
361.9005764856456,
|
||||||
|
399.16989485829595
|
||||||
|
],
|
||||||
|
"color": "#3f789e",
|
||||||
|
"font_size": 24,
|
||||||
|
"flags": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"title": "Model patch",
|
||||||
|
"bounding": [
|
||||||
|
-7.575982245696814,
|
||||||
|
506.15777888556613,
|
||||||
|
357.2928781597926,
|
||||||
|
546.8190068170823
|
||||||
|
],
|
||||||
|
"color": "#3f789e",
|
||||||
|
"font_size": 24,
|
||||||
|
"flags": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"config": {},
|
||||||
|
"extra": {
|
||||||
|
"ds": {
|
||||||
|
"scale": 0.7627768444385601,
|
||||||
|
"offset": [
|
||||||
|
1067.6762292181238,
|
||||||
|
-14.895608507226342
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"frontendVersion": "1.28.7",
|
||||||
|
"VHS_latentpreview": false,
|
||||||
|
"VHS_latentpreviewrate": 0,
|
||||||
|
"VHS_MetadataImage": true,
|
||||||
|
"VHS_KeepIntermediate": true
|
||||||
|
},
|
||||||
|
"version": 0.4
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 849 KiB |
@@ -0,0 +1 @@
|
|||||||
|
torch
|
||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
import torch
|
||||||
|
import torch.nn as nn
|
||||||
|
import math
|
||||||
|
import types
|
||||||
|
from comfy.model_patcher import ModelPatcher
|
||||||
|
from comfy import model_sampling
|
||||||
|
from .rope import get_1d_rotary_pos_embed
|
||||||
|
|
||||||
|
|
||||||
|
class FluxPosEmbed(nn.Module):
|
||||||
|
def __init__(self, theta: int, axes_dim: list[int], method: str = 'yarn', dype: bool = True, dype_exponent: float = 2.0): # Add dype_exponent
|
||||||
|
super().__init__()
|
||||||
|
self.theta = theta
|
||||||
|
self.axes_dim = axes_dim
|
||||||
|
self.method = method
|
||||||
|
self.dype = dype if method != 'base' else False
|
||||||
|
self.dype_exponent = dype_exponent
|
||||||
|
self.current_timestep = 1.0
|
||||||
|
self.base_resolution = 1024
|
||||||
|
self.base_patches = (self.base_resolution // 8) // 2
|
||||||
|
|
||||||
|
def set_timestep(self, timestep: float):
|
||||||
|
self.current_timestep = timestep
|
||||||
|
|
||||||
|
def forward(self, ids: torch.Tensor) -> torch.Tensor:
|
||||||
|
n_axes = ids.shape[-1]
|
||||||
|
emb_parts = []
|
||||||
|
pos = ids.float()
|
||||||
|
freqs_dtype = torch.bfloat16
|
||||||
|
|
||||||
|
for i in range(n_axes):
|
||||||
|
axis_pos = pos[..., i]
|
||||||
|
axis_dim = self.axes_dim[i]
|
||||||
|
|
||||||
|
common_kwargs = {'dim': axis_dim, 'pos': axis_pos, 'theta': self.theta, 'repeat_interleave_real': True, 'use_real': True, 'freqs_dtype': freqs_dtype}
|
||||||
|
|
||||||
|
# Pass the exponent to the RoPE function
|
||||||
|
dype_kwargs = {'dype': self.dype, 'current_timestep': self.current_timestep, 'dype_exponent': self.dype_exponent}
|
||||||
|
|
||||||
|
if i > 0:
|
||||||
|
max_pos = axis_pos.max().item()
|
||||||
|
current_patches = int(max_pos + 1)
|
||||||
|
|
||||||
|
if self.method == 'yarn' and current_patches > self.base_patches:
|
||||||
|
max_pe_len = torch.tensor(current_patches, dtype=freqs_dtype, device=pos.device)
|
||||||
|
cos, sin = get_1d_rotary_pos_embed(**common_kwargs, yarn=True, max_pe_len=max_pe_len, ori_max_pe_len=self.base_patches, **dype_kwargs)
|
||||||
|
elif self.method == 'ntk' and current_patches > self.base_patches:
|
||||||
|
base_ntk_scale = (current_patches / self.base_patches)
|
||||||
|
cos, sin = get_1d_rotary_pos_embed(**common_kwargs, ntk_factor=base_ntk_scale, **dype_kwargs)
|
||||||
|
else:
|
||||||
|
cos, sin = get_1d_rotary_pos_embed(**common_kwargs)
|
||||||
|
else:
|
||||||
|
cos, sin = get_1d_rotary_pos_embed(**common_kwargs)
|
||||||
|
|
||||||
|
cos_reshaped = cos.view(*cos.shape[:-1], -1, 2)[..., :1]
|
||||||
|
sin_reshaped = sin.view(*sin.shape[:-1], -1, 2)[..., :1]
|
||||||
|
row1 = torch.cat([cos_reshaped, -sin_reshaped], dim=-1)
|
||||||
|
row2 = torch.cat([sin_reshaped, cos_reshaped], dim=-1)
|
||||||
|
matrix = torch.stack([row1, row2], dim=-2)
|
||||||
|
emb_parts.append(matrix)
|
||||||
|
|
||||||
|
emb = torch.cat(emb_parts, dim=-3)
|
||||||
|
return emb.unsqueeze(1).to(ids.device)
|
||||||
|
|
||||||
|
def apply_dype_to_flux(model: ModelPatcher, width: int, height: int, method: str, enable_dype: bool, dype_exponent: float, base_shift: float, max_shift: float) -> ModelPatcher:
|
||||||
|
m = model.clone()
|
||||||
|
|
||||||
|
if not hasattr(m.model.model_sampling, "_dype_patched"):
|
||||||
|
model_sampler = m.model.model_sampling
|
||||||
|
if isinstance(model_sampler, model_sampling.ModelSamplingFlux):
|
||||||
|
patch_size = m.model.diffusion_model.patch_size
|
||||||
|
latent_h, latent_w = height // 8, width // 8
|
||||||
|
padded_h, padded_w = math.ceil(latent_h / patch_size) * patch_size, math.ceil(latent_w / patch_size) * patch_size
|
||||||
|
image_seq_len = (padded_h // patch_size) * (padded_w // patch_size)
|
||||||
|
base_seq_len, max_seq_len = 256, 4096
|
||||||
|
slope = (max_shift - base_shift) / (max_seq_len - base_seq_len)
|
||||||
|
intercept = base_shift - slope * base_seq_len
|
||||||
|
dype_shift = image_seq_len * slope + intercept
|
||||||
|
|
||||||
|
def patched_sigma_func(self, timestep):
|
||||||
|
return model_sampling.flux_time_shift(dype_shift, 1.0, timestep)
|
||||||
|
|
||||||
|
model_sampler.sigma = types.MethodType(patched_sigma_func, model_sampler)
|
||||||
|
model_sampler._dype_patched = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
orig_embedder = m.model.diffusion_model.pe_embedder
|
||||||
|
theta, axes_dim = orig_embedder.theta, orig_embedder.axes_dim
|
||||||
|
except AttributeError:
|
||||||
|
raise ValueError("The provided model is not a compatible FLUX model.")
|
||||||
|
|
||||||
|
new_pe_embedder = FluxPosEmbed(theta, axes_dim, method, enable_dype, dype_exponent)
|
||||||
|
m.add_object_patch("diffusion_model.pe_embedder", new_pe_embedder)
|
||||||
|
|
||||||
|
sigma_max = m.model.model_sampling.sigma_max.item()
|
||||||
|
|
||||||
|
def dype_wrapper_function(model_function, args_dict):
|
||||||
|
if enable_dype:
|
||||||
|
timestep_tensor = args_dict.get("timestep")
|
||||||
|
if timestep_tensor is not None and timestep_tensor.numel() > 0:
|
||||||
|
current_sigma = timestep_tensor.item()
|
||||||
|
if sigma_max > 0:
|
||||||
|
normalized_timestep = min(max(current_sigma / sigma_max, 0.0), 1.0)
|
||||||
|
new_pe_embedder.set_timestep(normalized_timestep)
|
||||||
|
|
||||||
|
input_x, c = args_dict.get("input"), args_dict.get("c", {})
|
||||||
|
return model_function(input_x, args_dict.get("timestep"), **c)
|
||||||
|
|
||||||
|
m.set_model_unet_function_wrapper(dype_wrapper_function)
|
||||||
|
|
||||||
|
return m
|
||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
import torch
|
||||||
|
import numpy as np
|
||||||
|
import math
|
||||||
|
|
||||||
|
def find_correction_factor(num_rotations, dim, base, max_position_embeddings):
|
||||||
|
return (dim * math.log(max_position_embeddings/(num_rotations * 2 * math.pi)))/(2 * math.log(base))
|
||||||
|
|
||||||
|
def find_correction_range(low_ratio, high_ratio, dim, base, ori_max_pe_len):
|
||||||
|
low = np.floor(find_correction_factor(low_ratio, dim, base, ori_max_pe_len))
|
||||||
|
high = np.ceil(find_correction_factor(high_ratio, dim, base, ori_max_pe_len))
|
||||||
|
return max(low, 0), min(high, dim-1)
|
||||||
|
|
||||||
|
def linear_ramp_mask(min_val, max_val, dim):
|
||||||
|
if min_val == max_val:
|
||||||
|
max_val += 0.001
|
||||||
|
|
||||||
|
linear_func = (torch.arange(dim, dtype=torch.float32) - min_val) / (max_val - min_val)
|
||||||
|
ramp_func = torch.clamp(linear_func, 0, 1)
|
||||||
|
return ramp_func
|
||||||
|
|
||||||
|
def find_newbase_ntk(dim, base, scale):
|
||||||
|
return base * (scale ** (dim / (dim - 2)))
|
||||||
|
|
||||||
|
def get_1d_rotary_pos_embed(
|
||||||
|
dim: int,
|
||||||
|
pos: torch.Tensor,
|
||||||
|
theta: float = 10000.0,
|
||||||
|
use_real=False,
|
||||||
|
linear_factor=1.0,
|
||||||
|
ntk_factor=1.0,
|
||||||
|
repeat_interleave_real=True,
|
||||||
|
freqs_dtype=torch.float32,
|
||||||
|
yarn=False,
|
||||||
|
max_pe_len=None,
|
||||||
|
ori_max_pe_len=64,
|
||||||
|
dype=False,
|
||||||
|
current_timestep=1.0,
|
||||||
|
dype_exponent=2.0,
|
||||||
|
):
|
||||||
|
assert dim % 2 == 0
|
||||||
|
device = pos.device
|
||||||
|
|
||||||
|
if yarn and max_pe_len is not None and max_pe_len > ori_max_pe_len:
|
||||||
|
if not isinstance(max_pe_len, torch.Tensor):
|
||||||
|
max_pe_len = torch.tensor(max_pe_len, dtype=freqs_dtype, device=device)
|
||||||
|
|
||||||
|
scale = torch.clamp_min(max_pe_len / ori_max_pe_len, 1.0)
|
||||||
|
|
||||||
|
beta_0, beta_1 = 1.25, 0.75
|
||||||
|
gamma_0, gamma_1 = 16, 2
|
||||||
|
|
||||||
|
freqs_base = 1.0 / (theta ** (torch.arange(0, dim, 2, dtype=freqs_dtype, device=device) / dim))
|
||||||
|
freqs_linear = 1.0 / torch.einsum('..., f -> ... f', scale, (theta ** (torch.arange(0, dim, 2, dtype=freqs_dtype, device=device) / dim)))
|
||||||
|
|
||||||
|
new_base = find_newbase_ntk(dim, theta, scale)
|
||||||
|
if new_base.dim() > 0: new_base = new_base.view(-1, 1)
|
||||||
|
freqs_ntk = 1.0 / torch.pow(new_base, (torch.arange(0, dim, 2, dtype=freqs_dtype, device=device) / dim))
|
||||||
|
if freqs_ntk.dim() > 1: freqs_ntk = freqs_ntk.squeeze()
|
||||||
|
|
||||||
|
if dype:
|
||||||
|
beta_0 = beta_0 ** (dype_exponent * (current_timestep ** dype_exponent))
|
||||||
|
beta_1 = beta_1 ** (dype_exponent * (current_timestep ** dype_exponent))
|
||||||
|
|
||||||
|
low, high = find_correction_range(beta_0, beta_1, dim, theta, ori_max_pe_len)
|
||||||
|
low, high = max(0, low), min(dim // 2, high)
|
||||||
|
|
||||||
|
freqs_mask = (1 - linear_ramp_mask(low, high, dim // 2).to(device).to(freqs_dtype))
|
||||||
|
freqs = freqs_linear * (1 - freqs_mask) + freqs_ntk * freqs_mask
|
||||||
|
|
||||||
|
if dype:
|
||||||
|
gamma_0 = gamma_0 ** (dype_exponent * (current_timestep ** dype_exponent))
|
||||||
|
gamma_1 = gamma_1 ** (dype_exponent * (current_timestep ** dype_exponent))
|
||||||
|
|
||||||
|
low, high = find_correction_range(gamma_0, gamma_1, dim, theta, ori_max_pe_len)
|
||||||
|
low, high = max(0, low), min(dim // 2, high)
|
||||||
|
|
||||||
|
freqs_mask = (1 - linear_ramp_mask(low, high, dim // 2).to(device).to(freqs_dtype))
|
||||||
|
freqs = freqs * (1 - freqs_mask) + freqs_base * freqs_mask
|
||||||
|
|
||||||
|
else:
|
||||||
|
theta_ntk = theta * ntk_factor
|
||||||
|
if dype and ntk_factor > 1.0:
|
||||||
|
theta_ntk = theta * (ntk_factor ** (dype_exponent * (current_timestep ** dype_exponent)))
|
||||||
|
|
||||||
|
freqs = 1.0 / (theta_ntk ** (torch.arange(0, dim, 2, dtype=freqs_dtype, device=device) / dim)) / linear_factor
|
||||||
|
|
||||||
|
freqs = torch.einsum("...s,d->...sd", pos, freqs)
|
||||||
|
|
||||||
|
if use_real and repeat_interleave_real:
|
||||||
|
freqs_cos = freqs.cos().repeat_interleave(2, dim=-1).float()
|
||||||
|
freqs_sin = freqs.sin().repeat_interleave(2, dim=-1).float()
|
||||||
|
|
||||||
|
if yarn and max_pe_len is not None and max_pe_len > ori_max_pe_len:
|
||||||
|
mscale = torch.where(scale <= 1., torch.tensor(1.0), 0.1 * torch.log(scale) + 1.0).to(scale)
|
||||||
|
freqs_cos, freqs_sin = freqs_cos * mscale, freqs_sin * mscale
|
||||||
|
return freqs_cos, freqs_sin
|
||||||
|
elif use_real:
|
||||||
|
return freqs.cos().float(), freqs.sin().float()
|
||||||
|
else:
|
||||||
|
return torch.polar(torch.ones_like(freqs), freqs)
|
||||||
Reference in New Issue
Block a user