o
    i8*                     @  s   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
dZd%d&ddZ	d'ddZ
d(d)ddZeG d d! d!ZG d"d# d#ZdS )*    )annotations)	dataclass)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   I/home/ubuntu/veenaModal/venv/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   r2   
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   )r3   r4   r5   r6   r2   r   r7   name
parametersfinetuneversionencodingkindr   r   r   naming_convention5   s   ""&"rD   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   dtypeztuple[int, ...]shaper   offset_startsizeurlr	   	bytearrayc                 C  s   t tj| j| j| jd}|S )N)rJ   startrI   )rK   SafetensorRemoteget_data_by_rangerJ   rH   rI   )selfdatar   r   r   rP   T   s   zRemoteTensor.dataN)r	   rK   )__name__
__module____qualname____annotations__rP   r   r   r   r   rE   L   s   
 rE   c                   @  sn   e Zd 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 )%rM   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Model z# does not have any safetensor files)check_file_existBASE_DOMAINget_list_tensorsrN   decodejsonloadsgetlistsetvaluessortitems
ValueError)clsrV   is_single_filerJ   	index_urlis_multiple_files
index_data	index_str
index_jsonrY   	all_filestensorsfilekeyvalr   r   r   get_list_tensors_hf_modelq   s,   	




z*SafetensorRemote.get_list_tensors_hf_modelrJ   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 |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': rF   rG   data_offsets)rF   rG   rH   rI   rJ   z$Missing key in metadata for tensor 'z	, meta = N)get_metadatare   
isinstancedictrf   rE   tupleKeyError)rg   rJ   metadatadata_start_offsetresr>   metarF   rG   offset_start_relativeoffset_end_relativerI   rH   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j}|| dkr3||||  7 }t|d| k rItdd|  d	t| |dd|  }|d
}z
t	|}	|	|fW S  tj
yt }
 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   rU   z%Not enough data to read metadata sizeNlittle)	byteorderz'Could not read complete metadata. Need z bytes, got rX   z-Failed to parse safetensor metadata as JSON: )rN   r#   rf   r   
from_bytesrM   	ALIGNMENTr]   r^   r_   JSONDecodeError)rg   rJ   	read_sizeraw_datametadata_lengthr|   	alignmentmetadata_bytesmetadata_strr{   r   r   r   r   rv      s(   


zSafetensorRemote.get_metadatarL   r   rI   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netlocrf   _get_request_headersr`   raise_for_statuscontentslice)	rg   rJ   rL   rI   r   r   
parsed_urlr   responser   r   r   rN      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   rf   r   headstatus_codeRequestException)rg   rJ   r   r   r   r   r   r   r   r   rZ      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environr`   )rg   r   r   r   r   r     s   z%SafetensorRemote._get_request_headersN)rV   r   r	   rW   )rJ   r   r	   rW   )rJ   r   r	   r   )r   )rJ   r   rL   r   rI   r   r	   r   )rJ   r   r	   r   )r	   r   )rQ   rR   rS   __doc__r[   r   classmethodrs   r\   rv   rN   rZ   r   r   r   r   r   rM   [   s     $#rM   )r   r   r   r   r	   r   )r   )r   r   r   r   r	   r   )
r*   r   r+   r   r,   r   r-   r   r	   r   )N)r3   r   r4   r   r5   r   r6   r   r2   r   r   r   r7   r8   r	   r   )
__future__r   dataclassesr   typingr   r   r^   r   r)   r2   rD   rE   rM   r   r   r   r   <module>   s    
	
