
    #;7j4                    $   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Zd)d*dZd+dZd,d-dZe G d d                      Z G d  d!          Ze G d" d#                      Ze G d$ d%                      Z G d& d'          ZdS ).    )annotations)	dataclass)Path)LiteralNfilenamestroutput_type
str | Nonereturnc                    ||                                 nd}||                                nd}|                     |||||          S )N )outtypeftypeOUTTYPEFTYPE)lowerupperformat)r   r	   ftype_lowercaseftype_uppercases       :/home/rurouni/src/llama.cpp-master/gguf-py/gguf/utility.pyfill_templated_filenamer      sb    2=2I;,,...rO2=2I;,,...rO???#2/#2/  K K K       model_params_countint
min_digitsc           
        | dk    r| dz  }d}n#| dk    r| dz  }d}n| dk    r| dz  }d	}n| d
z  }d}t          |t          t          t          |                                        d                    z
  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fixs        r   #model_weight_count_rounded_notationr-      s    D  058	c	!	!047	c	!	!047 147
j3s5)<#=#=>>EEcJJKKKQ
O
OC!9C9999<999r   total_paramsshared_paramsexpert_paramsexpert_countc                    |dk    r6t          t          |          t          |          z   d          }| d| }nt          t          |           d          }|S )Nr   r   )r   x)r-   abs)r.   r/   r0   r1   pretty_size
size_classs         r   
size_labelr7   ,   sl    a9#m:L:LsS`OaOa:anoppp$44{44

8\9J9JWXYYY
r   
model_name	base_namefinetune_stringversion_stringr7   
model_typeLiteral['vocab', 'LoRA'] | Nonec                   |=|                                                     dd                              dd          }nA| =|                                                      dd                              dd          }nd}|d| nd}|+d|                                                     dd           nd}	|+d|                                                     dd           nd}
|=d|                                                     dd                                           nd}|+d|                                                     dd           nd}| | |	 |
 | | S )N -/z
ggml-modelr   )stripreplacer   )r8   r9   r:   r;   r7   r	   r<   name
parametersfinetuneversionencodingkinds                r   naming_conventionrJ   7   s      ((c22::3DD		!!))#s33;;CEE%/%;!Z!!!JBQB]>?((**223<<>>>ceH@N@Z<.&&((00c::<<<`bGFQF]B;$$&&..sC88>>@@BBBceH9C9O5z!!))#s33555UWDCJCC'C8CTCCCr   c                  J    e Zd ZU ded<   ded<   ded<   ded<   ded<   ddZdS )RemoteTensorr   dtypetuple[int, ...]shaper   offset_startsizeurlr   	bytearrayc                x    t          t                              | j        | j        | j                            }|S )N)rR   startrQ   )rS   SafetensorRemoteget_data_by_rangerR   rP   rQ   )selfdatas     r   rY   zRemoteTensor.dataV   s6     );;PTPahlhq;rrssr   N)r   rS   )__name__
__module____qualname____annotations__rY    r   r   rL   rL   N   s]         JJJIIIHHH     r   rL   c                      e Zd ZdZdZedd            Zedd	            Zedd            Zeddd            Z	edd            Z
edd            ZdS )rV   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                   |                      | j         d| d          }|r"| j         d| d}|                     |          S | j         d| d}|                      |          }|r|                     |d          }|                    d          }t          j        |          }|                    d          
J d            |d         }	t          t          |	
                                                    }
|
                                 i }|
D ]C}| j         d| d	| }|                     |                                          D ]
\  }}|||<   D|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)
        rA   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_tensorsrW   decodejsonloadsgetlistsetvaluessortitems
ValueError)clsr`   is_single_filerR   	index_urlis_multiple_files
index_data	index_str
index_jsonrd   	all_filestensorsfilekeyvals                  r   get_list_tensors_hf_modelz*SafetensorRemote.get_list_tensors_hf_modelr   s    --.l.l8.l.l.lmm 	-_PPxPPPC'',,, ]]]]]	00;; 	..y!<<J"))'22II..J>>,//;;=a;;;#L1JS!2!2!4!45566INN/1G! ' 'II8II4II # 4 4S 9 9 ? ? A A ' 'HC#&GCLL'NQ8 Q Q Q
 
 	
r   rR   c           
        |                      |          \  }}i }|                                D ]\  }}|dk    rt          |t                    st	          d| d|           	 |d         }|d         }|d         \  }	}
|
|	z
  }||	z   }t          |t          |          |||          ||<   # t          $ r}t	          d| d| d	|           d
}~ww xY wt          t          |                                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': rM   rO   data_offsets)rM   rO   rP   rQ   rR   z$Missing key in metadata for tensor 'z	, meta = Nc                    | d         S Nr   r^   ts    r   <lambda>z3SafetensorRemote.get_list_tensors.<locals>.<lambda>   s
    QqT r   r|   )	get_metadatarp   
isinstancedictrq   rL   tupleKeyErrorsorted)rr   rR   metadatadata_start_offsetresrD   metarM   rO   offset_start_relativeoffset_end_relativerQ   rP   es                 r   rg   z!SafetensorRemote.get_list_tensors   s^    '*&6&6s&;&;##')"..** 	e 	eJD$~%%dD)) R !P!P!P$!P!PQQQeWW=A.=Q:%':*-BB03HH(uE%LLWcjntwxxxD		 e e e !c!c!cQR!c!c]a!c!cddde
 6#))++>>:::;;
s   &A	B00
C:CCtuple[dict, int]c                   d}|                      |d|          }t          |          dk     rt          d          t                              |dd         d          }d|z   }t          |          d|z   k     r%t          dd|z    d	t          |                     |dd|z            }|                    d
          }	 t          j        |          }||fS # t          j        $ r}	t          d|	           d}	~	ww xY 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 rc   z-Failed to parse safetensor metadata as JSON: )	rW   r'   rq   r   
from_bytesrh   ri   rj   JSONDecodeError)
rr   rR   	read_sizeraw_datametadata_lengthr   metadata_bytesmetadata_strr   r   s
             r   r   zSafetensorRemote.get_metadata   s9    $	((a;; x==1DEEE.."1".JJ / x==1...wq?GZwwhklthuhuwwxxx "!A$7"78%,,W55	Rz,//H...# 	R 	R 	RPQPPQQQ	Rs   C D*C<<DrU   r   rQ   bytesc                X   ddl }ddlm}  ||          }|j        r|j        st          d|           |                                 }|dk    rd| d||z    |d<   |                    |d	|
          }|                                 |j	        t          |dk    r|n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netlocrq   _get_request_headersrk   raise_for_statuscontentslice)	rr   rR   rU   rQ   r   r   
parsed_urlr   responses	            r   rW   z"SafetensorRemote.get_data_by_range   s     	))))))Xc]]
  	4
(9 	42S22333**,,"99>>>>>GG<<T7<KK!!### dRiiddT B BCCr   boolc                   ddl }ddlm}  ||          }|j        r|j        st          d|           	 |                                 }d|d<   |                    |d|          }d	|j        cxk    od
k     nc S # |j	        $ r Y dS w xY 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   rq   r   headstatus_codeRequestException)rr   rR   r   r   r   r   r   s          r   re   z!SafetensorRemote.check_file_exist   s     	))))))Xc]]
  	4
(9 	42S22333	..00G*GG}}S$}PPH(.444444444( 	 	 	55	s   AA= =
B
Bdict[str, str]c                |    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environrk   )rr   r   s     r   r   z%SafetensorRemote._get_request_headers  sD      !56:>>*%% 	J'IJ1G'I'IGO$r   N)r`   r   r   ra   )rR   r   r   ra   )rR   r   r   r   )r   )rR   r   rU   r   rQ   r   r   r   )rR   r   r   r   )r   r   )rZ   r[   r\   __doc__rf   classmethodr~   rg   r   rW   re   r   r^   r   r   rV   rV   ]   s         $ +K&
 &
 &
 [&
P    [> R R R [R@ D D D D [D*    [*    [  r   rV   c                  .    e Zd ZU ded<   ded<   ded<   dS )LocalTensorRanger   r   r   offsetrQ   N)rZ   r[   r\   r]   r^   r   r   r   r     s+         NNNKKKIIIIIr   r   c                  6    e Zd ZU ded<   ded<   ded<   dd	Zd
S )LocalTensorr   rM   rN   rO   r   
data_ranger   
np.ndarrayc                n    t          j        | j        j        d| j        j        | j        j                  S )Nc)moder   rO   )npmemmapr   r   r   rQ   )rX   s    r   
mmap_byteszLocalTensor.mmap_bytes  s,    y1DODZbfbqbvwwwwr   N)r   r   )rZ   r[   r\   r]   r   r^   r   r   r   r     sQ         JJJ    x x x x x xr   r   c                  2    e Zd ZU dZded<   d
dZd Z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]rz   r   r   c                   t          |d          5 }t                              |                    d          d          }t	          j        |          j        }|d|z   k     rt          dd|z    d|           |                    |                              d          }	 t          j
        |          }n)# t          j        $ r}t          d|           d }~ww xY w|                                }i }	|                                D ]s\  }
}|
d	k    rt          |d
         t          |d                   t!          |||d         d         z   |d         d         |d         d         z
                      |	|
<   tt#          t%          |	                                d                     | _        d d d            d S # 1 swxY w Y   d S )Nrbr   r   r   r   r   rc   z.Failed to parse safetensors metadata as JSON: r   rM   rO   r   r      )rM   rO   r   c                    | d         S r   r^   r   s    r   r   z+SafetensorsLocal.__init__.<locals>.<lambda>M  s
    ad r   r   )openr   r   readr   statst_sizerq   rh   ri   rj   r   tellrp   r   r   r   r   r   rz   )rX   r   r%   r   	file_sizer   r   r   r   rz   rD   r   s               r   __init__zSafetensorsLocal.__init__,  s7   (D!!  	MQ!nnQVVAYY(nKKO))1I1... !w1K^!w!wlu!w!wxxx66/2299'BBLW:l33' W W W !URS!U!UVVVW !".0G&nn..  
d>)) +w-W../ )D,@,CC^,Q/$~2Fq2II   ! ! !  w}}NN K K KLLDLA 	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	M  	Ms7   BG$B98G9CCCCGG
Gc                    ~~| j         S N)rz   rX   argskwargss      r   	__enter__zSafetensorsLocal.__enter__O  s    &|r   c                
    ~~d S r   r^   r   s      r   __exit__zSafetensorsLocal.__exit__S  s    &&&r   N)r   r   )rZ   r[   r\   r   r]   r   r   r   r^   r   r   r   r   "  se           $###!M !M !M !MF      r   r   )r   r   r	   r
   r   r   )r   )r   r   r   r   r   r   )
r.   r   r/   r   r0   r   r1   r   r   r   r   )r8   r
   r9   r
   r:   r
   r;   r
   r7   r
   r	   r
   r<   r=   r   r   )
__future__r   dataclassesr   pathlibr   typingr   r   ri   numpyr   r   r-   r7   rJ   rL   rV   r   r   r   r^   r   r   <module>r      s   " " " " " " ! ! ! ! ! !             				     K K K K: : : : :.   D D D D D.        q q q q q q q qh         x x x x x x x x2 2 2 2 2 2 2 2 2 2r   