mirror of
https://github.com/lllyasviel/stable-diffusion-webui-forge.git
synced 2026-07-21 21:01:24 +08:00
66 lines
2.4 KiB
Python
66 lines
2.4 KiB
Python
import math
|
|
|
|
import torch
|
|
|
|
from backend import memory_management
|
|
from backend.modules.k_prediction import k_prediction_from_diffusers_scheduler
|
|
|
|
|
|
class KModel(torch.nn.Module):
|
|
def __init__(self, model: torch.nn.Module, diffusers_scheduler, k_predictor=None, config=None):
|
|
super().__init__()
|
|
|
|
self.config = config
|
|
|
|
self.storage_dtype = model.storage_dtype
|
|
self.computation_dtype = model.computation_dtype
|
|
|
|
print(f"K-Model Created: {dict(storage_dtype=self.storage_dtype, computation_dtype=self.computation_dtype)}")
|
|
|
|
self.diffusion_model = model
|
|
self.diffusion_model.eval()
|
|
self.diffusion_model.requires_grad_(False)
|
|
|
|
if k_predictor is None:
|
|
self.predictor = k_prediction_from_diffusers_scheduler(diffusers_scheduler)
|
|
else:
|
|
self.predictor = k_predictor
|
|
|
|
def apply_model(self, x, t, c_concat=None, c_crossattn=None, control=None, transformer_options={}, **kwargs):
|
|
sigma = t
|
|
xc = self.predictor.calculate_input(sigma, x)
|
|
if c_concat is not None:
|
|
xc = torch.cat([xc] + [c_concat], dim=1)
|
|
|
|
context = c_crossattn
|
|
dtype = self.computation_dtype
|
|
|
|
xc = xc.to(dtype)
|
|
t = self.predictor.timestep(t).float()
|
|
context = context.to(dtype)
|
|
extra_conds = {}
|
|
for o in kwargs:
|
|
extra = kwargs[o]
|
|
if hasattr(extra, "dtype"):
|
|
if extra.dtype != torch.int and extra.dtype != torch.long:
|
|
extra = extra.to(dtype)
|
|
extra_conds[o] = extra
|
|
|
|
model_output = self.diffusion_model(xc, t, context=context, control=control, transformer_options=transformer_options, **extra_conds).float()
|
|
return self.predictor.calculate_denoised(sigma, model_output, x)
|
|
|
|
def memory_required(self, input_shape: list[int]) -> float:
|
|
"""https://github.com/comfyanonymous/ComfyUI/blob/v0.3.64/comfy/model_base.py#L354"""
|
|
input_shapes = [input_shape]
|
|
area = sum(map(lambda input_shape: input_shape[0] * math.prod(input_shape[2:]), input_shapes))
|
|
|
|
if memory_management.xformers_enabled():
|
|
return (area * memory_management.dtype_size(self.computation_dtype) * 0.01 * self.config.memory_usage_factor) * (1024 * 1024)
|
|
else:
|
|
return (area * 0.15 * self.config.memory_usage_factor) * (1024 * 1024)
|
|
|
|
def cleanup(self):
|
|
del self.config
|
|
del self.predictor
|
|
del self.diffusion_model
|