evalstate HF Staff commited on
Commit
c287f39
ยท
verified ยท
1 Parent(s): b6a400a

Upload convert_to_gguf.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. convert_to_gguf.py +279 -0
convert_to_gguf.py ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # dependencies = [
4
+ # "transformers>=4.36.0",
5
+ # "peft>=0.7.0",
6
+ # "torch>=2.0.0",
7
+ # "accelerate>=0.24.0",
8
+ # "huggingface_hub>=0.20.0",
9
+ # ]
10
+ # ///
11
+
12
+ import os
13
+ import torch
14
+ from transformers import AutoModelForCausalLM, AutoTokenizer
15
+ from peft import PeftModel
16
+ from huggingface_hub import HfApi, snapshot_download
17
+ import subprocess
18
+
19
+ print("๐Ÿ”„ GGUF Conversion Script")
20
+ print("=" * 60)
21
+
22
+ # Configuration
23
+ ADAPTER_MODEL = "evalstate/qwen-capybara-medium"
24
+ BASE_MODEL = "Qwen/Qwen2.5-0.5B"
25
+ OUTPUT_MODEL_NAME = "evalstate/qwen-capybara-medium-gguf"
26
+ username = os.environ.get("HF_USERNAME", "evalstate")
27
+
28
+ print(f"\n๐Ÿ“ฆ Configuration:")
29
+ print(f" Base model: {BASE_MODEL}")
30
+ print(f" Adapter model: {ADAPTER_MODEL}")
31
+ print(f" Output repo: {OUTPUT_MODEL_NAME}")
32
+
33
+ # Step 1: Load base model and adapter
34
+ print("\n๐Ÿ”ง Step 1: Loading base model and LoRA adapter...")
35
+ print(" (This may take a few minutes)")
36
+
37
+ base_model = AutoModelForCausalLM.from_pretrained(
38
+ BASE_MODEL,
39
+ torch_dtype=torch.float16,
40
+ device_map="auto",
41
+ trust_remote_code=True,
42
+ )
43
+ print(" โœ… Base model loaded")
44
+
45
+ # Load and merge adapter
46
+ print(" Loading LoRA adapter...")
47
+ model = PeftModel.from_pretrained(base_model, ADAPTER_MODEL)
48
+ print(" โœ… Adapter loaded")
49
+
50
+ print(" Merging adapter with base model...")
51
+ merged_model = model.merge_and_unload()
52
+ print(" โœ… Models merged!")
53
+
54
+ # Load tokenizer
55
+ tokenizer = AutoTokenizer.from_pretrained(ADAPTER_MODEL, trust_remote_code=True)
56
+ print(" โœ… Tokenizer loaded")
57
+
58
+ # Step 2: Save merged model temporarily
59
+ print("\n๐Ÿ’พ Step 2: Saving merged model...")
60
+ merged_dir = "/tmp/merged_model"
61
+ merged_model.save_pretrained(merged_dir, safe_serialization=True)
62
+ tokenizer.save_pretrained(merged_dir)
63
+ print(f" โœ… Merged model saved to {merged_dir}")
64
+
65
+ # Step 3: Install llama.cpp for conversion
66
+ print("\n๐Ÿ“ฅ Step 3: Setting up llama.cpp for GGUF conversion...")
67
+ print(" Cloning llama.cpp repository...")
68
+ subprocess.run(
69
+ ["git", "clone", "https://github.com/ggerganov/llama.cpp.git", "/tmp/llama.cpp"],
70
+ check=True,
71
+ capture_output=True
72
+ )
73
+ print(" โœ… llama.cpp cloned")
74
+
75
+ print(" Installing Python dependencies...")
76
+ subprocess.run(
77
+ ["pip", "install", "-r", "/tmp/llama.cpp/requirements.txt"],
78
+ check=True,
79
+ capture_output=True
80
+ )
81
+ print(" โœ… Dependencies installed")
82
+
83
+ # Step 4: Convert to GGUF (FP16)
84
+ print("\n๐Ÿ”„ Step 4: Converting to GGUF format (FP16)...")
85
+ gguf_output_dir = "/tmp/gguf_output"
86
+ os.makedirs(gguf_output_dir, exist_ok=True)
87
+
88
+ convert_script = "/tmp/llama.cpp/convert_hf_to_gguf.py"
89
+ gguf_file = f"{gguf_output_dir}/qwen-capybara-medium-f16.gguf"
90
+
91
+ subprocess.run(
92
+ [
93
+ "python", convert_script,
94
+ merged_dir,
95
+ "--outfile", gguf_file,
96
+ "--outtype", "f16"
97
+ ],
98
+ check=True
99
+ )
100
+ print(f" โœ… FP16 GGUF created: {gguf_file}")
101
+
102
+ # Step 5: Quantize to different formats
103
+ print("\nโš™๏ธ Step 5: Creating quantized versions...")
104
+ quantize_bin = "/tmp/llama.cpp/llama-quantize"
105
+
106
+ # Build quantize tool first
107
+ print(" Building quantize tool...")
108
+ subprocess.run(
109
+ ["make", "-C", "/tmp/llama.cpp", "llama-quantize"],
110
+ check=True,
111
+ capture_output=True
112
+ )
113
+ print(" โœ… Quantize tool built")
114
+
115
+ # Common quantization formats
116
+ quant_formats = [
117
+ ("Q4_K_M", "4-bit, medium quality (recommended)"),
118
+ ("Q5_K_M", "5-bit, higher quality"),
119
+ ("Q8_0", "8-bit, very high quality"),
120
+ ]
121
+
122
+ quantized_files = []
123
+ for quant_type, description in quant_formats:
124
+ print(f" Creating {quant_type} quantization ({description})...")
125
+ quant_file = f"{gguf_output_dir}/qwen-capybara-medium-{quant_type.lower()}.gguf"
126
+
127
+ subprocess.run(
128
+ [quantize_bin, gguf_file, quant_file, quant_type],
129
+ check=True,
130
+ capture_output=True
131
+ )
132
+ quantized_files.append((quant_file, quant_type))
133
+
134
+ # Get file size
135
+ size_mb = os.path.getsize(quant_file) / (1024 * 1024)
136
+ print(f" โœ… {quant_type}: {size_mb:.1f} MB")
137
+
138
+ # Step 6: Upload to Hub
139
+ print("\nโ˜๏ธ Step 6: Uploading to Hugging Face Hub...")
140
+ api = HfApi()
141
+
142
+ # Create repo
143
+ print(f" Creating repository: {OUTPUT_MODEL_NAME}")
144
+ try:
145
+ api.create_repo(repo_id=OUTPUT_MODEL_NAME, repo_type="model", exist_ok=True)
146
+ print(" โœ… Repository created")
147
+ except Exception as e:
148
+ print(f" โ„น๏ธ Repository may already exist: {e}")
149
+
150
+ # Upload FP16 version
151
+ print(" Uploading FP16 GGUF...")
152
+ api.upload_file(
153
+ path_or_fileobj=gguf_file,
154
+ path_in_repo="qwen-capybara-medium-f16.gguf",
155
+ repo_id=OUTPUT_MODEL_NAME,
156
+ )
157
+ print(" โœ… FP16 uploaded")
158
+
159
+ # Upload quantized versions
160
+ for quant_file, quant_type in quantized_files:
161
+ print(f" Uploading {quant_type}...")
162
+ api.upload_file(
163
+ path_or_fileobj=quant_file,
164
+ path_in_repo=f"qwen-capybara-medium-{quant_type.lower()}.gguf",
165
+ repo_id=OUTPUT_MODEL_NAME,
166
+ )
167
+ print(f" โœ… {quant_type} uploaded")
168
+
169
+ # Create README
170
+ print("\n๐Ÿ“ Creating README...")
171
+ readme_content = f"""---
172
+ base_model: {BASE_MODEL}
173
+ tags:
174
+ - gguf
175
+ - llama.cpp
176
+ - quantized
177
+ - trl
178
+ - sft
179
+ ---
180
+
181
+ # {OUTPUT_MODEL_NAME.split('/')[-1]}
182
+
183
+ This is a GGUF conversion of [{ADAPTER_MODEL}](https://huggingface.co/{ADAPTER_MODEL}), which is a LoRA fine-tuned version of [{BASE_MODEL}](https://huggingface.co/{BASE_MODEL}).
184
+
185
+ ## Model Details
186
+
187
+ - **Base Model:** {BASE_MODEL}
188
+ - **Fine-tuned Model:** {ADAPTER_MODEL}
189
+ - **Training:** Supervised Fine-Tuning (SFT) with TRL
190
+ - **Format:** GGUF (for llama.cpp, Ollama, LM Studio, etc.)
191
+
192
+ ## Available Quantizations
193
+
194
+ | File | Quant | Size | Description | Use Case |
195
+ |------|-------|------|-------------|----------|
196
+ | qwen-capybara-medium-f16.gguf | F16 | ~1GB | Full precision | Best quality, slower |
197
+ | qwen-capybara-medium-q8_0.gguf | Q8_0 | ~500MB | 8-bit | High quality |
198
+ | qwen-capybara-medium-q5_k_m.gguf | Q5_K_M | ~350MB | 5-bit medium | Good quality, smaller |
199
+ | qwen-capybara-medium-q4_k_m.gguf | Q4_K_M | ~300MB | 4-bit medium | Recommended - good balance |
200
+
201
+ ## Usage
202
+
203
+ ### With llama.cpp
204
+
205
+ ```bash
206
+ # Download model
207
+ huggingface-cli download {OUTPUT_MODEL_NAME} qwen-capybara-medium-q4_k_m.gguf
208
+
209
+ # Run with llama.cpp
210
+ ./llama-cli -m qwen-capybara-medium-q4_k_m.gguf -p "Your prompt here"
211
+ ```
212
+
213
+ ### With Ollama
214
+
215
+ 1. Create a `Modelfile`:
216
+ ```
217
+ FROM ./qwen-capybara-medium-q4_k_m.gguf
218
+ ```
219
+
220
+ 2. Create the model:
221
+ ```bash
222
+ ollama create qwen-capybara -f Modelfile
223
+ ollama run qwen-capybara
224
+ ```
225
+
226
+ ### With LM Studio
227
+
228
+ 1. Download the `.gguf` file
229
+ 2. Import into LM Studio
230
+ 3. Start chatting!
231
+
232
+ ## Training Details
233
+
234
+ This model was fine-tuned using:
235
+ - **Dataset:** trl-lib/Capybara (1,000 examples)
236
+ - **Method:** Supervised Fine-Tuning with LoRA
237
+ - **Epochs:** 3
238
+ - **LoRA rank:** 16
239
+ - **Hardware:** A10G Large GPU
240
+
241
+ ## License
242
+
243
+ Inherits the license from the base model: {BASE_MODEL}
244
+
245
+ ## Citation
246
+
247
+ ```bibtex
248
+ @misc{{qwen-capybara-medium-gguf,
249
+ author = {{{username}}},
250
+ title = {{Qwen Capybara Medium GGUF}},
251
+ year = {{2025}},
252
+ publisher = {{Hugging Face}},
253
+ url = {{https://huggingface.co/{OUTPUT_MODEL_NAME}}}
254
+ }}
255
+ ```
256
+
257
+ ---
258
+
259
+ *Converted to GGUF format using llama.cpp*
260
+ """
261
+
262
+ api.upload_file(
263
+ path_or_fileobj=readme_content.encode(),
264
+ path_in_repo="README.md",
265
+ repo_id=OUTPUT_MODEL_NAME,
266
+ )
267
+ print(" โœ… README uploaded")
268
+
269
+ print("\n" + "=" * 60)
270
+ print("โœ… GGUF Conversion Complete!")
271
+ print(f"๐Ÿ“ฆ Repository: https://huggingface.co/{OUTPUT_MODEL_NAME}")
272
+ print("\n๐Ÿ“ฅ Download with:")
273
+ print(f" huggingface-cli download {OUTPUT_MODEL_NAME} qwen-capybara-medium-q4_k_m.gguf")
274
+ print("\n๐Ÿš€ Use with Ollama:")
275
+ print(" 1. Download the GGUF file")
276
+ print(" 2. Create Modelfile: FROM ./qwen-capybara-medium-q4_k_m.gguf")
277
+ print(" 3. ollama create qwen-capybara -f Modelfile")
278
+ print(" 4. ollama run qwen-capybara")
279
+ print("=" * 60)