#!/usr/bin/env python3 """Direct SafeTensors to GGUF converter for unsupported architectures. This script attempts to convert SafeTensors models to GGUF format directly, without relying on llama.cpp's architecture-specific conversion logic. """ from __future__ import annotations import sys import traceback from argparse import ArgumentParser from pathlib import Path from helpers.logger import logger from helpers.services.gguf import GGUFConverter from helpers.utils.config_parser import ConfigParser from helpers.utils.tensor_mapping import TensorMapper def convert_safetensors_to_gguf( model_path: Path, output_path: Path, force_architecture: str | None = None ) -> bool: """Convert SafeTensors model to GGUF format with comprehensive metadata handling. Orchestrates the complete conversion workflow: loads configuration, maps architecture to known GGUF types, creates writer with proper metadata, processes all tensor files with name mapping, and adds tokeniser data. Handles BFloat16 conversion and provides fallback architecture mapping for unsupported model types to ensure maximum compatibility. Returns: True if conversion was successful, False otherwise. """ # Use ConfigParser to load configuration config_parser = ConfigParser() model_config = config_parser.load_model_config(model_path) arch_name = model_config.architectures[0] model_type = model_config.model_type logger.info(f"Architecture: {arch_name}") logger.info(f"Model type: {model_type}") # Use forced architecture or try to map to a known one if force_architecture: arch = force_architecture logger.warning(f"Using forced architecture: {arch}") else: # Use ConfigParser's architecture mapping arch = config_parser.get_architecture_mapping(arch_name) if arch != arch_name: logger.warning(f"Unknown architecture {arch_name}, using {arch} as fallback") # Use the new GGUFConverter for the conversion tensor_mapper = TensorMapper() return GGUFConverter.convert_safetensors( model_path, output_path, model_config, arch, tensor_mapper ) def main() -> None: """Main entry point for SafeTensors to GGUF conversion command-line interface. Parses command-line arguments, validates input paths, and orchestrates the conversion process with proper error handling. Supports forced architecture mapping and flexible output path specification. Provides comprehensive error reporting and exit codes for integration with automated workflows. """ parser = ArgumentParser(description="Convert SafeTensors to GGUF directly") parser.add_argument("model_path", help="Path to SafeTensors model directory") parser.add_argument("-o", "--output", help="Output GGUF file path") parser.add_argument("--force-arch", help="Force a specific architecture mapping") args = parser.parse_args() model_path = Path(args.model_path) if not model_path.exists(): logger.error(f"Model path not found: {model_path}") sys.exit(1) output_path = Path(args.output) if args.output else model_path / f"{model_path.name}-f32.gguf" try: success = convert_safetensors_to_gguf(model_path, output_path, args.force_arch) sys.exit(0 if success else 1) except Exception as e: logger.error(f"Conversion failed: {e}") traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()