o
    pi5                     @   s~  d Z ddlZddlmZ eeZG dd dejZddd	d
ddddddddZdddddddddddddZ	ddddddddddd
Z
i dddd dd!dd"dd#dd$dd%dd&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6Zdd d!d"d#d$d%d&d7d8d9d:d;Zd<d=d>Zeje
eje	iZejeejeiZejeiZd?d@iZdAdB ZdMdCdDZdMdEdFZdGdH ZdIdJ ZdMdKdLZdS )NzI
State dict utilities: utility methods for converting state dicts easily
    N   )
get_loggerc                   @   s    e Zd ZdZdZdZdZdZdS )StateDictTypez6
    The mode to use when converting state dicts.
    diffusers_oldkohya_sspeft	diffusersN)__name__
__module____qualname____doc__DIFFUSERS_OLDKOHYA_SSPEFT	DIFFUSERS r   r   ^/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/utils/state_dict_utils.pyr      s    r   z.to_out.0.lora_Bz.to_out.0.lora_Az.to_q.lora_Az.to_q.lora_Bz.to_k.lora_Az.to_k.lora_Bz.to_v.lora_Az.to_v.lora_Bz.lora_B.lora_Az.to_out.0.lora_magnitude_vector).to_out_lora.up.to_out_lora.down.to_q_lora.down.to_q_lora.up.to_k_lora.down.to_k_lora.up.to_v_lora.down.to_v_lora.upz.lora.upz
.lora.down.to_out.lora_magnitude_vectorz.q_proj.lora_Bz.q_proj.lora_Az.k_proj.lora_Bz.k_proj.lora_Az.v_proj.lora_Bz.v_proj.lora_Az.out_proj.lora_Bz.out_proj.lora_Aztext_projection.lora_A.weightztext_projection.lora_B.weight).q_proj.lora_linear_layer.up.q_proj.lora_linear_layer.down.k_proj.lora_linear_layer.up.k_proj.lora_linear_layer.down.v_proj.lora_linear_layer.up.v_proj.lora_linear_layer.down.out_proj.lora_linear_layer.up .out_proj.lora_linear_layer.down.lora_linear_layer.up.lora_linear_layer.downz text_projection.lora.down.weightztext_projection.lora.up.weight)
r   r   r   r   r   r   r   r   r%   r&   r   r   r   r    r!   r"   r#   r$   zto_k.lora_Azto_k.lora.downzto_k.lora_Bzto_k.lora.upzto_q.lora_Azto_q.lora.downzto_q.lora_Bzto_q.lora.upzto_v.lora_Azto_v.lora.downzto_v.lora_Bzto_v.lora.upzto_out.0.lora_Azto_out.0.lora.downzto_out.0.lora_Bzto_out.0.lora.upz.k_proj.lora_magnitude_vectorz.v_proj.lora_magnitude_vectorz.q_proj.lora_magnitude_vectorz.out_proj.lora_magnitude_vector)r   r   r   r   r   r   r   r   z.to_k.lora_magnitude_vectorz.to_v.lora_magnitude_vectorz.to_q.lora_magnitude_vectorr   	lora_downlora_up)lora_Alora_Bz.processor..c                 C   sz   i }|   D ]4\}}t D ]}||v rt| }|||}q| D ]}||v r5|| }|||} nq#|||< q|S )a&  
    Simply iterates over the state dict and replaces the patterns in `mapping` with the corresponding values.

    Args:
        state_dict (`dict[str, torch.Tensor]`):
            The state dict to convert.
        mapping (`dict[str, str]`):
            The mapping to use for conversion, the mapping should be a dictionary with the following structure:
                - key: the pattern to replace
                - value: the pattern to replace with

    Returns:
        converted_state_dict (`dict`)
            The converted state dict.
    )itemsKEYS_TO_ALWAYS_REPLACEkeysreplace)
state_dictmappingconverted_state_dictkvpatternnew_patternr   r   r   convert_state_dict   s   
r7   c                 K   sz   |du r&t dd |  D rtj}nt dd |  D r"tj}ntd|t vr4td| dt| }t| |S )a  
    Converts a state dict to the PEFT format The state dict can be from previous diffusers format (`OLD_DIFFUSERS`), or
    new diffusers format (`DIFFUSERS`). The method only supports the conversion from diffusers old/new to PEFT for now.

    Args:
        state_dict (`dict[str, torch.Tensor]`):
            The state dict to convert.
        original_type (`StateDictType`, *optional*):
            The original type of the state dict, if not provided, the method will try to infer it automatically.
    Nc                 s       | ]}d |v V  qdS to_out_loraNr   .0r3   r   r   r   	<genexpr>       z-convert_state_dict_to_peft.<locals>.<genexpr>c                 s   r8   lora_linear_layerNr   r;   r   r   r   r=      r>   -Could not automatically infer state dict typeOriginal type  is not supported)anyr.   r   r   r   
ValueErrorPEFT_STATE_DICT_MAPPINGSr7   r0   original_typekwargsr1   r   r   r   convert_state_dict_to_peft   s   
rJ   c                    s   | dd  durd   nd |du rFtdd |  D r$tj}n"t fdd|  D r5tj}ntdd |  D rB| S td	|t vrTtd
| dt| }t| |S )a  
    Converts a state dict to new diffusers format. The state dict can be from previous diffusers format
    (`OLD_DIFFUSERS`), or PEFT format (`PEFT`) or new diffusers format (`DIFFUSERS`). In the last case the method will
    return the state dict as is.

    The method only supports the conversion from diffusers old, PEFT to diffusers new for now.

    Args:
        state_dict (`dict[str, torch.Tensor]`):
            The state dict to convert.
        original_type (`StateDictType`, *optional*):
            The original type of the state dict, if not provided, the method will try to infer it automatically.
        kwargs (`dict`, *args*):
            Additional arguments to pass to the method.

            - **adapter_name**: For example, in case of PEFT, some keys will be pre-pended
                with the adapter name, therefore needs a special handling. By default PEFT also takes care of that in
                `get_peft_model_state_dict` method:
                https://github.com/huggingface/peft/blob/ba0477f2985b1ba311b83459d29895c809404e99/src/peft/utils/save_and_load.py#L92
                but we add it here in case we don't want to rely on that method.
    adapter_nameNr+    c                 s   r8   r9   r   r;   r   r   r   r=      r>   z2convert_state_dict_to_diffusers.<locals>.<genexpr>c                 3        | ]}d   d|v V  qdS r   z.weightNr   r;   peft_adapter_namer   r   r=          c                 s   r8   r?   r   r;   r   r   r   r=      r>   rA   rB   rC   )	poprD   r.   r   r   r   rE   DIFFUSERS_STATE_DICT_MAPPINGSr7   rG   r   rO   r   convert_state_dict_to_diffusers   s    

rT   c                 C   s   t }t| |S )za
    Converts a state dict from UNet format to diffusers format - i.e. by removing some keys
    )UNET_TO_DIFFUSERSr7   )r0   r1   r   r   r   convert_unet_state_dict_to_peft   s   
rV   c              
   C   sl   zt | }W n ty$ } zt|dkrt| }n W Y d}~nd}~ww tdd | D s4td|S )z
    Attempts to first `convert_state_dict_to_peft`, and if it doesn't detect `lora_linear_layer` for a valid
    `DIFFUSERS` LoRA for example, attempts to exclusively convert the Unet `convert_unet_state_dict_to_peft`
    rA   Nc                 s   s     | ]}d |v pd|v V  qdS )r)   r*   Nr   )r<   keyr   r   r   r=     rQ   z1convert_all_state_dict_to_peft.<locals>.<genexpr>z#Your LoRA was not converted to PEFT)rJ   	ExceptionstrrV   rD   r.   rE   )r0   	peft_dicter   r   r   convert_all_state_dict_to_peft   s   
r\   c           	         sh  zddl }W n ty   td  w |dd  dur#d   nd |du r9t fdd|  D r9tj}|t	 vrGt
d	| d
t| t	tj }i }| D ]\\}}d|v rd|dd}n d|v ro|dd}nd|v rz|dd}n
d|v r|dd}|dd|dd }| d}|||< d|v r|dd  d}|t|||< qU|S )a  
    Converts a `PEFT` state dict to `Kohya` format that can be used in AUTOMATIC1111, ComfyUI, SD.Next, InvokeAI, etc.
    The method only supports the conversion from PEFT to Kohya for now.

    Args:
        state_dict (`dict[str, torch.Tensor]`):
            The state dict to convert.
        original_type (`StateDictType`, *optional*):
            The original type of the state dict, if not provided, the method will try to infer it automatically.
        kwargs (`dict`, *args*):
            Additional arguments to pass to the method.

            - **adapter_name**: For example, in case of PEFT, some keys will be pre-pended
                with the adapter name, therefore needs a special handling. By default PEFT also takes care of that in
                `get_peft_model_state_dict` method:
                https://github.com/huggingface/peft/blob/ba0477f2985b1ba311b83459d29895c809404e99/src/peft/utils/save_and_load.py#L92
                but we add it here in case we don't want to rely on that method.
    r   NzDConverting PEFT state dicts to Kohya requires torch to be installed.rK   r+   rL   c                 3   rM   rN   r   r;   rO   r   r   r=   3  rQ   z.convert_state_dict_to_kohya.<locals>.<genexpr>rB   rC   ztext_encoder_2.z	lora_te2.ztext_encoder.z	lora_te1.unet	lora_unetlora_magnitude_vector
dora_scale_   r'   z.alpha)torchImportErrorloggererrorrR   rD   r.   r   r   KOHYA_STATE_DICT_MAPPINGSrE   r7   r,   r/   countsplittensorlen)	r0   rH   rI   rc   kohya_ss_partial_state_dictkohya_ss_state_dict	kohya_keyweight	alpha_keyr   rO   r   convert_state_dict_to_kohya  sD   

rq   )N)r   enumloggingr   r	   re   Enumr   rU   DIFFUSERS_TO_PEFTDIFFUSERS_OLD_TO_PEFTPEFT_TO_DIFFUSERSDIFFUSERS_OLD_TO_DIFFUSERSPEFT_TO_KOHYA_SSr   r   rF   r   rS   rg   r-   r7   rJ   rT   rV   r\   rq   r   r   r   r   <module>   s   	
	

!
/