Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	Implement running locally with local GGUF files
Browse filesAlso added architecture related metadata defaults
- README.md +1 -1
- _hf_gguf.py +76 -1
- app.py +124 -20
- requirements.txt +2 -2
    	
        README.md
    CHANGED
    
    | @@ -4,7 +4,7 @@ emoji: 🏢 | |
| 4 | 
             
            colorFrom: blue
         | 
| 5 | 
             
            colorTo: purple
         | 
| 6 | 
             
            sdk: gradio
         | 
| 7 | 
            -
            sdk_version: 5. | 
| 8 | 
             
            python_version: 3.11
         | 
| 9 | 
             
            app_file: app.py
         | 
| 10 | 
             
            pinned: false
         | 
|  | |
| 4 | 
             
            colorFrom: blue
         | 
| 5 | 
             
            colorTo: purple
         | 
| 6 | 
             
            sdk: gradio
         | 
| 7 | 
            +
            sdk_version: 5.25.2
         | 
| 8 | 
             
            python_version: 3.11
         | 
| 9 | 
             
            app_file: app.py
         | 
| 10 | 
             
            pinned: false
         | 
    	
        _hf_gguf.py
    CHANGED
    
    | @@ -71,6 +71,8 @@ class GGUFValueType(IntEnum): | |
| 71 |  | 
| 72 |  | 
| 73 | 
             
            standard_metadata = {
         | 
|  | |
|  | |
| 74 | 
             
                "general.type": (GGUFValueType.STRING, "model"),
         | 
| 75 | 
             
                "general.architecture": (GGUFValueType.STRING, "llama"),
         | 
| 76 | 
             
                "general.quantization_version": (GGUFValueType.UINT32, 2),
         | 
| @@ -141,6 +143,79 @@ standard_metadata = { | |
| 141 | 
             
            }
         | 
| 142 |  | 
| 143 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 144 | 
             
            deprecated_metadata = {
         | 
| 145 | 
             
                "tokenizer.ggml.prefix_token_id",
         | 
| 146 | 
             
                "tokenizer.ggml.suffix_token_id",
         | 
| @@ -374,7 +449,7 @@ class HuggingGGUFstream: | |
| 374 | 
             
                        if (alignment := self.metadata.get('general.alignment')) is not None:
         | 
| 375 | 
             
                            self.alignment = alignment.value
         | 
| 376 |  | 
| 377 | 
            -
                        self.metaend = self.fp.loc
         | 
| 378 | 
             
                        self.offset = self.metaend % self.alignment
         | 
| 379 |  | 
| 380 | 
             
                def adjust_padding(
         | 
|  | |
| 71 |  | 
| 72 |  | 
| 73 | 
             
            standard_metadata = {
         | 
| 74 | 
            +
                "adapter.type": (GGUFValueType.STRING, "lora"),
         | 
| 75 | 
            +
                "adapter.lora.alpha": (GGUFValueType.FLOAT32, 16),
         | 
| 76 | 
             
                "general.type": (GGUFValueType.STRING, "model"),
         | 
| 77 | 
             
                "general.architecture": (GGUFValueType.STRING, "llama"),
         | 
| 78 | 
             
                "general.quantization_version": (GGUFValueType.UINT32, 2),
         | 
|  | |
| 143 | 
             
            }
         | 
| 144 |  | 
| 145 |  | 
| 146 | 
            +
            standard_metadata_architecture = {
         | 
| 147 | 
            +
                "{arch}.vocab_size": (GGUFValueType.UINT32, 0),
         | 
| 148 | 
            +
                "{arch}.context_length": (GGUFValueType.UINT32, 0),
         | 
| 149 | 
            +
                "{arch}.embedding_length": (GGUFValueType.UINT32, 0),
         | 
| 150 | 
            +
                "{arch}.features_length": (GGUFValueType.UINT32, 0),
         | 
| 151 | 
            +
                "{arch}.block_count": (GGUFValueType.UINT32, 0),
         | 
| 152 | 
            +
                "{arch}.leading_dense_block_count": (GGUFValueType.UINT32, 0),
         | 
| 153 | 
            +
                "{arch}.feed_forward_length": (GGUFValueType.UINT32, 0),
         | 
| 154 | 
            +
                "{arch}.expert_feed_forward_length": (GGUFValueType.UINT32, 0),
         | 
| 155 | 
            +
                "{arch}.expert_shared_feed_forward_length": (GGUFValueType.UINT32, 0),
         | 
| 156 | 
            +
                "{arch}.use_parallel_residual": (GGUFValueType.BOOL, False),
         | 
| 157 | 
            +
                "{arch}.tensor_data_layout": (GGUFValueType.STRING, "Meta AI original pth"),
         | 
| 158 | 
            +
                "{arch}.expert_count": (GGUFValueType.UINT32, 0),
         | 
| 159 | 
            +
                "{arch}.expert_used_count": (GGUFValueType.UINT32, 0),
         | 
| 160 | 
            +
                "{arch}.expert_shared_count": (GGUFValueType.UINT32, 0),
         | 
| 161 | 
            +
                "{arch}.expert_weights_scale": (GGUFValueType.FLOAT32, 1),
         | 
| 162 | 
            +
                "{arch}.expert_weights_norm": (GGUFValueType.BOOL, False),
         | 
| 163 | 
            +
                "{arch}.expert_gating_func": (GGUFValueType.UINT32, 1),
         | 
| 164 | 
            +
                "{arch}.pooling_type": (GGUFValueType.UINT32, 0),
         | 
| 165 | 
            +
                "{arch}.logit_scale": (GGUFValueType.FLOAT32, 1),
         | 
| 166 | 
            +
                "{arch}.decoder_start_token_id": (GGUFValueType.UINT32, 0),
         | 
| 167 | 
            +
                "{arch}.attn_logit_softcapping": (GGUFValueType.FLOAT32, 0),
         | 
| 168 | 
            +
                "{arch}.final_logit_softcapping": (GGUFValueType.FLOAT32, 0),
         | 
| 169 | 
            +
                "{arch}.swin_norm": (GGUFValueType.BOOL, False),
         | 
| 170 | 
            +
                "{arch}.rescale_every_n_layers": (GGUFValueType.UINT32, 0),
         | 
| 171 | 
            +
                "{arch}.time_mix_extra_dim": (GGUFValueType.UINT32, 0),
         | 
| 172 | 
            +
                "{arch}.time_decay_extra_dim": (GGUFValueType.UINT32, 0),
         | 
| 173 | 
            +
                "{arch}.residual_scale": (GGUFValueType.FLOAT32, 1),
         | 
| 174 | 
            +
                "{arch}.embedding_scale": (GGUFValueType.FLOAT32, 1),
         | 
| 175 | 
            +
                "{arch}.token_shift_count": (GGUFValueType.UINT32, 0),
         | 
| 176 | 
            +
                "{arch}.interleave_moe_layer_step": (GGUFValueType.UINT32, 0),
         | 
| 177 | 
            +
                "{arch}.attention.head_count": (GGUFValueType.UINT32, 0),
         | 
| 178 | 
            +
                "{arch}.attention.head_count_kv": (GGUFValueType.UINT32, 0),
         | 
| 179 | 
            +
                "{arch}.attention.max_alibi_bias": (GGUFValueType.FLOAT32, 0),
         | 
| 180 | 
            +
                "{arch}.attention.clamp_kqv": (GGUFValueType.FLOAT32, 0),
         | 
| 181 | 
            +
                "{arch}.attention.key_length": (GGUFValueType.UINT32, 0),
         | 
| 182 | 
            +
                "{arch}.attention.value_length": (GGUFValueType.UINT32, 0),
         | 
| 183 | 
            +
                "{arch}.attention.layer_norm_epsilon": (GGUFValueType.FLOAT32, 0),
         | 
| 184 | 
            +
                "{arch}.attention.layer_norm_rms_epsilon": (GGUFValueType.FLOAT32, 0),
         | 
| 185 | 
            +
                "{arch}.attention.group_norm_epsilon": (GGUFValueType.FLOAT32, 0),
         | 
| 186 | 
            +
                "{arch}.attention.group_norm_groups": (GGUFValueType.UINT32, 0),
         | 
| 187 | 
            +
                "{arch}.attention.causal": (GGUFValueType.BOOL, False),
         | 
| 188 | 
            +
                "{arch}.attention.q_lora_rank": (GGUFValueType.UINT32, 0),
         | 
| 189 | 
            +
                "{arch}.attention.kv_lora_rank": (GGUFValueType.UINT32, 0),
         | 
| 190 | 
            +
                "{arch}.attention.decay_lora_rank": (GGUFValueType.UINT32, 0),
         | 
| 191 | 
            +
                "{arch}.attention.iclr_lora_rank": (GGUFValueType.UINT32, 0),
         | 
| 192 | 
            +
                "{arch}.attention.value_residual_mix_lora_rank": (GGUFValueType.UINT32, 0),
         | 
| 193 | 
            +
                "{arch}.attention.gate_lora_rank": (GGUFValueType.UINT32, 0),
         | 
| 194 | 
            +
                "{arch}.attention.relative_buckets_count": (GGUFValueType.UINT32, 0),
         | 
| 195 | 
            +
                "{arch}.attention.sliding_window": (GGUFValueType.UINT32, 0),
         | 
| 196 | 
            +
                "{arch}.attention.scale": (GGUFValueType.FLOAT32, 1),
         | 
| 197 | 
            +
                "{arch}.rope.dimension_count": (GGUFValueType.UINT32, 0),
         | 
| 198 | 
            +
                "{arch}.rope.dimension_sections": (GGUFValueType.UINT32, []),
         | 
| 199 | 
            +
                "{arch}.rope.freq_base": (GGUFValueType.FLOAT32, 0),
         | 
| 200 | 
            +
                "{arch}.rope.scaling.type": (GGUFValueType.STRING, "none"),
         | 
| 201 | 
            +
                "{arch}.rope.scaling.factor": (GGUFValueType.FLOAT32, 1),
         | 
| 202 | 
            +
                "{arch}.rope.scaling.attn_factor": (GGUFValueType.FLOAT32, 1),
         | 
| 203 | 
            +
                "{arch}.rope.scaling.original_context_length": (GGUFValueType.UINT32, 0),
         | 
| 204 | 
            +
                "{arch}.rope.scaling.finetuned": (GGUFValueType.BOOL, False),
         | 
| 205 | 
            +
                "{arch}.rope.scaling.yarn_log_multiplier": (GGUFValueType.FLOAT32, 1),
         | 
| 206 | 
            +
                "{arch}.ssm.conv_kernel": (GGUFValueType.UINT32, 0),
         | 
| 207 | 
            +
                "{arch}.ssm.inner_size": (GGUFValueType.UINT32, 0),
         | 
| 208 | 
            +
                "{arch}.ssm.state_size": (GGUFValueType.UINT32, 0),
         | 
| 209 | 
            +
                "{arch}.ssm.time_step_rank": (GGUFValueType.UINT32, 0),
         | 
| 210 | 
            +
                "{arch}.ssm.dt_b_c_rms": (GGUFValueType.BOOL, False),
         | 
| 211 | 
            +
                "{arch}.wkv.head_size": (GGUFValueType.UINT32, 0),
         | 
| 212 | 
            +
                "{arch}.posnet.embedding_length": (GGUFValueType.UINT32, 0),
         | 
| 213 | 
            +
                "{arch}.posnet.block_count": (GGUFValueType.UINT32, 0),
         | 
| 214 | 
            +
                "{arch}.convnext.embedding_length": (GGUFValueType.UINT32, 0),
         | 
| 215 | 
            +
                "{arch}.convnext.block_count": (GGUFValueType.UINT32, 0),
         | 
| 216 | 
            +
            }
         | 
| 217 | 
            +
             | 
| 218 | 
            +
             | 
| 219 | 
             
            deprecated_metadata = {
         | 
| 220 | 
             
                "tokenizer.ggml.prefix_token_id",
         | 
| 221 | 
             
                "tokenizer.ggml.suffix_token_id",
         | 
|  | |
| 449 | 
             
                        if (alignment := self.metadata.get('general.alignment')) is not None:
         | 
| 450 | 
             
                            self.alignment = alignment.value
         | 
| 451 |  | 
| 452 | 
            +
                        self.metaend = self.fp.loc if hasattr(self.fp, 'loc') else self.fp.tell()
         | 
| 453 | 
             
                        self.offset = self.metaend % self.alignment
         | 
| 454 |  | 
| 455 | 
             
                def adjust_padding(
         | 
    	
        app.py
    CHANGED
    
    | @@ -1,6 +1,8 @@ | |
| 1 | 
             
            import gradio as gr
         | 
| 2 | 
             
            import json
         | 
|  | |
| 3 | 
             
            import posixpath
         | 
|  | |
| 4 | 
             
            from fastapi import HTTPException, Path, Query, Request
         | 
| 5 | 
             
            from fastapi.responses import StreamingResponse
         | 
| 6 | 
             
            from gradio_huggingfacehub_search import HuggingfaceHubSearch
         | 
| @@ -8,8 +10,15 @@ from huggingface_hub import HfApi, HfFileSystem, auth_check | |
| 8 | 
             
            from typing import Annotated, Any, NamedTuple
         | 
| 9 | 
             
            from urllib.parse import urlencode
         | 
| 10 |  | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 13 |  | 
| 14 |  | 
| 15 | 
             
            hfapi = HfApi()
         | 
| @@ -78,21 +87,27 @@ with gr.Blocks( | |
| 78 | 
             
                            search_type = "model",
         | 
| 79 | 
             
                            sumbit_on_select = True,
         | 
| 80 | 
             
                            scale = 2,
         | 
|  | |
| 81 | 
             
                        )
         | 
| 82 |  | 
| 83 | 
             
                        hf_branch = gr.Dropdown(
         | 
| 84 | 
             
                            None,
         | 
| 85 | 
             
                            label = "Branch",
         | 
| 86 | 
             
                            scale = 1,
         | 
|  | |
| 87 | 
             
                        )
         | 
| 88 |  | 
| 89 | 
             
                        gr.LoginButton(
         | 
| 90 | 
             
                            "Sign in to access gated/private repos",
         | 
| 91 | 
             
                            scale = 1,
         | 
|  | |
| 92 | 
             
                        )
         | 
| 93 |  | 
| 94 | 
             
                    hf_file = FileExplorer(
         | 
| 95 | 
            -
                         | 
|  | |
|  | |
|  | |
| 96 | 
             
                    )
         | 
| 97 |  | 
| 98 | 
             
                    with gr.Row():
         | 
| @@ -203,6 +218,8 @@ with gr.Blocks( | |
| 203 | 
             
                        column_widths = ["35%", "15%", "50%"],
         | 
| 204 | 
             
                        wrap = True,
         | 
| 205 | 
             
                        interactive = False,
         | 
|  | |
|  | |
| 206 | 
             
                        visible = False,
         | 
| 207 | 
             
                    )
         | 
| 208 |  | 
| @@ -212,6 +229,46 @@ with gr.Blocks( | |
| 212 |  | 
| 213 | 
             
            An advanced GGUF editor, reading GGUF files directly from Hugging Face repositories and applying changes to your own copies.
         | 
| 214 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 215 | 
             
            Below you will find a collection of example use-cases to show you how to perform a few common GGUF editing operations:
         | 
| 216 | 
             
                        """,
         | 
| 217 | 
             
                    )
         | 
| @@ -678,7 +735,7 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 678 | 
             
                        hf_file: FileExplorer(
         | 
| 679 | 
             
                            "**/*.gguf",
         | 
| 680 | 
             
                            file_count = "single",
         | 
| 681 | 
            -
                            root_dir = repo,
         | 
| 682 | 
             
                            branch = branch,
         | 
| 683 | 
             
                            token = oauth_token.token if oauth_token else False,
         | 
| 684 | 
             
                            visible = True,
         | 
| @@ -815,9 +872,12 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 815 | 
             
                    if not repo_file:
         | 
| 816 | 
             
                        return
         | 
| 817 |  | 
| 818 | 
            -
                     | 
| 819 | 
            -
                         | 
| 820 | 
            -
                     | 
|  | |
|  | |
|  | |
| 821 |  | 
| 822 | 
             
                    try:
         | 
| 823 | 
             
                        progress(0, desc = 'Loading file...')
         | 
| @@ -829,11 +889,18 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 829 | 
             
                            cache_type = "readahead",
         | 
| 830 | 
             
                        ) as fp:
         | 
| 831 | 
             
                            progress(0, desc = 'Reading header...')
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 832 | 
             
                            gguf = HuggingGGUFstream(fp)
         | 
| 833 | 
             
                            num_metadata = gguf.header['metadata'].value
         | 
| 834 | 
             
                            metadata = gguf.read_metadata()
         | 
| 835 |  | 
| 836 | 
            -
                            meta.var['repo_file'] = repo_file
         | 
| 837 | 
             
                            meta.var['branch'] = branch
         | 
| 838 |  | 
| 839 | 
             
                            for k, v in progress.tqdm(metadata, desc = 'Reading metadata...', total = num_metadata, unit = f' of {num_metadata} metadata keys...'):
         | 
| @@ -861,10 +928,15 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 861 | 
             
                        )
         | 
| 862 | 
             
                        return
         | 
| 863 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
| 864 | 
             
                    yield {
         | 
| 865 | 
             
                        meta_state: meta,
         | 
| 866 | 
             
                        meta_keys: gr.Dropdown(
         | 
| 867 | 
            -
                            sorted(meta.key.keys() |  | 
| 868 | 
             
                            value = '',
         | 
| 869 | 
             
                            visible = True,
         | 
| 870 | 
             
                        ),
         | 
| @@ -892,8 +964,12 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 892 | 
             
                    meta: MetadataState,
         | 
| 893 | 
             
                    key: str | None,
         | 
| 894 | 
             
                ):
         | 
|  | |
|  | |
|  | |
|  | |
| 895 | 
             
                    typ = None
         | 
| 896 | 
            -
                    if (val := meta.key.get(key, standard_metadata.get(key))) is not None:
         | 
| 897 | 
             
                        typ = GGUFValueType(val[0]).name
         | 
| 898 | 
             
                    elif key:
         | 
| 899 | 
             
                        if key.startswith('tokenizer.chat_template.'):
         | 
| @@ -944,7 +1020,11 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 944 | 
             
                    val = None
         | 
| 945 | 
             
                    tokens = meta.key.get('tokenizer.ggml.tokens', (-1, []))[1]
         | 
| 946 |  | 
| 947 | 
            -
                     | 
|  | |
|  | |
|  | |
|  | |
| 948 | 
             
                        typ = data[0]
         | 
| 949 | 
             
                        val = data[1]
         | 
| 950 | 
             
                    elif not key:
         | 
| @@ -1048,9 +1128,17 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 1048 | 
             
                    for k, v in meta.key.items():
         | 
| 1049 | 
             
                        m.append([*human_readable_metadata(meta, k, v[0], v[1])])
         | 
| 1050 |  | 
| 1051 | 
            -
                     | 
| 1052 | 
            -
             | 
| 1053 | 
            -
                         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 1054 |  | 
| 1055 | 
             
                    permalink = None
         | 
| 1056 | 
             
                    if meta.rem or meta.add:
         | 
| @@ -1063,9 +1151,13 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 1063 | 
             
                            safe = '[]{}:"\',',
         | 
| 1064 | 
             
                        )
         | 
| 1065 |  | 
| 1066 | 
            -
                        if len(permalink) > 8192:
         | 
| 1067 | 
             
                            permalink = None
         | 
| 1068 |  | 
|  | |
|  | |
|  | |
|  | |
| 1069 | 
             
                    return {
         | 
| 1070 | 
             
                        meta_state: meta,
         | 
| 1071 | 
             
                        meta_changes: gr.HighlightedText(
         | 
| @@ -1076,7 +1168,7 @@ Any framework based on `llama-cpp-python` will let you select which chat templat | |
| 1076 | 
             
                            m,
         | 
| 1077 | 
             
                        ),
         | 
| 1078 | 
             
                        meta_keys: gr.Dropdown(
         | 
| 1079 | 
            -
                            sorted(meta.key.keys() |  | 
| 1080 | 
             
                            value = '',
         | 
| 1081 | 
             
                        ),
         | 
| 1082 | 
             
                        meta_permalink: gr.Markdown(
         | 
| @@ -1409,9 +1501,12 @@ def stream_repo_file( | |
| 1409 | 
             
                rem_meta: list[str] | None,
         | 
| 1410 | 
             
                token: str | None = None,
         | 
| 1411 | 
             
            ):
         | 
| 1412 | 
            -
                 | 
| 1413 | 
            -
                     | 
| 1414 | 
            -
                 | 
|  | |
|  | |
|  | |
| 1415 |  | 
| 1416 | 
             
                with fs.open(
         | 
| 1417 | 
             
                    repo_file,
         | 
| @@ -1426,6 +1521,12 @@ def stream_repo_file( | |
| 1426 | 
             
                    if not add_meta:
         | 
| 1427 | 
             
                        add_meta = []
         | 
| 1428 |  | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 1429 | 
             
                    gguf = HuggingGGUFstream(fp)
         | 
| 1430 | 
             
                    for _ in gguf.read_metadata():
         | 
| 1431 | 
             
                        pass
         | 
| @@ -1489,12 +1590,15 @@ if __name__ == "__main__": | |
| 1489 | 
             
                ):
         | 
| 1490 | 
             
                    token = request.session.get('oauth_info', {}).get('access_token')
         | 
| 1491 |  | 
| 1492 | 
            -
                    if posixpath.normpath(repo_file) != repo_file or '\\' in repo_file or repo_file.startswith('../') or repo_file.startswith('/') or repo_file.count('/') < 2:
         | 
| 1493 | 
             
                        raise HTTPException(
         | 
| 1494 | 
             
                            status_code = 404,
         | 
| 1495 | 
             
                            detail = 'Invalid repository',
         | 
| 1496 | 
             
                        )
         | 
| 1497 |  | 
|  | |
|  | |
|  | |
| 1498 | 
             
                    if session and state is not None and session in request.app.state_holder and state in request.app.state_holder[session]:
         | 
| 1499 | 
             
                        meta: MetadataState = request.app.state_holder[session][state]
         | 
| 1500 |  | 
|  | |
| 1 | 
             
            import gradio as gr
         | 
| 2 | 
             
            import json
         | 
| 3 | 
            +
            import os
         | 
| 4 | 
             
            import posixpath
         | 
| 5 | 
            +
            import sys
         | 
| 6 | 
             
            from fastapi import HTTPException, Path, Query, Request
         | 
| 7 | 
             
            from fastapi.responses import StreamingResponse
         | 
| 8 | 
             
            from gradio_huggingfacehub_search import HuggingfaceHubSearch
         | 
|  | |
| 10 | 
             
            from typing import Annotated, Any, NamedTuple
         | 
| 11 | 
             
            from urllib.parse import urlencode
         | 
| 12 |  | 
| 13 | 
            +
            local_folder = None
         | 
| 14 | 
            +
            if len(sys.argv) == 2:
         | 
| 15 | 
            +
                from fsspec.implementations.local import LocalFileSystem
         | 
| 16 | 
            +
                from gradio import FileExplorer
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                local_folder = posixpath.normpath(os.path.abspath(os.path.expanduser(sys.argv[1])).replace('\\', '/'))
         | 
| 19 | 
            +
            else:
         | 
| 20 | 
            +
                from _hf_explorer import FileExplorer
         | 
| 21 | 
            +
            from _hf_gguf import standard_metadata, standard_metadata_architecture, deprecated_metadata, TokenType, LlamaFileType, GGUFValueType, HuggingGGUFstream
         | 
| 22 |  | 
| 23 |  | 
| 24 | 
             
            hfapi = HfApi()
         | 
|  | |
| 87 | 
             
                            search_type = "model",
         | 
| 88 | 
             
                            sumbit_on_select = True,
         | 
| 89 | 
             
                            scale = 2,
         | 
| 90 | 
            +
                            visible = not local_folder,
         | 
| 91 | 
             
                        )
         | 
| 92 |  | 
| 93 | 
             
                        hf_branch = gr.Dropdown(
         | 
| 94 | 
             
                            None,
         | 
| 95 | 
             
                            label = "Branch",
         | 
| 96 | 
             
                            scale = 1,
         | 
| 97 | 
            +
                            visible = not local_folder,
         | 
| 98 | 
             
                        )
         | 
| 99 |  | 
| 100 | 
             
                        gr.LoginButton(
         | 
| 101 | 
             
                            "Sign in to access gated/private repos",
         | 
| 102 | 
             
                            scale = 1,
         | 
| 103 | 
            +
                            visible = not local_folder,
         | 
| 104 | 
             
                        )
         | 
| 105 |  | 
| 106 | 
             
                    hf_file = FileExplorer(
         | 
| 107 | 
            +
                        "**/*.gguf",
         | 
| 108 | 
            +
                        file_count = "single",
         | 
| 109 | 
            +
                        root_dir = local_folder,
         | 
| 110 | 
            +
                        visible = bool(local_folder),
         | 
| 111 | 
             
                    )
         | 
| 112 |  | 
| 113 | 
             
                    with gr.Row():
         | 
|  | |
| 218 | 
             
                        column_widths = ["35%", "15%", "50%"],
         | 
| 219 | 
             
                        wrap = True,
         | 
| 220 | 
             
                        interactive = False,
         | 
| 221 | 
            +
                        show_search = "filter",
         | 
| 222 | 
            +
                        show_copy_button = True,
         | 
| 223 | 
             
                        visible = False,
         | 
| 224 | 
             
                    )
         | 
| 225 |  | 
|  | |
| 229 |  | 
| 230 | 
             
            An advanced GGUF editor, reading GGUF files directly from Hugging Face repositories and applying changes to your own copies.
         | 
| 231 |  | 
| 232 | 
            +
            <details>
         | 
| 233 | 
            +
            <summary>Running the editor locally</summary>
         | 
| 234 | 
            +
             | 
| 235 | 
            +
            * Clone the space
         | 
| 236 | 
            +
              ```bash
         | 
| 237 | 
            +
              git clone https://huggingface.co/spaces/CISCai/gguf-editor
         | 
| 238 | 
            +
              cd gguf-editor
         | 
| 239 | 
            +
              ```
         | 
| 240 | 
            +
            * Create a virtual environment
         | 
| 241 | 
            +
              ```bash
         | 
| 242 | 
            +
              python3 -m venv .venv
         | 
| 243 | 
            +
              ```
         | 
| 244 | 
            +
            * Install dependencies
         | 
| 245 | 
            +
              ```
         | 
| 246 | 
            +
              .venv/bin/pip install -r requirements.txt
         | 
| 247 | 
            +
              ```
         | 
| 248 | 
            +
            * Gradio requires a HF_TOKEN for the LoginButton/OAuth, so log in to Hugging Face
         | 
| 249 | 
            +
              ```
         | 
| 250 | 
            +
              .venv/bin/huggingface-cli login
         | 
| 251 | 
            +
              ```
         | 
| 252 | 
            +
            * Start the server
         | 
| 253 | 
            +
              ```
         | 
| 254 | 
            +
              .venv/bin/python app.py
         | 
| 255 | 
            +
              ```
         | 
| 256 | 
            +
            * Browse to http://localhost:7860
         | 
| 257 | 
            +
             | 
| 258 | 
            +
            </details>
         | 
| 259 | 
            +
             | 
| 260 | 
            +
            <details>
         | 
| 261 | 
            +
            <summary>Editing local GGUF files</summary>
         | 
| 262 | 
            +
             | 
| 263 | 
            +
            * Set up the application locally (see above)
         | 
| 264 | 
            +
            * Start the server with additional parameter
         | 
| 265 | 
            +
              ```
         | 
| 266 | 
            +
              .venv/bin/python app.py "path/to/gguf/folder"
         | 
| 267 | 
            +
              ```
         | 
| 268 | 
            +
            * Browse to http://localhost:7860
         | 
| 269 | 
            +
             | 
| 270 | 
            +
            </details>
         | 
| 271 | 
            +
             | 
| 272 | 
             
            Below you will find a collection of example use-cases to show you how to perform a few common GGUF editing operations:
         | 
| 273 | 
             
                        """,
         | 
| 274 | 
             
                    )
         | 
|  | |
| 735 | 
             
                        hf_file: FileExplorer(
         | 
| 736 | 
             
                            "**/*.gguf",
         | 
| 737 | 
             
                            file_count = "single",
         | 
| 738 | 
            +
                            root_dir = local_folder or repo,
         | 
| 739 | 
             
                            branch = branch,
         | 
| 740 | 
             
                            token = oauth_token.token if oauth_token else False,
         | 
| 741 | 
             
                            visible = True,
         | 
|  | |
| 872 | 
             
                    if not repo_file:
         | 
| 873 | 
             
                        return
         | 
| 874 |  | 
| 875 | 
            +
                    if local_folder:
         | 
| 876 | 
            +
                        fs = LocalFileSystem()
         | 
| 877 | 
            +
                    else:
         | 
| 878 | 
            +
                        fs = HfFileSystem(
         | 
| 879 | 
            +
                            token = oauth_token.token if oauth_token else None,
         | 
| 880 | 
            +
                        )
         | 
| 881 |  | 
| 882 | 
             
                    try:
         | 
| 883 | 
             
                        progress(0, desc = 'Loading file...')
         | 
|  | |
| 889 | 
             
                            cache_type = "readahead",
         | 
| 890 | 
             
                        ) as fp:
         | 
| 891 | 
             
                            progress(0, desc = 'Reading header...')
         | 
| 892 | 
            +
             | 
| 893 | 
            +
                            if local_folder:
         | 
| 894 | 
            +
                                fp.details = fs.ls(
         | 
| 895 | 
            +
                                    repo_file,
         | 
| 896 | 
            +
                                    detail = True,
         | 
| 897 | 
            +
                                )[0]
         | 
| 898 | 
            +
             | 
| 899 | 
             
                            gguf = HuggingGGUFstream(fp)
         | 
| 900 | 
             
                            num_metadata = gguf.header['metadata'].value
         | 
| 901 | 
             
                            metadata = gguf.read_metadata()
         | 
| 902 |  | 
| 903 | 
            +
                            meta.var['repo_file'] = repo_file[len(local_folder) + 1:] if local_folder else repo_file
         | 
| 904 | 
             
                            meta.var['branch'] = branch
         | 
| 905 |  | 
| 906 | 
             
                            for k, v in progress.tqdm(metadata, desc = 'Reading metadata...', total = num_metadata, unit = f' of {num_metadata} metadata keys...'):
         | 
|  | |
| 928 | 
             
                        )
         | 
| 929 | 
             
                        return
         | 
| 930 |  | 
| 931 | 
            +
                    model_architecture = meta.key.get('general.architecture', (None, None))[1]
         | 
| 932 | 
            +
                    standard_metakeys = set(standard_metadata.keys())
         | 
| 933 | 
            +
                    if model_architecture:
         | 
| 934 | 
            +
                        standard_metakeys |= set(k.format(arch = model_architecture) for k in standard_metadata_architecture.keys())
         | 
| 935 | 
            +
             | 
| 936 | 
             
                    yield {
         | 
| 937 | 
             
                        meta_state: meta,
         | 
| 938 | 
             
                        meta_keys: gr.Dropdown(
         | 
| 939 | 
            +
                            sorted(meta.key.keys() | standard_metakeys),
         | 
| 940 | 
             
                            value = '',
         | 
| 941 | 
             
                            visible = True,
         | 
| 942 | 
             
                        ),
         | 
|  | |
| 964 | 
             
                    meta: MetadataState,
         | 
| 965 | 
             
                    key: str | None,
         | 
| 966 | 
             
                ):
         | 
| 967 | 
            +
                    default_metadata = None
         | 
| 968 | 
            +
                    if model_architecture := meta.key.get('general.architecture', (None, None))[1]:
         | 
| 969 | 
            +
                        default_metadata = standard_metadata_architecture.get(key.replace(model_architecture + '.', '{arch}.'))
         | 
| 970 | 
            +
             | 
| 971 | 
             
                    typ = None
         | 
| 972 | 
            +
                    if (val := meta.key.get(key, standard_metadata.get(key, default_metadata))) is not None:
         | 
| 973 | 
             
                        typ = GGUFValueType(val[0]).name
         | 
| 974 | 
             
                    elif key:
         | 
| 975 | 
             
                        if key.startswith('tokenizer.chat_template.'):
         | 
|  | |
| 1020 | 
             
                    val = None
         | 
| 1021 | 
             
                    tokens = meta.key.get('tokenizer.ggml.tokens', (-1, []))[1]
         | 
| 1022 |  | 
| 1023 | 
            +
                    default_metadata = None
         | 
| 1024 | 
            +
                    if model_architecture := meta.key.get('general.architecture', (None, None))[1]:
         | 
| 1025 | 
            +
                        default_metadata = standard_metadata_architecture.get(key.replace(model_architecture + '.', '{arch}.'))
         | 
| 1026 | 
            +
             | 
| 1027 | 
            +
                    if (data := meta.key.get(key, standard_metadata.get(key, default_metadata))) is not None:
         | 
| 1028 | 
             
                        typ = data[0]
         | 
| 1029 | 
             
                        val = data[1]
         | 
| 1030 | 
             
                    elif not key:
         | 
|  | |
| 1128 | 
             
                    for k, v in meta.key.items():
         | 
| 1129 | 
             
                        m.append([*human_readable_metadata(meta, k, v[0], v[1])])
         | 
| 1130 |  | 
| 1131 | 
            +
                    query_params = {
         | 
| 1132 | 
            +
                        'branch': meta.var['branch'],
         | 
| 1133 | 
            +
                        'session': request.session_hash,
         | 
| 1134 | 
            +
                        'state': str(meta_state._id),
         | 
| 1135 | 
            +
                    }
         | 
| 1136 | 
            +
             | 
| 1137 | 
            +
                    if not query_params['branch'] or query_params['branch'] == 'main':
         | 
| 1138 | 
            +
                        del query_params['branch']
         | 
| 1139 | 
            +
             | 
| 1140 | 
            +
                    link = request.request.url_for('download', repo_file = meta.var['repo_file']).include_query_params(**query_params)
         | 
| 1141 | 
            +
                    link = 'https' + str(link)[4:] if link.hostname not in ('localhost', '127.0.0.1', '::1') and link.scheme == 'http' else str(link)
         | 
| 1142 |  | 
| 1143 | 
             
                    permalink = None
         | 
| 1144 | 
             
                    if meta.rem or meta.add:
         | 
|  | |
| 1151 | 
             
                            safe = '[]{}:"\',',
         | 
| 1152 | 
             
                        )
         | 
| 1153 |  | 
| 1154 | 
            +
                        if len(permalink) > 8192 or local_folder:
         | 
| 1155 | 
             
                            permalink = None
         | 
| 1156 |  | 
| 1157 | 
            +
                    standard_metakeys = set(standard_metadata.keys())
         | 
| 1158 | 
            +
                    if model_architecture := meta.key.get('general.architecture', (None, None))[1]:
         | 
| 1159 | 
            +
                        standard_metakeys |= set(k.format(arch = model_architecture) for k in standard_metadata_architecture.keys())
         | 
| 1160 | 
            +
             | 
| 1161 | 
             
                    return {
         | 
| 1162 | 
             
                        meta_state: meta,
         | 
| 1163 | 
             
                        meta_changes: gr.HighlightedText(
         | 
|  | |
| 1168 | 
             
                            m,
         | 
| 1169 | 
             
                        ),
         | 
| 1170 | 
             
                        meta_keys: gr.Dropdown(
         | 
| 1171 | 
            +
                            sorted(meta.key.keys() | standard_metakeys),
         | 
| 1172 | 
             
                            value = '',
         | 
| 1173 | 
             
                        ),
         | 
| 1174 | 
             
                        meta_permalink: gr.Markdown(
         | 
|  | |
| 1501 | 
             
                rem_meta: list[str] | None,
         | 
| 1502 | 
             
                token: str | None = None,
         | 
| 1503 | 
             
            ):
         | 
| 1504 | 
            +
                if local_folder:
         | 
| 1505 | 
            +
                    fs = LocalFileSystem()
         | 
| 1506 | 
            +
                else:
         | 
| 1507 | 
            +
                    fs = HfFileSystem(
         | 
| 1508 | 
            +
                        token = token,
         | 
| 1509 | 
            +
                    )
         | 
| 1510 |  | 
| 1511 | 
             
                with fs.open(
         | 
| 1512 | 
             
                    repo_file,
         | 
|  | |
| 1521 | 
             
                    if not add_meta:
         | 
| 1522 | 
             
                        add_meta = []
         | 
| 1523 |  | 
| 1524 | 
            +
                    if local_folder:
         | 
| 1525 | 
            +
                        fp.details = fs.ls(
         | 
| 1526 | 
            +
                            repo_file,
         | 
| 1527 | 
            +
                            detail = True,
         | 
| 1528 | 
            +
                        )[0]
         | 
| 1529 | 
            +
             | 
| 1530 | 
             
                    gguf = HuggingGGUFstream(fp)
         | 
| 1531 | 
             
                    for _ in gguf.read_metadata():
         | 
| 1532 | 
             
                        pass
         | 
|  | |
| 1590 | 
             
                ):
         | 
| 1591 | 
             
                    token = request.session.get('oauth_info', {}).get('access_token')
         | 
| 1592 |  | 
| 1593 | 
            +
                    if posixpath.normpath(repo_file) != repo_file or '\\' in repo_file or ':' in repo_file or repo_file.startswith('../') or repo_file.startswith('/') or (repo_file.count('/') < 2 and not local_folder):
         | 
| 1594 | 
             
                        raise HTTPException(
         | 
| 1595 | 
             
                            status_code = 404,
         | 
| 1596 | 
             
                            detail = 'Invalid repository',
         | 
| 1597 | 
             
                        )
         | 
| 1598 |  | 
| 1599 | 
            +
                    if local_folder:
         | 
| 1600 | 
            +
                        repo_file = os.path.join(local_folder, repo_file)
         | 
| 1601 | 
            +
             | 
| 1602 | 
             
                    if session and state is not None and session in request.app.state_holder and state in request.app.state_holder[session]:
         | 
| 1603 | 
             
                        meta: MetadataState = request.app.state_holder[session][state]
         | 
| 1604 |  | 
    	
        requirements.txt
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            huggingface_hub==0. | 
| 3 | 
             
            # gradio_huggingfacehub_search==0.0.8
         | 
| 4 | 
             
            https://huggingface.co/spaces/CISCai/chat-template-editor/resolve/main/gradio_huggingfacehub_search-0.0.8-py3-none-any.whl
         | 
|  | |
| 1 | 
            +
            gradio[oauth]==5.25.2
         | 
| 2 | 
            +
            huggingface_hub==0.30.2
         | 
| 3 | 
             
            # gradio_huggingfacehub_search==0.0.8
         | 
| 4 | 
             
            https://huggingface.co/spaces/CISCai/chat-template-editor/resolve/main/gradio_huggingfacehub_search-0.0.8-py3-none-any.whl
         |