char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
dd1ea5243
char/aliceai-t5-moe
1#include "sampling.h" 2 3#include "common.h" 4#include "fit.h" 5#include "log.h" 6#include "reasoning-budget.h" 7 8#include "ggml.h" 9 10#include <algorithm> 11#include <cctype> 12#include <climits> 13#include <cmath> 14#include <cstring> 15#include <unordered_map> 16#include <vector> 17 18// the ring buffer works similarly to std::deque, but with a fixed capacity 19// TODO: deduplicate with llama-impl.h 20template < typename T > 21struct ring_buffer { 22ring_buffer (size_t cap ) :capacity (cap ),data (cap ) {} 23 24T & front () { 25if (sz == 0 ) { 26throw std::runtime_error ("ring buffer is empty" ); 27 } 28return data [first ]; 29 } 30 31const T & front ()const { 32if (sz == 0 ) { 33throw std::runtime_error ("ring buffer is empty" ); 34 } 35return data [first ]; 36 } 37 38T & back () { 39if (sz == 0 ) { 40throw std::runtime_error ("ring buffer is empty" ); 41 } 42return data [pos ]; 43 } 44 45const T & back ()const { 46if (sz == 0 ) { 47throw std::runtime_error ("ring buffer is empty" ); 48 } 49return data [pos ]; 50 } 51 52void push_back (const T & value ) { 53if (sz == capacity ) { 54// advance the start when buffer is full 55first = (first + 1 ) %capacity ; 56 }else { 57sz ++ ; 58 } 59data [pos ]= value ; 60pos = (pos + 1 ) %capacity ; 61 } 62 63T pop_front () { 64if (sz == 0 ) { 65throw std::runtime_error ("ring buffer is empty" ); 66 } 67T value = data [first ]; 68first = (first + 1 ) %capacity ; 69sz -- ; 70return value ; 71 } 72 73const T & rat (size_t i )const { 74if (i >=sz ) { 75throw std::runtime_error ("ring buffer: index out of bounds" ); 76 } 77return data [(first + sz - i - 1 ) %capacity ]; 78 } 79 80 std::vector < T > to_vector ()const { 81 std::vector < T > result ; 82result .reserve (sz ); 83for (size_t i = 0 ;i < sz ;i ++ ) { 84result .push_back (data [(first + i ) %capacity ]); 85 } 86return result ; 87 } 88 89void clear () { 90// here only reset the status of the buffer 91sz = 0 ; 92first = 0 ; 93pos = 0 ; 94 } 95 96bool empty ()const { 97return sz == 0 ; 98 } 99 100size_t size ()const { 101return sz ; 102 } 103 104size_t capacity = 0 ; 105size_t sz = 0 ; 106size_t first = 0 ; 107size_t pos = 0 ; 108 std::vector < T > data ; 109}; 110 111struct common_sampler { 112common_params_sampling params ; 113 114struct llama_sampler * grmr ; 115struct llama_sampler * rbudget ; 116struct llama_sampler * chain ; 117 118ring_buffer < llama_token > prev ; 119 120 std::vector < llama_token_data > cur ; 121 122llama_token_data_array cur_p ; 123 124void reset () { 125prev .clear (); 126 127llama_sampler_reset (chain ); 128 } 129 130void set_logits (struct llama_context * ctx ,int idx ) { 131const float * sampled_probs = llama_get_sampled_probs_ith (ctx ,idx ); 132const float * sampled_logits = llama_get_sampled_logits_ith (ctx ,idx ); 133const llama_token * sampled_ids = llama_get_sampled_candidates_ith (ctx ,idx ); 134 135const llama_model * model = llama_get_model (ctx ); 136const llama_vocab * vocab = llama_model_get_vocab (model ); 137 138const int n_vocab = llama_vocab_n_tokens (vocab ); 139 140if (sampled_probs ) { 141const uint32_t sampled_probs_count = llama_get_sampled_probs_count_ith (ctx ,idx ); 142cur .resize (sampled_probs_count ); 143for (uint32_t i = 0 ;i < sampled_probs_count ;++ i ) { 144cur [i ]= llama_token_data {sampled_ids [i ],sampled_logits [i ],sampled_probs [i ]}; 145 } 146 }else if (sampled_logits ) { 147const uint32_t sampled_logits_count = llama_get_sampled_logits_count_ith (ctx ,idx ); 148cur .resize (sampled_logits_count ); 149for (uint32_t i = 0 ;i < sampled_logits_count ;i ++ ) { 150cur [i ]= llama_token_data {sampled_ids [i ],sampled_logits [i ],0.0f }; 151 } 152 }else { 153const auto * logits = llama_get_logits_ith (ctx ,idx ); 154GGML_ASSERT (logits != nullptr ); 155cur .resize (n_vocab ); 156for (llama_token token_id = 0 ;token_id < n_vocab ;token_id ++ ) { 157cur [token_id ]= llama_token_data {token_id ,logits [token_id ],0.0f }; 158 } 159 } 160 161cur_p = {cur .data (),cur .size (),-1 , false }; 162 } 163 164common_time_meas tm () { 165return common_time_meas (t_total_us ,params .no_perf ); 166 } 167 168mutable int64_t t_total_us = 0 ; 169}; 170 171std::string common_params_sampling::const { 172char result [1024 ]; 173 174snprintf (result ,sizeof (result ), 175"\trepeat_last_n = %d, repeat_penalty = %.3f, frequency_penalty = %.3f, presence_penalty = %.3f\n" 176"\tdry_multiplier = %.3f, dry_base = %.3f, dry_allowed_length = %d, dry_penalty_last_n = %d\n" 177"\ttop_k = %d, top_p = %.3f, min_p = %.3f, xtc_probability = %.3f, xtc_threshold = %.3f, typical_p = %.3f, top_n_sigma = %.3f, temp = %.3f\n" 178"\tmirostat = %d, mirostat_lr = %.3f, mirostat_ent = %.3f, adaptive_target = %.3f, adaptive_decay = %.3f" , 179penalty_last_n ,penalty_repeat ,penalty_freq ,penalty_present , 180dry_multiplier ,dry_base ,dry_allowed_length ,dry_penalty_last_n , 181top_k ,top_p ,min_p ,xtc_probability ,xtc_threshold ,typ_p ,top_n_sigma ,temp , 182mirostat ,mirostat_eta ,mirostat_tau ,adaptive_target ,adaptive_decay ); 183 184return std::string (result ); 185} 186 187struct common_sampler * common_sampler_init ( 188const struct llama_model * model , 189struct common_params_sampling & params ) { 190if (!std::isfinite (params .penalty_repeat )|| 191params .penalty_repeat <=0.0f || 192 !std::isfinite (1.0f /params .penalty_repeat )) { 193throw std::invalid_argument ("penalty_repeat must be finite and greater than 0" ); 194 } 195if (!std::isfinite (params .penalty_freq )) { 196throw std::invalid_argument ("penalty_freq must be finite" ); 197 } 198if (!std::isfinite (params .penalty_present )) { 199throw std::invalid_argument ("penalty_present must be finite" ); 200 } 201const llama_vocab * vocab = llama_model_get_vocab (model ); 202llama_sampler_chain_params lparams = llama_sampler_chain_default_params (); 203 204lparams .no_perf = params .no_perf ; 205 206llama_sampler * grmr = nullptr ; 207llama_sampler * rbudget = nullptr ; 208llama_sampler * chain = llama_sampler_chain_init (lparams ); 209 210 std::vector < llama_sampler *> samplers ; 211 212const std::string & grammar_str = common_grammar_value (params .grammar ); 213if (grammar_str .compare (0 ,11 ,"%llguidance" )== 0 ) { 214#ifdef LLAMA_USE_LLGUIDANCE 215grmr = llama_sampler_init_llg (vocab ,"lark" ,grammar_str .c_str ()); 216#else 217GGML_ABORT ("llguidance (cmake -DLLAMA_LLGUIDANCE=ON) is not enabled" ); 218#endif // LLAMA_USE_LLGUIDANCE 219 }else { 220 std::vector < std::string > trigger_patterns ; 221 std::vector < llama_token > trigger_tokens ; 222for (const auto & trigger :params .grammar_triggers ) { 223switch (trigger .type ) { 224case COMMON_GRAMMAR_TRIGGER_TYPE_WORD : 225 { 226const auto & word = trigger .value ; 227trigger_patterns .push_back (regex_escape (word )); 228break ; 229 } 230case COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN : 231 { 232trigger_patterns .push_back (trigger .value ); 233break ; 234 } 235case COMMON_GRAMMAR_TRIGGER_TYPE_PATTERN_FULL : 236 { 237const auto & pattern = trigger .value ; 238 std::string anchored = "^$" ; 239if (!pattern .empty ()) { 240anchored = (pattern .front ()!= '^' ?"^" :"" ) 241+ pattern 242+ (pattern .back ()!= '$' ?"$" :"" ); 243 } 244trigger_patterns .push_back (anchored ); 245break ; 246 } 247case COMMON_GRAMMAR_TRIGGER_TYPE_TOKEN : 248 { 249const auto token = trigger .token ; 250trigger_tokens .push_back (token ); 251break ; 252 } 253default : 254GGML_ASSERT (false&& "unknown trigger type" ); 255 } 256 } 257 258 std::vector < const char *> trigger_patterns_c ; 259trigger_patterns_c .reserve (trigger_patterns .size ()); 260for (const auto & regex :trigger_patterns ) { 261trigger_patterns_c .push_back (regex .c_str ()); 262 } 263 264if (!grammar_str .empty ()) { 265if (params .grammar_lazy ) { 266grmr = llama_sampler_init_grammar_lazy_patterns (vocab ,grammar_str .c_str (),"root" , 267trigger_patterns_c .data (),trigger_patterns_c .size (), 268trigger_tokens .data (),trigger_tokens .size ()); 269 }else { 270grmr = llama_sampler_init_grammar (vocab ,grammar_str .c_str (),"root" ); 271 } 272 } 273 } 274if (!grmr && !grammar_str .empty ()) { 275throw std::runtime_error ("failed to parse grammar" ); 276 } 277 278// Compute prefill tokens from the generation prompt 279 std::vector < llama_token > prefill_tokens ; 280if (!params .generation_prompt .empty ()) { 281GGML_ASSERT (vocab != nullptr ); 282auto tokens = common_tokenize (vocab ,params .generation_prompt , false, true); 283for (size_t i = 0 ;i < tokens .size ();i ++ ) { 284 std::string piece = common_token_to_piece (vocab ,tokens [i ], true); 285if (i == 0 && std::isspace (piece [0 ])&& !std::isspace (params .generation_prompt [0 ])) { 286// Some tokenizers will add a space before the first special token, need to exclude 287continue ; 288 } 289LOG_DBG ("%s: prefill token: %d = %s\n" ,__func__ ,tokens [i ],piece .c_str ()); 290prefill_tokens .push_back (tokens [i ]); 291 } 292 } 293 294// Feed generation prompt tokens to the grammar sampler so it advances past 295// tokens the template already placed in the prompt. 296// Only applies to output-format and tool-call grammars; user-supplied grammars must not be prefilled. 297if (grmr && !params .grammar_lazy && common_grammar_needs_prefill (params .grammar )) { 298try { 299for (const auto & token :prefill_tokens ) { 300llama_sampler_accept (grmr ,token ); 301LOG_DBG ("%s: grammar accepted prefill token (%d)\n" ,__func__ ,token ); 302 } 303 }catch (std::exception & e ) { 304LOG_ERR ("%s: error initializing grammar sampler for grammar:\n%s\n\nGeneration prompt:\n'%s'\n" ,__func__ , 305common_grammar_value (params .grammar ).c_str (),params .generation_prompt .c_str ()); 306throw e ; 307 } 308 } 309 310// reasoning budget sampler (skip when budget is unlimited unless a lazy grammar is active, which needs rbudget for thinking-block suppression) 311if (!params .reasoning_budget_start .empty ()&& !params .reasoning_budget_end .empty ()&& (params .grammar_lazy || params .reasoning_budget_tokens >=0 || params .reasoning_control )) { 312rbudget = common_reasoning_budget_init ( 313vocab , 314 {params .reasoning_budget_start }, 315params .reasoning_budget_end , 316params .reasoning_budget_forced , 317params .reasoning_budget_tokens < 0 ?INT_MAX :params .reasoning_budget_tokens ); 318 319for (const auto & token :prefill_tokens ) { 320llama_sampler_accept (rbudget ,token ); 321LOG_DBG ("%s: reasoning-budget accepted prefill token (%d)\n" ,__func__ ,token ); 322 } 323 } 324 325// logit bias: user biases + model suppress tokens (-INFINITY) 326 { 327 std::vector < llama_logit_bias > merged = params .logit_bias ; 328 329int32_t n_suppress = 0 ; 330const llama_token * suppress = llama_vocab_get_suppress_tokens (vocab ,& n_suppress ); 331for (int32_t i = 0 ;i < n_suppress ;++ i ) { 332merged .push_back ({suppress [i ],- INFINITY }); 333 } 334 335if (!merged .empty ()) { 336samplers .push_back (llama_sampler_init_logit_bias (llama_vocab_n_tokens (vocab ),merged .size (),merged .data ())); 337 } 338 } 339 340if (params .mirostat == 0 ) { 341 342bool use_adaptive_p = false;// see below 343 344for (const auto & cnstr :params .samplers ) { 345switch (cnstr ) { 346case COMMON_SAMPLER_TYPE_DRY : 347 { 348 std::vector < const char *> c_breakers ; 349c_breakers .reserve (params .dry_sequence_breakers .size ()); 350for (const auto & str :params .dry_sequence_breakers ) { 351c_breakers .push_back (str .c_str ()); 352 } 353samplers .push_back (llama_sampler_init_dry (vocab ,params .dry_multiplier ,params .dry_base ,params .dry_allowed_length ,params .dry_penalty_last_n ,c_breakers .data (),c_breakers .size ())); 354 } 355break ; 356case COMMON_SAMPLER_TYPE_TOP_K : 357samplers .push_back (llama_sampler_init_top_k (params .top_k )); 358break ; 359case COMMON_SAMPLER_TYPE_TOP_P : 360samplers .push_back (llama_sampler_init_top_p (params .top_p ,params .min_keep )); 361break ; 362case COMMON_SAMPLER_TYPE_TOP_N_SIGMA : 363samplers .push_back (llama_sampler_init_top_n_sigma (params .top_n_sigma )); 364break ; 365case COMMON_SAMPLER_TYPE_MIN_P : 366samplers .push_back (llama_sampler_init_min_p (params .min_p ,params .min_keep )); 367break ; 368case COMMON_SAMPLER_TYPE_XTC : 369samplers .push_back (llama_sampler_init_xtc (params .xtc_probability ,params .xtc_threshold ,params .min_keep ,params .seed )); 370break ; 371case COMMON_SAMPLER_TYPE_TYPICAL_P : 372samplers .push_back (llama_sampler_init_typical (params .typ_p ,params .min_keep )); 373break ; 374case COMMON_SAMPLER_TYPE_TEMPERATURE : 375samplers .push_back (llama_sampler_init_temp_ext (params .temp ,params .dynatemp_range ,params .dynatemp_exponent )); 376break ; 377case COMMON_SAMPLER_TYPE_INFILL : 378samplers .push_back (llama_sampler_init_infill (vocab )); 379break ; 380case COMMON_SAMPLER_TYPE_PENALTIES : 381samplers .push_back (llama_sampler_init_penalties (llama_vocab_n_tokens (vocab ),params .penalty_last_n ,params .penalty_repeat ,params .penalty_freq ,params .penalty_present )); 382break ; 383case COMMON_SAMPLER_TYPE_ADAPTIVE_P : 384// the `adaptive-p` sampler is like `dist` and `mirostat` in that it selects 385// a single token, so we will add `dist` at the end of the chain by default, 386// unless the user specifically included `adaptive-p`. we set this flag here 387// so we know to add the sampler at the very end. 388use_adaptive_p = true; 389break ; 390default : 391GGML_ASSERT (false&& "unknown sampler type" ); 392 } 393 } 394if (use_adaptive_p ) { 395// only if user explicitly included adaptive-p sampler 396samplers .push_back (llama_sampler_init_adaptive_p (params .adaptive_target ,params .adaptive_decay ,params .seed )); 397 }else { 398// default: sample from distribution 399samplers .push_back (llama_sampler_init_dist (params .seed )); 400 } 401 }else if (params .mirostat == 1 ) { 402samplers .push_back (llama_sampler_init_temp (params .temp )); 403samplers .push_back (llama_sampler_init_mirostat (llama_vocab_n_tokens (vocab ),params .seed ,params .mirostat_tau ,params .mirostat_eta ,100 )); 404 }else if (params .mirostat == 2 ) { 405samplers .push_back (llama_sampler_init_temp (params .temp )); 406samplers .push_back (llama_sampler_init_mirostat_v2 (params .seed ,params .mirostat_tau ,params .mirostat_eta )); 407 }else { 408GGML_ASSERT (false&& "unknown mirostat version" ); 409 } 410 411for (auto * smpl :samplers ) { 412llama_sampler_chain_add (chain ,smpl ); 413 } 414 415if (grmr && params .backend_sampling ) { 416LOG_WRN ("%s: backend sampling is not compatible with grammar, disabling\n" ,__func__ ); 417 418params .backend_sampling = false; 419 } 420 421if (rbudget && params .backend_sampling ) { 422LOG_WRN ("%s: backend sampling is not compatible with reasoning budget, disabling\n" ,__func__ ); 423 424params .backend_sampling = false; 425 } 426 427auto * result = new common_sampler { 428/* .params = */ params , 429/* .grmr = */ grmr , 430/* .rbudget = */ rbudget , 431/* .chain = */ chain , 432/* .prev = */ ring_buffer < llama_token > (std::max (32 ,params .n_prev )), 433/* .cur = */ {}, 434/* .cur_p = */ {}, 435 }; 436 437return result ; 438} 439 440void common_sampler_free (struct common_sampler * gsmpl ) { 441if (!gsmpl ) { 442return ; 443 } 444 445llama_sampler_free (gsmpl -> grmr ); 446llama_sampler_free (gsmpl -> rbudget ); 447llama_sampler_free (gsmpl -> chain ); 448 449delete gsmpl ; 450} 451 452static bool grammar_should_apply (struct common_sampler * gsmpl ) { 453if (!gsmpl -> grmr ) { 454return false; 455 } 456if (!gsmpl -> rbudget ) { 457return true; 458 } 459if (gsmpl -> params .grammar_lazy ) { 460// if grammar is lazy, only apply when reasoning budget is not active 461const auto state = common_reasoning_budget_get_state (gsmpl -> rbudget ); 462return state == REASONING_BUDGET_IDLE || state == REASONING_BUDGET_DONE ; 463 } 464return true; 465} 466 467void common_sampler_accept (struct common_sampler * gsmpl ,llama_token token ,bool is_generated ) { 468if (!gsmpl ) { 469return ; 470 } 471 472const auto tm = gsmpl -> tm (); 473 474// grammar_should_apply() checks the reasoning budget state, so calculate this before we accept 475const auto accept_grammar = is_generated && grammar_should_apply (gsmpl ); 476 477if (gsmpl -> rbudget && is_generated ) { 478llama_sampler_accept (gsmpl -> rbudget ,token ); 479 480// if done, replay end sequence which may contain a grammar trigger 481const bool is_done = common_reasoning_budget_get_state (gsmpl -> rbudget )== REASONING_BUDGET_DONE ; 482if (gsmpl -> grmr && !accept_grammar && is_done ) { 483const llama_tokens * end_seq = common_reasoning_budget_get_end_match (gsmpl -> rbudget ); 484if (end_seq ) { 485for (const llama_token end_token :* end_seq ) { 486llama_sampler_accept (gsmpl -> grmr ,end_token ); 487 } 488 } 489 } 490 } 491 492if (gsmpl -> grmr && accept_grammar ) { 493llama_sampler_accept (gsmpl -> grmr ,token ); 494 } 495 496llama_sampler_accept (gsmpl -> chain ,token ); 497 498gsmpl -> prev .push_back (token ); 499} 500 501void common_sampler_reset (struct common_sampler * gsmpl ) { 502if (!gsmpl ) { 503return ; 504 } 505 506gsmpl -> reset (); 507} 508 509struct common_sampler * common_sampler_clone (common_sampler * gsmpl ) { 510return new common_sampler { 511/* .params = */ gsmpl -> params , 512/* .grmr = */ llama_sampler_clone (gsmpl -> grmr ), 513/* .rbudget = */ llama_sampler_clone (gsmpl -> rbudget ), 514/* .chain = */ llama_sampler_clone (gsmpl -> chain ), 515/* .prev = */ gsmpl -> prev , 516/* .cur = */ gsmpl -> cur , 517/* .cur_p = */ gsmpl -> cur_p , 518 }; 519} 520 521void common_sampler_copy (const common_sampler * src ,common_sampler * dst ) { 522if (!src || !dst || src == dst ) { 523return ; 524 } 525 526GGML_ASSERT ((src -> grmr == nullptr )== (dst -> grmr == nullptr )); 527GGML_ASSERT ((src -> rbudget == nullptr )== (dst -> rbudget == nullptr )); 528 529llama_sampler_copy (src -> grmr ,dst -> grmr ); 530llama_sampler_copy (src -> rbudget ,dst -> rbudget ); 531llama_sampler_copy (src -> chain ,dst -> chain ); 532 533dst -> params = src -> params ; 534dst -> prev = src -> prev ; 535dst -> cur = src -> cur ; 536dst -> cur_p = src -> cur_p ; 537dst -> cur_p .data = src -> cur_p .data ?dst -> cur .data () :nullptr ;// re-point to dst's buffer 538dst -> t_total_us = src -> t_total_us ; 539} 540 541void common_perf_print (const struct llama_context * ctx ,const struct common_sampler * gsmpl ) { 542// TODO: measure grammar performance 543 544const double t_sampling_ms = gsmpl ?1e-3 * gsmpl -> t_total_us :0 ; 545 546llama_perf_sampler_data data_smpl ; 547llama_perf_context_data data_ctx ; 548 549memset (& data_smpl ,0 ,sizeof (data_smpl )); 550memset (& data_ctx ,0 ,sizeof (data_ctx )); 551 552if (gsmpl ) { 553auto & data = data_smpl ; 554 555data = llama_perf_sampler (gsmpl -> chain ); 556 557// note: the sampling time includes the samplers time + extra time spent in common/sampling 558LOG_INF ("%s: sampling time = %10.2f ms\n" ,__func__ ,t_sampling_ms ); 559LOG_INF ("%s: samplers time = %10.2f ms / %5d tokens\n" ,__func__ ,data .t_sample_ms ,data .n_sample ); 560 } 561 562if (ctx ) { 563auto & data = data_ctx ; 564 565data = llama_perf_context (ctx ); 566 567const double t_end_ms = 1e-3 * ggml_time_us (); 568 569const double t_total_ms = t_end_ms - data .t_start_ms ; 570const double t_unacc_ms = t_total_ms - (t_sampling_ms + data .t_p_eval_ms + data .t_eval_ms ); 571const double t_unacc_pc = 100.0 * t_unacc_ms /t_total_ms ; 572 573LOG_INF ("%s: load time = %10.2f ms\n" ,__func__ ,data .t_load_ms ); 574LOG_INF ("%s: prompt eval time = %10.2f ms / %5d tokens (%8.2f ms per token, %8.2f tokens per second)\n" , 575__func__ ,data .t_p_eval_ms ,data .n_p_eval ,data .t_p_eval_ms /data .n_p_eval ,1e3 /data .t_p_eval_ms * data .n_p_eval ); 576LOG_INF ("%s: eval time = %10.2f ms / %5d runs (%8.2f ms per token, %8.2f tokens per second)\n" , 577__func__ ,data .t_eval_ms ,data .n_eval ,data .t_eval_ms /data .n_eval ,1e3 /data .t_eval_ms * data .n_eval ); 578LOG_INF ("%s: total time = %10.2f ms / %5d tokens\n" ,__func__ , (t_end_ms - data .t_start_ms ), (data .n_p_eval + data .n_eval )); 579LOG_INF ("%s: unaccounted time = %10.2f ms / %5.1f %% (total - sampling - prompt eval - eval) / (total)\n" ,__func__ ,t_unacc_ms ,t_unacc_pc ); 580LOG_INF ("%s: graphs reused = %10d\n" ,__func__ ,data .n_reused ); 581 582common_memory_breakdown_print (ctx ); 583 } 584} 585 586struct llama_sampler * common_sampler_get (const struct common_sampler * gsmpl ) { 587if (!gsmpl ) { 588return nullptr ; 589 } 590 591return gsmpl -> chain ; 592} 593 594llama_token common_sampler_sample (struct common_sampler * gsmpl ,struct llama_context * ctx ,int idx ,bool grammar_first ) { 595llama_synchronize (ctx ); 596 597// start measuring sampling time after the llama_context synchronization in order to not measure any ongoing async operations 598const auto tm = gsmpl -> tm (); 599 600llama_token id = LLAMA_TOKEN_NULL ; 601 602auto & grmr = gsmpl -> grmr ; 603auto & rbudget = gsmpl -> rbudget ; 604auto & chain = gsmpl -> chain ; 605auto & cur_p = gsmpl -> cur_p ;// initialized by set_logits 606 607gsmpl -> set_logits (ctx ,idx ); 608 609// Check if a backend sampler has already sampled a token in which case we 610// return that token id directly. 611 { 612id = llama_get_sampled_token_ith (ctx ,idx ); 613 614if (id != LLAMA_TOKEN_NULL ) { 615LOG_DBG ("%s: Backend sampler selected token: '%d'. Will not run any CPU samplers\n" ,__func__ ,id ); 616 617GGML_ASSERT (!gsmpl -> grmr && "using grammar in combination with backend sampling is not supported" ); 618GGML_ASSERT (!gsmpl -> rbudget && "using reasoning budget in combination with backend sampling is not supported" ); 619 620for (size_t i = 0 ;i < cur_p .size ;++ i ) { 621if (cur_p .data [i ].id == id ) { 622cur_p .selected = i ; 623break ; 624 } 625 } 626 627return id ; 628 } 629 } 630 631// apply reasoning budget first 632llama_sampler_apply (rbudget ,& cur_p ); 633 634if (grammar_first && grammar_should_apply (gsmpl )) { 635llama_sampler_apply (grmr ,& cur_p ); 636 } 637 638llama_sampler_apply (chain ,& cur_p ); 639 640id = cur_p .data [cur_p .selected ].id ; 641 642if (grammar_first || !grammar_should_apply (gsmpl )) { 643return id ; 644 } 645 646// check if it the sampled token fits the grammar (grammar-based rejection sampling) 647 { 648llama_token_data single_token_data = {id ,1.0f ,0.0f }; 649llama_token_data_array single_token_data_array = {& single_token_data ,1 ,-1 , false }; 650 651llama_sampler_apply (grmr ,& single_token_data_array ); 652 653const bool is_valid = single_token_data_array .data [0 ].logit != - INFINITY ; 654if (is_valid ) { 655return id ; 656 } 657 } 658 659// resampling: 660// if the token is not valid, sample again, but first apply the grammar sampler and then the sampling chain 661gsmpl -> set_logits (ctx ,idx ); 662 663llama_sampler_apply (rbudget ,& cur_p ); 664 665if (grammar_should_apply (gsmpl )) { 666llama_sampler_apply (grmr ,& cur_p ); 667 } 668 669llama_sampler_apply (chain ,& cur_p ); 670 671GGML_ASSERT (cur_p .selected != -1 && "no selected token during sampling - check your sampling configuration" ); 672 673id = cur_p .data [cur_p .selected ].id ; 674 675return id ; 676} 677 678std::vector < llama_token > common_sampler_sample_and_accept_n (struct common_sampler * gsmpl ,struct llama_context * ctx ,const std::vector < int > & idxs ,const llama_tokens & draft ,bool grammar_first ) { 679GGML_ASSERT (idxs .size ()== draft .size ()+ 1 && "idxs.size() must be draft.size() + 1" ); 680 681 std::vector < llama_token > result ; 682result .reserve (idxs .size ()); 683 684size_t i = 0 ; 685for (;i < draft .size ();i ++ ) { 686const llama_token id = common_sampler_sample (gsmpl ,ctx ,idxs [i ],grammar_first ); 687 688common_sampler_accept (gsmpl ,id , true); 689 690result .push_back (id ); 691 692if (draft [i ]!= id ) { 693break ; 694 } 695 } 696 697if (i == draft .size ()) { 698const llama_token id = common_sampler_sample (gsmpl ,ctx ,idxs [i ],grammar_first ); 699 700common_sampler_accept (gsmpl ,id , true); 701 702result .push_back (id ); 703 } 704 705return result ; 706} 707 708std::vector < llama_token > common_sampler_sample_and_accept_n (struct common_sampler * gsmpl ,struct llama_context * ctx ,const llama_tokens & draft ,bool grammar_first ) { 709 std::vector < int > idxs (draft .size ()+ 1 ); 710for (size_t i = 0 ;i < idxs .size ();++ i ) { 711idxs [i ]= i ; 712 } 713 714return common_sampler_sample_and_accept_n (gsmpl ,ctx ,idxs ,draft ,grammar_first ); 715} 716 717uint32_t common_sampler_get_seed (const struct common_sampler * gsmpl ) { 718return llama_sampler_get_seed (gsmpl -> chain ); 719} 720 721bool common_sampler_reasoning_budget_force (struct common_sampler * gsmpl ) { 722if (!gsmpl ) { 723return false; 724 } 725 726return common_reasoning_budget_force (gsmpl -> rbudget ); 727} 728 729// helpers 730 731llama_token_data_array * common_sampler_get_candidates (struct common_sampler * gsmpl ,bool do_sort ) { 732const auto tm = gsmpl -> tm (); 733 734auto * res = & gsmpl -> cur_p ; 735 736if (do_sort && !res -> sorted ) { 737// remember the selected token before sorting 738const llama_token id = res -> data [res -> selected ].id ; 739 740 std::sort (res -> data ,res -> data + res -> size , [](const llama_token_data & a ,const llama_token_data & b ) { 741return a .p > b .p ; 742 }); 743 744// restore the selected token after sorting 745for (size_t i = 0 ;i < res -> size ;++ i ) { 746if (res -> data [i ].id == id ) { 747res -> selected = i ; 748break ; 749 } 750 } 751 752res -> sorted = true; 753 } 754 755return res ; 756} 757 758llama_token common_sampler_last (const struct common_sampler * gsmpl ) { 759return gsmpl -> prev .rat (0 ); 760} 761 762std::string common_sampler_print (const struct common_sampler * gsmpl ) { 763 std::string result = "logits " ; 764 765for (int i = 0 ;i < llama_sampler_chain_n (gsmpl -> chain );i ++ ) { 766const auto * smpl = llama_sampler_chain_get (gsmpl -> chain ,i ); 767result += std::string ("-> " ); 768result += std::string (llama_sampler_name (smpl ))+ " " ; 769 } 770 771return result ; 772} 773 774std::string common_sampler_prev_str (common_sampler * gsmpl ,llama_context * ctx_main ,int n ) { 775n = std::min (n , (int )gsmpl -> prev .size ()); 776 777if (n <=0 ) { 778return "" ; 779 } 780 781 std::string result ; 782result .reserve (8 * n );// 8 is the average length of a token [citation needed], TODO: compute this from the vocab 783 784for (int i = n - 1 ;i >=0 ;i -- ) { 785const llama_token id = gsmpl -> prev .rat (i ); 786 787GGML_ASSERT (id != LLAMA_TOKEN_NULL && "null token in the sampling history - should not happen" ); 788 789result += common_token_to_piece (ctx_main ,id ); 790 } 791 792return result ; 793} 794 795char common_sampler_type_to_chr (enum common_sampler_type cnstr ) { 796switch (cnstr ) { 797case COMMON_SAMPLER_TYPE_DRY :return 'd' ; 798case COMMON_SAMPLER_TYPE_TOP_K :return 'k' ; 799case COMMON_SAMPLER_TYPE_TYPICAL_P :return 'y' ; 800case COMMON_SAMPLER_TYPE_TOP_P :return 'p' ; 801case COMMON_SAMPLER_TYPE_TOP_N_SIGMA :return 's' ; 802case COMMON_SAMPLER_TYPE_MIN_P :return 'm' ; 803case COMMON_SAMPLER_TYPE_TEMPERATURE :return 't' ; 804case COMMON_SAMPLER_TYPE_XTC :return 'x' ; 805case COMMON_SAMPLER_TYPE_INFILL :return 'i' ; 806case COMMON_SAMPLER_TYPE_PENALTIES :return 'e' ; 807case COMMON_SAMPLER_TYPE_ADAPTIVE_P :return 'a' ; 808default :return '?' ; 809 } 810} 811 812std::string common_sampler_type_to_str (enum common_sampler_type cnstr ) { 813switch (cnstr ) { 814case COMMON_SAMPLER_TYPE_DRY :return "dry" ; 815case COMMON_SAMPLER_TYPE_TOP_K :return "top_k" ; 816case COMMON_SAMPLER_TYPE_TYPICAL_P :return "typ_p" ; 817case COMMON_SAMPLER_TYPE_TOP_P :return "top_p" ; 818case COMMON_SAMPLER_TYPE_TOP_N_SIGMA :return "top_n_sigma" ; 819case COMMON_SAMPLER_TYPE_MIN_P :return "min_p" ; 820case COMMON_SAMPLER_TYPE_TEMPERATURE :return "temperature" ; 821case COMMON_SAMPLER_TYPE_XTC :return "xtc" ; 822case COMMON_SAMPLER_TYPE_INFILL :return "infill" ; 823case COMMON_SAMPLER_TYPE_PENALTIES :return "penalties" ; 824case COMMON_SAMPLER_TYPE_ADAPTIVE_P :return "adaptive_p" ; 825default :return "" ; 826 } 827} 828 829std::vector < common_sampler_type > common_sampler_types_from_names (const std::vector < std::string > & names ) { 830// sampler names can be written multiple ways; generate aliases from canonical names 831static const auto sampler_name_map = []{ 832// canonical sampler name mapping 833 std::unordered_map < std::string ,common_sampler_type > canonical_name_map { 834 {"dry" ,COMMON_SAMPLER_TYPE_DRY }, 835 {"top_k" ,COMMON_SAMPLER_TYPE_TOP_K }, 836 {"top_p" ,COMMON_SAMPLER_TYPE_TOP_P }, 837 {"top_n_sigma" ,COMMON_SAMPLER_TYPE_TOP_N_SIGMA }, 838 {"typ_p" ,COMMON_SAMPLER_TYPE_TYPICAL_P }, 839 {"min_p" ,COMMON_SAMPLER_TYPE_MIN_P }, 840 {"temperature" ,COMMON_SAMPLER_TYPE_TEMPERATURE }, 841 {"xtc" ,COMMON_SAMPLER_TYPE_XTC }, 842 {"infill" ,COMMON_SAMPLER_TYPE_INFILL }, 843 {"penalties" ,COMMON_SAMPLER_TYPE_PENALTIES }, 844 {"adaptive_p" ,COMMON_SAMPLER_TYPE_ADAPTIVE_P } 845 }; 846 std::unordered_map < std::string ,common_sampler_type > alias_name_map ; 847for (const auto & entry :canonical_name_map ) { 848const std::string & canonical = entry .first ; 849if (canonical .find ('_' )== std::string::npos ) { 850continue ; 851 } 852// kebab-case: "top-k", "min-p", etc. 853 { 854 std::string kebab_case = canonical ; 855 std::replace (kebab_case .begin (),kebab_case .end (),'_' ,'-' ); 856alias_name_map .insert ({kebab_case ,entry .second }); 857 } 858// no dash: "topk", "minp", etc. 859 { 860 std::string no_dash = canonical ; 861no_dash .erase (std::remove (no_dash .begin (),no_dash .end (),'_' ),no_dash .end ()); 862alias_name_map .insert ({no_dash ,entry .second }); 863 } 864 } 865// misc. aliases 866alias_name_map .insert ({"nucleus" ,COMMON_SAMPLER_TYPE_TOP_P }); 867alias_name_map .insert ({"temp" ,COMMON_SAMPLER_TYPE_TEMPERATURE }); 868alias_name_map .insert ({"typ" ,COMMON_SAMPLER_TYPE_TYPICAL_P }); 869// include aliases + canonical names in the complete mapping 870alias_name_map .merge (canonical_name_map ); 871return alias_name_map ; 872 }(); 873 874 std::vector < common_sampler_type > samplers ; 875samplers .reserve (names .size ()); 876 877for (const auto & name :names ) { 878 std::string name_lower = name ; 879 std::transform (name_lower .begin (),name_lower .end (),name_lower .begin (), ::tolower ); 880auto sampler = sampler_name_map .find (name_lower ); 881if (sampler != sampler_name_map .end ()) { 882samplers .push_back (sampler -> second ); 883continue ; 884 } 885LOG_WRN ("%s: unable to match sampler by name '%s'\n" ,__func__ ,name_lower .c_str ()); 886 } 887 888return samplers ; 889} 890 891std::vector < common_sampler_type > common_sampler_types_from_chars (const std::string & chars ) { 892 std::unordered_map < char ,common_sampler_type > sampler_name_map = { 893 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_DRY ),COMMON_SAMPLER_TYPE_DRY }, 894 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_TOP_K ),COMMON_SAMPLER_TYPE_TOP_K }, 895 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_TYPICAL_P ),COMMON_SAMPLER_TYPE_TYPICAL_P }, 896 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_TOP_P ),COMMON_SAMPLER_TYPE_TOP_P }, 897 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_TOP_N_SIGMA ),COMMON_SAMPLER_TYPE_TOP_N_SIGMA }, 898 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_MIN_P ),COMMON_SAMPLER_TYPE_MIN_P }, 899 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_TEMPERATURE ),COMMON_SAMPLER_TYPE_TEMPERATURE }, 900 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_XTC ),COMMON_SAMPLER_TYPE_XTC }, 901 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_INFILL ),COMMON_SAMPLER_TYPE_INFILL }, 902 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_PENALTIES ),COMMON_SAMPLER_TYPE_PENALTIES }, 903 {common_sampler_type_to_chr (COMMON_SAMPLER_TYPE_ADAPTIVE_P ),COMMON_SAMPLER_TYPE_ADAPTIVE_P }, 904 }; 905 906 std::vector < common_sampler_type > samplers ; 907samplers .reserve (chars .size ()); 908 909for (const auto & c :chars ) { 910const auto sampler = sampler_name_map .find (c ); 911if (sampler != sampler_name_map .end ()) { 912samplers .push_back (sampler -> second ); 913 }else { 914LOG_WRN ("%s: unable to match sampler by char '%c'\n" ,__func__ ,c ); 915 } 916 } 917 918return samplers ; 919}