o
    Gi%                     @   sR  d dl Z 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
 ddlmZ ddlmZ d	d
lmZmZmZmZ d	dlmZmZmZ ddlmZ eeZG dd deZG dd deZG dd deZG dd deZG dd deZ G dd deZ!G dd deZ"G dd de"Z#G dd de"Z$G d d! d!e"Z%G d"d# d#e"Z&dS )$    N)Any   )
FrozenDict)ClassifierFreeGuidance)ControlNetModelUNet2DConditionModel)EulerDiscreteScheduler)logging   )
BlockStateLoopSequentialPipelineBlocksModularPipelineBlocksPipelineState)ComponentSpec
InputParamOutputParam   ) StableDiffusionXLModularPipelinec                	   @   sp   e Zd ZdZedee fddZedefddZ	edee fddZ
e d	ed
ededefddZdS )#StableDiffusionXLLoopBeforeDenoiserstable-diffusion-xlreturnc                 C      t dtgS N	schedulerr   r   self r   k/home/ubuntu/.local/lib/python3.10/site-packages/diffusers/modular_pipelines/stable_diffusion_xl/denoise.pyexpected_components+      z7StableDiffusionXLLoopBeforeDenoiser.expected_componentsc                 C      	 dS )Nzstep within the denoising loop that prepare the latent input for the denoiser. This block should be used to compose the `sub_blocks` attribute of a `LoopSequentialPipelineBlocks` object (e.g. `StableDiffusionXLDenoiseLoopWrapper`)r   r   r   r   r   description1      z/StableDiffusionXLLoopBeforeDenoiser.descriptionc                 C   s   t ddtjddgS )NlatentsT^The initial latents to use for the denoising process. Can be generated in prepare_latent step.required	type_hintr"   r   torchTensorr   r   r   r   inputs9   s   z*StableDiffusionXLLoopBeforeDenoiser.inputs
componentsblock_stateitc                 C   s   |j |j||_||fS N)r   scale_model_inputr$   scaled_latentsr   r-   r.   r/   r0   r   r   r   __call__D   s   z,StableDiffusionXLLoopBeforeDenoiser.__call__N)__name__
__module____qualname__
model_namepropertylistr   r   strr"   r,   r*   no_gradr   r   intr5   r   r   r   r   r   (   s    
 r   c                	   @   s|   e Zd ZdZedee fddZedefddZ	edee fddZ
ed	d
 Ze dedededefddZdS )*StableDiffusionXLInpaintLoopBeforeDenoiserr   r   c                 C      t dtt dtgS Nr   unetr   r   r   r   r   r   r   r   O      z>StableDiffusionXLInpaintLoopBeforeDenoiser.expected_componentsc                 C   r!   )Nzstep within the denoising loop that prepare the latent input for the denoiser (for inpainting workflow only). This block should be used to compose the `sub_blocks` attribute of a `LoopSequentialPipelineBlocks` objectr   r   r   r   r   r"   V   r#   z6StableDiffusionXLInpaintLoopBeforeDenoiser.descriptionc                 C   s8   t ddtjddt dtjd B ddt dtjd B d	dgS )
Nr$   Tr%   r&   mask{The mask to use for the denoising process, for inpainting task only. Can be generated in vae_encode or prepare_latent step.r(   r"   masked_image_latentszThe masked image latents to use for the denoising process, for inpainting task only. Can be generated in vae_encode or prepare_latent step.r)   r   r   r   r   r,   ]   s"   z1StableDiffusionXLInpaintLoopBeforeDenoiser.inputsc                 C   s   | j }|dkrO|jd u s|jd u rtd|jjd }|jjd }|jjd }|| | |krQtd| jj d| jjj d| d| d| d	|| |  d
d S d S )N	   zKmask and masked_image_latents must be provided for inpainting-specific Unetr   zCIncorrect configuration settings! The config of `components.unet`: z	 expects z& but received `num_channels_latents`: z + `num_channels_mask`: z  + `num_channels_masked_image`: z = zV. Please verify the config of `components.unet` or your `mask_image` or `image` input.)	num_channels_unetrE   rH   
ValueErrorr$   shaperB   configin_channels)r-   r.   rJ   num_channels_latentsnum_channels_masknum_channels_masked_imager   r   r   check_inputsr   s.   
z7StableDiffusionXLInpaintLoopBeforeDenoiser.check_inputsr-   r.   r/   r0   c                 C   sL   |  || |j|j||_|jdkr"tj|j|j|j	gdd|_||fS )NrI   r   )dim)
rR   r   r2   r$   r3   rJ   r*   catrE   rH   r4   r   r   r   r5      s   
z3StableDiffusionXLInpaintLoopBeforeDenoiser.__call__N)r6   r7   r8   r9   r:   r;   r   r   r<   r"   r,   staticmethodrR   r*   r=   r   r   r>   r5   r   r   r   r   r?   L   s    
 r?   c                   @   s|   e Zd ZdZedee fddZedefddZ	edee
eef  fddZe d	ed
edededef
ddZdS )StableDiffusionXLLoopDenoiserr   r   c                 C   s"   t dttddiddt dtgS )Nguiderguidance_scale      @from_configrM   default_creation_methodrB   )r   r   r   r   r   r   r   r   r      s   
z1StableDiffusionXLLoopDenoiser.expected_componentsc                 C   r!   )NzStep within the denoising loop that denoise the latents with guidance. This block should be used to compose the `sub_blocks` attribute of a `LoopSequentialPipelineBlocks` object (e.g. `StableDiffusionXLDenoiseLoopWrapper`)r   r   r   r   r   r"      r#   z)StableDiffusionXLLoopDenoiser.descriptionc                 C   s4   t dt ddtddt dtjd B ddt d	d
dgS )Ncross_attention_kwargsnum_inference_stepsTgThe number of inference steps to use for the denoising process. Can be generated in set_timesteps step.r&   timestep_condzThe guidance scale embedding to use for Latent Consistency Models(LCMs). Can be generated in prepare_additional_conditioning step.rG   denoiser_input_fields  All conditional model inputs that need to be prepared with guider. It should contain prompt_embeds/negative_prompt_embeds, add_time_ids/negative_add_time_ids, pooled_prompt_embeds/negative_pooled_prompt_embeds, and ip_adapter_embeds/negative_ip_adapter_embeds (optional).please add `kwargs_type=denoiser_input_fields` to their parameter spec (`OutputParam`) when they are created and added to the pipeline statekwargs_typer"   )r   r>   r*   r+   r   r   r   r   r,      s"   z$StableDiffusionXLLoopDenoiser.inputsr-   r.   r/   r0   c           	   
      s   t |dd t |dd ft |dd t |dd ft |dd t |dd ft |dd t |dd fd	}|jj||j|d
 |j|}|D ]2 |j|j  fdd| D }|d}|j|j	|||j
|j|ddd  _|j|j qA||d |_||fS )Nprompt_embedsnegative_prompt_embedsadd_time_idsnegative_add_time_idspooled_prompt_embedsnegative_pooled_prompt_embedsip_adapter_embedsnegative_ip_adapter_embedsre   time_idstext_embedsimage_embedsstepr^   timestepc                    s   i | ]}|t  |qS r   )getattr).0
input_nameguider_state_batchr   r   
<dictcomp>   s    z:StableDiffusionXLLoopDenoiser.__call__.<locals>.<dictcomp>F)encoder_hidden_statesr`   r]   added_cond_kwargsreturn_dictr   )rt   rW   	set_stater^   prepare_inputsprepare_modelsrB   keyspopr3   r`   r]   
noise_predcleanup_models)	r   r-   r.   r/   r0   guider_inputsguider_statecond_kwargsre   r   rw   r   r5      sB   









	z&StableDiffusionXLLoopDenoiser.__call__N)r6   r7   r8   r9   r:   r;   r   r   r<   r"   tupler   r,   r*   r=   r   r   r>   r   r5   r   r   r   r   rV      s(    rV   c                	   @   s   e Zd ZdZedee fddZedefddZ	edee
eef  fddZeg fd	d
Ze dedededefddZdS )'StableDiffusionXLControlNetLoopDenoiserr   r   c                 C   *   t dttddiddt dtt dtgS )NrW   rX   rY   rZ   r[   rB   
controlnet)r   r   r   r   r   r   r   r   r   r        
z;StableDiffusionXLControlNetLoopDenoiser.expected_componentsc                 C   r!   )Nzstep within the denoising loop that denoise the latents with guidance (with controlnet). This block should be used to compose the `sub_blocks` attribute of a `LoopSequentialPipelineBlocks` object (e.g. `StableDiffusionXLDenoiseLoopWrapper`)r   r   r   r   r   r"     r#   z3StableDiffusionXLControlNetLoopDenoiser.descriptionc                 C   sz   t dt ddtjddt dtddt d	dtd
dt ddtt ddt dtjd B ddt ddtddt dddt dddg	S )Nr]   controlnet_condTzgThe control image to use for the denoising process. Can be generated in prepare_controlnet_inputs step.r&   conditioning_scalez}The controlnet conditioning scale value to use for the denoising process. Can be generated in prepare_controlnet_inputs step.rG   
guess_modezjThe guess mode value to use for the denoising process. Can be generated in prepare_controlnet_inputs step.controlnet_keepzpThe controlnet keep values to use for the denoising process. Can be generated in prepare_controlnet_inputs step.r`   zThe guidance scale embedding to use for Latent Consistency Models(LCMs), can be generated by prepare_additional_conditioning stepr^   r_   ra   rb   rc   controlnet_kwargszadditional kwargs for controlnet (e.g. control_type_idx and control_type from the controlnet union input step )please add `kwargs_type=controlnet_kwargs` to their parameter spec (`OutputParam`) when they are created and added to the pipeline state)r   r*   r+   floatboolr;   r>   r   r   r   r   r,     sX   z.StableDiffusionXLControlNetLoopDenoiser.inputsc                 K   F   t t| j }i }| D ]\}}||v r ||vr |||< q|S r1   setinspect	signature
parametersr   itemsfuncexclude_kwargskwargsaccepted_kwargsextra_kwargskeyvaluer   r   r   prepare_extra_kwargsW     z<StableDiffusionXLControlNetLoopDenoiser.prepare_extra_kwargsr-   r.   r/   r0   c                 C   s  | j |jjfi |j}t|dd t|dd ft|dd t|dd ft|dd t|dd ft|dd t|dd fd	}t|j| trSd
d t|j	|j| D |_
n|j	}t|tr_|d }||j|  |_
d |_d |_|jj||j|d |j|}|D ]}	|j|j |	j|	jd}
t|	dr|	jd ur|	j|
d< |	j|	jd}|jr|jjs|j}|j}n0|j|j|f|	j|j|j
|j|dd|\}}|jd u rdd |D |_|jd u rt||_|j|j||	j|j|j|
||dd	d |	_ |j!|j q||d |_ ||fS )Nre   rf   rg   rh   ri   rj   rk   rl   rm   c                 S   s   g | ]\}}|| qS r   r   )ru   csr   r   r   
<listcomp>~  s    zDStableDiffusionXLControlNetLoopDenoiser.__call__.<locals>.<listcomp>r   rq   )ro   rn   rp   F)rz   r   r   r   r{   r|   c                 S   s   g | ]}t |qS r   )r*   
zeros_like)ru   dr   r   r   r     s    )rz   r`   r]   r{   down_block_additional_residualsmid_block_additional_residualr|   )"r   r   forwardr   rt   
isinstancer   r;   zipr   
cond_scaledown_block_res_samples_zerosmid_block_res_sample_zerosrW   r}   r^   r~   r   rB   ro   rn   hasattrrp   r   is_conditionalr3   re   r   r*   r   r`   r]   r   r   )r   r-   r.   r/   r0   extra_controlnet_kwargsr   controlnet_cond_scaler   rx   r{   controlnet_added_cond_kwargsdown_block_res_samplesmid_block_res_sampler   r   r   r5   a  s   











	



z0StableDiffusionXLControlNetLoopDenoiser.__call__N)r6   r7   r8   r9   r:   r;   r   r   r<   r"   r   r   r,   rU   r   r*   r=   r   r   r>   r5   r   r   r   r   r     s    9	 r   c                	   @   s   e Zd ZdZedee fddZedefddZ	edee
eef  fddZedee fd	d
Zeg fddZe dedededefddZdS )"StableDiffusionXLLoopAfterDenoiserr   r   c                 C   r   r   r   r   r   r   r   r     r    z6StableDiffusionXLLoopAfterDenoiser.expected_componentsc                 C   r!   )Nzstep within the denoising loop that update the latents. This block should be used to compose the `sub_blocks` attribute of a `LoopSequentialPipelineBlocks` object (e.g. `StableDiffusionXLDenoiseLoopWrapper`)r   r   r   r   r   r"     r#   z.StableDiffusionXLLoopAfterDenoiser.descriptionc                 C   s   t dddt dgS )Neta        default	generator)r   r   r   r   r   r,     s   
z)StableDiffusionXLLoopAfterDenoiser.inputsc                 C      t dtjddgS Nr$   zThe denoised latentsrG   r   r*   r+   r   r   r   r   intermediate_outputs     z7StableDiffusionXLLoopAfterDenoiser.intermediate_outputsc                 K   r   r1   r   r   r   r   r   r     r   z7StableDiffusionXLLoopAfterDenoiser.prepare_extra_kwargsr-   r.   r/   r0   c                 C   s   | j |jj|j|jd|_|jj|_|jj|j	||jfi |jddid |_|jj|jkr=t
jj r=|j|j|_||fS )Nr   r   r|   Fr   )r   r   rr   r   r   extra_step_kwargsr$   dtypelatents_dtyper   r*   backendsmpsis_availabletor4   r   r   r   r5     s&   
z+StableDiffusionXLLoopAfterDenoiser.__call__N)r6   r7   r8   r9   r:   r;   r   r   r<   r"   r   r   r,   r   r   rU   r   r*   r=   r   r   r>   r5   r   r   r   r   r     s    	 r   c                	   @   s   e Zd ZdZedee fddZedefddZ	edee
eef  fddZedee fd	d
Zeg fddZdd Ze dedededefddZdS ))StableDiffusionXLInpaintLoopAfterDenoiserr   r   c                 C   r@   rA   rC   r   r   r   r   r     rD   z=StableDiffusionXLInpaintLoopAfterDenoiser.expected_componentsc                 C   r!   )Nzstep within the denoising loop that update the latents (for inpainting workflow only). This block should be used to compose the `sub_blocks` attribute of a `LoopSequentialPipelineBlocks` object (e.g. `StableDiffusionXLDenoiseLoopWrapper`)r   r   r   r   r   r"   "  r#   z5StableDiffusionXLInpaintLoopAfterDenoiser.descriptionc              
   C   sZ   t dddt dt ddtjddt d	tjd B d
dt dtjd B ddt dtjd B ddgS )Nr   r   r   r   	timestepsTWThe timesteps to use for the denoising process. Can be generated in set_timesteps step.r&   rE   rF   rG   noisezhThe noise added to the image latents, for inpainting task only. Can be generated in prepare_latent step.image_latentszThe image latents to use for the denoising process, for inpainting/image-to-image task only. Can be generated in vae_encode or prepare_latent step.r)   r   r   r   r   r,   *  s0   
z0StableDiffusionXLInpaintLoopAfterDenoiser.inputsc                 C   r   r   r   r   r   r   r   r   F  r   z>StableDiffusionXLInpaintLoopAfterDenoiser.intermediate_outputsc                 K   r   r1   r   r   r   r   r   r   J  r   z>StableDiffusionXLInpaintLoopAfterDenoiser.prepare_extra_kwargsc                 C   sf   |j dkr/|jd u rtd| jj |jd u r!td| jj |jd u r1td| jj d S d S )N   z(image_latents is required for this step zmask is required for this step z noise is required for this step )rJ   r   rK   	__class__r6   rE   r   )r   r-   r.   r   r   r   rR   T  s   



z6StableDiffusionXLInpaintLoopAfterDenoiser.check_inputsr-   r.   r/   r0   c                 C   s   |  || | j|jj|j|jd|_|jj|_	|jj|j
||jfi |jddid |_|jj|j	krCtjj rC|j|j	|_|jdkr||j|_|t|jd k rm|j|d  |_|j|j|jt|jg|_d|j |j |j|j  |_||fS )Nr   r|   Fr   r   r   )rR   r   r   rr   r   r   r   r$   r   r   r   r*   r   r   r   r   rJ   r   init_latents_properlenr   noise_timestep	add_noiser   tensorrE   r4   r   r   r   r5   ]  s@   


z2StableDiffusionXLInpaintLoopAfterDenoiser.__call__N)r6   r7   r8   r9   r:   r;   r   r   r<   r"   r   r   r,   r   r   rU   r   rR   r*   r=   r   r   r>   r5   r   r   r   r   r     s    		 r   c                   @   sl   e Zd ZdZedefddZedee fddZ	edee
 fddZe d	ed
edefddZdS )#StableDiffusionXLDenoiseLoopWrapperr   r   c                 C   r!   )NzPipeline block that iteratively denoise the latents over `timesteps`. The specific steps with each iteration can be customized with `sub_blocks` attributesr   r   r   r   r   r"     r#   z/StableDiffusionXLDenoiseLoopWrapper.descriptionc                 C   r   )NrW   rX   rY   rZ   r[   r   rB   )r   r   r   r   r   r   r   r   r   loop_expected_components  r   z<StableDiffusionXLDenoiseLoopWrapper.loop_expected_componentsc                 C   s"   t ddtjddt ddtddgS )Nr   Tr   r&   r^   r_   )r   r*   r+   r>   r   r   r   r   loop_inputs  s   z/StableDiffusionXLDenoiseLoopWrapper.loop_inputsr-   statec                 C   s  |  |}|jjjd urdnd|_|jr|j  n|j  tt	|j
|j|jj  d|_| j|jd;}t|j
D ]-\}}| j||||d\}}|t	|j
d kse|d |jkri|d |jj dkri|  q<W d    n1 stw   Y  | || ||fS )NTFr   )total)r/   r0   r   )get_block_staterB   rM   time_cond_proj_dimdisable_guidancerW   disableenablemaxr   r   r^   r   ordernum_warmup_stepsprogress_bar	enumerate	loop_stepupdateset_block_state)r   r-   r   r.   r   r/   r0   r   r   r   r5     s&   

"z,StableDiffusionXLDenoiseLoopWrapper.__call__N)r6   r7   r8   r9   r:   r<   r"   r;   r   r   r   r   r*   r=   r   r   r5   r   r   r   r   r     s    r   c                   @   0   e Zd ZeeegZg dZede	fddZ
dS )StableDiffusionXLDenoiseStepbefore_denoiserdenoiserafter_denoiserr   c                 C   r!   )Nax  Denoise step that iteratively denoise the latents. 
Its loop logic is defined in `StableDiffusionXLDenoiseLoopWrapper.__call__` method 
At each iteration, it runs blocks defined in `sub_blocks` sequentially:
 - `StableDiffusionXLLoopBeforeDenoiser`
 - `StableDiffusionXLLoopDenoiser`
 - `StableDiffusionXLLoopAfterDenoiser`
This block supports both text2img and img2img tasks.r   r   r   r   r   r"     r#   z(StableDiffusionXLDenoiseStep.descriptionN)r6   r7   r8   r   rV   r   block_classesblock_namesr:   r<   r"   r   r   r   r   r         r   c                   @   r   )&StableDiffusionXLControlNetDenoiseStepr   r   c                 C   r!   )Na  Denoise step that iteratively denoise the latents with controlnet. 
Its loop logic is defined in  `StableDiffusionXLDenoiseLoopWrapper.__call__` method 
At each iteration, it runs blocks defined in `sub_blocks` sequentially:
 - `StableDiffusionXLLoopBeforeDenoiser`
 - `StableDiffusionXLControlNetLoopDenoiser`
 - `StableDiffusionXLLoopAfterDenoiser`
This block supports using controlnet for both text2img and img2img tasks.r   r   r   r   r   r"     r#   z2StableDiffusionXLControlNetDenoiseStep.descriptionN)r6   r7   r8   r   r   r   r   r   r:   r<   r"   r   r   r   r   r     r   r   c                   @   r   )#StableDiffusionXLInpaintDenoiseStepr   r   c                 C   r!   )Na  Denoise step that iteratively denoise the latents(for inpainting task only). 
Its loop logic is defined in `StableDiffusionXLDenoiseLoopWrapper.__call__` method 
At each iteration, it runs blocks defined in `sub_blocks` sequentially:
 - `StableDiffusionXLInpaintLoopBeforeDenoiser`
 - `StableDiffusionXLLoopDenoiser`
 - `StableDiffusionXLInpaintLoopAfterDenoiser`
This block onlysupports inpainting tasks.r   r   r   r   r   r"     r#   z/StableDiffusionXLInpaintDenoiseStep.descriptionN)r6   r7   r8   r?   rV   r   r   r   r:   r<   r"   r   r   r   r   r     r   r   c                   @   r   )-StableDiffusionXLInpaintControlNetDenoiseStepr   r   c                 C   r!   )Na  Denoise step that iteratively denoise the latents(for inpainting task only) with controlnet. 
Its loop logic is defined in `StableDiffusionXLDenoiseLoopWrapper.__call__` method 
At each iteration, it runs blocks defined in `sub_blocks` sequentially:
 - `StableDiffusionXLInpaintLoopBeforeDenoiser`
 - `StableDiffusionXLControlNetLoopDenoiser`
 - `StableDiffusionXLInpaintLoopAfterDenoiser`
This block only supports using controlnet for inpainting tasks.r   r   r   r   r   r"     r#   z9StableDiffusionXLInpaintControlNetDenoiseStep.descriptionN)r6   r7   r8   r?   r   r   r   r   r:   r<   r"   r   r   r   r   r     r   r   )'r   typingr   r*   configuration_utilsr   guidersr   modelsr   r   
schedulersr   utilsr	   modular_pipeliner   r   r   r   modular_pipeline_utilsr   r   r   r   
get_loggerr6   loggerr   r?   rV   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s0   
$Gr SAnD