From fc514b4fb5b11493f58daba05b5dd2368570c650 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 13 Sep 2023 23:42:05 +0900 Subject: [PATCH] improve: lora block weight - support sub block weight --- __init__.py | 2 +- js/lora_block_weight.js | 70 ++++++++++++++++++++++++++++++------- lora_block_weight.py | 74 +++++++++++++++++++++++++++------------- resources/lbw-preset.txt | 17 +++++++++ 4 files changed, 126 insertions(+), 37 deletions(-) diff --git a/__init__.py b/__init__.py index 7d3f959..1c95c2a 100644 --- a/__init__.py +++ b/__init__.py @@ -7,7 +7,7 @@ import importlib -print(f"### Loading: ComfyUI-Inspire-Pack (V0.10)") +print(f"### Loading: ComfyUI-Inspire-Pack (V0.11)") node_list = [ "lora_block_weight", diff --git a/js/lora_block_weight.js b/js/lora_block_weight.js index 933d4e7..9b9c73c 100644 --- a/js/lora_block_weight.js +++ b/js/lora_block_weight.js @@ -40,20 +40,66 @@ app.registerExtension({ if(!value.startsWith('@') && node.widgets[vector_i].value != "") node.widgets[vector_i].value += "\n"; if(value.startsWith('@')) { - let n = parseInt(value.split(':')[1]); - node.widgets[vector_i].value = ""; - for(let i=1; i<=n; i++) { - var temp = ""; - for(let j=1; j<=n; j++) { - if(temp!='') - temp += ','; - if(j==i) - temp += 'A'; - else - temp += '0'; + let spec = value.split(':')[1]; + var n; + var sub_n = null; + var block = null; + + if(isNaN(spec)) { + let sub_spec = spec.split(','); + + if(sub_spec.length != 3) { + node.widgets_values[vector_i] = '!! SPEC ERROR !!'; + node._value = ''; + return; } - node.widgets[vector_i].value += `B${i}:${temp}\n`; + n = parseInt(sub_spec[0].trim()); + sub_n = parseInt(sub_spec[1].trim()); + block = parseInt(sub_spec[2].trim()); + } + else { + n = parseInt(spec.trim()); + } + + node.widgets[vector_i].value = ""; + if(sub_n == null) { + for(let i=1; i<=n; i++) { + var temp = ""; + for(let j=1; j<=n; j++) { + if(temp!='') + temp += ','; + if(j==i) + temp += 'A'; + else + temp += '0'; + } + + node.widgets[vector_i].value += `B${i}:${temp}\n`; + } + } + else { + for(let i=1; i<=sub_n; i++) { + var temp = ""; + for(let j=1; j<=n; j++) { + if(temp!='') + temp += ','; + + if(block!=j) + temp += '0'; + else { + temp += ' '; + for(let k=1; k<=sub_n; k++) { + if(k==i) + temp += 'A '; + else + temp += '0 '; + } + } + } + + node.widgets[vector_i].value += `B${block}.SUB${i}:${temp}\n`; + } } } else { diff --git a/lora_block_weight.py b/lora_block_weight.py index 634d9e8..aa716cf 100644 --- a/lora_block_weight.py +++ b/lora_block_weight.py @@ -10,6 +10,7 @@ import re from server import PromptServer from .libs import utils + def is_numeric_string(input_str): return re.match(r'^-?\d+(\.\d+)?$', input_str) is not None @@ -67,31 +68,48 @@ class LoraLoaderBlockWeight: return False for x in vectors: - if x not in ['R', 'r', 'U', 'u', 'A', 'a', 'B', 'b'] and not is_numeric_string(x): - return False + if x in ['R', 'r', 'U', 'u', 'A', 'a', 'B', 'b'] or is_numeric_string(x): + continue + else: + subvectors = x.strip().split(' ') + for y in subvectors: + y = y.strip() + if y not in ['R', 'r', 'U', 'u', 'A', 'a', 'B', 'b'] and not is_numeric_string(y): + return False return True @staticmethod def convert_vector_value(A, B, vector_value): - if vector_value in ['U', 'u']: - ratio = np.random.uniform(-1.5, 1.5) - ratio = round(ratio, 2) - elif vector_value in ['R', 'r']: - ratio = np.random.uniform(0, 3.0) - ratio = round(ratio, 2) - elif vector_value == 'A': - ratio = A - elif vector_value == 'a': - ratio = A/2 - elif vector_value == 'B': - ratio = B - elif vector_value == 'b': - ratio = B/2 - else: - ratio = float(vector_value) + def simple_vector(x): + if x in ['U', 'u']: + ratio = np.random.uniform(-1.5, 1.5) + ratio = round(ratio, 2) + elif x in ['R', 'r']: + ratio = np.random.uniform(0, 3.0) + ratio = round(ratio, 2) + elif x == 'A': + ratio = A + elif x == 'a': + ratio = A/2 + elif x == 'B': + ratio = B + elif x == 'b': + ratio = B/2 + elif is_numeric_string(x): + ratio = float(x) + else: + ratio = None - return ratio + return ratio + + v = simple_vector(vector_value) + if v is not None: + ratios = [v] + else: + ratios = [simple_vector(x) for x in vector_value.split(" ")] + + return ratios @staticmethod def norm_value(value): # make to int if 1.0 or 0.0 @@ -126,7 +144,6 @@ class LoraLoaderBlockWeight: last_k_unet_num = None new_modelpatcher = model.clone() - ratio = strength_model populated_ratio = strength_model def parse_unet_num(s): @@ -162,9 +179,11 @@ class LoraLoaderBlockWeight: # prepare patch np.random.seed(seed % (2**31)) populated_vector_list = [] + ratios = [] for k, v, k_unet_num, k_unet in (input_blocks + middle_blocks + output_blocks): if last_k_unet_num != k_unet_num and len(vector) > vector_i: - ratio = LoraLoaderBlockWeight.convert_vector_value(A, B, vector[vector_i].strip()) + ratios = LoraLoaderBlockWeight.convert_vector_value(A, B, vector[vector_i].strip()) + ratio = ratios.pop(0) if inverse: populated_ratio = 1 - ratio @@ -174,6 +193,14 @@ class LoraLoaderBlockWeight: populated_vector_list.append(LoraLoaderBlockWeight.norm_value(populated_ratio)) vector_i += 1 + else: + if len(ratios) > 0: + ratio = ratios.pop(0) + + if inverse: + populated_ratio = 1 - ratio + else: + populated_ratio = ratio last_k_unet_num = k_unet_num @@ -184,12 +211,11 @@ class LoraLoaderBlockWeight: # print(f"\t{k_unet} -> ({ratio}) ") # prepare base patch - ratio = LoraLoaderBlockWeight.convert_vector_value(A, B, vector[0].strip()) + ratios = LoraLoaderBlockWeight.convert_vector_value(A, B, vector[0].strip()) + ratio = ratios.pop(0) if inverse: populated_ratio = 1 - ratio - else: - populated_ratio = ratio populated_vector_list.insert(0, LoraLoaderBlockWeight.norm_value(populated_ratio)) diff --git a/resources/lbw-preset.txt b/resources/lbw-preset.txt index b1459a1..7150695 100644 --- a/resources/lbw-preset.txt +++ b/resources/lbw-preset.txt @@ -25,5 +25,22 @@ SDXL-INALL:1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 SDXL-MIDALL:1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0 SDXL-OUTALL:1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1 @SD-FULL-TEST:17 +@SD-BLOCK1-TEST:17,12,1 +@SD-BLOCK2-TEST:17,12,2 +@SD-BLOCK3-TEST:17,12,3 +@SD-BLOCK4-TEST:17,12,4 +@SD-BLOCK5-TEST:17,12,5 +@SD-BLOCK6-TEST:17,12,6 +@SD-BLOCK7-TEST:17,12,7 +@SD-BLOCK8-TEST:17,12,8 +@SD-BLOCK9-TEST:17,12,9 +@SD-BLOCK10-TEST:17,12,10 +@SD-BLOCK11-TEST:17,12,11 +@SD-BLOCK12-TEST:17,12,12 +@SD-BLOCK13-TEST:17,12,13 +@SD-BLOCK14-TEST:17,12,14 +@SD-BLOCK15-TEST:17,12,15 +@SD-BLOCK16-TEST:17,12,16 +@SD-BLOCK17-TEST:17,12,17 @SD-LyC-FULL-TEST:27 @SDXL-FULL-TEST:20 \ No newline at end of file