Last active
August 21, 2025 01:02
-
-
Save codingstark-dev/263dcf913f9a7e7f83bf3f7f65ae8792 to your computer and use it in GitHub Desktop.
This script automates the conversion of a Hugging Face model into GGUF format and uploads it back to Hugging Face. Step-by-step: Installs dependencies needed for model conversion. Clones llama.cpp (the tool that converts models to GGUF). Downloads the original model from Hugging Face. Converts the model from Hugging Face format → GGUF format (.g…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import subprocess | |
| import sys | |
| from pathlib import Path | |
| from huggingface_hub import snapshot_download, HfApi, upload_file | |
| import shutil | |
| def install_requirements(): | |
| """Install required packages""" | |
| packages = [ | |
| "huggingface_hub", | |
| "torch", | |
| "transformers", | |
| "accelerate", | |
| "sentencepiece", | |
| "protobuf", | |
| "numpy" | |
| ] | |
| for package in packages: | |
| subprocess.check_call([sys.executable, "-m", "pip", "install", package]) | |
| def clone_llama_cpp(): | |
| """Clone llama.cpp repository if not exists""" | |
| if not Path("llama.cpp").exists(): | |
| subprocess.check_call([ | |
| "git", "clone", "https://github.com/ggerganov/llama.cpp.git" | |
| ]) | |
| # Install llama.cpp requirements | |
| requirements_files = [ | |
| "llama.cpp/requirements.txt", | |
| "llama.cpp/requirements/requirements-convert-hf-to-gguf.txt" | |
| ] | |
| for req_file in requirements_files: | |
| if Path(req_file).exists(): | |
| subprocess.check_call([ | |
| sys.executable, "-m", "pip", "install", | |
| "-r", req_file | |
| ]) | |
| break | |
| def find_conversion_script(): | |
| """Find the correct conversion script in llama.cpp directory""" | |
| possible_scripts = [ | |
| "llama.cpp/convert-hf-to-gguf.py", # Most likely location | |
| "llama.cpp/convert_hf_to_gguf.py", # Alternative naming | |
| "llama.cpp/convert.py", # Legacy naming | |
| "llama.cpp/examples/convert-hf-to-gguf.py" # Possible subdirectory | |
| ] | |
| for script_path in possible_scripts: | |
| if Path(script_path).exists(): | |
| return script_path | |
| # If not found, list all python files with 'convert' in name | |
| print("Conversion script not found. Searching for conversion scripts...") | |
| for root, dirs, files in os.walk("llama.cpp"): | |
| for file in files: | |
| if "convert" in file.lower() and file.endswith(".py"): | |
| full_path = os.path.join(root, file) | |
| print(f"Found conversion script: {full_path}") | |
| if "gguf" in file.lower() or "hf" in file.lower(): | |
| return full_path | |
| return None | |
| def download_source_model(model_id, local_dir): | |
| """Download the source model from Hugging Face""" | |
| print(f"Downloading model {model_id}...") | |
| try: | |
| snapshot_download( | |
| repo_id=model_id, | |
| local_dir=local_dir, | |
| token="your token" | |
| ) | |
| print(f"Model downloaded to {local_dir}") | |
| except Exception as e: | |
| print(f"Error downloading model: {e}") | |
| raise | |
| def convert_to_gguf(input_dir, output_file, quantization="f16"): | |
| """Convert model to GGUF format""" | |
| print(f"Converting model to GGUF format...") | |
| # Find the conversion script | |
| convert_script = find_conversion_script() | |
| if not convert_script: | |
| raise FileNotFoundError( | |
| "No GGUF conversion script found in llama.cpp directory. " | |
| "Make sure llama.cpp was cloned correctly." | |
| ) | |
| print(f"Using conversion script: {convert_script}") | |
| # Run conversion - different scripts may have different arguments | |
| if "convert-hf-to-gguf.py" in convert_script or "convert_hf_to_gguf.py" in convert_script: | |
| cmd = [ | |
| sys.executable, convert_script, | |
| input_dir, | |
| "--outfile", output_file, | |
| "--outtype", quantization | |
| ] | |
| else: | |
| # For convert.py or other scripts | |
| cmd = [ | |
| sys.executable, convert_script, | |
| input_dir, | |
| "--outfile", output_file, | |
| "--outtype", quantization | |
| ] | |
| try: | |
| print(f"Running command: {' '.join(cmd)}") | |
| subprocess.check_call(cmd) | |
| print(f"Model converted to {output_file}") | |
| except subprocess.CalledProcessError as e: | |
| print(f"Error during conversion: {e}") | |
| print("Try running the conversion manually to see detailed error messages.") | |
| raise | |
| def create_repository(repo_id, token=None): | |
| """Create repository on Hugging Face""" | |
| print(f"Creating repository {repo_id}...") | |
| api = HfApi(token=token) | |
| try: | |
| api.create_repo( | |
| repo_id=repo_id, | |
| exist_ok=True, | |
| repo_type="model" | |
| ) | |
| print(f"Repository {repo_id} created/verified") | |
| except Exception as e: | |
| print(f"Error creating repository: {e}") | |
| raise | |
| def upload_gguf_model(gguf_file, repo_id, token=None): | |
| """Upload GGUF file to Hugging Face repository""" | |
| print(f"Uploading {gguf_file} to {repo_id}...") | |
| if not Path(gguf_file).exists(): | |
| raise FileNotFoundError(f"GGUF file {gguf_file} not found") | |
| api = HfApi(token=token) | |
| try: | |
| api.upload_file( | |
| path_or_fileobj=gguf_file, | |
| path_in_repo=Path(gguf_file).name, | |
| repo_id=repo_id, | |
| token=token | |
| ) | |
| print(f"Upload completed successfully") | |
| except Exception as e: | |
| print(f"Error uploading file: {e}") | |
| raise | |
| def create_readme(repo_id, original_model, quantization, token=None): | |
| """Create README.md for the repository""" | |
| readme_content = f"""# {repo_id.split('/')[-1]} | |
| **Original model**: [{original_model}](https://huggingface.co/{original_model}) | |
| **Format**: GGUF | |
| **Quantization**: {quantization} | |
| This is a GGUF conversion of the {original_model} model, optimized for use with applications like LM Studio, Ollama, and other GGUF-compatible inference engines. | |
| ## Usage | |
| Load this model in any GGUF-compatible application by referencing the `.gguf` file. | |
| ## Model Details | |
| - **Original Repository**: {original_model} | |
| - **Converted Format**: GGUF | |
| - **Quantization Level**: {quantization} | |
| - **Compatible With**: LM Studio, Ollama, llama.cpp, and other GGUF inference engines | |
| ## Conversion Process | |
| This model was converted using the llama.cpp conversion scripts with the following settings: | |
| - Input format: Hugging Face Transformers | |
| - Output format: GGUF | |
| - Quantization: {quantization} | |
| ## License | |
| Please refer to the original model's license terms. | |
| """ | |
| # Save README temporarily | |
| with open("README.md", "w") as f: | |
| f.write(readme_content) | |
| # Upload README | |
| api = HfApi(token=token) | |
| try: | |
| api.upload_file( | |
| path_or_fileobj="README.md", | |
| path_in_repo="README.md", | |
| repo_id=repo_id, | |
| token=token | |
| ) | |
| print("README.md uploaded successfully") | |
| except Exception as e: | |
| print(f"Error uploading README: {e}") | |
| finally: | |
| # Clean up temp file | |
| if Path("README.md").exists(): | |
| Path("README.md").unlink() | |
| def main(): | |
| # Configuration | |
| SOURCE_MODEL = "Codingstark/gemma3-270m-leetcode" | |
| TARGET_REPO = "Codingstark/gemma3-270m-leetcode-gguf" | |
| LOCAL_MODEL_DIR = "Gemma-3-leetcode-download" | |
| GGUF_OUTPUT_FILE = "Gemma-3-leetcode.gguf" | |
| QUANTIZATION = "bf16" # Options: f16, f32, q8_0, q4_0, q4_1, q5_0, q5_1 | |
| # Get Hugging Face token | |
| hf_token = "your token" | |
| try: | |
| # Step 1: Install requirements | |
| print("Step 1: Installing requirements...") | |
| install_requirements() | |
| # Step 2: Clone llama.cpp | |
| print("\nStep 2: Setting up llama.cpp...") | |
| clone_llama_cpp() | |
| # Step 3: Download source model | |
| print(f"\nStep 3: Downloading source model...") | |
| download_source_model(SOURCE_MODEL, LOCAL_MODEL_DIR) | |
| # Verify model was downloaded | |
| if not Path(LOCAL_MODEL_DIR).exists(): | |
| raise FileNotFoundError(f"Model directory {LOCAL_MODEL_DIR} not found after download") | |
| # Step 4: Convert to GGUF | |
| print(f"\nStep 4: Converting to GGUF...") | |
| convert_to_gguf(LOCAL_MODEL_DIR, GGUF_OUTPUT_FILE, QUANTIZATION) | |
| # Verify GGUF file was created | |
| if not Path(GGUF_OUTPUT_FILE).exists(): | |
| raise FileNotFoundError(f"GGUF file {GGUF_OUTPUT_FILE} not found after conversion") | |
| # Step 5: Create target repository | |
| print(f"\nStep 5: Creating target repository...") | |
| create_repository(TARGET_REPO, hf_token) | |
| # Step 6: Upload GGUF file | |
| print(f"\nStep 6: Uploading GGUF file...") | |
| upload_gguf_model(GGUF_OUTPUT_FILE, TARGET_REPO, hf_token) | |
| # Step 7: Create and upload README | |
| print(f"\nStep 7: Creating documentation...") | |
| create_readme(TARGET_REPO, SOURCE_MODEL, QUANTIZATION, hf_token) | |
| print(f"\n✅ Conversion completed successfully!") | |
| print(f"Model available at: https://huggingface.co/{TARGET_REPO}") | |
| # Cleanup | |
| print(f"\nCleaning up temporary files...") | |
| if Path(LOCAL_MODEL_DIR).exists(): | |
| shutil.rmtree(LOCAL_MODEL_DIR) | |
| if Path(GGUF_OUTPUT_FILE).exists(): | |
| Path(GGUF_OUTPUT_FILE).unlink() | |
| except Exception as e: | |
| print(f"\n❌ Error during conversion: {e}") | |
| print("\nTroubleshooting tips:") | |
| print("1. Ensure git is installed and accessible") | |
| print("2. Check your internet connection") | |
| print("3. Verify your Hugging Face token has the necessary permissions") | |
| print("4. Make sure you have sufficient disk space") | |
| return 1 | |
| return 0 | |
| if __name__ == "__main__": | |
| exit_code = main() | |
| sys.exit(exit_code) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment