o
    pib                     @   s  d dl Z d dlZd dlZd dlZd dlmZmZmZmZm	Z	m
Z
m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mZmZmZmZ e rOd dlZe rXd dlmZ e rad dlmZ e rhd dl Z d	e!fd
dZ"dd Z#de$fddZ%	d2dededej&dej&dej&dej&dej&de'de
e	ej& e	ej& f fddZ(dedee$ej&f fddZ)ej*fdeej+j,eej+j, f fd d!Z-d"ee$ej&f d#e$d$ej+j,fd%d&Z.	d3d'e$d(e!d)e'd*e'd+e'f
d,d-Z/d4d'e$fd.d/Z0G d0d1 d1Z1dS )5    N)AnyDictIterableListOptionalTupleUnion   )UNet2DConditionModel)SchedulerMixin)convert_state_dict_to_diffusersconvert_state_dict_to_peft	deprecateis_peft_availableis_torch_npu_availableis_torchvision_availableis_transformers_available)set_peft_model_state_dict)
transformsseedc                 C   sF   t |  tj |  t|  t rtj|  dS tj|  dS )z
    Args:
    Helper function for reproducible behavior to set the seed in `random`, `numpy`, `torch`.
        seed (`int`): The seed to set.
    N)	randomr   nptorchmanual_seedr   npumanual_seed_allcuda)r    r   V/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/training_utils.pyset_seed$   s   

r   c                 C   s   | j }|d }d| d }|j|jd|  }t|jt|jk r0|d }t|jt|jk s"||j}|j|jd|  }t|jt|jk rY|d }t|jt|jk sK||j}|| d }|S )z
    Computes SNR as per
    https://github.com/TiankaiHang/Min-SNR-Diffusion-Training/blob/521b624bd70c67cee4bdf49225915f5945a872e3/guided_diffusion/gaussian_diffusion.py#L847-L849
          ?      ?device).N   )alphas_cumprodtor#   floatlenshapeexpand)noise_scheduler	timestepsr%   sqrt_alphas_cumprodsqrt_one_minus_alphas_cumprodalphasigmasnrr   r   r   compute_snr4   s   r2   interpolation_typec                 C   s   t  std| dkrtjj}|S | dkrtjj}|S | dkr%tjj}|S | dkr/tjj}|S | dkr9tjj}|S | dkrCtjj	}|S | dkrMtjj
}|S td	|  d
)a  
    Maps a string describing an interpolation function to the corresponding torchvision `InterpolationMode` enum. The
    full list of supported enums is documented at
    https://pytorch.org/vision/0.9/transforms.html#torchvision.transforms.functional.InterpolationMode.

    Args:
        interpolation_type (`str`):
            A string describing an interpolation method. Currently, `bilinear`, `bicubic`, `box`, `nearest`,
            `nearest_exact`, `hamming`, and `lanczos` are supported, corresponding to the supported interpolation modes
            in torchvision.

    Returns:
        `torchvision.transforms.InterpolationMode`: an `InterpolationMode` enum used by torchvision's `resize`
        transform.
    zhPlease make sure to install `torchvision` to be able to use the `resolve_interpolation_mode()` function.bilinearbicubicboxnearestnearest_exacthamminglanczoszThe given interpolation mode z is not supported. Currently supported interpolation modes are `bilinear`, `bicubic`, `box`, `nearest`, `nearest_exact`, `hamming`, and `lanczos`.)r   ImportErrorr   InterpolationModeBILINEARBICUBICBOXNEARESTNEAREST_EXACTHAMMINGLANCZOS
ValueError)r3   interpolation_moder   r   r   resolve_interpolation_modeN   s8   	
rF   r!   unetr+   r,   noisenoisy_latentstargetencoder_hidden_statesdream_detail_preservationreturnc                 C   s   |j |j|dddf }d| d }	|	| }
d}t  | |||j}W d   n1 s/w   Y  d\}}|jjdkr[|}||  }|	|
 |
|	| }|
|}||fS |jjdkretdtd|jj )	a  
    Implements "DREAM (Diffusion Rectification and Estimation-Adaptive Models)" from http://arxiv.org/abs/2312.00210.
    DREAM helps align training with sampling to help training be more efficient and accurate at the cost of an extra
    forward step without gradients.

    Args:
        `unet`: The state unet to use to make a prediction.
        `noise_scheduler`: The noise scheduler used to add noise for the given timestep.
        `timesteps`: The timesteps for the noise_scheduler to user.
        `noise`: A tensor of noise in the shape of noisy_latents.
        `noisy_latents`: Previously noise latents from the training loop.
        `target`: The ground-truth tensor to predict after eps is removed.
        `encoder_hidden_states`: Text embeddings from the text model.
        `dream_detail_preservation`: A float value that indicates detail preservation level.
          See reference.

    Returns:
        `tuple[torch.Tensor, torch.Tensor]`: Adjusted noisy_latents and target.
    Nr!   r    )NNepsilonv_predictionz/DREAM has not been implemented for v-predictionzUnknown prediction type )r%   r&   r#   r   no_gradsampleconfigprediction_typedetachmul_addNotImplementedErrorrD   )rG   r+   r,   rH   rI   rJ   rK   rL   r%   r.   dream_lambdapred_noisy_latents_targetpredicted_noisedelta_noiser   r   r    compute_dream_and_update_latentsz   s$   


r^   c                 C   sb   i }|   D ](\}}t|dr.t|d}|dur.| }| D ]\}}||| d| < q q|S )zL
    Returns:
        A state dict containing just the LoRA parameters.
    set_lora_layer
lora_layerNz.lora.)named_moduleshasattrgetattr
state_dictitems)rG   lora_state_dictnamemoduler`   current_lora_layer_sdlora_layer_matrix_name
lora_paramr   r   r   unet_lora_state_dict   s   

rl   modelc                 C   s>   t | ts| g} | D ]}| D ]}|jr|||_qq
d S N)
isinstancelist
parametersrequires_gradr&   data)rm   dtypemparamr   r   r   cast_training_params   s   
rw   rf   prefixtext_encoderc                    s4    fdd|   D }tt|}t||dd dS )aD  
    Sets the `lora_state_dict` into `text_encoder` coming from `transformers`.

    Args:
        lora_state_dict: The state dictionary to be set.
        prefix: String identifier to retrieve the portion of the state dict that belongs to `text_encoder`.
        text_encoder: Where the `lora_state_dict` is to be set.
    c                    s*   i | ]\}}|  r| d  |qS ) )
startswithreplace).0kvrx   r   r   
<dictcomp>   s
    z5_set_state_dict_into_text_encoder.<locals>.<dictcomp>default)adapter_nameN)re   r   r   r   )rf   rx   ry   text_encoder_state_dictr   r   r   !_set_state_dict_into_text_encoder   s
   
r   weighting_scheme
batch_size
logit_mean	logit_std
mode_scalec                 C   s   | dkrt j|||fdd}t jj|}|S | dkr;t j|fdd}d| |t tj| d d d |   }|S t j|fdd}|S )zCompute the density for sampling the timesteps when doing SD3 training.

    Courtesy: This was contributed by Rafie Walker in https://github.com/huggingface/diffusers/pull/8528.

    SD3 paper reference: https://arxiv.org/abs/2403.03206v1.
    logit_normalcpu)meanstdsizer#   mode)r   r#   r	   r$   )	r   normalnn
functionalsigmoidrandcosmathpi)r   r   r   r   r   ur   r   r   %compute_density_for_timestep_sampling   s   	,r   c                 C   sX   | dkr|d   }|S | dkr%dd|  d|d   }dtj|  }|S t|}|S )zComputes loss weighting scheme for SD3 training.

    Courtesy: This was contributed by Rafie Walker in https://github.com/huggingface/diffusers/pull/8528.

    SD3 paper reference: https://arxiv.org/abs/2403.03206v1.
    
sigma_sqrtg       cosmapr	   r$   )r'   r   r   r   	ones_like)r   sigmas	weightingbotr   r   r   compute_loss_weighting_for_sd3   s   
r   c                   @   sF  e Zd ZdZ									d.d	eejj d
edede	de
deee	f deee	f de
dee deeef fddZed/d0ddZdd Zde	defddZe d	eejj fddZd	eejj ddfdd Zd1d!d"Zd2d1d#d$Zdefd%d&Zd	eejj ddfd'd(Zd	eejj ddfd)d*Zd+eddfd,d-ZdS )3EMAModelz6
    Exponential Moving Average of models weights
    H.?        r   Fr!   UUUUUU?Nrq   decay	min_decayupdate_after_stepuse_ema_warmup	inv_gammapowerforeach	model_clsmodel_configc                 K   s  t |tjjrd}tdd|dd | }d}|dddur-d	}tdd|dd |d }|d
ddurCd}td
d|dd |d
 }t|}dd |D | _|dddurid}tdd|dd | j	|d d d| _
|| _|| _|| _|| _|| _|| _d| _d| _|| _|	| _|
| _dS )a{  
        Args:
            parameters (Iterable[torch.nn.Parameter]): The parameters to track.
            decay (float): The decay factor for the exponential moving average.
            min_decay (float): The minimum decay factor for the exponential moving average.
            update_after_step (int): The number of steps to wait before starting to update the EMA weights.
            use_ema_warmup (bool): Whether to use EMA warmup.
            inv_gamma (float):
                Inverse multiplicative factor of EMA warmup. Default: 1. Only used if `use_ema_warmup` is True.
            power (float): Exponential factor of EMA warmup. Default: 2/3. Only used if `use_ema_warmup` is True.
            foreach (bool): Use torch._foreach functions for updating shadow parameters. Should be faster.
            device (Optional[Union[str, torch.device]]): The device to store the EMA weights on. If None, the EMA
                        weights will be stored on CPU.

        @crowsonkb's notes on EMA Warmup:
            If gamma=1 and power=1, implements a simple average. gamma=1, power=2/3 are good values for models you plan
            to train for a million or more steps (reaches decay factor 0.999 at 31.6K steps, 0.9999 at 1M steps),
            gamma=1, power=3/4 for models you plan to train for less (reaches decay factor 0.999 at 10K steps, 0.9999
            at 215.4k steps).
        zzPassing a `torch.nn.Module` to `ExponentialMovingAverage` is deprecated. Please pass the parameters of the module instead.z9passing a `torch.nn.Module` to `ExponentialMovingAverage`1.0.0Fstandard_warnT	max_valueNzCThe `max_value` argument is deprecated. Please use `decay` instead.	min_valuezGThe `min_value` argument is deprecated. Please use `min_decay` instead.c                 S   s   g | ]}|   qS r   )clonerT   r}   pr   r   r   
<listcomp>J  s    z%EMAModel.__init__.<locals>.<listcomp>r#   z=The `device` argument is deprecated. Please use `to` instead.r"   r   )ro   r   r   Moduler   rq   getrp   shadow_paramsr&   temp_stored_paramsr   r   r   r   r   r   optimization_stepcur_decay_valuer   r   r   )selfrq   r   r   r   r   r   r   r   r   r   kwargsdeprecation_messager   r   r   __init__  sJ   #
zEMAModel.__init__rM   c                 C   s@   |j |dd\}}||}| | ||j|d}|| |S )NT)return_unused_kwargs)r   r   r   )load_configfrom_pretrainedrq   rR   load_state_dict)clspathr   r   _
ema_kwargsrm   	ema_modelr   r   r   r   `  s
   

zEMAModel.from_pretrainedc                 C   sr   | j d u r	td| jd u rtd| j | j}|  }|dd  |jdi | | |  |	| d S )NzJ`save_pretrained` can only be used if `model_cls` was defined at __init__.zM`save_pretrained` can only be used if `model_config` was defined at __init__.r   r   )
r   rD   r   from_configrd   popregister_to_configcopy_torq   save_pretrained)r   r   rm   rd   r   r   r   r   j  s   

zEMAModel.save_pretrainedr   c                 C   sn   t d|| j d }|dkrdS | jr!dd|| j  | j   }nd| d|  }t|| j}t || j}|S )zN
        Compute the decay factor for the exponential moving average.
        r   r	   r   
   )maxr   r   r   r   minr   r   )r   r   stepr   r   r   r   	get_decayy  s   zEMAModel.get_decayc              	   C   s  t |tjjrd}tdd|dd | }t|}|  jd7  _| | j}|| _	d| }t
j}t r<tj r<dd l}| jrt rOtj rO|jj|d d}| E d	d
 |D }dd
 t| j|D }t|t|k rtjdd
 t| j|D dd
 |D dd tj|t|||d W d    d S 1 sw   Y  d S t| j|D ]9\}	}
t rtj r|jj|
d d}|  |
jr|	||	|
   n|	|
 W d    n1 sw   Y  qd S )NzPassing a `torch.nn.Module` to `ExponentialMovingAverage.step` is deprecated. Please pass the parameters of the module instead.z>passing a `torch.nn.Module` to `ExponentialMovingAverage.step`r   Fr   r	   r   )modifier_rankc                 S   s   g | ]}|j r|qS r   rr   r}   rv   r   r   r   r         z!EMAModel.step.<locals>.<listcomp>c                 S   s   g | ]	\}}|j r|qS r   r   r}   s_paramrv   r   r   r   r     s
    
c                 S   s   g | ]	\}}|j s|qS r   r   r   r   r   r   r     s    c                 S   s   g | ]}|j s|qS r   r   r   r   r   r   r     r   T)non_blocking)r/   )ro   r   r   r   r   rq   rp   r   r   r   
contextlibnullcontextr   transformers	deepspeedis_deepspeed_zero3_enabledr   zeroGatheredParameterszipr   r(   _foreach_copy__foreach_sub__foreach_subrr   sub_copy_)r   rq   r   r   one_minus_decaycontext_managerr   params_grads_params_gradr   rv   r   r   r   r     s^   
"
zEMAModel.stepc                 C   sj   t |}| jrtdd |D dd t| j|D  dS t| j|D ]\}}|j||j	j q#dS )aa  
        Copy current averaged parameters into given collection of parameters.

        Args:
            parameters: Iterable of `torch.nn.Parameter`; the parameters to be
                updated with the stored moving averages. If `None`, the parameters with which this
                `ExponentialMovingAverage` was initialized will be used.
        c                 S      g | ]}|j qS r   rs   r   r   r   r   r         z$EMAModel.copy_to.<locals>.<listcomp>c                 S   s   g | ]\}}| |jjqS r   )r&   r#   rs   r   r   r   r   r     s    N)
rp   r   r   r   r   r   rs   r   r&   r#   )r   rq   r   rv   r   r   r   r     s   	zEMAModel.copy_toc                 C   s   dd | j D | _ dS )z
        Move internal buffers of the ExponentialMovingAverage to pinned memory. Useful for non-blocking transfers for
        offloading EMA params to the host.
        c                 S   s   g | ]}|  qS r   )
pin_memoryr   r   r   r   r     s    z'EMAModel.pin_memory.<locals>.<listcomp>Nr   r   r   r   r   r     s   zEMAModel.pin_memoryc                    s    fdd| j D | _ dS )zMove internal buffers of the ExponentialMovingAverage to `device`.

        Args:
            device: like `device` argument to `torch.Tensor.to`
        c                    s2   g | ]}|  r|j d n|j dqS )r#   rt   r   )r#   r   )is_floating_pointr&   r   r   r   r   r     s    zEMAModel.to.<locals>.<listcomp>Nr   )r   r#   rt   r   r   r   r   r&     s   zEMAModel.toc              	   C   s&   | j | j| j| j| j| j| j| jdS )z
        Returns the state of the ExponentialMovingAverage as a dict. This method is used by accelerate during
        checkpointing to save the ema state dict.
        r   r   r   r   r   r   r   r   r   r   r   r   r   rd     s   	zEMAModel.state_dictc                 C   s   dd |D | _ dS )z
        Args:
        Save the current parameters for restoring later.
            parameters: Iterable of `torch.nn.Parameter`; the parameters to be
                temporarily stored.
        c                 S   s   g | ]
}|    qS r   )rT   r   r   r   r   r   r   r     s    z"EMAModel.store.<locals>.<listcomp>N)r   )r   rq   r   r   r   store  s   zEMAModel.storec                 C   sj   | j du r	td| jrtdd |D dd | j D  nt| j |D ]\}}|j|j q$d| _ dS )aF  
        Args:
        Restore the parameters stored with the `store` method. Useful to validate the model with EMA parameters without:
        affecting the original optimization process. Store the parameters before the `copy_to()` method. After
        validation (or model saving), use this to restore the former parameters.
            parameters: Iterable of `torch.nn.Parameter`; the parameters to be
                updated with the stored parameters. If `None`, the parameters with which this
                `ExponentialMovingAverage` was initialized will be used.
        NzGThis ExponentialMovingAverage has no `store()`ed weights to `restore()`c                 S   r   r   r   r   r   r   r   r     r   z$EMAModel.restore.<locals>.<listcomp>c                 S   r   r   r   )r}   c_paramr   r   r   r     r   )r   RuntimeErrorr   r   r   r   rs   r   )r   rq   r   rv   r   r   r   restore  s   


zEMAModel.restorerd   c                 C   sh  t |}|d| j| _| jdk s| jdkrtd|d| j| _t| jts-td|d| j| _t| jt	s?td|d	| j
| _
t| j
t	sQtd
|d| j| _t| jtsctd|d| j| _t| jtt	fswtd|d| j| _t| jtt	fstd|dd}|dur|| _t| jtstdtdd | jD stddS dS )a  
        Args:
        Loads the ExponentialMovingAverage state. This method is used by accelerate during checkpointing to save the
        ema state dict.
            state_dict (dict): EMA state. Should be an object returned
                from a call to :meth:`state_dict`.
        r   r   r!   zDecay must be between 0 and 1r   zInvalid min_decayr   zInvalid optimization_stepr   zInvalid update_after_stepr   zInvalid use_ema_warmupr   zInvalid inv_gammar   zInvalid powerr   Nzshadow_params must be a listc                 s   s    | ]	}t |tjV  qd S rn   )ro   r   Tensorr   r   r   r   	<genexpr>P  s    z+EMAModel.load_state_dict.<locals>.<genexpr>z!shadow_params must all be Tensors)copydeepcopyr   r   rD   r   ro   r'   r   intr   r   boolr   r   r   rp   all)r   rd   r   r   r   r   r   $  s>   
	zEMAModel.load_state_dict)	r   r   r   Fr!   r   FNN)F)rM   r   )rM   N)NNF)__name__
__module____qualname____doc__r   r   r   	Parameterr'   r   r   r   r   r   r   strr   classmethodr   r   r   rP   r   r   r   r&   dictrd   r   r   r   r   r   r   r   r     sZ    


	


T	;
	r   )r!   )NNNrn   )2r   r   r   r   typingr   r   r   r   r   r   r   numpyr   r   modelsr
   
schedulersr   utilsr   r   r   r   r   r   r   r   peftr   torchvisionr   	torch_npur   r   r2   r  rF   r   r'   r^   rl   float32r   r   rw   r   r   r   r   r   r   r   r   <module>   s    $$4	
6(


