a
     d7                     @   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eejf ee	e  d
ddZejedddZd7eeejf ee eeee f dddZd8ejjeeeeef  edddZd9ejje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"d<e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
Z.ej-ej&ej)ej(ej%ej'ej*ej,ej+ejd*
Z/eej0d+d,d-Z1eeejf d.d/d0Z2ejeed1d2d3Z3eeejf eeeeef f d4d5d6Z4dS )=    N)defaultdict)AnyDictListOptionalSetTupleUnion)deserialize	safe_open	serializeserialize_file)tensorreturnc                 C   sP   z|    W S  tyJ   z|   W  Y S  tyD   Y Y dS 0 Y n0 d S )Nr   )untyped_storagedata_ptr	ExceptionstorageNotImplementedErrorr    r   Z/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/safetensors/torch.pystorage_ptr   s    r   c                 C   sl   z|    W S  tyf   z|   t| j  W  Y S  ty`   |  t| j   Y  Y S 0 Y n0 d S N)	r   nbytesAttributeErrorr   size_SIZEdtyper   nelementr   r   r   r   storage_size   s    r    )
state_dictr   c                 C   sV   t t}|  D ]0\}}|jtdkr|t||jf | qtt|	 }|S )Nmeta)
r   setitemsdevicetorchr   addlistsortedvalues)r!   tensorskvr   r   r   _find_shared_tensors$   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_complete.   s    r/   )r!   preferred_namesr   c           	         s   |d u rg }t |}t }tt}|D ]~} fdd|D }|sRtd| d|t |}|rvtt|d }nt|d }t|D ]}||kr|| | qq(|S )Nc                    s   g | ]}t  | r|qS r   )r/   ).0namer!   r   r   
<listcomp><       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   )r#   r.   r   r(   RuntimeErrorintersectionr)   append)	r!   r0   Zshareds	to_removeZsharedZcomplete_names	preferredZ	keep_namer2   r   r3   r   _remove_duplicate_names2   s&    
r;   T)modelfilenamemetadataforce_contiguousc              
   C   s   |   }t|}| D ]4\}}|D ]&}|du r4i }||vrD|||< ||= q$q|rddd | D }zt|||d W n< ty }	 z$t|	}
|
d7 }
t|
W Y d}	~	n
d}	~	0 0 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r1   r,   r-   r   r   r   
<dictcomp>v   r5   zsave_model.<locals>.<dictcomp>r>   zT Or use save_model(..., force_contiguous=True), read the docs for potential caveats.)r!   r;   r$   	save_file
ValueErrorstr)r<   r=   r>   r?   r!   
to_removesZ	kept_nameto_remove_groupr9   emsgr   r   r   
save_modelQ   s"    
rK   )r<   r=   r   c                 C   s   t |}|  }t|| d}| j|dd\}}t|}| D ],}|D ]"}	|	|v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 )aY  
    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`):
            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.
    )r0   F)strictz, c                 S   s   g | ]}d | d qS "r   r1   r,   r   r   r   r4      r5   zload_model.<locals>.<listcomp>c                 S   s   g | ]}d | d qS rM   r   rO   r   r   r   r4      r5   z#Error(s) in loading state_dict for :z#
    Missing key(s) in state_dict: z&
    Unexpected key(s) in state_dict: )	load_filer!   r;   keysZload_state_dictr#   r*   r8   removejoinr)   	__class____name__r6   )r<   r=   rL   r!   Zmodel_state_dictrG   missingZ
unexpectedrH   r9   Zmissing_keysZunexpected_keyserrorr   r   r   
load_model   s(    rY   )r+   r>   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)
    ```
    rC   )r   _flattenbytes)r+   r>   Z
serializedresultr   r   r   save   s    r]   r+   r=   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")
    ```
    rC   N)r   rZ   r^   r   r   r   rD      s    rD   cpu)r=   r   c                 C   sR   i }t | d|d,}| D ]}||||< qW d   n1 sD0    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 (`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	frameworkr%   N)r   rR   Z
get_tensor)r=   r%   r\   fr,   r   r   r   rQ      s
    .rQ   )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)rb   Zflatr   r   r   load	  s    rd               )
ZF64ZF32ZF16ZBF16ZI64ZI32ZI16ZI8ZU8ZBOOL)	dtype_strr   c                 C   s   t |  S r   )_TYPES)ri   r   r   r   	_getdtypeB  s    rk   )r   c                 C   sF   i }| D ]8\}}t |d }tj|d |d|d }|||< q|S )Nr   rb   )r   shape)rk   r&   Z
frombufferZreshape)Zsafeviewr\   r,   r-   r   Zarrr   r   r   rc   F  s    
rc   )r   r2   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}	|	 S )Nz)You are trying to save a sparse tensor: `z` 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.r_   r   r5   )layoutr&   stridedrE   Zis_contiguousr%   typetoctypesnumpyintprodrl   itemr   r   r   castPOINTERc_ubyteZ	ctypeslibZas_arraytobytes)
r   r2   rq   nplengthZbytes_per_itemtotal_bytesptrZnewptrrb   r   r   r   _tobytesP  s*    



r~   )r+   r   c                 C   s   t jdkrtdt| ts.tdt|  tt}|  D ]J\}}t|t	j
sjtd| dt| |jt	jkr>|t| | q>g }| D ]\}}t|dkr|| q|rtd| dd	d
 |  D S )NbigzFBig endian is not supported, serialization need to be in little endianz4Expected a dict of [str, torch.Tensor] but received zKey `z1` is invalid, expected torch.Tensor but received rh   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   rl   rb   )rF   r   splitrl   r~   rA   r   r   r   rB     s   z_flatten.<locals>.<dictcomp>)sys	byteorderrE   
isinstancedictro   r   r#   r$   r&   Tensorrm   rn   r   r'   lenr8   r6   )r+   Zptrsr,   r-   Zfailingr}   namesr   r   r   rZ   w  s.    

rZ   )N)NT)T)N)N)r_   )5osr   collectionsr   typingr   r   r   r   r   r   r	   r&   Zsafetensorsr
   r   r   r   r   rs   r   r    rF   r.   boolr/   r;   nnModulerK   rY   r[   r]   PathLikerD   rQ   rd   int64float32int32Zbfloat16float16int16Zuint8Zint8float64r   rj   r   rk   rc   r~   rZ   r   r   r   r   <module>   sl   $"
   .(,*! "&
'