o
    Gi0                     @   s   d dl mZ d dlZddlmZ ddlmZ ddlmZm	Z	m
Z
 ddlmZ dd	lmZmZ e r=d dlm  mZ d
ZndZe	eZdZG dd deZdS )    )CallableN   )UNet2DModel)CMStochasticIterativeScheduler)is_torch_xla_availableloggingreplace_example_docstring)randn_tensor   )DiffusionPipelineImagePipelineOutputTFa  
    Examples:
        ```py
        >>> import torch

        >>> from diffusers import ConsistencyModelPipeline

        >>> device = "cuda"
        >>> # Load the cd_imagenet64_l2 checkpoint.
        >>> model_id_or_path = "openai/diffusers-cd_imagenet64_l2"
        >>> pipe = ConsistencyModelPipeline.from_pretrained(model_id_or_path, torch_dtype=torch.float16)
        >>> pipe.to(device)

        >>> # Onestep Sampling
        >>> image = pipe(num_inference_steps=1).images[0]
        >>> image.save("cd_imagenet64_l2_onestep_sample.png")

        >>> # Onestep sampling, class-conditional image generation
        >>> # ImageNet-64 class label 145 corresponds to king penguins
        >>> image = pipe(num_inference_steps=1, class_labels=145).images[0]
        >>> image.save("cd_imagenet64_l2_onestep_sample_penguin.png")

        >>> # Multistep sampling, class-conditional image generation
        >>> # Timesteps can be explicitly specified; the particular timesteps below are from the original GitHub repo:
        >>> # https://github.com/openai/consistency_models/blob/main/scripts/launch.sh#L77
        >>> image = pipe(num_inference_steps=None, timesteps=[22, 0], class_labels=145).images[0]
        >>> image.save("cd_imagenet64_l2_multistep_sample_penguin.png")
        ```
c                       s   e Zd ZdZdZdededdf fddZd dd	Zd!de	j
defddZd ddZdd Ze	 ee							
			d"dede	j
ee B eB dB dedee de	jee	j B dB de	j
dB dedB dedeeee	j
gdf dB defddZ  ZS )#ConsistencyModelPipelineab  
    Pipeline for unconditional or class-conditional image generation.

    This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods
    implemented for all pipelines (downloading, saving, running on a particular device, etc.).

    Args:
        unet ([`UNet2DModel`]):
            A `UNet2DModel` to denoise the encoded image latents.
        scheduler ([`SchedulerMixin`]):
            A scheduler to be used in combination with `unet` to denoise the encoded image latents. Currently only
            compatible with [`CMStochasticIterativeScheduler`].
    unet	schedulerreturnNc                    s"   t    | j||d d | _d S )N)r   r   )super__init__register_modulessafety_checker)selfr   r   	__class__ v/home/ubuntu/.local/lib/python3.10/site-packages/diffusers/pipelines/consistency_models/pipeline_consistency_models.pyr   T   s   

z!ConsistencyModelPipeline.__init__c	           
      C   st   ||||f}	t |trt||krtdt| d| d|d u r+t|	|||d}n|j||d}|| jj }|S )Nz/You have passed a list of generators of length z+, but requested an effective batch size of z@. Make sure the batch size matches the length of the generators.)	generatordevicedtype)r   r   )
isinstancelistlen
ValueErrorr	   tor   init_noise_sigma)
r   
batch_sizenum_channelsheightwidthr   r   r   latentsshaper   r   r   prepare_latents^   s   z(ConsistencyModelPipeline.prepare_latentspilsampleoutput_typec                 C   sj   |dvrt d| d|d d dd}|dkr|S | ddd	d }|d
kr.|S | |}|S )N)ptnpr*   zoutput_type=zD is not supported. Make sure to choose one of ['pt', 'np', or 'pil']r
   g      ?r      r-   r   r.   )r    clampcpupermutenumpynumpy_to_pil)r   r+   r,   r   r   r   postprocess_imagep   s   

z*ConsistencyModelPipeline.postprocess_imagec                 C   s   | j jjd urCt|trtj|tjd}n't|tr,|dks"J dtj|gtjd}n|d u r<tjd| j jj|fd}|	|}|S d }|S )N)r   r/   z)Batch size must be 1 if classes is an intr   )size)
r   confignum_class_embedsr   r   torchtensorintrandintr!   )r   r#   r   class_labelsr   r   r   prepare_class_labels   s   


z-ConsistencyModelPipeline.prepare_class_labelsc                 C   s   |d u r|d u rt d|d ur |d ur td| d| d |d ur;|d||f}|j|kr;t d|j d| d|d u sL|d urYt|trL|d	kr[t d
| dt| dd S d S )NzEExactly one of `num_inference_steps` or `timesteps` must be supplied.zBoth `num_inference_steps`: z and `timesteps`: zC are supplied; `timesteps` will be used over `num_inference_steps`.r   zThe shape of latents is z but is expected to be .r   z5`callback_steps` has to be a positive integer but is z	 of type )r    loggerwarningr(   r   r;   type)r   num_inference_steps	timestepsr'   r#   img_sizecallback_stepsexpected_shaper   r   r   check_inputs   s$   
z%ConsistencyModelPipeline.check_inputsr/   Tr#   r=   rC   rD   r   r'   return_dictcallbackrF   c              
   C   sn  | j jj}| j}| ||||||
 | j|| j jj||| j j|||d}| j|||d}|durA| j	j
||d | j	j}t|}n
| j	
| | j	j}| j|dI}t|D ]<\}}| j	||}| j |||ddd }| j	j||||d	d }|  |	dur||
 dkr|	||| trt  qVW d   n1 sw   Y  | j||d
}|   |s|fS t|dS )a	  
        Args:
            batch_size (`int`, *optional*, defaults to 1):
                The number of images to generate.
            class_labels (`torch.Tensor` or `list[int]` or `int`, *optional*):
                Optional class labels for conditioning class-conditional consistency models. Not used if the model is
                not class-conditional.
            num_inference_steps (`int`, *optional*, defaults to 1):
                The number of denoising steps. More denoising steps usually lead to a higher quality image at the
                expense of slower inference.
            timesteps (`list[int]`, *optional*):
                Custom timesteps to use for the denoising process. If not defined, equal spaced `num_inference_steps`
                timesteps are used. Must be in descending order.
            generator (`torch.Generator`, *optional*):
                A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
                generation deterministic.
            latents (`torch.Tensor`, *optional*):
                Pre-generated noisy latents sampled from a Gaussian distribution, to be used as inputs for image
                generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
                tensor is generated by sampling using the supplied random `generator`.
            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 [`~pipelines.ImagePipelineOutput`] instead of a plain tuple.
            callback (`Callable`, *optional*):
                A function that calls every `callback_steps` steps during inference. The function is called with the
                following arguments: `callback(step: int, timestep: int, latents: torch.Tensor)`.
            callback_steps (`int`, *optional*, defaults to 1):
                The frequency at which the `callback` function is called. If not specified, the callback is called at
                every step.

        Examples:

        Returns:
            [`~pipelines.ImagePipelineOutput`] or `tuple`:
                If `return_dict` is `True`, [`~pipelines.ImagePipelineOutput`] is returned, otherwise a `tuple` is
                returned where the first element is a list with the generated images.
        )r#   r$   r%   r&   r   r   r   r'   )r=   N)rD   r   )totalF)r=   rI   r   )r   )r,   )images)r   r7   sample_size_execution_devicerH   r)   in_channelsr   r>   r   set_timestepsrD   r   progress_bar	enumeratescale_model_inputstepupdateXLA_AVAILABLExm	mark_stepr5   maybe_free_model_hooksr   )r   r#   r=   rC   rD   r   r'   r,   rI   rJ   rF   rE   r   r+   rQ   itscaled_samplemodel_outputimager   r   r   __call__   sL   
6

z!ConsistencyModelPipeline.__call__)N)r*   )
r/   Nr/   NNNr*   TNr/   )__name__
__module____qualname____doc__model_cpu_offload_seqr   r   r   r)   r9   Tensorstrr5   r>   rH   no_gradr   EXAMPLE_DOC_STRINGr;   r   	Generatorboolr   r_   __classcell__r   r   r   r   r   C   sR    


	
r   )typingr   r9   modelsr   
schedulersr   utilsr   r   r   utils.torch_utilsr	   pipeline_utilsr   r   torch_xla.core.xla_modelcore	xla_modelrW   rV   
get_loggerr`   r@   rh   r   r   r   r   r   <module>   s   
