U
    +-eA                     @   s  d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
mZ d dlZd dlmZmZmZmZ ejedddZejeddd	Zejedd
dZee	e  eeejf ee	e  dddZeeejf ee	e  dddZejedddZdddeeejf eee  eee  eeee f dddZd=ejjeeeeef  edddZd>ejjeee j f e
ee ee f dddZ!d?eeejf eeeef  e"dd d!Z#d@eeejf eee j f eeeef  d"d#d$Z$dAeee j f eeejf d&d'd(Z%e"eeejf d)d*d+Z&ej'd,ej(d-ej)d-ej*d.ej+d.ej,d.ej-d/ej.d/ejd/ej/d,i
Z0ej/ej(ej+ej*ej'ej)ej,ej.ej-ejd0
Z1eej2d1d2d3Z3eeejf d4d5d6Z4ejee"d7d8d9Z5eeejf eeeeef f d:d;d<Z6dS )B    N)defaultdict)AnyDictListOptionalSetTupleUnion)deserialize	safe_open	serializeserialize_file)tensorreturnc                 C   sT   z|    W S  tk
rN   z|   W  Y S  tk
rH   Y Y dS X Y nX d S )Nr   )untyped_storagedata_ptr	ExceptionstorageNotImplementedErrorr    r   R/var/www/html/Darija-Ai-Train/env/lib/python3.8/site-packages/safetensors/torch.pystorage_ptr   s    r   c                 C   s2   |   r&| dd  t| j  }n|  }|S )N)nelementviewr   _SIZEdtype)r   stopr   r   r   _end_ptr   s    r   c                 C   sp   z|    W S  tk
rj   z|   t| j  W  Y S  tk
rd   |  t| j   Y  Y S X Y nX d S N)	r   nbytesAttributeErrorr   sizer   r   r   r   r   r   r   r   storage_size   s    r$   )tensors
state_dictr   c                 C   s   g }| D ]}t |dk r$|| qg }|D ]$}|| }|| t||f q,|  |d \}}}	||	h |dd  D ]2\}
}}|
|kr||h n|d | |}qq|S )N   r      r   )lenappendr   r   sortadd)r%   r&   Zfiltered_tensorssharedZareasnamer   _Z	last_stop	last_namestartr   r   r   r   _filter_shared_not_shared,   s$    
r2   )r&   r   c                 C   s~   t t}|  D ]N\}}|jtdkrt|dkrt|dkr||jt|t|f | qtt	|
 }t|| }|S )Nmetar   )r   setitemsdevicetorchr   r$   r,   listsortedvaluesr2   )r&   r%   kvr   r   r   _find_shared_tensorsE   s    ( 
r=   c                 C   s*   |   t| ko(|  t| j  t| kS r    )r   r   r   r   r   r$   r   r   r   r   _is_completeP   s    r>   )preferred_namesdiscard_names)r&   r?   r@   r   c          
         s   |d krg }t |}|d kr g }t |}t }tt}|D ]}t  fdd|D }|sjtd| dtt|d }||}|rtt|d }|r||}|rtt|d }t|D ]}	|	|kr|| |	 qq<|S )Nc                    s   g | ]}t  | r|qS r   )r>   ).0r.   r&   r   r   
<listcomp>d   s      z+_remove_duplicate_names.<locals>.<listcomp>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   )	r4   r=   r   r8   RuntimeErrorr9   
differenceintersectionr*   )
r&   r?   r@   Zshareds	to_remover-   Zcomplete_namesZ	keep_name	preferredr.   r   rB   r   _remove_duplicate_namesT   s4    


rI   T)modelfilenamemetadataforce_contiguousc              
   C   s   |   }t|}| D ]4\}}|D ]&}|dkr4i }||krD|||< ||= q$q|rddd | D }zt|||d W n: tk
r }	 zt|	}
|
d7 }
t|
W 5 d}	~	X Y nX dS )a  
    Saves a given torch model to specified filename.
    This method exists specifically to avoid tensor sharing issues which are
    not allowed in `safetensors`. [More information on tensor sharing](../torch_shared_tensors)

    Args:
        model (`torch.nn.Module`):
            The model to save on disk.
        filename (`str`):
            The filename location to save the file
        metadata (`Dict[str, str]`, *optional*):
            Extra information to save along with the file.
            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
        force_contiguous (`boolean`, *optional*, defaults to True):
            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.
    Nc                 S   s   i | ]\}}||  qS r   )
contiguousrA   r;   r<   r   r   r   
<dictcomp>   s      zsave_model.<locals>.<dictcomp>rL   zT Or use save_model(..., force_contiguous=True), read the docs for potential caveats.)r&   rI   r5   	save_file
ValueErrorstr)rJ   rK   rL   rM   r&   
to_removesZ	kept_nameto_remove_grouprG   emsgr   r   r   
save_model   s"    
rY   )rJ   rK   r   c                 C   s   t |}|  }t|| d}| j|dd\}}t|}| D ],}|D ]"}	|	|krb||	 qJ||	 qJqB|r|s||rd	dd t
|D }
d	dd t
|D }d| jj d	}|r|d
|
 7 }|r|d| 7 }t|||fS )an  
    Loads a given filename onto a torch model.
    This method exists specifically to avoid tensor sharing issues which are
    not allowed in `safetensors`. [More information on tensor sharing](../torch_shared_tensors)

    Args:
        model (`torch.nn.Module`):
            The model to load onto.
        filename (`str`, or `os.PathLike`):
            The filename location to load the file from.
        strict (`bool`, *optional*, defaults to True):
            Wether to fail if you're missing keys or having unexpected ones
            When false, the function simply returns missing and unexpected names.

    Returns:
        `(missing, unexpected): (List[str], List[str])`
            `missing` are names in the model which were not modified during loading
            `unexpected` are names that are on the file, but weren't used during
            the load.
    )r?   F)strictz, c                 S   s   g | ]}d | d qS "r   rA   r;   r   r   r   rC      s     zload_model.<locals>.<listcomp>c                 S   s   g | ]}d | d qS r[   r   r]   r   r   r   rC      s     z#Error(s) in loading state_dict for :z#
    Missing key(s) in state_dict: z&
    Unexpected key(s) in state_dict: )	load_filer&   rI   keysZload_state_dictr4   r:   r*   removejoinr9   	__class____name__rD   )rJ   rK   rZ   r&   Zmodel_state_dictrU   missingZ
unexpectedrV   rG   Zmissing_keysZunexpected_keyserrorr   r   r   
load_model   s(    rg   )r%   rL   r   c                 C   s   t t| |d}t|}|S )a$  
    Saves a dictionary of tensors into raw bytes in safetensors format.

    Args:
        tensors (`Dict[str, torch.Tensor]`):
            The incoming tensors. Tensors need to be contiguous and dense.
        metadata (`Dict[str, str]`, *optional*, defaults to `None`):
            Optional text only metadata you might want to save in your header.
            For instance it can be useful to specify more about the underlying
            tensors. This is purely informative and does not affect tensor loading.

    Returns:
        `bytes`: The raw bytes representing the format

    Example:

    ```python
    from safetensors.torch import save
    import torch

    tensors = {"embedding": torch.zeros((512, 1024)), "attention": torch.zeros((256, 256))}
    byte_data = save(tensors)
    ```
    rQ   )r   _flattenbytes)r%   rL   Z
serializedresultr   r   r   save   s    rk   r%   rK   rL   c                 C   s   t t| ||d dS )ah  
    Saves a dictionary of tensors into raw bytes in safetensors format.

    Args:
        tensors (`Dict[str, torch.Tensor]`):
            The incoming tensors. Tensors need to be contiguous and dense.
        filename (`str`, or `os.PathLike`)):
            The filename we're saving into.
        metadata (`Dict[str, str]`, *optional*, defaults to `None`):
            Optional text only metadata you might want to save in your header.
            For instance it can be useful to specify more about the underlying
            tensors. This is purely informative and does not affect tensor loading.

    Returns:
        `None`

    Example:

    ```python
    from safetensors.torch import save_file
    import torch

    tensors = {"embedding": torch.zeros((512, 1024)), "attention": torch.zeros((256, 256))}
    save_file(tensors, "model.safetensors")
    ```
    rQ   N)r   rh   rl   r   r   r   rR      s    rR   cpu)rK   r   c              	   C   s>   i }t | d|d"}| D ]}||||< qW 5 Q R X |S )a  
    Loads a safetensors file into torch format.

    Args:
        filename (`str`, or `os.PathLike`):
            The name of the file which contains the tensors
        device (`Dict[str, any]`, *optional*, defaults to `cpu`):
            The device where the tensors need to be located after load.
            available options are all regular torch device locations

    Returns:
        `Dict[str, torch.Tensor]`: dictionary that contains name as key, value as `torch.Tensor`

    Example:

    ```python
    from safetensors.torch import load_file

    file_path = "./my_folder/bert.safetensors"
    loaded = load_file(file_path)
    ```
    pt)Z	frameworkr6   )r   r`   Z
get_tensor)rK   r6   rj   fr;   r   r   r   r_     s
    r_   )datar   c                 C   s   t | }t|S )a  
    Loads a safetensors file into torch format from pure bytes.

    Args:
        data (`bytes`):
            The content of a safetensors file

    Returns:
        `Dict[str, torch.Tensor]`: dictionary that contains name as key, value as `torch.Tensor` on cpu

    Example:

    ```python
    from safetensors.torch import load

    file_path = "./my_folder/bert.safetensors"
    with open(file_path, "rb") as f:
        data = f.read()

    loaded = load(data)
    ```
    )r
   _view2torch)rp   Zflatr   r   r   load:  s    rr         r'   r(   )
ZF64ZF32ZF16ZBF16ZI64ZI32ZI16ZI8ZU8ZBOOL)	dtype_strr   c                 C   s   t |  S r    )_TYPES)ru   r   r   r   	_getdtypes  s    rw   )r   c                 C   sf   i }| D ]X\}}t |d }tj|d |d|d }tjdkrXt| jdd}|||< q|S )Nr   rp   )r   shapebigFZinplace)	rw   r7   Z
frombufferZreshapesys	byteorderZ
from_numpynumpybyteswap)Zsafeviewrj   r;   r<   r   Zarrr   r   r   rq   w  s    

rq   )r   r.   r   c                 C   s:  | j tjkrtd| d|  s4td| d| jjdkrJ| d} dd l}dd l	}t
|| j }t| j }|| }|  }|dkrdS ||||j}|j||f}	tjdkr2tj|jtj|jtj|jtj|jtj|jtj|jtj|jtj|jtj t tj!|j!i
}
|
| j }|	"|j#d	d
}	|	$ S )Nz)You are trying to save a sparse tensor: `` which this library does not support. You can make it a dense tensor before saving with `.to_dense()` but be aware this might make a much larger file than needed.z1You are trying to save a non contiguous tensor: `a  ` which is not allowed. It either means you are trying to save tensors which are reference of each other in which case it's recommended to save only the full tensors, and reslice at load time, or simply call `.contiguous()` on your tensor to pack it before saving.rm   r       ry   Frz   )%layoutr7   stridedrS   Zis_contiguousr6   typetoctypesr}   intprodrx   itemr   r   r   castZPOINTERZc_ubyteZ	ctypeslibZas_arrayr{   r|   int64float32int32bfloat16float16int16uint8int8boolfloat64r   r~   tobytes)r   r.   r   nplengthZbytes_per_itemtotal_bytesZptrZnewptrrp   ZNPDTYPESZnpdtyper   r   r   _tobytes  sZ    



          
r   )r%   r   c                 C   s   t | tstdt|  g }|  D ]B\}}t |tjsTtd| dt| |jtjkr(|	| q(|rtd| dt
| }g }|D ]}t|dkr|	| q|rtd| dd	d
 |  D S )Nz4Expected a dict of [str, torch.Tensor] but received zKey `z1` is invalid, expected torch.Tensor but received z*You are trying to save a sparse tensors: `r   r(   z
            Some tensors share memory, this will lead to duplicate memory on disk and potential differences when loading them again: z.
            A potential way to correctly save your model is to use `save_model`.
            More information at https://huggingface.co/docs/safetensors/torch_shared_tensors
            c                 S   s6   i | ].\}}|t |jd d |jt||dqS ).r   )r   rx   rp   )rT   r   splitrx   r   rO   r   r   r   rP     s   z_flatten.<locals>.<dictcomp>)
isinstancedictrS   r   r5   r7   Tensorr   r   r*   r=   r)   rD   )r%   Zinvalid_tensorsr;   r<   Zshared_pointersZfailingnamesr   r   r   rh     s4    

rh   )NT)T)N)N)rm   )7osr{   collectionsr   typingr   r   r   r   r   r   r	   r7   Zsafetensorsr
   r   r   r   r   r   r   r   r$   rT   r2   r=   r   r>   rI   nnModulerY   PathLikerg   ri   rk   rR   r_   rr   r   r   r   r   r   r   r   r   r   r   rv   r   rw   rq   r   rh   r   r   r   r   <module>   s   $,"

/      .2,*! "&          7