char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
41361c859
char/aliceai-t5-moe
1#include "ggml.h" 2#include "ggml-alloc.h" 3#include "gguf.h" 4 5#include "arg.h" 6#include "common.h" 7 8#include <clocale> 9#include <map> 10#include <vector> 11#include <string> 12#include <fstream> 13 14static bool g_verbose = false; 15 16struct tensor_transformation { 17struct ggml_tensor * in ; 18struct ggml_tensor * out ; 19bool is_copy ; 20}; 21 22static std::string get_kv_str (struct gguf_context * ctx_gguf ,const std::string & key ){ 23int id = gguf_find_key (ctx_gguf ,key .c_str ()); 24return id < 0 ?"" : std::string (gguf_get_val_str (ctx_gguf ,id )); 25} 26 27static float get_kv_f32 (struct gguf_context * ctx_gguf ,const std::string & key ) { 28int id = gguf_find_key (ctx_gguf ,key .c_str ()); 29return id < 0 ?0.0f :gguf_get_val_f32 (ctx_gguf ,id ); 30} 31 32static void zeros (std::ofstream & file ,size_t n ) { 33char zero = 0 ; 34for (size_t i = 0 ;i < n ;++ i ) { 35file .write (& zero ,1 ); 36 } 37} 38 39static std::string ggml_ne_string (const ggml_tensor * t ) { 40 std::string str ; 41for (int i = 0 ;i < GGML_MAX_DIMS ;++ i ) { 42str += std::to_string (t -> ne [i ]); 43if (i + 1 < GGML_MAX_DIMS ) { 44str += ", " ; 45 } 46 } 47return str ; 48} 49 50static struct gguf_context * load_gguf (std::string & fname ,struct ggml_context ** ctx_ggml ) { 51struct gguf_init_params params = { 52/*.no_alloc = */ true, 53/*.ctx = */ ctx_ggml , 54 }; 55struct gguf_context * ctx_gguf = gguf_init_from_file (fname .c_str (),params ); 56if (!ctx_gguf ) { 57throw std::runtime_error ("failed to load input GGUF from " + fname ); 58 } 59return ctx_gguf ; 60} 61 62struct file_input { 63struct ggml_context * ctx_meta = nullptr ; 64struct gguf_context * ctx_gguf = nullptr ; 65 std::ifstream f_in ; 66 std::map < std::string ,ggml_tensor *> tensors ; 67float alpha ; 68float scale ; 69 70file_input (std::string & fname ,float scale ):f_in (fname , std::ios::binary ),scale (scale ) { 71if (!f_in .is_open ()) { 72throw std::runtime_error ("failed to open input gguf from " + fname ); 73 } 74 75ctx_gguf = load_gguf (fname ,& ctx_meta ); 76alpha = get_kv_f32 (ctx_gguf ,"adapter.lora.alpha" ); 77printf ("%s: loaded gguf from %s\n" ,__func__ ,fname .c_str ()); 78 79for (ggml_tensor * cur = ggml_get_first_tensor (ctx_meta );cur ;cur = ggml_get_next_tensor (ctx_meta ,cur )) { 80 std::string name (cur -> name ); 81tensors [name ]= cur ; 82if (g_verbose ) { 83printf ("%s: %s\n" ,__func__ ,cur -> name ); 84 } 85 } 86 } 87 88ggml_tensor * get_tensor (std::string name ) { 89if (tensors .find (name )== tensors .end ()) { 90return nullptr ; 91 } 92return tensors [name ]; 93 } 94 95void read_tensor_data (std::string name , std::vector < uint8_t > & buf ) { 96if (tensors .find (name )== tensors .end ()) { 97throw std::runtime_error ("cannot find tensor with name: " + name ); 98 } 99auto len = ggml_nbytes (tensors [name ]); 100if (buf .size ()< len ) { 101buf .resize (len ); 102 } 103auto i_tensor_in = gguf_find_tensor (ctx_gguf ,name .c_str ());// idx of tensor in the input file 104auto offset = gguf_get_data_offset (ctx_gguf )+ gguf_get_tensor_offset (ctx_gguf ,i_tensor_in ); 105f_in .seekg (offset ); 106f_in .read ((char * )buf .data (),len ); 107 } 108 109 ~file_input () { 110gguf_free (ctx_gguf ); 111ggml_free (ctx_meta ); 112 } 113}; 114 115struct lora_merge_ctx { 116// input base model + adapters 117file_input base_model ; 118 std::vector < std::unique_ptr < file_input >> adapters ; 119 120// for computing merged tensor 121int n_threads ; 122ggml_backend_t backend = nullptr ; 123ggml_gallocr_t allocr = nullptr ; 124 std::vector < uint8_t > read_buf ; 125 126// output file 127struct gguf_context * ctx_out ; 128struct ggml_context * ctx_out_ggml ; 129 std::ofstream fout ; 130 131lora_merge_ctx ( 132 std::string & base_fname , 133 std::vector < common_adapter_lora_info > & lora_files , 134 std::string & outfile , 135int n_threads ) :base_model (base_fname ,0 ),n_threads (n_threads ),fout (outfile , std::ios::binary ) { 136fout .exceptions (std::ofstream::failbit );// fail fast on write errors 137 138if (gguf_find_key (base_model .ctx_gguf ,LLM_KV_SPLIT_COUNT ) >=0 ) { 139throw std::runtime_error ("split model is not yet supported" ); 140 } 141 142for (auto & lora_inp :lora_files ) { 143auto fname = lora_inp .path ; 144auto scale = lora_inp .scale ; 145 std::unique_ptr < file_input > adapter (new file_input (fname ,scale )); 146check_metadata_lora (adapter .get ()); 147adapters .push_back (std::move (adapter )); 148 } 149 150ctx_out = gguf_init_empty (); 151struct ggml_init_params params = { 152/*.mem_size =*/ static_cast < size_t > (gguf_get_n_tensors (base_model .ctx_gguf )* ggml_tensor_overhead ()), 153/*.mem_buffer =*/ NULL , 154/*.no_alloc =*/ true, 155 }; 156ctx_out_ggml = ggml_init (params ); 157backend = ggml_backend_cpu_init (); 158allocr = ggml_gallocr_new (ggml_backend_get_default_buffer_type (backend )); 159 } 160 161void check_metadata_lora (file_input * adapter ) { 162auto general_type = get_kv_str (adapter -> ctx_gguf ,"general.type" ); 163if (general_type != "adapter" ) { 164throw std::runtime_error ("expect general.type to be 'adapter', but got: " + general_type ); 165 } 166 167auto adapter_type = get_kv_str (adapter -> ctx_gguf ,"adapter.type" ); 168if (adapter_type != "lora" ) { 169throw std::runtime_error ("expect adapter.type to be 'lora', but got: " + adapter_type ); 170 } 171 172auto general_arch_base = get_kv_str (base_model .ctx_gguf ,"general.architecture" ); 173auto general_arch_lora = get_kv_str (adapter -> ctx_gguf ,"general.architecture" ); 174if (general_arch_base != general_arch_lora ) { 175throw std::runtime_error ("model arch and LoRA arch mismatch" ); 176 } 177 } 178 179ggml_type get_out_tensor_type (struct ggml_tensor * t ) { 180if (t -> type == GGML_TYPE_F32 ) { 181return GGML_TYPE_F32 ; 182 }else { 183return GGML_TYPE_F16 ; 184 } 185 } 186 187void run_merge () { 188// prepare metadata 189gguf_set_kv (ctx_out ,base_model .ctx_gguf ); 190// output is forced to f16 for now 191gguf_set_val_u32 (ctx_out ,"general.file_type" ,LLAMA_FTYPE_MOSTLY_F16 ); 192 193// check if all lora adapters have the same tensors 194// TODO: remove this when we can support merging subset of adapters. Ref: https://github.com/ggml-org/llama.cpp/pull/8607#discussion_r1686027777 195static const char * err_no_subset_adapter = "Input adapters do not have the same list of tensors. This is not yet supported. Please merge the adapter one-by-one instead of merging all at once." ; 196if (adapters .size ()> 1 ) { 197for (size_t i = 1 ;i < adapters .size ();++ i ) { 198if (adapters [0 ]-> tensors .size ()!= adapters [i ]-> tensors .size ()) { 199throw std::runtime_error (err_no_subset_adapter ); 200 } 201for (auto & it :adapters [i ]-> tensors ) { 202if (adapters [0 ]-> get_tensor (it .first )== nullptr ) { 203throw std::runtime_error (err_no_subset_adapter ); 204 } 205 } 206 } 207 } 208 209// mapping base tensor to out tensor (same shape with base, but different type) 210 std::vector < tensor_transformation > trans ; 211for (auto & it :base_model .tensors ) { 212bool t_a = true; 213bool t_b = true; 214for (auto & adapter :adapters ) { 215t_a &=nullptr != adapter -> get_tensor (it .first + ".lora_a" ); 216t_b &=nullptr != adapter -> get_tensor (it .first + ".lora_b" ); 217 } 218auto base_tensor = it .second ; 219if (!t_a && !t_b ) { 220// only copy 221struct ggml_tensor * cpy_tensor = ggml_dup_tensor (ctx_out_ggml ,base_tensor ); 222ggml_set_name (cpy_tensor ,base_tensor -> name ); 223trans .push_back ({ 224cpy_tensor , 225cpy_tensor , 226 true, 227 }); 228gguf_add_tensor (ctx_out ,cpy_tensor ); 229 }else if (t_a && t_b ) { 230// need merging 231struct ggml_tensor * out_tensor = ggml_new_tensor ( 232ctx_out_ggml ,get_out_tensor_type (base_tensor ),GGML_MAX_DIMS ,base_tensor -> ne ); 233ggml_set_name (out_tensor ,base_tensor -> name ); 234trans .push_back ({ 235base_tensor , 236out_tensor , 237 false, 238 }); 239gguf_add_tensor (ctx_out ,out_tensor ); 240 }else { 241throw std::runtime_error ("tensor " + it .first + " missing either lora_a or lora_b" ); 242 } 243 } 244 245// placeholder for the meta data 246 { 247size_t meta_size = gguf_get_meta_size (ctx_out ); 248zeros (fout ,meta_size ); 249 } 250 251// process base model tensors 252size_t n_merged = 0 ; 253for (auto & it :trans ) { 254if (!it .is_copy ) { 255merge_tensor (it .in ,it .out ); 256n_merged ++ ; 257 }else { 258copy_tensor (it .in ); 259 } 260 } 261 262// write output metadata 263 { 264 std::vector < uint8_t > data (gguf_get_meta_size (ctx_out )); 265gguf_get_meta_data (ctx_out ,data .data ()); 266fout .seekp (0 ); 267fout .write ((const char * )data .data (),data .size ()); 268 } 269 270printf ("%s : merged %zu tensors with lora adapters\n" ,__func__ ,n_merged ); 271printf ("%s : wrote %zu tensors to output file\n" ,__func__ ,trans .size ()); 272 } 273 274void copy_tensor (struct ggml_tensor * base ) { 275printf ("%s : %s [%s]\n" ,__func__ ,base -> name ,ggml_ne_string (base ).c_str ()); 276size_t len = ggml_nbytes (base ); 277base_model .read_tensor_data (base -> name ,read_buf ); 278fout .write ((char * )read_buf .data (),len ); 279zeros (fout ,GGML_PAD (len ,GGUF_DEFAULT_ALIGNMENT )- len ); 280 } 281 282void merge_tensor (struct ggml_tensor * base ,struct ggml_tensor * out ) { 283 std::string name_base (base -> name ); 284 std::string name_lora_a = name_base + ".lora_a" ; 285 std::string name_lora_b = name_base + ".lora_b" ; 286 287printf ("%s : %s [%s]\n" ,__func__ ,base -> name ,ggml_ne_string (base ).c_str ()); 288 289// context for input tensor 290 std::vector < struct ggml_tensor *> inp_a (adapters .size ()); 291 std::vector < struct ggml_tensor *> inp_b (adapters .size ()); 292struct ggml_init_params params { 293/*.mem_size =*/ ggml_tensor_overhead ()* (2 + adapters .size ()* 2 ), 294/*.mem_buffer =*/ NULL , 295/*.no_alloc =*/ true, 296 }; 297struct ggml_context * ctx = ggml_init (params ); 298 299// alloc tensors 300struct ggml_tensor * inp_base = ggml_new_tensor (ctx ,GGML_TYPE_F32 ,GGML_MAX_DIMS ,base -> ne ); 301for (size_t i = 0 ;i < adapters .size ();++ i ) { 302auto t_a = adapters [i ]-> get_tensor (name_lora_a ); 303auto t_b = adapters [i ]-> get_tensor (name_lora_b ); 304// TODO: add support for quantized lora 305if (ggml_is_quantized (t_a -> type )|| ggml_is_quantized (t_b -> type )) { 306throw std::runtime_error ("quantized LoRA adapters is not supported, please retry with f16 or f32" ); 307 } 308inp_a [i ]= ggml_dup_tensor (ctx ,t_a ); 309inp_b [i ]= ggml_dup_tensor (ctx ,t_b ); 310 } 311ggml_backend_buffer_t buffer = ggml_backend_alloc_ctx_tensors (ctx ,backend ); 312 313// load base tensor to backend buffer 314base_model .read_tensor_data (name_base ,read_buf ); 315if (base -> type != GGML_TYPE_F32 ) { 316// optionally dequantize it 317printf ("%s : + dequantize base tensor from %s to F32\n" ,__func__ ,ggml_type_name (base -> type )); 318auto nels = ggml_nelements (inp_base ); 319const auto * qtype = ggml_get_type_traits (base -> type ); 320 std::vector < uint8_t > dequant_buf (nels * sizeof (float )); 321qtype -> to_float (read_buf .data (), (float * )dequant_buf .data (),nels ); 322ggml_backend_tensor_set (inp_base ,dequant_buf .data (),0 ,dequant_buf .size ()); 323 }else { 324ggml_backend_tensor_set (inp_base ,read_buf .data (),0 ,ggml_nbytes (inp_base )); 325 } 326 327// load lora tensors to backend buffer 328for (size_t i = 0 ;i < adapters .size ();++ i ) { 329adapters [i ]-> read_tensor_data (name_lora_a ,read_buf ); 330ggml_backend_tensor_set (inp_a [i ],read_buf .data (),0 ,ggml_nbytes (inp_a [i ])); 331adapters [i ]-> read_tensor_data (name_lora_b ,read_buf ); 332ggml_backend_tensor_set (inp_b [i ],read_buf .data (),0 ,ggml_nbytes (inp_b [i ])); 333 } 334 335// build graph 336struct ggml_cgraph * gf ; 337 { 338static size_t buf_size = ggml_tensor_overhead ()* GGML_DEFAULT_GRAPH_SIZE + ggml_graph_overhead (); 339static std::vector < uint8_t > buf (buf_size ); 340struct ggml_init_params params0 = { 341/*.mem_size =*/ buf_size , 342/*.mem_buffer =*/ buf .data (), 343/*.no_alloc =*/ true, 344 }; 345struct ggml_context * ctx0 = ggml_init (params0 ); 346gf = ggml_new_graph (ctx0 ); 347struct ggml_tensor * cur = inp_base ; 348for (size_t i = 0 ;i < adapters .size ();++ i ) { 349struct ggml_tensor * delta ; 350bool is_tok_embd = string_starts_with (name_base ,"token_embd" ); 351if (is_tok_embd ) { 352printf ("%s : detected token embeddings tensor\n" ,__func__ ); 353delta = ggml_mul_mat (ctx0 , 354ggml_cast (ctx0 ,inp_b [i ],GGML_TYPE_F32 ), 355ggml_cast (ctx0 ,inp_a [i ],GGML_TYPE_F32 )); 356 }else { 357delta = ggml_mul_mat (ctx0 , 358ggml_cont (ctx0 ,ggml_transpose (ctx0 ,ggml_cast (ctx0 ,inp_a [i ],GGML_TYPE_F32 ))), 359ggml_cast (ctx0 ,inp_b [i ],GGML_TYPE_F32 )); 360 } 361// scale 362const float alpha = adapters [i ]-> alpha ; 363const float rank = (float )inp_b [i ]-> ne [0 ]; 364const float scale = alpha ?adapters [i ]-> scale * alpha /rank :adapters [i ]-> scale ; 365delta = ggml_scale (ctx0 ,delta ,scale ); 366cur = ggml_add (ctx0 ,delta ,cur ); 367printf ("%s : + merging from adapter[%zu] type=%s\n" ,__func__ ,i ,ggml_type_name (inp_a [i ]-> type )); 368printf ("%s : input_scale=%f calculated_scale=%f rank=%d\n" ,__func__ ,adapters [i ]-> scale ,scale , (int )inp_b [i ]-> ne [0 ]); 369 } 370cur = ggml_cast (ctx0 ,cur ,out -> type ); 371printf ("%s : + output type is %s\n" ,__func__ ,ggml_type_name (out -> type )); 372ggml_build_forward_expand (gf ,cur ); 373ggml_free (ctx0 ); 374 } 375 376// compute 377 { 378ggml_gallocr_alloc_graph (allocr ,gf ); 379ggml_backend_cpu_set_n_threads (backend ,n_threads ); 380ggml_backend_graph_compute (backend ,gf ); 381 } 382 383// write data to output file 384 { 385auto * result = ggml_graph_node (gf ,-1 ); 386size_t len = ggml_nbytes (result ); 387if (read_buf .size ()< len ) { 388read_buf .resize (len ); 389 } 390ggml_backend_tensor_get (result ,read_buf .data (),0 ,len ); 391fout .write ((char * )read_buf .data (),len ); 392zeros (fout ,GGML_PAD (len ,GGUF_DEFAULT_ALIGNMENT )- len ); 393 } 394 395ggml_free (ctx ); 396ggml_backend_buffer_free (buffer ); 397 } 398 399 ~lora_merge_ctx () { 400ggml_gallocr_free (allocr ); 401ggml_backend_free (backend ); 402gguf_free (ctx_out ); 403ggml_free (ctx_out_ggml ); 404 } 405}; 406 407static void print_usage (int ,char ** argv ) { 408printf ("\nexample usage:\n" ); 409printf ("\n %s -m base-model.gguf --lora lora-file.gguf -o merged-model-f16.gguf\n" ,argv [0 ]); 410printf ("\nNOTE: output model is F16\n" ); 411printf ("\n" ); 412} 413 414int main (int argc ,char ** argv ) { 415 std::setlocale (LC_NUMERIC ,"C" ); 416 417common_params params ; 418 419params .out_file = "ggml-lora-merged-f16.gguf" ; 420 421common_init (); 422 423if (!common_params_parse (argc ,argv ,params ,LLAMA_EXAMPLE_EXPORT_LORA ,print_usage )) { 424return 1 ; 425 } 426 427g_verbose = (params .verbosity > 1 ); 428try { 429lora_merge_ctx ctx (params .model .path ,params .lora_adapters ,params .out_file ,params .cpuparams .n_threads ); 430ctx .run_merge (); 431 }catch (const std::exception & err ) { 432fprintf (stderr ,"%s\n" ,err .what ()); 433exit (EXIT_FAILURE ); 434 } 435 436printf ("done, output file is %s\n" ,params .out_file .c_str ()); 437 438return 0 ; 439}