fusion-llm-demo / deployment /export_ggml.py
zhan1206
fix: comprehensive audit fixes - Thinking Dial unification, deployment scripts, README, bilingual filter, data download
bce487e
Raw
History Blame
5.93 kB
"""
GGUF 部署 — 将 FusionModel 导出为 GGUF 格式(用于 llama.cpp)
使用方式:
python deployment/export_gguf.py --checkpoint output/mini_model --output output/gguf/model.gguf
python deployment/export_gguf.py --checkpoint output/mini_model --output output/gguf/model-Q4_K_M.gguf --quantize Q4_K_M
依赖: llama.cpp (自动检测)
"""
import sys
import os
import json
import argparse
import struct
from pathlib import Path
sys.path.insert(0, '.')
def find_llama_cpp():
"""Find llama.cpp installation."""
candidates = [
os.path.expanduser("~/llama.cpp"),
os.path.expanduser("~/src/llama.cpp"),
"/usr/local/bin/llama-cli",
"llama-cli",
]
for c in candidates:
if os.path.isfile(c) or os.path.isdir(c):
return c
# Check PATH
import shutil
if shutil.which("llama-cli") or shutil.which("llama-cpp"):
return shutil.which("llama-cli") or shutil.which("llama-cpp")
return None
def export_to_hf_format(model, output_dir):
"""Export model to HuggingFace format (safetensors + config.json).
This is the canonical intermediate format. Use llama.cpp's convert
script to produce GGUF from this.
"""
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
# Save model using HF's save_pretrained (produces safetensors)
model.save_pretrained(str(output_dir), safe_serialization=True)
# Write tokenizer config for llama.cpp compatibility
tokenizer_config = {
"model_type": "fusion",
"vocab_size": model.config.vocab_size,
"bos_token_id": 1,
"eos_token_id": 2,
"pad_token_id": 0,
}
with open(output_dir / "tokenizer_config.json", "w", encoding="utf-8") as f:
json.dump(tokenizer_config, f, indent=2)
print(f"[EXPORT] HF format saved to {output_dir}")
return output_dir
def convert_to_gguf(hf_dir, output_path, llama_cpp_path=None, quantize=None):
"""Convert HuggingFace format to GGUF using llama.cpp's convert script.
Args:
hf_dir: Path to HF format directory
output_path: Output GGUF file path
llama_cpp_path: Path to llama.cpp installation
quantize: Quantization type (e.g. Q4_K_M, Q5_K_M, Q8_0)
"""
import subprocess
llama_cpp = llama_cpp_path or find_llama_cpp()
if llama_cpp is None:
print("[WARNING] llama.cpp not found. Saving HF format only.")
print(" To convert to GGUF, install llama.cpp and run:")
print(f" python convert_hf_to_gguf.py {hf_dir} --outfile {output_path}")
return False
# Find convert script
convert_script = None
if os.path.isdir(llama_cpp):
for name in ["convert_hf_to_gguf.py", "convert.py"]:
candidate = os.path.join(llama_cpp, name)
if os.path.isfile(candidate):
convert_script = candidate
break
if convert_script is None:
print("[WARNING] llama.cpp convert script not found. Saving HF format only.")
print(f" Manual conversion: python convert_hf_to_gguf.py {hf_dir} --outfile {output_path}")
return False
# Run conversion
cmd = [sys.executable, convert_script, str(hf_dir), "--outfile", str(output_path)]
print(f"[CONVERT] Running: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"[ERROR] Conversion failed: {result.stderr}")
return False
print(f"[CONVERT] GGUF saved to {output_path}")
# Quantize if requested
if quantize and os.path.isdir(llama_cpp):
quantize_bin = os.path.join(llama_cpp, "llama-quantize")
if not os.path.isfile(quantize_bin):
quantize_bin = os.path.join(llama_cpp, "quantize")
if os.path.isfile(quantize_bin):
quantized_path = str(output_path).replace(".gguf", f"-{quantize}.gguf")
cmd = [quantize_bin, str(output_path), quantized_path, quantize]
print(f"[QUANTIZE] Running: {' '.join(cmd)}")
subprocess.run(cmd)
print(f"[QUANTIZE] Quantized model saved to {quantized_path}")
else:
print(f"[WARNING] Quantize binary not found. Skipping quantization.")
return True
def export_gguf(model, output_path, llama_cpp_path=None, quantize=None):
"""Full export pipeline: FusionModel -> HF format -> GGUF.
Args:
model: FusionModel instance
output_path: Output GGUF file path
llama_cpp_path: Path to llama.cpp installation (optional)
quantize: Quantization type (e.g. Q4_K_M)
"""
output_path = Path(output_path)
hf_dir = output_path.parent / "hf_intermediate"
# Step 1: Export to HF format
export_to_hf_format(model, hf_dir)
# Step 2: Convert to GGUF
success = convert_to_gguf(hf_dir, output_path, llama_cpp_path, quantize)
if success:
print(f"\n[DONE] GGUF export complete: {output_path}")
else:
print(f"\n[PARTIAL] HF format saved at {hf_dir}")
print(" Install llama.cpp to complete GGUF conversion.")
return success
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Export FusionModel to GGUF format")
parser.add_argument("--checkpoint", required=True, help="Path to model checkpoint")
parser.add_argument("--output", default="output/gguf/model.gguf", help="Output GGUF path")
parser.add_argument("--llama-cpp", default=None, help="Path to llama.cpp installation")
parser.add_argument("--quantize", default=None, help="Quantization type (Q4_K_M, Q5_K_M, Q8_0)")
args = parser.parse_args()
from models.fusion_model import FusionModel
model = FusionModel.from_pretrained(args.checkpoint)
export_gguf(model, args.output, args.llama_cpp, args.quantize)