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 6#include <clocale> 7#include <cmath> 8#include <cstdio> 9#include <string> 10#include <vector> 11#include <algorithm> 12 13static void print_usage (int ,char ** argv ) { 14LOG ("\nexample usage:\n" ); 15LOG ("\n %s -m model.gguf --junk 250 --pos 90 --keep 32 --grp-attn-n 2 [--seed 1234]\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 .n_junk = 250 ; 25params .n_keep = 32 ; 26params .i_pos = -1 ; 27 28common_init (); 29 30if (!common_params_parse (argc ,argv ,params ,LLAMA_EXAMPLE_PASSKEY ,print_usage )) { 31return 1 ; 32 } 33 34int n_junk = params .n_junk ; 35int n_keep = params .n_keep ; 36int n_grp = params .grp_attn_n ; 37int i_pos = params .i_pos ; 38 39if (i_pos == -1 ) { 40i_pos = rand () %n_junk ; 41 } 42 43const std::string prompt_prefix = "There is an important info hidden inside a lot of irrelevant text. Find it and memorize them. I will quiz you about the important information there." ; 44const std::string prompt_suffix = " What is the pass key? The pass key is" ; 45 46// generate junk text 47params .prompt = prompt_prefix ; 48 49const int passkey = rand () %50000 + 1 ; 50 51for (int i = 0 ;i < n_junk ;i ++ ) { 52if (i %n_junk == i_pos ) { 53params .prompt += " The pass key is " + std::to_string (passkey )+ ". Remember it. " + std::to_string (passkey )+ " is the pass key." ; 54 } 55 56params .prompt += " The grass is green. The sky is blue. The sun is yellow. Here we go. There and back again." ; 57 } 58 59params .prompt += prompt_suffix ; 60 61// init LLM 62 63llama_backend_init (); 64llama_numa_init (params .numa ); 65 66// initialize the model 67 68llama_model_params model_params = common_model_params_to_llama (params ); 69 70llama_model * model = llama_model_load_from_file (params .model .path .c_str (),model_params ); 71 72if (model == NULL ) { 73LOG_ERR ("%s: unable to load model\n" ,__func__ ); 74return 1 ; 75 } 76 77const llama_vocab * vocab = llama_model_get_vocab (model ); 78 79// initialize the context 80 81llama_context_params ctx_params = common_context_params_to_llama (params ); 82 83ctx_params .n_ctx = llama_model_n_ctx_train (model )* n_grp + n_keep ; 84 85GGML_ASSERT (ctx_params .n_batch %n_grp == 0 && "n_batch must be divisible by n_grp" ); 86 87llama_context * ctx = llama_init_from_model (model ,ctx_params ); 88if (ctx == NULL ) { 89LOG_ERR ("%s: failed to create the llama_context\n" ,__func__ ); 90return 1 ; 91 } 92 93auto sparams = llama_sampler_chain_default_params (); 94 95llama_sampler * smpl = llama_sampler_chain_init (sparams ); 96 97llama_sampler_chain_add (smpl ,llama_sampler_init_greedy ()); 98 99// tokenize the prompt 100 std::vector < llama_token > tokens_list ; 101tokens_list = common_tokenize (ctx ,params .prompt , true); 102 103// tokenize the prefix and use it as a sink 104const int n_tokens_prefix = common_tokenize (ctx ,prompt_prefix , true).size (); 105 106const int n_tokens_all = tokens_list .size (); 107 108// we leave a margin of 16 tokens for the generated text - it should contain just the passkey 109const int n_predict = 16 ; 110 111// total length of the sequences including the prompt 112const int n_len = n_tokens_all + n_predict ; 113 114const int n_ctx = llama_n_ctx (ctx )- n_keep ; 115const int n_kv_req = llama_n_ctx (ctx ); 116const int n_batch = ctx_params .n_batch ; 117const int n_batch_grp = ctx_params .n_batch /n_grp ; 118 119LOG_INF ("\n%s: n_len = %d, n_ctx = %d, n_kv_req = %d, n_grp = %d, n_batch = %d, n_junk = %d, i_pos = %d\n" ,__func__ ,n_len ,n_ctx ,n_kv_req ,n_grp ,n_batch ,n_junk ,i_pos ); 120 121// print the prompt token-by-token 122 123LOG_INF ("\n" ); 124LOG_INF ("prefix tokens: %d\n" ,n_tokens_prefix ); 125LOG_INF ("prompt tokens: %d\n" ,n_tokens_all ); 126//LOG_INF("prompt: %s\n", params.prompt.c_str()); 127 128llama_batch batch = llama_batch_init (params .n_batch ,0 ,1 ); 129 130int n_past = 0 ; 131 132auto * mem = llama_get_memory (ctx ); 133 134// fill the KV cache 135for (int i = 0 ;i < n_ctx ;i += n_batch ) { 136if (i > 0 && n_grp > 1 ) { 137// if SelfExtend is enabled, we compress the position from the last batch by a factor of n_grp 138const int ib = i /n_batch - 1 ; 139const int bd = n_batch_grp * (n_grp - 1 ); 140 141llama_memory_seq_add (mem ,0 ,n_past - n_batch ,n_past ,ib * bd ); 142llama_memory_seq_div (mem ,0 ,n_past - n_batch + ib * bd ,n_past + ib * bd ,n_grp ); 143 144n_past = llama_memory_seq_pos_max (mem ,0 )+ 1 ; 145 } 146 147common_batch_clear (batch ); 148 149for (int j = 0 ;j < n_batch && i + j < n_tokens_all ;j ++ ) { 150common_batch_add (batch ,tokens_list [i + j ],n_past ++ , {0 }, false); 151 } 152 153if (i + n_batch >=n_tokens_all ) { 154batch .logits [batch .n_tokens - 1 ]= true; 155 } 156 157if (llama_decode (ctx ,batch )!= 0 ) { 158LOG_INF ("%s: llama_decode() failed\n" ,__func__ ); 159return 1 ; 160 } 161 162LOG_INF ("%s: processed: [%6d, %6d)\n" ,__func__ ,i , std::min (i + n_batch ,n_tokens_all )); 163 164if (i + n_batch >=n_tokens_all ) { 165break ; 166 } 167 } 168 169for (int i = n_ctx ;i < n_tokens_all ;i += n_batch ) { 170const int n_discard = n_batch ; 171 172LOG_INF ("%s: shifting KV cache with %d\n" ,__func__ ,n_discard ); 173 174llama_memory_seq_rm (mem ,0 ,n_keep ,n_keep + n_discard ); 175llama_memory_seq_add (mem ,0 ,n_keep + n_discard ,n_ctx ,- n_discard ); 176 177n_past = llama_memory_seq_pos_max (mem ,0 )+ 1 ; 178 179common_batch_clear (batch ); 180 181for (int j = 0 ;j < n_batch && i + j < n_tokens_all ;j ++ ) { 182common_batch_add (batch ,tokens_list [i + j ],n_past ++ , {0 }, false); 183 } 184 185if (i + n_batch >=n_tokens_all ) { 186batch .logits [batch .n_tokens - 1 ]= true; 187 } 188 189if (llama_decode (ctx ,batch )!= 0 ) { 190LOG_ERR ("%s: llama_decode() failed\n" ,__func__ ); 191return 1 ; 192 } 193 194LOG_INF ("%s: processed: [%6d, %6d)\n" ,__func__ ,i , std::min (i + n_batch ,n_tokens_all )); 195 } 196 197 { 198const int n_discard = n_past - n_ctx + n_predict ; 199 200if (n_discard > 0 ) { 201LOG_INF ("%s: shifting KV cache with %d to free space for the answer\n" ,__func__ ,n_discard ); 202 203llama_memory_seq_rm (mem ,0 ,n_keep ,n_keep + n_discard ); 204llama_memory_seq_add (mem ,0 ,n_keep + n_discard ,n_ctx ,- n_discard ); 205 206n_past = llama_memory_seq_pos_max (mem ,0 )+ 1 ; 207 } 208 } 209 210LOG_INF ("\n" ); 211LOG_INF ("%s: passkey = %d, inserted at position %d / %d (token pos: ~%d)\n" ,__func__ ,passkey ,i_pos ,n_junk , (i_pos * n_tokens_all ) /n_junk ); 212LOG_INF ("\n" ); 213 214// main loop 215 216int n_cur = n_tokens_all ; 217int n_decode = 0 ; 218 219LOG_INF ("%s" ,prompt_suffix .c_str ()); 220 221const auto t_main_start = ggml_time_us (); 222 223while (n_cur <=n_len ) { 224// sample the next token 225 { 226const llama_token new_token_id = llama_sampler_sample (smpl ,ctx ,batch .n_tokens - 1 ); 227 228// is it an end of generation? 229if (llama_vocab_is_eog (vocab ,new_token_id )|| n_cur == n_len ) { 230LOG ("\n" ); 231 232break ; 233 } 234 235LOG ("%s" ,common_token_to_piece (ctx ,new_token_id ).c_str ()); 236 237n_decode += 1 ; 238 239// prepare the next batch 240common_batch_clear (batch ); 241 242// push this new token for next evaluation 243common_batch_add (batch ,new_token_id ,n_past ++ , {0 }, true); 244 } 245 246n_cur += 1 ; 247 248// evaluate the current batch with the transformer model 249if (llama_decode (ctx ,batch )) { 250LOG_ERR ("%s : failed to eval, return code %d\n" ,__func__ ,1 ); 251return 1 ; 252 } 253 } 254 255LOG ("\n" ); 256 257const auto t_main_end = ggml_time_us (); 258 259LOG_INF ("%s: decoded %d tokens in %.2f s, speed: %.2f t/s\n" , 260__func__ ,n_decode , (t_main_end - t_main_start ) /1000000.0f ,n_decode / ((t_main_end - t_main_start ) /1000000.0f )); 261 262LOG ("\n" ); 263llama_perf_context_print (ctx ); 264 265LOG ("\n" ); 266 267llama_sampler_free (smpl ); 268 269llama_batch_free (batch ); 270 271llama_free (ctx ); 272llama_model_free (model ); 273 274llama_backend_free (); 275 276return 0 ; 277}