@@ -2,7 +2,6 @@ package convert
22
33import (
44 "encoding/binary"
5- "fmt"
65 "math"
76 "os"
87 "path/filepath"
@@ -13,87 +12,14 @@ import (
1312type ProgressFunc func (step string , current , total int )
1413
1514// Convert converts SafeTensors model files in modelDir to a GGUF file.
16- // Each architecture has a dedicated Go converter. For architectures without
17- // a Go converter, it falls back to the official llama.cpp convert_hf_to_gguf.py .
15+ // Conversion is delegated to the official llama.cpp convert_hf_to_gguf.py
16+ // so users only need one consistent conversion path .
1817func Convert (modelDir string , progress ProgressFunc ) (string , error ) {
1918 if progress == nil {
2019 progress = func (string , int , int ) {}
2120 }
2221
23- progress ("Reading model configuration" , 0 , 0 )
24-
25- cfg , err := loadModelConfig (modelDir )
26- if err != nil {
27- return "" , fmt .Errorf ("loading config: %w" , err )
28- }
29-
30- hfArch := cfg .Architectures [0 ]
31- ggufArch , ok := detectGGUFArch (hfArch )
32- if ! ok {
33- return ConvertPython (modelDir , progress )
34- }
35-
36- converter := getConverter (ggufArch , cfg )
37- if converter == nil {
38- return ConvertPython (modelDir , progress )
39- }
40-
41- progress ("Scanning SafeTensors files" , 0 , 0 )
42-
43- stFiles , err := scanSafeTensorsFiles (modelDir )
44- if err != nil {
45- return "" , fmt .Errorf ("scanning SafeTensors: %w" , err )
46- }
47-
48- sources := collectTensors (stFiles )
49-
50- progress ("Parsing tokenizer" , 0 , 0 )
51-
52- tok , err := parseTokenizer (modelDir , hfArch )
53- if err != nil {
54- return "" , fmt .Errorf ("parsing tokenizer: %w" , err )
55- }
56-
57- if cfg .VocabSize > len (tok .Tokens ) {
58- for i := len (tok .Tokens ); i < cfg .VocabSize ; i ++ {
59- tok .Tokens = append (tok .Tokens , fmt .Sprintf ("[PAD%d]" , i ))
60- tok .Scores = append (tok .Scores , - 1 )
61- tok .Types = append (tok .Types , tokenTypeUserDefined )
62- }
63- }
64-
65- progress ("Building GGUF" , 0 , 0 )
66-
67- writer := newGGUFWriter ()
68- converter .WriteKV (writer , cfg )
69- writeTokenizerKV (writer , tok , cfg )
70-
71- if err := converter .ConvertTensors (writer , sources , cfg , progress ); err != nil {
72- return "" , fmt .Errorf ("converting tensors: %w" , err )
73- }
74-
75- idx := findKVIndex (writer .kvs , "general.file_type" )
76- if idx >= 0 {
77- writer .kvs [idx ].value = uint32 (1 ) // GGML_FTYPE_MOSTLY_F16
78- }
79-
80- outputName := generateOutputName (modelDir , cfg )
81- outputPath := filepath .Join (modelDir , outputName )
82- tmpPath := outputPath + ".tmp"
83-
84- progress ("Writing GGUF file" , 0 , 0 )
85-
86- if err := writer .writeTo (tmpPath ); err != nil {
87- os .Remove (tmpPath )
88- return "" , fmt .Errorf ("writing GGUF: %w" , err )
89- }
90-
91- if err := os .Rename (tmpPath , outputPath ); err != nil {
92- os .Remove (tmpPath )
93- return "" , fmt .Errorf ("finalizing GGUF: %w" , err )
94- }
95-
96- return outputPath , nil
22+ return ConvertPython (modelDir , progress )
9723}
9824
9925// HasGGUF checks if a GGUF file already exists in the model directory.
0 commit comments