V:0.2.1 - Model concepts #5 + cascade
This commit is contained in:
+105
-32
@@ -154,24 +154,34 @@ class PrimereLCMSelector:
|
||||
return (sampler_name, scheduler_name, steps, cfg_scale, model_concept,)
|
||||
|
||||
class PrimereModelConceptSelector:
|
||||
RETURN_TYPES = (comfy.samplers.KSampler.SAMPLERS, comfy.samplers.KSampler.SCHEDULERS, "INT", "FLOAT", "STRING", "STRING", "INT")
|
||||
RETURN_NAMES = ("SAMPLER_NAME", "SCHEDULER_NAME", "STEPS", "CFG", "MODEL_CONCEPT", "LIGHTNING_SELECTOR", "LIGHTNING_MODEL_STEP")
|
||||
RETURN_TYPES = (comfy.samplers.KSampler.SAMPLERS, comfy.samplers.KSampler.SCHEDULERS, "INT", "FLOAT", "STRING", "STRING", "INT", "STRING", "STRING", "STRING", "STRING")
|
||||
RETURN_NAMES = ("SAMPLER_NAME", "SCHEDULER_NAME", "STEPS", "CFG", "MODEL_CONCEPT", "LIGHTNING_SELECTOR", "LIGHTNING_MODEL_STEP", "CASCADE_STAGE_A", "CASCADE_STAGE_B", "CASCADE_STAGE_C", "CASCADE_CLIP")
|
||||
FUNCTION = "select_model_concept"
|
||||
CATEGORY = TREE_DASHBOARD
|
||||
|
||||
UNETLIST = folder_paths.get_filename_list("unet")
|
||||
VAELIST = folder_paths.get_filename_list("vae")
|
||||
CLIPLIST = folder_paths.get_filename_list("clip")
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"model_concept":(["Normal", "LCM", "Turbo", "Cascade", "Lightning"], {"default": "Normal"}),
|
||||
"lightning_selector": (["UNET", "LORA", "SAFETENSOR", "CUSTOM"], {"default": "SAFETENSOR"}),
|
||||
"lightning_model_step": ([1, 2, 4, 8], {"default": 8}),
|
||||
"lightning_sampler": ("BOOLEAN", {"default": False, "label_on": "Set by model", "label_off": "Custom (external)"}),
|
||||
|
||||
"normal_sampler_name": (comfy.samplers.KSampler.SAMPLERS, {"forceInput": True, "default": "euler"}),
|
||||
"normal_scheduler_name": (comfy.samplers.KSampler.SCHEDULERS, {"forceInput": True, "default": "normal"}),
|
||||
"normal_cfg_scale": ('FLOAT', {"forceInput": True, "default": 7}),
|
||||
"normal_steps": ('INT', {"forceInput": True, "default": 12}),
|
||||
|
||||
"model_concept": (["Normal", "LCM", "Turbo", "Cascade", "Lightning"], {"default": "Normal"}),
|
||||
"lightning_selector": (["UNET", "LORA", "SAFETENSOR", "CUSTOM"], {"default": "SAFETENSOR"}),
|
||||
"lightning_model_step": ([1, 2, 4, 8], {"default": 8}),
|
||||
"lightning_sampler": (
|
||||
"BOOLEAN", {"default": False, "label_on": "Set by model", "label_off": "Custom (external)"}),
|
||||
|
||||
"cascade_stage_a": (cls.VAELIST,),
|
||||
"cascade_stage_b": (cls.UNETLIST,),
|
||||
"cascade_stage_c": (cls.UNETLIST,),
|
||||
"cascade_clip": (cls.CLIPLIST,),
|
||||
},
|
||||
"optional": {
|
||||
"lcm_sampler_name": (comfy.samplers.KSampler.SAMPLERS, {"forceInput": True, "default": "lcm"}),
|
||||
@@ -196,7 +206,8 @@ class PrimereModelConceptSelector:
|
||||
}
|
||||
}
|
||||
|
||||
def select_model_concept(self, model_concept = 'Normal', lightning_selector = "SAFETENSOR", lightning_model_step = 8, lightning_sampler = False,
|
||||
def select_model_concept(self, cascade_stage_a, cascade_stage_b, cascade_stage_c, cascade_clip,
|
||||
model_concept = 'Normal', lightning_selector = "SAFETENSOR", lightning_model_step = 8, lightning_sampler = False,
|
||||
normal_sampler_name = 'euler', normal_scheduler_name = 'normal', normal_cfg_scale = 7, normal_steps = 12,
|
||||
lcm_sampler_name = 'lcm', lcm_scheduler_name = 'sgm_uniform', lcm_cfg_scale = 1.2, lcm_steps = 6,
|
||||
turbo_sampler_name = 'dpmpp_sde', turbo_scheduler_name = "karras", turbo_cfg_scale = 1.15, turbo_steps = 2,
|
||||
@@ -244,7 +255,13 @@ class PrimereModelConceptSelector:
|
||||
lightning_selector = None
|
||||
lightning_model_step = None
|
||||
|
||||
return (sampler_name, scheduler_name, steps, round(cfg_scale, 2), model_concept, lightning_selector, lightning_model_step)
|
||||
if model_concept != 'Cascade':
|
||||
cascade_stage_a = None
|
||||
cascade_stage_b = None
|
||||
cascade_stage_c = None
|
||||
cascade_clip = None
|
||||
|
||||
return (sampler_name, scheduler_name, steps, round(cfg_scale, 2), model_concept, lightning_selector, lightning_model_step, cascade_stage_a, cascade_stage_b, cascade_stage_c, cascade_clip)
|
||||
|
||||
class PrimereCKPTLoader:
|
||||
RETURN_TYPES = ("MODEL", "CLIP", "VAE", "STRING",)
|
||||
@@ -256,7 +273,7 @@ class PrimereCKPTLoader:
|
||||
self.loaded_lora = None
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"ckpt_name": ("CHECKPOINT_NAME",),
|
||||
@@ -274,13 +291,41 @@ class PrimereCKPTLoader:
|
||||
},
|
||||
}
|
||||
|
||||
def load_primere_ckpt(self, ckpt_name, use_yaml, strength_lcm_model, strength_lcm_clip, model_concept = "Normal", concept_data = None, lightning_selector = 'SAFETENSOR', lightning_model_step = 8, loaded_model = None, loaded_clip = None, loaded_vae = None):
|
||||
def load_primere_ckpt(self, ckpt_name, use_yaml, strength_lcm_model, strength_lcm_clip,
|
||||
model_concept = "Normal", concept_data = None,
|
||||
lightning_selector = 'SAFETENSOR', lightning_model_step = 8,
|
||||
cascade_stage_a = None, cascade_stage_b = None, cascade_stage_c = None, cascade_clip = None,
|
||||
loaded_model = None, loaded_clip = None, loaded_vae = None):
|
||||
|
||||
if concept_data is not None:
|
||||
if 'lightning_selector' in concept_data:
|
||||
lightning_selector = concept_data['lightning_selector']
|
||||
if 'lightning_model_step' in concept_data:
|
||||
lightning_model_step = concept_data['lightning_model_step']
|
||||
|
||||
if 'cascade_stage_a' in concept_data:
|
||||
cascade_stage_a = concept_data['cascade_stage_a']
|
||||
if 'cascade_stage_b' in concept_data:
|
||||
cascade_stage_b = concept_data['cascade_stage_b']
|
||||
if 'cascade_stage_c' in concept_data:
|
||||
cascade_stage_c = concept_data['cascade_stage_c']
|
||||
if 'cascade_clip' in concept_data:
|
||||
cascade_clip = concept_data['cascade_clip']
|
||||
|
||||
if model_concept == "Cascade" and cascade_stage_a is not None and cascade_stage_b is not None and cascade_stage_c is not None and cascade_clip is not None:
|
||||
MODEL_VERSION = 'SDXL_2048'
|
||||
is_sdxl = 1
|
||||
|
||||
OUTPUT_VAE = nodes.VAELoader.load_vae(self, cascade_stage_a)[0]
|
||||
|
||||
MODEL_B = nodes.UNETLoader.load_unet(self, cascade_stage_b)[0]
|
||||
MODEL_C = nodes.UNETLoader.load_unet(self, cascade_stage_c)[0]
|
||||
|
||||
OUTPUT_CLIP = nodes.CLIPLoader.load_clip(self, cascade_clip, 'stable_cascade')[0]
|
||||
OUTPUT_MODEL = [MODEL_B, MODEL_C]
|
||||
|
||||
return (OUTPUT_MODEL,) + (OUTPUT_CLIP,) + (OUTPUT_VAE,) + (MODEL_VERSION,)
|
||||
|
||||
ModelConceptChanges = utility.ModelConceptNames(ckpt_name, model_concept, lightning_selector, lightning_model_step)
|
||||
ckpt_name = ModelConceptChanges['ckpt_name']
|
||||
lora_name = ModelConceptChanges['lora_name']
|
||||
@@ -734,44 +779,60 @@ class PrimereCLIP:
|
||||
|
||||
if (adv_encode == True):
|
||||
if (is_sdxl == 0):
|
||||
|
||||
if model_concept == 'Cascade':
|
||||
positive_text = utility.clear_cascade(positive_text)
|
||||
negative_text = utility.clear_cascade(negative_text)
|
||||
|
||||
embeddings_final_pos, pooled_pos = advanced_encode(clip, positive_text, token_normalization, weight_interpretation, w_max = 1.0, apply_to_pooled = True)
|
||||
embeddings_final_neg, pooled_neg = advanced_encode(clip, negative_text, token_normalization, weight_interpretation, w_max = 1.0, apply_to_pooled = True)
|
||||
|
||||
return ([[embeddings_final_pos, {"pooled_output": pooled_pos}]], [[embeddings_final_neg, {"pooled_output": pooled_neg}]], positive_text, negative_text, "", "")
|
||||
else:
|
||||
# embeddings_final_pos, pooled_pos = advanced_encode_XL(clip, sdxl_positive_l, positive_text, token_normalization, weight_interpretation, w_max = 1.0, clip_balance = sdxl_balance_l, apply_to_pooled = True)
|
||||
# embeddings_final_neg, pooled_neg = advanced_encode_XL(clip, sdxl_negative_l, negative_text, token_normalization, weight_interpretation, w_max = 1.0, clip_balance = sdxl_balance_l, apply_to_pooled = True)
|
||||
# return ([[embeddings_final_pos, {"pooled_output": pooled_pos}]],[[embeddings_final_neg, {"pooled_output": pooled_neg}]], positive_text, negative_text, sdxl_positive_l, sdxl_negative_l)
|
||||
if model_concept == 'Cascade':
|
||||
positive_text = utility.clear_cascade(positive_text)
|
||||
negative_text = utility.clear_cascade(negative_text)
|
||||
|
||||
tokens_p = clip.tokenize(positive_text)
|
||||
tokens_p["l"] = clip.tokenize(sdxl_positive_l)["l"]
|
||||
|
||||
if len(tokens_p["l"]) != len(tokens_p["g"]):
|
||||
empty = clip.tokenize("")
|
||||
while len(tokens_p["l"]) < len(tokens_p["g"]):
|
||||
tokens_p["l"] += empty["l"]
|
||||
while len(tokens_p["l"]) > len(tokens_p["g"]):
|
||||
tokens_p["g"] += empty["g"]
|
||||
if 'l' in clip.tokenize(sdxl_positive_l):
|
||||
tokens_p["l"] = clip.tokenize(sdxl_positive_l)["l"]
|
||||
if len(tokens_p["l"]) != len(tokens_p["g"]):
|
||||
empty = clip.tokenize("")
|
||||
while len(tokens_p["l"]) < len(tokens_p["g"]):
|
||||
tokens_p["l"] += empty["l"]
|
||||
while len(tokens_p["l"]) > len(tokens_p["g"]):
|
||||
tokens_p["g"] += empty["g"]
|
||||
|
||||
tokens_n = clip.tokenize(negative_text)
|
||||
tokens_n["l"] = clip.tokenize(sdxl_negative_l)["l"]
|
||||
if 'l' in clip.tokenize(sdxl_negative_l):
|
||||
tokens_n["l"] = clip.tokenize(sdxl_negative_l)["l"]
|
||||
|
||||
if len(tokens_n["l"]) != len(tokens_n["g"]):
|
||||
empty = clip.tokenize("")
|
||||
while len(tokens_n["l"]) < len(tokens_n["g"]):
|
||||
tokens_n["l"] += empty["l"]
|
||||
while len(tokens_n["l"]) > len(tokens_n["g"]):
|
||||
tokens_n["g"] += empty["g"]
|
||||
if len(tokens_n["l"]) != len(tokens_n["g"]):
|
||||
empty = clip.tokenize("")
|
||||
while len(tokens_n["l"]) < len(tokens_n["g"]):
|
||||
tokens_n["l"] += empty["l"]
|
||||
while len(tokens_n["l"]) > len(tokens_n["g"]):
|
||||
tokens_n["g"] += empty["g"]
|
||||
|
||||
cond_p, pooled_p = clip.encode_from_tokens(tokens_p, return_pooled = True)
|
||||
cond_n, pooled_n = clip.encode_from_tokens(tokens_n, return_pooled = True)
|
||||
|
||||
return ([[cond_p, {"pooled_output": pooled_p, "width": width, "height": height, "crop_w": 0, "crop_h": 0, "target_width": width, "target_height": height}]], [[cond_n, {"pooled_output": pooled_n, "width": width, "height": height, "crop_w": 0, "crop_h": 0, "target_width": width, "target_height": height}]], positive_text, negative_text, sdxl_positive_l, sdxl_negative_l)
|
||||
|
||||
else:
|
||||
if model_concept == 'Cascade':
|
||||
positive_text = utility.clear_cascade(positive_text)
|
||||
negative_text = utility.clear_cascade(negative_text)
|
||||
|
||||
tokens = clip.tokenize(positive_text)
|
||||
cond_pos, pooled_pos = clip.encode_from_tokens(tokens, return_pooled = True)
|
||||
|
||||
tokens = clip.tokenize(negative_text)
|
||||
cond_neg, pooled_neg = clip.encode_from_tokens(tokens, return_pooled = True)
|
||||
|
||||
return ([[cond_pos, {"pooled_output": pooled_pos}]], [[cond_neg, {"pooled_output": pooled_neg}]], positive_text, negative_text, "", "")
|
||||
|
||||
class PrimereResolution:
|
||||
@@ -1075,9 +1136,12 @@ class PrimereClearPrompt:
|
||||
"remove_lycoris": ("BOOLEAN", {"default": False}),
|
||||
"remove_hypernetwork": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
"optional": {
|
||||
"model_concept": ("STRING", {"default": "Normal", "forceInput": True}),
|
||||
}
|
||||
}
|
||||
|
||||
def clean_prompt(self, positive_prompt, negative_prompt, remove_comfy_embedding, remove_a1111_embedding, remove_lora, remove_lycoris, remove_hypernetwork, remove_only_if_sdxl, model_version = 'BaseModel_1024'):
|
||||
def clean_prompt(self, positive_prompt, negative_prompt, remove_comfy_embedding, remove_a1111_embedding, remove_lora, remove_lycoris, remove_hypernetwork, remove_only_if_sdxl, model_version = 'BaseModel_1024', model_concept = "Normal"):
|
||||
NETWORK_START = []
|
||||
|
||||
is_sdxl = 0
|
||||
@@ -1113,9 +1177,13 @@ class PrimereClearPrompt:
|
||||
negative_prompt = re.sub(r'(, )\1+', r', ', negative_prompt).strip(', ').replace(' ,', ',')
|
||||
|
||||
if len(NETWORK_START) > 0:
|
||||
NETWORK_END = ['\n', '>', ' ', ',', '}', ')', '|'] + NETWORK_START
|
||||
positive_prompt = utility.clear_prompt(NETWORK_START, NETWORK_END, positive_prompt)
|
||||
negative_prompt = utility.clear_prompt(NETWORK_START, NETWORK_END, negative_prompt)
|
||||
NETWORK_END = ['\n', '>', ' ', ',', '}', ')', '|'] + NETWORK_START
|
||||
positive_prompt = utility.clear_prompt(NETWORK_START, NETWORK_END, positive_prompt)
|
||||
negative_prompt = utility.clear_prompt(NETWORK_START, NETWORK_END, negative_prompt)
|
||||
|
||||
if model_concept == 'Cascade':
|
||||
positive_prompt = utility.clear_cascade(positive_prompt)
|
||||
negative_prompt = utility.clear_cascade(negative_prompt)
|
||||
|
||||
return (positive_prompt, negative_prompt,)
|
||||
|
||||
@@ -1359,11 +1427,16 @@ class PrimereConceptDataTuple:
|
||||
CATEGORY = TREE_DASHBOARD
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"lightning_selector": ("STRING", {"default": "SAFETENSOR", "forceInput": True}),
|
||||
"lightning_model_step": ("INT", {"default": 8, "forceInput": True}),
|
||||
|
||||
"cascade_stage_a": ("STRING", {"forceInput": True}),
|
||||
"cascade_stage_b": ("STRING", {"forceInput": True}),
|
||||
"cascade_stage_c": ("STRING", {"forceInput": True}),
|
||||
"cascade_clip": ("STRING", {"forceInput": True}),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -358,15 +358,20 @@ class PrimereVAESelector:
|
||||
"required": {
|
||||
"vae_sd": ("VAE",),
|
||||
"vae_sdxl": ("VAE",),
|
||||
"vae_cascade": ("VAE",),
|
||||
"model_version": ("STRING", {"default": 'BaseModel_1024', "forceInput": True}),
|
||||
"model_concept": ("STRING", {"default": "Normal", "forceInput": True}),
|
||||
}
|
||||
}
|
||||
|
||||
def primere_vae_selector(self, vae_sd, vae_sdxl, model_version = "BaseModel_1024"):
|
||||
if model_version == 'SDXL_2048':
|
||||
return (vae_sdxl, )
|
||||
else:
|
||||
return (vae_sd, )
|
||||
def primere_vae_selector(self, vae_sd, vae_sdxl, vae_cascade, model_version = "BaseModel_1024", model_concept = 'Normal'):
|
||||
match model_concept:
|
||||
case 'Cascade':
|
||||
return (vae_cascade,)
|
||||
match model_version:
|
||||
case 'SDXL_2048':
|
||||
return (vae_sdxl,)
|
||||
return (vae_sd,)
|
||||
|
||||
class PrimereMetaRead:
|
||||
CATEGORY = TREE_INPUTS
|
||||
|
||||
@@ -14,6 +14,9 @@ import comfy.samplers
|
||||
from .modules import exif_data_checker
|
||||
from nodes import common_ksampler
|
||||
import comfy_extras.nodes_custom_sampler as nodes_custom_sampler
|
||||
import comfy_extras.nodes_stable_cascade as nodes_stable_cascade
|
||||
import torch
|
||||
from ..components import utility
|
||||
|
||||
ALLOWED_EXT = ('.jpeg', '.jpg', '.png', '.tiff', '.gif', '.bmp', '.webp')
|
||||
|
||||
@@ -467,6 +470,30 @@ class PrimereKSampler:
|
||||
sampler = comfy.samplers.sampler_object(sampler_name)
|
||||
turbo_samples = nodes_custom_sampler.SamplerCustom().sample(model, True, seed, cfg, positive, negative, sampler, sigmas[0], latent_image)
|
||||
samples = (turbo_samples[0],)
|
||||
if (model_concept == "Cascade"):
|
||||
if type(model).__name__ == 'list':
|
||||
latent_size = utility.getLatentSize(latent_image)
|
||||
if (latent_size[0] < latent_size[1]):
|
||||
orientation = 'Vertical'
|
||||
else:
|
||||
orientation = 'Horizontal'
|
||||
|
||||
cascade_standards = [42, 84, 126, 168, 210, 252, 294, 336, 378, 420, 462, 504, 546, 588, 630, 672, 714, 756, 798, 840, 882, 924, 966, 1008, 1050, 1092, 1134, 1176, 1218, 1260, 1302, 1344, 1386, 1428, 1470, 1512, 1554, 1596, 1638, 1680]
|
||||
dimensions = utility.calculate_dimensions(self, 'Square [1:1]', orientation, True, 'SDXL_2048', True, latent_size[0], latent_size[1], cascade_standards)
|
||||
dimension_x = dimensions[0]
|
||||
dimension_y = dimensions[1]
|
||||
|
||||
height = dimension_y
|
||||
width = dimension_x
|
||||
compression = 42
|
||||
if type(model[0]).__name__ == 'ModelPatcher' and type(model[1]).__name__ == 'ModelPatcher':
|
||||
c_latent = {"samples": torch.zeros([1, 16, height // compression, width // compression])}
|
||||
b_latent = {"samples": torch.zeros([1, 4, height // 4, width // 4])}
|
||||
samples_c = common_ksampler(model[1], seed, steps, cfg, sampler_name, scheduler_name, positive, negative, c_latent, denoise=denoise)[0]
|
||||
conditining_c = nodes_stable_cascade.StableCascade_StageB_Conditioning.set_prior(self, positive, samples_c)[0]
|
||||
samples = common_ksampler(model[0], seed, 10, 1.00, sampler_name, scheduler_name, conditining_c, negative, b_latent, denoise=denoise)
|
||||
else:
|
||||
samples = latent_image
|
||||
else:
|
||||
samples = common_ksampler(model, seed, steps, cfg, sampler_name, scheduler_name, positive, negative, latent_image, denoise=denoise)
|
||||
|
||||
|
||||
+24
-2
@@ -44,7 +44,10 @@ def remove_quotes(string):
|
||||
def add_quotes(string):
|
||||
return '"' + str(string) + '"'
|
||||
|
||||
def calculate_dimensions(self, ratio: str, orientation: str, round_to_standard: bool, model_version: str, calculate_by_custom: bool, custom_side_a: float, custom_side_b: float):
|
||||
def calculate_dimensions(self, ratio: str, orientation: str, round_to_standard: bool, model_version: str, calculate_by_custom: bool, custom_side_a: float, custom_side_b: float, custom_standards=None):
|
||||
if custom_standards is None:
|
||||
custom_standards = []
|
||||
|
||||
DEFAULT_RES = 768
|
||||
|
||||
match model_version:
|
||||
@@ -81,7 +84,11 @@ def calculate_dimensions(self, ratio: str, orientation: str, round_to_standard:
|
||||
side_base = round(math.sqrt(result_y))
|
||||
side_a = round(ratio_1 * side_base)
|
||||
if round_to_standard == True:
|
||||
side_a = min(STANDARD_SIDES, key=lambda x: abs(side_a - x))
|
||||
if len(custom_standards) > 1 and custom_standards is not None:
|
||||
side_a = min(custom_standards, key=lambda x: abs(side_a - x))
|
||||
else:
|
||||
side_a = min(STANDARD_SIDES, key=lambda x: abs(side_a - x))
|
||||
|
||||
side_b = round(FullPixels / side_a)
|
||||
return sorted([side_a, side_b], reverse=True)
|
||||
|
||||
@@ -142,6 +149,9 @@ def clear_prompt(NETWORK_START, NETWORK_END, promptstring):
|
||||
|
||||
return promptstring_temp.replace('()', '').replace(' , ,', ',').replace('||', '').replace('{,', '').replace(' ', ' ').replace(', ,', ',').strip(', ')
|
||||
|
||||
def clear_cascade(prompt):
|
||||
return re.sub("(\.\d+)|(:\d+)|[()]|BREAK|break", "", prompt).replace(' ', ' ')
|
||||
|
||||
def get_networks_prompt(NETWORK_START, NETWORK_END, promptstring):
|
||||
valid_networks = []
|
||||
|
||||
@@ -657,3 +667,15 @@ def LightningConceptModel(self, model_concept, lightningModeValid, lightning_sel
|
||||
OUTPUT_MODEL = nodes_model_advanced.ModelSamplingDiscrete.patch(self, OUTPUT_MODEL, "x0", False)[0]
|
||||
|
||||
return OUTPUT_MODEL
|
||||
|
||||
def getLatentSize(samples):
|
||||
for tensor in samples['samples'][0]:
|
||||
if isinstance(tensor, torch.Tensor):
|
||||
shape = tensor.shape
|
||||
tensor_height = shape[-2]
|
||||
tensor_width = shape[-1]
|
||||
return (tensor_width, tensor_height)
|
||||
else:
|
||||
return (None, None)
|
||||
|
||||
return (None, None)
|
||||
|
||||
Reference in New Issue
Block a user