@@ -176,7 +176,6 @@ def __init__(
176176 self .image_processor = VaeImageProcessor (vae_scale_factor = self .vae_scale_factor * 2 )
177177 self .system_prompt = "Describe the image by detailing the color, quantity, text, shape, size, texture, spatial relationships of the objects and background: "
178178 self .user_prompt_begin_id = 28
179- self .tokenizer_max_length = 256 + self .user_prompt_begin_id
180179 self .default_sample_size = 128
181180
182181 def _get_messages (
@@ -202,11 +201,12 @@ def _get_ovis_prompt_embeds(
202201 self ,
203202 prompt : str | list [str ] = None ,
204203 num_images_per_prompt : int = 1 ,
204+ max_sequence_length : int = 256 ,
205205 device : torch .device | None = None ,
206206 dtype : torch .dtype | None = None ,
207207 ):
208208 device = device or self ._execution_device
209- dtype = dtype or self .text_encoder .dtype
209+ dtype = dtype or ( self .text_encoder .dtype if self . text_encoder is not None else self . transformer . dtype )
210210
211211 messages = self ._get_messages (prompt )
212212 batch_size = len (messages )
@@ -215,7 +215,7 @@ def _get_ovis_prompt_embeds(
215215 messages ,
216216 padding = "max_length" ,
217217 truncation = True ,
218- max_length = self .tokenizer_max_length ,
218+ max_length = max_sequence_length + self .user_prompt_begin_id ,
219219 return_tensors = "pt" ,
220220 add_special_tokens = False ,
221221 )
@@ -237,41 +237,86 @@ def _get_ovis_prompt_embeds(
237237
238238 return prompt_embeds
239239
240+ def _prepare_prompt_embeds (
241+ self ,
242+ prompt : str | list [str ],
243+ prompt_embeds : torch .FloatTensor | None ,
244+ num_images_per_prompt : int ,
245+ max_sequence_length : int ,
246+ device : torch .device ,
247+ ):
248+ if prompt_embeds is None :
249+ prompt_embeds = self ._get_ovis_prompt_embeds (
250+ prompt = prompt ,
251+ device = device ,
252+ num_images_per_prompt = num_images_per_prompt ,
253+ max_sequence_length = max_sequence_length ,
254+ )
255+ else :
256+ dtype = self .text_encoder .dtype if self .text_encoder is not None else self .transformer .dtype
257+ prompt_embeds = prompt_embeds .to (device = device , dtype = dtype )
258+ batch_size , seq_len , _ = prompt_embeds .shape
259+ prompt_embeds = prompt_embeds .repeat (1 , num_images_per_prompt , 1 )
260+ prompt_embeds = prompt_embeds .view (batch_size * num_images_per_prompt , seq_len , - 1 )
261+
262+ dtype = self .text_encoder .dtype if self .text_encoder is not None else self .transformer .dtype
263+ text_ids = torch .zeros (prompt_embeds .shape [1 ], 3 )
264+ text_ids [..., 1 ] = text_ids [..., 1 ] + torch .arange (prompt_embeds .shape [1 ])[None , :]
265+ text_ids [..., 2 ] = text_ids [..., 2 ] + torch .arange (prompt_embeds .shape [1 ])[None , :]
266+ text_ids = text_ids .to (device = device , dtype = dtype )
267+ return prompt_embeds , text_ids
268+
240269 def encode_prompt (
241270 self ,
242271 prompt : str | list [str ],
272+ negative_prompt : str | list [str ] | None = None ,
273+ do_classifier_free_guidance : bool = True ,
243274 device : torch .device | None = None ,
244275 num_images_per_prompt : int = 1 ,
276+ max_sequence_length : int = 256 ,
245277 prompt_embeds : torch .FloatTensor | None = None ,
278+ negative_prompt_embeds : torch .FloatTensor | None = None ,
246279 ):
247280 r"""
248281
249282 Args:
250- prompt (`str`, *optional*):
283+ prompt (`str` or `list[str]` , *optional*):
251284 prompt to be encoded
285+ negative_prompt (`str` or `list[str]`, *optional*):
286+ The prompt or prompts not to guide the image generation. Used only when `do_classifier_free_guidance`
287+ is `True`. If not defined, an empty string is used.
288+ do_classifier_free_guidance (`bool`, *optional*, defaults to `True`):
289+ Whether to also encode the `negative_prompt` for classifier-free guidance.
252290 device: (`torch.device`):
253291 torch device
254292 num_images_per_prompt (`int`):
255293 number of images that should be generated per prompt
294+ max_sequence_length (`int`, *optional*, defaults to 256):
295+ Maximum sequence length to use for the `prompt`.
256296 prompt_embeds (`torch.FloatTensor`, *optional*):
257297 Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not
258298 provided, text embeddings will be generated from `prompt` input argument.
299+ negative_prompt_embeds (`torch.FloatTensor`, *optional*):
300+ Pre-generated negative text embeddings. If not provided, they are generated from `negative_prompt`.
259301 """
260302 device = device or self ._execution_device
261303
262- if prompt_embeds is None :
263- prompt_embeds = self ._get_ovis_prompt_embeds (
264- prompt = prompt ,
265- device = device ,
266- num_images_per_prompt = num_images_per_prompt ,
304+ prompt_embeds , text_ids = self ._prepare_prompt_embeds (
305+ prompt , prompt_embeds , num_images_per_prompt , max_sequence_length , device
306+ )
307+
308+ negative_text_ids = None
309+ if do_classifier_free_guidance :
310+ if negative_prompt is None :
311+ negative_prompt = ""
312+ if isinstance (negative_prompt , str ):
313+ batch_size = prompt_embeds .shape [0 ] // num_images_per_prompt
314+ negative_prompt = batch_size * [negative_prompt ]
315+ negative_prompt_embeds , negative_text_ids = self ._prepare_prompt_embeds (
316+ negative_prompt , negative_prompt_embeds , num_images_per_prompt , max_sequence_length , device
267317 )
268318
269- dtype = self .text_encoder .dtype if self .text_encoder is not None else self .transformer .dtype
270- text_ids = torch .zeros (prompt_embeds .shape [1 ], 3 )
271- text_ids [..., 1 ] = text_ids [..., 1 ] + torch .arange (prompt_embeds .shape [1 ])[None , :]
272- text_ids [..., 2 ] = text_ids [..., 2 ] + torch .arange (prompt_embeds .shape [1 ])[None , :]
273- text_ids = text_ids .to (device = device , dtype = dtype )
274- return prompt_embeds , text_ids
319+ return prompt_embeds , negative_prompt_embeds , text_ids , negative_text_ids
275320
276321 def check_inputs (
277322 self ,
@@ -516,6 +561,7 @@ def __call__(
516561 max_sequence_length = max_sequence_length ,
517562 )
518563
564+ self ._guidance_scale = guidance_scale
519565 self ._joint_attention_kwargs = joint_attention_kwargs
520566 self ._current_timestep = None
521567 self ._interrupt = False
@@ -533,23 +579,19 @@ def __call__(
533579 do_classifier_free_guidance = guidance_scale > 1
534580 (
535581 prompt_embeds ,
582+ negative_prompt_embeds ,
536583 text_ids ,
584+ negative_text_ids ,
537585 ) = self .encode_prompt (
538586 prompt = prompt ,
587+ negative_prompt = negative_prompt ,
588+ do_classifier_free_guidance = do_classifier_free_guidance ,
539589 prompt_embeds = prompt_embeds ,
590+ negative_prompt_embeds = negative_prompt_embeds ,
540591 device = device ,
541592 num_images_per_prompt = num_images_per_prompt ,
593+ max_sequence_length = max_sequence_length ,
542594 )
543- if do_classifier_free_guidance :
544- (
545- negative_prompt_embeds ,
546- negative_text_ids ,
547- ) = self .encode_prompt (
548- prompt = negative_prompt ,
549- prompt_embeds = negative_prompt_embeds ,
550- device = device ,
551- num_images_per_prompt = num_images_per_prompt ,
552- )
553595
554596 # 4. Prepare latent variables
555597 num_channels_latents = self .transformer .config .in_channels // 4
@@ -609,6 +651,7 @@ def __call__(
609651 encoder_hidden_states = prompt_embeds ,
610652 txt_ids = text_ids ,
611653 img_ids = latent_image_ids ,
654+ joint_attention_kwargs = self .joint_attention_kwargs ,
612655 return_dict = False ,
613656 )[0 ]
614657
@@ -620,6 +663,7 @@ def __call__(
620663 encoder_hidden_states = negative_prompt_embeds ,
621664 txt_ids = negative_text_ids ,
622665 img_ids = latent_image_ids ,
666+ joint_attention_kwargs = self .joint_attention_kwargs ,
623667 return_dict = False ,
624668 )[0 ]
625669 noise_pred = neg_noise_pred + guidance_scale * (noise_pred - neg_noise_pred )
0 commit comments