mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
update xet and patch qk_norm defaults
Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
- **Captioning** new feature: analyze existing images for prompt adherence
|
||||
*tip*: image analysis requires larger VLM model to produce quality output
|
||||
new api endpoint: `/sdapi/v1/analyze`
|
||||
- **HF download** use `XET` by default
|
||||
see *settings -> huggingface -> download method* for options
|
||||
- **AI**
|
||||
- Cognitive analysis and improvements to *all* AI prompts
|
||||
- Automated fixes using `/check-` skills
|
||||
@@ -18,6 +20,7 @@
|
||||
- `gradio` initial hijack
|
||||
- `SmolVLM` captioning
|
||||
- `gradio` temp files guard against large image
|
||||
- `diffusers` patch custom pipelines for `qk_norm`
|
||||
|
||||
## Update for 2026-05-13
|
||||
|
||||
|
||||
+10
-13
@@ -1,7 +1,6 @@
|
||||
import os
|
||||
import time
|
||||
import gradio as gr
|
||||
from installer import install
|
||||
from modules.logger import log
|
||||
from modules.shared import opts
|
||||
|
||||
@@ -19,22 +18,20 @@ def hf_init():
|
||||
os.environ.setdefault('HF_ENABLE_PARALLEL_LOADING', 'true' if opts.sd_parallel_load else 'false')
|
||||
os.environ.setdefault('HF_HUB_CACHE', opts.hfcache_dir)
|
||||
os.environ.setdefault('HF_XET_CACHE', opts.xetcache_dir)
|
||||
if opts.hf_transfer_mode == 'requests':
|
||||
if opts.hf_transfer_mode == 'HTTP':
|
||||
os.environ.setdefault('HF_XET_HIGH_PERFORMANCE', 'false')
|
||||
os.environ.setdefault('HF_HUB_ENABLE_HF_TRANSFER', 'false')
|
||||
os.environ.setdefault('HF_HUB_DISABLE_XET', 'true')
|
||||
elif opts.hf_transfer_mode == 'rust':
|
||||
install('hf_transfer')
|
||||
elif opts.hf_transfer_mode == 'XET':
|
||||
os.environ.setdefault('HF_XET_HIGH_PERFORMANCE', 'false')
|
||||
os.environ.setdefault('HF_HUB_ENABLE_HF_TRANSFER', 'true')
|
||||
os.environ.setdefault('HF_HUB_DISABLE_XET', 'true')
|
||||
elif opts.hf_transfer_mode == 'xet':
|
||||
install('hf_xet')
|
||||
import huggingface_hub
|
||||
huggingface_hub.utils._runtime.is_xet_available = lambda: True # pylint: disable=protected-access
|
||||
os.environ.setdefault('HF_XET_HIGH_PERFORMANCE', 'true')
|
||||
os.environ.setdefault('HF_HUB_ENABLE_HF_TRANSFER', 'true')
|
||||
os.environ.setdefault('HF_HUB_DISABLE_XET', 'false')
|
||||
elif opts.hf_transfer_mode == 'XET HighPerformance':
|
||||
os.environ.setdefault('HF_XET_HIGH_PERFORMANCE', 'true')
|
||||
os.environ.setdefault('HF_HUB_DISABLE_XET', 'false')
|
||||
os.environ.setdefault('HF_XET_RECONSTRUCT_WRITE_SEQUENTIALLY', 'false')
|
||||
elif opts.hf_transfer_mode == 'XET Sequential':
|
||||
os.environ.setdefault('HF_XET_HIGH_PERFORMANCE', 'false')
|
||||
os.environ.setdefault('HF_HUB_DISABLE_XET', 'false')
|
||||
os.environ.setdefault('HF_XET_RECONSTRUCT_WRITE_SEQUENTIALLY', 'true')
|
||||
|
||||
obfuscated_token = None
|
||||
if len(opts.huggingface_token) > 0 and opts.huggingface_token.startswith('hf_'):
|
||||
|
||||
@@ -9,14 +9,14 @@ orig_xet_get = None
|
||||
|
||||
|
||||
def http_get_hijack(*args, **kwargs):
|
||||
from modules.shared import state
|
||||
from modules.shared import state, opts
|
||||
if len(args) > 0 and isinstance(args[0], str) and args[0].endswith(".json"):
|
||||
return orig_http_get(*args, **kwargs)
|
||||
jobid = state.begin('Download')
|
||||
fn = kwargs.get("displayed_filename", None)
|
||||
size = kwargs.get("expected_size", None)
|
||||
if fn and not fn.endswith(".json") and size is not None and size > 10240:
|
||||
log.debug(f'Download: type=http fn="{fn}" size={size}')
|
||||
log.debug(f'Download: type=http mode="{opts.hf_transfer_mode}" fn="{fn}" size={size}')
|
||||
debug(f'Download start: type=http args={args} kwargs={kwargs}')
|
||||
t0 = time.time()
|
||||
res = orig_http_get(*args, **kwargs)
|
||||
@@ -27,14 +27,14 @@ def http_get_hijack(*args, **kwargs):
|
||||
|
||||
|
||||
def xet_get_hijack(*args, **kwargs):
|
||||
from modules.shared import state
|
||||
from modules.shared import state, opts
|
||||
if len(args) > 0 and isinstance(args[0], str) and args[0].endswith(".json"):
|
||||
return orig_xet_get(*args, **kwargs)
|
||||
jobid = state.begin('Download')
|
||||
fn = kwargs.get("displayed_filename", None)
|
||||
size = kwargs.get("expected_size", None)
|
||||
if fn and not fn.endswith(".json"):
|
||||
log.debug(f'Download: type=xet fn="{fn}" size={size}')
|
||||
log.debug(f'Download: type=xet mode="{opts.hf_transfer_mode}" fn="{fn}" size={size}')
|
||||
debug(f'Download start: type=xet args={args} kwargs={kwargs}')
|
||||
res = orig_xet_get(*args, **kwargs)
|
||||
debug(f'Download end: type=xet res={res}')
|
||||
|
||||
@@ -606,7 +606,7 @@ def create_settings(cmd_opts):
|
||||
"huggingface_sep": OptionInfo("<h2>Huggingface</h2>", "", gr.HTML),
|
||||
"diffuser_cache_config": OptionInfo(True, "Use cached model config when available"),
|
||||
"huggingface_token": OptionInfo('', 'HuggingFace token', gr.Textbox, {"lines": 2}, secret=True, env_var='HF_TOKEN'),
|
||||
"hf_transfer_mode": OptionInfo("rust", "HuggingFace download method", gr.Radio, {"choices": ['requests', 'rust', 'xet']}),
|
||||
"hf_transfer_mode": OptionInfo("XET", "HuggingFace download method", gr.Dropdown, {"choices": ['HTTP', 'XET', 'XET HighPerformance', 'XET Sequential']}),
|
||||
"huggingface_mirror": OptionInfo('', 'HuggingFace mirror', gr.Textbox),
|
||||
"offline_mode": OptionInfo(False, 'Force offline mode', gr.Checkbox),
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
"venv": ". venv/bin/activate",
|
||||
"start": ". venv/bin/activate; python launch.py --debug",
|
||||
"localize": "node cli/localize.js",
|
||||
"packages": ". venv/bin/activate && pip install --upgrade accelerate huggingface_hub safetensors tokenizers peft pytorch_lightning pylint ruff",
|
||||
"packages": ". venv/bin/activate && pip install --upgrade accelerate huggingface_hub hf_xet safetensors tokenizers peft pytorch_lightning pylint ruff",
|
||||
"format": ". venv/bin/activate && pre-commit run --all-files",
|
||||
"format-win": "venv\\scripts\\activate && pre-commit run --all-files",
|
||||
"eslint": "eslint javascript/",
|
||||
|
||||
@@ -106,9 +106,11 @@ class FluxSingleTransformerBlock(nn.Module):
|
||||
@maybe_allow_in_graph
|
||||
class FluxTransformerBlock(nn.Module):
|
||||
def __init__(
|
||||
self, dim: int, num_attention_heads: int, attention_head_dim: int, qk_norm: str = "rms_norm", eps: float = 1e-6
|
||||
self, dim: int, num_attention_heads: int, attention_head_dim: int, qk_norm: str | bool | None = "rms_norm", eps: float = 1e-6
|
||||
):
|
||||
super().__init__()
|
||||
if isinstance(qk_norm, bool):
|
||||
qk_norm = "rms_norm" if qk_norm else None
|
||||
|
||||
self.norm1 = AdaLayerNormZero(dim)
|
||||
self.norm1_context = AdaLayerNormZero(dim)
|
||||
|
||||
@@ -440,8 +440,10 @@ class TransformerBlock(nn.Module):
|
||||
processing of `context` conditions.
|
||||
"""
|
||||
|
||||
def __init__(self, dim, num_attention_heads, attention_head_dim, qk_norm="rms_norm", eps=1e-6):
|
||||
def __init__(self, dim, num_attention_heads, attention_head_dim, qk_norm: str | bool | None = "rms_norm", eps=1e-6):
|
||||
super().__init__()
|
||||
if isinstance(qk_norm, bool):
|
||||
qk_norm = "rms_norm" if qk_norm else None
|
||||
|
||||
self.norm1 = AdaLayerNormZero(dim)
|
||||
|
||||
|
||||
@@ -23,6 +23,14 @@ from .edit_head import MetaConnector
|
||||
logger = logging.get_logger(__name__) # pylint: disable=invalid-name
|
||||
|
||||
|
||||
def _normalize_qk_norm(qk_norm: str | bool | None) -> str | None:
|
||||
"""Normalize legacy boolean qk_norm values to Diffusers-compatible strings."""
|
||||
if isinstance(qk_norm, bool):
|
||||
# Legacy checkpoints can store qk_norm as bool while current diffusers expects a string.
|
||||
return "rms_norm" if qk_norm else None
|
||||
return qk_norm
|
||||
|
||||
|
||||
class SanaLinearAttnProcessor2_0:
|
||||
r"""Processor for implementing scaled dot-product linear attention."""
|
||||
|
||||
@@ -112,7 +120,7 @@ class SanaTransformerBlock(nn.Module):
|
||||
cross_attention_dim: int = 2240,
|
||||
norm_eps: float = 1e-6,
|
||||
mlp_ratio: float = 2.5,
|
||||
qk_norm: str | None = None,
|
||||
qk_norm: str | bool | None = None,
|
||||
*,
|
||||
attention_out_bias: bool = True,
|
||||
attention_bias: bool = True,
|
||||
@@ -130,12 +138,13 @@ class SanaTransformerBlock(nn.Module):
|
||||
cross_attention_dim (int): The dimension of the cross-attention context.
|
||||
norm_eps (float): Epsilon value for layer normalization stability.
|
||||
mlp_ratio (float): Expansion ratio for the feed-forward network hidden dimension.
|
||||
qk_norm (str | None): Normalization method for Query/Key vectors.
|
||||
qk_norm (str | bool | None): Normalization method for Query/Key vectors.
|
||||
attention_out_bias (bool): Whether to include bias in the attention output projection.
|
||||
attention_bias (bool): Whether to include bias in the attention Q/K/V projections.
|
||||
norm_elementwise_affine (bool): Whether to learn affine parameters for normalization.
|
||||
"""
|
||||
super().__init__()
|
||||
qk_norm = _normalize_qk_norm(qk_norm)
|
||||
|
||||
# 1. Self Attention
|
||||
self.norm1 = nn.LayerNorm(dim, elementwise_affine=False, eps=norm_eps)
|
||||
@@ -269,7 +278,7 @@ class VIBESanaEditingModel(SanaTransformer2DModel):
|
||||
patch_size: int = 1,
|
||||
norm_eps: float = 1e-6,
|
||||
interpolation_scale: int | None = None,
|
||||
qk_norm: str | None = None,
|
||||
qk_norm: str | bool | None = None,
|
||||
timestep_scale: float = 1.0,
|
||||
input_condition_type: str = "channel_cat",
|
||||
edit_head_input_dim: int = 2048,
|
||||
@@ -299,7 +308,7 @@ class VIBESanaEditingModel(SanaTransformer2DModel):
|
||||
patch_size (int): Size of the patches extracted from the input latent.
|
||||
norm_eps (float): Epsilon for layer normalization.
|
||||
interpolation_scale (int | None): Scale factor for positional embedding interpolation.
|
||||
qk_norm (str | None): Normalization type for Query/Key (e.g., 'rms_norm').
|
||||
qk_norm (str | bool | None): Normalization type for Query/Key (e.g., 'rms_norm').
|
||||
timestep_scale (float): Scale factor for the timestep.
|
||||
input_condition_type (str): Method for conditioning on the input image. Options: 'channel_cat', 'seq_cat'.
|
||||
edit_head_input_dim (int): Input dimension for the `MetaConnector` edit head.
|
||||
@@ -311,6 +320,7 @@ class VIBESanaEditingModel(SanaTransformer2DModel):
|
||||
guidance_embeds (bool): Whether to use additional guidance embeddings.
|
||||
"""
|
||||
super(SanaTransformer2DModel, self).__init__()
|
||||
qk_norm = _normalize_qk_norm(qk_norm)
|
||||
|
||||
out_channels = out_channels or in_channels
|
||||
inner_dim = num_attention_heads * attention_head_dim
|
||||
|
||||
+2
-1
@@ -30,7 +30,8 @@ requests==2.32.3
|
||||
tqdm==4.67.3
|
||||
accelerate==1.13.0
|
||||
einops==0.8.1
|
||||
huggingface_hub==1.14.0
|
||||
huggingface_hub==1.15.0
|
||||
hf_xet==1.5.0
|
||||
numpy==2.1.2
|
||||
pandas==2.3.1
|
||||
protobuf==6.33.5
|
||||
|
||||
Reference in New Issue
Block a user