
    gg                        d Z ddlZddlZddlZddlZddlm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mZ ddlmZmZ d	d
lmZmZmZ  ej        e          ZerddlZddeddddddeee
f         dee         de dee!ef         deeeef                  de fdZ"ddeddddeedf         deee
f         dee         de dee!ef         deeeef                  de ddfdZ#ej$        eddeedf         dedee!ef         defdZ%dddee!eedf         f         fdZ&dddeedee!eedf         f         e!f                  fd Z'ddde!fd!Z( e            d1d"            Z)dddee!eedf         f         fd#Z*	 d1deedf         deeef         de fd$Z+ddde!fd%Z,d&eee                  deedf         deee                  fd'Z-deedf         deee                  fd(Z.ddde fd)Z/ddd*deedf         d+eee                  d,eee                  deeee         f         fd-Z0 e            d.d/de!fd0            Z1dS )2z"Contains pytorch-specific helpers.    N)defaultdict)	lru_cache)Path)TYPE_CHECKINGAnyDictListOptionalSetTupleUnion   )	constantslogging   )MAX_SHARD_SIZEStateDictSplit$split_state_dict_into_shards_factoryT)filename_patternforce_contiguousmax_shard_sizemetadatasafe_serializationmodelztorch.nn.Modulesave_directoryr   r   r   r   r   c          	      V    t          |                                 ||||||           dS )a  
    Saves a given torch model to disk, handling sharding and shared tensors issues.

    See also [`save_torch_state_dict`] to save a state dict with more flexibility.

    For more information about tensor sharing, check out [this guide](https://huggingface.co/docs/safetensors/torch_shared_tensors).

    The model state dictionary is split into shards so that each shard is smaller than a given size. The shards are
    saved in the `save_directory` with the given `filename_pattern`. If the model is too big to fit in a single shard,
    an index file is saved in the `save_directory` to indicate where each tensor is saved. This helper uses
    [`split_torch_state_dict_into_shards`] under the hood. If `safe_serialization` is `True`, the shards are saved as
    safetensors (the default). Otherwise, the shards are saved as pickle.

    Before saving the model, the `save_directory` is cleaned from any previous shard files.

    <Tip warning={true}>

    If one of the model's tensor is bigger than `max_shard_size`, it will end up in its own shard which will have a
    size greater than `max_shard_size`.

    </Tip>

    Args:
        model (`torch.nn.Module`):
            The model to save on disk.
        save_directory (`str` or `Path`):
            The directory in which the model will be saved.
        filename_pattern (`str`, *optional*):
            The pattern to generate the files names in which the model will be saved. Pattern must be a string that
            can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix`
            Defaults to `"model{suffix}.safetensors"` or `pytorch_model{suffix}.bin` depending on `safe_serialization`
            parameter.
        force_contiguous (`boolean`, *optional*):
            Forcing the state_dict to be saved as contiguous tensors. This has no effect on the correctness of the
            model, but it could potentially change performance if the layout of the tensor was chosen specifically for
            that reason. Defaults to `True`.
        max_shard_size (`int` or `str`, *optional*):
            The maximum size of each shard, in bytes. Defaults to 5GB.
        metadata (`Dict[str, str]`, *optional*):
            Extra information to save along with the model. Some metadata will be added for each dropped tensors.
            This information will not be enough to recover the entire shared structure but might help understanding
            things.
        safe_serialization (`bool`, *optional*):
            Whether to save as safetensors, which is the default behavior. If `False`, the shards are saved as pickle.
            Safe serialization is recommended for security reasons. Saving as pickle is deprecated and will be removed
            in a future version.

    Example:

    ```py
    >>> from huggingface_hub import save_torch_model
    >>> model = ... # A PyTorch model

    # Save state dict to "path/to/folder". The model will be split into shards of 5GB each and saved as safetensors.
    >>> save_torch_model(model, "path/to/folder")

    # Load model back
    >>> from huggingface_hub import load_torch_model  # TODO
    >>> load_torch_model(model, "path/to/folder")
    >>>
    ```
    )
state_dictr   r   r   r   r   r   N)save_torch_state_dictr   )r   r   r   r   r   r   r   s          `/var/www/html/ai-engine/env/lib/python3.11/site-packages/huggingface_hub/serialization/_torch.pysave_torch_modelr    #   sG    P ##%%))%-%         r   ztorch.Tensorreturnc          	          t          |          }||rt          j        nt          j        }|r*	 ddlm} nB# t          $ r}t          d          |d}~ww xY wddlm} t          
                    d           |i }|rt           ||           t           ||          }	t          j        |                    d	
          dz             }
t!          j        |          D ]}|
                    |          r	 t                              d| d           t!          j        t           j                            ||                     i# t.          $ r+}t          
                    d| d| d           Y d}~d}~ww xY wddi}|	j        s|                    |           |rd|ini }|	j                                        D ]X\  }} fd|D             } ||t           j                            ||          fi | t                              d|            Y|	j        r|                    d
          dz   }i |	j        ||	j        d}t=          t           j                            ||          d          5 }t?          j         ||d           ddd           n# 1 swxY w Y   t          !                    d| dtE          |	j                   d| d           t          !                    d | d!           dS )"a`  
    Save a model state dictionary to the disk, handling sharding and shared tensors issues.

    See also [`save_torch_model`] to directly save a PyTorch model.

    For more information about tensor sharing, check out [this guide](https://huggingface.co/docs/safetensors/torch_shared_tensors).

    The model state dictionary is split into shards so that each shard is smaller than a given size. The shards are
    saved in the `save_directory` with the given `filename_pattern`. If the model is too big to fit in a single shard,
    an index file is saved in the `save_directory` to indicate where each tensor is saved. This helper uses
    [`split_torch_state_dict_into_shards`] under the hood. If `safe_serialization` is `True`, the shards are saved as
    safetensors (the default). Otherwise, the shards are saved as pickle.

    Before saving the model, the `save_directory` is cleaned from any previous shard files.

    <Tip warning={true}>

    If one of the model's tensor is bigger than `max_shard_size`, it will end up in its own shard which will have a
    size greater than `max_shard_size`.

    </Tip>

    Args:
        state_dict (`Dict[str, torch.Tensor]`):
            The state dictionary to save.
        save_directory (`str` or `Path`):
            The directory in which the model will be saved.
        filename_pattern (`str`, *optional*):
            The pattern to generate the files names in which the model will be saved. Pattern must be a string that
            can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix`
            Defaults to `"model{suffix}.safetensors"` or `pytorch_model{suffix}.bin` depending on `safe_serialization`
            parameter.
        force_contiguous (`boolean`, *optional*):
            Forcing the state_dict to be saved as contiguous tensors. This has no effect on the correctness of the
            model, but it could potentially change performance if the layout of the tensor was chosen specifically for
            that reason. Defaults to `True`.
        max_shard_size (`int` or `str`, *optional*):
            The maximum size of each shard, in bytes. Defaults to 5GB.
        metadata (`Dict[str, str]`, *optional*):
            Extra information to save along with the model. Some metadata will be added for each dropped tensors.
            This information will not be enough to recover the entire shared structure but might help understanding
            things.
        safe_serialization (`bool`, *optional*):
            Whether to save as safetensors, which is the default behavior. If `False`, the shards are saved as pickle.
            Safe serialization is recommended for security reasons. Saving as pickle is deprecated and will be removed
            in a future version.

    Example:

    ```py
    >>> from huggingface_hub import save_torch_state_dict
    >>> model = ... # A PyTorch model

    # Save state dict to "path/to/folder". The model will be split into shards of 5GB each and saved as safetensors.
    >>> state_dict = model_to_save.state_dict()
    >>> save_torch_state_dict(state_dict, "path/to/folder")
    ```
    Nr   )	save_filezjPlease install `safetensors` to use safe serialization. You can install it with `pip install safetensors`.)savea  You are using unsafe serialization. Due to security reasons, it is recommended not to load pickled models from untrusted sources. If you intend to share your model, we strongly recommend using safe serialization by installing `safetensors` with `pip install safetensors`.)r   r   r   z(-\d{5}-of-\d{5})?)suffixz(\.index\.json)?zRemoving existing file 'z' from folder.z&Error when trying to remove existing 'z' from folder: z. Continuing...formatptr   c                 "    i | ]}||         S  r+   ).0tensorr   s     r   
<dictcomp>z)save_torch_state_dict.<locals>.<dictcomp>   s     BBBF+BBBr!   zShard saved to  z.index.json)r   
weight_mapwr   )indentz:The model is bigger than the maximum size per checkpoint (z#). Model weighs have been saved in z^ checkpoint shards. You can find where each parameters has been saved in the index located at .z$Model weights successfully saved to !)#strr    SAFETENSORS_WEIGHTS_FILE_PATTERNPYTORCH_WEIGHTS_FILE_PATTERNsafetensors.torchr$   ImportErrortorchr%   loggerwarning!_clean_state_dict_for_safetensors"split_torch_state_dict_into_shardsrecompiler(   oslistdirmatchdebugremovepathjoin	Exception
is_shardedupdatefilename_to_tensorsitemsr   tensor_to_filenameopenjsondumpinfolen)r   r   r   r   r   r   r   save_file_fnestate_dict_splitexisting_files_regexfilenameper_file_metadatasafe_file_kwargstensorsshard
index_pathindexfs   `                  r   r   r   v   s1   H ((N "8I667 	  
	CCCCCCC 	 	 	E  	 	/.....c	
 	
 	
  p6z8^nooo
 :%5n  
 :&6&=&=EZ&=&[&[^q&qrrJ~.. u u%%h// 	uuPPPPQQQ	"',,~x@@AAAA u u usssabsssttttttttu		u "4(& +  ***:LT
$566RT-AGGII 3 3'BBBB'BBBUBGLLBBWWFVWWW1x112222 " 
%,,B,77-G
A+4AA*=
 
 "',,~z::C@@ 	*AIeQq))))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*g g g/23C3W/X/Xg gYcg g g	
 	
 	
 KKH~HHHIIIIIs@   7 
AAA:AE
F !E;;F ?J##J'*J'r&   c                >    t          | ||t          t                    S )a>
  
    Split a model state dictionary in shards so that each shard is smaller than a given size.

    The shards are determined by iterating through the `state_dict` in the order of its keys. There is no optimization
    made to make each shard as close as possible to the maximum size passed. For example, if the limit is 10GB and we
    have tensors of sizes [6GB, 6GB, 2GB, 6GB, 2GB, 2GB] they will get sharded as [6GB], [6+2GB], [6+2+2GB] and not
    [6+2+2GB], [6+2GB], [6GB].


    <Tip>

    To save a model state dictionary to the disk, see [`save_torch_state_dict`]. This helper uses
    `split_torch_state_dict_into_shards` under the hood.

    </Tip>

    <Tip warning={true}>

    If one of the model's tensor is bigger than `max_shard_size`, it will end up in its own shard which will have a
    size greater than `max_shard_size`.

    </Tip>

    Args:
        state_dict (`Dict[str, torch.Tensor]`):
            The state dictionary to save.
        filename_pattern (`str`, *optional*):
            The pattern to generate the files names in which the model will be saved. Pattern must be a string that
            can be formatted with `filename_pattern.format(suffix=...)` and must contain the keyword `suffix`
            Defaults to `"model{suffix}.safetensors"`.
        max_shard_size (`int` or `str`, *optional*):
            The maximum size of each shard, in bytes. Defaults to 5GB.

    Returns:
        [`StateDictSplit`]: A `StateDictSplit` object containing the shards and the index to retrieve them.

    Example:
    ```py
    >>> import json
    >>> import os
    >>> from safetensors.torch import save_file as safe_save_file
    >>> from huggingface_hub import split_torch_state_dict_into_shards

    >>> def save_state_dict(state_dict: Dict[str, torch.Tensor], save_directory: str):
    ...     state_dict_split = split_torch_state_dict_into_shards(state_dict)
    ...     for filename, tensors in state_dict_split.filename_to_tensors.items():
    ...         shard = {tensor: state_dict[tensor] for tensor in tensors}
    ...         safe_save_file(
    ...             shard,
    ...             os.path.join(save_directory, filename),
    ...             metadata={"format": "pt"},
    ...         )
    ...     if state_dict_split.is_sharded:
    ...         index = {
    ...             "metadata": state_dict_split.metadata,
    ...             "weight_map": state_dict_split.tensor_to_filename,
    ...         }
    ...         with open(os.path.join(save_directory, "model.safetensors.index.json"), "w") as f:
    ...             f.write(json.dumps(index, indent=2))
    ```
    )r   r   get_storage_sizeget_storage_id)r   get_torch_storage_sizeget_torch_storage_id)r   r   r   s      r   r>   r>     s+    F 0%)/+   r!   r-   .c                 J    	 ddl m}  |           r2                                 \  }}t           fd|D                       S n# t          $ r Y nw xY w j        j        dk    r-t                      rddl}|j	        
                               }nt                     }|S )zReturns a unique id for plain tensor
    or a (potentially nested) Tuple of unique id for the flattened Tensor
    if the input is a wrapper tensor subclass Tensor
    r   is_traceable_wrapper_subclassc              3   R   K   | ]!}t          t          |                    V  "d S N)_get_unique_idgetattrr,   attrr-   s     r   	<genexpr>z!_get_unique_id.<locals>.<genexpr>_  s5      QQ4(=(=>>QQQQQQr!   xlaN)torch.utils._python_dispatchrf   __tensor_flatten__tupler9   devicetypeis_torch_tpu_available	torch_xla_XLAC_xla_get_tensor_idstorage_ptr)r-   rf   attrs_ru   	unique_ids   `     r   ri   ri   S  s    
NNNNNN((00 	R0022HE1QQQQ5QQQQQQ	R     }U""'='?'?"
 	O66v>>		''	   AA 
AAztorch.devicec                 n    | j         j        dk    rdS | j         t          |           t          |           fS )a,  
    Return unique identifier to a tensor storage.

    Multiple different tensors can share the same underlying storage. This identifier is
    guaranteed to be unique and constant for this tensor's storage during its lifetime. Two tensor storages with
    non-overlapping lifetimes may have the same id.
    In the case of meta tensors, we return None since we can't tell if they share the same storage.

    Taken from https://github.com/huggingface/transformers/blob/1ecf5f7c982d761b4daaa96719d162c324187c64/src/transformers/pytorch_utils.py#L278.
    metaN)rr   rs   ri   rb   )r-   s    r   rc   rc   s  s9     }V##t}nV446LV6T6TTTr!   c                 
    	 ddl m}  |           r2                                 \  }}t           fd|D                       S n# t          $ r Y nw xY w	                                                                  S # t          $ rz 	                                  	                                t           j                  z  cY S # t          $ r.                                  t           j                  z  cY cY S w xY ww xY w)z
    Taken from https://github.com/huggingface/safetensors/blob/08db34094e9e59e2f9218f2df133b7b4aaff5a99/bindings/python/py_src/safetensors/torch.py#L31C1-L41C59
    r   re   c              3   R   K   | ]!}t          t          |                    V  "d S rh   )rb   rj   rk   s     r   rm   z)get_torch_storage_size.<locals>.<genexpr>  s6      WW-gfd.C.CDDWWWWWWr!   )ro   rf   rp   sumr9   untyped_storagenbytesAttributeErrorstoragesize_get_dtype_sizedtypeNotImplementedErrornelementr-   rf   ry   rz   s   `   r   rb   rb     sU   	NNNNNN((00 	X0022HE1WWWWQVWWWWWW	X    	E%%''..000 E E E	E>>##((**_V\-J-JJJJJ" 	E 	E 	E ??$$v|'D'DDDDDDD	E	EsB   AA 
AA%A> >
D	:CD3C>9D=C>>Dc                     t           j                            d          5| r1	 ddlmc m} |                                }dS # t          $ r Y dS w xY wdS dS )z
    Checks if `torch_xla` is installed and potentially if a TPU is in the environment

    Taken from https://github.com/huggingface/transformers/blob/1ecf5f7c982d761b4daaa96719d162c324187c64/src/transformers/utils/import_utils.py#L463.
    ru   Nr   TF)	importlibutil	find_spectorch_xla.core.xla_modelcore	xla_model
xla_deviceRuntimeError)check_devicexmrz   s      r   rt   rt     s     ~,,8 	555555555MMOOt   uut5s   A 
AAc                 F   	 ddl m}  ||           rt          |           S n# t          $ r Y nw xY w	 |                                                                 S # t          $ r< 	 |                                                                 cY S # t          $ r Y Y dS w xY ww xY w)z
    Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L11.
    r   re   )	ro   rf   ri   r9   r   data_ptrrH   r   r   )r-   rf   s     r   rx   rx     s    NNNNNN((00 	*!&)))	*   %%''00222   	>>##,,....." 	 	 	111		s;   # 
00%A 
B %%B
B 
BB BB c                     t          |           }|                                D ]\  }}|D ]}|i }||vr|||<   | |= |rd |                                 D             } | S )a6  Remove shared tensors from state_dict and update metadata accordingly (for reloading).

    Warning: `state_dict` and `metadata` are mutated in-place!

    Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L155.
    Nc                 >    i | ]\  }}||                                 S r+   )
contiguous)r,   kvs      r   r.   z5_clean_state_dict_for_safetensors.<locals>.<dictcomp>  s&    GGGDAqaGGGr!   )_remove_duplicate_namesrL   )r   r   r   
to_removes	kept_nameto_remove_group	to_removes          r   r=   r=     s     )44J&0&6&6&8&8 & &"	?( 	& 	&I((&/#9%%	&  HGGJ4D4D4F4FGGG
r!   c                     |                                  rC|                     d          d                                         t          | j                  z   }n|                                 }|S )z
    Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L23.
    )r   viewr   r   r   )r-   stops     r   _end_ptrr     s[      !{{2r"++--0M0MM  Kr!   rZ   c                    g }| D ]}t          |          dk     r|                    |           +g }|D ]A}||         }|                    |                                t          |          |f           B|                                 |d         \  }}}	|                    |	h           |dd         D ]@\  }
}}|
|k    r|                    |h           n|d                             |           |}A|S )z
    Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L44
    r   r   r   Nr   )rR   appendr   r   sortadd)rZ   r   filtered_tensorssharedareasnamer-   rz   	last_stop	last_namestartr   s               r   _filter_shared_not_sharedr     s/      v;;??##F+++ 	F 	FD%FLL&//++Xf-=-=tDEEEE

"'(9i,,,!&qrr 	 	E4	!! ''//// $((...II	 r!   c                    ddl }t          t                    }|                                 D ]\  }}|j         |j        d          k    rct          |          dk    rPt          |          dk    r=||j        t          |          t          |          f                             |           t          t          |
                                                    }t          ||           }|S )z
    Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L69.
    r   Nr~   )r:   r   setrL   rr   rx   rb   r   listsortedvaluesr   )r   r:   tensors_dictr   r   rZ   s         r   _find_shared_tensorsr     s     LLLs##L  "" W W18|u|F++++A!0C0CH^_`HaHaefHfHf!(KNN4J14M4MNOSSTUVVV6,--//0011G'<<GNr!   c                 l    	 ddl m}  |           r2                                 \  }}t           fd|D                       S n# t          $ r Y nw xY w                                 t                     k    o9                                 t           j	                  z  t                     k    S )
    Taken from https://github.com/huggingface/safetensors/blob/079781fd0dc455ba0fe851e2b4507c33d0c0d407/bindings/python/py_src/safetensors/torch.py#L80
    r   re   c              3   R   K   | ]!}t          t          |                    V  "d S rh   )_is_completerj   rk   s     r   rm   z_is_complete.<locals>.<genexpr>&  s5      MMt|GFD$9$9::MMMMMMr!   )ro   rf   rp   allr9   r   rx   r   r   r   rb   r   s   `   r   r   r     s    	NNNNNN((00 	N0022HE1MMMMuMMMMMM	N     ??F 3 33 (8I8IOM M 9		'	'9( (r|   )preferred_namesdiscard_namesr   r   c                    |g }t          |          }|g }t          |          }t                     }t          t                    }|D ]}t           fd|D                       }|st	          d| d          t          t          |                    d         }	|                    |          }
|
r"t          t          |
                    d         }	|r9|                    |          }
|
r"t          t          |
                    d         }	t          |          D ]#}||	k    r||	                             |           $|S )r   Nc                 >    g | ]}t          |                   |S r+   )r   )r,   r   r   s     r   
<listcomp>z+_remove_duplicate_names.<locals>.<listcomp>C  s,    XXXtjQUFV9W9WXdXXXr!   zvError while trying to find names to remove to save state dict, but found no suitable name to keep for saving amongst: z. None is covering the entire storage. Refusing to save/load the model since you could be storing much more memory than needed. Please refer to https://huggingface.co/docs/safetensors/torch_shared_tensors for more information. Or open an issue.r   )	r   r   r   r   r   r   
differenceintersectionr   )r   r   r   unique_preferred_namesunique_discard_namessharedsr   r   complete_names	keep_name	preferredr   s   `           r   r   r   0  s     11}--":..GD!!I 2 2XXXXvXXXYY 	(.     4//003	 #--.BCC	 	3tI//2I! 	7.;;NKKI 7"4	??33A6	6NN 	2 	2Dy  )$++D111	2 r!   r   ztorch.dtypec                     ddl }t          |dd          }t          |dd          }|j        d|j        d|j        d|j        d|j        d|j        d|j        d|j	        d|j
        d|j        d|d|di}||          S )	z
    Taken from https://github.com/huggingface/safetensors/blob/08db34094e9e59e2f9218f2df133b7b4aaff5a99/bindings/python/py_src/safetensors/torch.py#L344
    r   Nfloat8_e4m3fnfloat8_e5m2      r   r   )r:   rj   int64float32int32bfloat16float16int16uint8int8boolfloat64)r   r:   _float8_e4m3fn_float8_e5m2_SIZEs        r   r   r   a  s    
 LLL UOT::N5-66LQqQqQQ
A
AqaE <r!   )T)2__doc__r   rO   rA   r?   collectionsr   	functoolsr   pathlibr   typingr   r   r   r	   r
   r   r   r   r/   r   r   _baser   r   r   
get_logger__file__r;   r:   r5   r   intr    r   r6   r>   ri   rc   rb   rt   rx   r=   r   r   r   r   r   r   r+   r!   r   <module>r      s   ) (      				 				 # # # # # #             N N N N N N N N N N N N N N N N N N N N ! ! ! ! ! ! ! ! W W W W W W W W W W 
	H	%	% LLL '+!&4)-#P P PP#t)$P sm	P
 P #s(OP tCH~&P P P P Pn '+!&4)-#NJ NJ NJS.()NJ#t)$NJ sm	NJ
 NJ #s(ONJ tCH~&NJ NJ 
NJ NJ NJ NJh &F&4	I I IS.()I I #s(O	I
 I I I IX> eCsCx4H.I    @U UHU>SXY\^cdgildl^mYmSnpsCs=t4u U U U U"E> Ec E E E E6    ( 5eCHo1E+F    4 _c S.()59#s(^W[   0^     tCH~ 4^H[C\ aefijmfnao    8T#~*=%> 4C>     ( (D ( ( ( (. ,0)-	. . .S.(). d3i(. DI&	.
 
#tCy.. . . .b = S      r!   