o
    ۷i'                     @   s   d dl Zd dl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eZd	eejjB ejB fd
dZdeejjB ejB fddZG dd deZdS )    N   )UNet2DModel)RePaintScheduler)PIL_INTERPOLATION	deprecatelogging)randn_tensor   )DiffusionPipelineImagePipelineOutputimagec                    s   d}t dd|dd t| tjr| S t| tjjr| g} t| d tjjrh| d j\ dd  fD \  fd	d
| D } tj| dd} t	| 
tjd } | dddd} d|  d } t| } | S t| d tjrwtj| dd} | S )NzThe preprocess method is deprecated and will be removed in diffusers 1.0.0. Please use VaeImageProcessor.preprocess(...) instead
preprocessz1.0.0F)standard_warnr   c                 s       | ]	}||d   V  qdS )   N .0xr   r   m/home/ubuntu/vllm_env/lib/python3.10/site-packages/diffusers/pipelines/deprecated/repaint/pipeline_repaint.py	<genexpr>)       z$_preprocess_image.<locals>.<genexpr>c                    s4   g | ]}t |j ftd  ddddf qS )lanczosresampleN)nparrayresizer   )r   ihwr   r   
<listcomp>+   s   4 z%_preprocess_image.<locals>.<listcomp>axis     o@r	         g       @g      ?dim)r   
isinstancetorchTensorPILImagesizer   concatenater   astypefloat32	transpose
from_numpycat)r   deprecation_messager   r   r   _preprocess_image   s&   
r7   maskc                    s   t | tjr| S t | tjjr| g} t | d tjjrY| d j\ dd  fD \  fdd| D } tj| dd} | tj	d } d| | dk < d	| | dk< t
| } | S t | d tjrhtj| dd
} | S )Nr   c                 s   r   )    Nr   r   r   r   r   r   >   r   z#_preprocess_mask.<locals>.<genexpr>c                    s:   g | ]}t |d j ftd ddddf qS )Lnearestr   N)r   r   convertr   r   )r   mr   r   r   r"   ?   s   : z$_preprocess_mask.<locals>.<listcomp>r#   r%         ?r&   r(   )r*   r+   r,   r-   r.   r/   r   r0   r1   r2   r4   r5   )r8   r   r   r   _preprocess_mask6   s"   
r?   c                       s   e Zd ZU dZeed< eed< dZdedef fddZe	
 							
	dde	jejjB de	jejjB dedededede	jee	j B d	B ded	B dedeeB fddZ  ZS )RePaintPipelinea  
    Pipeline for image inpainting using RePaint.

    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.).

    Parameters:
        unet ([`UNet2DModel`]):
            A `UNet2DModel` to denoise the encoded image latents.
        scheduler ([`RePaintScheduler`]):
            A `RePaintScheduler` to be used in combination with `unet` to denoise the encoded image.
    unet	schedulerc                    s   t    | j||d d S )N)rA   rB   )super__init__register_modules)selfrA   rB   	__class__r   r   rD   \   s   
zRePaintPipeline.__init__           
   NpilTr   
mask_imagenum_inference_stepsetajump_lengthjump_n_sample	generatoroutput_typereturn_dictreturnc
              	   C   s  |}
t |
}
|
j| j| jjd}
t|}|j| j| jjd}|
jd }t|tr;t	||kr;t
dt	| d| d|
j}t||| j| jjd}| j|||| j || j_| jjd d }t|trh|d n|}t| | jjD ]&\}}||k r| ||j}| j||||
||j}n| j|||}|}qs|d d	 dd}| ddd
d }|dkr| |}|	s|fS t|dS )a  
        The call function to the pipeline for generation.

        Args:
            image (`torch.Tensor` or `PIL.Image.Image`):
                The original image to inpaint on.
            mask_image (`torch.Tensor` or `PIL.Image.Image`):
                The mask_image where 0.0 define which part of the original image to inpaint.
            num_inference_steps (`int`, *optional*, defaults to 1000):
                The number of denoising steps. More denoising steps usually lead to a higher quality image at the
                expense of slower inference.
            eta (`float`):
                The weight of the added noise in a diffusion step. Its value is between 0.0 and 1.0; 0.0 corresponds to
                DDIM and 1.0 is the DDPM scheduler.
            jump_length (`int`, *optional*, defaults to 10):
                The number of steps taken forward in time before going backward in time for a single jump ("j" in
                RePaint paper). Take a look at Figure 9 and 10 in the
                [paper](https://huggingface.co/papers/2201.09865).
            jump_n_sample (`int`, *optional*, defaults to 10):
                The number of times to make a forward time jump for a given chosen time sample. Take a look at Figure 9
                and 10 in the [paper](https://huggingface.co/papers/2201.09865).
            generator (`torch.Generator`, *optional*):
                A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
                generation deterministic.
            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 [`ImagePipelineOutput`] instead of a plain tuple.

        Example:

        ```py
        >>> from io import BytesIO
        >>> import torch
        >>> import PIL
        >>> import requests
        >>> from diffusers import RePaintPipeline, RePaintScheduler


        >>> def download_image(url):
        ...     response = requests.get(url)
        ...     return PIL.Image.open(BytesIO(response.content)).convert("RGB")


        >>> img_url = "https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/repaint/celeba_hq_256.png"
        >>> mask_url = "https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/repaint/mask_256.png"

        >>> # Load the original image and the mask as PIL images
        >>> original_image = download_image(img_url).resize((256, 256))
        >>> mask_image = download_image(mask_url).resize((256, 256))

        >>> # Load the RePaint scheduler and pipeline based on a pretrained DDPM model
        >>> scheduler = RePaintScheduler.from_pretrained("google/ddpm-ema-celebahq-256")
        >>> pipe = RePaintPipeline.from_pretrained("google/ddpm-ema-celebahq-256", scheduler=scheduler)
        >>> pipe = pipe.to("cuda")

        >>> generator = torch.Generator(device="cuda").manual_seed(0)
        >>> output = pipe(
        ...     image=original_image,
        ...     mask_image=mask_image,
        ...     num_inference_steps=250,
        ...     eta=0.0,
        ...     jump_length=10,
        ...     jump_n_sample=10,
        ...     generator=generator,
        ... )
        >>> inpainted_image = output.images[0]
        ```

        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.
        )devicedtyper   z/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.)rR   rV   rW   r&   r'   r>   r	   rL   )images)r7   to_execution_devicerA   rW   r?   shaper*   listlen
ValueErrorr   rB   set_timestepsrO   	timesteps	enumerateprogress_barsamplestepprev_sample	undo_stepclampcpupermutenumpynumpy_to_pilr   )rF   r   rM   rN   rO   rP   rQ   rR   rS   rT   original_image
batch_sizeimage_shapet_lastr   tmodel_outputr   r   r   __call__`   s>   X


zRePaintPipeline.__call__)rI   rJ   rK   rK   NrL   T)__name__
__module____qualname____doc__r   __annotations__r   model_cpu_offload_seqrD   r+   no_gradr,   r-   r.   intfloat	Generatorr\   strboolr   tuplerr   __classcell__r   r   rG   r   r@   J   sF   
 	
r@   )rj   r   	PIL.Imager-   r+   modelsr   
schedulersr   utilsr   r   r   utils.torch_utilsr   pipeline_utilsr
   r   
get_loggerrs   loggerr\   r.   r,   r7   r?   r@   r   r   r   r   <module>   s   
