o
    [۷i4                     @  s   d dl mZ d dlmZ d dlmZ d dlmZ d dlZd dl	Z	d dl
Zd+ddZd,d-ddZd.ddZd/d0dd ZeG d!d" d"ZG d#d$ d$ZeG d%d& d&ZeG d'd( d(ZG d)d* d*ZdS )1    )annotations)	dataclass)Path)LiteralNfilenamestroutput_type
str | Nonereturnc                 C  s<   |d ur|  nd}|d ur| nd}| j|||||dS )N )outtypeftypeOUTTYPEFTYPE)lowerupperformat)r   r   ftype_lowercaseftype_uppercase r   B/home/ubuntu/vllm_env/lib/python3.10/site-packages/gguf/utility.pyfill_templated_filename   s   r      model_params_countint
min_digitsc                 C  s   | dkr| d }d}n| dkr| d }d}n| dkr!| d }d	}n| d
 }d}t |ttt|d d}|d| d| S )Ng   mBg-q=Tg    eAg&.>Bg    .Agư>MgMbP?K0r   .f)maxlenr   roundlstrip)r   r   scaled_model_paramsscale_suffixfixr   r   r   #model_weight_count_rounded_notation   s    r*   total_paramsshared_paramsexpert_paramsexpert_countc                 C  sF   |dkrt t|t| dd}| d| }|S t t| dd}|S )Nr   r   )r   x)r*   abs)r+   r,   r-   r.   pretty_size
size_classr   r   r   
size_label,   s   r3   
model_name	base_namefinetune_stringversion_string
model_typeLiteral['vocab', 'LoRA'] | Nonec                 C  s  |d ur|  dddd}n| d ur"|   dddd}nd}|d ur-d| nd}|d ur>d|  dd nd}	|d urOd|  dd nd}
|d urbd|  dd  nd}|d ursd|  dd nd}| | |	 |
 | | S )N -/z
ggml-modelr   )stripreplacer   )r4   r5   r6   r7   r3   r   r8   name
parametersfinetuneversionencodingkindr   r   r   naming_convention7   s   ""&"rE   c                   @  s@   e Zd ZU ded< ded< ded< ded< ded< dddZdS )RemoteTensorr   dtypetuple[int, ...]shaper   offset_startsizeurlr
   	bytearrayc                 C  s   t tj| j| j| jd}|S )N)rL   startrK   )rM   SafetensorRemoteget_data_by_rangerL   rJ   rK   )selfdatar   r   r   rR   V   s   zRemoteTensor.dataN)r
   rM   )__name__
__module____qualname____annotations__rR   r   r   r   r   rF   N   s   
 rF   c                   @  sj   e Zd ZdZdZedddZedd
dZedddZed d!ddZ	ed"ddZ
ed#ddZdS )$rO   a  
    Uility class to handle remote safetensor files.
    This class is designed to work with Hugging Face model repositories.

    Example (one model has single safetensor file, the other has multiple):
        for model_id in ["ngxson/TEST-Tiny-Llama4", "Qwen/Qwen2.5-7B-Instruct"]:
            tensors = SafetensorRemote.get_list_tensors_hf_model(model_id)
            print(tensors)

    Example reading tensor data:
        tensors = SafetensorRemote.get_list_tensors_hf_model(model_id)
        for name, meta in tensors.items():
            dtype, shape, offset_start, size, remote_safetensor_url = meta
            # read the tensor data
            data = SafetensorRemote.get_data_by_range(remote_safetensor_url, offset_start, size)
            print(data)
    zhttps://huggingface.comodel_idr   r
   dict[str, RemoteTensor]c                 C  s  |  | j d| d}|r| j d| d}| |S | j d| d}|  |}|r{| |d}|d}t|}|ddusGJ d|d }	tt	|	
 }
|
  i }|
D ]}| j d| d	| }| | D ]\}}|||< qoq[|S td
| d)z
        Get list of tensors from a Hugging Face model repository.

        Returns a dictionary of tensor names and their metadata.
        Each tensor is represented as a tuple of (dtype, shape, offset_start, size, remote_safetensor_url)
        r<   z/resolve/main/model.safetensorsz*/resolve/main/model.safetensors.index.jsonr   utf-8
weight_mapNz"weight_map not found in index filez/resolve/main/z,No safetensor file has been found for model z.If the repo has safetensor files, make sure the model is public or you have a valid Hugging Face token set in the environment variable HF_TOKEN.)check_file_existBASE_DOMAINget_list_tensorsrP   decodejsonloadsgetlistsetvaluessortitems
ValueError)clsrW   is_single_filerL   	index_urlis_multiple_files
index_data	index_str
index_jsonrZ   	all_filestensorsfilekeyvalr   r   r   get_list_tensors_hf_modelr   s0   	





z*SafetensorRemote.get_list_tensors_hf_modelrL   c                 C  s   |  |\}}i }| D ]V\}}|dkrqt|ts%td| d| z%|d }|d }|d \}	}
|
|	 }||	 }t|t||||d||< W q tyc } ztd| d| d	| d
}~ww tt| dd d}|S )z
        Get list of tensors from a remote safetensor file.

        Returns a dictionary of tensor names and their metadata.
        Each tensor is represented as a tuple of (dtype, shape, offset_start, size)
        __metadata__zInvalid metadata for tensor 'z': rG   rI   data_offsets)rG   rI   rJ   rK   rL   z$Missing key in metadata for tensor 'z	, meta = Nc                 S     | d S Nr   r   tr   r   r   <lambda>       z3SafetensorRemote.get_list_tensors.<locals>.<lambda>rr   )	get_metadatarf   
isinstancedictrg   rF   tupleKeyErrorsorted)rh   rL   metadatadata_start_offsetresr?   metarG   rI   offset_start_relativeoffset_end_relativerK   rJ   er   r   r   r]      s(   
z!SafetensorRemote.get_list_tensorstuple[dict, int]c           
   
   C  s   d}|  |d|}t|dk rtdtj|dd dd}d| }t|d| k r8tdd|  d	t| |dd|  }|d
}z
t|}||fW S  tjyc }	 ztd|	 d}	~	ww )zz
        Get JSON metadata from a remote safetensor file.

        Returns tuple of (metadata, data_start_offset)
        i  P r      z%Not enough data to read metadata sizeNlittle	byteorder'Could not read complete metadata. Need  bytes, got rY   z-Failed to parse safetensor metadata as JSON: )	rP   r$   rg   r   
from_bytesr^   r_   r`   JSONDecodeError)
rh   rL   	read_sizeraw_datametadata_lengthr   metadata_bytesmetadata_strr   r   r   r   r   r~      s"   


zSafetensorRemote.get_metadatarN   r   rK   bytesc           	      C  s   ddl }ddlm} ||}|jr|jstd| |  }|dkr/d| d||  |d< |j|d	|d
}|  |j	t
|dkrF| S d S )z
        Get raw byte data from a remote file by range.
        If size is not specified, it will read the entire file.
        r   NurlparseInvalid URL: r   zbytes=r;   RangeTallow_redirectsheaders)requestsurllib.parser   schemenetlocrg   _get_request_headersra   raise_for_statuscontentslice)	rh   rL   rN   rK   r   r   
parsed_urlr   responser   r   r   rP      s   z"SafetensorRemote.get_data_by_rangeboolc                 C  s   ddl }ddlm} ||}|jr|jstd| z|  }d|d< |j|d|d}d	|j  ko7d
k W S   W S  |j	yE   Y dS w )zt
        Check if a file exists at the given URL.
        Returns True if the file exists, False otherwise.
        r   Nr   r   z	bytes=0-0r   Tr      i  F)
r   r   r   r   r   rg   r   headstatus_codeRequestException)rh   rL   r   r   r   r   r   r   r   r   r[      s   z!SafetensorRemote.check_file_existdict[str, str]c                 C  s,   ddi}t jdrdt jd  |d< |S )z$Prepare common headers for requests.z
User-Agentconvert_hf_to_ggufHF_TOKENzBearer Authorization)osenvironra   )rh   r   r   r   r   r     s   z%SafetensorRemote._get_request_headersN)rW   r   r
   rX   )rL   r   r
   rX   )rL   r   r
   r   )r   )rL   r   rN   r   rK   r   r
   r   )rL   r   r
   r   )r
   r   )rS   rT   rU   __doc__r\   classmethodrt   r]   r~   rP   r[   r   r   r   r   r   rO   ]   s    ( rO   c                   @  s&   e Zd ZU ded< ded< ded< dS )LocalTensorRanger   r   r   offsetrK   N)rS   rT   rU   rV   r   r   r   r   r     s   
 r   c                   @  s0   e Zd ZU ded< ded< ded< dd	d
ZdS )LocalTensorr   rG   rH   rI   r   
data_ranger
   
np.ndarrayc                 C  s   t j| jjd| jj| jjdS )Nc)moder   rI   )npmemmapr   r   r   rK   )rQ   r   r   r   
mmap_bytes  s   zLocalTensor.mmap_bytesN)r
   r   )rS   rT   rU   rV   r   r   r   r   r   r     s
   
 r   c                   @  s4   e Zd ZU dZded< dddZdd	 Zd
d ZdS )SafetensorsLocalz
        Read a safetensors file from the local filesystem.

        Custom parsing gives a bit more control over the memory usage.
        The official safetensors library doesn't expose file ranges.
    zdict[str, LocalTensor]rp   r   r   c                 C  sD  t |d}tj|ddd}t|j}|d| k r(tdd|  d| ||d}zt	
|}W n t	jyK } ztd| d }~ww | }i }	| D ],\}
}|
d	kr_qVt|d
 t|d t|||d d  |d d |d d  d|	|
< qVtt|	 dd d| _W d    d S 1 sw   Y  d S )Nrbr   r   r   r   r   rY   z.Failed to parse safetensors metadata as JSON: ru   rG   rI   rv   r      )rG   rI   r   c                 S  rw   rx   r   ry   r   r   r   r{   M  r|   z+SafetensorsLocal.__init__.<locals>.<lambda>r}   )openr   r   readr   statst_sizerg   r^   r_   r`   r   tellrf   r   r   r   r   r   rp   )rQ   r   r"   r   	file_sizer   r   r   r   rp   r?   r   r   r   r   __init__,  s8   
"zSafetensorsLocal.__init__c                 O  s
   ~~| j S N)rp   rQ   argskwargsr   r   r   	__enter__O  s   zSafetensorsLocal.__enter__c                 O  s   ~~d S r   r   r   r   r   r   __exit__S  s   zSafetensorsLocal.__exit__N)r   r   )rS   rT   rU   r   rV   r   r   r   r   r   r   r   r   "  s   
 
#r   )r   r   r   r	   r
   r   )r   )r   r   r   r   r
   r   )
r+   r   r,   r   r-   r   r.   r   r
   r   r   )r4   r	   r5   r	   r6   r	   r7   r	   r3   r	   r   r	   r8   r9   r
   r   )
__future__r   dataclassesr   pathlibr   typingr   r   r_   numpyr   r   r*   r3   rE   rF   rO   r   r   r   r   r   r   r   <module>   s(    
	
 5	