
    5h +                        S SK Jr  S SKJr  S SKJr  S SKrS SKrSS jrSSS jjr	SS jr
SSS jjr\ " S	 S
5      5       r " S S5      rg)    )annotations)	dataclass)LiteralNc                x    Ub  UR                  5       OSnUb  UR                  5       OSnU R                  UX"X3S9$ )N )outtypeftypeOUTTYPEFTYPE)lowerupperformat)filenameoutput_typeftype_lowercaseftype_uppercases       4/home/james-whalen/llama.cpp/gguf-py/gguf/utility.pyfill_templated_filenamer   
   sL    2=2I;,,.rO2=2I;,,.rO???#2#2  K K    c           
         U S:  a  U S-  nSnO#U S:  a  U S-  nSnOU S:  a  U S-  nS	nOU S
-  nSn[        U[        [        [        U5      5      R	                  S5      5      -
  S5      nUSU S3 U 3$ )Ng   mBg-q=Tg    eAg&.>Bg    .Agư>MgMbP?K0r   .f)maxlenstrroundlstrip)model_params_count
min_digitsscaled_model_paramsscale_suffixfixs        r   #model_weight_count_rounded_notationr(      s    D 058	c	!047	c	!047 147
j3s5)<#=>EEcJKKQ
OC!!C5*<.99r   c                    US:  a(  [        [        U5      [        U5      -   SS9nU SU 3nU$ [        [        U 5      SS9nU$ )Nr      )r$   x)r(   abs)total_paramsshared_paramsexpert_paramsexpert_countpretty_size
size_classs         r   
size_labelr3   *   sY    a9#m:LsS`Oa:anop$~Q{m4
  9\9JWXY
r   c                b   Ub1  UR                  5       R                  SS5      R                  SS5      nO6U b1  U R                  5       R                  SS5      R                  SS5      nOSnUb  SU 3OSnUb#  SUR                  5       R                  SS5       3OSn	Ub#  SUR                  5       R                  SS5       3OSn
Ub1  SUR                  5       R                  SS5      R                  5        3OSnUb#  SUR                  5       R                  SS5       3OSnU U U	 U
 U U 3$ )N -/z
ggml-modelr   )stripreplacer   )
model_name	base_namefinetune_stringversion_stringr3   r   
model_typename
parametersfinetuneversionencodingkinds                r   naming_conventionrE   5   sJ     ((c2::3D		!))#s3;;CE%/%;1ZL!JBQB]?((*223<=>ceH@N@Z.&&(00c:;<`bGFQF];$$&..sC8>>@ABceH9C9OQz!))#s345UWDVJ<z'8*TFCCr   c                  R    \ rS rSr% S\S'   S\S'   S\S'   S\S'   S\S	'   SS
 jrSrg)RemoteTensorL   r    dtypeztuple[int, ...]shapeintoffset_startsizeurlc                ~    [        [        R                  U R                  U R                  U R
                  S95      nU$ )N)rN   startrM   )	bytearraySafetensorRemoteget_data_by_rangerN   rL   rM   )selfdatas     r   rU   RemoteTensor.dataT   s8     );;PTPaPahlhqhq;rsr    N)returnrQ   )__name__
__module____qualname____firstlineno____annotations__rU   __static_attributes__rW   r   r   rG   rG   L   s"    J
I	Hr   rG   c                      \ rS rSrSrSrSr\SS j5       r\SS j5       r	\SS j5       r
\SSS jj5       r\SS	 j5       r\SS
 j5       rSrg)rR   [   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   c                   U R                  U R                   SU S35      nU(       a#  U R                   SU S3nU R                  U5      $ U R                   SU S3nU R                  U5      nU(       a  U R                  US5      nUR	                  S5      n[
        R                  " U5      nUR                  S5      c   S5       eUS   n	[        [        U	R                  5       5      5      n
U
R                  5         0 nU
 HC  nU R                   SU SU 3nU R                  U5      R                  5        H	  u  pXU'   M     ME     U$ [        S	U S
35      e)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)
r7   z/resolve/main/model.safetensorsz*/resolve/main/model.safetensors.index.jsonr   utf-8
weight_mapz"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_tensorsrS   decodejsonloadsgetlistsetvaluessortitems
ValueError)clsmodel_idis_single_filerN   	index_urlis_multiple_files
index_data	index_str
index_jsonrd   	all_filestensorsfilekeyvals                  r   get_list_tensors_hf_model*SafetensorRemote.get_list_tensors_hf_modelq   sr    --0A8*Lk.lm__%Qxj0OPC'',, 'q
2\]	00;..y!<J"))'2II.J>>,/;a=aa;#L1JS!2!2!456INN/1G!)8*N4&I # 4 4S 9 ? ? AHC#&CL !B " N:8* EQ Q
 	
r   c           
     l   U R                  U5      u  p#0 nUR                  5        Hd  u  pVUS:X  a  M  [        U[        5      (       d  [	        SU SU 35      e US   nUS   nUS   u  pX-
  nX9-   n[        U[        U5      XUS9XE'   Mf     U$ ! [         a  n[	        SU SU S	U 35      eS
nAff = f)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': rI   rJ   data_offsets)rI   rJ   rL   rM   rN   z$Missing key in metadata for tensor 'z	, meta = N)get_metadatarp   
isinstancedictrq   rG   tupleKeyError)rr   rN   metadatadata_start_offsetresr?   metarI   rJ   offset_start_relativeoffset_end_relativerM   rL   es                 r   rg   !SafetensorRemote.get_list_tensors   s     '*&6&6s&;#')"..*JD~%dD)) #@c$!PQQeWW=A.=Q:%*B0H(uE%LWctwx	 + 
  e #GvSQRPSS\]a\b!cddes   0B
B3B..B3c                   SnU R                  USU5      n[        U5      S:  a  [        S5      e[        R	                  USS SS9nSU-   n[
        R                  nXV-  S:w  a	  XVXV-  -
  -  n[        U5      SU-   :  a  [        SSU-    S	[        U5       35      eUSSU-    nUR                  S
5      n [        R                  " U5      n	X4$ ! [        R                   a  n
[        SU
 35      eSn
A
ff = f)zb
Get JSON metadata from a remote safetensor file.

Returns tuple of (metadata, data_start_offset)
i  P r   ra   z%Not enough data to read metadata sizeNlittle)	byteorderz'Could not read complete metadata. Need z bytes, got rc   z-Failed to parse safetensor metadata as JSON: )rS   r   rq   rK   
from_bytesrR   	ALIGNMENTrh   ri   rj   JSONDecodeError)rr   rN   	read_sizeraw_datametadata_lengthr   	alignmentmetadata_bytesmetadata_strr   r   s              r   r   SafetensorRemote.get_metadata   s*    $	((a; x=1DEE.."1.J /$..	(A-.?.K!LL x=1..Fq?GZF[[ghklthugvwxx "!A$78%,,W5	Rzz,/H..## 	RLQCPQQ	Rs   6C C6#C11C6c                Z   SSK nSSKJn  U" U5      nUR                  (       a  UR                  (       d  [        SU 35      eU R                  5       nUS:  a  SU SX#-    3US'   UR                  US	US
9nUR                  5         UR                  [        US:  a  U5         $ S5         $ )zh
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: zbytes=r6   RangeTallow_redirectsheaders)requestsurllib.parser   schemenetlocrq   _get_request_headersrk   raise_for_statuscontentslice)	rr   rN   rP   rM   r   r   
parsed_urlr   responses	            r   rS   "SafetensorRemote.get_data_by_range   s     	)c]
  
(9(9}SE233**,"9!'wa~>GG<<T7<K!!# dRid BCCT BCCr   c                >   SSK nSSKJn  U" U5      nUR                  (       a  UR                  (       d  [        SU 35      e U R                  5       nSUS'   UR                  USUS9nS	UR                  s=:*  =(       a    S
:  $ s  $ ! UR                   a     gf = f)z\
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   rq   r   headstatus_codeRequestException)rr   rN   r   r   r   r   r   s          r   re   !SafetensorRemote.check_file_exist   s     	)c]
  
(9(9}SE233	..0G*GG}}S$}PH(..444444(( 		s   AB	 B	 	BBc                    SS0n[         R                  R                  S5      (       a  S[         R                  S    3US'   U$ )z$Prepare common headers for requests.z
User-Agentconvert_hf_to_ggufHF_TOKENzBearer Authorization)osenvironrk   )rr   r   s     r   r   %SafetensorRemote._get_request_headers  sB      !56::>>*%%)0J1G0H'IGO$r   rW   N)rs   r    rX   dict[str, RemoteTensor])rN   r    rX   r   )rN   r    rX   ztuple[dict, int])r   )rN   r    rP   rK   rM   rK   rX   bytes)rN   r    rX   bool)rX   zdict[str, str])rY   rZ   r[   r\   __doc__rf   r   classmethodr   rg   r   rS   re   r   r^   rW   r   r   rR   rR   [   s    $ +KI&
 &
P  6 !R !RF D D*  *  r   rR   )r   r    r   
str | NonerX   r    )r*   )r#   rK   r$   rK   rX   r    )
r-   rK   r.   rK   r/   rK   r0   rK   rX   r    )N)r:   r   r;   r   r<   r   r=   r   r3   r   r   r   r>   zLiteral['vocab', 'LoRA'] | NonerX   r    )
__future__r   dataclassesr   typingr   r   ri   r   r(   r3   rE   rG   rR   rW   r   r   <module>r      sO    " !  	 K:.D.   q qr   