o
    
۾i'(                  	   @   sn  d 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
mZmZ ddlmZ ddlmZmZmZ dd	lmZ d
dlmZ eeZedeeB defddZedeeB defddZdZdedefddZdeeB deeef fddZ deeB defddZ!dededB fddZ"deddfddZ#ded edefd!d"Z$	d(d#eeB d$ed%edB defd&d'Z%dS ))zGGUF utility functions.    )cache)PathLike)PathN)KeysVisionProjectorType)GGMLQuantizationType)Gemma3ConfigPretrainedConfigSiglipVisionConfig)init_logger   )list_filtered_repo_filesmodelreturnc              
   C   s   t | } |  s
dS | jdkrdS z| d}|d}W d   n1 s'w   Y  |dkW S  tyJ } ztd| | W Y d}~dS d}~ww )	z"Check if the file is a GGUF model.F.ggufTrb   Ns   GGUFzError reading file %s: %s)r   is_filesuffixopenread	Exceptionloggerdebug)r   fheadere r   V/home/ubuntu/.local/lib/python3.10/site-packages/vllm/transformers_utils/gguf_utils.pycheck_gguf_file   s   

r   c                 C   s4   d}t | } t|| r| dd\}}t|S dS )z*Check if the model is a remote GGUF model.zG^[a-zA-Z0-9][a-zA-Z0-9._-]*/[a-zA-Z0-9][a-zA-Z0-9._-]*:[A-Za-z0-9_+-]+$:r   F)strre	fullmatchrsplitis_valid_gguf_quant_type)r   pattern_
quant_typer   r   r   is_remote_gguf)   s   r)   )_M_S_L_XL_XS_XXSgguf_quant_typec                 C   sT   t t| ddur
dS tD ]}| |r'| dt|  }t t|ddur' dS qdS )zCheck if the quant type is a valid GGUF quant type.

    Supports both exact GGML quant types (e.g., Q4_K, IQ1_S) and
    extended naming conventions (e.g., Q4_K_M, Q3_K_S, Q5_K_L).
    NTF)getattrr   _GGUF_QUANT_SUFFIXESendswithlen)r0   r   	base_typer   r   r   r%   9   s   
r%   c                 C   sH   t | } t| r| dd}|d |d fS td|  dtj dt )z,Split the model into repo_id and quant type.r    r   r   z-Wrong GGUF model or invalid GGUF quant type: zI.
- It should be in repo_id:quant_type format.
- Valid base quant types: z%
- Extended suffixes also supported: )r!   r)   r$   
ValueErrorr   _member_names_r2   )r   partsr   r   r   split_remote_ggufM   s   r9   c                 C   s   t | } t| r
dS t| S )zCheck if the model is a GGUF model.

    Args:
        model: Model name, path, or Path object to check.

    Returns:
        True if the model is a GGUF model, False otherwise.
    T)r!   r   r)   )r   r   r   r   is_gguf[   s   	r:   c                 C   sx   |  dsdS z*t| }| sW dS |j}g d}|D ]}t||}|r.|d   W S qW dS  ty;   Y dS w )zCheck if GGUF model has multimodal projector file.

    Args:
        model: Model path string

    Returns:
        Path to mmproj file if found, None otherwise
    r   N)zmmproj.ggufzmmproj-*.ggufz*mmproj*.ggufr   )r3   r   r   parentlistglobr   )r   
model_path	model_dirmmproj_patternsr&   mmproj_filesr   r   r   detect_gguf_multimodaln   s"   
	rB   mmproj_pathzSiglipVisionConfig | Nonec                 C   sj  t t| }d}|tjj}|r9zt|jd 	d}W n t
tfy8 } ztd| W Y d}~nd}~ww tjjdtftjjdtftjjdtftjjjdtftjjd	tftjjd
tftjjjdtfi}i }| D ]!\}\}}	||}
|
du rtd|  dS |	|
jd ||< qm|tjkrd|d< td tdi |}|rtd| |S td |S )a[  Extract vision config parameters from mmproj.gguf metadata.

    Reads vision encoder configuration from GGUF metadata fields using
    standardized GGUF constants. Automatically detects the projector type
    (e.g., gemma3, llama4) and applies model-specific parameters accordingly.

    The function extracts standard CLIP vision parameters from GGUF metadata
    and applies projector-type-specific customizations. For unknown projector
    types, it uses safe defaults from SiglipVisionConfig.

    Args:
        mmproj_path: Path to mmproj.gguf file (str or Path)

    Returns:
        SiglipVisionConfig if extraction succeeds, None if any required
        field is missing from the GGUF metadata

    Raises:
        Exception: Exceptions from GGUF reading (file not found, corrupted
            file, etc.) propagate directly from gguf.GGUFReader
    Nzutf-8z-Failed to decode projector type from GGUF: %shidden_sizeintermediate_sizenum_hidden_layersnum_attention_heads
image_size
patch_sizelayer_norm_epsz8Missing required vision config field '%s' in mmproj.ggufFvision_use_headz8Detected Gemma3 projector, disabling vision pooling headz=Extracted vision config from mmproj.gguf (projector_type: %s)z1Extracted vision config from mmproj.gguf metadatar   )gguf
GGUFReaderr!   	get_fieldr   ClipPROJECTOR_TYPEbytesr8   decodeAttributeErrorUnicodeDecodeErrorr   warning
ClipVisionEMBEDDING_LENGTHintFEED_FORWARD_LENGTHBLOCK_COUNT	Attention
HEAD_COUNT
IMAGE_SIZE
PATCH_SIZELAYERNORM_EPSfloatitemsr   GEMMA3infor
   )rC   readerprojector_typeprojector_type_fieldr   VISION_CONFIG_FIELDSconfig_paramsgguf_key
param_namedtypefieldconfigr   r   r   extract_vision_config_from_gguf   sP   



ro   	hf_configc                 C   sR   t | }|dur'tt|}| }|jdv }|dur'|r't||dgd}|}|S )aC  Patch HF config for GGUF models.

    Applies GGUF-specific patches to HuggingFace config:
    1. For multimodal models: patches architecture and vision config
    2. For all GGUF models: overrides vocab_size from embedding tensor

    This ensures compatibility with GGUF models that have extended
    vocabularies (e.g., Unsloth) where the GGUF file contains more
    tokens than the HuggingFace tokenizer config specifies.

    Args:
        model: Model path string
        hf_config: HuggingFace config to patch in-place

    Returns:
        Updated HuggingFace config
    N)gemma3gemma3_textGemma3ForConditionalGeneration)text_configvision_configarchitectures)rB   ro   r!   get_text_config
model_typer   )r   rp   rC   ru   rt   	is_gemma3new_hf_configr   r   r   maybe_patch_hf_config_from_gguf   s   
r{   repo_idr(   revisionc                 C   sv   t | } d| dd| dd| dd| dg}t| ||d}t|dkr-td| ||jdd	 d
 |d }|S )as  Get the GGUF file path from HuggingFace Hub based on repo_id and quant_type.

    Args:
        repo_id: The HuggingFace repository ID (e.g., "Qwen/Qwen3-0.6B")
        quant_type: The quantization type (e.g., "Q4_K_M", "F16")
        revision: Optional revision/branch name

    Returns:
        The path to the GGUF file on HuggingFace Hub (e.g., "filename.gguf"),
    z*-r   z-*.ggufz*/*-)allow_patternsr}   r   z:Could not find GGUF file for repo %s with quantization %s.c                 S   s   |  d| fS )N-)count)xr   r   r   <lambda>+  s    z,get_gguf_file_path_from_hf.<locals>.<lambda>)key)r!   r   r4   r6   sort)r|   r(   r}   gguf_patternsmatching_filesgguf_filenamer   r   r   get_gguf_file_path_from_hf  s(   



r   )N)&__doc__	functoolsr   osr   pathlibr   rM   regexr"   gguf.constantsr   r   gguf.quantsr   transformersr   r	   r
   vllm.loggerr   
repo_utilsr   __name__r   r!   boolr   r)   r2   r%   tupler9   r:   rB   ro   r{   r   r   r   r   r   <module>   sN   U
+