char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
d9f918d2d
char/aliceai-t5-moe
1#pragma once 2 3#include "common.h" 4#include "llama.h" 5 6#include <string> 7#include <unordered_set> 8#include <list> 9#include <map> 10 11// TODO: prevent including the whole server-common.h as we only use server_tokens 12#include "server-common.h" 13 14 15enum server_task_type { 16SERVER_TASK_TYPE_COMPLETION , 17SERVER_TASK_TYPE_EMBEDDING , 18SERVER_TASK_TYPE_RERANK , 19SERVER_TASK_TYPE_INFILL , 20SERVER_TASK_TYPE_CANCEL , 21SERVER_TASK_TYPE_CONTROL , 22SERVER_TASK_TYPE_NEXT_RESPONSE , 23SERVER_TASK_TYPE_METRICS , 24SERVER_TASK_TYPE_SLOT_GET , 25SERVER_TASK_TYPE_SLOT_SAVE , 26SERVER_TASK_TYPE_SLOT_RESTORE , 27SERVER_TASK_TYPE_SLOT_ERASE , 28SERVER_TASK_TYPE_GET_LORA , 29SERVER_TASK_TYPE_SET_LORA , 30}; 31 32// TODO: change this to more generic "response_format" to replace the "format_response_*" in server-common 33enum task_response_type { 34TASK_RESPONSE_TYPE_NONE ,// llama.cpp native format 35TASK_RESPONSE_TYPE_OAI_CHAT , 36TASK_RESPONSE_TYPE_OAI_CMPL , 37TASK_RESPONSE_TYPE_OAI_RESP , 38TASK_RESPONSE_TYPE_OAI_ASR ,// transcriptions API 39TASK_RESPONSE_TYPE_OAI_EMBD , 40TASK_RESPONSE_TYPE_ANTHROPIC , 41}; 42 43enum stop_type { 44STOP_TYPE_NONE , 45STOP_TYPE_EOS , 46STOP_TYPE_WORD , 47STOP_TYPE_LIMIT , 48}; 49 50struct task_params { 51bool stream = false; 52bool include_usage = false; 53bool cache_prompt = true;// remember the prompt to avoid reprocessing all prompt 54bool return_tokens = false; 55bool return_progress = false; 56 57int32_t sse_ping_interval = 30 ;// seconds between SSE comment pings while the stream stays silent, -1 disables 58 59int32_t n_keep = 0 ;// number of tokens to keep from initial prompt 60int32_t n_discard = 0 ;// number of tokens after n_keep that may be discarded when shifting context, 0 defaults to half 61int32_t n_predict = -1 ;// new tokens to predict 62int32_t n_indent = 0 ;// minimum line indentation for the generated text in number of whitespace characters 63int32_t n_cmpl = 1 ;// number of completions to generate from this prompt 64 65int32_t n_cache_reuse = 0 ;// min chunk size to attempt reusing from the cache via KV shifting (0 = disabled) 66 67int64_t t_max_prompt_ms = -1 ;// TODO: implement 68int64_t t_max_predict_ms = -1 ;// if positive, limit the generation phase to this time limit 69 70std ::map < int ,float > lora ;// mapping adapter ID -> scale 71 72std ::vector < std ::string > antiprompt ; 73std ::vector < std ::string > response_fields ; 74 75bool timings_per_token = false; 76bool post_sampling_probs = false; 77 78struct common_params_sampling sampling ; 79struct common_params_speculative speculative ; 80 81// response formatting 82bool verbose = false; 83task_response_type res_type = TASK_RESPONSE_TYPE_NONE ; 84std ::string oaicompat_model ; 85std ::string oaicompat_cmpl_id ; 86 87// realtime control (SERVER_TASK_TYPE_CONTROL) 88std ::string control_action ; 89std ::string control_cmpl_id ; 90 91// per-request parameters for chat parsing 92common_chat_parser_params chat_parser_params ; 93 94// message spans for checkpointing 95common_chat_msg_spans message_spans ; 96 97// Embeddings 98int32_t embd_normalize = 2 ;// (-1=none, 0=max absolute int16, 1=taxicab, 2=Euclidean/L2, >2=p-norm) 99 100json format_logit_bias (const std ::vector < llama_logit_bias > & logit_bias )const ; 101json to_json (bool only_metrics = false)const ; 102}; 103 104// struct for tracking the state of a task (e.g., for streaming) 105struct task_result_state { 106// tracking diffs for partial tool calls 107std ::vector < common_chat_msg_diff > diffs ; 108common_chat_parser_params chat_parser_params ; 109common_chat_msg chat_msg ; 110std ::string generated_text ;// append new chunks of generated text here 111std ::vector < std ::string > generated_tool_call_ids ; 112std ::unordered_set < size_t > sent_tool_call_names ; 113 114// for OpenAI Responses and Anthropic streaming API: 115// track output item / content block state across chunks 116bool thinking_block_started = false; 117bool text_block_started = false; 118 119// for OpenAI Responses streaming API 120bool oai_resp_created = false; 121const std ::string oai_resp_id ; 122const std ::string oai_resp_reasoning_id ; 123const std ::string oai_resp_message_id ; 124std ::string oai_resp_fc_id ;// function call ID for current args delta 125 126task_result_state (const common_chat_parser_params & chat_parser_params ); 127 128// parse partial tool calls and update the internal state 129common_chat_msg update_chat_msg ( 130const std ::string & text_added , 131bool is_partial , 132std ::vector < common_chat_msg_diff > & diffs , 133bool filter_tool_calls = false); 134}; 135 136struct server_task { 137int id = -1 ;// to be filled by server_queue 138 139// TODO @ngxson : remove this field and implement a mapping task_id -> idx in the response_reader 140size_t index = 0 ;// used when there are multiple prompts (batch request) 141 142// used by SERVER_TASK_TYPE_CANCEL 143int id_target = -1 ; 144int id_slot = -1 ; 145 146// used by parallel sampling (multiple completions from same prompt) 147int id_parent = -1 ; 148// temporary store of child tasks for scheduling 149// note: accessing to elements is invalid after the task is moved to server_slot 150std ::vector < server_task > child_tasks ; 151 152// used by SERVER_TASK_TYPE_INFERENCE 153task_params params ; 154server_tokens tokens ; 155 156// only used by CLI, this allow tokenizing CLI inputs on server side 157// we need this because mtmd_context and vocab are not accessible outside of server_context 158bool cli = false; 159std ::string cli_prompt ; 160std ::vector < raw_buffer > cli_files ; 161 162server_task_type type ; 163 164// used by SERVER_TASK_TYPE_SLOT_SAVE, SERVER_TASK_TYPE_SLOT_RESTORE, SERVER_TASK_TYPE_SLOT_ERASE 165struct slot_action { 166int id_slot ; 167std ::string filename ; 168std ::string filepath ; 169 }; 170slot_action slot_action ; 171 172// used by SERVER_TASK_TYPE_METRICS 173bool metrics_reset_bucket = false; 174 175// used by SERVER_TASK_TYPE_SET_LORA 176std ::map < int ,float > set_lora ;// mapping adapter ID -> scale 177 178server_task ()= default ; 179 180server_task (server_task_type type ) :type (type ) {} 181 182int32_t n_tokens ()const { 183return tokens .size (); 184 } 185 186bool need_embd ()const { 187switch (type ) { 188case SERVER_TASK_TYPE_EMBEDDING : 189case SERVER_TASK_TYPE_RERANK : 190return true; 191default : 192return false; 193 } 194 } 195 196bool need_logits ()const { 197switch (type ) { 198case SERVER_TASK_TYPE_COMPLETION : 199case SERVER_TASK_TYPE_INFILL : 200return true; 201default : 202return false; 203 } 204 } 205 206bool need_sampling ()const { 207switch (type ) { 208case SERVER_TASK_TYPE_COMPLETION : 209case SERVER_TASK_TYPE_INFILL : 210return true; 211default : 212return false; 213 } 214 } 215 216// utility function 217static std ::unordered_set < int > get_list_id (const std ::vector < server_task > & tasks ) { 218std ::unordered_set < int > ids (tasks .size ()); 219for (size_t i = 0 ;i < tasks .size ();i ++ ) { 220ids .insert (tasks [i ].id ); 221for (auto& child :tasks [i ].child_tasks ) { 222ids .insert (child .id ); 223 } 224 } 225return ids ; 226 } 227 228void add_child (int id_parent ,int id_child ) { 229server_task copy ; 230 231copy .id = id_child ; 232copy .id_parent = id_parent ; 233copy .params = params ; 234copy .type = type ; 235copy .tokens = tokens .clone (); 236copy .id_slot = -1 ;// child tasks cannot specify slot 237 238// use different sampling seed for each child 239// note: https://github.com/ggml-org/llama.cpp/pull/18700#discussion_r2675115723 240if (copy .params .sampling .seed != LLAMA_DEFAULT_SEED ) { 241copy .params .sampling .seed += (uint32_t )child_tasks .size ()+ 1 ; 242 } 243 244child_tasks .push_back (std ::move (copy )); 245 } 246 247// the task will be moved into queue, then onto slots 248// however, the state must be kept by caller (e.g., HTTP thread) 249task_result_state create_state ()const { 250return task_result_state (params .chat_parser_params ); 251 } 252 253bool is_parent ()const { 254return child_tasks .size ()> 0 ; 255 } 256 257bool is_child ()const { 258return id_parent != -1 ; 259 } 260}; 261 262struct result_prompt_progress { 263int32_t total = 0 ; 264int32_t cache = 0 ; 265int32_t processed = 0 ; 266int64_t time_ms = 0 ; 267 268json to_json ()const ; 269}; 270 271struct server_task_result { 272int id = -1 ; 273int id_slot = -1 ; 274 275// TODO @ngxson : remove this field and implement a mapping task_id -> idx in the response_reader 276size_t index = 0 ;// to be used for batched tasks 277 278virtual bool is_error () { 279// only used by server_task_result_error 280return false; 281 } 282virtual bool is_stop () { 283// only used by server_task_result_cmpl_* 284return true; 285 } 286virtual void update (task_result_state & ) { 287// only used by server_task_result_cmpl_* 288 } 289virtual json to_json ()= 0 ; 290virtual ~server_task_result ()= default ; 291virtual server_task_result * clone ()const { 292GGML_ABORT ("not implemented for this task type" ); 293 } 294}; 295 296// using shared_ptr for polymorphism of server_task_result 297using server_task_result_ptr = std ::unique_ptr < server_task_result > ; 298 299struct completion_token_output { 300llama_token tok ; 301float prob ; 302std ::string text_to_send ; 303struct prob_info { 304llama_token tok ; 305std ::string txt ; 306float prob ; 307 }; 308std ::vector < prob_info > probs ; 309 310json to_json (bool post_sampling_probs )const ; 311 312static json probs_vector_to_json (const std ::vector < completion_token_output > & probs ,bool post_sampling_probs ); 313 314static float logarithm (float x ); 315 316static std ::vector < unsignedchar > str_to_bytes (const std ::string & str ); 317 318}; 319 320struct server_task_result_cmpl_final :server_task_result { 321std ::string content ; 322llama_tokens tokens ; 323 324bool stream ; 325bool include_usage ; 326server_slot_stats stats ; 327std ::string prompt ; 328 329bool truncated ; 330int32_t n_decoded ; 331int32_t n_prompt_tokens ; 332int32_t n_prompt_tokens_cache ; 333int32_t n_tokens_cached ; 334bool has_new_line ; 335std ::string stopping_word ; 336stop_type stop = STOP_TYPE_NONE ; 337 338bool post_sampling_probs ; 339std ::vector < completion_token_output > probs_output ; 340std ::vector < std ::string > response_fields ; 341 342task_params generation_params ; 343 344// response formatting 345bool verbose = false; 346task_response_type res_type = TASK_RESPONSE_TYPE_NONE ; 347std ::string oaicompat_model ; 348std ::string oaicompat_cmpl_id ; 349common_chat_msg oaicompat_msg ;// to be populated by update() 350 351std ::vector < common_chat_msg_diff > oaicompat_msg_diffs ;// to be populated by update() 352bool is_updated = false; 353 354// for OpenAI Responses API 355std ::string oai_resp_id ; 356std ::string oai_resp_reasoning_id ; 357std ::string oai_resp_message_id ; 358 359virtual bool is_stop ()override { 360return true;// in stream mode, final responses are considered stop 361 } 362 363virtual json to_json ()override ; 364 365virtual void update ( task_result_state & state) override { 366is_updated = true; 367oaicompat_msg = state. update_chat_msg (content, false, oaicompat_msg_diffs); 368 369oai_resp_id = state. oai_resp_id ; 370oai_resp_reasoning_id = state. oai_resp_reasoning_id ; 371oai_resp_message_id = state. oai_resp_message_id ; 372} 373 374json to_json_non_oaicompat (); 375 376json usage_json_oaicompat (); 377 378json to_json_oaicompat (); 379 380json to_json_oaicompat_chat (); 381 382json to_json_oaicompat_chat_stream (); 383 384json to_json_oaicompat_resp (); 385 386json to_json_oaicompat_resp_stream (); 387 388json to_json_oaicompat_asr (); 389 390json to_json_anthropic (); 391 392json to_json_anthropic_stream (); 393}; 394 395struct server_task_result_cmpl_partial : server_task_result { 396std :: string content; 397llama_tokens tokens; 398 399int32_t n_decoded; 400int32_t n_prompt_tokens; 401int32_t n_prompt_tokens_cache; 402 403bool post_sampling_probs; 404bool is_progress = false; 405bool is_begin = false; // whether to send 200 status to HTTP client (begin of SSE stream) 406// ref: https://github.com/ggml-org/llama.cpp/pull/23884 407completion_token_output prob_output; 408server_slot_stats stats; 409result_prompt_progress progress; 410 411// response formatting 412bool verbose = false; 413task_response_type res_type = TASK_RESPONSE_TYPE_NONE ; 414std :: string oaicompat_model; 415std :: string oaicompat_cmpl_id; 416std ::vector < common_chat_msg_diff > oaicompat_msg_diffs; // to be populated by update() 417bool is_updated = false; 418 419// Streaming state copied from task_result_state for this chunk 420bool thinking_block_started = false; 421bool text_block_started = false; 422 423// for OpenAI Responses API 424bool oai_resp_created = false; 425std :: string oai_resp_id; 426std :: string oai_resp_reasoning_id; 427std :: string oai_resp_message_id; 428std :: string oai_resp_fc_id; 429 430// for Anthropic API: track if any reasoning content has been generated 431bool anthropic_has_reasoning = false; 432 433virtual bool is_stop () override { 434return false; // in stream mode, partial responses are not considered stop 435} 436 437virtual void update (task_result_state & state) override; 438 439virtual json to_json () override ; 440 441json to_json_non_oaicompat (); 442 443json to_json_oaicompat (); 444 445json to_json_oaicompat_chat (); 446 447json to_json_oaicompat_resp (); 448 449json to_json_oaicompat_asr (); 450 451json to_json_anthropic (); 452}; 453 454struct server_task_result_embd : server_task_result { 455std ::vector < std::vector < float>> embedding; 456 457int32_t n_tokens; 458 459// response formatting 460task_response_type res_type = TASK_RESPONSE_TYPE_NONE ; 461 462virtual json to_json () override ; 463 464json to_json_non_oaicompat (); 465 466json to_json_oaicompat (); 467}; 468 469struct server_task_result_rerank : server_task_result { 470float score = -1e6 ; 471 472int32_t n_tokens; 473 474virtual json to_json () override ; 475}; 476 477struct server_task_result_error : server_task_result { 478error_type err_type = ERROR_TYPE_SERVER ; 479std :: string err_msg; 480 481// for ERROR_TYPE_EXCEED_CONTEXT_SIZE 482int32_t n_prompt_tokens = 0 ; 483int32_t n_ctx = 0 ; 484 485virtual bool is_error () override { 486return true; 487} 488 489virtual json to_json () override ; 490}; 491 492// used by /metrics API 493struct server_task_result_metrics : server_task_result { 494// these are immediate stats, not accumulated (server_metrics is cumulative) 495int n_processing_slots = 0 ; 496int n_tasks_deferred = 0 ; 497 498server_metrics metrics; 499 500virtual json to_json () override ; 501 502struct metric_item { 503std :: string name ; 504std :: string description ; 505double value ; // prometheus values are always float64 506}; 507std::string to_metrics (); 508}; 509 510// used by /slots API 511struct server_task_result_slots : server_task_result { 512int n_idle_slots = 0 ; 513 514// while we can also use std::vector<server_slot> this requires copying the slot object which can be quite messy 515// therefore, we use json to temporarily store the slot.to_json() result 516json slots_data = json:: array (); 517 518virtual json to_json () override; 519}; 520 521struct server_task_result_slot_save_load : server_task_result { 522std :: string filename; 523bool is_save; // true = save, false = load 524 525size_t n_tokens; 526size_t n_bytes; 527double t_ms; 528 529virtual json to_json () override ; 530}; 531 532struct server_task_result_slot_erase : server_task_result { 533size_t n_erased; 534 535virtual json to_json () override ; 536}; 537 538struct server_task_result_control : server_task_result { 539bool success = false; 540std :: string message; // optional detail when success is false 541 542virtual json to_json () override { 543json out = json { { "success" , success } }; 544if (!message. empty ()) { 545out[ "message" ] = message; 546} 547return out; 548} 549}; 550 551struct server_task_result_get_lora : server_task_result { 552struct lora { 553common_adapter_lora_info info ; 554std :: string alora_invocation_string ; 555llama_tokens alora_invocation_tokens ; 556}; 557std ::vector < lora > loras; 558 559virtual json to_json () override ; 560}; 561 562struct server_task_result_apply_lora : server_task_result { 563virtual json to_json () override ; 564}; 565 566struct server_prompt { 567server_tokens tokens ; 568 569std :: list < common_prompt_checkpoint > checkpoints ; 570 571void clear () { 572tokens . clear (); 573checkpoints . clear (); 574} 575 576int n_tokens () const { 577return tokens . size (); 578} 579 580server_prompt clone () const { 581return server_prompt { 582tokens. clone (), 583checkpoints, 584}; 585} 586}; 587 588struct server_prompt_data { 589std :: vector < uint8_t > main ; 590std :: vector < uint8_t > drft ; 591 592size_t size () const { 593return main. size () + drft . size (); 594} 595}; 596 597struct server_prompt_cache_state { 598server_prompt prompt ; 599server_prompt_data data ; 600 601size_t size () const { 602size_t res = data . size (); 603 604for ( const auto & ckpt : prompt.checkpoints) { 605res += ckpt . size (); 606} 607 608return res; 609} 610}; 611 612struct server_prompt_cache { 613server_prompt_cache( int32_t limit_size_mib , size_t limit_tokens) { 614this -> limit_size = 1024ull * 1024ull * ( limit_size_mib < 0 ? 0 : limit_size_mib); 615this -> limit_tokens = limit_tokens ; 616} 617 618std::list < server_prompt_cache_state > states; 619 620// in bytes, 0 = no limit 621size_t limit_size = 0 ; 622 623// in tokens, 0 = no limit 624size_t limit_tokens = 0 ; 625 626size_t size () const ; 627 628size_t n_tokens () const; 629 630server_prompt_cache_state * alloc ( const server_prompt & prompt, size_t state_size_main, size_t state_size_drft); 631 632bool load ( server_prompt & prompt, const server_tokens & tokens_new, llama_context * ctx_tgt, llama_context * ctx_dft, int32_t id_slot); 633 634void update (); 635}; 636 637// used exclusively by router mode 638struct server_task_result_router : server_task_result { 639json data; 640virtual json to_json () override { return data; } 641virtual server_task_result * clone () const override { 642return new server_task_result_router ( * this ); 643 } 644};