mirror of
https://github.com/lllyasviel/stable-diffusion-webui-forge.git
synced 2026-07-21 21:01:24 +08:00
support Mugen
This commit is contained in:
parent
f357202574
commit
1e3dfb0a06
@ -15,7 +15,6 @@ class Anima(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"qwen3_06b": huggingface_components["text_encoder"]}, tokenizer_dict={"qwen3_06b": huggingface_components["tokenizer"], "t5xxl": huggingface_components["tokenizer_2"]})
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ class Chroma(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"t5xxl": huggingface_components["text_encoder"]}, tokenizer_dict={"t5xxl": huggingface_components["tokenizer"]})
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@ class Flux(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"clip_l": huggingface_components["text_encoder"], "t5xxl": huggingface_components["text_encoder_2"]}, tokenizer_dict={"clip_l": huggingface_components["tokenizer"], "t5xxl": huggingface_components["tokenizer_2"]})
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ class Flux2(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"qwen3": huggingface_components["text_encoder"]}, tokenizer_dict={"qwen3": huggingface_components["tokenizer"]})
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ class Lumina2(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"gemma2": huggingface_components["text_encoder"]}, tokenizer_dict={"gemma2": huggingface_components["tokenizer"]})
|
||||
|
||||
|
||||
123
backend/diffusion_engine/mugen.py
Normal file
123
backend/diffusion_engine/mugen.py
Normal file
@ -0,0 +1,123 @@
|
||||
import torch
|
||||
from huggingface_guess import model_list
|
||||
|
||||
from backend import memory_management
|
||||
from backend.args import dynamic_args
|
||||
from backend.diffusion_engine.base import ForgeDiffusionEngine, ForgeObjects
|
||||
from backend.modules.k_prediction import PredictionDiscreteFlow
|
||||
from backend.nn.unet import Timestep
|
||||
from backend.patcher.clip import CLIP
|
||||
from backend.patcher.unet import UnetPatcher
|
||||
from backend.patcher.vae import VAE
|
||||
from backend.text_processing.classic_engine import ClassicTextProcessingEngine
|
||||
from modules.shared import opts
|
||||
|
||||
|
||||
class Mugen(ForgeDiffusionEngine):
|
||||
matched_guesses = [model_list.Mugen]
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
|
||||
clip = CLIP(model_dict={"clip_l": huggingface_components["text_encoder"], "clip_g": huggingface_components["text_encoder_2"]}, tokenizer_dict={"clip_l": huggingface_components["tokenizer"], "clip_g": huggingface_components["tokenizer_2"]})
|
||||
|
||||
vae = VAE(model=huggingface_components["vae"], is_mugen=True)
|
||||
|
||||
k_predictor = PredictionDiscreteFlow(estimated_config)
|
||||
unet = UnetPatcher.from_model(model=huggingface_components["unet"], diffusers_scheduler=None, k_predictor=k_predictor, config=estimated_config)
|
||||
|
||||
self.text_processing_engine_l = ClassicTextProcessingEngine(
|
||||
text_encoder=clip.cond_stage_model.clip_l,
|
||||
tokenizer=clip.tokenizer.clip_l,
|
||||
embedding_dir=dynamic_args.embedding_dir,
|
||||
embedding_key="clip_l",
|
||||
embedding_expected_shape=2048,
|
||||
text_projection=False,
|
||||
minimal_clip_skip=2,
|
||||
clip_skip=2,
|
||||
return_pooled=False,
|
||||
final_layer_norm=False,
|
||||
)
|
||||
|
||||
self.text_processing_engine_g = ClassicTextProcessingEngine(
|
||||
text_encoder=clip.cond_stage_model.clip_g,
|
||||
tokenizer=clip.tokenizer.clip_g,
|
||||
embedding_dir=dynamic_args.embedding_dir,
|
||||
embedding_key="clip_g",
|
||||
embedding_expected_shape=2048,
|
||||
text_projection=True,
|
||||
minimal_clip_skip=2,
|
||||
clip_skip=2,
|
||||
return_pooled=True,
|
||||
final_layer_norm=False,
|
||||
)
|
||||
|
||||
self.embedder = Timestep(256)
|
||||
|
||||
self.forge_objects = ForgeObjects(unet=unet, clip=clip, vae=vae, clipvision=None)
|
||||
self.forge_objects_original = self.forge_objects.shallow_copy()
|
||||
self.forge_objects_after_applying_lora = self.forge_objects.shallow_copy()
|
||||
|
||||
# WebUI Legacy
|
||||
self.is_sdxl = True
|
||||
|
||||
def set_clip_skip(self, clip_skip):
|
||||
self.text_processing_engine_l.clip_skip = clip_skip
|
||||
self.text_processing_engine_g.clip_skip = clip_skip
|
||||
|
||||
@torch.inference_mode()
|
||||
def get_learned_conditioning(self, prompt: list[str]):
|
||||
memory_management.load_model_gpu(self.forge_objects.clip.patcher)
|
||||
|
||||
shift = getattr(prompt, "distilled_cfg_scale", 3.0)
|
||||
self.forge_objects.unet.model.predictor.set_parameters(shift=shift)
|
||||
memory_management.logger.debug(f"Shift: {shift}")
|
||||
|
||||
cond_l = self.text_processing_engine_l(prompt)
|
||||
cond_g, clip_pooled = self.text_processing_engine_g(prompt)
|
||||
|
||||
width = getattr(prompt, "width", 1024) or 1024
|
||||
height = getattr(prompt, "height", 1024) or 1024
|
||||
|
||||
crop_w = opts.sdxl_crop_left
|
||||
crop_h = opts.sdxl_crop_top
|
||||
target_width = width
|
||||
target_height = height
|
||||
|
||||
out = [self.embedder(torch.Tensor([height])), self.embedder(torch.Tensor([width])), self.embedder(torch.Tensor([crop_h])), self.embedder(torch.Tensor([crop_w])), self.embedder(torch.Tensor([target_height])), self.embedder(torch.Tensor([target_width]))]
|
||||
|
||||
flat = torch.flatten(torch.cat(out)).unsqueeze(dim=0).repeat(clip_pooled.shape[0], 1).to(clip_pooled)
|
||||
|
||||
if opts.sdxl_zero_neg and getattr(prompt, "is_negative_prompt", False) and all(x == "" for x in prompt):
|
||||
clip_pooled = torch.zeros_like(clip_pooled)
|
||||
cond_l = torch.zeros_like(cond_l)
|
||||
cond_g = torch.zeros_like(cond_g)
|
||||
|
||||
# ensure cond_l and cond_g have the same length
|
||||
max_len = max(cond_l.shape[1], cond_g.shape[1])
|
||||
cond_l = torch.cat([cond_l, cond_l.new_zeros(cond_l.size(0), max_len - cond_l.shape[1], cond_l.size(2))], dim=1)
|
||||
cond_g = torch.cat([cond_g, cond_g.new_zeros(cond_g.size(0), max_len - cond_g.shape[1], cond_g.size(2))], dim=1)
|
||||
|
||||
cond = dict(
|
||||
crossattn=torch.cat([cond_l, cond_g], dim=2),
|
||||
vector=torch.cat([clip_pooled, flat], dim=1),
|
||||
)
|
||||
|
||||
return cond
|
||||
|
||||
@torch.inference_mode()
|
||||
def get_prompt_lengths_on_ui(self, prompt):
|
||||
_, token_count = self.text_processing_engine_l.process_texts([prompt])
|
||||
return token_count, self.text_processing_engine_l.get_target_prompt_token_count(token_count)
|
||||
|
||||
@torch.inference_mode()
|
||||
def encode_first_stage(self, x):
|
||||
sample = self.forge_objects.vae.encode(x.movedim(1, -1) * 0.5 + 0.5)
|
||||
sample = self.forge_objects.vae.first_stage_model.process_in(sample)
|
||||
return sample.to(x)
|
||||
|
||||
@torch.inference_mode()
|
||||
def decode_first_stage(self, x):
|
||||
sample = self.forge_objects.vae.first_stage_model.process_out(x)
|
||||
sample = self.forge_objects.vae.decode(sample).movedim(-1, 1) * 2.0 - 1.0
|
||||
return sample.to(x)
|
||||
@ -23,7 +23,6 @@ class QwenImage(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"qwen25_7b": huggingface_components["text_encoder"]}, tokenizer_dict={"qwen25_7b": huggingface_components["tokenizer"]})
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ class Wan(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"umt5xxl": huggingface_components["text_encoder"]}, tokenizer_dict={"umt5xxl": huggingface_components["tokenizer"]})
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ class ZImage(ForgeDiffusionEngine):
|
||||
|
||||
def __init__(self, estimated_config, huggingface_components):
|
||||
super().__init__(estimated_config, huggingface_components)
|
||||
self.is_inpaint = False
|
||||
|
||||
clip = CLIP(model_dict={"qwen3": huggingface_components["text_encoder"]}, tokenizer_dict={"qwen3": huggingface_components["tokenizer"]})
|
||||
|
||||
|
||||
34
backend/huggingface/CabalResearch/Mugen/model_index.json
Normal file
34
backend/huggingface/CabalResearch/Mugen/model_index.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"_class_name": "StableDiffusionXLPipeline",
|
||||
"_diffusers_version": "0.19.0.dev0",
|
||||
"force_zeros_for_empty_prompt": true,
|
||||
"add_watermarker": null,
|
||||
"scheduler": [
|
||||
"diffusers",
|
||||
"EulerDiscreteScheduler"
|
||||
],
|
||||
"text_encoder": [
|
||||
"transformers",
|
||||
"CLIPTextModel"
|
||||
],
|
||||
"text_encoder_2": [
|
||||
"transformers",
|
||||
"CLIPTextModelWithProjection"
|
||||
],
|
||||
"tokenizer": [
|
||||
"transformers",
|
||||
"CLIPTokenizer"
|
||||
],
|
||||
"tokenizer_2": [
|
||||
"transformers",
|
||||
"CLIPTokenizer"
|
||||
],
|
||||
"unet": [
|
||||
"diffusers",
|
||||
"UNet2DConditionModel"
|
||||
],
|
||||
"vae": [
|
||||
"diffusers",
|
||||
"AutoencoderKLFlux2"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
{
|
||||
"_class_name": "EulerDiscreteScheduler",
|
||||
"_diffusers_version": "0.19.0.dev0",
|
||||
"beta_end": 0.012,
|
||||
"beta_schedule": "scaled_linear",
|
||||
"beta_start": 0.00085,
|
||||
"clip_sample": false,
|
||||
"interpolation_type": "linear",
|
||||
"num_train_timesteps": 1000,
|
||||
"prediction_type": "epsilon",
|
||||
"sample_max_value": 1.0,
|
||||
"set_alpha_to_one": false,
|
||||
"skip_prk_steps": true,
|
||||
"steps_offset": 1,
|
||||
"timestep_spacing": "leading",
|
||||
"trained_betas": null,
|
||||
"use_karras_sigmas": false
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"architectures": [
|
||||
"CLIPTextModel"
|
||||
],
|
||||
"attention_dropout": 0.0,
|
||||
"bos_token_id": 0,
|
||||
"dropout": 0.0,
|
||||
"eos_token_id": 2,
|
||||
"hidden_act": "quick_gelu",
|
||||
"hidden_size": 768,
|
||||
"initializer_factor": 1.0,
|
||||
"initializer_range": 0.02,
|
||||
"intermediate_size": 3072,
|
||||
"layer_norm_eps": 1e-05,
|
||||
"max_position_embeddings": 77,
|
||||
"model_type": "clip_text_model",
|
||||
"num_attention_heads": 12,
|
||||
"num_hidden_layers": 12,
|
||||
"pad_token_id": 1,
|
||||
"projection_dim": 768,
|
||||
"torch_dtype": "float16",
|
||||
"transformers_version": "4.32.0.dev0",
|
||||
"vocab_size": 49408
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"architectures": [
|
||||
"CLIPTextModelWithProjection"
|
||||
],
|
||||
"attention_dropout": 0.0,
|
||||
"bos_token_id": 0,
|
||||
"dropout": 0.0,
|
||||
"eos_token_id": 2,
|
||||
"hidden_act": "gelu",
|
||||
"hidden_size": 1280,
|
||||
"initializer_factor": 1.0,
|
||||
"initializer_range": 0.02,
|
||||
"intermediate_size": 5120,
|
||||
"layer_norm_eps": 1e-05,
|
||||
"max_position_embeddings": 77,
|
||||
"model_type": "clip_text_model",
|
||||
"num_attention_heads": 20,
|
||||
"num_hidden_layers": 32,
|
||||
"pad_token_id": 1,
|
||||
"projection_dim": 1280,
|
||||
"torch_dtype": "float16",
|
||||
"transformers_version": "4.32.0.dev0",
|
||||
"vocab_size": 49408
|
||||
}
|
||||
48895
backend/huggingface/CabalResearch/Mugen/tokenizer/merges.txt
Normal file
48895
backend/huggingface/CabalResearch/Mugen/tokenizer/merges.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,24 @@
|
||||
{
|
||||
"bos_token": {
|
||||
"content": "<|startoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"eos_token": {
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"pad_token": "<|endoftext|>",
|
||||
"unk_token": {
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
"add_prefix_space": false,
|
||||
"bos_token": {
|
||||
"__type": "AddedToken",
|
||||
"content": "<|startoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"clean_up_tokenization_spaces": true,
|
||||
"do_lower_case": true,
|
||||
"eos_token": {
|
||||
"__type": "AddedToken",
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"errors": "replace",
|
||||
"model_max_length": 77,
|
||||
"pad_token": "<|endoftext|>",
|
||||
"tokenizer_class": "CLIPTokenizer",
|
||||
"unk_token": {
|
||||
"__type": "AddedToken",
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
}
|
||||
}
|
||||
49410
backend/huggingface/CabalResearch/Mugen/tokenizer/vocab.json
Normal file
49410
backend/huggingface/CabalResearch/Mugen/tokenizer/vocab.json
Normal file
File diff suppressed because it is too large
Load Diff
48895
backend/huggingface/CabalResearch/Mugen/tokenizer_2/merges.txt
Normal file
48895
backend/huggingface/CabalResearch/Mugen/tokenizer_2/merges.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,24 @@
|
||||
{
|
||||
"bos_token": {
|
||||
"content": "<|startoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"eos_token": {
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"pad_token": "!",
|
||||
"unk_token": {
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
"add_prefix_space": false,
|
||||
"bos_token": {
|
||||
"__type": "AddedToken",
|
||||
"content": "<|startoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"clean_up_tokenization_spaces": true,
|
||||
"do_lower_case": true,
|
||||
"eos_token": {
|
||||
"__type": "AddedToken",
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
},
|
||||
"errors": "replace",
|
||||
"model_max_length": 77,
|
||||
"pad_token": "!",
|
||||
"tokenizer_class": "CLIPTokenizer",
|
||||
"unk_token": {
|
||||
"__type": "AddedToken",
|
||||
"content": "<|endoftext|>",
|
||||
"lstrip": false,
|
||||
"normalized": true,
|
||||
"rstrip": false,
|
||||
"single_word": false
|
||||
}
|
||||
}
|
||||
49410
backend/huggingface/CabalResearch/Mugen/tokenizer_2/vocab.json
Normal file
49410
backend/huggingface/CabalResearch/Mugen/tokenizer_2/vocab.json
Normal file
File diff suppressed because it is too large
Load Diff
69
backend/huggingface/CabalResearch/Mugen/unet/config.json
Normal file
69
backend/huggingface/CabalResearch/Mugen/unet/config.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"_class_name": "UNet2DConditionModel",
|
||||
"_diffusers_version": "0.19.0.dev0",
|
||||
"act_fn": "silu",
|
||||
"addition_embed_type": "text_time",
|
||||
"addition_embed_type_num_heads": 64,
|
||||
"addition_time_embed_dim": 256,
|
||||
"attention_head_dim": [
|
||||
5,
|
||||
10,
|
||||
20
|
||||
],
|
||||
"block_out_channels": [
|
||||
320,
|
||||
640,
|
||||
1280
|
||||
],
|
||||
"center_input_sample": false,
|
||||
"class_embed_type": null,
|
||||
"class_embeddings_concat": false,
|
||||
"conv_in_kernel": 3,
|
||||
"conv_out_kernel": 3,
|
||||
"cross_attention_dim": 2048,
|
||||
"cross_attention_norm": null,
|
||||
"down_block_types": [
|
||||
"DownBlock2D",
|
||||
"CrossAttnDownBlock2D",
|
||||
"CrossAttnDownBlock2D"
|
||||
],
|
||||
"downsample_padding": 1,
|
||||
"dual_cross_attention": false,
|
||||
"encoder_hid_dim": null,
|
||||
"encoder_hid_dim_type": null,
|
||||
"flip_sin_to_cos": true,
|
||||
"freq_shift": 0,
|
||||
"in_channels": 4,
|
||||
"layers_per_block": 2,
|
||||
"mid_block_only_cross_attention": null,
|
||||
"mid_block_scale_factor": 1,
|
||||
"mid_block_type": "UNetMidBlock2DCrossAttn",
|
||||
"norm_eps": 1e-05,
|
||||
"norm_num_groups": 32,
|
||||
"num_attention_heads": null,
|
||||
"num_class_embeds": null,
|
||||
"only_cross_attention": false,
|
||||
"out_channels": 4,
|
||||
"projection_class_embeddings_input_dim": 2816,
|
||||
"resnet_out_scale_factor": 1.0,
|
||||
"resnet_skip_time_act": false,
|
||||
"resnet_time_scale_shift": "default",
|
||||
"sample_size": 128,
|
||||
"time_cond_proj_dim": null,
|
||||
"time_embedding_act_fn": null,
|
||||
"time_embedding_dim": null,
|
||||
"time_embedding_type": "positional",
|
||||
"timestep_post_act": null,
|
||||
"transformer_layers_per_block": [
|
||||
1,
|
||||
2,
|
||||
10
|
||||
],
|
||||
"up_block_types": [
|
||||
"CrossAttnUpBlock2D",
|
||||
"CrossAttnUpBlock2D",
|
||||
"UpBlock2D"
|
||||
],
|
||||
"upcast_attention": null,
|
||||
"use_linear_projection": true
|
||||
}
|
||||
40
backend/huggingface/CabalResearch/Mugen/vae/config.json
Normal file
40
backend/huggingface/CabalResearch/Mugen/vae/config.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"_class_name": "AutoencoderKLFlux2",
|
||||
"_diffusers_version": "0.37.0.dev0",
|
||||
"_name_or_path": "black-forest-labs/FLUX.2-dev",
|
||||
"act_fn": "silu",
|
||||
"batch_norm_eps": 0.0001,
|
||||
"batch_norm_momentum": 0.1,
|
||||
"block_out_channels": [
|
||||
128,
|
||||
256,
|
||||
512,
|
||||
512
|
||||
],
|
||||
"down_block_types": [
|
||||
"DownEncoderBlock2D",
|
||||
"DownEncoderBlock2D",
|
||||
"DownEncoderBlock2D",
|
||||
"DownEncoderBlock2D"
|
||||
],
|
||||
"force_upcast": true,
|
||||
"in_channels": 3,
|
||||
"latent_channels": 32,
|
||||
"layers_per_block": 2,
|
||||
"mid_block_add_attention": true,
|
||||
"norm_num_groups": 32,
|
||||
"out_channels": 3,
|
||||
"patch_size": [
|
||||
2,
|
||||
2
|
||||
],
|
||||
"sample_size": 1024,
|
||||
"up_block_types": [
|
||||
"UpDecoderBlock2D",
|
||||
"UpDecoderBlock2D",
|
||||
"UpDecoderBlock2D",
|
||||
"UpDecoderBlock2D"
|
||||
],
|
||||
"use_post_quant_conv": true,
|
||||
"use_quant_conv": true
|
||||
}
|
||||
@ -14,6 +14,7 @@ from backend.diffusion_engine.chroma import Chroma
|
||||
from backend.diffusion_engine.flux import Flux
|
||||
from backend.diffusion_engine.flux2 import Flux2
|
||||
from backend.diffusion_engine.lumina import Lumina2
|
||||
from backend.diffusion_engine.mugen import Mugen
|
||||
from backend.diffusion_engine.qwen import QwenImage
|
||||
from backend.diffusion_engine.sd15 import StableDiffusion
|
||||
from backend.diffusion_engine.sdxl import StableDiffusionXL, StableDiffusionXLRefiner
|
||||
@ -35,7 +36,7 @@ from backend.utils import (
|
||||
)
|
||||
from modules_forge.packages.comfy.utils import convert_diffusers_mmdit
|
||||
|
||||
possible_models = [StableDiffusion, StableDiffusionXLRefiner, StableDiffusionXL, Chroma, Flux, Flux2, Wan, QwenImage, Lumina2, ZImage, Anima]
|
||||
possible_models = [StableDiffusion, StableDiffusionXLRefiner, StableDiffusionXL, Mugen, Chroma, Flux, Flux2, Wan, QwenImage, Lumina2, ZImage, Anima]
|
||||
|
||||
logger = logging.getLogger("loader")
|
||||
setup_logger(logger)
|
||||
|
||||
@ -355,6 +355,8 @@ class AutoencoderKLFlux2(IntegratedAutoencoderKL):
|
||||
)
|
||||
self.bn.eval()
|
||||
|
||||
self.mugen = False # 32 <-> 128
|
||||
|
||||
def encode(self, x):
|
||||
z = super().encode(x)
|
||||
|
||||
@ -373,9 +375,11 @@ class AutoencoderKLFlux2(IntegratedAutoencoderKL):
|
||||
eps=self.bn_eps,
|
||||
)
|
||||
|
||||
z = self.postprocess_encode(z)
|
||||
return z
|
||||
|
||||
def decode(self, z):
|
||||
z = self.preprocess_decode(z)
|
||||
s = torch.sqrt(memory_management.cast_to(self.bn.running_var.view(1, -1, 1, 1), dtype=z.dtype, device=z.device) + self.bn_eps)
|
||||
m = memory_management.cast_to(self.bn.running_mean.view(1, -1, 1, 1), dtype=z.dtype, device=z.device)
|
||||
z = z * s + m
|
||||
@ -393,3 +397,34 @@ class AutoencoderKLFlux2(IntegratedAutoencoderKL):
|
||||
|
||||
def process_out(self, latent):
|
||||
return latent
|
||||
|
||||
def preprocess_decode(self, latent: torch.Tensor):
|
||||
packed_channels: int = latent.size(1)
|
||||
latent_channels: int = 128
|
||||
scale_factor: int = 2
|
||||
|
||||
if self.mugen:
|
||||
h = latent.shape[-2]
|
||||
w = latent.shape[-1]
|
||||
if h % scale_factor != 0 or w % scale_factor != 0:
|
||||
pad_h = (scale_factor - (h % scale_factor)) % scale_factor
|
||||
pad_w = (scale_factor - (w % scale_factor)) % scale_factor
|
||||
latent = torch.nn.functional.pad(latent, (0, pad_w, 0, pad_h))
|
||||
h = latent.shape[-2]
|
||||
w = latent.shape[-1]
|
||||
latent = latent.reshape(latent.shape[0], packed_channels, h // scale_factor, scale_factor, w // scale_factor, scale_factor)
|
||||
latent = latent.permute(0, 1, 3, 5, 2, 4).reshape(latent.shape[0], latent_channels, h // scale_factor, w // scale_factor)
|
||||
|
||||
return latent
|
||||
|
||||
def postprocess_encode(self, latent: torch.Tensor):
|
||||
packed_channels: int = 32
|
||||
scale_factor: int = 2
|
||||
|
||||
if self.mugen:
|
||||
h = latent.shape[-2]
|
||||
w = latent.shape[-1]
|
||||
latent = latent.reshape(latent.shape[0], packed_channels, scale_factor, scale_factor, h, w)
|
||||
latent = latent.permute(0, 1, 4, 2, 5, 3).reshape(latent.shape[0], packed_channels, h * scale_factor, w * scale_factor)
|
||||
|
||||
return latent
|
||||
|
||||
@ -121,7 +121,7 @@ def tiled_scale(samples, function, tile_x=64, tile_y=64, overlap=8, upscale_amou
|
||||
|
||||
|
||||
class VAE:
|
||||
def __init__(self, model=None, device=None, dtype=None, no_init=False, *, is_wan=False, is_flux2=False):
|
||||
def __init__(self, model=None, device=None, dtype=None, no_init=False, *, is_wan=False, is_flux2=False, is_mugen=False):
|
||||
if no_init:
|
||||
return
|
||||
|
||||
@ -135,10 +135,10 @@ class VAE:
|
||||
self.memory_used_encode = lambda shape, dtype: (1767 * shape[2] * shape[3]) * memory_management.dtype_size(dtype)
|
||||
self.memory_used_decode = lambda shape, dtype: (2178 * shape[2] * shape[3] * 64) * memory_management.dtype_size(dtype)
|
||||
|
||||
if is_flux2:
|
||||
if is_flux2 or is_mugen:
|
||||
self.upscale_ratio = 16
|
||||
self.downscale_ratio = 16
|
||||
self.latent_channels = 128
|
||||
self.latent_channels = 32 if is_mugen else 128
|
||||
self.memory_used_decode = lambda shape, dtype: (2178 * shape[2] * shape[3] * 64) * memory_management.dtype_size(dtype) * 4.0
|
||||
|
||||
else:
|
||||
@ -153,6 +153,8 @@ class VAE:
|
||||
|
||||
self.output_channels = 3
|
||||
self.first_stage_model = model.eval()
|
||||
if is_mugen:
|
||||
self.first_stage_model.mugen = True
|
||||
|
||||
self.device = device or memory_management.vae_device()
|
||||
offload_device = memory_management.vae_offload_device()
|
||||
|
||||
@ -162,3 +162,10 @@ class Flux2(LatentFormat):
|
||||
|
||||
def process_out(self, latent):
|
||||
return latent
|
||||
|
||||
|
||||
class SDXL_Flux2(Flux2):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.latent_rgb_factors_reshape = None
|
||||
self.latent_channels = 32
|
||||
|
||||
@ -57,7 +57,7 @@ class BASE:
|
||||
return {}
|
||||
|
||||
def inpaint_model(self):
|
||||
return self.unet_config.get("in_channels", -1) > 4
|
||||
return False
|
||||
|
||||
def __init__(self, unet_config):
|
||||
self.unet_config = unet_config.copy()
|
||||
@ -115,6 +115,9 @@ class SD15(BASE):
|
||||
latent_format = latent.SD15
|
||||
memory_usage_factor = 1.0
|
||||
|
||||
def inpaint_model(self):
|
||||
return self.unet_config.get("in_channels", -1) > 4
|
||||
|
||||
def process_clip_state_dict(self, state_dict):
|
||||
k = list(state_dict.keys())
|
||||
for x in k:
|
||||
@ -179,6 +182,8 @@ class SDXL(BASE):
|
||||
|
||||
unet_config = {
|
||||
"model_channels": 320,
|
||||
"in_channels": 4,
|
||||
"out_channels": 4,
|
||||
"use_linear_in_transformer": True,
|
||||
"transformer_depth": [0, 0, 2, 2, 10, 10],
|
||||
"context_dim": 2048,
|
||||
@ -189,6 +194,9 @@ class SDXL(BASE):
|
||||
latent_format = latent.SDXL
|
||||
memory_usage_factor = 0.8
|
||||
|
||||
def inpaint_model(self):
|
||||
return self.unet_config.get("in_channels", -1) > 4
|
||||
|
||||
def model_type(self, state_dict: dict):
|
||||
if "v_pred" in state_dict:
|
||||
return ModelType.V_PREDICTION
|
||||
@ -225,6 +233,23 @@ class SDXL(BASE):
|
||||
return {"clip_l": "text_encoder", "clip_g": "text_encoder_2"}
|
||||
|
||||
|
||||
class Mugen(SDXL):
|
||||
huggingface_repo = "CabalResearch/Mugen"
|
||||
|
||||
unet_config = dict(SDXL.unet_config, in_channels=32, out_channels=32)
|
||||
|
||||
sampling_settings = {
|
||||
"shift": 12.0,
|
||||
}
|
||||
|
||||
latent_format = latent.SDXL_Flux2
|
||||
|
||||
vae_key_prefix = ["vae.", "first_stage_model."]
|
||||
|
||||
def inpaint_model(self):
|
||||
return False
|
||||
|
||||
|
||||
class Flux(BASE):
|
||||
huggingface_repo = "black-forest-labs/FLUX.1-dev"
|
||||
|
||||
@ -537,6 +562,7 @@ class QwenImage(BASE):
|
||||
models = [
|
||||
SD15,
|
||||
SDXL,
|
||||
Mugen,
|
||||
SDXLRefiner,
|
||||
Flux,
|
||||
FluxSchnell,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user