
    bi(                     ^   d dl Z d dlmZmZmZmZ d dl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Zd	Zd
Z e	       xr	  e
dd      Zerd dlmZ d dlmZ  G d de      Z G d de      Z	 	 	 d!dej8                  j:                  dej<                  dej<                  deeeedf   f   deeeej8                  j:                     df      de ddfdZ!	 	 	 	 d"dej8                  j:                  dej<                  dej<                  deeedf      deeeej8                  j:                     df      de deddfdZ"dej8                  j:                  dej<                  dej<                  de ddf
dZ#dej8                  j:                  de fdZ$dej8                  j:                  ddfd Z%y)#    N)OptionalTupleTypeUnion   )
get_loggeris_peft_availableis_peft_version   )_GO_LC_SUPPORTED_PYTORCH_LAYERS)HookRegistry	ModelHooklayerwise_castingpeft_autocast_disable)	pos_embedpatch_embednormz	^proj_in$z
^proj_out$>z0.14.0)disable_input_dtype_casting)BaseTunerLayerc                   $   e Zd ZdZdZdej                  dej                  deddfdZd	ej                  j                  fd
Zd	ej                  j                  fdZd	ej                  j                  fdZd	ej                  j                  fdZy)LayerwiseCastingHookz
    A hook that casts the weights of a module to a high precision dtype for computation, and to a low precision dtype
    for storage. This process may lead to quality loss in the output, but can significantly reduce the memory
    footprint.
    Fstorage_dtypecompute_dtypenon_blockingreturnNc                 .    || _         || _        || _        y N)r   r   r   )selfr   r   r   s       \/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/hooks/layerwise_casting.py__init__zLayerwiseCastingHook.__init__1   s    **(    modulec                 T    |j                  | j                  | j                         |S N)dtyper   tor   r   r   r#   s     r    initialize_hookz$LayerwiseCastingHook.initialize_hook6   #    		**9J9J	Kr"   c                     t        d      )Nap  LayerwiseCastingHook does not support deinitialization. A model once enabled with layerwise casting will have casted its weights to a lower precision dtype for storage. Casting this back to the original dtype will lead to precision loss, which might have an impact on the model's generation quality. The model should be re-initialized and loaded in the original dtype.)NotImplementedErrorr)   s     r    deinitalize_hookz%LayerwiseCastingHook.deinitalize_hook:   s    !B
 	
r"   c                 X    |j                  | j                  | j                         ||fS r%   )r(   r   r   r   r#   argskwargss       r    pre_forwardz LayerwiseCastingHook.pre_forwardB   s(    		**9J9J	KV|r"   c                 T    |j                  | j                  | j                         |S r%   r'   )r   r#   outputs      r    post_forwardz!LayerwiseCastingHook.post_forwardF   r+   r"   )__name__
__module____qualname____doc___is_statefultorchr&   boolr!   nnModuler*   r.   r3   r6    r"   r    r   r   (   s     L)ekk )%++ )]a )fj )
ehhoo 
uxx 
%((// 588?? r"   r   c                   D    e Zd ZdZdej
                  j                  fdZy)PeftInputAutocastDisableHookas  
    A hook that disables the casting of inputs to the module weight dtype during the forward pass. By default, PEFT
    casts the inputs to the weight dtype of the module, which can lead to precision loss.

    The reasons for needing this are:
        - If we don't add PEFT layers' weight names to `skip_modules_pattern` when applying layerwise casting, the
          inputs will be casted to the, possibly lower precision, storage dtype. Reference:
          https://github.com/huggingface/peft/blob/0facdebf6208139cbd8f3586875acb378813dd97/src/peft/tuners/lora/layer.py#L706
        - We can, on our end, use something like accelerate's `send_to_device` but for dtypes. This way, we can ensure
          that the inputs are casted to the computation dtype correctly always. However, there are two goals we are
          hoping to achieve:
            1. Making forward implementations independent of device/dtype casting operations as much as possible.
            2. Performing inference without losing information from casting to different precisions. With the current
               PEFT implementation (as linked in the reference above), and assuming running layerwise casting inference
               with storage_dtype=torch.float8_e4m3fn and compute_dtype=torch.bfloat16, inputs are cast to
               torch.float8_e4m3fn in the lora layer. We will then upcast back to torch.bfloat16 when we continue the
               forward pass in PEFT linear forward or Diffusers layer forward, with a `send_to_dtype` operation from
               LayerwiseCastingHook. This will be a lossy operation and result in poorer generation quality.
    r#   c                 |    t        |      5   | j                  j                  |i |cd d d        S # 1 sw Y   y xY wr   )r   fn_reforiginal_forwardr0   s       r    new_forwardz(PeftInputAutocastDisableHook.new_forward`   s<    (0 	A/4;;//@@	A 	A 	As   2;N)r7   r8   r9   r:   r<   r>   r?   rF   r@   r"   r    rB   rB   K   s    (A%((// Ar"   rB   r#   r   r   skip_modules_pattern.skip_modules_classesr   r   c                 v    |dk(  rt         }||t        | |||       yt        | |||||       t        |        y)a  
    Applies layerwise casting to a given module. The module expected here is a Diffusers ModelMixin but it can be any
    nn.Module using diffusers layers or pytorch primitives.

    Example:

    ```python
    >>> import torch
    >>> from diffusers import CogVideoXTransformer3DModel

    >>> transformer = CogVideoXTransformer3DModel.from_pretrained(
    ...     model_id, subfolder="transformer", torch_dtype=torch.bfloat16
    ... )

    >>> apply_layerwise_casting(
    ...     transformer,
    ...     storage_dtype=torch.float8_e4m3fn,
    ...     compute_dtype=torch.bfloat16,
    ...     skip_modules_pattern=["patch_embed", "norm", "proj_out"],
    ...     non_blocking=True,
    ... )
    ```

    Args:
        module (`torch.nn.Module`):
            The module whose leaf modules will be cast to a high precision dtype for computation, and to a low
            precision dtype for storage.
        storage_dtype (`torch.dtype`):
            The dtype to cast the module to before/after the forward pass for storage.
        compute_dtype (`torch.dtype`):
            The dtype to cast the module to during the forward pass for computation.
        skip_modules_pattern (`Tuple[str, ...]`, defaults to `"auto"`):
            A list of patterns to match the names of the modules to skip during the layerwise casting process. If set
            to `"auto"`, the default patterns are used. If set to `None`, no modules are skipped. If set to `None`
            alongside `skip_modules_classes` being `None`, the layerwise casting is applied directly to the module
            instead of its internal submodules.
        skip_modules_classes (`Tuple[Type[torch.nn.Module], ...]`, defaults to `None`):
            A list of module classes to skip during the layerwise casting process.
        non_blocking (`bool`, defaults to `False`):
            If `True`, the weight casting operations are non-blocking.
    autoN)DEFAULT_SKIP_MODULES_PATTERNapply_layerwise_casting_hook_apply_layerwise_casting_disable_peft_input_autocast)r#   r   r   rG   rH   r   s         r    apply_layerwise_castingrO   e   sT    b v%;#(<(D$V]M<X !(r"   _prefixc           
      t   |d uxr t        | |      xs |d uxr t        fd|D              }|rt        j                  d d       y t        | t              r(t        j                  d d       t        | |||       y | j                         D ]"  \  }}	r d| n|}
t        |	||||||
       $ y )Nc              3   J   K   | ]  }t        j                  |        y wr   )research).0patternrP   s     r    	<genexpr>z+_apply_layerwise_casting.<locals>.<genexpr>   s     0qQX7G1L0qs    #z&Skipping layerwise casting for layer ""z%Applying layerwise casting to layer ".)rP   )
isinstanceanyloggerdebugr   rL   named_childrenrM   )r#   r   r   rG   rH   r   rP   should_skipname	submodule
layer_names         `    r    rM   rM      s     (t3`
6K_8` D(qS0q\p0q-q  =gYaHI&9:<WIQGH$V]M<X!002 

i,3y$(
   	


r"   c                 t    t        j                  |       }t        |||      }|j                  |t               y)a  
    Applies a `LayerwiseCastingHook` to a given module.

    Args:
        module (`torch.nn.Module`):
            The module to attach the hook to.
        storage_dtype (`torch.dtype`):
            The dtype to cast the module to before the forward pass.
        compute_dtype (`torch.dtype`):
            The dtype to cast the module to during the forward pass.
        non_blocking (`bool`):
            If `True`, the weight casting operations are non-blocking.
    N)r   check_if_exists_or_initializer   register_hook_LAYERWISE_CASTING_HOOK)r#   r   r   r   registryhooks         r    rL   rL      s3      99&AH}lKD4!89r"   c                     | j                         D ]0  }t        |d      s|j                  j                  t              0 y y)N_diffusers_hookTF)moduleshasattrrj   get_hookrf   )r#   ra   s     r    _is_layerwise_casting_activern      sC    ^^% 	I01))223JKW r"   c                     t         sy | j                         D ]T  }t        |t              st	        |      s t        j                  |      }t               }|j                  |t               V y r   )
#_SHOULD_DISABLE_PEFT_INPUT_AUTOCASTrk   rZ   r   rn   r   rd   rB   re   _PEFT_AUTOCAST_DISABLE_HOOK)r#   ra   rg   rh   s       r    rN   rN      s\    .^^% F	i05QR[5\#AA)LH/1D""4)DE	Fr"   )rJ   NF)NNF )&rS   typingr   r   r   r   r<   utilsr   r	   r
   _commonr   hooksr   r   r7   r\   rf   rq   rK   rp   peft.helpersr   peft.tuners.tuners_utilsr   r   rB   r>   r?   r&   strr=   rO   rM   rL   rn   rN   r@   r"   r    <module>rz      s#   
 / /  B B 4 * 
H	 . 5 ^  '8&9&\ocS[>\ #&87 9  FA9 A< 9?HL@)HHOO@);;@) ;;@)  U38_ 45	@)
 #5ehhoo)>)C#DE@) @) 
@)N 7;HL
HHOO
;;
 ;;
 #5c?3	

 #5ehhoo)>)C#DE
 
 
 

D:HHOO:,1KK:HM:cg:	:* T F FT Fr"   