o
    i.                     @   s  d dl Z d dlZd dlZd dlZd dlmZmZmZmZm	Z	 d dl
mZ d dlmZmZmZ g dZeeeeef f Zeeef Zeeef Z	d'dedee defd	d
Zdedeeef fddZdededee fddZdededefddZdedeeef fddZ	d(dedee dede	eeeef f fddZ	d(deeef dee dede	eeeeeef f f fd d!Zdedeeef fd"d#Zd$edefd%d&ZdS ))    N)DictIterableOptionalTupleUnion)Tensor)SAFE_WEIGHTS_INDEX_NAMESAFE_WEIGHTS_NAMEcached_file)	get_safetensors_folderget_safetensors_headermatch_param_namemerge_namesget_weight_mappingsget_nested_weight_mappings#get_nested_mappings_from_state_dict*get_quantization_parameter_to_path_mappingis_quantization_parampretrained_model_name_or_path	cache_dirreturnc                 C   sx   t j| rt j| S t| t|dd}t| t|dd}|dur(t j|d S |dur4t j|d S td|  d)a  
    Given a Hugging Face stub or a local path, return the folder containing the
    safetensors weight files

    :param pretrained_model_name_or_path: local path to model or HF stub
    :param cache_dir: optional cache dir to search through, if none is specified the
    model will be searched for in the default TRANSFORMERS_CACHE
    :return: local folder containing model data
    F)r   %_raise_exceptions_for_missing_entriesNr   z7Could not locate safetensors weight or index file from .)	ospathexistsabspathr
   r	   r   split
ValueError)r   r   safetensors_path
index_path r!   ]/home/ubuntu/.local/lib/python3.10/site-packages/compressed_tensors/utils/safetensors_load.pyr   *   s.   r   r   c                 C   sZ   t | d}td|dd }||}t|}W d   |S 1 s&w   Y  |S )z
    Extracts the metadata from a safetensors file as JSON

    :param safetensors_path: path to a safetensors file
    :return: dictionary of metadata extracted from the safetensors file
    rbz<Q   r   N)openstructunpackreadjsonloads)r   flength_of_headerheader_dataheaderr!   r!   r"   r   T   s   

r   	full_name
param_namec                 C   s0   d| d }t || }t|dkrdS |d S )a_  
    Helper function extracting the uncompressed parameterized layer name from a
    compressed name. Assumes the compressed name was merged using merge_names.

    :param full_name: full name of parameter in compressed model
    :param param_name: compression paramater name
    :return: uncompressed name of the uncompressed parameterized layer
    z^(.*)\.$r   N)refindalllen)r/   r0   patternregexr!   r!   r"   r   c   s
   	r   parent_name
child_namec                 C   s   | d | S )aQ  
    Helper function for merging an uncompressed parameterized layer name with a
    compression parameter. Names merged with this function can then be parsed by
    match_param_name.

    :param parent_name: uncompressed parameterized layer name
    :param child_name: compression parameter name
    :return: merged compressed name
    r   r!   )r7   r8   r!   r!   r"   r   s   s   
r   path_to_model_or_tensorsc                 C   s  t j| rt| }| D ]}| ||< q|dd |S t j| t}t j| t}t j	|rGt|}| D ]}t||< q9|dd n.t j	|rnt
|ddd}t|}W d   n1 sdw   Y  |d }ntd|  | D ]\}}t j| |||< qy|S )a  
    Takes a path to a state dict saved in safetensors format and returns a mapping
    from parameterized layer name to file location.

    {
        layer.weight.bitmask: file_location,
        layer.weight.row_offsets: file_location,
        layer.weight.shape: file_location,
        layer.weight.compressed: file_location
    }

    This generalizes to cases where the model is split into multiple safetensors files

    :param path_to_model_or_tensors: path to directory that contains
        safetensors (must contain either a single file or multiple files with an index),
        or a path to a single safetensors file
    :return: mapping of parameterized layer name to file location
    __metadata__Nrzutf-8)encoding
weight_mapz5Could not find a safetensors weight or index file at )r   r   isfiler   keyspopjoinr	   r   r   r%   r)   loadr   items)r9   r.   keyr   r    r+   indexvaluer!   r!   r"   r      s4   


r   F
model_pathparams_to_nestreturn_unmatched_paramsc                 C   s~   t | }i }i }| D ]*\}}d}|D ]}	t||	}
|
r-|
|vr%i ||
< |||
 |	< d}q|r6|s6|||< q|r=||fS |S )a  
    Takes a path to a state dict saved in safetensors format and returns a nested
    mapping from uncompressed parameterized layer names to the file locations of
    each layer's compression parameters.

    Example of the nested mapping:
    layer: {
        bitmask: file_location,
        row_offsets: file_location,
        shape: file_location,
        compressed: file_location
    }

    If other parameters are found that do not match the nested parameters, they will
    be returned in a separate dictionary only if return_unmatched_params is True.
    This dictionary may be needed for cases where compressors are stacked (e.g.,
    quantization compression followed by sparse compression).

    Example of the unmatched params mapping:
    {
        layer.weight_scale: file_location,
        layer.input_scale: file_location
    }

    This generalizes to cases where the model is split into multiple safetensors
    files.

    :param model_path: Path to the safetensors state dict, must contain either a
        single safetensors file or multiple files with an index.
    :param params_to_nest: Iterable of parameter names to nest.
    :param return_unmatched_params: If True, return a second dictionary containing
        the remaining parameters that were not matched to the params_to_nest.
    :return:
        - If return_unmatched_params is False:
            NestedWeightMappingType: A nested mapping of parameterized layer names to
            file locations of each layer's compression parameters.
        - If return_unmatched_params is True:
            Tuple[NestedWeightMappingType, WeightMappingType]: A tuple containing:
                - NestedWeightMappingType: A nested mapping of parameterized layer
                names to file locations of each layer's compression parameters.
                - WeightMappingType: A mapping of the remaining parameter names to
                their file locations that were not matched to the params_to_nest.
    FT)r   rC   r   )rG   rH   rI   weight_mappingsnested_weight_mappingsunmatched_paramsrD   file_locationmatchedr0   module_pathr!   r!   r"   r      s&   0
r   
state_dictc           	      C   sz   i }i }|   D ],}d}|D ]}t||}|r)||vri ||< | | || |< d}q|r4|s4| | ||< q|r;||fS |S )a{  
    Takes a state dict and returns a nested mapping from uncompressed
    parameterized layer names to the value of
    each layer's compression parameters.

    Example of the nested mapping:
    layer: {
        weight_scale: ...,
        weight: ...,
        zero_point: ...,
    }

    :param state_dict: state dict of the model
    :param params_to_nest: Iterable of parameter names to nest.
    :return: Nested mapping of parameterized layer names to the value of
        each layer's compression parameters. If `return_unmatched_params`, then
        also return a dictionary mapping unused parameter names to their values
    FT)r?   r   )	rP   rH   rI   rK   rL   rD   rN   r0   rO   r!   r!   r"   r      s$   
r   c                 C   s4   t | }i }| D ]\}}t|r|||< q
q
|S )z[
    Given a model path, return a mapping between a parameter and its path
    on disk
    )r   rC   r   )rG   rJ   mappingweight_name	safe_pathr!   r!   r"   r   &  s   r   namec                 C   s.   |  drdS |  drdS |  drdS dS )z
    Checks is a parameter name is associated with a quantization parameter

    :param name: parameter name to check
    :return: True if parameter name is a quantization parameter, else False
    _scaleT
zero_pointg_idxF)endswith)rT   r!   r!   r"   r   4  s   


r   )N)F)r)   r   r2   r&   typingr   r   r   r   r   torchr   transformers.utilsr   r	   r
   __all__strNestedStateDictTypeWeightMappingTypeNestedWeightMappingTyper   r   r   r   r   boolr   r   r   r   r!   r!   r!   r"   <module>   sZ   
*9
H

+