From 57e6389eeba2abf836d872a39c451f2370feacc3 Mon Sep 17 00:00:00 2001
From: awsr <43862868+awsr@users.noreply.github.com>
Date: Thu, 16 Apr 2026 22:13:26 -0700
Subject: [PATCH 01/31] Reorder logic to improve static analysis
---
modules/ui_extra_networks.py | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index 17a1c5b7e..2888e97a9 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -8,7 +8,6 @@ import html
import base64
import urllib.parse
import threading
-from typing import TYPE_CHECKING
from types import SimpleNamespace
from pathlib import Path
from html.parser import HTMLParser
@@ -881,11 +880,10 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
from modules import images
page, item = get_item(state, params)
is_style = (page is not None) and (page.title == 'Style')
- is_valid = (item is not None) and hasattr(item, 'name') and hasattr(item, 'filename')
+ is_valid = False
- if is_valid:
- if TYPE_CHECKING:
- assert item is not None # Part of the definition of "is_valid"
+ if (item is not None) and hasattr(item, 'name') and hasattr(item, 'filename'):
+ is_valid = True
stat_size, stat_mtime = modelstats.stat(item.filename)
if hasattr(item, 'size') and item.size > 0:
stat_size = item.size
From ba889d6f1bd9b5eddf4f8ef883b926c11cad9e5e Mon Sep 17 00:00:00 2001
From: awsr <43862868+awsr@users.noreply.github.com>
Date: Thu, 16 Apr 2026 22:16:21 -0700
Subject: [PATCH 02/31] Remove old now-unreachable code
---
modules/ui_extra_networks.py | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index 2888e97a9..ee49f95ac 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -890,14 +890,9 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
if hasattr(item, 'mtime') and item.mtime is not None:
stat_mtime = item.mtime
desc = item.description
- fullinfo = shared.readfile(os.path.splitext(item.filename)[0] + '.json', silent=True, as_type="dict")
- if 'modelVersions' in fullinfo: # sanitize massive objects
- fullinfo['modelVersions'] = []
- info = fullinfo
- if isinstance(info, list):
- item.filename = None
- log.warning('Network: show details not supported for compound item')
- info = None
+ info = shared.readfile(os.path.splitext(item.filename)[0] + '.json', silent=True, as_type="dict")
+ if 'modelVersions' in info: # sanitize massive objects
+ info['modelVersions'] = []
if prompt is not None and len(prompt) > 0:
item.prompt = prompt
if negative is not None and len(negative) > 0:
From ab4e284ef5a8eadd8ea11c131ec21e3ab5bbf83e Mon Sep 17 00:00:00 2001
From: awsr <43862868+awsr@users.noreply.github.com>
Date: Thu, 16 Apr 2026 22:34:30 -0700
Subject: [PATCH 03/31] Minor typing updates
---
modules/ui_extra_networks.py | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index ee49f95ac..a913dcd89 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -133,7 +133,7 @@ class DateTimeEncoder(json.JSONEncoder):
class ExtraNetworksPage:
- def __init__(self, title):
+ def __init__(self, title: str):
self.title = title
self.name = title.lower()
self.allow_negative_prompt = False
@@ -197,7 +197,7 @@ class ExtraNetworksPage:
errors.display(e, 'Network version')
return all_versions[0]
- def link_preview(self, filename):
+ def link_preview(self, filename: str):
quoted_filename = urllib.parse.quote(filename.replace('\\', '/'))
mtime = os.path.getmtime(filename) if os.path.exists(filename) else 0
preview = f"{shared.opts.subpath}/sdapi/v1/network/thumb?filename={quoted_filename}&mtime={mtime}"
@@ -255,7 +255,7 @@ class ExtraNetworksPage:
log.info(f'Network thumbnails: type={self.name} created={created}')
self.missing_thumbs.clear()
- def create_items(self, tabname):
+ def create_items(self, tabname: str):
if self.refresh_time is not None and self.refresh_time > refresh_time: # cached results
return
t0 = time.time()
@@ -275,7 +275,7 @@ class ExtraNetworksPage:
debug(f'EN create-items: page={self.name} items={len(self.items)} time={t1-t0:.2f}')
self.list_time += t1-t0
- def create_page(self, tabname, skip = False):
+ def create_page(self, tabname: str, skip = False):
debug(f'EN create-page: {self.name}')
if self.page_time > refresh_time and len(self.html) > 0: # cached page
return self.patch(self.html, tabname)
@@ -387,7 +387,7 @@ class ExtraNetworksPage:
def allowed_directories_for_previews(self):
return []
- def create_html(self, item, tabname):
+ def create_html(self, item, tabname: str):
def random_bright_color():
r = random.randint(100, 255)
g = random.randint(100, 255)
@@ -428,7 +428,7 @@ class ExtraNetworksPage:
errors.display(e, 'Networks')
return ""
- def find_preview_file(self, path):
+ def find_preview_file(self, path: str | None):
if path is None:
return 'html/missing.png'
if os.path.join('models', 'Reference') in path:
@@ -449,7 +449,7 @@ class ExtraNetworksPage:
return file
return 'html/missing.png'
- def find_preview(self, filename):
+ def find_preview(self, filename: str):
t0 = time.time()
preview_file = self.find_preview_file(filename)
self.preview_time += time.time() - t0
@@ -502,7 +502,7 @@ class ExtraNetworksPage:
debug(f'EN missing-preview: {item["name"]}')
self.preview_time += time.time() - t0
- def find_description(self, path, info=None):
+ def find_description(self, path: str | None, info=None):
t0 = time.time()
class HTMLFilter(HTMLParser):
text = ""
@@ -534,7 +534,7 @@ class ExtraNetworksPage:
self.desc_time += t1-t0
return f.text
- def find_info(self, path):
+ def find_info(self, path: str | None):
data = {}
if shared.cmd_opts.no_metadata:
return data
@@ -593,7 +593,7 @@ def register_pages():
register_page(ExtraNetworksPageTextualInversion())
-def get_pages(title=None):
+def get_pages(title: str | None = None):
visible = shared.opts.extra_networks
pages: list[ExtraNetworksPage] = []
if 'All' in visible or visible == []: # default en sort order
@@ -645,7 +645,7 @@ class ExtraNetworksUi:
self.state: gr.State = None
-def create_ui(container, button_parent, tabname, skip_indexing = False):
+def create_ui(container, button_parent: gr.Button, tabname: str, skip_indexing = False):
if 'networks' in shared.opts.ui_disabled:
return None
debug(f'EN create-ui: {tabname}')
From 609e679c553a7d1c2fe943e605d2263080aac13e Mon Sep 17 00:00:00 2001
From: awsr <43862868+awsr@users.noreply.github.com>
Date: Thu, 16 Apr 2026 22:54:09 -0700
Subject: [PATCH 04/31] Update Civit AI linking
- Minor adjustment to avoid type mixing
---
modules/ui_extra_networks.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index a913dcd89..277079223 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -969,8 +969,10 @@ def create_ui(container, button_parent: gr.Button, tabname: str, skip_indexing =
url = item.name.replace('Diffusers/', '')
url = f'https://huggingface.co/models/{url}' if url is not None else 'N/A'
else:
- url = info.get('id', None) if info is not None else None
- url = f'civitai.com/models/{url}' if url is not None else 'N/A'
+ info_id = info.get('id', None)
+ nsfw = info.get('nsfw', False) if info_id is not None else False
+ tld = "red" if nsfw else "com"
+ url = f'civitai.{tld}/models/{info_id}' if info_id is not None else 'N/A'
text = f'''
{item.name}
From c5b869a0e2b3512cf2cfd85ea30837f02a9bb5a2 Mon Sep 17 00:00:00 2001
From: awsr <43862868+awsr@users.noreply.github.com>
Date: Thu, 16 Apr 2026 22:59:39 -0700
Subject: [PATCH 05/31] Remove unreachable logic
---
modules/ui_extra_networks.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index 277079223..e599a99cd 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -967,7 +967,7 @@ def create_ui(container, button_parent: gr.Button, tabname: str, skip_indexing =
'''
if item.name.startswith('Diffusers'):
url = item.name.replace('Diffusers/', '')
- url = f'https://huggingface.co/models/{url}' if url is not None else 'N/A'
+ url = f'https://huggingface.co/models/{url}'
else:
info_id = info.get('id', None)
nsfw = info.get('nsfw', False) if info_id is not None else False
From 3e2c16e8ae8881a62e341bf6619f003292577a6e Mon Sep 17 00:00:00 2001
From: vladmandic
Date: Fri, 17 Apr 2026 13:40:43 +0200
Subject: [PATCH 06/31] cleanup and update changelog
Signed-off-by: vladmandic
---
CHANGELOG.md | 13 +++++++++----
extensions-builtin/sdnext-kanvas | 2 +-
launch.py | 10 +++++-----
wiki | 2 +-
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c702ba997..405aad5a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,20 +1,20 @@
# Change Log for SD.Next
-## Update for 2026-04-16
+## Update for 2026-04-17
-### Highlights for 2026-04-16
+### Highlights for 2026-04-17
*What's New?*
- Built-in **Tag-Autocomplete** with support for 10+ tag databases
- New models! **Zeta-Chroma**, **ERNIE**, **Nucleus**, **Bria-FIBO**, **Anima-v3**, **SDXS-1B**, **LTX 2.3 v1.1**
-- Additional Schedulers, updates to NudeNet, OpenVINO and ROCm and other features
+- Major **Kanvas** update, additional Schedulers, updates to NudeNet, OpenVINO and ROCm and other features
And tons of *quality-of-life* improvements and *bug-fixes*!
In addition, to jump on a bandwagon, we're now fully **AI agent** ready with detailed instructions and skills!
[ReadMe](https://github.com/vladmandic/automatic/blob/master/README.md) | [ChangeLog](https://github.com/vladmandic/automatic/blob/master/CHANGELOG.md) | [Docs](https://vladmandic.github.io/sdnext-docs/) | [WiKi](https://github.com/vladmandic/automatic/wiki) | [Discord](https://discord.com/invite/sd-next-federal-batch-inspectors-1101998836328697867) | [Sponsor](https://github.com/sponsors/vladmandic)
-### Details for 2026-04-16
+### Details for 2026-04-17
- **Models**
- [Zeta-Chroma](https://huggingface.co/lodestones/Zeta-Chroma) pixel-space diffusion transformer image model
@@ -63,6 +63,11 @@ In addition, to jump on a bandwagon, we're now fully **AI agent** ready with det
- **SDNQ** improvements
add quant support to `nn.Embedding` type
support fp execution according to gpu capabilities
+- **Kanvas**
+ multi-image workflow: add additional stagaes as needed (when starting generate, sdnext will use image/mask from active stage)
+ full undo/redo
+ list, select, transform any shapes
+ magic-wand paint with auto-fill and perceptual tolerance
- **UI**
- `gallery` send-to button advanced options with right-click
- `tag autocomplete` quick toggle in main prompt area
diff --git a/extensions-builtin/sdnext-kanvas b/extensions-builtin/sdnext-kanvas
index 1e840033b..faf0c77f8 160000
--- a/extensions-builtin/sdnext-kanvas
+++ b/extensions-builtin/sdnext-kanvas
@@ -1 +1 @@
-Subproject commit 1e840033b040d8915ddfb5dbf62c80f411bcec0a
+Subproject commit faf0c77f800d3eeac9d7689365fa24fe2c814dfe
diff --git a/launch.py b/launch.py
index e1c191f31..20b982331 100755
--- a/launch.py
+++ b/launch.py
@@ -182,11 +182,11 @@ def clean_server():
pass
collected = gc.collect() # python gc
modules_cleaned = sorted(sys.modules.keys())
- modules_keys = [m.split('.')[0] for m in modules_cleaned if not m.startswith('_')]
- modules_sorted = {}
- for module_key in modules_keys:
- modules_sorted[module_key] = len([m for m in modules_cleaned if m.startswith(module_key)])
- log.trace(f'Server modules: {modules_sorted}')
+ # modules_keys = [m.split('.')[0] for m in modules_cleaned if not m.startswith('_')]
+ # modules_sorted = {}
+ # for module_key in modules_keys:
+ # modules_sorted[module_key] = len([m for m in modules_cleaned if m.startswith(module_key)])
+ # log.trace(f'Server modules: {modules_sorted}')
t1 = time.time()
log.trace(f'Server modules: total={len(modules_loaded)} unloaded={len(removed_removed)} remaining={len(modules_cleaned)} gc={collected} time={t1-t0:.2f}')
diff --git a/wiki b/wiki
index 26c4d7bf5..1295f52bb 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 26c4d7bf56a4f515f6e8baa7398573eecd19a95d
+Subproject commit 1295f52bb38dedca4bd9c4cc49fdc36f68b283ec
From 576d5664295ad4a6ef7007198e8f6f65878fce6d Mon Sep 17 00:00:00 2001
From: resonantsky
Date: Fri, 17 Apr 2026 16:45:38 +0200
Subject: [PATCH 07/31] established rdna2 best configs
---
modules/sdnq/triton_mm.py | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/modules/sdnq/triton_mm.py b/modules/sdnq/triton_mm.py
index beda09f03..0a78f0b72 100644
--- a/modules/sdnq/triton_mm.py
+++ b/modules/sdnq/triton_mm.py
@@ -12,16 +12,31 @@ import torch
import triton
import triton.language as tl
+try:
+ from .common import is_rdna2
+except Exception:
+ is_rdna2 = False
-matmul_configs = [
- triton.Config({'BLOCK_SIZE_M': BM, 'BLOCK_SIZE_N': BN, "BLOCK_SIZE_K": BK, "GROUP_SIZE_M": GM}, num_warps=w, num_stages=s)
- for BM in [32, 64, 128, 256]
- for BN in [32, 64, 128, 256]
- for BK in [32, 64, 128]
- for GM in [4, 8]
- for w in [4, 8]
- for s in [2]
-]
+if is_rdna2:
+ matmul_configs = [
+ triton.Config({'BLOCK_SIZE_M': BM, 'BLOCK_SIZE_N': BN, "BLOCK_SIZE_K": BK, "GROUP_SIZE_M": GM}, num_warps=w, num_stages=s)
+ for BM in [64, 128]
+ for BN in [64, 128]
+ for BK in [64]
+ for GM in [2, 4]
+ for w in [2, 4]
+ for s in [2]
+ ]
+else:
+ matmul_configs = [
+ triton.Config({'BLOCK_SIZE_M': BM, 'BLOCK_SIZE_N': BN, "BLOCK_SIZE_K": BK, "GROUP_SIZE_M": GM}, num_warps=w, num_stages=s)
+ for BM in [32, 64, 128, 256]
+ for BN in [32, 64, 128, 256]
+ for BK in [32, 64, 128]
+ for GM in [4, 8]
+ for w in [4, 8]
+ for s in [2]
+ ]
@triton.autotune(configs=matmul_configs, key=["M", "N", "K", "stride_bk", "ACCUMULATOR_DTYPE"], cache_results=True)
From cefad871b9e1f8491addadf9b1059b2ba74fa976 Mon Sep 17 00:00:00 2001
From: resonantsky
Date: Fri, 17 Apr 2026 18:44:24 +0200
Subject: [PATCH 08/31] fix rdna2 variable name: is_rdna2 -> is_rdna2_and_older
---
modules/sdnq/triton_mm.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/modules/sdnq/triton_mm.py b/modules/sdnq/triton_mm.py
index 0a78f0b72..955761e88 100644
--- a/modules/sdnq/triton_mm.py
+++ b/modules/sdnq/triton_mm.py
@@ -13,11 +13,11 @@ import triton
import triton.language as tl
try:
- from .common import is_rdna2
+ from .common import is_rdna2_and_older
except Exception:
- is_rdna2 = False
+ is_rdna2_and_older = False
-if is_rdna2:
+if is_rdna2_and_older:
matmul_configs = [
triton.Config({'BLOCK_SIZE_M': BM, 'BLOCK_SIZE_N': BN, "BLOCK_SIZE_K": BK, "GROUP_SIZE_M": GM}, num_warps=w, num_stages=s)
for BM in [64, 128]
From 1640a9eb749bd8e5e371c6a004510cc7021c4a63 Mon Sep 17 00:00:00 2001
From: vladmandic
Date: Sat, 18 Apr 2026 12:10:03 +0200
Subject: [PATCH 09/31] set/validate xet cache
Signed-off-by: vladmandic
---
CHANGELOG.md | 12 ++++++++----
eslint.config.mjs | 2 +-
extensions-builtin/sdnext-kanvas | 2 +-
extensions-builtin/sdnext-modernui | 2 +-
modules/models_hf.py | 18 +++++++++++++-----
modules/paths.py | 1 +
modules/ui_definitions.py | 2 ++
wiki | 2 +-
8 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 405aad5a5..d1800f2cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,20 +1,21 @@
# Change Log for SD.Next
-## Update for 2026-04-17
+## Update for 2026-04-18
-### Highlights for 2026-04-17
+### Highlights for 2026-04-18
*What's New?*
- Built-in **Tag-Autocomplete** with support for 10+ tag databases
- New models! **Zeta-Chroma**, **ERNIE**, **Nucleus**, **Bria-FIBO**, **Anima-v3**, **SDXS-1B**, **LTX 2.3 v1.1**
-- Major **Kanvas** update, additional Schedulers, updates to NudeNet, OpenVINO and ROCm and other features
+- Major **Kanvas** update for enhanced inpaint/outpaint
+- Additional Schedulers, updates to NudeNet, OpenVINO and ROCm and other features
And tons of *quality-of-life* improvements and *bug-fixes*!
In addition, to jump on a bandwagon, we're now fully **AI agent** ready with detailed instructions and skills!
[ReadMe](https://github.com/vladmandic/automatic/blob/master/README.md) | [ChangeLog](https://github.com/vladmandic/automatic/blob/master/CHANGELOG.md) | [Docs](https://vladmandic.github.io/sdnext-docs/) | [WiKi](https://github.com/vladmandic/automatic/wiki) | [Discord](https://discord.com/invite/sd-next-federal-batch-inspectors-1101998836328697867) | [Sponsor](https://github.com/sponsors/vladmandic)
-### Details for 2026-04-17
+### Details for 2026-04-18
- **Models**
- [Zeta-Chroma](https://huggingface.co/lodestones/Zeta-Chroma) pixel-space diffusion transformer image model
@@ -51,6 +52,7 @@ In addition, to jump on a bandwagon, we're now fully **AI agent** ready with det
allows for any *settings* property name (as defined in `modules/ui_definitions.py` and saved to `config.json`)
- **preview** add explicit `method=None`
if you want to skip preview, but show finished images, works with batch progression
+ - add **xet cache** to *settings -> paths* and initialize on startup
- **Compute**
- **ROCm** futher work on advanced configuration and tuning, thanks @resonantsky
now covers both ROCm on Windows and Linux
@@ -63,11 +65,13 @@ In addition, to jump on a bandwagon, we're now fully **AI agent** ready with det
- **SDNQ** improvements
add quant support to `nn.Embedding` type
support fp execution according to gpu capabilities
+ enhanced `triton` kernels for RDNA2/RDNA3
- **Kanvas**
multi-image workflow: add additional stagaes as needed (when starting generate, sdnext will use image/mask from active stage)
full undo/redo
list, select, transform any shapes
magic-wand paint with auto-fill and perceptual tolerance
+ see [Kanvas Docs](https://vladmandic.github.io/sdnext-docs/Kanvas) for details
- **UI**
- `gallery` send-to button advanced options with right-click
- `tag autocomplete` quick toggle in main prompt area
diff --git a/eslint.config.mjs b/eslint.config.mjs
index eb04c771d..2f247dafa 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -168,7 +168,7 @@ const jsConfig = defineConfig([
'@stylistic/max-len': [
'warn',
{
- code: 275,
+ code: 300,
tabWidth: 2,
},
],
diff --git a/extensions-builtin/sdnext-kanvas b/extensions-builtin/sdnext-kanvas
index faf0c77f8..83dbace79 160000
--- a/extensions-builtin/sdnext-kanvas
+++ b/extensions-builtin/sdnext-kanvas
@@ -1 +1 @@
-Subproject commit faf0c77f800d3eeac9d7689365fa24fe2c814dfe
+Subproject commit 83dbace796d1a682b484f3499fc9475c4d27e00d
diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui
index 8cbc80bc4..2cec63d89 160000
--- a/extensions-builtin/sdnext-modernui
+++ b/extensions-builtin/sdnext-modernui
@@ -1 +1 @@
-Subproject commit 8cbc80bc49410c4cc436aacd0d25a3290f53630f
+Subproject commit 2cec63d8976bc8143bec7e2197219c82a61dc6e9
diff --git a/modules/models_hf.py b/modules/models_hf.py
index 7f3d3f039..c3e643b06 100644
--- a/modules/models_hf.py
+++ b/modules/models_hf.py
@@ -18,6 +18,7 @@ def hf_init():
os.environ.setdefault('HF_HUB_ETAG_TIMEOUT', '10')
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':
os.environ.setdefault('HF_XET_HIGH_PERFORMANCE', 'false')
os.environ.setdefault('HF_HUB_ENABLE_HF_TRANSFER', 'false')
@@ -42,14 +43,21 @@ def hf_init():
def hf_check_cache():
- prev_default = os.environ.get("SD_HFCACHEDIR", None) or os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'hub')
from modules.modelstats import stat
+ prev_default = os.environ.get("SD_HFCACHEDIR", None) or os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'hub')
if opts.hfcache_dir != prev_default:
size, _mtime = stat(prev_default)
- if size//1024//1024 > 16:
- log.warning(f'Cache location changed: previous="{prev_default}" size={size//1024//1024} MB')
- size, _mtime = stat(opts.hfcache_dir)
- log.debug(f'Huggingface: cache="{opts.hfcache_dir}" size={size//1024//1024} MB')
+ if size//1024//1024 > 32:
+ log.warning(f'Huggingface cache changed: type=huggingface unused="{prev_default}" size={size//1024//1024} MB')
+ prev_default = os.path.join(os.path.expanduser('~'), '.cache', 'huggingface', 'xet')
+ if opts.xetcache_dir != prev_default:
+ size, _mtime = stat(prev_default)
+ if size//1024//1024 > 32:
+ log.warning(f'Huggingface cache changed: type=xet unused="{prev_default}" size={size//1024//1024} MB')
+
+ hf_size, _mtime = stat(opts.hfcache_dir)
+ xet_size, _mtime = stat(opts.xetcache_dir)
+ log.debug(f'Huggingface: cache="{opts.hfcache_dir}" size={hf_size//1024//1024} MB xet="{opts.xetcache_dir}" size={xet_size//1024//1024} MB')
def hf_search(keyword):
diff --git a/modules/paths.py b/modules/paths.py
index 06851a6f5..0c1408f86 100644
--- a/modules/paths.py
+++ b/modules/paths.py
@@ -107,6 +107,7 @@ def create_paths(opts):
create_path(fix_path('ckpt_dir'))
create_path(fix_path('diffusers_dir'))
create_path(fix_path('hfcache_dir'))
+ create_path(fix_path('xetcache_dir'))
create_path(fix_path('vae_dir'))
create_path(fix_path('unet_dir'))
create_path(fix_path('te_dir'))
diff --git a/modules/ui_definitions.py b/modules/ui_definitions.py
index e5bbb1a5b..4b573296d 100644
--- a/modules/ui_definitions.py
+++ b/modules/ui_definitions.py
@@ -64,6 +64,7 @@ def create_settings(cmd_opts):
default_hfcache_dir = os.environ.get("SD_HFCACHEDIR", None) or os.path.join(paths.models_path, 'huggingface')
default_checkpoint = list_checkpoint_titles()[0] if len(list_checkpoint_titles()) > 0 else "model.safetensors"
+ default_xetcache_dir = os.environ.get("HF_XET_CACHE ", None) or os.path.join(paths.models_path, 'xet')
hide_dirs = {"visible": not cmd_opts.hide_ui_dir_config}
@@ -384,6 +385,7 @@ def create_settings(cmd_opts):
"ckpt_dir": OptionInfo(os.path.join(paths.models_path, 'Stable-diffusion'), "Folder with stable diffusion models", folder=True),
"diffusers_dir": OptionInfo(os.path.join(paths.models_path, 'Diffusers'), "Folder with Huggingface models", folder=True),
"hfcache_dir": OptionInfo(default_hfcache_dir, "Folder for Huggingface cache", folder=True),
+ "xetcache_dir": OptionInfo(default_xetcache_dir, "Folder for XET cache", folder=True),
"tunable_dir": OptionInfo(os.path.join(paths.models_path, 'tunable'), "Folder for Tunable ops cache", folder=True),
"vae_dir": OptionInfo(os.path.join(paths.models_path, 'VAE'), "Folder with VAE files", folder=True),
"unet_dir": OptionInfo(os.path.join(paths.models_path, 'UNET'), "Folder with UNET files", folder=True),
diff --git a/wiki b/wiki
index 1295f52bb..90887c335 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 1295f52bb38dedca4bd9c4cc49fdc36f68b283ec
+Subproject commit 90887c3356ec6231e0749c9ba5ad9ae1f76eb53a
From 5f99160d5b80a88c791c63dd7647a87d1a3ef0f1 Mon Sep 17 00:00:00 2001
From: Oleksandr Liutyi
Date: Sat, 18 Apr 2026 13:55:26 +0000
Subject: [PATCH 10/31] ERNIE covers recreated incl. int4 versions
---
data/reference-quant.json | 4 ++--
...T--ERNIE_Image_Turbo_sdnq_dynamic_int4.jpg | Bin 0 -> 360800 bytes
.../OzzyGT--ERNIE_Image_sdnq_dynamic_int4.jpg | Bin 0 -> 89052 bytes
models/Reference/baidu--ERNIE-Image-Turbo.jpg | Bin 95877 -> 102159 bytes
models/Reference/baidu--ERNIE-Image.jpg | Bin 78083 -> 91086 bytes
5 files changed, 2 insertions(+), 2 deletions(-)
create mode 100644 models/Reference/OzzyGT--ERNIE_Image_Turbo_sdnq_dynamic_int4.jpg
create mode 100644 models/Reference/OzzyGT--ERNIE_Image_sdnq_dynamic_int4.jpg
diff --git a/data/reference-quant.json b/data/reference-quant.json
index 0869aa52c..edeb0dbf2 100644
--- a/data/reference-quant.json
+++ b/data/reference-quant.json
@@ -238,7 +238,7 @@
},
"Baidu ERNIE-Image sdnq-dynamic-int4": {
"path": "OzzyGT/ERNIE_Image_sdnq_dynamic_int4",
- "preview": "baidu--ERNIE-Image.jpg",
+ "preview": "OzzyGT--ERNIE_Image_sdnq_dynamic_int4.jpg",
"desc": "ERNIE-Image is a text-to-image diffusion transformer model that combines a Mistral3 text encoder with a FlowMatch transformer and Flux2-style VAE for 1024px image generation.",
"skip": true,
"extras": "sampler: Default, cfg_scale: 4.0, steps: 50",
@@ -247,7 +247,7 @@
},
"Baidu ERNIE-Image-Turbo sdnq-dynamic-int4": {
"path": "OzzyGT/ERNIE_Image_Turbo_sdnq_dynamic_int4",
- "preview": "baidu--ERNIE-Image-Turbo.jpg",
+ "preview": "OzzyGT--ERNIE_Image_Turbo_sdnq_dynamic_int4.jpg",
"desc": "ERNIE-Image-Turbo is a distilled ERNIE-Image variant optimized for fast generation with fewer denoising steps.",
"skip": true,
"extras": "sampler: Default, cfg_scale: 1.0, steps: 8",
diff --git a/models/Reference/OzzyGT--ERNIE_Image_Turbo_sdnq_dynamic_int4.jpg b/models/Reference/OzzyGT--ERNIE_Image_Turbo_sdnq_dynamic_int4.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e07a1d19a2075b827dd2690323f651bb41358149
GIT binary patch
literal 360800
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