@@ -291,6 +291,8 @@ def INPUT_TYPES(s):
291291 "start_latent" : ("LATENT" , {"tooltip" : "init Latents to use for image2video" } ),
292292 "end_latent" : ("LATENT" , {"tooltip" : "end Latents to use for image2video" } ),
293293 "end_image_embeds" : ("CLIP_VISION_OUTPUT" , {"tooltip" : "end Image's clip embeds" } ),
294+ "embed_interpolation" : (["weighted_average" , "linear" ], {"default" : 'linear' , "tooltip" : "Image embedding interpolation type. If linear, will smoothly interpolate with time, else it'll be weighted average with the specified weight." }),
295+ "start_embed_strength" : ("FLOAT" , {"default" : 0.5 , "min" : 0.0 , "max" : 1.0 , "step" : 0.01 , "tooltip" : "Weighted average constant for image embed interpolation. If end image is not set, the embed's strength won't be affected" }),
294296 "initial_samples" : ("LATENT" , {"tooltip" : "init Latents to use for video2video" } ),
295297 "denoise_strength" : ("FLOAT" , {"default" : 1.0 , "min" : 0.0 , "max" : 1.0 , "step" : 0.01 }),
296298 }
@@ -302,7 +304,7 @@ def INPUT_TYPES(s):
302304 CATEGORY = "FramePackWrapper"
303305
304306 def process (self , model , shift , positive , negative , latent_window_size , use_teacache , total_second_length , teacache_rel_l1_thresh , image_embeds , steps , cfg ,
305- guidance_scale , seed , sampler , gpu_memory_preservation , start_latent = None , end_latent = None , end_image_embeds = None , initial_samples = None , denoise_strength = 1.0 ):
307+ guidance_scale , seed , sampler , gpu_memory_preservation , start_latent = None , end_latent = None , end_image_embeds = None , embed_interpolation = "linear" , start_embed_strength = 1.0 , initial_samples = None , denoise_strength = 1.0 ):
306308 total_latent_sections = (total_second_length * 30 ) / (latent_window_size * 4 )
307309 total_latent_sections = int (max (round (total_latent_sections ), 1 ))
308310 print ("total_latent_sections: " , total_latent_sections )
@@ -326,13 +328,13 @@ def process(self, model, shift, positive, negative, latent_window_size, use_teac
326328 print ("start_latent" , start_latent .shape )
327329 B , C , T , H , W = start_latent .shape
328330
329- image_encoder_last_hidden_state = image_embeds ["last_hidden_state" ].to (base_dtype ).to (device )
331+ start_image_encoder_last_hidden_state = image_embeds ["last_hidden_state" ].to (base_dtype ).to (device )
330332
331333 if has_end_image :
332334 assert end_image_embeds is not None
333335 end_image_encoder_last_hidden_state = end_image_embeds ["last_hidden_state" ].to (base_dtype ).to (device )
334- # Combine both image embeddings or use a weighted approach
335- image_encoder_last_hidden_state = ( image_encoder_last_hidden_state + end_image_encoder_last_hidden_state ) / 2
336+ else :
337+ end_image_encoder_last_hidden_state = torch . zeros_like ( start_image_encoder_last_hidden_state )
336338
337339 llama_vec = positive [0 ][0 ].to (base_dtype ).to (device )
338340 clip_l_pooler = positive [0 ][1 ]["pooled_output" ].to (base_dtype ).to (device )
@@ -380,13 +382,20 @@ def process(self, model, shift, positive, negative, latent_window_size, use_teac
380382 # use `latent_paddings = list(reversed(range(total_latent_sections)))` to compare
381383 latent_paddings = [3 ] + [2 ] * (total_latent_sections - 3 ) + [1 , 0 ]
382384 latent_paddings_list = latent_paddings .copy ()
383-
384- for latent_padding in latent_paddings :
385+
386+ for i , latent_padding in enumerate ( latent_paddings ) :
385387 print (f"latent_padding: { latent_padding } " )
386388 is_last_section = latent_padding == 0
387389 is_first_section = latent_padding == latent_paddings [0 ]
388390 latent_padding_size = latent_padding * latent_window_size
389391
392+ if embed_interpolation == "linear" :
393+ frac = 1 - i / (total_latent_sections - 1 ) # going backwards
394+ else :
395+ frac = start_embed_strength if has_end_image else 1.0
396+
397+ image_encoder_last_hidden_state = start_image_encoder_last_hidden_state * frac + (1 - frac ) * end_image_encoder_last_hidden_state
398+
390399 print (f'latent_padding_size = { latent_padding_size } , is_last_section = { is_last_section } , is_first_section = { is_first_section } ' )
391400
392401 indices = torch .arange (0 , sum ([1 , latent_padding_size , latent_window_size , 1 , 2 , 16 ])).unsqueeze (0 )
0 commit comments