char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
41361c859
char/aliceai-t5-moe
1#include "arg.h" 2#include "common.h" 3#include "log.h" 4#include "llama.h" 5#include "sampling.h" 6 7#include <algorithm> 8#include <clocale> 9#include <cstdio> 10#include <string> 11#include <vector> 12 13static void print_usage (int ,char ** argv ) { 14LOG ("\nexample usage:\n" ); 15LOG ("\n %s -m model.gguf -p \"Hello my name is\" -n 32 -np 4\n" ,argv [0 ]); 16LOG ("\n" ); 17} 18 19int main (int argc ,char ** argv ) { 20 std::setlocale (LC_NUMERIC ,"C" ); 21 22common_params params ; 23 24params .prompt = "Hello my name is" ; 25params .n_predict = 32 ; 26 27common_init (); 28 29if (!common_params_parse (argc ,argv ,params ,LLAMA_EXAMPLE_BATCHED ,print_usage )) { 30return 1 ; 31 } 32 33// number of parallel batches 34int n_parallel = params .n_parallel ; 35 36// total length of the sequences including the prompt 37int n_predict = params .n_predict ; 38 39// init LLM 40 41llama_backend_init (); 42llama_numa_init (params .numa ); 43 44// initialize the model 45 46llama_model_params model_params = common_model_params_to_llama (params ); 47 48llama_model * model = llama_model_load_from_file (params .model .path .c_str (),model_params ); 49 50if (model == NULL ) { 51LOG_ERR ("%s: error: unable to load model\n" ,__func__ ); 52return 1 ; 53 } 54 55const llama_vocab * vocab = llama_model_get_vocab (model ); 56 57// tokenize the prompt 58 59 std::vector < llama_token > tokens_list ; 60tokens_list = common_tokenize (vocab ,params .prompt , true); 61 62const int n_kv_req = tokens_list .size ()+ (n_predict - tokens_list .size ())* n_parallel ; 63 64// initialize the context 65 66llama_context_params ctx_params = common_context_params_to_llama (params ); 67 68ctx_params .n_ctx = n_kv_req ; 69ctx_params .n_batch = std::max (n_predict ,n_parallel ); 70 71auto sparams = llama_sampler_chain_default_params (); 72sparams .no_perf = false; 73 74 std::vector < llama_sampler_seq_config > sampler_configs ; 75 76for (int32_t i = 0 ;i < n_parallel ;++ i ) { 77llama_sampler * smpl = llama_sampler_chain_init (sparams ); 78 79llama_sampler_chain_add (smpl ,llama_sampler_init_top_k (params .sampling .top_k )); 80llama_sampler_chain_add (smpl ,llama_sampler_init_top_p (params .sampling .top_p ,params .sampling .min_keep )); 81llama_sampler_chain_add (smpl ,llama_sampler_init_temp (params .sampling .temp )); 82llama_sampler_chain_add (smpl ,llama_sampler_init_dist (params .sampling .seed )); 83 84sampler_configs .push_back ({i ,smpl }); 85 } 86 87if (params .sampling .backend_sampling ) { 88ctx_params .samplers = sampler_configs .data (); 89ctx_params .n_samplers = sampler_configs .size (); 90 } 91 92llama_context * ctx = llama_init_from_model (model ,ctx_params ); 93 94if (ctx == NULL ) { 95LOG_ERR ("%s: error: failed to create the llama_context\n" ,__func__ ); 96return 1 ; 97 } 98 99const int n_ctx = llama_n_ctx (ctx ); 100 101LOG_INF ("\n%s: n_predict = %d, n_ctx = %d, n_batch = %u, n_parallel = %d, n_kv_req = %d\n" ,__func__ ,n_predict ,n_ctx ,ctx_params .n_batch ,n_parallel ,n_kv_req ); 102 103// make sure the KV cache is big enough to hold all the prompt and generated tokens 104if (n_kv_req > n_ctx ) { 105LOG_ERR ("%s: error: n_kv_req (%d) > n_ctx, the required KV cache size is not big enough\n" ,__func__ ,n_kv_req ); 106LOG_ERR ("%s: either reduce n_parallel or increase n_ctx\n" ,__func__ ); 107return 1 ; 108 } 109 110// print the prompt token-by-token 111 112LOG ("\n" ); 113 114for (auto id :tokens_list ) { 115LOG ("%s" ,common_token_to_piece (ctx ,id ).c_str ()); 116 } 117 118// create a llama_batch 119// we use this object to submit token data for decoding 120llama_batch batch = llama_batch_init (std::max (tokens_list .size (), (size_t )n_parallel ),0 ,n_parallel ); 121 122 std::vector < llama_seq_id > seq_ids (n_parallel ,0 ); 123for (int32_t i = 0 ;i < n_parallel ;++ i ) { 124seq_ids [i ]= i ; 125 } 126 127// evaluate the initial prompt 128for (size_t i = 0 ;i < tokens_list .size ();++ i ) { 129common_batch_add (batch ,tokens_list [i ],i ,seq_ids , false); 130 } 131GGML_ASSERT (batch .n_tokens == (int )tokens_list .size ()); 132 133if (llama_model_has_encoder (model )) { 134if (llama_encode (ctx ,batch )) { 135LOG_ERR ("%s : failed to eval\n" ,__func__ ); 136return 1 ; 137 } 138 139llama_token decoder_start_token_id = llama_model_decoder_start_token (model ); 140if (decoder_start_token_id == LLAMA_TOKEN_NULL ) { 141decoder_start_token_id = llama_vocab_bos (vocab ); 142 } 143 144common_batch_clear (batch ); 145common_batch_add (batch ,decoder_start_token_id ,0 ,seq_ids , false); 146 } 147 148// llama_decode will output logits only for the last token of the prompt 149batch .logits [batch .n_tokens - 1 ]= true; 150 151if (llama_decode (ctx ,batch )!= 0 ) { 152LOG_ERR ("%s: llama_decode() failed\n" ,__func__ ); 153return 1 ; 154 } 155 156//// assign the system KV cache to all parallel sequences 157//// this way, the parallel sequences will "reuse" the prompt tokens without having to copy them 158//for (int32_t i = 1; i < n_parallel; ++i) { 159// llama_kv_cache_seq_cp(ctx, 0, i, -1, -1); 160//} 161 162if (n_parallel > 1 ) { 163LOG ("\n\n%s: generating %d sequences ...\n" ,__func__ ,n_parallel ); 164 } 165 166// main loop 167 168// we will store the parallel decoded sequences in this vector 169 std::vector < std::string > streams (n_parallel ); 170 171// remember the batch index of the last token for each parallel sequence 172// we need this to determine which logits to sample from 173 std::vector < int32_t > i_batch (n_parallel ,batch .n_tokens - 1 ); 174 175int n_cur = batch .n_tokens ; 176int n_decode = 0 ; 177 178const auto t_main_start = ggml_time_us (); 179 180while (n_cur <=n_predict ) { 181// prepare the next batch 182common_batch_clear (batch ); 183 184// sample the next token for each parallel sequence / stream 185for (int32_t i = 0 ;i < n_parallel ;++ i ) { 186if (i_batch [i ]< 0 ) { 187// the stream has already finished 188continue ; 189 } 190 191const llama_token new_token_id = llama_sampler_sample (sampler_configs [i ].sampler ,ctx ,i_batch [i ]); 192 193// is it an end of generation? -> mark the stream as finished 194if (llama_vocab_is_eog (vocab ,new_token_id )|| n_cur == n_predict ) { 195i_batch [i ]= -1 ; 196LOG ("\n" ); 197if (n_parallel > 1 ) { 198LOG_INF ("%s: stream %d finished at n_cur = %d" ,__func__ ,i ,n_cur ); 199 } 200 201continue ; 202 } 203 204// if there is only one stream, we print immediately to stdout 205if (n_parallel == 1 ) { 206LOG ("%s" ,common_token_to_piece (ctx ,new_token_id ).c_str ()); 207 } 208 209streams [i ]+= common_token_to_piece (ctx ,new_token_id ); 210 211i_batch [i ]= batch .n_tokens ; 212 213// push this new token for next evaluation 214common_batch_add (batch ,new_token_id ,n_cur , {i }, true); 215 216n_decode += 1 ; 217 } 218 219// all streams are finished 220if (batch .n_tokens == 0 ) { 221break ; 222 } 223 224n_cur += 1 ; 225 226// evaluate the current batch with the transformer model 227if (llama_decode (ctx ,batch )) { 228LOG_ERR ("%s : failed to eval, return code %d\n" ,__func__ ,1 ); 229return 1 ; 230 } 231 } 232 233if (n_parallel > 1 ) { 234LOG ("\n" ); 235 236for (int32_t i = 0 ;i < n_parallel ;++ i ) { 237LOG ("sequence %d:\n\n%s%s\n\n" ,i ,params .prompt .c_str (),streams [i ].c_str ()); 238 } 239 } 240 241const auto t_main_end = ggml_time_us (); 242 243LOG_INF ("%s: decoded %d tokens in %.2f s, speed: %.2f t/s\n" , 244__func__ ,n_decode , (t_main_end - t_main_start ) /1000000.0f ,n_decode / ((t_main_end - t_main_start ) /1000000.0f )); 245 246LOG ("\n" ); 247llama_perf_sampler_print (sampler_configs [0 ].sampler ); 248llama_perf_context_print (ctx ); 249 250fprintf (stderr ,"\n" ); 251 252llama_batch_free (batch ); 253 254for (auto & sampler_config :sampler_configs ) { 255llama_sampler_free (sampler_config .sampler ); 256 } 257 258llama_free (ctx ); 259llama_model_free (model ); 260 261llama_backend_free (); 262 263return 0 ; 264}