o
    shE                     @   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 dejdefddZdejdefd	d
ZdejdefddZdee	e  deeejf dee	e  fddZdeeejf dee	e  fddZdejdefddZddddeeejf deee  deee  deeee f fddZ	d@dejjdedeeeef  defdd Z	!dAdejjdeee j f d"ed#eeef de
ee ee f f
d$d%Z!dBdeeejf deeeef  de"fd&d'Z#	dBdeeejf deee j f deeeef  fd(d)Z$dCdeee j f d#eeef deeejf fd*d+Z%d,e"deeejf fd-d.Z&e'ed/dZ(e'ed0dZ)ej*d1ej+d2ej,d2ej-d3ej.d3ej/d3ej0d4ej1d4ejd4ej2d1e(d4e)d4iZ3ej2ej+ej.ej-ej*ej,ej/ej1ej0eje(e)d5Z4d6edej5fd7d8Z6deeejf fd9d:Z7dejd;ede"fd<d=Z8deeejf deeeeef f fd>d?Z9dS )D    N)defaultdict)AnyDictListOptionalSetTupleUnion)deserialize	safe_open	serializeserialize_filetensorreturnc                 C   sH   z|    W S  ty#   z	|   W  Y S  ty"   Y Y dS w w )Nr   )untyped_storagedata_ptr	ExceptionstorageNotImplementedErrorr    r   e/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/safetensors/torch.pystorage_ptr   s   r   c                 C   s4   |   r| dd  t| j  }|S |  }|S )N)nelementviewr   _SIZEdtype)r   stopr   r   r   _end_ptr   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 N)	r   nbytesAttributeErrorr   sizer   r   r   r   r   r   r   r   storage_size   s   r$   tensors
state_dictc                 C   s   g }| D ]V}t |dk r|| qg }|D ]}|| }|| t||f q|  |d \}}}	||	h |dd  D ]\}
}}|
|krP||h n|d | |}q@q|S )N   r      r   )lenappendr   r   sortadd)r%   r&   filtered_tensorssharedareasnamer   _	last_stop	last_namestartr   r   r   r   _filter_shared_not_shared,   s&   
r5   c                 C   s~   t t}|  D ]'\}}|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valuesr5   )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   *rA   )preferred_namesdiscard_namesrB   rC   c          
         s   |d u rg }t |}|d u rg }t |}t }tt}|D ]Q}t  fdd|D }|s5td| dtt|d }||}|rLtt|d }|r]||}|r]tt|d }t|D ]}	|	|krn|| |	 qaq|S )Nc                    s   g | ]
}t  | r|qS r   )rA   ).0r0   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   )	r7   r@   r   r;   RuntimeErrorr<   
differenceintersectionr*   )
r&   rB   rC   shareds	to_remover.   complete_names	keep_name	preferredr0   r   rE   r   _remove_duplicate_namesT   s<   

rO   Tmodelfilenamemetadataforce_contiguousc              
   C   s   |   }t|}| D ]\}}|D ]}|du ri }||vr"|||< ||= qq|r2dd | D }z
t|||d W dS  tyT }	 zt|	}
|
d7 }
t|
d}	~	ww )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rD   r>   r?   r   r   r   
<dictcomp>   s    zsave_model.<locals>.<dictcomp>rR   zT Or use save_model(..., force_contiguous=True), read the docs for potential caveats.)r&   rO   r8   	save_file
ValueErrorstr)rP   rQ   rR   rS   r&   
to_removes	kept_nameto_remove_grouprK   emsgr   r   r   
save_model   s(   r`   cpustrictr9   c                 C   s   t ||d}|  }t|| d}| j|dd\}}t|}| D ]}	|	D ]}
|
|vr3||
 q'||
 q'q#|rv|s@|rvd	dd t
|D }d	dd t
|D }d	| jj d
}|ri|d| 7 }|rr|d| 7 }t|||fS )aA  
    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):
            Whether to fail if you're missing keys or having unexpected ones.
            When false, the function simply returns missing and unexpected names.
        device (`Union[str, int]`, *optional*, defaults to `cpu`):
            The device where the tensors need to be located after load.
            available options are all regular torch device locations.

    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.
    )r9   )rB   F)rb   z, c                 S      g | ]}d | d qS "r   rD   r>   r   r   r   rF          zload_model.<locals>.<listcomp>c                 S   rc   rd   r   rf   r   r   r   rF      rg   z#Error(s) in loading state_dict for :z#
    Missing key(s) in state_dict: z&
    Unexpected key(s) in state_dict: )	load_filer&   rO   keysload_state_dictr7   r=   r*   removejoinr<   	__class____name__rG   )rP   rQ   rb   r9   r&   model_state_dictr[   missing
unexpectedr]   rK   missing_keysunexpected_keyserrorr   r   r   
load_model   s*   rv   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)
    ```
    rW   )r   _flattenbytes)r%   rR   
serializedresultr   r   r   save   s   r{   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")
    ```
    rW   N)r   rw   )r%   rQ   rR   r   r   r   rX      s   rX   c                 C   sT   i }t | d|d}| D ]	}||||< qW d   |S 1 s#w   Y  |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 (`Union[str, int]`, *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)	frameworkr9   N)r   rj   
get_tensor)rQ   r9   rz   fr>   r   r   r   ri   !  s   
ri   datac                 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)r   flatr   r   r   load?  s   r   float8_e4m3fnfloat8_e5m2      r'   r(   )F64F32F16BF16I64I32I16I8U8BOOLF8_E4M3F8_E5M2	dtype_strc                 C   s   t |  S r    )_TYPES)r   r   r   r   	_getdtype  s   r   c                 C   s   i }| D ]K\}}t |d }t|d dkr-tdd |d D s#J tj|d |d}ntj|d |d|d }tjdkrKt	|
 jd	d
}|||< q|S )Nr   r   r   c                 s   s    | ]}|d kV  qdS )r   Nr   )rD   xr   r   r   	<genexpr>  s    z_view2torch.<locals>.<genexpr>shape)r   bigFinplace)r   r)   anyr:   empty
frombufferreshapesys	byteorder
from_numpynumpybyteswap)safeviewrz   r>   r?   r   arrr   r   r   r     s   

r   r0   c                 C   sD  | j tjkrtd| d|  std| d| jjdkr%| d} dd l}dd l	}t
|| j }t| j }|| }|  }|dkrJdS ||||j}|j||f}	tjdkrt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!t"|jt#|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.ra   r       r   Fr   )'layoutr:   stridedrY   is_contiguousr9   typetoctypesr   intprodr   itemr   r   r   castPOINTERc_ubyte	ctypeslibas_arrayr   r   int64float32int32bfloat16float16int16uint8int8boolfloat64_float8_e4m3fn_float8_e5m2r   r   tobytes)r   r0   r   nplengthbytes_per_itemtotal_bytesptrnewptrr   NPDTYPESnpdtyper   r   r   _tobytes  sJ   





r   c                 C   s   t | tstdt|  g }|  D ]!\}}t |tjs*td| dt| |jtjkr5|	| q|r@td| dt
| }g }|D ]}t|dkrU|	| qH|r`t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   r   r   )rZ   r   splitr   r   rU   r   r   r   rV     s    z_flatten.<locals>.<dictcomp>)
isinstancedictrY   r   r8   r:   Tensorr   r   r*   r@   r)   rG   )r%   invalid_tensorsr>   r?   shared_pointersfailingnamesr   r   r   rw     s8   



rw   )NT)Tra   r    )ra   ):osr   collectionsr   typingr   r   r   r   r   r   r	   r:   safetensorsr
   r   r   r   r   r   r   r   r$   rZ   r5   r@   r   rA   rO   nnModuler`   PathLikerv   rx   r{   rX   ri   r   getattrr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rw   r   r   r   r   <module>   s    $0$


/
/

.1!
4"0: