
    bi8                     *   d Z ddlZddlZddlmZ ddlmZ  e       rddlZ ee      Z	 G 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/d0d1d2d3d4d5d6d7Zd d!d"d#d$d%d&d'd8d9d:d;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@dAiZdB ZdKdCZdKdDZdE ZdF ZdKdGZdKdHZdIe fdJZ!y)LzI
State dict utilities: utility methods for converting state dicts easily
    N   )is_torch_available)
get_loggerc                        e Zd ZdZdZdZdZdZy)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     [/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/utils/state_dict_utils.pyr   r       s     $MHDIr   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                    i }| j                         D ]u  \  }}t        j                         D ]"  }||v st        |   }|j                  ||      }$ |j                         D ]  }||v s||   }|j                  ||      } n |||<   w |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_patterns          r   convert_state_dictr<      s        " $1-224 	4G!|4W=IIg{3	4
 ||~ 	G!|%g.IIg{3		
 #$Q$  r   c                 T   |mt        d | j                         D              rt        j                  }n<t        d | j                         D              rt        j                  }nt        d      |t        j                         vrt        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.
    c              3   $   K   | ]  }d |v  
 ywto_out_loraNr   .0r8   s     r   	<genexpr>z-convert_state_dict_to_peft.<locals>.<genexpr>        =a}!=   c              3   $   K   | ]  }d |v  
 ywlora_linear_layerNr   rA   s     r   rC   z-convert_state_dict_to_peft.<locals>.<genexpr>        Ea$)ErE   -Could not automatically infer state dict typeOriginal type  is not supported)anyr3   r   r   r   
ValueErrorPEFT_STATE_DICT_MAPPINGSr<   )r5   original_typekwargsr6   s       r   convert_state_dict_to_peftrR      s     =:??+<==)77ME:??3DEE)33MLMM499;;>-8IJKK&}5Gj'22r   c                    |j                  dd      dz   nd|t        d | j                         D              rt        j                  }n`t        fd| j                         D              rt        j
                  }n-t        d | j                         D              r| S t        d      |t        j                         vrt        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 prepended
                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              3   $   K   | ]  }d |v  
 ywr?   r   rA   s     r   rC   z2convert_state_dict_to_diffusers.<locals>.<genexpr>   rD   rE   c              3   .   K   | ]  }d  d|v   ywr   z.weightNr   rB   r8   peft_adapter_names     r   rC   z2convert_state_dict_to_diffusers.<locals>.<genexpr>   s!     Vq7,-W5:V   c              3   $   K   | ]  }d |v  
 ywrG   r   rA   s     r   rC   z2convert_state_dict_to_diffusers.<locals>.<genexpr>   rI   rE   rJ   rK   rL   )	poprM   r3   r   r   r   rN   DIFFUSERS_STATE_DICT_MAPPINGSr<   )r5   rP   rQ   r6   rZ   s       @r   convert_state_dict_to_diffusersr_      s    , 

>48$"33=:??+<==)77MVJOODUVV)..ME:??3DEELMM9>>@@>-8IJKK+M:Gj'22r   c                 &    t         }t        | |      S )za
    Converts a state dict from UNet format to diffusers format - i.e. by removing some keys
    )UNET_TO_DIFFUSERSr<   )r5   r6   s     r   convert_unet_state_dict_to_peftrb      s      Gj'22r   c                     	 t        |       }t	        d |j                         D              st        d      |S # t        $ r%}t        |      dk(  rt        |       }n Y d}~Vd}~ww xY w)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`
    rJ   Nc              3   0   K   | ]  }d |v xs d|v   yw)r-   r.   Nr   )rB   keys     r   rC   z1convert_all_state_dict_to_peft.<locals>.<genexpr>  s      Ncx31(c/1Ns   z#Your LoRA was not converted to PEFT)rR   	Exceptionstrrb   rM   r3   rN   )r5   	peft_dictes      r   convert_all_state_dict_to_peftrj     sk    
.z:	 NY^^=MNN>??  q6DD7
CI s   : 	A(A##A(c                 Z  	 	 ddl }|j	                  dd      		d	z   	nd	|2t        	fd| j                         D              rt        j                  }|t        j                         vrt        d| d	      t        | t        t        j                           }i }|j                         D ]  \  }}d
|v r|j                  d
d      }nDd|v r|j                  dd      }n-d|v r|j                  dd      }nd|v r|j                  dd      }|j                  dd|j                  d      dz
        }|j                  	d      }|||<   d|v s|j                  d      d    d} |j                   t#        |            ||<    |S # t        $ r t        j                  d        w xY w)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 prepended
                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.rT   r/   rU   c              3   .   K   | ]  }d  d|v   ywrX   r   rY   s     r   rC   z.convert_state_dict_to_kohya.<locals>.<genexpr>9  s!     TQ*+73q8Tr[   rK   rL   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errorr]   rM   r3   r   r   KOHYA_STATE_DICT_MAPPINGSrN   r<   r1   r4   countsplittensorlen)
r5   rP   rQ   rs   kohya_ss_partial_state_dictkohya_ss_state_dict	kohya_keyweight	alpha_keyrZ   s
            @r   convert_state_dict_to_kohyar     s   &
 

>48$"33T*//BSTT)..M5::<<>-8IJKK #5ZAZ[h[m[mAn"o 9>>@ G	6	)!))*;[II	)!))/;GIy !))&+>I$	1!))*A<PI%%c3	0Dq0HI	%%&7<	)/I&)#$??3/236:I-9U\\#f+-F	*G" O  [\s   F
 
 F*c                     |Lt        |t              r|g}| j                         D ci c]  \  }t        fd|D              s| } }}t	        d | j                         D              S c c}}w )Nc              3   &   K   | ]  }|v  
 y wNr   )rB   fr8   s     r   rC   z&state_dict_all_zero.<locals>.<genexpr>\  s     @\Aa@\s   c              3   h   K   | ]*  }t        j                  |d k(        j                          , yw)r   N)rs   allitem)rB   params     r   rC   z&state_dict_all_zero.<locals>.<genexpr>^  s&     Muyy!$))+Ms   02)
isinstancerg   r1   rM   r   values)r5   
filter_strr8   r9   s     ` r   state_dict_all_zeror   X  so    j#&$J'1'7'7'9]]tq!S@\Q[@\=\ad]
]M9J9J9LMMM ^s   A0A0
model_filec                 "   dd l }ddlm} |j                  j	                  | dd      5 }|j                         xs i }d d d        j                  dd        |r*|j                  |      }|rt        j                  |      S d S y # 1 sw Y   HxY w)Nr   rr   )LORA_ADAPTER_METADATA_KEYptcpu)	frameworkdeviceformat)
safetensors.torchloaders.lora_baser   rs   	safe_openmetadatar]   getjsonloads)r   safetensorsr   r   r   raws         r   _load_sft_state_dict_metadatar   a  s    =				$	$Z4	$	N &RS::<%2& LL4 ll45"%tzz#/4/& &s   BBr   )"r   enumr   import_utilsr   loggingr   rs   r   ru   Enumr   ra   DIFFUSERS_TO_PEFTDIFFUSERS_OLD_TO_PEFTPEFT_TO_DIFFUSERSDIFFUSERS_OLD_TO_DIFFUSERSPEFT_TO_KOHYA_SSr   r   rO   r   r^   rw   r2   r<   rR   r_   rb   rj   r   r   rg   r   r   r   r   <module>r      si     ,   
H	DII  *+%#%#%#%F   %5&6$4&6$4&6&8(:&((G&E   &'%'%')+&( 46 4 6	
 4 6 8 : # > # > # > +  )! ( 4737377;#B#B#B%F     !6.  !;)! 
 +//1AB  3 
 B36,3^3&<~Nc r   