From b38167314367e4ca9d7d1587cd9ed026a2aff553 Mon Sep 17 00:00:00 2001 From: CalamitousFelicitousness Date: Sun, 26 Jul 2026 21:36:07 +0100 Subject: [PATCH] feat(xyz): lora block weight axis String axis rewriting every lora tag in the prompt: an existing lbw= argument is replaced, None removes it for a clean baseline cell. Choices list the preset names; raw vectors go through csv mode with escaped commas. Long values truncate in the grid legend. --- scripts/xyz/xyz_grid_classes.py | 4 ++++ scripts/xyz/xyz_grid_shared.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/scripts/xyz/xyz_grid_classes.py b/scripts/xyz/xyz_grid_classes.py index 198d93c91..2f1ed59bf 100644 --- a/scripts/xyz/xyz_grid_classes.py +++ b/scripts/xyz/xyz_grid_classes.py @@ -19,6 +19,9 @@ from scripts.xyz.xyz_grid_shared import ( # pylint: disable=no-name-in-module, u list_lora, apply_lora, apply_lora_strength, + list_lora_blocks, + apply_lora_blocks, + format_value_trim, apply_te, apply_guidance, apply_styles, @@ -217,6 +220,7 @@ axis_options = [ AxisOption("[Prompt] Prompt parser", str, apply_setting("prompt_attention"), choices=lambda: ["native", "compel", "xhinker", "a1111", "fixed"]), AxisOption("[Network] LoRA", str, apply_lora, cost=0.5, choices=list_lora), AxisOption("[Network] LoRA strength", float, apply_lora_strength, cost=0.6), + AxisOption("[Network] LoRA block weight", str, apply_lora_blocks, cost=0.6, fmt=format_value_trim, choices=list_lora_blocks), AxisOption("[Network] LoRA stack mode", str, apply_setting("lora_stack_mode"), cost=0.6, choices=lambda: ["sum", "ties", "dare_ties", "dare_linear", "magnitude_prune", "klora", "estlora"]), AxisOption("[Network] LoRA stack density", float, apply_setting("lora_stack_density"), cost=0.6), AxisOption("[Network] LoRA stack ramp", float, apply_setting("lora_stack_alpha"), cost=0.6), diff --git a/scripts/xyz/xyz_grid_shared.py b/scripts/xyz/xyz_grid_shared.py index b90d37848..af6b30b77 100644 --- a/scripts/xyz/xyz_grid_shared.py +++ b/scripts/xyz/xyz_grid_shared.py @@ -260,6 +260,31 @@ def apply_lora_strength(p, x, xs): shared.opts.data['extra_networks_default_multiplier'] = x +def list_lora_blocks(): + from modules.lora import lora_blocks + from modules.merging.merge_presets import BLOCK_WEIGHTS_PRESETS, SDXL_BLOCK_WEIGHTS_PRESETS + return ['None'] + list(lora_blocks.CLASSIC) + list(lora_blocks.CHAIN_NAMES) + sorted(BLOCK_WEIGHTS_PRESETS) + sorted(SDXL_BLOCK_WEIGHTS_PRESETS) + + +re_lora_tag = re.compile(r']+)>') + + +def apply_lora_blocks(p, x, xs): + x = str(x or '').strip() + if ':' in x or '>' in x: + log.error(f'XYZ grid apply LoRA block weight: value="{x}" invalid characters') + return + def rewrite(m): + items = [i for i in m.group(1).split(':') if not i.lower().startswith('lbw=')] + if x and x.lower() != 'none': + items.append(f'lbw={x}') + return '' + p.prompt = re_lora_tag.sub(rewrite, p.prompt) + p.all_prompts = None # a populated list would shadow the edited prompt in processing + p.all_negative_prompts = None + log.debug(f'XYZ grid apply LoRA block weight: "{x}"') + + def apply_te(p, x, xs): shared.opts.data["sd_text_encoder"] = x sd_models.reload_text_encoder() @@ -383,6 +408,13 @@ def format_value_join_list(p, opt, x): return ", ".join(x) +def format_value_trim(p, opt, x): + x = str(x) + if len(x) > 40: + x = x[:37] + '...' # block-weight vectors would flood the grid legend + return f"{opt.label}: {x}" + + def do_nothing(p, x, xs): pass