|
37 | 37 | module = importlib.util.module_from_spec(spec)
|
38 | 38 | sys.modules[module_name] = module
|
39 | 39 | spec.loader.exec_module(module)
|
| 40 | +import comfy_extras |
40 | 41 | from nodes_upscale_model import UpscaleModelLoader, ImageUpscaleWithModel
|
41 | 42 | from comfy.model_management import soft_empty_cache, free_memory, get_torch_device, current_loaded_models, load_model_gpu
|
42 | 43 | from nodes import LoraLoader, ConditioningAverage, common_ksampler, ImageScale, ImageScaleBy, VAEEncode, VAEDecode
|
@@ -320,11 +321,12 @@ def process_wildcard_syntax(text, seed):
|
320 | 321 | # wildcard sytax is {like|this}
|
321 | 322 | # select a random word from the | separated list
|
322 | 323 | random.seed(seed)
|
323 |
| - wc_re = re.compile(r'{([^}]+)}') |
| 324 | + wc_re = re.compile(r'{([^{}]*)}') |
324 | 325 | def repl(m):
|
325 |
| - return random.choice(m.group(1).split('|')) |
326 |
| - for m in wc_re.finditer(text): |
327 |
| - text = text.replace(m.group(0), repl(m)) |
| 326 | + parts = m.group(1).split('|') |
| 327 | + return random.choice(parts) |
| 328 | + while wc_re.search(text): |
| 329 | + text = wc_re.sub(repl, text) |
328 | 330 | return text
|
329 | 331 |
|
330 | 332 | def search_and_replace(text, extra_pnginfo, prompt):
|
@@ -5212,6 +5214,122 @@ def process(self, positive_prompt, negative_prompt, clip, option_positive_clip_l
|
5212 | 5214 | [[negative_conditioning, {'pooled_output': negative_pooled}]],
|
5213 | 5215 | )
|
5214 | 5216 |
|
| 5217 | +# model merge PixArtSigmaXL2_1024MS |
| 5218 | +# blocks.0 to 27 |
| 5219 | +# final_layer, pos_embed, t_block.1, t_embedder, x_embedder, y_embedder |
| 5220 | +class ModelMergePixArtSigmaXL2_1024MS(comfy_extras.nodes_model_merging.ModelMergeBlocks): |
| 5221 | + CATEGORY = 'Mikey/Model Merging/model_specific' |
| 5222 | + |
| 5223 | + @classmethod |
| 5224 | + def INPUT_TYPES(s): |
| 5225 | + arg_dict = {'model1': ('MODEL',), |
| 5226 | + 'model2': ('MODEL',)} |
| 5227 | + |
| 5228 | + argument = ('FLOAT', {'default': 1.0, 'min': 0.0, 'max': 1.0, 'step': 0.01}) |
| 5229 | + |
| 5230 | + for i in range(28): |
| 5231 | + arg_dict['blocks.{}.'.format(i)] = argument |
| 5232 | + |
| 5233 | + arg_dict['final_layer'] = argument |
| 5234 | + arg_dict['pos_embed'] = argument |
| 5235 | + arg_dict['t_block.1'] = argument |
| 5236 | + arg_dict['t_embedder'] = argument |
| 5237 | + arg_dict['x_embedder'] = argument |
| 5238 | + arg_dict['y_embedder'] = argument |
| 5239 | + |
| 5240 | + return {'required': arg_dict} |
| 5241 | + |
| 5242 | +class ModelMergeTrainDiff: |
| 5243 | + # https://github.com/hako-mikan/sd-webui-supermerger |
| 5244 | + @classmethod |
| 5245 | + def INPUT_TYPES(s): |
| 5246 | + return {'required': {'model1': ('MODEL',), |
| 5247 | + 'model2': ('MODEL',), |
| 5248 | + 'model3': ('MODEL',), |
| 5249 | + 'ratio': ('FLOAT', {'default': 1.0, 'min': -10.0, 'max': 10.0, 'step': 0.01})}} |
| 5250 | + |
| 5251 | + RETURN_TYPES = ('MODEL',) |
| 5252 | + FUNCTION = 'traindiff' |
| 5253 | + CATEGORY = 'Mikey/Model Merging' |
| 5254 | + |
| 5255 | + def traindiff(self, model1, model2, model3, **kwargs): |
| 5256 | + theta_0 = model1.clone() |
| 5257 | + m = model1.clone() |
| 5258 | + mp = m.get_key_patches("diffusion_model.") |
| 5259 | + theta_1 = model2.get_key_patches("diffusion_model.") |
| 5260 | + theta_2 = model3.get_key_patches("diffusion_model.") |
| 5261 | + |
| 5262 | + default_ratio = next(iter(kwargs.values())) |
| 5263 | + |
| 5264 | + for k in mp: |
| 5265 | + ratio = default_ratio |
| 5266 | + k_unet = k[len("diffusion_model."):] |
| 5267 | + |
| 5268 | + last_arg_size = 0 |
| 5269 | + for arg in kwargs: |
| 5270 | + if k_unet.startswith(arg) and last_arg_size < len(arg): |
| 5271 | + ratio = kwargs[arg] |
| 5272 | + last_arg_size = len(arg) |
| 5273 | + |
| 5274 | + diff_AB = theta_1[k][0].float() - theta_2[k][0].float() |
| 5275 | + |
| 5276 | + distance_A0 = torch.abs(theta_1[k][0].float() - theta_2[k][0].float()) |
| 5277 | + distance_A1 = torch.abs(theta_1[k][0].float() - mp[k][0].float()) |
| 5278 | + |
| 5279 | + sum_distances = distance_A0 + distance_A1 |
| 5280 | + |
| 5281 | + scale = torch.where(sum_distances != 0, distance_A1 / sum_distances, torch.tensor(0.).float()) |
| 5282 | + sign_scale = torch.sign(theta_1[k][0].float() - theta_2[k][0].float()) |
| 5283 | + scale = sign_scale * torch.abs(scale) |
| 5284 | + |
| 5285 | + new_diff = scale * torch.abs(diff_AB) |
| 5286 | + weight = new_diff * (ratio*1.8) |
| 5287 | + mp[k] = (weight,) |
| 5288 | + theta_0.add_patches({k: mp[k]}, 1.0, 1.0) |
| 5289 | + return (theta_0,) |
| 5290 | + |
| 5291 | +class ModelMergeTrainDiffPixartSigmaXL2_1024MS(ModelMergeTrainDiff): |
| 5292 | + CATEGORY = 'Mikey/Model Merging/Model Specific' |
| 5293 | + |
| 5294 | + @classmethod |
| 5295 | + def INPUT_TYPES(s): |
| 5296 | + arg_dict = {'model1': ('MODEL',), |
| 5297 | + 'model2': ('MODEL',), |
| 5298 | + 'model3': ('MODEL',)} |
| 5299 | + |
| 5300 | + argument = ('FLOAT', {'default': 1.0, 'min': -10.0, 'max': 10.0, 'step': 0.01}) |
| 5301 | + |
| 5302 | + for i in range(28): |
| 5303 | + arg_dict['blocks.{}.'.format(i)] = argument |
| 5304 | + |
| 5305 | + arg_dict['final_layer'] = argument |
| 5306 | + arg_dict['pos_embed'] = argument |
| 5307 | + arg_dict['t_block.1'] = argument |
| 5308 | + arg_dict['t_embedder'] = argument |
| 5309 | + arg_dict['x_embedder'] = argument |
| 5310 | + arg_dict['y_embedder'] = argument |
| 5311 | + |
| 5312 | + return {'required': arg_dict} |
| 5313 | + |
| 5314 | +class CheckpointSaveModelOnly: |
| 5315 | + def __init__(self): |
| 5316 | + self.output_dir = folder_paths.get_output_directory() |
| 5317 | + |
| 5318 | + @classmethod |
| 5319 | + def INPUT_TYPES(s): |
| 5320 | + return {"required": { "model": ("MODEL",), |
| 5321 | + "vae": ("VAE",), |
| 5322 | + "filename_prefix": ("STRING", {"default": "checkpoints/ComfyUI"}),}, |
| 5323 | + "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},} |
| 5324 | + RETURN_TYPES = () |
| 5325 | + FUNCTION = "save" |
| 5326 | + OUTPUT_NODE = True |
| 5327 | + |
| 5328 | + CATEGORY = "Mikey/Model Merging" |
| 5329 | + |
| 5330 | + def save(self, model, vae, filename_prefix, clip=None, prompt=None, extra_pnginfo=None): |
| 5331 | + comfy_extras.nodes_model_merging.save_checkpoint(model, clip=clip, vae=vae, filename_prefix=filename_prefix, output_dir=self.output_dir, prompt=prompt, extra_pnginfo=extra_pnginfo) |
| 5332 | + return {} |
5215 | 5333 |
|
5216 | 5334 | NODE_CLASS_MAPPINGS = {
|
5217 | 5335 | 'Wildcard Processor': WildcardProcessor,
|
@@ -5281,7 +5399,11 @@ def process(self, positive_prompt, negative_prompt, clip, option_positive_clip_l
|
5281 | 5399 | 'MosaicExpandImage': MosaicExpandImage,
|
5282 | 5400 | 'GetSubdirectories': GetSubdirectories,
|
5283 | 5401 | 'TextPadderMikey': TextPadderMikey,
|
5284 |
| - 'SD3TextConditioningWithOptionsOnePrompt': SD3TextConditioningWithOptionsOnePrompt |
| 5402 | + 'SD3TextConditioningWithOptionsOnePrompt': SD3TextConditioningWithOptionsOnePrompt, |
| 5403 | + 'ModelMergePixArtSigmaXL2_1024MS': ModelMergePixArtSigmaXL2_1024MS, |
| 5404 | + 'ModelMergeTrainDiff': ModelMergeTrainDiff, |
| 5405 | + 'ModelMergeTrainDiffPixartSigmaXL2_1024MS': ModelMergeTrainDiffPixartSigmaXL2_1024MS, |
| 5406 | + 'CheckpointSaveModelOnly': CheckpointSaveModelOnly, |
5285 | 5407 | }
|
5286 | 5408 |
|
5287 | 5409 | NODE_DISPLAY_NAME_MAPPINGS = {
|
@@ -5352,5 +5474,9 @@ def process(self, positive_prompt, negative_prompt, clip, option_positive_clip_l
|
5352 | 5474 | 'MosaicExpandImage': 'Mosaic Expand Image (Mikey)',
|
5353 | 5475 | 'GetSubdirectories': 'Get Subdirectories (Mikey)',
|
5354 | 5476 | 'TextPadderMikey': 'Text Padder (Mikey)',
|
5355 |
| - 'SD3TextConditioningWithOptionsOnePrompt': 'SD3 Text Conditioning With Options. One Prompt (Mikey)' |
| 5477 | + 'SD3TextConditioningWithOptionsOnePrompt': 'SD3 Text Conditioning With Options. One Prompt (Mikey)', |
| 5478 | + 'ModelMergePixArtSigmaXL2_1024MS': 'Model Merge PixArtSigmaXL2_1024MS (Mikey)', |
| 5479 | + 'ModelMergeTrainDiff': 'Train Diff (Mikey)', |
| 5480 | + 'ModelMergeTrainDiffPixartSigmaXL2_1024MS': 'Train Diff PixArtSigmaXL2_1024MS (Mikey)', |
| 5481 | + 'CheckpointSaveModelOnly': 'Save Model Only (Mikey)', |
5356 | 5482 | }
|
0 commit comments