def __call__(
        self,
        image: PipelineImageInput,
        last_image: Optional[PipelineImageInput] = None,
        prompt: Union[str, List[str]] = None,
        prompt_2: Union[str, List[str]] = None,
        negative_prompt: Union[str, List[str]] = None,
        negative_prompt_2: Union[str, List[str]] = None,
        height: int = 720,
        width: int = 1280,
        num_frames: int = 129,
        latent_window_size: int = 9,
        num_inference_steps: int = 50,
        sigmas: List[float] = None,
        true_cfg_scale: float = 1.0,
        guidance_scale: float = 6.0,
        num_videos_per_prompt: Optional[int] = 1,
        generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
        image_latents: Optional[torch.Tensor] = None,
        last_image_latents: Optional[torch.Tensor] = None,
        prompt_embeds: Optional[torch.Tensor] = None,
        pooled_prompt_embeds: Optional[torch.Tensor] = None,
        prompt_attention_mask: Optional[torch.Tensor] = None,
        negative_prompt_embeds: Optional[torch.Tensor] = None,
        negative_pooled_prompt_embeds: Optional[torch.Tensor] = None,
        negative_prompt_attention_mask: Optional[torch.Tensor] = None,
        output_type: Optional[str] = "pil",
        return_dict: bool = True,
        attention_kwargs: Optional[Dict[str, Any]] = None,
        callback_on_step_end: Optional[
            Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks]
        ] = None,
        callback_on_step_end_tensor_inputs: List[str] = ["latents"],
        prompt_template: Dict[str, Any] = DEFAULT_PROMPT_TEMPLATE,
        max_sequence_length: int = 256,
        sampling_type: FramepackSamplingType = FramepackSamplingType.INVERTED_ANTI_DRIFTING,
    ):
        r"""
        The call function to the pipeline for generation.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image to be used as the starting point for the video generation.
            last_image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`, *optional*):
                The optional last image to be used as the ending point for the video generation. This is useful for
                generating transitions between two images.
            prompt (`str` or `List[str]`, *optional*):
                The prompt or prompts to guide the image generation. If not defined, one has to pass `prompt_embeds`.
                instead.
            prompt_2 (`str` or `List[str]`, *optional*):
                The prompt or prompts to be sent to `tokenizer_2` and `text_encoder_2`. If not defined, `prompt` is
                will be used instead.
            negative_prompt (`str` or `List[str]`, *optional*):
                The prompt or prompts not to guide the image generation. If not defined, one has to pass
                `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `true_cfg_scale` is
                not greater than `1`).
            negative_prompt_2 (`str` or `List[str]`, *optional*):
                The prompt or prompts not to guide the image generation to be sent to `tokenizer_2` and
                `text_encoder_2`. If not defined, `negative_prompt` is used in all the text-encoders.
            height (`int`, defaults to `720`):
                The height in pixels of the generated image.
            width (`int`, defaults to `1280`):
                The width in pixels of the generated image.
            num_frames (`int`, defaults to `129`):
                The number of frames in the generated video.
            num_inference_steps (`int`, defaults to `50`):
                The number of denoising steps. More denoising steps usually lead to a higher quality image at the
                expense of slower inference.
            sigmas (`List[float]`, *optional*):
                Custom sigmas to use for the denoising process with schedulers which support a `sigmas` argument in
                their `set_timesteps` method. If not defined, the default behavior when `num_inference_steps` is passed
                will be used.
            true_cfg_scale (`float`, *optional*, defaults to 1.0):
                When > 1.0 and a provided `negative_prompt`, enables true classifier-free guidance.
            guidance_scale (`float`, defaults to `6.0`):
                Guidance scale as defined in [Classifier-Free Diffusion
                Guidance](https://huggingface.co/papers/2207.12598). `guidance_scale` is defined as `w` of equation 2.
                of [Imagen Paper](https://huggingface.co/papers/2205.11487). Guidance scale is enabled by setting
                `guidance_scale > 1`. Higher guidance scale encourages to generate images that are closely linked to
                the text `prompt`, usually at the expense of lower image quality. Note that the only available
                HunyuanVideo model is CFG-distilled, which means that traditional guidance between unconditional and
                conditional latent is not applied.
            num_videos_per_prompt (`int`, *optional*, defaults to 1):
                The number of images to generate per prompt.
            generator (`torch.Generator` or `List[torch.Generator]`, *optional*):
                A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
                generation deterministic.
            image_latents (`torch.Tensor`, *optional*):
                Pre-encoded image latents. If not provided, the image will be encoded using the VAE.
            last_image_latents (`torch.Tensor`, *optional*):
                Pre-encoded last image latents. If not provided, the last image will be encoded using the VAE.
            prompt_embeds (`torch.Tensor`, *optional*):
                Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not
                provided, text embeddings are generated from the `prompt` input argument.
            pooled_prompt_embeds (`torch.FloatTensor`, *optional*):
                Pre-generated pooled text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting.
                If not provided, pooled text embeddings will be generated from `prompt` input argument.
            negative_prompt_embeds (`torch.FloatTensor`, *optional*):
                Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
                weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input
                argument.
            negative_pooled_prompt_embeds (`torch.FloatTensor`, *optional*):
                Pre-generated negative pooled text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
                weighting. If not provided, pooled negative_prompt_embeds will be generated from `negative_prompt`
                input argument.
            output_type (`str`, *optional*, defaults to `"pil"`):
                The output format of the generated image. Choose between `PIL.Image` or `np.array`.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a [`HunyuanVideoFramepackPipelineOutput`] instead of a plain tuple.
            attention_kwargs (`dict`, *optional*):
                A kwargs dictionary that if specified is passed along to the `AttentionProcessor` as defined under
                `self.processor` in
                [diffusers.models.attention_processor](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
            clip_skip (`int`, *optional*):
                Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
                the output of the pre-final layer will be used for computing the prompt embeddings.
            callback_on_step_end (`Callable`, `PipelineCallback`, `MultiPipelineCallbacks`, *optional*):
                A function or a subclass of `PipelineCallback` or `MultiPipelineCallbacks` that is called at the end of
                each denoising step during the inference. with the following arguments: `callback_on_step_end(self:
                DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)`. `callback_kwargs` will include a
                list of all tensors as specified by `callback_on_step_end_tensor_inputs`.
            callback_on_step_end_tensor_inputs (`List`, *optional*):
                The list of tensor inputs for the `callback_on_step_end` function. The tensors specified in the list
                will be passed as `callback_kwargs` argument. You will only be able to include variables listed in the
                `._callback_tensor_inputs` attribute of your pipeline class.

        Examples:

        Returns:
            [`~HunyuanVideoFramepackPipelineOutput`] or `tuple`:
                If `return_dict` is `True`, [`HunyuanVideoFramepackPipelineOutput`] is returned, otherwise a `tuple` is
                returned where the first element is a list with the generated images and the second element is a list
                of `bool`s indicating whether the corresponding generated image contains "not-safe-for-work" (nsfw)
                content.
        """

        if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)):
            callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs

        # 1. Check inputs. Raise error if not correct
        self.check_inputs(
            prompt,
            prompt_2,
            height,
            width,
            prompt_embeds,
            callback_on_step_end_tensor_inputs,
            prompt_template,
            image,
            image_latents,
            last_image,
            last_image_latents,
            sampling_type,
        )

        has_neg_prompt = negative_prompt is not None or (
            negative_prompt_embeds is not None and negative_pooled_prompt_embeds is not None
        )
        do_true_cfg = true_cfg_scale > 1 and has_neg_prompt

        self._guidance_scale = guidance_scale
        self._attention_kwargs = attention_kwargs
        self._current_timestep = None
        self._interrupt = False

        device = self._execution_device
        transformer_dtype = self.transformer.dtype
        vae_dtype = self.vae.dtype

        # 2. Define call parameters
        if prompt is not None and isinstance(prompt, str):
            batch_size = 1
        elif prompt is not None and isinstance(prompt, list):
            batch_size = len(prompt)
        else:
            batch_size = prompt_embeds.shape[0]

        # 3. Encode input prompt
        transformer_dtype = self.transformer.dtype
        prompt_embeds, pooled_prompt_embeds, prompt_attention_mask = self.encode_prompt(
            prompt=prompt,
            prompt_2=prompt_2,
            prompt_template=prompt_template,
            num_videos_per_prompt=num_videos_per_prompt,
            prompt_embeds=prompt_embeds,
            pooled_prompt_embeds=pooled_prompt_embeds,
            prompt_attention_mask=prompt_attention_mask,
            device=device,
            max_sequence_length=max_sequence_length,
        )
        prompt_embeds = prompt_embeds.to(transformer_dtype)
        prompt_attention_mask = prompt_attention_mask.to(transformer_dtype)
        pooled_prompt_embeds = pooled_prompt_embeds.to(transformer_dtype)

        if do_true_cfg:
            negative_prompt_embeds, negative_pooled_prompt_embeds, negative_prompt_attention_mask = self.encode_prompt(
                prompt=negative_prompt,
                prompt_2=negative_prompt_2,
                prompt_template=prompt_template,
                num_videos_per_prompt=num_videos_per_prompt,
                prompt_embeds=negative_prompt_embeds,
                pooled_prompt_embeds=negative_pooled_prompt_embeds,
                prompt_attention_mask=negative_prompt_attention_mask,
                device=device,
                max_sequence_length=max_sequence_length,
            )
            negative_prompt_embeds = negative_prompt_embeds.to(transformer_dtype)
            negative_prompt_attention_mask = negative_prompt_attention_mask.to(transformer_dtype)
            negative_pooled_prompt_embeds = negative_pooled_prompt_embeds.to(transformer_dtype)

        # 4. Prepare image
        image = self.video_processor.preprocess(image, height, width)
        image_embeds = self.encode_image(image, device=device).to(transformer_dtype)
        if last_image is not None:
            # Credits: https://github.com/lllyasviel/FramePack/pull/167
            # Users can modify the weighting strategy applied here
            last_image = self.video_processor.preprocess(last_image, height, width)
            last_image_embeds = self.encode_image(last_image, device=device).to(transformer_dtype)
            last_image_embeds = (image_embeds + last_image_embeds) / 2

        # 5. Prepare latent variables
        num_channels_latents = self.transformer.config.in_channels
        window_num_frames = (latent_window_size - 1) * self.vae_scale_factor_temporal + 1
        num_latent_sections = max(1, (num_frames + window_num_frames - 1) // window_num_frames)
        history_video = None
        total_generated_latent_frames = 0

        image_latents = self.prepare_image_latents(
            image, dtype=torch.float32, device=device, generator=generator, latents=image_latents
        )
        if last_image is not None:
            last_image_latents = self.prepare_image_latents(
                last_image, dtype=torch.float32, device=device, generator=generator
            )

        # Specific to the released checkpoints:
        #   - https://huggingface.co/lllyasviel/FramePackI2V_HY
        #   - https://huggingface.co/lllyasviel/FramePack_F1_I2V_HY_20250503
        # TODO: find a more generic way in future if there are more checkpoints
        if sampling_type == FramepackSamplingType.INVERTED_ANTI_DRIFTING:
            history_sizes = [1, 2, 16]
            history_latents = torch.zeros(
                batch_size,
                num_channels_latents,
                sum(history_sizes),
                height // self.vae_scale_factor_spatial,
                width // self.vae_scale_factor_spatial,
                device=device,
                dtype=torch.float32,
            )

        elif sampling_type == FramepackSamplingType.VANILLA:
            history_sizes = [16, 2, 1]
            history_latents = torch.zeros(
                batch_size,
                num_channels_latents,
                sum(history_sizes),
                height // self.vae_scale_factor_spatial,
                width // self.vae_scale_factor_spatial,
                device=device,
                dtype=torch.float32,
            )
            history_latents = torch.cat([history_latents, image_latents], dim=2)
            total_generated_latent_frames += 1

        else:
            assert False

        # 6. Prepare guidance condition
        guidance = torch.tensor([guidance_scale] * batch_size, dtype=transformer_dtype, device=device) * 1000.0

        # 7. Denoising loop
        for k in range(num_latent_sections):
            if sampling_type == FramepackSamplingType.INVERTED_ANTI_DRIFTING:
                latent_paddings = list(reversed(range(num_latent_sections)))
                if num_latent_sections > 4:
                    latent_paddings = [3] + [2] * (num_latent_sections - 3) + [1, 0]

                is_first_section = k == 0
                is_last_section = k == num_latent_sections - 1
                latent_padding_size = latent_paddings[k] * latent_window_size

                indices = torch.arange(0, sum([1, latent_padding_size, latent_window_size, *history_sizes]))
                (
                    indices_prefix,
                    indices_padding,
                    indices_latents,
                    indices_latents_history_1x,
                    indices_latents_history_2x,
                    indices_latents_history_4x,
                ) = indices.split([1, latent_padding_size, latent_window_size, *history_sizes], dim=0)
                # Inverted anti-drifting sampling: Figure 2(c) in the paper
                indices_clean_latents = torch.cat([indices_prefix, indices_latents_history_1x], dim=0)

                latents_prefix = image_latents
                latents_history_1x, latents_history_2x, latents_history_4x = history_latents[
                    :, :, : sum(history_sizes)
                ].split(history_sizes, dim=2)
                if last_image is not None and is_first_section:
                    latents_history_1x = last_image_latents
                latents_clean = torch.cat([latents_prefix, latents_history_1x], dim=2)

            elif sampling_type == FramepackSamplingType.VANILLA:
                indices = torch.arange(0, sum([1, *history_sizes, latent_window_size]))
                (
                    indices_prefix,
                    indices_latents_history_4x,
                    indices_latents_history_2x,
                    indices_latents_history_1x,
                    indices_latents,
                ) = indices.split([1, *history_sizes, latent_window_size], dim=0)
                indices_clean_latents = torch.cat([indices_prefix, indices_latents_history_1x], dim=0)

                latents_prefix = image_latents
                latents_history_4x, latents_history_2x, latents_history_1x = history_latents[
                    :, :, -sum(history_sizes) :
                ].split(history_sizes, dim=2)
                latents_clean = torch.cat([latents_prefix, latents_history_1x], dim=2)

            else:
                assert False

            latents = self.prepare_latents(
                batch_size,
                num_channels_latents,
                height,
                width,
                window_num_frames,
                dtype=torch.float32,
                device=device,
                generator=generator,
                latents=None,
            )

            sigmas = np.linspace(1.0, 0.0, num_inference_steps + 1)[:-1] if sigmas is None else sigmas
            image_seq_len = (
                latents.shape[2] * latents.shape[3] * latents.shape[4] / self.transformer.config.patch_size**2
            )
            exp_max = 7.0
            mu = calculate_shift(
                image_seq_len,
                self.scheduler.config.get("base_image_seq_len", 256),
                self.scheduler.config.get("max_image_seq_len", 4096),
                self.scheduler.config.get("base_shift", 0.5),
                self.scheduler.config.get("max_shift", 1.15),
            )
            mu = min(mu, math.log(exp_max))
            timesteps, num_inference_steps = retrieve_timesteps(
                self.scheduler, num_inference_steps, device, sigmas=sigmas, mu=mu
            )
            num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
            self._num_timesteps = len(timesteps)

            with self.progress_bar(total=num_inference_steps) as progress_bar:
                for i, t in enumerate(timesteps):
                    if self.interrupt:
                        continue

                    self._current_timestep = t
                    timestep = t.expand(latents.shape[0])

                    noise_pred = self.transformer(
                        hidden_states=latents.to(transformer_dtype),
                        timestep=timestep,
                        encoder_hidden_states=prompt_embeds,
                        encoder_attention_mask=prompt_attention_mask,
                        pooled_projections=pooled_prompt_embeds,
                        image_embeds=image_embeds,
                        indices_latents=indices_latents,
                        guidance=guidance,
                        latents_clean=latents_clean.to(transformer_dtype),
                        indices_latents_clean=indices_clean_latents,
                        latents_history_2x=latents_history_2x.to(transformer_dtype),
                        indices_latents_history_2x=indices_latents_history_2x,
                        latents_history_4x=latents_history_4x.to(transformer_dtype),
                        indices_latents_history_4x=indices_latents_history_4x,
                        attention_kwargs=attention_kwargs,
                        return_dict=False,
                    )[0]

                    if do_true_cfg:
                        neg_noise_pred = self.transformer(
                            hidden_states=latents.to(transformer_dtype),
                            timestep=timestep,
                            encoder_hidden_states=negative_prompt_embeds,
                            encoder_attention_mask=negative_prompt_attention_mask,
                            pooled_projections=negative_pooled_prompt_embeds,
                            image_embeds=image_embeds,
                            indices_latents=indices_latents,
                            guidance=guidance,
                            latents_clean=latents_clean.to(transformer_dtype),
                            indices_latents_clean=indices_clean_latents,
                            latents_history_2x=latents_history_2x.to(transformer_dtype),
                            indices_latents_history_2x=indices_latents_history_2x,
                            latents_history_4x=latents_history_4x.to(transformer_dtype),
                            indices_latents_history_4x=indices_latents_history_4x,
                            attention_kwargs=attention_kwargs,
                            return_dict=False,
                        )[0]
                        noise_pred = neg_noise_pred + true_cfg_scale * (noise_pred - neg_noise_pred)

                    # compute the previous noisy sample x_t -> x_t-1
                    latents = self.scheduler.step(noise_pred.float(), t, latents, return_dict=False)[0]

                    if callback_on_step_end is not None:
                        callback_kwargs = {}
                        for k in callback_on_step_end_tensor_inputs:
                            callback_kwargs[k] = locals()[k]
                        callback_outputs = callback_on_step_end(self, i, t, callback_kwargs)

                        latents = callback_outputs.pop("latents", latents)
                        prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds)

                    # call the callback, if provided
                    if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0):
                        progress_bar.update()

                    if XLA_AVAILABLE:
                        xm.mark_step()

                if sampling_type == FramepackSamplingType.INVERTED_ANTI_DRIFTING:
                    if is_last_section:
                        latents = torch.cat([image_latents, latents], dim=2)
                    total_generated_latent_frames += latents.shape[2]
                    history_latents = torch.cat([latents, history_latents], dim=2)
                    real_history_latents = history_latents[:, :, :total_generated_latent_frames]
                    section_latent_frames = (
                        (latent_window_size * 2 + 1) if is_last_section else (latent_window_size * 2)
                    )
                    index_slice = (slice(None), slice(None), slice(0, section_latent_frames))

                elif sampling_type == FramepackSamplingType.VANILLA:
                    total_generated_latent_frames += latents.shape[2]
                    history_latents = torch.cat([history_latents, latents], dim=2)
                    real_history_latents = history_latents[:, :, -total_generated_latent_frames:]
                    section_latent_frames = latent_window_size * 2
                    index_slice = (slice(None), slice(None), slice(-section_latent_frames, None))

                else:
                    assert False

                if history_video is None:
                    if not output_type == "latent":
                        current_latents = real_history_latents.to(vae_dtype) / self.vae.config.scaling_factor
                        history_video = self.vae.decode(current_latents, return_dict=False)[0]
                    else:
                        history_video = [real_history_latents]
                else:
                    if not output_type == "latent":
                        overlapped_frames = (latent_window_size - 1) * self.vae_scale_factor_temporal + 1
                        current_latents = (
                            real_history_latents[index_slice].to(vae_dtype) / self.vae.config.scaling_factor
                        )
                        current_video = self.vae.decode(current_latents, return_dict=False)[0]

                        if sampling_type == FramepackSamplingType.INVERTED_ANTI_DRIFTING:
                            history_video = self._soft_append(current_video, history_video, overlapped_frames)
                        elif sampling_type == FramepackSamplingType.VANILLA:
                            history_video = self._soft_append(history_video, current_video, overlapped_frames)
                        else:
                            assert False
                    else:
                        history_video.append(real_history_latents)

        self._current_timestep = None

        if not output_type == "latent":
            generated_frames = history_video.size(2)
            generated_frames = (
                generated_frames - 1
            ) // self.vae_scale_factor_temporal * self.vae_scale_factor_temporal + 1
            history_video = history_video[:, :, :generated_frames]
            video = self.video_processor.postprocess_video(history_video, output_type=output_type)
        else:
            video = history_video

        # Offload all models
        self.maybe_free_model_hooks()

        if not return_dict:
            return (video,)

        return HunyuanVideoFramepackPipelineOutput(frames=video)

        The call function to the pipeline for generation.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image to be used as the starting point for the video generation.
            last_image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`, *optional*):
                The optional last image to be used as the ending point for the video generation. This is useful for
                generating transitions between two images.
            prompt (`str` or `List[str]`, *optional*):
                The prompt or prompts to guide the image generation. If not defined, one has to pass `prompt_embeds`.
                instead.
            prompt_2 (`str` or `List[str]`, *optional*):
                The prompt or prompts to be sent to `tokenizer_2` and `text_encoder_2`. If not defined, `prompt` is
                will be used instead.
            negative_prompt (`str` or `List[str]`, *optional*):
                The prompt or prompts not to guide the image generation. If not defined, one has to pass
                `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `true_cfg_scale` is
                not greater than `1`).
            negative_prompt_2 (`str` or `List[str]`, *optional*):
                The prompt or prompts not to guide the image generation to be sent to `tokenizer_2` and
                `text_encoder_2`. If not defined, `negative_prompt` is used in all the text-encoders.
            height (`int`, defaults to `720`):
                The height in pixels of the generated image.
            width (`int`, defaults to `1280`):
                The width in pixels of the generated image.
            num_frames (`int`, defaults to `129`):
                The number of frames in the generated video.
            num_inference_steps (`int`, defaults to `50`):
                The number of denoising steps. More denoising steps usually lead to a higher quality image at the
                expense of slower inference.
            sigmas (`List[float]`, *optional*):
                Custom sigmas to use for the denoising process with schedulers which support a `sigmas` argument in
                their `set_timesteps` method. If not defined, the default behavior when `num_inference_steps` is passed
                will be used.
            true_cfg_scale (`float`, *optional*, defaults to 1.0):
                When > 1.0 and a provided `negative_prompt`, enables true classifier-free guidance.
            guidance_scale (`float`, defaults to `6.0`):
                Guidance scale as defined in [Classifier-Free Diffusion
                Guidance](https://huggingface.co/papers/2207.12598). `guidance_scale` is defined as `w` of equation 2.
                of [Imagen Paper](https://huggingface.co/papers/2205.11487). Guidance scale is enabled by setting
                `guidance_scale > 1`. Higher guidance scale encourages to generate images that are closely linked to
                the text `prompt`, usually at the expense of lower image quality. Note that the only available
                HunyuanVideo model is CFG-distilled, which means that traditional guidance between unconditional and
                conditional latent is not applied.
            num_videos_per_prompt (`int`, *optional*, defaults to 1):
                The number of images to generate per prompt.
            generator (`torch.Generator` or `List[torch.Generator]`, *optional*):
                A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
                generation deterministic.
            image_latents (`torch.Tensor`, *optional*):
                Pre-encoded image latents. If not provided, the image will be encoded using the VAE.
            last_image_latents (`torch.Tensor`, *optional*):
                Pre-encoded last image latents. If not provided, the last image will be encoded using the VAE.
            prompt_embeds (`torch.Tensor`, *optional*):
                Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not
                provided, text embeddings are generated from the `prompt` input argument.
            pooled_prompt_embeds (`torch.FloatTensor`, *optional*):
                Pre-generated pooled text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting.
                If not provided, pooled text embeddings will be generated from `prompt` input argument.
            negative_prompt_embeds (`torch.FloatTensor`, *optional*):
                Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
                weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input
                argument.
            negative_pooled_prompt_embeds (`torch.FloatTensor`, *optional*):
                Pre-generated negative pooled text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
                weighting. If not provided, pooled negative_prompt_embeds will be generated from `negative_prompt`
                input argument.
            output_type (`str`, *optional*, defaults to `"pil"`):
                The output format of the generated image. Choose between `PIL.Image` or `np.array`.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a [`HunyuanVideoFramepackPipelineOutput`] instead of a plain tuple.
            attention_kwargs (`dict`, *optional*):
                A kwargs dictionary that if specified is passed along to the `AttentionProcessor` as defined under
                `self.processor` in
                [diffusers.models.attention_processor](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
            clip_skip (`int`, *optional*):
                Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
                the output of the pre-final layer will be used for computing the prompt embeddings.
            callback_on_step_end (`Callable`, `PipelineCallback`, `MultiPipelineCallbacks`, *optional*):
                A function or a subclass of `PipelineCallback` or `MultiPipelineCallbacks` that is called at the end of
                each denoising step during the inference. with the following arguments: `callback_on_step_end(self:
                DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)`. `callback_kwargs` will include a
                list of all tensors as specified by `callback_on_step_end_tensor_inputs`.
            callback_on_step_end_tensor_inputs (`List`, *optional*):
                The list of tensor inputs for the `callback_on_step_end` function. The tensors specified in the list
                will be passed as `callback_kwargs` argument. You will only be able to include variables listed in the
                `._callback_tensor_inputs` attribute of your pipeline class.

        Examples:

        Returns:
            [`~HunyuanVideoFramepackPipelineOutput`] or `tuple`:
                If `return_dict` is `True`, [`HunyuanVideoFramepackPipelineOutput`] is returned, otherwise a `tuple` is
                returned where the first element is a list with the generated images and the second element is a list
                of `bool`s indicating whether the corresponding generated image contains "not-safe-for-work" (nsfw)
                content.
        
src/diffusers/pipelines/hunyuan_video/pipeline_hunyuan_video_framepack.py