char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
cb8f4fa3f
char/aliceai-t5-moe
1#include "llama.h" 2#include <clocale> 3#include <cstdio> 4#include <cstring> 5#include <iostream> 6#include <string> 7#include <vector> 8 9static void print_usage (int ,char ** argv ) { 10printf ("\nexample usage:\n" ); 11printf ("\n %s -m model.gguf [-c context_size] [-ngl n_gpu_layers]\n" ,argv [0 ]); 12printf ("\n" ); 13} 14 15int main (int argc ,char ** argv ) { 16 std::setlocale (LC_NUMERIC ,"C" ); 17 18 std::string model_path ; 19int ngl = 99 ; 20int n_ctx = 2048 ; 21 22// parse command line arguments 23for (int i = 1 ;i < argc ;i ++ ) { 24try { 25if (strcmp (argv [i ],"-m" )== 0 ) { 26if (i + 1 < argc ) { 27model_path = argv [++ i ]; 28 }else { 29print_usage (argc ,argv ); 30return 1 ; 31 } 32 }else if (strcmp (argv [i ],"-c" )== 0 ) { 33if (i + 1 < argc ) { 34n_ctx = std::stoi (argv [++ i ]); 35 }else { 36print_usage (argc ,argv ); 37return 1 ; 38 } 39 }else if (strcmp (argv [i ],"-ngl" )== 0 ) { 40if (i + 1 < argc ) { 41ngl = std::stoi (argv [++ i ]); 42 }else { 43print_usage (argc ,argv ); 44return 1 ; 45 } 46 }else { 47print_usage (argc ,argv ); 48return 1 ; 49 } 50 }catch (std::exception & e ) { 51fprintf (stderr ,"error: %s\n" ,e .what ()); 52print_usage (argc ,argv ); 53return 1 ; 54 } 55 } 56if (model_path .empty ()) { 57print_usage (argc ,argv ); 58return 1 ; 59 } 60 61// only print errors 62llama_log_set ([](enum ggml_log_level level ,const char * text ,void * /* user_data */ ) { 63if (level >=GGML_LOG_LEVEL_ERROR ) { 64fprintf (stderr ,"%s" ,text ); 65 } 66 },nullptr ); 67 68// load dynamic backends 69ggml_backend_load_all (); 70 71// initialize the model 72llama_model_params model_params = llama_model_default_params (); 73model_params .n_gpu_layers = ngl ; 74 75llama_model * model = llama_model_load_from_file (model_path .c_str (),model_params ); 76if (!model ) { 77fprintf (stderr ,"%s: error: unable to load model\n" ,__func__ ); 78return 1 ; 79 } 80 81const llama_vocab * vocab = llama_model_get_vocab (model ); 82 83// initialize the context 84llama_context_params ctx_params = llama_context_default_params (); 85ctx_params .n_ctx = n_ctx ; 86ctx_params .n_batch = n_ctx ; 87 88llama_context * ctx = llama_init_from_model (model ,ctx_params ); 89if (!ctx ) { 90fprintf (stderr ,"%s: error: failed to create the llama_context\n" ,__func__ ); 91return 1 ; 92 } 93 94// initialize the sampler 95llama_sampler * smpl = llama_sampler_chain_init (llama_sampler_chain_default_params ()); 96llama_sampler_chain_add (smpl ,llama_sampler_init_min_p (0.05f ,1 )); 97llama_sampler_chain_add (smpl ,llama_sampler_init_temp (0.8f )); 98llama_sampler_chain_add (smpl ,llama_sampler_init_dist (LLAMA_DEFAULT_SEED )); 99 100// helper function to evaluate a prompt and generate a response 101auto generate = [& ](const std::string & prompt ) { 102 std::string response ; 103 104const bool is_first = llama_memory_seq_pos_max (llama_get_memory (ctx ),0 )== -1 ; 105 106// tokenize the prompt 107const int n_prompt_tokens = - llama_tokenize (vocab ,prompt .c_str (),prompt .size (),NULL ,0 ,is_first , true); 108 std::vector < llama_token > prompt_tokens (n_prompt_tokens ); 109if (llama_tokenize (vocab ,prompt .c_str (),prompt .size (),prompt_tokens .data (),prompt_tokens .size (),is_first , true)< 0 ) { 110GGML_ABORT ("failed to tokenize the prompt\n" ); 111 } 112 113// prepare a batch for the prompt 114llama_batch batch = llama_batch_get_one (prompt_tokens .data (),prompt_tokens .size ()); 115llama_token new_token_id ; 116while (true) { 117// check if we have enough space in the context to evaluate this batch 118int n_ctx = llama_n_ctx (ctx ); 119int n_ctx_used = llama_memory_seq_pos_max (llama_get_memory (ctx ),0 )+ 1 ; 120if (n_ctx_used + batch .n_tokens > n_ctx ) { 121printf ("\033[0m\n" ); 122fprintf (stderr ,"context size exceeded\n" ); 123exit (0 ); 124 } 125 126int ret = llama_decode (ctx ,batch ); 127if (ret != 0 ) { 128GGML_ABORT ("failed to decode, ret = %d\n" ,ret ); 129 } 130 131// sample the next token 132new_token_id = llama_sampler_sample (smpl ,ctx ,-1 ); 133 134// is it an end of generation? 135if (llama_vocab_is_eog (vocab ,new_token_id )) { 136break ; 137 } 138 139// convert the token to a string, print it and add it to the response 140char buf [256 ]; 141int n = llama_token_to_piece (vocab ,new_token_id ,buf ,sizeof (buf ),0 , true); 142if (n < 0 ) { 143GGML_ABORT ("failed to convert token to piece\n" ); 144 } 145 std::string piece (buf ,n ); 146printf ("%s" ,piece .c_str ()); 147fflush (stdout ); 148response += piece ; 149 150// prepare the next batch with the sampled token 151batch = llama_batch_get_one (& new_token_id ,1 ); 152 } 153 154return response ; 155 }; 156 157 std::vector < llama_chat_message > messages ; 158 std::vector < char > formatted (llama_n_ctx (ctx )); 159int prev_len = 0 ; 160while (true) { 161// get user input 162printf ("\033[32m> \033[0m" ); 163 std::string user ; 164 std::getline (std::cin ,user ); 165 166if (user .empty ()) { 167break ; 168 } 169 170const char * tmpl = llama_model_chat_template (model ,/* name */ nullptr ); 171 172// add the user input to the message list and format it 173messages .push_back ({"user" ,strdup (user .c_str ())}); 174int new_len = llama_chat_apply_template (tmpl ,messages .data (),messages .size (), true,formatted .data (),formatted .size ()); 175if (new_len > (int )formatted .size ()) { 176formatted .resize (new_len ); 177new_len = llama_chat_apply_template (tmpl ,messages .data (),messages .size (), true,formatted .data (),formatted .size ()); 178 } 179if (new_len < 0 ) { 180fprintf (stderr ,"failed to apply the chat template\n" ); 181return 1 ; 182 } 183 184// remove previous messages to obtain the prompt to generate the response 185 std::string prompt (formatted .begin ()+ prev_len ,formatted .begin ()+ new_len ); 186 187// generate a response 188printf ("\033[33m" ); 189 std::string response = generate (prompt ); 190printf ("\n\033[0m" ); 191 192// add the response to the messages 193messages .push_back ({"assistant" ,strdup (response .c_str ())}); 194prev_len = llama_chat_apply_template (tmpl ,messages .data (),messages .size (), false,nullptr ,0 ); 195if (prev_len < 0 ) { 196fprintf (stderr ,"failed to apply the chat template\n" ); 197return 1 ; 198 } 199 } 200 201// free resources 202for (auto & msg :messages ) { 203free (const_cast < char *> (msg .content )); 204 } 205llama_sampler_free (smpl ); 206llama_free (ctx ); 207llama_model_free (model ); 208 209return 0 ; 210}