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 <string> 6#include <vector> 7 8static void print_usage (int ,char ** argv ) { 9printf ("\nexample usage:\n" ); 10printf ("\n %s -m model.gguf [-n n_predict] [-ngl n_gpu_layers] [prompt]\n" ,argv [0 ]); 11printf ("\n" ); 12} 13 14int main (int argc ,char ** argv ) { 15 std::setlocale (LC_NUMERIC ,"C" ); 16 17// path to the model gguf file 18 std::string model_path ; 19// prompt to generate text from 20 std::string prompt = "Hello my name is" ; 21// number of layers to offload to the GPU 22int ngl = 99 ; 23// number of tokens to predict 24int n_predict = 32 ; 25 26// parse command line arguments 27 28 { 29int i = 1 ; 30for (;i < argc ;i ++ ) { 31if (strcmp (argv [i ],"-m" )== 0 ) { 32if (i + 1 < argc ) { 33model_path = argv [++ i ]; 34 }else { 35print_usage (argc ,argv ); 36return 1 ; 37 } 38 }else if (strcmp (argv [i ],"-n" )== 0 ) { 39if (i + 1 < argc ) { 40try { 41n_predict = std::stoi (argv [++ i ]); 42 }catch (...) { 43print_usage (argc ,argv ); 44return 1 ; 45 } 46 }else { 47print_usage (argc ,argv ); 48return 1 ; 49 } 50 }else if (strcmp (argv [i ],"-ngl" )== 0 ) { 51if (i + 1 < argc ) { 52try { 53ngl = std::stoi (argv [++ i ]); 54 }catch (...) { 55print_usage (argc ,argv ); 56return 1 ; 57 } 58 }else { 59print_usage (argc ,argv ); 60return 1 ; 61 } 62 }else { 63// prompt starts here 64break ; 65 } 66 } 67if (model_path .empty ()) { 68print_usage (argc ,argv ); 69return 1 ; 70 } 71if (i < argc ) { 72prompt = argv [i ++ ]; 73for (;i < argc ;i ++ ) { 74prompt += " " ; 75prompt += argv [i ]; 76 } 77 } 78 } 79 80// load dynamic backends 81 82ggml_backend_load_all (); 83 84// initialize the model 85 86llama_model_params model_params = llama_model_default_params (); 87model_params .n_gpu_layers = ngl ; 88 89llama_model * model = llama_model_load_from_file (model_path .c_str (),model_params ); 90 91if (model == NULL ) { 92fprintf (stderr ,"%s: error: unable to load model\n" ,__func__ ); 93return 1 ; 94 } 95 96const llama_vocab * vocab = llama_model_get_vocab (model ); 97// tokenize the prompt 98 99// find the number of tokens in the prompt 100const int n_prompt = - llama_tokenize (vocab ,prompt .c_str (),prompt .size (),NULL ,0 , true, true); 101 102// allocate space for the tokens and tokenize the prompt 103 std::vector < llama_token > prompt_tokens (n_prompt ); 104if (llama_tokenize (vocab ,prompt .c_str (),prompt .size (),prompt_tokens .data (),prompt_tokens .size (), true, true)< 0 ) { 105fprintf (stderr ,"%s: error: failed to tokenize the prompt\n" ,__func__ ); 106return 1 ; 107 } 108 109// initialize the context 110 111llama_context_params ctx_params = llama_context_default_params (); 112// n_ctx is the context size 113ctx_params .n_ctx = n_prompt + n_predict - 1 ; 114// n_batch is the maximum number of tokens that can be processed in a single call to llama_decode 115ctx_params .n_batch = n_prompt ; 116// enable performance counters 117ctx_params .no_perf = false; 118 119llama_context * ctx = llama_init_from_model (model ,ctx_params ); 120 121if (ctx == NULL ) { 122fprintf (stderr ,"%s: error: failed to create the llama_context\n" ,__func__ ); 123return 1 ; 124 } 125 126// initialize the sampler 127 128auto sparams = llama_sampler_chain_default_params (); 129sparams .no_perf = false; 130llama_sampler * smpl = llama_sampler_chain_init (sparams ); 131 132llama_sampler_chain_add (smpl ,llama_sampler_init_greedy ()); 133 134// print the prompt token-by-token 135 136for (auto id :prompt_tokens ) { 137char buf [128 ]; 138int n = llama_token_to_piece (vocab ,id ,buf ,sizeof (buf ),0 , true); 139if (n < 0 ) { 140fprintf (stderr ,"%s: error: failed to convert token to piece\n" ,__func__ ); 141return 1 ; 142 } 143 std::string s (buf ,n ); 144printf ("%s" ,s .c_str ()); 145 } 146 147// prepare a batch for the prompt 148 149llama_batch batch = llama_batch_get_one (prompt_tokens .data (),prompt_tokens .size ()); 150 151if (llama_model_has_encoder (model )) { 152if (llama_encode (ctx ,batch )) { 153fprintf (stderr ,"%s : failed to eval\n" ,__func__ ); 154return 1 ; 155 } 156 157llama_token decoder_start_token_id = llama_model_decoder_start_token (model ); 158if (decoder_start_token_id == LLAMA_TOKEN_NULL ) { 159decoder_start_token_id = llama_vocab_bos (vocab ); 160 } 161 162batch = llama_batch_get_one (& decoder_start_token_id ,1 ); 163 } 164 165// main loop 166 167const auto t_main_start = ggml_time_us (); 168int n_decode = 0 ; 169llama_token new_token_id ; 170 171for (int n_pos = 0 ;n_pos + batch .n_tokens < n_prompt + n_predict ; ) { 172// evaluate the current batch with the transformer model 173if (llama_decode (ctx ,batch )) { 174fprintf (stderr ,"%s : failed to eval, return code %d\n" ,__func__ ,1 ); 175return 1 ; 176 } 177 178n_pos += batch .n_tokens ; 179 180// sample the next token 181 { 182new_token_id = llama_sampler_sample (smpl ,ctx ,-1 ); 183 184// is it an end of generation? 185if (llama_vocab_is_eog (vocab ,new_token_id )) { 186break ; 187 } 188 189char buf [128 ]; 190int n = llama_token_to_piece (vocab ,new_token_id ,buf ,sizeof (buf ),0 , true); 191if (n < 0 ) { 192fprintf (stderr ,"%s: error: failed to convert token to piece\n" ,__func__ ); 193return 1 ; 194 } 195 std::string s (buf ,n ); 196printf ("%s" ,s .c_str ()); 197fflush (stdout ); 198 199// prepare the next batch with the sampled token 200batch = llama_batch_get_one (& new_token_id ,1 ); 201 202n_decode += 1 ; 203 } 204 } 205 206printf ("\n" ); 207 208const auto t_main_end = ggml_time_us (); 209 210fprintf (stderr ,"%s: decoded %d tokens in %.2f s, speed: %.2f t/s\n" , 211__func__ ,n_decode , (t_main_end - t_main_start ) /1000000.0f ,n_decode / ((t_main_end - t_main_start ) /1000000.0f )); 212 213fprintf (stderr ,"\n" ); 214llama_perf_sampler_print (smpl ); 215llama_perf_context_print (ctx ); 216fprintf (stderr ,"\n" ); 217 218llama_sampler_free (smpl ); 219llama_free (ctx ); 220llama_model_free (model ); 221 222return 0 ; 223}