Skill 14 · Huggingface LLM Trainer
Subchapter 14.1
references/gguf_conversion.mdMarkdown10 KBView on GitHub
After training models with TRL on Hugging Face Jobs, convert them to GGUF format for use with llama.cpp, Ollama, LM Studio, and other local inference tools.
This guide provides production-ready, tested code based on successful conversions. All critical dependencies and build steps are included.
Scripts
Convert To GgufGGUF (GPT-Generated Unified Format):
Convert when:
Based on production testing, these are essential for reliable conversion:
Before cloning llama.cpp, install build dependencies:
subprocess.run(["apt-get", "update", "-qq"], check=True, capture_output=True)
subprocess.run(["apt-get", "install", "-y", "-qq", "build-essential", "cmake"], check=True, capture_output=True)Why: The quantization tool requires gcc and cmake. Installing after cloning doesn’t help.
Build the quantize tool with CMake:
# Create build directory
os.makedirs("/tmp/llama.cpp/build", exist_ok=True)
# Configure
subprocess.run([
"cmake", "-B", "/tmp/llama.cpp/build", "-S", "/tmp/llama.cpp",
"-DGGML_CUDA=OFF" # Faster build, CUDA not needed for quantization
], check=True, capture_output=True, text=True)
# Build
subprocess.run([
"cmake", "--build", "/tmp/llama.cpp/build",
"--target", "llama-quantize", "-j", "4"
], check=True, capture_output=True, text=True)
# Binary path
quantize_bin = "/tmp/llama.cpp/build/bin/llama-quantize"Why: CMake is more reliable than make and produces consistent binary paths.
PEP 723 header must include:
# /// script
# dependencies = [
# "transformers>=4.36.0",
# "peft>=0.7.0",
# "torch>=2.0.0",
# "accelerate>=0.24.0",
# "huggingface_hub>=0.20.0",
# "sentencepiece>=0.1.99", # Required for tokenizer
# "protobuf>=3.20.0", # Required for tokenizer
# "numpy",
# "gguf",
# ]
# ///Why: sentencepiece and protobuf are critical for tokenizer conversion. Missing them causes silent failures.
Always verify repos exist:
# Before submitting job, verify:
hub_repo_details([ADAPTER_MODEL], repo_type="model")
hub_repo_details([BASE_MODEL], repo_type="model")Why: Non-existent dataset/model names cause job failures that could be caught in seconds.
See scripts/convert_to_gguf.py for the complete, production-ready script.
Key features:
# Before submitting: VERIFY MODELS EXIST
hub_repo_details(["username/my-finetuned-model"], repo_type="model")
hub_repo_details(["Qwen/Qwen2.5-0.5B"], repo_type="model")
# Submit conversion job
hf_jobs("uv", {
"script": open("trl/scripts/convert_to_gguf.py").read(), # Or inline the script
"flavor": "a10g-large",
"timeout": "45m",
"secrets": {"HF_TOKEN": "$HF_TOKEN"},
"env": {
"ADAPTER_MODEL": "username/my-finetuned-model",
"BASE_MODEL": "Qwen/Qwen2.5-0.5B",
"OUTPUT_REPO": "username/my-model-gguf",
"HF_USERNAME": "username" # Optional, for README
}
})The script performs these steps:
llama-quantizeCommon quantization formats (from smallest to largest):
| Format | Size | Quality | Use Case |
|---|---|---|---|
| Q4_K_M | ~300MB | Good | Recommended - best balance of size/quality |
| Q5_K_M | ~350MB | Better | Higher quality, slightly larger |
| Q8_0 | ~500MB | Very High | Near-original quality |
| F16 | ~1GB | Original | Full precision, largest file |
Recommendation: Create Q4_K_M, Q5_K_M, and Q8_0 versions to give users options.
For conversion:
Time estimates:
GGUF models work on both CPU and GPU. They’re optimized for CPU inference but can also leverage GPU acceleration when available.
# Download GGUF
hf download username/my-model-gguf model-q4_k_m.gguf
# Create Modelfile
echo "FROM ./model-q4_k_m.gguf" > Modelfile
# Create and run (uses GPU automatically if available)
ollama create my-model -f Modelfile
ollama run my-model# CPU only
./llama-cli -m model-q4_k_m.gguf -p "Your prompt"
# With GPU acceleration (offload 32 layers to GPU)
./llama-cli -m model-q4_k_m.gguf -ngl 32 -p "Your prompt".gguf filehub_repo_details)Fix:
device_map="auto" for automatic placementdtype=torch.float16 or torch.bfloat16Fix:
git clone --depth 1 https://github.com/ggerganov/llama.cpp.gitFix:
apt-get install build-essential cmake/tmp/llama.cpp/build/bin/llama-quantizeFix:
"sentencepiece>=0.1.99", "protobuf>=3.20.0"Fix:
"timeout": "1h"These are from production testing and real failures:
Lesson: Don’t assume repos/datasets exist. Check first.
# BEFORE submitting job
hub_repo_details(["trl-lib/argilla-dpo-mix-7k"], repo_type="dataset") # Would catch errorPrevented failures: Non-existent dataset names, typos in model names
Lesson: Default to what’s most likely to succeed.
Prevented failures: Build failures, missing binaries
Lesson: Don’t remove dependencies or steps. Scripts should work as a unit.
Prevented failures: Missing tokenizer libraries, build tool failures
In this skill:
scripts/convert_to_gguf.py - Complete, production-ready scriptExternal:
Critical checklist for GGUF conversion:
scripts/convert_to_gguf.py/tmp/llama.cpp/build/bin/llama-quantizeThe script in scripts/convert_to_gguf.py incorporates all these lessons and has been tested successfully in production.