diff --git a/BatchFuncs.py b/BatchFuncs.py index 60a3e6f..bbd2b33 100644 --- a/BatchFuncs.py +++ b/BatchFuncs.py @@ -66,9 +66,8 @@ def batch_split_weighted_subprompts(text, pre_text, app_text): return pos, neg def interpolate_prompt_series(animation_prompts, max_frames, pre_text, app_text, prompt_weight_1=[], - prompt_weight_2=[], prompt_weight_3=[], - prompt_weight_4=[], Is_print = False): # parse the conditioning strength and determine in-betweens. - # Get prompts sorted by keyframe + prompt_weight_2=[], prompt_weight_3=[], prompt_weight_4=[], Is_print = False): + max_f = max_frames # needed for numexpr even though it doesn't look like it's in use. parsed_animation_prompts = {} for key, value in animation_prompts.items(): @@ -122,8 +121,6 @@ def interpolate_prompt_series(animation_prompts, max_frames, pre_text, app_text, current_weight = 1 - next_weight # add the appropriate prompts and weights to their respective containers. - # print(weight_series) - # print(weight_series[f]) cur_prompt_series[f] = '' nxt_prompt_series[f] = '' weight_series[f] = 0.0 @@ -159,8 +156,6 @@ def interpolate_prompt_series(animation_prompts, max_frames, pre_text, app_text, prompt_weight_4 = tuple([prompt_weight_4] * max_frames) # Evaluate the current and next prompt's expressions - print(cur_prompt_series) - for i in range(0,len(cur_prompt_series)): cur_prompt_series[i] = prepare_batch_prompt(cur_prompt_series[i], max_frames, i, prompt_weight_1[i], prompt_weight_2[i], prompt_weight_3[i], prompt_weight_4[i]) @@ -180,11 +175,6 @@ def BatchPoolAnimConditioning(cur_prompt_series, nxt_prompt_series, weight_serie pooled_out = [] cond_out = [] - group_size = 4 - - intermediate_pooled = [] - intermediate_cond = [] - for i in range(len(cur_prompt_series)): tokens = clip.tokenize(str(cur_prompt_series[i])) cond_to, pooled_to = clip.encode_from_tokens(tokens, return_pooled=True) @@ -199,18 +189,9 @@ def BatchPoolAnimConditioning(cur_prompt_series, nxt_prompt_series, weight_serie interpolated_cond = interpolated_conditioning[0][0] interpolated_pooled = interpolated_conditioning[0][1].get("pooled_output", pooled_from) - intermediate_pooled.append(interpolated_pooled) - intermediate_cond.append(interpolated_cond) + pooled_out.append(interpolated_pooled) + cond_out.append(interpolated_cond) - if len(intermediate_pooled) == group_size or i == len(cur_prompt_series) - 1: - pooled_group = torch.cat(intermediate_pooled, dim=0) - cond_group = torch.cat(intermediate_cond, dim=0) - - pooled_out.append(pooled_group) - cond_out.append(cond_group) - - intermediate_pooled = [] - intermediate_cond = [] final_pooled_output = torch.cat(pooled_out, dim=0) final_conditioning = torch.cat(cond_out, dim=0) @@ -342,8 +323,6 @@ def BatchInterpolatePromptsSDXL(animation_promptsG, animation_promptsL, max_fram current_weight = 1 - next_weight # add the appropriate prompts and weights to their respective containers. - # print(weight_series) - # print(weight_series[f]) if f < max_frames: cur_prompt_series_G[f] = '' nxt_prompt_series_G[f] = '' @@ -398,8 +377,6 @@ def BatchInterpolatePromptsSDXL(animation_promptsG, animation_promptsL, max_fram current_weight = 1 - next_weight # add the appropriate prompts and weights to their respective containers. - # print(weight_series) - # print(weight_series[f]) if f < max_frames: cur_prompt_series_L[f] = '' nxt_prompt_series_L[f] = '' @@ -435,7 +412,6 @@ def BatchInterpolatePromptsSDXL(animation_promptsG, animation_promptsL, max_fram pw_a, pw_b, pw_c, pw_d) nxt_prompt_series_L[i] = prepare_batch_prompt(nxt_prompt_series_L[i], max_frames, pw_a, pw_b, pw_c, pw_d) - #if Is_print == True: current_conds = [] next_conds = [] @@ -444,6 +420,14 @@ def BatchInterpolatePromptsSDXL(animation_promptsG, animation_promptsL, max_fram cur_prompt_series_G[i], cur_prompt_series_L[i])) next_conds.append(SDXLencode(clip, width, height, crop_w, crop_h, target_width, target_height, nxt_prompt_series_G[i], nxt_prompt_series_L[i])) + + if Is_print == True: + # Show the to/from prompts with evaluated expressions for transparency. + for i in range(len(cur_prompt_series)): + print("\n", "Max Frames: ", max_frames, "\n", "Current Prompt G: ", cur_prompt_series_G[i], + "\n", "Current Prompt L: ", cur_prompt_series_L[i], "\n", "Next Prompt G: ", nxt_prompt_series_G[i], + "\n", "Next Prompt L : ", nxt_prompt_series_L[i], "\n"), "\n", "Current weight: ", weight_series[i] + return BatchPoolAnimConditioningSDXL(current_conds, next_conds, weight_series, clip) diff --git a/ScheduleFuncs.py b/ScheduleFuncs.py index 2f10720..d0c96dd 100644 --- a/ScheduleFuncs.py +++ b/ScheduleFuncs.py @@ -191,88 +191,6 @@ def interpolate_string(animation_prompts, max_frames, current_frame, pre_text, a # Output methods depending if the prompts are the same or if the current frame is a keyframe. # if it is an in-between frame and the prompts differ, composable diffusion will be performed. return (cur_prompt_series[current_frame]) - -def interpolate_prompts(animation_prompts, max_frames, current_frame, pre_text, app_text, prompt_weight_1, prompt_weight_2, prompt_weight_3, prompt_weight_4): #parse the conditioning strength and determine in-betweens. - #Get prompts sorted by keyframe - max_f = max_frames #needed for numexpr even though it doesn't look like it's in use. - - proper_json_data = {str(key): value for key, value in animation_prompts.items()} - animation_prompts = json.dumps(proper_json_data, indent=2) - animation_prompts = re.sub(r',\s*}', '}', animation_prompts) - animation_prompts = json.loads(animation_prompts.strip()) - - parsed_animation_prompts = {} - for key, value in animation_prompts.items(): - if check_is_number(key): #default case 0:(1 + t %5), 30:(5-t%2) - parsed_animation_prompts[key] = value - else: #math on the left hand side case 0:(1 + t %5), maxKeyframes/2:(5-t%2) - parsed_animation_prompts[int(numexpr.evaluate(key))] = value - - sorted_prompts = sorted(parsed_animation_prompts.items(), key=lambda item: int(item[0])) - - #Setup containers for interpolated prompts - cur_prompt_series = pd.Series([np.nan for a in range(max_frames)]) - nxt_prompt_series = pd.Series([np.nan for a in range(max_frames)]) - - #simple array for strength values - weight_series = [np.nan] * max_frames - - #in case there is only one keyed promt, set all prompts to that prompt - for i in range(0, len(cur_prompt_series)): - for key, value in sorted_prompts: - key = int(key) - if i <= key: - current_prompt = value - break - - cur_prompt_series[i] = current_prompt - nxt_prompt_series[i] = current_prompt - - #Initialized outside of loop for nan check - current_key = 0 - next_key = 0 - - # For every keyframe prompt except the last - for i in range(0, len(sorted_prompts) - 1): - current_key = int(sorted_prompts[i][0]) - next_key = int(sorted_prompts[i + 1][0]) - - current_prompt = sorted_prompts[i][1] - next_prompt = sorted_prompts[i + 1][1] - - weight_step = 1 / (next_key - current_key) - - for f in range(max_frames): - if f < current_key: - # Frame is before the first keyframe, use the first keyframe prompt - cur_prompt_series[f] = current_prompt - nxt_prompt_series[f] = current_prompt - current_weight = 1.0 # Set current_weight unconditionally - elif current_key <= f < next_key: - # Frame is between keyframes, interpolate prompts - next_weight = weight_step * (f - current_key) - current_weight = 1 - next_weight - - cur_prompt_series[f] = current_prompt - nxt_prompt_series[f] = next_prompt - else: - # Frame is after the last keyframe, use the last keyframe prompt - cur_prompt_series[f] = next_prompt - nxt_prompt_series[f] = next_prompt - - weight_series[f] = current_weight - - #Evaluate the current and next prompt's expressions - cur_prompt_series[current_frame] = prepare_prompt(cur_prompt_series[current_frame], max_frames, current_frame, prompt_weight_1, prompt_weight_2, prompt_weight_3, prompt_weight_4) - nxt_prompt_series[current_frame] = prepare_prompt(nxt_prompt_series[current_frame], max_frames, current_frame, prompt_weight_1, prompt_weight_2, prompt_weight_3, prompt_weight_4) - - #Show the to/from prompts with evaluated expressions for transparency. - print("\n", "Max Frames: ", max_frames, "\n", "Current Prompt: ", cur_prompt_series[current_frame], "\n", "Next Prompt: ", nxt_prompt_series[current_frame], "\n", "Strength : ", weight_series[current_frame], "\n") - - #Output methods depending if the prompts are the same or if the current frame is a keyframe. - #if it is an in-between frame and the prompts differ, composable diffusion will be performed. - return (cur_prompt_series[current_frame], nxt_prompt_series[current_frame], weight_series[current_frame]) - def PoolAnimConditioning(cur_prompt, nxt_prompt, weight, clip): if str(cur_prompt) == str(nxt_prompt): tokens = clip.tokenize(str(cur_prompt)) @@ -307,7 +225,7 @@ def SDXLencode(clip, width, height, crop_w, crop_h, target_width, target_height, cond, pooled = clip.encode_from_tokens(tokens, return_pooled=True) return [[cond, {"pooled_output": pooled, "width": width, "height": height, "crop_w": crop_w, "crop_h": crop_h, "target_width": target_width, "target_height": target_height}]] -def interpolate_prompts_SDXL(animation_promptsG, animation_promptsL, max_frames, current_frame, clip, app_text_G, app_text_L, pre_text_G, pre_text_L, pw_a, pw_b, pw_c, pw_d, width, height, crop_w, crop_h, target_width, target_height): #parse the conditioning strength and determine in-betweens. +def interpolate_prompts_SDXL(animation_promptsG, animation_promptsL, max_frames, current_frame, clip, app_text_G, app_text_L, pre_text_G, pre_text_L, pw_a, pw_b, pw_c, pw_d, width, height, crop_w, crop_h, target_width, target_height, print_output): #parse the conditioning strength and determine in-betweens. #Get prompts sorted by keyframe max_f = max_frames #needed for numexpr even though it doesn't look like it's in use. parsed_animation_promptsG = {} @@ -381,8 +299,6 @@ def interpolate_prompts_SDXL(animation_promptsG, animation_promptsL, max_frames, current_weight = 1 - next_weight #add the appropriate prompts and weights to their respective containers. - #print(weight_series) - #print(weight_series[f]) cur_prompt_series_G[f] = '' nxt_prompt_series_G[f] = '' weight_series[f] = 0.0 @@ -436,8 +352,6 @@ def interpolate_prompts_SDXL(animation_promptsG, animation_promptsL, max_frames, current_weight = 1 - next_weight #add the appropriate prompts and weights to their respective containers. - #print(weight_series) - #print(weight_series[f]) cur_prompt_series_L[f] = '' nxt_prompt_series_L[f] = '' weight_series[f] = 0.0 @@ -467,14 +381,14 @@ def interpolate_prompts_SDXL(animation_promptsG, animation_promptsL, max_frames, nxt_prompt_series_G[current_frame] = prepare_prompt(nxt_prompt_series_G[current_frame], max_frames, current_frame, pw_a, pw_b, pw_c, pw_d) cur_prompt_series_L[current_frame] = prepare_prompt(cur_prompt_series_L[current_frame], max_frames, current_frame, pw_a, pw_b, pw_c, pw_d) nxt_prompt_series_L[current_frame] = prepare_prompt(nxt_prompt_series_L[current_frame], max_frames, current_frame, pw_a, pw_b, pw_c, pw_d) + if print_output == True: + #Show the to/from prompts with evaluated expressions for transparency. + print("\n", "G_Clip:", "\n", "Max Frames: ", max_frames, "\n", "Current Prompt: ", cur_prompt_series_G[current_frame], "\n", "Next Prompt: ", nxt_prompt_series_G[current_frame], "\n", "Strength : ", weight_series[current_frame], "\n") - #Show the to/from prompts with evaluated expressions for transparency. - print("\n", "G_Clip:", "\n", "Max Frames: ", max_frames, "\n", "Current Prompt: ", cur_prompt_series_G[current_frame], "\n", "Next Prompt: ", nxt_prompt_series_G[current_frame], "\n", "Strength : ", weight_series[current_frame], "\n") + print("\n", "L_Clip:", "\n", "Max Frames: ", max_frames, "\n", "Current Prompt: ", cur_prompt_series_L[current_frame], "\n", "Next Prompt: ", nxt_prompt_series_L[current_frame], "\n", "Strength : ", weight_series[current_frame], "\n") - print("\n", "L_Clip:", "\n", "Max Frames: ", max_frames, "\n", "Current Prompt: ", cur_prompt_series_L[current_frame], "\n", "Next Prompt: ", nxt_prompt_series_L[current_frame], "\n", "Strength : ", weight_series[current_frame], "\n") #Output methods depending if the prompts are the same or if the current frame is a keyframe. #if it is an in-between frame and the prompts differ, composable diffusion will be performed. - current_cond = SDXLencode(clip, width, height, crop_w, crop_h, target_width, target_height, cur_prompt_series_G[current_frame], cur_prompt_series_L[current_frame]) if str(cur_prompt_series_G[current_frame]) == str(nxt_prompt_series_G[current_frame]) and str(cur_prompt_series_L[current_frame]) == str(nxt_prompt_series_L[current_frame]): diff --git a/ScheduledNodes.py b/ScheduledNodes.py index 21c090f..1adbfb7 100644 --- a/ScheduledNodes.py +++ b/ScheduledNodes.py @@ -10,7 +10,7 @@ import json from .ScheduleFuncs import ( - check_is_number, interpolate_prompts, interpolate_prompts_SDXL, PoolAnimConditioning, + check_is_number, interpolate_prompts_SDXL, PoolAnimConditioning, interpolate_string, addWeighted, reverseConcatenation, split_weighted_subprompts ) from .BatchFuncs import interpolate_prompt_series, BatchPoolAnimConditioning, BatchInterpolatePromptsSDXL, batch_split_weighted_subprompts #, BatchGLIGENConditioning @@ -159,12 +159,8 @@ class BatchPromptScheduleLatentInput: inputText = re.sub(r',\s*}', '}', inputText) animation_prompts = json.loads(inputText.strip()) - print("animation_prompts :", animation_prompts) pos, neg = batch_split_weighted_subprompts(animation_prompts, pre_text, app_text) - print("pos :", pos) - print("neg :", neg) - pos_cur_prompt, pos_nxt_prompt, weight = interpolate_prompt_series(pos, max_frames, pre_text, app_text, pw_a, pw_b, pw_c, pw_d, print_output) @@ -327,7 +323,6 @@ class BatchPromptScheduleEncodeSDXLLatentInput: def animate(self, clip, width, height, crop_w, crop_h, target_width, target_height, text_g, text_l, app_text_G, app_text_L, pre_text_G, pre_text_L, num_latents, print_output, pw_a, pw_b, pw_c, pw_d): max_frames = sum(tensor.size(0) for tensor in num_latents.values()) - print("max_frames", max_frames) inputTextG = str("{" + text_g + "}") inputTextL = str("{" + text_l + "}") inputTextG = re.sub(r',\s*}', '}', inputTextG) @@ -434,12 +429,11 @@ class PromptScheduleNodeFlowEnd: text = text[:-1] if text[0] == ",": text = text[:0] + inputText = str("{" + text + "}") - - print(inputText) inputText = re.sub(r',\s*}', '}', inputText) - animation_prompts = json.loads(inputText.strip()) + pos, neg = batch_split_weighted_subprompts(animation_prompts, pre_text, app_text) pos_cur_prompt, pos_nxt_prompt, weight = interpolate_prompt_series(pos, max_frames, pre_text, app_text, pw_a, @@ -481,11 +475,9 @@ class BatchPromptScheduleNodeFlowEnd: if text[0] == ",": text = text[:0] inputText = str("{" + text + "}") - - print(inputText) inputText = re.sub(r',\s*}', '}', inputText) - animation_prompts = json.loads(inputText.strip()) + pos, neg = batch_split_weighted_subprompts(animation_prompts, pre_text, app_text) pos_cur_prompt, pos_nxt_prompt, weight = interpolate_prompt_series(pos, max_frames, pre_text, app_text, pw_a, @@ -535,6 +527,7 @@ class BatchGLIGENSchedule: inputText = str("{" + text + "}") inputText = re.sub(r',\s*}', '}', inputText) animation_prompts = json.loads(inputText.strip()) + cur_series, nxt_series, weight_series = interpolate_prompt_series(animation_prompts, max_frames, pre_text, app_text, pw_a, pw_b, pw_c, pw_d, print_output) out = [] for i in range(0, max_frames - 1):