chaddy81 commited on
Commit
c6c04af
·
verified ·
1 Parent(s): 0da65ef

Upload convert_grpo_to_gguf.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. convert_grpo_to_gguf.py +188 -0
convert_grpo_to_gguf.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # "sentencepiece>=0.1.99",
10
+ # "protobuf>=3.20.0",
11
+ # "numpy",
12
+ # "gguf",
13
+ # ]
14
+ # ///
15
+
16
+ """GGUF Conversion for GRPO Model - Q8_0 Quantization"""
17
+
18
+ import os
19
+ import torch
20
+ from transformers import AutoModelForCausalLM, AutoTokenizer
21
+ from peft import PeftModel
22
+ from huggingface_hub import HfApi
23
+ import subprocess
24
+
25
+ print("=" * 60)
26
+ print("GGUF Conversion - GRPO Model Q8_0")
27
+ print("=" * 60)
28
+
29
+ # Configuration - GRPO model (built on top of SFT)
30
+ BASE_MODEL = "Qwen/Qwen3-0.6B"
31
+ SFT_ADAPTER = "chaddy81/qwen3-0.6b-multicode-sft"
32
+ GRPO_ADAPTER = "chaddy81/qwen3-0.6b-multicode-grpo"
33
+ OUTPUT_REPO = "chaddy81/qwen3-0.6b-multicode-grpo-gguf"
34
+
35
+ print(f"\n Configuration:")
36
+ print(f" Base model: {BASE_MODEL}")
37
+ print(f" SFT adapter: {SFT_ADAPTER}")
38
+ print(f" GRPO adapter: {GRPO_ADAPTER}")
39
+ print(f" Output repo: {OUTPUT_REPO}")
40
+ print(f" Quantization: Q8_0 (8-bit)")
41
+
42
+ # Step 1: Load base model
43
+ print("\n Step 1: Loading base model...")
44
+ base_model = AutoModelForCausalLM.from_pretrained(
45
+ BASE_MODEL, torch_dtype=torch.float16, device_map="auto", trust_remote_code=True,
46
+ )
47
+ print(" Base model loaded")
48
+
49
+ # Step 2: Load and merge SFT adapter first
50
+ print("\n Step 2: Loading and merging SFT adapter...")
51
+ model = PeftModel.from_pretrained(base_model, SFT_ADAPTER)
52
+ model = model.merge_and_unload()
53
+ print(" SFT adapter merged")
54
+
55
+ # Step 3: Load and merge GRPO adapter on top
56
+ print("\n Step 3: Loading and merging GRPO adapter...")
57
+ model = PeftModel.from_pretrained(model, GRPO_ADAPTER)
58
+ merged_model = model.merge_and_unload()
59
+ print(" GRPO adapter merged")
60
+
61
+ # Step 4: Load tokenizer
62
+ tokenizer = AutoTokenizer.from_pretrained(GRPO_ADAPTER, trust_remote_code=True)
63
+ print(" Tokenizer loaded")
64
+
65
+ # Step 5: Save merged model
66
+ print("\n Step 4: Saving fully merged model...")
67
+ merged_dir = "/tmp/merged_grpo_model"
68
+ merged_model.save_pretrained(merged_dir, safe_serialization=True)
69
+ tokenizer.save_pretrained(merged_dir)
70
+ print(f" Merged model saved to {merged_dir}")
71
+
72
+ # Step 6: Setup llama.cpp
73
+ print("\n Step 5: Setting up llama.cpp...")
74
+ subprocess.run(["apt-get", "update", "-qq"], check=True, capture_output=True)
75
+ subprocess.run(["apt-get", "install", "-y", "-qq", "build-essential", "cmake"], check=True, capture_output=True)
76
+ print(" Build tools installed")
77
+
78
+ subprocess.run(["git", "clone", "--depth", "1", "https://github.com/ggerganov/llama.cpp.git", "/tmp/llama.cpp"], check=True, capture_output=True)
79
+ print(" llama.cpp cloned")
80
+
81
+ subprocess.run(["pip", "install", "-r", "/tmp/llama.cpp/requirements.txt"], check=True, capture_output=True)
82
+ subprocess.run(["pip", "install", "sentencepiece", "protobuf"], check=True, capture_output=True)
83
+ print(" Dependencies installed")
84
+
85
+ # Step 7: Convert to GGUF (FP16)
86
+ print("\n Step 6: Converting to GGUF format...")
87
+ gguf_output_dir = "/tmp/gguf_output"
88
+ os.makedirs(gguf_output_dir, exist_ok=True)
89
+
90
+ model_name = "qwen3-0.6b-multicode-grpo"
91
+ gguf_file = f"{gguf_output_dir}/{model_name}-f16.gguf"
92
+
93
+ result = subprocess.run(
94
+ ["python", "/tmp/llama.cpp/convert_hf_to_gguf.py", merged_dir, "--outfile", gguf_file, "--outtype", "f16"],
95
+ check=True, capture_output=True, text=True
96
+ )
97
+ print(f" FP16 GGUF created")
98
+
99
+ # Step 8: Build quantize and create Q8_0
100
+ print("\n Step 7: Creating Q8_0 quantization...")
101
+ os.makedirs("/tmp/llama.cpp/build", exist_ok=True)
102
+ subprocess.run(
103
+ ["cmake", "-B", "/tmp/llama.cpp/build", "-S", "/tmp/llama.cpp", "-DGGML_CUDA=OFF"],
104
+ check=True, capture_output=True, text=True
105
+ )
106
+ subprocess.run(
107
+ ["cmake", "--build", "/tmp/llama.cpp/build", "--target", "llama-quantize", "-j", "4"],
108
+ check=True, capture_output=True, text=True
109
+ )
110
+ print(" Quantize tool built")
111
+
112
+ quant_file = f"{gguf_output_dir}/{model_name}-q8_0.gguf"
113
+ result = subprocess.run(
114
+ ["/tmp/llama.cpp/build/bin/llama-quantize", gguf_file, quant_file, "Q8_0"],
115
+ check=True, capture_output=True, text=True
116
+ )
117
+ size_mb = os.path.getsize(quant_file) / (1024 * 1024)
118
+ print(f" Q8_0: {size_mb:.1f} MB")
119
+
120
+ # Step 9: Upload
121
+ print("\n Step 8: Uploading to Hub...")
122
+ api = HfApi()
123
+ api.create_repo(repo_id=OUTPUT_REPO, repo_type="model", exist_ok=True)
124
+ print(" Repository ready")
125
+
126
+ api.upload_file(path_or_fileobj=quant_file, path_in_repo=f"{model_name}-q8_0.gguf", repo_id=OUTPUT_REPO)
127
+ print(" Q8_0 uploaded")
128
+
129
+ readme = f"""---
130
+ base_model: {BASE_MODEL}
131
+ tags:
132
+ - gguf
133
+ - llama.cpp
134
+ - quantized
135
+ - trl
136
+ - grpo
137
+ - qwen3
138
+ - code
139
+ ---
140
+
141
+ # {model_name} GGUF
142
+
143
+ GGUF conversion of [{GRPO_ADAPTER}](https://huggingface.co/{GRPO_ADAPTER}).
144
+
145
+ ## Model Details
146
+
147
+ - **Base Model:** {BASE_MODEL}
148
+ - **SFT Model:** {SFT_ADAPTER}
149
+ - **GRPO Model:** {GRPO_ADAPTER}
150
+ - **Training:** SFT on code datasets + GRPO with code execution rewards
151
+ - **Quantization:** Q8_0 (8-bit, high quality)
152
+
153
+ ## Training Pipeline
154
+
155
+ 1. **SFT:** Fine-tuned on Codeforces, Golang, Vue/Nuxt, React datasets
156
+ 2. **GRPO:** Reinforcement learning with code execution rewards (pass/fail on test cases)
157
+
158
+ ## Usage
159
+
160
+ ### With Ollama
161
+
162
+ ```bash
163
+ huggingface-cli download {OUTPUT_REPO} {model_name}-q8_0.gguf
164
+ echo "FROM ./{model_name}-q8_0.gguf" > Modelfile
165
+ ollama create qwen3-grpo -f Modelfile
166
+ ollama run qwen3-grpo
167
+ ```
168
+
169
+ ### With llama.cpp
170
+
171
+ ```bash
172
+ huggingface-cli download {OUTPUT_REPO} {model_name}-q8_0.gguf
173
+ ./llama-cli -m {model_name}-q8_0.gguf -p "Write a Python function to find prime numbers"
174
+ ```
175
+
176
+ ### With LM Studio
177
+
178
+ Download the `.gguf` file and import into LM Studio.
179
+ """
180
+
181
+ api.upload_file(path_or_fileobj=readme.encode(), path_in_repo="README.md", repo_id=OUTPUT_REPO)
182
+ print(" README uploaded")
183
+
184
+ print("\n" + "=" * 60)
185
+ print(" GGUF Conversion Complete!")
186
+ print(f" https://huggingface.co/{OUTPUT_REPO}")
187
+ print(f" huggingface-cli download {OUTPUT_REPO} {model_name}-q8_0.gguf")
188
+ print("=" * 60)