o
    Zh                  	   @   s   d Z ddlZddlmZ ddlmZmZmZ ddlm	Z	m
Z
mZmZ er(ddlZe	e
ddeed	f d
ededefddZdd	dedeef fddZdd	defddZe d ddZdd	defddZdd	defddZe dddefddZdS )!z"Contains pytorch-specific helpers.    N)	lru_cache)TYPE_CHECKINGDictTuple   )FILENAME_PATTERNMAX_SHARD_SIZEStateDictSplit$split_state_dict_into_shards_factory)filename_patternmax_shard_size
state_dictztorch.Tensorr   r   returnc                C   s   t | ||ttd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 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.values():
    ...         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_tensor_sizeget_storage_id)r
   r   r   )r   r   r    r   [/var/www/html/lang_env/lib/python3.10/site-packages/huggingface_hub/serialization/_torch.py"split_torch_state_dict_into_shards   s   ;r   tensorztorch.devicec                 C   s@   | j jdkrt rddl}|j| }nt| }| j |t| fS )a1  
    Return unique identifier to a tensor storage.

    Multiple different tensors can share the same underlying storage. For
    example, "meta" tensors all share the same storage, and thus their identifier will all be equal. 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.

    Taken from https://github.com/huggingface/transformers/blob/1ecf5f7c982d761b4daaa96719d162c324187c64/src/transformers/pytorch_utils.py#L278.
    Zxlar   N)Zdevicetypeis_torch_tpu_available	torch_xlaZ_XLACZ_xla_get_tensor_idstorage_ptrget_storage_size)r   r   	unique_idr   r   r   r   _   s
   r   c                 C   s   |   |   S )N)ZnumelZelement_sizer   r   r   r   r   x   s   r   Tc                 C   sR   t jddur'| r%zddlm  m} | }W dS  ty$   Y dS 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.
    r   Nr   TF)	importlibutil	find_specZtorch_xla.core.xla_modelcoreZ	xla_modelZ
xla_deviceRuntimeError)Zcheck_deviceZxm_r   r   r   r   |   s   r   c                 C   sH   z|    W S  ty#   z	|   W  Y S  ty"   Y Y dS w w )z
    Taken from https://github.com/huggingface/safetensors/blob/08db34094e9e59e2f9218f2df133b7b4aaff5a99/bindings/python/py_src/safetensors/torch.py#L11C1-L20C21.
    r   )untyped_storageZdata_ptr	ExceptionstorageNotImplementedErrorr   r   r   r   r      s   r   c                 C   sd   z|    W S  ty1   z|   t| j W  Y S  ty0   |  t| j  Y  Y S w w )z
    Taken from https://github.com/huggingface/safetensors/blob/08db34094e9e59e2f9218f2df133b7b4aaff5a99/bindings/python/py_src/safetensors/torch.py#L31C1-L41C59
    )	r"   nbytesAttributeErrorr$   size_get_dtype_sizedtyper%   Znelementr   r   r   r   r      s   r   r*   ztorch.dtypec                 C   sp   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   NZfloat8_e4m3fnZfloat8_e5m2         r   )torchgetattrZint64Zfloat32Zint32Zbfloat16Zfloat16Zint16Zuint8Zint8boolZfloat64)r*   r.   Z_float8_e4m3fnZ_float8_e5m2Z_SIZEr   r   r   r)      s"   r)   )T)__doc__r   	functoolsr   typingr   r   r   _baser   r   r	   r
   r.   strintr   r   r   r   r   r   r)   r   r   r   r   <module>   s4   

D