char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
98a01afd9
char/aliceai-t5-moe
1#include "llama-context.h" 2 3#include "ggml.h" 4#include "llama-arch.h" 5#include "llama-graph.h" 6#include "llama-impl.h" 7#include "llama-batch.h" 8#include "llama-io.h" 9#include "llama-memory.h" 10#include "llama-mmap.h" 11#include "llama-model.h" 12#include "llama-ext.h" 13#include "llama-sampler.h" 14#include "llama.h" 15 16#include <cinttypes> 17#include <cmath> 18#include <cstring> 19#include <limits> 20#include <stdexcept> 21#include <string> 22 23// 24// llama_context 25// 26 27static llm_graph_type ctx_type_to_graph_type (llama_context_type ctx_type ) { 28switch (ctx_type ) { 29case LLAMA_CONTEXT_TYPE_DEFAULT :return LLM_GRAPH_TYPE_DEFAULT ; 30case LLAMA_CONTEXT_TYPE_MTP :return LLM_GRAPH_TYPE_DECODER_MTP ; 31 } 32throw std::runtime_error ("Unsupported ctx type" ); 33} 34 35struct llm_fused_op_probe { 36llm_fused_op op ; 37const char * name ; 38uint32_t n_tokens_per_seq ; 39}; 40 41static const llm_fused_op_probe llm_fused_op_flash_attn_probe = { 42/*.op =*/ LLM_FUSED_OP_FLASH_ATTN , 43/*.name =*/ "Flash Attention" , 44/*.n_tokens_per_seq =*/ 1 , 45}; 46 47static const llm_fused_op_probe llm_fused_op_gdn_ar_probe = { 48/*.op =*/ LLM_FUSED_OP_GDN_AR , 49/*.name =*/ "fused Gated Delta Net (autoregressive)" , 50/*.n_tokens_per_seq =*/ 1 , 51}; 52 53static const llm_fused_op_probe llm_fused_op_gdn_ch_probe = { 54/*.op =*/ LLM_FUSED_OP_GDN_CH , 55/*.name =*/ "fused Gated Delta Net (chunked)" , 56/*.n_tokens_per_seq =*/ 16 , 57}; 58 59static const llm_fused_op_probe llm_fused_op_lid_probe = { 60/*.op =*/ LLM_FUSED_OP_LIGHTNING_INDEXER , 61/*.name =*/ "Lightning Indexer" , 62/*.n_tokens_per_seq =*/ 1 , 63}; 64 65static const llm_fused_op_probe llm_fused_op_dsv4_hc_pre_probe = { 66/*.op =*/ LLM_FUSED_OP_DSV4_HC_PRE , 67/*.name =*/ "fused DeepSeek V4 HC pre" , 68/*.n_tokens_per_seq =*/ 1 , 69}; 70 71static const llm_fused_op_probe llm_fused_op_dsv4_hc_comb_probe = { 72/*.op =*/ LLM_FUSED_OP_DSV4_HC_COMB , 73/*.name =*/ "fused DeepSeek V4 HC comb" , 74/*.n_tokens_per_seq =*/ 1 , 75}; 76 77static const llm_fused_op_probe llm_fused_op_dsv4_hc_post_probe = { 78/*.op =*/ LLM_FUSED_OP_DSV4_HC_POST , 79/*.name =*/ "fused DeepSeek V4 HC post" , 80/*.n_tokens_per_seq =*/ 1 , 81}; 82 83llama_context::llama_context ( 84const llama_model & model , 85llama_context_params params ) : 86model (model ), 87cvec (std::make_unique < llama_adapter_cvec > ()), 88loras (std::make_unique < llama_adapter_loras > ()), 89balloc (std::make_unique < llama_batch_allocr > (model .hparams .n_pos_per_embd ())) { 90// TODO warning when creating llama_context with awkward ctx size that is not a power of 2, 91// may need to be backend-dependent 92LLAMA_LOG_INFO ("%s: constructing llama_context\n" ,__func__ ); 93 94t_start_us = model .t_start_us ; 95t_load_us = model .t_load_us ; 96 97const auto & hparams = model .hparams ; 98 99cparams .n_seq_max = std::max (1u ,params .n_seq_max ); 100if (cparams .n_seq_max > LLAMA_MAX_SEQ ) { 101throw std::runtime_error ("n_seq_max must be <= " + std::to_string (LLAMA_MAX_SEQ )); 102 } 103 104cparams .n_rs_seq = params .n_rs_seq ; 105if (cparams .n_rs_seq > 0 && !llm_arch_supports_rs_rollback (model .arch )) { 106LLAMA_LOG_DEBUG ("%s: n_rs_seq=%u requested but model does not support recurrent partial rollback; clamping to 0\n" , 107__func__ ,cparams .n_rs_seq ); 108cparams .n_rs_seq = 0 ; 109 } 110 111cparams .n_threads = params .n_threads ; 112cparams .n_threads_batch = params .n_threads_batch ; 113cparams .yarn_ext_factor = params .yarn_ext_factor >=0.0f ?params .yarn_ext_factor :hparams .yarn_ext_factor ; 114cparams .yarn_attn_factor = params .yarn_attn_factor >=0.0f ?params .yarn_attn_factor :hparams .yarn_attn_factor ; 115cparams .yarn_beta_fast = params .yarn_beta_fast >=0.0f ?params .yarn_beta_fast :hparams .yarn_beta_fast ; 116cparams .yarn_beta_slow = params .yarn_beta_slow >=0.0f ?params .yarn_beta_slow :hparams .yarn_beta_slow ; 117cparams .embeddings = params .embeddings ; 118cparams .embeddings_nextn = false; 119cparams .embeddings_nextn_masked = false; 120cparams .offload_kqv = params .offload_kqv ; 121cparams .no_perf = params .no_perf ; 122cparams .warmup = false; 123 124// +1: id n_layer() taps the output of the last layer ("input" of the head) 125cparams .embeddings_layer_inp .resize (hparams .n_layer ()+ 1 , false); 126embd_layer_inp .resize (hparams .n_layer ()+ 1 ); 127 128cparams .ctx_type = params .ctx_type ; 129cparams .rope_scaling_type = params .rope_scaling_type ; 130cparams .pooling_type = params .pooling_type ; 131 132cparams .n_ctx = params .n_ctx == 0 ?hparams .n_ctx_train :params .n_ctx ; 133cparams .rope_freq_base = params .rope_freq_base == 0.0f ?hparams .rope_freq_base_train :params .rope_freq_base ; 134cparams .rope_freq_scale = params .rope_freq_scale == 0.0f ?hparams .rope_freq_scale_train :params .rope_freq_scale ; 135 136cparams .n_ctx_orig_yarn = params .yarn_orig_ctx != 0 ?params .yarn_orig_ctx : 137hparams .n_ctx_orig_yarn != 0 ?hparams .n_ctx_orig_yarn : 138hparams .n_ctx_train ; 139 140cparams .cb_eval = params .cb_eval ; 141cparams .cb_eval_user_data = params .cb_eval_user_data ; 142 143cparams .ctx_other = nullptr ; 144 145// TODO: more generic 146if (model .arch == LLM_ARCH_GEMMA4_ASSISTANT ) { 147if (params .ctx_other == nullptr ) { 148// TODO: change from runtime_error to llama_exception to avoid printing error message 149throw std::runtime_error ("Gemma4Assistant requires ctx_other to be set (this warning is normal during memory fitting)" ); 150 } 151 152cparams .ctx_other = params .ctx_other ; 153 } 154 155if (model .arch == LLM_ARCH_EAGLE3 || model .arch == LLM_ARCH_DFLASH ) { 156if (model .tok_embd == nullptr || model .output == nullptr ) { 157if (params .ctx_other == nullptr ) { 158throw std::runtime_error (model .arch_name ()+ " requires ctx_other to be set (this warning is normal during memory fitting)" ); 159 } 160cparams .ctx_other = params .ctx_other ; 161 } 162 } 163 164if (cparams .rope_scaling_type == LLAMA_ROPE_SCALING_TYPE_UNSPECIFIED ) { 165cparams .rope_scaling_type = hparams .rope_scaling_type_train ; 166 } 167 168if (cparams .rope_scaling_type == LLAMA_ROPE_SCALING_TYPE_NONE ) { 169cparams .rope_freq_scale = 1.0f ;// never scale if scaling type is none 170 } 171 172if (cparams .yarn_ext_factor < 0.0f ) {// negative indicates 'not set' 173cparams .yarn_ext_factor = cparams .rope_scaling_type == LLAMA_ROPE_SCALING_TYPE_YARN ?1.0f :0.0f ; 174 } 175 176if (cparams .yarn_ext_factor != 0 ) { 177static auto get_mscale = [](float scale ,float mscale ) { 178return scale <=1.0f ?1.0f : (0.1f * mscale * logf (scale )+ 1.0f ); 179 }; 180 181const float factor = 1.0f /cparams .rope_freq_scale ; 182 183// ref: https://github.com/huggingface/transformers/blob/6d00f6b0a5679c36510f203e4226e36f517c3032/src/transformers/modeling_rope_utils.py#L336-L348 184if (hparams .rope_yarn_log_mul != 0.0f ) { 185// note: here we assume `mscale == 1.0f` 186// TODO: start reading the actual value of mscale and handle the case where it is not 1.0f 187float mscale = 1.0f ; 188const float mscale_all_dims = hparams .rope_yarn_log_mul ; 189 190// [TAG_DEEPSEEK2_YARN_LOG_MUL_FIX] 191// special-case DEEPSEEK v2: 192// https://huggingface.co/deepseek-ai/DeepSeek-V2-Lite-Chat/blob/main/config.json#L42-L43 193if (model .arch == LLM_ARCH_DEEPSEEK2 && mscale_all_dims != 1.0f ) { 194mscale = mscale_all_dims ; 195 } 196 197cparams .yarn_attn_factor = get_mscale (factor ,mscale ) /get_mscale (factor ,mscale_all_dims ); 198 199LLAMA_LOG_WARN ("%s: setting new yarn_attn_factor = %.4f (mscale == %.1f, mscale_all_dim = %.1f)\n" , 200__func__ ,cparams .yarn_attn_factor ,mscale ,mscale_all_dims ); 201 }else { 202cparams .yarn_attn_factor = get_mscale (factor ,1.0f ); 203 } 204 205// when YARN is applied with yarn_ext_factor != 0.0f, we need to cancel this factor: 206// https://github.com/ggml-org/llama.cpp/blob/a81a569577cc38b32558958b048228150be63eae/ggml/src/ggml-cpu/ops.cpp#L5541-L5544 207// 208// ref: https://github.com/ggml-org/llama.cpp/discussions/7416 209// https://github.com/ggml-org/llama.cpp/pull/17945 210cparams .yarn_attn_factor *=1.0f / (1.0f + 0.1f * logf (factor )); 211 } 212 213cparams .yarn_attn_factor *=hparams .rope_attn_factor ; 214 215if (cparams .pooling_type == LLAMA_POOLING_TYPE_UNSPECIFIED ) { 216if (hparams .pooling_type == LLAMA_POOLING_TYPE_UNSPECIFIED ) { 217cparams .pooling_type = LLAMA_POOLING_TYPE_NONE ; 218 }else { 219cparams .pooling_type = hparams .pooling_type ; 220 } 221 } 222 223if (params .attention_type == LLAMA_ATTENTION_TYPE_UNSPECIFIED ) { 224cparams .causal_attn = hparams .causal_attn ; 225 }else { 226cparams .causal_attn = params .attention_type == LLAMA_ATTENTION_TYPE_CAUSAL ; 227 } 228 229cparams .flash_attn = params .flash_attn_type != LLAMA_FLASH_ATTN_TYPE_DISABLED ; 230cparams .auto_fa = params .flash_attn_type == LLAMA_FLASH_ATTN_TYPE_AUTO ; 231 232cparams .fused_gdn_ar = true; 233cparams .fused_gdn_ch = true; 234cparams .auto_fgdn = false; 235 236cparams .fused_lid = true; 237cparams .auto_flid = false; 238 239cparams .fused_dsv4_hc_pre = true; 240cparams .fused_dsv4_hc_comb = true; 241cparams .fused_dsv4_hc_post = true; 242cparams .auto_fhc = true; 243 244// with causal attention, the batch size is limited by the context size 245cparams .n_batch = cparams .causal_attn ? std::min (cparams .n_ctx ,params .n_batch ) :params .n_batch ; 246 247cparams .n_ubatch = std::min (cparams .n_batch ,params .n_ubatch == 0 ?params .n_batch :params .n_ubatch ); 248 249cparams .n_outputs_max = params .n_outputs_max == 0 || llama_model_has_encoder (& model ) ?cparams .n_batch :params .n_outputs_max ; 250cparams .n_outputs_max_per_seq = params .n_outputs_max_per_seq == 0 ? 251cparams .n_outputs_max : std::min (params .n_outputs_max_per_seq ,cparams .n_outputs_max ); 252 253// Initialize backend samplers here so they are part of the sampling graph 254// before the reserve passes run later in this function. This avoids a later 255// re-reserve when graph nodes change. 256if (params .samplers != nullptr && params .n_samplers > 0 ) { 257for (size_t i = 0 ;i < params .n_samplers ;++ i ) { 258const auto & config = params .samplers [i ]; 259 260if (llama_sampler_chain_get (config .sampler ,-1 )== nullptr ) { 261throw std::runtime_error ("the backend samplers must be of type llama_sampler_chain" ); 262 } 263 264if (set_sampler (config .seq_id ,config .sampler )) { 265const int n_samplers = llama_sampler_chain_n (config .sampler ); 266 267LLAMA_LOG_INFO ("%s: setting backend sampler for seq_id %d (n = %d)\n" ,__func__ ,config .seq_id ,n_samplers ); 268 } 269 } 270 } 271 272cparams .op_offload = params .op_offload ; 273cparams .kv_unified = params .kv_unified ; 274 275// initialized later 276cparams .pipeline_parallel = false; 277 278 { 279const char * LLAMA_GRAPH_REUSE_DISABLE = getenv ("LLAMA_GRAPH_REUSE_DISABLE" ); 280graph_reuse_disable = LLAMA_GRAPH_REUSE_DISABLE ? (atoi (LLAMA_GRAPH_REUSE_DISABLE )!= 0 ) :graph_reuse_disable ; 281 282if (graph_reuse_disable ) { 283LLAMA_LOG_WARN ("%s: graph reuse disabled\n" ,__func__ ); 284 } 285 } 286 287// ref: https://github.com/ggml-org/llama.cpp/pull/17046#discussion_r2503085732 288cparams .n_ctx = GGML_PAD (cparams .n_ctx ,256 ); 289 290if (cparams .kv_unified ) { 291cparams .n_ctx_seq = cparams .n_ctx ; 292 }else { 293cparams .n_ctx_seq = cparams .n_ctx /cparams .n_seq_max ; 294cparams .n_ctx_seq = GGML_PAD (cparams .n_ctx_seq ,256 ); 295 296if (cparams .n_ctx_seq == 0 ) { 297throw std::runtime_error ("n_ctx_seq == 0" ); 298 } 299 300if (cparams .n_ctx != cparams .n_ctx_seq * cparams .n_seq_max ) { 301cparams .n_ctx = cparams .n_ctx_seq * cparams .n_seq_max ; 302LLAMA_LOG_WARN ("%s: n_ctx is not divisible by n_seq_max - rounding down to %u\n" ,__func__ ,cparams .n_ctx ); 303 } 304 } 305 306LLAMA_LOG_INFO ("%s: n_seq_max = %u\n" ,__func__ ,cparams .n_seq_max ); 307LLAMA_LOG_INFO ("%s: n_ctx = %u\n" ,__func__ ,cparams .n_ctx ); 308LLAMA_LOG_INFO ("%s: n_ctx_seq = %u\n" ,__func__ ,cparams .n_ctx_seq ); 309LLAMA_LOG_INFO ("%s: n_batch = %u\n" ,__func__ ,cparams .n_batch ); 310LLAMA_LOG_INFO ("%s: n_ubatch = %u\n" ,__func__ ,cparams .n_ubatch ); 311LLAMA_LOG_INFO ("%s: causal_attn = %d\n" ,__func__ ,cparams .causal_attn ); 312LLAMA_LOG_INFO ("%s: flash_attn = %s\n" ,__func__ ,llama_flash_attn_type_name (params .flash_attn_type )); 313LLAMA_LOG_INFO ("%s: kv_unified = %s\n" ,__func__ ,cparams .kv_unified ?"true" :"false" ); 314LLAMA_LOG_INFO ("%s: freq_base = %.1f\n" ,__func__ ,cparams .rope_freq_base ); 315LLAMA_LOG_INFO ("%s: freq_scale = %g\n" ,__func__ ,cparams .rope_freq_scale ); 316LLAMA_LOG_INFO ("%s: n_rs_seq = %u\n" ,__func__ ,cparams .n_rs_seq ); 317LLAMA_LOG_INFO ("%s: n_outputs_max = %u\n" ,__func__ ,cparams .n_outputs_max ); 318LLAMA_LOG_INFO ("%s: n_outputs_max_per_seq = %u\n" ,__func__ ,cparams .n_outputs_max_per_seq ); 319 320if (cparams .n_ctx_seq < hparams .n_ctx_train ) { 321LLAMA_LOG_INFO ("%s: n_ctx_seq (%u) < n_ctx_train (%u) -- the full capacity of the model will not be utilized\n" , 322__func__ ,cparams .n_ctx_seq ,hparams .n_ctx_train ); 323 } 324 325if (cparams .n_ctx_seq > hparams .n_ctx_train ) { 326LLAMA_LOG_WARN ("%s: n_ctx_seq (%u) > n_ctx_train (%u) -- possible training context overflow\n" , 327__func__ ,cparams .n_ctx_seq ,hparams .n_ctx_train ); 328 } 329 330if (!hparams .vocab_only ) { 331// GPU backends 332for (const auto & dev :model .devices ) { 333ggml_backend_t backend = ggml_backend_dev_init (dev .dev ,nullptr ); 334if (backend == nullptr ) { 335throw std::runtime_error (format ("failed to initialize %s backend" ,ggml_backend_dev_name (dev .dev ))); 336 } 337backends .emplace_back (backend ); 338 } 339 340// add ACCEL backends (such as BLAS) 341for (size_t i = 0 ;i < ggml_backend_dev_count ();++ i ) { 342ggml_backend_dev_t dev = ggml_backend_dev_get (i ); 343if (ggml_backend_dev_type (dev )== GGML_BACKEND_DEVICE_TYPE_ACCEL ) { 344ggml_backend_t backend = ggml_backend_dev_init (dev ,nullptr ); 345if (backend == nullptr ) { 346throw std::runtime_error (format ("failed to initialize %s backend" ,ggml_backend_dev_name (dev ))); 347 } 348backends .emplace_back (backend ); 349 } 350 } 351 352// add CPU backend 353backend_cpu = ggml_backend_init_by_type (GGML_BACKEND_DEVICE_TYPE_CPU ,nullptr ); 354if (backend_cpu == nullptr ) { 355throw std::runtime_error ("failed to initialize CPU backend" ); 356 } 357backends .emplace_back (backend_cpu ); 358 359// create a list of the set_n_threads functions in the backends 360for (auto & backend :backends ) { 361ggml_backend_dev_t dev = ggml_backend_get_device (backend .get ()); 362ggml_backend_reg_t reg = dev ?ggml_backend_dev_backend_reg (dev ) :nullptr ; 363if (reg ) { 364auto ggml_backend_set_n_threads_fn = (ggml_backend_set_n_threads_t )ggml_backend_reg_get_proc_address (reg ,"ggml_backend_set_n_threads" ); 365if (ggml_backend_set_n_threads_fn ) { 366set_n_threads_fns .emplace_back (backend .get (),ggml_backend_set_n_threads_fn ); 367 } 368 } 369 } 370 371llama_set_abort_callback (this ,params .abort_callback ,params .abort_callback_data ); 372 373// graph outputs buffer 374 { 375if (output_reserve (params .n_seq_max )< params .n_seq_max ) { 376throw std::runtime_error ("failed to reserve initial output buffer" ); 377 } 378 379LLAMA_LOG_INFO ("%s: %10s output buffer size = %8.2f MiB\n" ,__func__ , 380ggml_backend_buffer_name (buf_output .get ()), 381ggml_backend_buffer_get_size (buf_output .get ()) /1024.0 /1024.0 ); 382 } 383 } 384 385// init the memory module 386if (!hparams .vocab_only ) { 387llama_memory_params params_mem = { 388/*.type_k =*/ params .type_k , 389/*.type_v =*/ params .type_v , 390/*.swa_full =*/ params .swa_full , 391/*.ctx_type =*/ cparams .ctx_type , 392/*.mem_other =*/ llama_get_memory (cparams .ctx_other ), 393 }; 394 395memory .reset (model .create_memory (params_mem ,cparams )); 396 } 397 398// init backends 399if (!hparams .vocab_only ) { 400LLAMA_LOG_DEBUG ("%s: enumerating backends\n" ,__func__ ); 401 402backend_buft .clear (); 403backend_ptrs .clear (); 404backend_buf_exp_size .clear (); 405 406for (auto & backend :backends ) { 407auto * buft = ggml_backend_get_default_buffer_type (backend .get ()); 408auto backend_type = ggml_backend_dev_type (ggml_backend_get_device (backend .get ())); 409 410if (backend_type == GGML_BACKEND_DEVICE_TYPE_CPU && !model .devices .empty ()) { 411// use the host buffer of the first device CPU for faster transfer of the intermediate state 412const auto & dev = model .devices [0 ]; 413auto * host_buft = ggml_backend_dev_host_buffer_type (dev .dev ); 414if (host_buft ) { 415buft = host_buft ; 416 } 417 } 418 419backend_buft .push_back (buft ); 420backend_ptrs .push_back (backend .get ()); 421backend_buf_exp_size .push_back (0 ); 422 } 423 424LLAMA_LOG_DEBUG ("%s: backend_ptrs.size() = %zu\n" ,__func__ ,backend_ptrs .size ()); 425 426// TODO: move these checks to ggml_backend_sched 427// enabling pipeline parallelism in the scheduler increases memory usage, so it is only done when necessary 428bool pipeline_parallel = 429model .n_devices ()> 1 && 430model .n_gpu_layers ()> model .hparams .n_layer_all && 431model .split_mode ()== LLAMA_SPLIT_MODE_LAYER && 432cparams .offload_kqv && 433 !model .has_tensor_overrides (); 434 435// pipeline parallelism requires support for async compute and events in all devices 436if (pipeline_parallel ) { 437for (auto & backend :backends ) { 438auto dev_type = ggml_backend_dev_type (ggml_backend_get_device (backend .get ())); 439if (dev_type == GGML_BACKEND_DEVICE_TYPE_CPU ) { 440// ignore CPU backend 441// TODO: should we ignore ACCEL types too? 442continue ; 443 } 444auto * dev = ggml_backend_get_device (backend .get ()); 445ggml_backend_dev_props props ; 446ggml_backend_dev_get_props (dev ,& props ); 447if (!props .caps .async || !props .caps .events ) { 448// device does not support async compute or events 449pipeline_parallel = false; 450break ; 451 } 452 } 453 } 454 455cparams .pipeline_parallel = pipeline_parallel ; 456 457if (cparams .pipeline_parallel ) { 458LLAMA_LOG_INFO ("%s: pipeline parallelism enabled\n" ,__func__ ); 459 } 460 461sched_reserve (); 462 463if (!cparams .flash_attn ) { 464if (ggml_is_quantized (params .type_v )) { 465throw std::runtime_error ("quantized V cache was requested, but this requires Flash Attention" ); 466 } 467 } 468 } 469 470// Initialize the full vocabulary token ids for backend samplers. 471 { 472const int n_vocab = model .vocab .n_tokens (); 473 474sampling .token_ids_full_vocab .resize (n_vocab ); 475for (int i = 0 ;i < n_vocab ;++ i ) { 476sampling .token_ids_full_vocab [i ]= i ; 477 } 478 } 479} 480 481llama_context::~llama_context () { 482// wait for any pending asynchronous copies into the output buffers before they are freed 483synchronize (); 484 485// when training, ggml_opt allocates extra buffers through the scheduler, so the sizes no longer match the expectation 486if (!model .hparams .no_alloc && !opt_ctx ) { 487for (size_t i = 0 ;i < backend_ptrs .size ();++ i ) { 488ggml_backend_t backend = backend_ptrs [i ]; 489ggml_backend_buffer_type_t buft = backend_buft [i ]; 490 491const size_t size_exp = backend_buf_exp_size [i ]; 492const size_t size_act = ggml_backend_sched_get_buffer_size (sched .get (),backend ); 493if (size_exp == size_act ) { 494LLAMA_LOG_DEBUG ("%s: %10s compute buffer size is %8.4f MiB, matches expectation of %8.4f MiB\n" , 495__func__ ,ggml_backend_buft_name (buft ),size_act / (1024.0 * 1024.0 ),size_exp / (1024.0 * 1024.0 )); 496 }else { 497LLAMA_LOG_WARN ("%s: %10s compute buffer size of %8.4f MiB, does not match expectation of %8.4f MiB\n" , 498__func__ ,ggml_backend_buft_name (buft ),size_act / (1024.0 * 1024.0 ),size_exp / (1024.0 * 1024.0 )); 499 } 500 } 501 } 502ggml_opt_free (opt_ctx ); 503} 504 505void llama_context::resolve_fused_ops (const llama_memory_context_i * mctx ,uint32_t n_seqs ) { 506const char * func = __func__ ; 507auto resolve = [& ](const llm_fused_op_probe & probe ,bool & enabled ) { 508if (!enabled ) { 509return ; 510 } 511 512const uint32_t n_tokens_probe = probe .n_tokens_per_seq * n_seqs ; 513 514auto * gf = graph_reserve (n_tokens_probe ,n_seqs ,n_tokens_probe ,mctx , true); 515if (!gf ) { 516throw std::runtime_error (std::string ("failed to reserve graph for " )+ probe .name + " check" ); 517 } 518 519bool device_mismatch = false; 520for (const auto & node :get_gf_res_reserve ()-> get_fused_nodes ()) { 521if (node .op != probe .op ) { 522continue ; 523 } 524 525GGML_ASSERT (node .il >=0 ); 526 527ggml_backend_t backend_fused = ggml_backend_sched_get_tensor_backend (sched .get (),node .tensor ); 528ggml_backend_dev_t device_fused = backend_fused ?ggml_backend_get_device (backend_fused ) :nullptr ; 529 530// TODO: make this descriptor-specific; model.dev_layer() preserves the current behavior, 531// but is still wrong for cases like --no-kv-offload. 532ggml_backend_dev_t device_layer = model .dev_layer (node .il ); 533 534if (device_fused != device_layer ) { 535LLAMA_LOG_WARN ("%s: layer %d is assigned to device %s but %s " 536"is assigned to device %s (usually due to missing support)\n" , 537func ,node .il , 538device_layer ?ggml_backend_dev_name (device_layer ) :"none" , 539probe .name , 540device_fused ?ggml_backend_dev_name (device_fused ) :"none" ); 541device_mismatch = true; 542break ; 543 } 544 } 545 546if (device_mismatch ) { 547enabled = false; 548LLAMA_LOG_WARN ("%s: %s not supported, set to disabled\n" ,func ,probe .name ); 549 }else { 550enabled = true; 551LLAMA_LOG_INFO ("%s: %s enabled\n" ,func ,probe .name ); 552 } 553 }; 554 555if (cparams .auto_fa ) { 556resolve (llm_fused_op_flash_attn_probe ,cparams .flash_attn ); 557cparams .auto_fa = false; 558 } 559 560if (cparams .auto_fgdn ) { 561LLAMA_LOG_INFO ("%s: resolving fused Gated Delta Net support:\n" ,func ); 562resolve (llm_fused_op_gdn_ar_probe ,cparams .fused_gdn_ar ); 563resolve (llm_fused_op_gdn_ch_probe ,cparams .fused_gdn_ch ); 564cparams .auto_fgdn = false; 565 } 566 567if (cparams .auto_flid ) { 568LLAMA_LOG_INFO ("%s: resolving fused Lightning Indexer support:\n" ,func ); 569resolve (llm_fused_op_lid_probe ,cparams .fused_lid ); 570cparams .auto_flid = false; 571 } 572 573if (cparams .auto_fhc ) { 574LLAMA_LOG_INFO ("%s: resolving fused DeepSeek V4 HC support:\n" ,func ); 575resolve (llm_fused_op_dsv4_hc_pre_probe ,cparams .fused_dsv4_hc_pre ); 576resolve (llm_fused_op_dsv4_hc_comb_probe ,cparams .fused_dsv4_hc_comb ); 577resolve (llm_fused_op_dsv4_hc_post_probe ,cparams .fused_dsv4_hc_post ); 578cparams .auto_fhc = false; 579 } 580} 581 582void llama_context::sched_reserve () { 583if (!sched_need_reserve ) { 584return ; 585 } 586 587sched_need_reserve = false; 588 589LLAMA_LOG_INFO ("%s: reserving ...\n" ,__func__ ); 590 591synchronize (); 592 593const int64_t t_start_us = ggml_time_us (); 594 595const uint32_t n_seqs = cparams .n_seq_max ; 596const uint32_t n_tokens = std::min (cparams .n_ctx ,cparams .n_ubatch ); 597 598const size_t max_nodes = this -> graph_max_nodes (n_tokens ); 599 600LLAMA_LOG_DEBUG ("%s: max_nodes = %zu\n" ,__func__ ,max_nodes ); 601 602gf_res_prev .reset (new llm_graph_result (max_nodes )); 603gf_res_reserve .reset (new llm_graph_result (max_nodes )); 604 605sched .reset (ggml_backend_sched_new (backend_ptrs .data (),backend_buft .data (),backend_ptrs .size (),max_nodes ,cparams .pipeline_parallel ,cparams .op_offload )); 606 607llama_memory_context_ptr mctx ; 608if (memory ) { 609LLAMA_LOG_DEBUG ("%s: reserving full memory module\n" ,__func__ ); 610mctx = memory -> init_full (); 611if (!mctx ) { 612throw std::runtime_error ("failed to initialize memory module" ); 613 } 614 } 615 616// avoid reserving graphs with zero outputs - assume one output per sequence 617const int n_outputs = n_seqs ; 618 619LLAMA_LOG_DEBUG ("%s: worst-case: n_tokens = %d, n_seqs = %d, n_outputs = %d\n" ,__func__ ,n_tokens ,n_seqs ,n_outputs ); 620 621resolve_fused_ops (mctx .get (),n_seqs ); 622 623// reserve worst-case graph 624int n_splits_pp = -1 ; 625int n_nodes_pp = -1 ; 626 627int n_splits_tg = -1 ; 628int n_nodes_tg = -1 ; 629 630const uint32_t n_outputs_pp = std::min (n_tokens ,cparams .n_outputs_max ); 631 632// reserve pp (prompt processing) graph first so that buffers are only allocated once 633 { 634auto * gf = graph_reserve (n_tokens ,n_seqs ,n_outputs_pp ,mctx .get (), 635model .hparams .no_alloc ,model .hparams .no_alloc ?backend_buf_exp_size .data () :nullptr ); 636if (!gf ) { 637if (cparams .pipeline_parallel ) { 638LLAMA_LOG_WARN ("%s: compute buffer allocation failed, retrying without pipeline parallelism\n" ,__func__ ); 639cparams .pipeline_parallel = false; 640sched .reset (ggml_backend_sched_new (backend_ptrs .data (),backend_buft .data (),backend_ptrs .size (),max_nodes , false,cparams .op_offload )); 641gf = graph_reserve (n_tokens ,n_seqs ,n_outputs_pp ,mctx .get ()); 642 } 643if (!gf ) { 644throw std::runtime_error ("failed to allocate compute pp buffers" ); 645 } 646 } 647 648n_splits_pp = ggml_backend_sched_get_n_splits (sched .get ()); 649n_nodes_pp = ggml_graph_n_nodes (gf ); 650 } 651 652// reserve with tg (token generation) graph to get the number of splits and nodes 653 { 654auto * gf = graph_reserve (n_seqs ,n_seqs ,n_seqs ,mctx .get (),model .hparams .no_alloc ); 655if (!gf ) { 656throw std::runtime_error ("failed to allocate compute tg buffers" ); 657 } 658 659n_splits_tg = ggml_backend_sched_get_n_splits (sched .get ()); 660n_nodes_tg = ggml_graph_n_nodes (gf ); 661 } 662 663// reserve again with pp graph to avoid ggml-alloc reallocations during inference 664 { 665// TODO: the worst case graph is not always reached for `n_seqs > 1` 666// need to implement a more robust mechanism that tries a few different inputs and analyzes the results 667ggml_cgraph * gf = nullptr ; 668switch (model .arch ) { 669case LLM_ARCH_KIMI_LINEAR : 670case LLM_ARCH_MINIMAX_01 : 671// [TAG_RESERVE_DIAG_DECAY] 672// the `inp_diag_decay` tensor size scales with `n_seq_tokens^2` which 673// makes `n_seqs == 1` use more memory for the compute graph compared to `n_seqs > 1` 674gf = graph_reserve (n_tokens ,1 ,n_outputs_pp ,mctx .get (),model .hparams .no_alloc ); 675break ; 676default : 677gf = graph_reserve (n_tokens ,n_seqs ,n_outputs_pp ,mctx .get (),model .hparams .no_alloc ); 678 }; 679 680if (!gf ) { 681throw std::runtime_error ("failed to allocate compute pp buffers" ); 682 } 683 } 684 685for (size_t i = 0 ;i < backend_ptrs .size ();++ i ) { 686ggml_backend_t backend = backend_ptrs [i ]; 687ggml_backend_buffer_type_t buft = backend_buft [i ]; 688if (!model .hparams .no_alloc ) { 689backend_buf_exp_size [i ]= ggml_backend_sched_get_buffer_size (sched .get (),backend ); 690 } 691if (backend_buf_exp_size [i ]> 1 ) { 692LLAMA_LOG_INFO ("%s: %10s compute buffer size = %8.2f MiB\n" ,__func__ , 693ggml_backend_buft_name (buft ), 694backend_buf_exp_size [i ] /1024.0 /1024.0 ); 695 } 696 } 697 698if (n_nodes_pp == n_nodes_tg ) { 699LLAMA_LOG_INFO ("%s: graph nodes = %d\n" ,__func__ ,n_nodes_pp ); 700 }else { 701LLAMA_LOG_INFO ("%s: graph nodes = %d (with bs=%d), %d (with bs=1)\n" ,__func__ ,n_nodes_pp ,n_tokens ,n_nodes_tg ); 702 } 703 704if (n_splits_pp == n_splits_tg ) { 705LLAMA_LOG_INFO ("%s: graph splits = %d\n" ,__func__ ,n_splits_pp ); 706 }else { 707LLAMA_LOG_INFO ("%s: graph splits = %d (with bs=%d), %d (with bs=1)\n" ,__func__ ,n_splits_pp ,n_tokens ,n_splits_tg ); 708 } 709 710const int64_t t_end_us = ggml_time_us (); 711 712LLAMA_LOG_INFO ("%s: reserve took %.2f ms, sched copies = %d\n" , 713__func__ , (t_end_us - t_start_us )/1000.0 ,ggml_backend_sched_get_n_copies (sched .get ())); 714} 715 716void llama_context::synchronize () { 717if (!sched ) { 718return ; 719 } 720 721ggml_backend_sched_synchronize (sched .get ()); 722 723// FIXME: if multiple single tokens are evaluated without a synchronization, 724// the stats will be added to the prompt evaluation stats 725// this should only happen when using batch size 1 to evaluate a batch 726 727// add the evaluation to the stats 728if (n_queued_tokens == 1 ) { 729if (!cparams .no_perf ) { 730t_eval_us += ggml_time_us ()- t_compute_start_us ; 731 } 732n_eval ++ ; 733 }else if (n_queued_tokens > 1 ) { 734if (!cparams .no_perf ) { 735t_p_eval_us += ggml_time_us ()- t_compute_start_us ; 736 } 737n_p_eval += n_queued_tokens ; 738 } 739 740// get a more accurate load time, upon first eval 741if (n_queued_tokens > 0 && !has_evaluated_once ) { 742t_load_us = ggml_time_us ()- t_start_us ; 743has_evaluated_once = true; 744 } 745 746n_queued_tokens = 0 ; 747t_compute_start_us = 0 ; 748} 749 750const llama_model & llama_context::get_model ()const { 751return model ; 752} 753 754const llama_cparams & llama_context::get_cparams ()const { 755return cparams ; 756} 757 758ggml_backend_sched_t llama_context::get_sched ()const { 759return sched .get (); 760} 761 762uint32_t llama_context::n_ctx ()const { 763return cparams .n_ctx ; 764} 765 766uint32_t llama_context::n_ctx_seq ()const { 767return cparams .n_ctx_seq ; 768} 769 770uint32_t llama_context::n_batch ()const { 771return cparams .n_batch ; 772} 773 774uint32_t llama_context::n_ubatch ()const { 775return cparams .n_ubatch ; 776} 777 778uint32_t llama_context::n_seq_max ()const { 779return cparams .n_seq_max ; 780} 781 782uint32_t llama_context::n_threads ()const { 783return cparams .n_threads ; 784} 785 786uint32_t llama_context::n_threads_batch ()const { 787return cparams .n_threads_batch ; 788} 789 790llama_memory_t llama_context::get_memory ()const { 791return memory .get (); 792} 793 794bool llama_context::memory_update (bool optimize ) { 795if (!memory ) { 796return false; 797 } 798 799 { 800const auto mctx = memory -> init_update (this ,optimize ); 801switch (mctx -> get_status ()) { 802case LLAMA_MEMORY_STATUS_SUCCESS : 803 { 804// noop 805 }break ; 806case LLAMA_MEMORY_STATUS_NO_UPDATE : 807 { 808// no updates need to be performed 809return false; 810 } 811case LLAMA_MEMORY_STATUS_FAILED_PREPARE : 812case LLAMA_MEMORY_STATUS_FAILED_COMPUTE : 813 { 814LLAMA_LOG_ERROR ("%s: failed to prepare memory update\n" ,__func__ ); 815return false; 816 } 817 } 818 819// reset the previous graph result to make sure that it won't be reused 820// TODO: change the mctx->apply() to return information if a graph reserve is needed 821// reset the graph result only if the memory module did reset the scheduler 822gf_res_prev -> reset (); 823 824if (!mctx -> apply ()) { 825LLAMA_LOG_ERROR ("%s: failed to apply memory update\n" ,__func__ ); 826 } 827 } 828 829// if the memory module did any computation, we have to reserve a new worst-case graph 830 { 831const auto mctx = memory -> init_full (); 832if (!mctx ) { 833throw std::runtime_error ("failed to initialize memory context" ); 834 } 835 836const uint32_t n_seqs = cparams .n_seq_max ; 837const uint32_t n_tokens = std::min (cparams .n_ctx ,cparams .n_ubatch ); 838 839const uint32_t n_outputs_max = std::min (n_tokens ,cparams .n_outputs_max ); 840 841auto * gf = graph_reserve (n_tokens ,n_seqs ,n_outputs_max ,mctx .get ()); 842if (!gf ) { 843LLAMA_LOG_ERROR ("%s: failed to reserve graph after the memory update\n" ,__func__ ); 844 } 845 } 846 847return true; 848} 849 850enum llama_pooling_type llama_context::pooling_type ()const { 851return cparams .pooling_type ; 852} 853 854float * llama_context::get_logits () { 855output_reorder (); 856 857return logits .data ; 858} 859 860int64_t llama_context::output_resolve_row (int32_t i )const { 861int64_t j = -1 ; 862 863// support negative indices (last output row) 864if (i < 0 ) { 865j = n_outputs + i ; 866if (j < 0 ) { 867throw std::runtime_error (format ("negative index out of range [0, %d)" ,n_outputs )); 868 } 869 }else if ((size_t )i >=output_ids .size ()) { 870throw std::runtime_error (format ("out of range [0, %zu)" ,output_ids .size ())); 871 }else { 872// use output_ids to translate the batch token index into a row number 873// that holds this token's data. 874j = output_ids [i ]; 875 } 876 877if (j < 0 ) { 878// the batch token was not configured to output anything 879throw std::runtime_error (format ("batch.logits[%d] != true" ,i )); 880 } 881 882if (j >=n_outputs ) { 883throw std::runtime_error (format ("corrupt output buffer (j=%" PRId64 ", n_outputs=%d)" ,j ,n_outputs )); 884 } 885 886return j ; 887} 888 889float * llama_context::get_logits_ith (int32_t i ) { 890output_reorder (); 891 892try { 893if (logits .data == nullptr ) { 894throw std::runtime_error ("no logits" ); 895 } 896 897const int64_t j = output_resolve_row (i ); 898return logits .data + j * model .vocab .n_tokens (); 899 }catch (const std::exception & err ) { 900LLAMA_LOG_ERROR ("%s: invalid logits id %d, reason: %s\n" ,__func__ ,i ,err .what ()); 901#ifndef NDEBUG 902GGML_ABORT ("fatal error" ); 903#else 904return nullptr ; 905#endif 906 } 907} 908 909float * llama_context::get_embeddings () { 910output_reorder (); 911 912return embd .data ; 913} 914 915llama_token * llama_context::get_sampled_tokens ()const { 916return sampling .sampled .data ; 917} 918 919float * llama_context::get_embeddings_ith (int32_t i ) { 920output_reorder (); 921 922try { 923if (embd .data == nullptr ) { 924throw std::runtime_error ("no embeddings" ); 925 } 926 927const int64_t j = output_resolve_row (i ); 928const uint32_t n_embd_out = model .hparams .n_embd_out (); 929return embd .data + j * n_embd_out ; 930 }catch (const std::exception & err ) { 931LLAMA_LOG_ERROR ("%s: invalid embeddings id %d, reason: %s\n" ,__func__ ,i ,err .what ()); 932#ifndef NDEBUG 933GGML_ABORT ("fatal error" ); 934#else 935return nullptr ; 936#endif 937 } 938} 939 940float * llama_context::get_embeddings_seq (llama_seq_id seq_id ) { 941auto it = embd_seq .find (seq_id ); 942if (it == embd_seq .end ()) { 943return nullptr ; 944 } 945 946return it -> second .data (); 947} 948 949float * llama_context::get_embeddings_nextn () { 950output_reorder (); 951 952return embd_nextn .data ; 953} 954 955float * llama_context::get_embeddings_nextn_ith (int32_t i ) { 956output_reorder (); 957 958try { 959if (embd_nextn .data == nullptr ) { 960throw std::runtime_error ("no nextn embeddings" ); 961 } 962 963const uint32_t n_embd = model .hparams .n_embd_out (); 964 965if (!cparams .embeddings_nextn_masked ) { 966// unmasked: nextn rows are stored densely, indexed by raw token position. 967if (i < 0 || (size_t )(i + 1 )* n_embd > embd_nextn .size ) { 968throw std::runtime_error (format ("out of range [0, %zu)" ,embd_nextn .size /n_embd )); 969 } 970return embd_nextn .data + (size_t )i * n_embd ; 971 } 972 973const int64_t j = output_resolve_row (i ); 974return embd_nextn .data + j * n_embd ; 975 }catch (const std::exception & err ) { 976LLAMA_LOG_ERROR ("%s: invalid nextn embeddings id %d, reason: %s\n" ,__func__ ,i ,err .what ()); 977#ifndef NDEBUG 978GGML_ABORT ("fatal error" ); 979#else 980return nullptr ; 981#endif 982 } 983} 984 985float * llama_context::get_embeddings_layer_inp (uint32_t lid ) { 986output_reorder (); 987 988GGML_ASSERT (lid < embd_layer_inp .size ()&& embd_layer_inp [lid ].has_data ()); 989 990return embd_layer_inp [lid ].data ; 991} 992 993llama_token llama_context::get_sampled_token_ith (int32_t idx ) { 994output_reorder (); 995 996if (!sampling .sampled .has_data ()) { 997return LLAMA_TOKEN_NULL ; 998 } 999 1000try { 1001const int64_t row = output_resolve_row (idx ); 1002GGML_ASSERT (row < (int64_t )sampling .sampled .size ); 1003return sampling .sampled .data [row ]; 1004 }catch (const std::exception & err ) { 1005LLAMA_LOG_ERROR ("%s: invalid backend sampled token id %d, reason: %s\n" ,__func__ ,idx ,err .what ()); 1006return LLAMA_TOKEN_NULL ; 1007 } 1008} 1009 1010float * llama_context::get_sampled_probs_ith (int32_t idx ) { 1011output_reorder (); 1012 1013if (!sampling .probs .has_data ()) { 1014return nullptr ; 1015 } 1016 1017try { 1018const int64_t row = output_resolve_row (idx ); 1019if ((size_t )row >=sampling .probs_count .size ()|| sampling .probs_count [row ]== 0 ) { 1020return nullptr ; 1021 } 1022return sampling .probs .data + row * model .vocab .n_tokens (); 1023 }catch (const std::exception & err ) { 1024LLAMA_LOG_ERROR ("%s: invalid backend sampled probs id %d, reason: %s\n" ,__func__ ,idx ,err .what ()); 1025return nullptr ; 1026 } 1027} 1028 1029float * llama_context::get_sampled_logits_ith (int32_t idx ) { 1030output_reorder (); 1031 1032if (!sampling .logits .has_data ()) { 1033return nullptr ; 1034 } 1035 1036try { 1037const int64_t row = output_resolve_row (idx ); 1038if ((size_t )row >=sampling .logits_count .size ()|| sampling .logits_count [row ]== 0 ) { 1039return nullptr ; 1040 } 1041return sampling .logits .data + row * model .vocab .n_tokens (); 1042 }catch (const std::exception & err ) { 1043LLAMA_LOG_ERROR ("%s: invalid backend sampled logits id %d, reason: %s\n" ,__func__ ,idx ,err .what ()); 1044return nullptr ; 1045 } 1046} 1047 1048const llama_token * llama_context::get_sampled_candidates_ith (int32_t idx ) { 1049output_reorder (); 1050 1051try { 1052const int64_t row = output_resolve_row (idx ); 1053if (sampling .candidates .has_data ()&& 1054 (size_t )row < sampling .candidates_count .size ()&& 1055sampling .candidates_count [row ]> 0 ) { 1056return sampling .candidates .data + row * model .vocab .n_tokens (); 1057 } 1058 }catch (const std::exception & err ) { 1059// fallback to full vocab list 1060GGML_UNUSED (err ); 1061 } 1062 1063return sampling .token_ids_full_vocab .data (); 1064} 1065 1066size_t llama_context::get_sampled_candidates_count (int32_t idx ) { 1067output_reorder (); 1068 1069if (!sampling .candidates .has_data ()) { 1070return 0 ; 1071 } 1072 1073try { 1074const int64_t row = output_resolve_row (idx ); 1075if ((size_t )row >=sampling .candidates_count .size ()) { 1076return 0 ; 1077 } 1078return sampling .candidates_count [row ]; 1079 }catch (const std::exception & err ) { 1080LLAMA_LOG_ERROR ("%s: invalid backend sampled candidates count id %d, reason: %s\n" ,__func__ ,idx ,err .what ()); 1081return 0 ; 1082 } 1083} 1084 1085size_t llama_context::get_sampled_logits_count (int32_t idx ) { 1086output_reorder (); 1087 1088if (!sampling .logits .has_data ()) { 1089return model .vocab .n_tokens (); 1090 } 1091 1092try { 1093const int64_t row = output_resolve_row (idx ); 1094if ((size_t )row >=sampling .logits_count .size ()) { 1095return 0 ; 1096 } 1097return sampling .logits_count [row ]; 1098 }catch (const std::exception & err ) { 1099LLAMA_LOG_ERROR ("%s: invalid backend sampled logits count id %d, reason: %s\n" ,__func__ ,idx ,err .what ()); 1100return 0 ; 1101 } 1102} 1103 1104size_t llama_context::get_sampled_probs_count (int32_t idx ) { 1105output_reorder (); 1106 1107if (!sampling .probs .has_data ()) { 1108return 0 ; 1109 } 1110 1111try { 1112const int64_t row = output_resolve_row (idx ); 1113if ((size_t )row >=sampling .probs_count .size ()) { 1114return 0 ; 1115 } 1116return sampling .probs_count [row ]; 1117 }catch (const std::exception & err ) { 1118LLAMA_LOG_ERROR ("%s: invalid backend sampled probs count id %d, reason: %s\n" ,__func__ ,idx ,err .what ()); 1119return 0 ; 1120 } 1121} 1122 1123 1124void llama_context::attach_threadpool ( 1125ggml_threadpool_t threadpool , 1126ggml_threadpool_t threadpool_batch ) { 1127LLAMA_LOG_DEBUG ("%s: call\n" ,__func__ ); 1128 1129this -> threadpool = threadpool ; 1130this -> threadpool_batch = threadpool_batch ?threadpool_batch :threadpool ; 1131} 1132 1133void llama_context::detach_threadpool () { 1134LLAMA_LOG_DEBUG ("%s: call\n" ,__func__ ); 1135 1136this -> threadpool = nullptr ; 1137this -> threadpool_batch = nullptr ; 1138} 1139 1140void llama_context::set_n_threads (int32_t n_threads ,int32_t n_threads_batch ) { 1141LLAMA_LOG_DEBUG ("%s: n_threads = %d, n_threads_batch = %d\n" ,__func__ ,n_threads ,n_threads_batch ); 1142 1143cparams .n_threads = n_threads ; 1144cparams .n_threads_batch = n_threads_batch ; 1145} 1146 1147void llama_context::set_abort_callback (bool (* abort_callback )(void * data ),void * abort_callback_data ) { 1148LLAMA_LOG_DEBUG ("%s: call\n" ,__func__ ); 1149 1150this -> abort_callback = abort_callback ; 1151this -> abort_callback_data = abort_callback_data ; 1152 1153for (auto & backend :backends ) { 1154auto * reg = ggml_backend_dev_backend_reg (ggml_backend_get_device (backend .get ())); 1155if (reg ) { 1156auto * set_abort_callback_fn = (ggml_backend_set_abort_callback_t )ggml_backend_reg_get_proc_address (reg ,"ggml_backend_set_abort_callback" ); 1157if (set_abort_callback_fn ) { 1158set_abort_callback_fn (backend .get (),this -> abort_callback ,this -> abort_callback_data ); 1159 } 1160 } 1161 } 1162} 1163 1164void llama_context::set_embeddings (bool value ) { 1165LLAMA_LOG_DEBUG ("%s: value = %d\n" ,__func__ ,value ); 1166 1167cparams .embeddings = value ; 1168 1169// TODO: not sure yet if we want to reserve here 1170//sched_need_reserve = true; 1171} 1172 1173void llama_context::set_embeddings_nextn (bool value ,bool masked ) { 1174LLAMA_LOG_DEBUG ("%s: value = %d, masked = %d\n" ,__func__ ,value ,masked ); 1175 1176cparams .embeddings_nextn = value ; 1177cparams .embeddings_nextn_masked = masked ; 1178} 1179 1180void llama_context::set_embeddings_layer_inp (uint32_t lid ,bool enable ) { 1181LLAMA_LOG_DEBUG ("%s: lid = %d, enable = %d\n" ,__func__ ,lid ,enable ); 1182 1183GGML_ASSERT (lid <=model .hparams .n_layer ()); 1184 1185cparams .embeddings_layer_inp [lid ]= enable ; 1186 1187// note: without this reserve, the draft acceptance drops to zero. not sure why - this is unexpected 1188sched_need_reserve = true; 1189} 1190 1191void llama_context::set_nextn_layer_offset (int32_t offset ) { 1192cparams .nextn_layer_offset = offset ; 1193} 1194 1195void llama_context::set_causal_attn (bool value ) { 1196LLAMA_LOG_DEBUG ("%s: value = %d\n" ,__func__ ,value ); 1197 1198if (cparams .causal_attn == value ) { 1199return ; 1200 } 1201 1202cparams .causal_attn = value ; 1203 1204sched_need_reserve = true; 1205} 1206 1207void llama_context::set_warmup (bool value ) { 1208LLAMA_LOG_DEBUG ("%s: value = %d\n" ,__func__ ,value ); 1209 1210if (cparams .warmup == value ) { 1211return ; 1212 } 1213 1214cparams .warmup = value ; 1215 1216// warmups are usually with small batches, so no need to reserve 1217//sched_need_reserve = true; 1218} 1219 1220bool llama_context::set_sampler (llama_seq_id seq_id ,llama_sampler * sampler ) { 1221if (!sampler && sampling .samplers .count (seq_id )== 0 ) { 1222return true; 1223 } 1224 1225LLAMA_LOG_DEBUG ("%s: seq_id = %d, sampler = %p\n" ,__func__ , (int )seq_id , (void * )sampler ); 1226 1227if (sampler && model .split_mode ()== LLAMA_SPLIT_MODE_TENSOR ) { 1228static bool warned = false; 1229if (!warned ) { 1230LLAMA_LOG_WARN ("%s: backend sampling not supported with SPLIT_MODE_TENSOR; using CPU\n" ,__func__ ); 1231warned = true; 1232 } 1233if (sampling .samplers .count (seq_id )> 0 ) { 1234sched_need_reserve = true; 1235 } 1236sampling .samplers .erase (seq_id ); 1237return false; 1238 } 1239 1240const bool can_offload = 1241sampler && 1242sampler -> iface -> backend_init && 1243sampler -> iface -> backend_apply && 1244llama_sampler_chain_n (sampler )> 0 ; 1245 1246if (sampler && can_offload ) { 1247auto * buft = ggml_backend_dev_buffer_type (model .dev_output ()); 1248 1249sampler -> iface -> backend_init (sampler ,buft ,cparams .n_outputs_max_per_seq ); 1250 1251sampling .samplers [seq_id ]= sampler ; 1252 1253sched_need_reserve = true; 1254 1255return true; 1256 } 1257 1258if (sampler && !can_offload ) { 1259LLAMA_LOG_WARN ("%s: sampler '%s' for seq_id = %d, cannot be offloaded to the backend\n" ,__func__ ,llama_sampler_name (sampler ),seq_id ); 1260 1261if (sampling .samplers .count (seq_id )> 0 ) { 1262sched_need_reserve = true; 1263 } 1264 1265sampling .samplers .erase (seq_id ); 1266 1267return false; 1268 } 1269 1270sampling .samplers .erase (seq_id ); 1271 1272sched_need_reserve = true; 1273 1274return true; 1275} 1276 1277void llama_context::set_adapters_lora (llama_adapter_lora ** adapters ,size_t n_adapters ,float * scales ) { 1278LLAMA_LOG_DEBUG ("%s: adapters = %p\n" ,__func__ , (void * )adapters ); 1279 1280if (adapters_lora_are_same (adapters ,n_adapters ,scales )) { 1281return ; 1282 } 1283 1284loras .reset (new llama_adapter_loras ()); 1285 1286for (size_t i = 0 ;i < n_adapters ;i ++ ) { 1287if (scales [i ]!= 0.0f ) { 1288loras -> insert ({adapters [i ],scales [i ]}); 1289 } 1290 } 1291 1292sched_need_reserve = true; 1293} 1294 1295bool llama_context::adapters_lora_are_same (llama_adapter_lora ** adapters ,size_t n_adapters ,float * scales ) { 1296LLAMA_LOG_DEBUG ("%s: adapters = %p\n" ,__func__ , (void * )adapters ); 1297 1298// Adapters with a zero scale are never added to `loras`, so also ignore them for the comparison. 1299size_t n_non_zero = 0 ; 1300 1301for (size_t i = 0 ;i < n_adapters ;i ++ ) { 1302if (scales [i ]== 0.0f ) { 1303continue ; 1304 } 1305n_non_zero ++ ; 1306 1307auto it = loras -> find (adapters [i ]); 1308 1309if (it == loras -> end ()|| it -> second != scales [i ]) { 1310return false; 1311 } 1312 } 1313 1314if (n_non_zero != loras -> size ()) { 1315return false; 1316 } 1317 1318return true; 1319} 1320 1321bool llama_context::set_adapter_cvec ( 1322const float * data , 1323size_t len , 1324int32_t n_embd , 1325int32_t il_start , 1326int32_t il_end ) { 1327LLAMA_LOG_DEBUG ("%s: il_start = %d, il_end = %d\n" ,__func__ ,il_start ,il_end ); 1328 1329bool res = cvec -> apply (model ,data ,len ,n_embd ,il_start ,il_end ); 1330 1331sched_need_reserve = true; 1332 1333return res ; 1334} 1335 1336llm_graph_result * llama_context::process_ubatch (const llama_ubatch & ubatch ,llm_graph_type gtype ,llama_memory_context_i * mctx ,ggml_status & ret ) { 1337if (mctx && !mctx -> apply ()) { 1338LLAMA_LOG_ERROR ("%s: failed to apply memory context\n" ,__func__ ); 1339ret = GGML_STATUS_FAILED ; 1340return nullptr ; 1341 } 1342 1343auto * res = gf_res_prev .get (); 1344auto * gf = res -> get_gf (); 1345 1346// the new graph parameters 1347// in order to correctly reuse a graph, it's full topology has to be uniquely determined by these parameters 1348const auto gparams = graph_params (res ,ubatch ,mctx ,gtype ); 1349 1350if (!graph_reuse_disable && res -> can_reuse (gparams )) { 1351//LLAMA_LOG_DEBUG("%s: reusing previous graph\n", __func__); 1352 1353// with pipeline parallelism, the previous graph_compute_async may still be running 1354// on the GPU. we must synchronize before set_inputs to avoid overwriting input tensors 1355// that the previous compute is still reading. 1356if (cparams .pipeline_parallel ) { 1357ggml_backend_sched_synchronize (sched .get ()); 1358 } 1359 1360n_reused ++ ; 1361 }else { 1362res -> reset (); 1363 1364ggml_backend_sched_reset (sched .get ()); 1365ggml_backend_sched_set_eval_callback (sched .get (),cparams .cb_eval ,cparams .cb_eval_user_data ); 1366 1367//const auto t_start_us = ggml_time_us(); 1368 1369gf = model .build_graph (gparams ); 1370 1371//LLAMA_LOG_INFO("graph build time: %.3f ms\n", (ggml_time_us() - t_start_us)/1000.0); 1372 1373if (!gf ) { 1374LLAMA_LOG_ERROR ("%s: failed to initialize graph\n" ,__func__ ); 1375ret = GGML_STATUS_FAILED ; 1376return nullptr ; 1377 } 1378 1379if (!ggml_backend_sched_alloc_graph (sched .get (),gf )) { 1380LLAMA_LOG_ERROR ("%s: failed to allocate graph\n" ,__func__ ); 1381ret = GGML_STATUS_ALLOC_FAILED ; 1382return nullptr ; 1383 } 1384 } 1385 1386// set the input data for the input tensors 1387 { 1388//const auto t_start_us = ggml_time_us(); 1389 1390// FIXME this call causes a crash if any model inputs were not used in the graph and were therefore not allocated 1391res -> set_inputs (& ubatch ); 1392 1393//LLAMA_LOG_INFO("graph set inputs time: %.3f ms\n", (ggml_time_us() - t_start_us)/1000.0); 1394 } 1395 1396const auto status = graph_compute (res -> get_gf (),ubatch .n_tokens > 1 ); 1397if (status != GGML_STATUS_SUCCESS ) { 1398LLAMA_LOG_ERROR ("%s: failed to compute graph, compute status: %d\n" ,__func__ ,status ); 1399ret = status ; 1400return nullptr ; 1401 } 1402 1403ret = GGML_STATUS_SUCCESS ; 1404 1405return res ; 1406} 1407 1408int llama_context::encode (const llama_batch & batch_inp ) { 1409// MTP hook batches carry both token (next-token id) and embd (h_nextn row), 1410// so accept either present rather than requiring exactly one. 1411GGML_ASSERT (batch_inp .token || batch_inp .embd ); 1412 1413if (batch_inp .n_tokens == 0 ) { 1414LLAMA_LOG_ERROR ("%s: n_tokens == 0\n" ,__func__ ); 1415return -1 ; 1416 } 1417 1418const auto & hparams = model .hparams ; 1419 1420// eagle3/DFlash: features as encoder input, and non-draft paths fall back to model's input dim 1421const int64_t n_embd = hparams .n_embd_inp_enc (); 1422const int64_t n_vocab = model .vocab .n_tokens (); 1423 1424// note: during encode, we always pass the full sequence starting from pos = 0 1425if (!balloc -> init (batch_inp ,model .vocab ,nullptr ,n_embd ,cparams .kv_unified ?LLAMA_MAX_SEQ :cparams .n_seq_max , true)) { 1426LLAMA_LOG_ERROR ("%s: failed to initialize batch\n" ,__func__ ); 1427return -1 ; 1428 } 1429 1430const uint32_t n_tokens = balloc -> get_n_tokens (); 1431 1432// [TAG_NO_CACHE_PAD] 1433// TODO: add new split mode where we pad the input sequences so that ubatch.equal_seqs == true 1434const llama_ubatch ubatch = balloc -> split_simple (n_tokens ); 1435 1436// micro-batching is not possible for non-causal encoding, so we process the batch in a single shot 1437GGML_ASSERT (cparams .n_ubatch >=n_tokens && "encoder requires n_ubatch >= n_tokens" ); 1438 1439// TODO: this clear of the buffer can easily be forgotten - need something better 1440// sync first so any in-flight async copies into embd_seq complete before it is freed 1441if (!embd_seq .empty ()) { 1442synchronize (); 1443 } 1444embd_seq .clear (); 1445 1446if (t_compute_start_us == 0 ) { 1447t_compute_start_us = ggml_time_us (); 1448 } 1449 1450sched_reserve (); 1451 1452n_queued_tokens += n_tokens ; 1453 1454// reserve output buffer 1455if (output_reserve (n_tokens )< n_tokens ) { 1456LLAMA_LOG_ERROR ("%s: could not reserve space for batch with %u outputs\n" ,__func__ ,n_tokens ); 1457return -2 ; 1458 }; 1459 1460for (uint32_t i = 0 ;i < n_tokens ;++ i ) { 1461output_ids [i ]= i ; 1462 } 1463 1464n_outputs = n_tokens ; 1465 1466const auto causal_attn_org = cparams .causal_attn ; 1467 1468// always use non-causal attention for encoder graphs 1469// TODO: this is a tmp solution until we have a proper way to support enc-dec models 1470// ref: https://github.com/ggml-org/llama.cpp/pull/12181#issuecomment-2730451223 1471cparams .causal_attn = false; 1472 1473ggml_status status ; 1474const auto * res = process_ubatch (ubatch ,LLM_GRAPH_TYPE_ENCODER ,nullptr ,status ); 1475 1476cparams .causal_attn = causal_attn_org ; 1477 1478if (!res ) { 1479switch (status ) { 1480case GGML_STATUS_ABORTED :return 2 ; 1481case GGML_STATUS_ALLOC_FAILED :return -2 ; 1482case GGML_STATUS_FAILED :return -3 ; 1483case GGML_STATUS_SUCCESS :GGML_ABORT ("should not happen" ); 1484 } 1485 } 1486 1487auto * t_logits = res -> get_logits (); 1488auto * t_embd = res -> get_embd_pooled () ?res -> get_embd_pooled () :res -> get_embd (); 1489auto * t_h_nextn = cparams .embeddings_nextn ?res -> get_h_nextn () :nullptr ; 1490 1491// extract logits 1492if (logits .data && t_logits ) { 1493ggml_backend_t backend_res = ggml_backend_sched_get_tensor_backend (sched .get (),t_logits ); 1494GGML_ASSERT (backend_res != nullptr ); 1495GGML_ASSERT (logits .data != nullptr ); 1496 1497ggml_backend_tensor_get_async (backend_res ,t_logits ,logits .data ,0 ,n_tokens * n_vocab * sizeof (float )); 1498 } 1499 1500// extract embeddings 1501if (embd .data && t_embd ) { 1502ggml_backend_t backend_embd = ggml_backend_sched_get_tensor_backend (sched .get (),t_embd ); 1503GGML_ASSERT (backend_embd != nullptr ); 1504 1505switch (cparams .pooling_type ) { 1506case LLAMA_POOLING_TYPE_NONE : 1507 { 1508// extract token embeddings 1509GGML_ASSERT (embd .data != nullptr ); 1510const uint32_t n_embd_out = hparams .n_embd_out (); 1511 1512GGML_ASSERT (n_tokens * n_embd_out <= (int64_t )embd .size ); 1513ggml_backend_tensor_get_async (backend_embd ,t_embd ,embd .data ,0 ,n_tokens * n_embd_out * sizeof (float )); 1514 }break ; 1515case LLAMA_POOLING_TYPE_MEAN : 1516case LLAMA_POOLING_TYPE_CLS : 1517case LLAMA_POOLING_TYPE_LAST : 1518 { 1519// extract sequence embeddings 1520auto & embd_seq_out = embd_seq ; 1521 1522for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 1523const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 1524const int32_t seq_idx = ubatch .seq_idx [seq_id ]; 1525 1526// use n_embd_out (not n_embd_inp) - the pooled embedding has the model's 1527// output dimension, which differs from input dimension for deepstack models (e.g. qwen3vl) 1528const uint32_t n_embd_out = hparams .n_embd_out (); 1529embd_seq_out [seq_id ].resize (n_embd_out ); 1530ggml_backend_tensor_get_async (backend_embd ,t_embd ,embd_seq_out [seq_id ].data (), (n_embd_out * seq_idx )* sizeof (float ),n_embd_out * sizeof (float )); 1531 } 1532 }break ; 1533case LLAMA_POOLING_TYPE_RANK : 1534 { 1535// extract the rerank score - n_cls_out floats per sequence 1536auto & embd_seq_out = embd_seq ; 1537 1538const uint32_t n_cls_out = hparams .n_cls_out ; 1539 1540for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 1541const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 1542const int32_t seq_idx = ubatch .seq_idx [seq_id ]; 1543 1544embd_seq_out [seq_id ].resize (n_cls_out ); 1545ggml_backend_tensor_get_async (backend_embd ,t_embd ,embd_seq_out [seq_id ].data (), (n_cls_out * seq_idx )* sizeof (float ),n_cls_out * sizeof (float )); 1546 } 1547 }break ; 1548case LLAMA_POOLING_TYPE_UNSPECIFIED : 1549 { 1550GGML_ABORT ("unknown pooling type" ); 1551 } 1552 } 1553 } 1554 1555// extract nextn embeddings (hidden state before the final output norm) 1556if (embd_nextn .data && t_h_nextn && cparams .pooling_type == LLAMA_POOLING_TYPE_NONE ) { 1557ggml_backend_t backend_h = ggml_backend_sched_get_tensor_backend (sched .get (),t_h_nextn ); 1558GGML_ASSERT (backend_h != nullptr ); 1559 1560const uint32_t n_embd = hparams .n_embd_out (); 1561GGML_ASSERT (n_tokens * n_embd <= (int64_t )embd_nextn .size ); 1562ggml_backend_tensor_get_async (backend_h ,t_h_nextn ,embd_nextn .data ,0 ,n_tokens * n_embd * sizeof (float )); 1563 } 1564 1565// TODO: hacky solution 1566if ((model .arch == LLM_ARCH_T5 || model .arch == LLM_ARCH_ALICEAI_T5_MOE )&& t_embd ) { 1567//cross.t_embd = t_embd; 1568 1569synchronize (); 1570 1571cross .n_embd = t_embd -> ne [0 ]; 1572cross .n_enc = t_embd -> ne [1 ]; 1573cross .v_embd .resize (cross .n_embd * cross .n_enc ); 1574memcpy (cross .v_embd .data (),embd .data ,ggml_nbytes (t_embd )); 1575 1576const auto & batch = balloc -> get_batch (); 1577 1578// remember the sequence ids used during the encoding - needed for cross attention later 1579cross .seq_ids_enc .resize (n_tokens ); 1580for (uint32_t i = 0 ;i < n_tokens ;i ++ ) { 1581cross .seq_ids_enc [i ].clear (); 1582 1583for (int s = 0 ;s < batch .n_seq_id [i ];s ++ ) { 1584const llama_seq_id seq_id = batch .seq_id [i ][s ]; 1585 1586cross .seq_ids_enc [i ].insert (seq_id ); 1587 } 1588 } 1589 } 1590 1591return 0 ; 1592} 1593 1594template < typename T > 1595static void copy_tensor_async_rows ( 1596const std::vector < ggml_tensor *> & tensors , 1597const buffer_view < T > & dst , 1598size_t stride , 1599uint32_t row_offset , 1600ggml_backend_sched_t sched , 1601 std::vector < uint32_t > * counts = nullptr ) { 1602if (!dst .has_data ()) { 1603return ; 1604 } 1605 1606for (size_t i = 0 ;i < tensors .size ();++ i ) { 1607auto * tensor = tensors [i ]; 1608if (tensor == nullptr ) { 1609continue ; 1610 } 1611 1612const uint32_t row = row_offset + i ; 1613const size_t n_elements = ggml_nelements (tensor ); 1614GGML_ASSERT (ggml_is_contiguous (tensor )&& "sampling tensor must be contiguous for async copy" ); 1615GGML_ASSERT (n_elements <=stride ); 1616GGML_ASSERT ((size_t )row * stride + n_elements <=dst .size ); 1617 1618ggml_backend_t backend = ggml_backend_sched_get_tensor_backend (sched ,tensor ); 1619T * row_ptr = dst .data + (size_t )row * stride ; 1620ggml_backend_tensor_get_async (backend ,tensor ,row_ptr ,0 ,ggml_nbytes (tensor )); 1621 1622if (counts ) { 1623GGML_ASSERT (row < counts -> size ()); 1624 (* counts )[row ]= n_elements ; 1625 } 1626 } 1627} 1628 1629static bool needs_raw_logits (const llama_ubatch & ubatch ,const std::map < llama_seq_id ,llama_sampler *> & samplers ) { 1630for (uint32_t i = 0 ;i < ubatch .n_tokens ;i ++ ) { 1631if (!ubatch .output [i ]) { 1632continue ; 1633 } 1634 1635// Check if the output token has at least one sequence without a backend sampler. 1636for (int32_t j = 0 ;j < ubatch .n_seq_id [i ];++ j ) { 1637llama_seq_id seq_id = ubatch .seq_id [i ][j ]; 1638if (samplers .find (seq_id )== samplers .end ()) { 1639return true; 1640 } 1641 } 1642 } 1643return false;// all sequences use backend sampling 1644} 1645 1646int llama_context::decode (const llama_batch & batch_inp ) { 1647// MTP hook batches carry both token (next-token id) and embd (h_nextn row), 1648// so accept either present rather than requiring exactly one. 1649GGML_ASSERT (batch_inp .token || batch_inp .embd ); 1650 1651if (!memory ) { 1652LLAMA_LOG_DEBUG ("%s: cannot decode batches with this context (calling encode() instead)\n" ,__func__ ); 1653return encode (batch_inp ); 1654 } 1655 1656if (batch_inp .n_tokens == 0 ) { 1657LLAMA_LOG_ERROR ("%s: n_tokens == 0\n" ,__func__ ); 1658return -1 ; 1659 } 1660 1661const auto & vocab = model .vocab ; 1662const auto & hparams = model .hparams ; 1663 1664const int64_t n_vocab = vocab .n_tokens (); 1665const bool mtp_embd = cparams .ctx_type == LLAMA_CONTEXT_TYPE_MTP && batch_inp .embd ; 1666// DFlash embd batches carry the fused target features at the encoder input width 1667const bool dflash_embd = model .arch == LLM_ARCH_DFLASH && batch_inp .embd ; 1668const int64_t n_embd = mtp_embd ?hparams .n_embd_out () :dflash_embd ?hparams .n_embd_inp_enc () :hparams .n_embd_inp (); 1669 1670// when computing embeddings, all tokens are output 1671const bool output_all = cparams .embeddings ; 1672const bool has_samplers = !sampling .samplers .empty (); 1673 1674const uint32_t n_seq_max = cparams .kv_unified ?LLAMA_MAX_SEQ :cparams .n_seq_max ; 1675 1676// embedding contexts output every token even when batch.logits is not set 1677if (has_samplers && (output_all || batch_inp .logits )) { 1678 std::vector < int32_t > seq_output_count (n_seq_max ,0 ); 1679 1680for (int32_t i = 0 ;i < batch_inp .n_tokens ;++ i ) { 1681if (!output_all && batch_inp .logits [i ]== 0 ) { 1682continue ; 1683 } 1684 1685const int ns = batch_inp .n_seq_id ?batch_inp .n_seq_id [i ] :1 ; 1686 1687for (int32_t s = 0 ;s < ns ;++ s ) { 1688const llama_seq_id seq_id = batch_inp .seq_id ?batch_inp .seq_id [i ][s ] :0 ; 1689 1690if (seq_id < 0 || (uint32_t )seq_id >=n_seq_max ) { 1691continue ; 1692 } 1693 1694seq_output_count [seq_id ]++ ; 1695auto sampler = sampling .samplers .find (seq_id ); 1696if (sampler != sampling .samplers .end ()&& 1697seq_output_count [seq_id ]> (int32_t )cparams .n_outputs_max_per_seq ) { 1698LLAMA_LOG_ERROR ("%s: backend sampling supports at most %u outputs per sequence " 1699"(seq_id %d had %d)\n" ,__func__ ,cparams .n_outputs_max_per_seq , 1700seq_id ,seq_output_count [seq_id ]); 1701return -1 ; 1702 } 1703 } 1704 } 1705 } 1706 1707if (!balloc -> init (batch_inp ,vocab ,memory .get (),n_embd ,n_seq_max ,output_all )) { 1708LLAMA_LOG_ERROR ("%s: failed to initialize batch\n" ,__func__ ); 1709return -1 ; 1710 } 1711 1712const uint32_t n_tokens_all = balloc -> get_n_tokens (); 1713const uint32_t n_outputs_all = balloc -> get_n_outputs (); 1714 1715if (output_all ) { 1716// require that all tokens are output 1717if (n_outputs_all != n_tokens_all ) { 1718LLAMA_LOG_ERROR ("%s: pooled embedding requires that all tokens are output (n_outputs_all = %d, n_tokens_all = %d)\n" , 1719__func__ ,n_outputs_all ,n_tokens_all ); 1720return -1 ; 1721 } 1722 } 1723 1724GGML_ASSERT (n_tokens_all <=cparams .n_batch ); 1725 1726GGML_ASSERT ((cparams .causal_attn || cparams .n_ubatch >=n_tokens_all )&& "non-causal attention requires n_ubatch >= n_tokens" ); 1727 1728// TODO: this clear of the buffer can easily be forgotten - need something better 1729// sync first so any in-flight async copies into embd_seq complete before it is freed 1730if (!embd_seq .empty ()) { 1731synchronize (); 1732 } 1733embd_seq .clear (); 1734 1735if (t_compute_start_us == 0 ) { 1736t_compute_start_us = ggml_time_us (); 1737 } 1738n_queued_tokens += n_tokens_all ; 1739 1740output_swaps .clear (); 1741 1742sched_reserve (); 1743 1744bool did_optimize = false; 1745 1746// handle any pending shifts/copies 1747memory_update (false); 1748 1749llama_memory_context_ptr mctx ; 1750 1751while (true) { 1752mctx = memory -> init_batch (* balloc ,cparams .n_ubatch ,output_all ); 1753if (!mctx ) { 1754return -2 ; 1755 } 1756 1757switch (mctx -> get_status ()) { 1758case LLAMA_MEMORY_STATUS_SUCCESS : 1759 { 1760 }break ; 1761case LLAMA_MEMORY_STATUS_NO_UPDATE : 1762 { 1763LLAMA_LOG_ERROR ("%s: unexpected memory context status: %d\n" ,__func__ ,mctx -> get_status ()); 1764 1765return -2 ; 1766 } 1767case LLAMA_MEMORY_STATUS_FAILED_PREPARE : 1768 { 1769if (!did_optimize ) { 1770did_optimize = true; 1771 1772if (memory_update (true)) { 1773LLAMA_LOG_DEBUG ("%s: retrying batch size %d after cache optimization\n" ,__func__ ,balloc -> get_n_tokens ()); 1774 1775continue ; 1776 } 1777 } 1778 1779LLAMA_LOG_WARN ("%s: failed to find a memory slot for batch of size %d\n" ,__func__ ,balloc -> get_n_tokens ()); 1780 1781return 1 ; 1782 } 1783case LLAMA_MEMORY_STATUS_FAILED_COMPUTE : 1784 { 1785LLAMA_LOG_ERROR ("%s: compute failed while preparing batch of size %d\n" ,__func__ ,balloc -> get_n_tokens ()); 1786 1787return -2 ; 1788 } 1789 } 1790 1791break ; 1792 } 1793 1794// reserve output buffer 1795if (output_reserve (n_outputs_all )< n_outputs_all ) { 1796LLAMA_LOG_ERROR ("%s: could not reserve space for batch with %d outputs\n" ,__func__ ,n_outputs_all ); 1797return -2 ; 1798 }; 1799 1800// start a new sampling transaction for this logical batch 1801for (const auto & entry :sampling .samplers ) { 1802llama_sampler_backend_begin (entry .second ); 1803 } 1804 1805int64_t n_outputs_prev = 0 ; 1806int64_t n_tokens_prev = 0 ; 1807 1808do { 1809const auto & ubatch = mctx -> get_ubatch (); 1810 1811// count the outputs in this ubatch 1812 { 1813int32_t n_outputs_new = 0 ; 1814 1815if (n_outputs_all == n_tokens_all ) { 1816n_outputs_new = ubatch .n_tokens ; 1817 }else { 1818for (uint32_t i = 0 ;i < ubatch .n_tokens ;i ++ ) { 1819n_outputs_new += (int32_t ) (ubatch .output [i ]!= 0 ); 1820 } 1821 } 1822 1823// needs to happen before the graph is built 1824n_outputs = n_outputs_new ; 1825 } 1826 1827ggml_status status ; 1828 1829const auto * res = process_ubatch (ubatch ,ctx_type_to_graph_type (cparams .ctx_type ),mctx .get (),status ); 1830 1831if (!res ) { 1832// the last ubatch failed or was aborted -> remove all positions of that ubatch from the memory module 1833llama_pos pos_min [LLAMA_MAX_SEQ ]; 1834for (int s = 0 ;s < LLAMA_MAX_SEQ ;++ s ) { 1835pos_min [s ]= std::numeric_limits < llama_pos > ::max (); 1836 } 1837 1838for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 1839const auto & seq_id = ubatch .seq_id [i ][0 ]; 1840 1841pos_min [seq_id ]= std::min (pos_min [seq_id ],ubatch .pos [i ]); 1842 } 1843 1844for (int s = 0 ;s < LLAMA_MAX_SEQ ;++ s ) { 1845if (pos_min [s ]== std::numeric_limits < llama_pos > ::max ()) { 1846continue ; 1847 } 1848 1849LLAMA_LOG_WARN ("%s: removing memory module entries for seq_id = %d, pos = [%d, +inf)\n" ,__func__ ,s ,pos_min [s ]); 1850 1851memory -> seq_rm (s ,pos_min [s ],-1 ); 1852 } 1853 1854switch (status ) { 1855case GGML_STATUS_ABORTED :return 2 ; 1856case GGML_STATUS_ALLOC_FAILED :return -2 ; 1857case GGML_STATUS_FAILED :return -3 ; 1858case GGML_STATUS_SUCCESS :GGML_ABORT ("should not happen" ); 1859 } 1860 } 1861 1862// plot the computation graph in dot format (for debugging purposes) 1863//if (n_past%100 == 0) { 1864// ggml_graph_dump_dot(gf, NULL, "llama.dot"); 1865//} 1866 1867auto * t_logits = res -> get_logits (); 1868auto * t_embd = cparams .embeddings ?res -> get_embd () :nullptr ; 1869auto * t_h_nextn = cparams .embeddings_nextn ?res -> get_h_nextn () :nullptr ; 1870 1871if (t_embd && res -> get_embd_pooled ()) { 1872t_embd = res -> get_embd_pooled (); 1873 } 1874 1875// extract logits 1876if (logits .data && t_logits && n_outputs > 0 && needs_raw_logits (ubatch ,sampling .samplers )) { 1877ggml_backend_t backend_res = ggml_backend_sched_get_tensor_backend (sched .get (),t_logits ); 1878GGML_ASSERT (backend_res != nullptr ); 1879GGML_ASSERT (logits .data != nullptr ); 1880 1881float * logits_out = logits .data + n_outputs_prev * n_vocab ; 1882 1883if (n_outputs ) { 1884GGML_ASSERT (n_outputs_prev + n_outputs <=n_outputs_all ); 1885GGML_ASSERT ((n_outputs_prev + n_outputs )* n_vocab <= (int64_t )logits .size ); 1886ggml_backend_tensor_get_async (backend_res ,t_logits ,logits_out ,0 ,n_outputs * n_vocab * sizeof (float )); 1887 } 1888 } 1889 1890// extract embeddings 1891if (embd .data && t_embd && n_outputs > 0 ) { 1892ggml_backend_t backend_embd = ggml_backend_sched_get_tensor_backend (sched .get (),t_embd ); 1893GGML_ASSERT (backend_embd != nullptr ); 1894 1895switch (cparams .pooling_type ) { 1896case LLAMA_POOLING_TYPE_NONE : 1897 { 1898// extract token embeddings 1899GGML_ASSERT (embd .data != nullptr ); 1900const uint32_t n_embd_out = hparams .n_embd_out (); 1901float * embd_out = embd .data + n_outputs_prev * n_embd_out ; 1902 1903if (n_outputs ) { 1904GGML_ASSERT (n_outputs_prev + n_outputs <=n_outputs_all ); 1905GGML_ASSERT ((n_outputs_prev + n_outputs )* n_embd_out <= (int64_t )embd .size ); 1906ggml_backend_tensor_get_async (backend_embd ,t_embd ,embd_out ,0 ,n_outputs * n_embd_out * sizeof (float )); 1907 } 1908 }break ; 1909case LLAMA_POOLING_TYPE_MEAN : 1910case LLAMA_POOLING_TYPE_CLS : 1911case LLAMA_POOLING_TYPE_LAST : 1912 { 1913// extract sequence embeddings (cleared before processing each batch) 1914auto & embd_seq_out = embd_seq ; 1915 1916// use n_embd_out (not n_embd_inp) - the pooled embedding has the model's 1917// output dimension, which differs from input dimension for deepstack models (e.g. qwen3vl) 1918const uint32_t n_embd_out = hparams .n_embd_out (); 1919 1920for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 1921const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 1922const int32_t seq_idx = ubatch .seq_idx [seq_id ]; 1923 1924embd_seq_out [seq_id ].resize (n_embd_out ); 1925ggml_backend_tensor_get_async (backend_embd ,t_embd ,embd_seq_out [seq_id ].data (), (n_embd_out * seq_idx )* sizeof (float ),n_embd_out * sizeof (float )); 1926 } 1927 }break ; 1928case LLAMA_POOLING_TYPE_RANK : 1929 { 1930// extract the rerank score - n_cls_out floats per sequence 1931auto & embd_seq_out = embd_seq ; 1932 1933const uint32_t n_cls_out = hparams .n_cls_out ; 1934 1935for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 1936const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 1937const int32_t seq_idx = ubatch .seq_idx [seq_id ]; 1938 1939embd_seq_out [seq_id ].resize (n_cls_out ); 1940ggml_backend_tensor_get_async (backend_embd ,t_embd ,embd_seq_out [seq_id ].data (), (n_cls_out * seq_idx )* sizeof (float ),n_cls_out * sizeof (float )); 1941 } 1942 }break ; 1943case LLAMA_POOLING_TYPE_UNSPECIFIED : 1944 { 1945GGML_ABORT ("unknown pooling type" ); 1946 } 1947 } 1948 } 1949 1950extract_layer_inputs (res ,n_tokens_prev ,ubatch .n_tokens ); 1951 1952// extract nextn embeddings before 1953// only meaningful in LLAMA_POOLING_TYPE_NONE (per-token); other pooling modes are ignored. 1954 { 1955const bool masked = cparams .embeddings_nextn_masked ; 1956const int64_t n_rows = masked ?n_outputs : (int64_t )ubatch .n_tokens ; 1957const int64_t offset = masked ?n_outputs_prev :n_tokens_prev ; 1958 1959if (embd_nextn .data && t_h_nextn && n_rows > 0 && cparams .pooling_type == LLAMA_POOLING_TYPE_NONE ) { 1960ggml_backend_t backend_h = ggml_backend_sched_get_tensor_backend (sched .get (),t_h_nextn ); 1961GGML_ASSERT (backend_h != nullptr ); 1962 1963const uint32_t n_embd = hparams .n_embd_out (); 1964float * embd_nextn_out = embd_nextn .data + offset * n_embd ; 1965 1966GGML_ASSERT ((offset + n_rows )* n_embd <= (int64_t )embd_nextn .size ); 1967ggml_backend_tensor_get_async (backend_h ,t_h_nextn ,embd_nextn_out ,0 ,n_rows * n_embd * sizeof (float )); 1968 } 1969 } 1970 1971if (has_samplers ) { 1972const auto stride = n_vocab ; 1973 1974// async copy the sampling data from the backend to the host 1975copy_tensor_async_rows (res -> t_sampled ,sampling .sampled ,1 ,n_outputs_prev ,sched .get ()); 1976copy_tensor_async_rows (res -> t_sampled_logits ,sampling .logits ,stride ,n_outputs_prev ,sched .get (),& sampling .logits_count ); 1977copy_tensor_async_rows (res -> t_sampled_probs ,sampling .probs ,stride ,n_outputs_prev ,sched .get (),& sampling .probs_count ); 1978copy_tensor_async_rows (res -> t_candidates ,sampling .candidates ,stride ,n_outputs_prev ,sched .get (),& sampling .candidates_count ); 1979 } 1980 1981n_outputs_prev += n_outputs ; 1982n_tokens_prev += ubatch .n_tokens ; 1983 }while (mctx -> next ()); 1984 1985// set to total number of outputs in the batch, for use in llama_get_logits_ith 1986n_outputs = n_outputs_all ; 1987 1988// set output mappings 1989if (n_outputs > 0 ) { 1990bool sorted_output = true; 1991 1992auto & out_ids = balloc -> get_out_ids (); 1993 1994GGML_ASSERT (out_ids .size ()== (size_t )n_outputs ); 1995 1996for (int64_t i = 0 ;i < n_outputs ;++ i ) { 1997int64_t out_id = out_ids [i ]; 1998output_ids [out_id ]= i ; 1999if (out_id != i ) { 2000sorted_output = false; 2001 } 2002 } 2003 2004// make the outputs have the same order they had in the user-provided batch 2005// note: this is mostly relevant for recurrent models atm 2006if (!sorted_output && n_outputs > 1 ) { 2007GGML_ASSERT ((size_t )n_outputs == out_ids .size ()); 2008 2009// TODO: is there something more efficient which also minimizes swaps? 2010// selection sort, to minimize swaps (from https://en.wikipedia.org/wiki/Selection_sort) 2011for (uint32_t i = 0 ;i < n_outputs - 1 ;++ i ) { 2012uint32_t j_min = i ; 2013for (uint32_t j = i + 1 ;j < n_outputs ;++ j ) { 2014if (out_ids [j ]< out_ids [j_min ]) { 2015j_min = j ; 2016 } 2017 } 2018if (j_min == i ) { 2019continue ; 2020 } 2021 std::swap (out_ids [i ],out_ids [j_min ]); 2022 2023// remember the swaps and apply them lazily upon logits/embeddings access 2024output_swaps .push_back ({i ,j_min }); 2025 } 2026 2027 std::fill (output_ids .begin (),output_ids .end (),-1 ); 2028 2029for (uint32_t i = 0 ;i < n_outputs ;++ i ) { 2030output_ids [out_ids [i ]]= i ; 2031 } 2032 } 2033 } 2034 2035// wait for the computation to finish (automatically done when obtaining the model output) 2036//synchronize(); 2037 2038return 0 ; 2039} 2040 2041// 2042// output 2043// 2044 2045uint32_t llama_context::output_reserve (int32_t n_outputs ) { 2046const auto & hparams = model .hparams ; 2047const auto & vocab = model .vocab ; 2048 2049const int64_t n_outputs_max = std::max < int64_t > (n_outputs ,n_seq_max ()); 2050 2051const auto n_batch = cparams .n_batch ; 2052const auto n_vocab = vocab .n_tokens (); 2053const auto n_embd = hparams .n_embd ; 2054const auto n_embd_out = hparams .n_embd_out (); 2055 2056bool has_logits = true; 2057bool has_embd = cparams .embeddings ; 2058bool has_embd_nextn = cparams .embeddings_nextn ; 2059 2060// TODO: hacky enc-dec support 2061if (model .arch == LLM_ARCH_T5 || model .arch == LLM_ARCH_ALICEAI_T5_MOE ) { 2062has_logits = true; 2063has_embd = true; 2064 } 2065 2066size_t backend_float_count = 0 ; 2067size_t backend_token_count = 0 ; 2068size_t embd_layer_inp_float_count = 0 ; 2069 2070logits .size = has_logits ?n_vocab * n_outputs_max :0 ; 2071embd .size = has_embd ?n_embd_out * n_outputs_max :0 ; 2072embd_nextn .size = has_embd_nextn ?n_embd_out * n_outputs_max :0 ; 2073 2074if (has_embd_nextn && !cparams .embeddings_nextn_masked ) { 2075// unmasked: nextn row exists for every token in the batch, not just 2076// those flagged via batch.logits[i] -> size by token count instead. 2077embd_nextn .size = (size_t )n_embd_out * n_batch ; 2078 } 2079 2080for (bool enabled :cparams .embeddings_layer_inp ) { 2081if (enabled ) { 2082embd_layer_inp_float_count += (size_t )n_embd * n_batch ; 2083 } 2084 } 2085 2086// Allocate backend sampling output buffers if there are backend samplers configured. 2087const bool has_sampling = !sampling .samplers .empty (); 2088if (has_sampling ) { 2089backend_float_count = 2 * n_vocab * n_outputs_max ;// logits + probs 2090backend_token_count = (1 + n_vocab )* n_outputs_max ;// sampled + candidates 2091 } 2092 2093if (output_ids .empty ()) { 2094// init, never resized afterwards 2095output_ids .resize (n_batch ); 2096 } 2097 2098const size_t prev_size = buf_output ?ggml_backend_buffer_get_size (buf_output .get ()) :0 ; 2099const size_t new_size = 2100 (logits .size + embd .size + embd_nextn .size + embd_layer_inp_float_count + backend_float_count )* sizeof (float )+ 2101 (backend_token_count )* sizeof (llama_token ); 2102 2103// alloc only when more than the current capacity is required 2104// TODO: also consider shrinking the buffer 2105if (!buf_output || prev_size < new_size ) { 2106if (buf_output ) { 2107#ifndef NDEBUG 2108// This doesn't happen often, but may be annoying in some cases (like the HellaSwag benchmark) 2109LLAMA_LOG_DEBUG ("%s: reallocating output buffer from size %.02f MiB to %.02f MiB\n" ,__func__ ,prev_size /1024.0 /1024.0 ,new_size /1024.0 /1024.0 ); 2110#endif 2111synchronize (); 2112 2113// TODO: not needed? 2114buf_output = nullptr ; 2115logits .data = nullptr ; 2116embd .data = nullptr ; 2117embd_nextn .data = nullptr ; 2118for (auto & layer_inp :embd_layer_inp ) { 2119layer_inp = {nullptr ,0 }; 2120 } 2121 } 2122 2123auto * buft = ggml_backend_cpu_buffer_type (); 2124// try to use the host buffer of the device where the output tensor is allocated for faster transfer to system memory 2125auto * output_dev = model .dev_output (); 2126auto * output_dev_host_buft = output_dev ?ggml_backend_dev_host_buffer_type (output_dev ) :nullptr ; 2127if (output_dev_host_buft ) { 2128buft = output_dev_host_buft ; 2129 } 2130buf_output .reset (ggml_backend_buft_alloc_buffer (buft ,new_size )); 2131if (buf_output == nullptr ) { 2132LLAMA_LOG_ERROR ("%s: failed to allocate output buffer of size %.2f MiB\n" ,__func__ ,new_size / (1024.0 * 1024.0 )); 2133return 0 ; 2134 } 2135ggml_backend_buffer_clear (buf_output .get (),0 ); 2136 } 2137 2138float * output_base = (float * )ggml_backend_buffer_get_base (buf_output .get ()); 2139 2140size_t offset = 0 ; 2141uint8_t * base = (uint8_t * )output_base ; 2142 2143logits = has_logits ?buffer_view < float > {output_base ,logits .size } :buffer_view < float > {nullptr ,0 }; 2144offset += logits .size * sizeof (float ); 2145 2146embd = has_embd ?buffer_view < float > {(float * ) (base + offset ),embd .size } :buffer_view < float > {nullptr ,0 }; 2147offset += embd .size * sizeof (float ); 2148 2149embd_nextn = has_embd_nextn ?buffer_view < float > {(float * ) (base + offset ),embd_nextn .size } :buffer_view < float > {nullptr ,0 }; 2150offset += embd_nextn .size * sizeof (float ); 2151 2152for (uint32_t il = 0 ;il < embd_layer_inp .size ();++ il ) { 2153if (cparams .embeddings_layer_inp [il ]) { 2154embd_layer_inp [il ]= buffer_view < float > {(float * ) (base + offset ), (size_t )n_embd * n_batch }; 2155offset += embd_layer_inp [il ].size * sizeof (float ); 2156 }else { 2157embd_layer_inp [il ]= buffer_view < float > {nullptr ,0 }; 2158 } 2159 } 2160 2161if (has_sampling ) { 2162sampling .logits = {(float * ) (base + offset ), (size_t )(n_vocab * n_outputs_max )}; 2163offset += sampling .logits .size * sizeof (float ); 2164 2165sampling .probs = {(float * ) (base + offset ), (size_t )(n_vocab * n_outputs_max )}; 2166offset += sampling .probs .size * sizeof (float ); 2167 2168sampling .sampled = {(llama_token * ) (base + offset ), (size_t )n_outputs_max }; 2169offset += sampling .sampled .size * sizeof (llama_token ); 2170 2171sampling .candidates = {(llama_token * ) (base + offset ), (size_t )(n_vocab * n_outputs_max )}; 2172offset += sampling .candidates .size * sizeof (llama_token ); 2173 2174// The count vectors keep track of the actual number of logits/probs/candidates 2175// copied from the backend for each output row. 2176 2177sampling .logits_count .resize (n_outputs_max ); 2178sampling .probs_count .resize (n_outputs_max ); 2179sampling .candidates_count .resize (n_outputs_max ); 2180 2181 std::fill (sampling .logits_count .begin (),sampling .logits_count .end (),0 ); 2182 std::fill (sampling .probs_count .begin (),sampling .probs_count .end (),0 ); 2183 std::fill (sampling .candidates_count .begin (),sampling .candidates_count .end (),0 ); 2184 2185 std::fill_n (sampling .sampled .data ,sampling .sampled .size ,LLAMA_TOKEN_NULL ); 2186 }else { 2187sampling .logits = {nullptr ,0 }; 2188sampling .probs = {nullptr ,0 }; 2189sampling .sampled = {nullptr ,0 }; 2190sampling .candidates = {nullptr ,0 }; 2191 2192sampling .logits_count .clear (); 2193sampling .probs_count .clear (); 2194sampling .candidates_count .clear (); 2195 } 2196 2197// set all ids as invalid (negative) 2198 std::fill (output_ids .begin (),output_ids .end (),-1 ); 2199 2200this -> n_outputs = 0 ; 2201 2202GGML_ASSERT (n_outputs_max <=cparams .n_outputs_max ); 2203 2204return n_outputs_max ; 2205} 2206 2207void llama_context::extract_layer_inputs (const llm_graph_result * res ,size_t token_offset ,size_t n_tokens ) { 2208for (uint32_t il = 0 ;il < cparams .embeddings_layer_inp .size ();++ il ) { 2209if (!cparams .embeddings_layer_inp [il ]) { 2210continue ; 2211 } 2212if (!embd_layer_inp [il ].has_data ()) { 2213GGML_ABORT ("output layer input buffer not allocated" ); 2214 } 2215ggml_tensor * t = res -> get_layer_inp ((int )il ); 2216if (!t ) { 2217GGML_ABORT ("layer input tensor not found" ); 2218 } 2219 2220const size_t nbytes = ggml_nbytes (t ); 2221const size_t nfloats = nbytes /sizeof (float ); 2222GGML_ASSERT (n_tokens > 0 ); 2223GGML_ASSERT (nfloats %n_tokens == 0 ); 2224 2225const size_t row_floats = nfloats /n_tokens ; 2226const size_t dst_offset = token_offset * row_floats ; 2227GGML_ASSERT (dst_offset + nfloats <=embd_layer_inp [il ].size ); 2228 2229ggml_backend_t backend = ggml_backend_sched_get_tensor_backend (sched .get (),t ); 2230GGML_ASSERT (backend != nullptr ); 2231ggml_backend_tensor_get_async (backend ,t ,embd_layer_inp [il ].data + dst_offset ,0 ,nbytes ); 2232 } 2233} 2234 2235void llama_context::output_reorder () { 2236const uint64_t n_vocab = model .vocab .n_tokens (); 2237const uint64_t n_embd = model .hparams .n_embd ; 2238const uint64_t n_embd_out = model .hparams .n_embd_out (); 2239 2240for (size_t s = 0 ;s < output_swaps .size ();++ s ) { 2241const uint64_t i0 = output_swaps [s ].i0 ; 2242const uint64_t i1 = output_swaps [s ].i1 ; 2243 2244if (logits .size > 0 ) { 2245for (uint64_t k = 0 ;k < n_vocab ;k ++ ) { 2246 std::swap (logits .data [i0 * n_vocab + k ],logits .data [i1 * n_vocab + k ]); 2247 } 2248 } 2249 2250if (embd .size > 0 ) { 2251for (uint64_t k = 0 ;k < n_embd_out ;k ++ ) { 2252 std::swap (embd .data [i0 * n_embd_out + k ],embd .data [i1 * n_embd_out + k ]); 2253 } 2254 } 2255 2256if (embd_nextn .size > 0 ) { 2257for (uint64_t k = 0 ;k < n_embd_out ;k ++ ) { 2258 std::swap (embd_nextn .data [i0 * n_embd_out + k ],embd_nextn .data [i1 * n_embd_out + k ]); 2259 } 2260 } 2261 2262if (embd_layer_inp .size ()> 0 ) { 2263for (int lid = 0 ;lid < (int )embd_layer_inp .size ();++ lid ) { 2264if (embd_layer_inp [lid ].size > 0 ) { 2265for (uint64_t k = 0 ;k < n_embd ;++ k ) { 2266 std::swap (embd_layer_inp [lid ].data [i0 * n_embd + k ],embd_layer_inp [lid ].data [i1 * n_embd + k ]); 2267 } 2268 } 2269 } 2270 } 2271 2272if (!sampling .samplers .empty ()) { 2273assert (sampling .logits .size > 0 ); 2274assert (sampling .probs .size > 0 ); 2275assert (sampling .candidates .size > 0 ); 2276assert (sampling .sampled .size > 0 ); 2277assert (sampling .logits_count .size ()> 0 ); 2278assert (sampling .probs_count .size ()> 0 ); 2279assert (sampling .candidates_count .size ()> 0 ); 2280 2281for (uint64_t k = 0 ;k < n_vocab ;++ k ) { 2282 std::swap (sampling .logits .data [i0 * n_vocab + k ],sampling .logits .data [i1 * n_vocab + k ]); 2283 } 2284 2285for (uint64_t k = 0 ;k < n_vocab ;++ k ) { 2286 std::swap (sampling .probs .data [i0 * n_vocab + k ],sampling .probs .data [i1 * n_vocab + k ]); 2287 } 2288 2289for (uint64_t k = 0 ;k < n_vocab ;++ k ) { 2290 std::swap (sampling .candidates .data [i0 * n_vocab + k ],sampling .candidates .data [i1 * n_vocab + k ]); 2291 } 2292 2293 std::swap (sampling .sampled .data [i0 ],sampling .sampled .data [i1 ]); 2294 std::swap (sampling .logits_count [i0 ],sampling .logits_count [i1 ]); 2295 std::swap (sampling .probs_count [i0 ],sampling .probs_count [i1 ]); 2296 std::swap (sampling .candidates_count [i0 ],sampling .candidates_count [i1 ]); 2297 } 2298 } 2299 2300output_swaps .clear (); 2301} 2302 2303// 2304// graph 2305// 2306 2307uint32_t llama_context::graph_max_nodes (uint32_t n_tokens )const { 2308uint32_t res ; 2309if (model .arch == LLM_ARCH_KIMI_K3 ) { 2310// the n_tokens*40 budget below is exhausted at ubatch 3840 2311res = std::max < uint32_t > (n_tokens * 160 ,64u * model .n_tensors ()); 2312 }else if (model .arch == LLM_ARCH_QWEN3NEXT || 2313model .arch == LLM_ARCH_KIMI_LINEAR || 2314model .arch == LLM_ARCH_BAILINGMOE3 || 2315model .arch == LLM_ARCH_QWEN35 || 2316model .arch == LLM_ARCH_QWEN35MOE || 2317model .arch == LLM_ARCH_QWEN4EXP || 2318model .arch == LLM_ARCH_DEEPSEEK4 || 2319 (model .arch == LLM_ARCH_DFLASH && model .hparams .dsv4_hc_mult > 0 )|| 2320model .arch == LLM_ARCH_NANBEIGE || 2321model .arch == LLM_ARCH_MINIMAX_01 || 2322model .arch == LLM_ARCH_MINIMAX_M3 || 2323model .arch == LLM_ARCH_HY_V4 ) { 2324res = std::max < uint32_t > (n_tokens * 40 ,32u * model .n_tensors ()); 2325 }else if (model .arch == LLM_ARCH_DFLASH && model .hparams .dflash_selector_rank > 0 ) { 2326// DFlash2's convolutions and selector are shape work rather than matmuls, 2327// so they cost ~8.6 nodes per tensor against ~5.9 for a plain DFlash draft 2328res = std::max < uint32_t > (1024u ,12u * model .n_tensors ()); 2329 }else { 2330res = std::max < uint32_t > (1024u ,8u * model .n_tensors ()); 2331for (const auto & lora :model .loras ) { 2332res += lora -> get_n_nodes (); 2333 } 2334 } 2335 2336uint32_t n_sampling_nodes = 0 ; 2337uint32_t n_sampling_nodes_max = 0 ; 2338for (const auto & [seq_id ,sampler ] :sampling .samplers ) { 2339const uint32_t n_nodes = llama_sampler_backend_n_nodes (sampler ); 2340n_sampling_nodes += n_nodes ; 2341if (cparams .n_outputs_max_per_seq > 1 ) { 2342n_sampling_nodes_max = std::max (n_sampling_nodes_max ,n_nodes ); 2343 } 2344 } 2345 2346const uint32_t n_sampling_outputs_max = std::min < uint64_t > ( 2347 std::min (n_tokens ,cparams .n_outputs_max ), 2348 (uint64_t )cparams .n_seq_max * cparams .n_outputs_max_per_seq ); 2349 2350res += n_sampling_nodes ; 2351if (n_sampling_outputs_max > 1 ) { 2352res += (n_sampling_outputs_max - 1 )* n_sampling_nodes_max ; 2353 } 2354return res ; 2355} 2356 2357llm_graph_result * llama_context::get_gf_res_reserve ()const { 2358return static_cast < llm_graph_result *> (gf_res_reserve .get ()); 2359} 2360 2361// pack sampler outputs into as few sequences as possible before using sequences without samplers 2362static void ubatch_prepare_reserve ( 2363llama_ubatch & ubatch , 2364uint32_t n_outputs , 2365const std::map < llama_seq_id ,llama_sampler *> & samplers , 2366uint32_t n_outputs_max_per_seq ) { 2367const uint32_t n_seqs = ubatch .n_seqs ; 2368const uint32_t n_seq_tokens = ubatch .n_seq_tokens ; 2369 2370for (uint32_t s = 0 ;s < n_seqs ;++ s ) { 2371for (uint32_t t = 0 ;t < n_seq_tokens ;++ t ) { 2372const uint32_t i = s * n_seq_tokens + t ; 2373ubatch .n_seq_id [i ]= 1 ; 2374ubatch .seq_id [i ]= & ubatch .seq_id_unq [s ]; 2375 } 2376 } 2377 2378// sequences with a sampler that fit in this ubatch 2379 std::vector < uint32_t > sampler_seqs ; 2380 std::vector < bool > has_sampler (n_seqs ,false ); 2381for (const auto & entry :samplers ) { 2382const llama_seq_id seq_id = entry .first ; 2383if (seq_id < 0 || (uint32_t )seq_id >=n_seqs ) { 2384continue ; 2385 } 2386 2387sampler_seqs .push_back (seq_id ); 2388has_sampler [seq_id ]= true; 2389 } 2390 2391uint32_t n_outputs_set = 0 ; 2392 2393const uint32_t n_outputs_per_seq = std::min (n_seq_tokens ,n_outputs_max_per_seq ); 2394for (uint32_t s :sampler_seqs ) { 2395if (n_outputs_set >=n_outputs ) { 2396break ; 2397 } 2398 2399for (uint32_t t = 0 ;t < n_outputs_per_seq && n_outputs_set < n_outputs ;++ t ) { 2400ubatch .output [s * n_seq_tokens + t ]= true; 2401++ n_outputs_set ; 2402 } 2403 } 2404 2405// use sequences without samplers for any remaining outputs 2406for (uint32_t t = 0 ;t < n_seq_tokens && n_outputs_set < n_outputs ;++ t ) { 2407for (uint32_t s = 0 ;s < n_seqs && n_outputs_set < n_outputs ;++ s ) { 2408if (has_sampler [s ]) { 2409continue ; 2410 } 2411 2412ubatch .output [s * n_seq_tokens + t ]= true; 2413++ n_outputs_set ; 2414 } 2415 } 2416} 2417 2418ggml_cgraph * llama_context::graph_reserve ( 2419uint32_t n_tokens ,uint32_t n_seqs ,uint32_t n_outputs ,const llama_memory_context_i * mctx ,bool split_only ,size_t * sizes ) { 2420LLAMA_LOG_DEBUG ("%s: reserving a graph for ubatch with n_tokens = %4u, n_seqs = %2u, n_outputs = %4u\n" ,__func__ ,n_tokens ,n_seqs ,n_outputs ); 2421GGML_ASSERT (n_outputs >=1 ); 2422 2423if (n_tokens %n_seqs != 0 ) { 2424n_tokens = ((n_tokens + (n_seqs - 1 )) /n_seqs )* n_seqs ;// round to next multiple of n_seqs 2425LLAMA_LOG_DEBUG ("%s: making n_tokens a multiple of n_seqs - n_tokens = %u, n_seqs = %u, n_outputs = %u\n" ,__func__ ,n_tokens ,n_seqs ,n_outputs ); 2426 } 2427 2428ggml_backend_sched_reset (sched .get ()); 2429 2430// when the scheduler is reset, we cannot reuse the old graph, so we reset the previous graph result to prevent that 2431gf_res_prev -> reset (); 2432 2433// store the n_outputs as it is, and restore it afterwards 2434// TODO: not sure if needed, might simplify in the future by removing this 2435const auto save_n_outputs = this -> n_outputs ; 2436 2437this -> n_outputs = n_outputs ; 2438 2439llama_batch_allocr balloc (model .hparams .n_pos_per_embd ()); 2440llama_ubatch ubatch = balloc .ubatch_reserve (n_tokens /n_seqs ,n_seqs ); 2441 2442ubatch_prepare_reserve (ubatch ,n_outputs ,sampling .samplers ,cparams .n_outputs_max_per_seq ); 2443 2444auto * res = gf_res_reserve .get (); 2445 2446const auto gparams = graph_params (res ,ubatch ,mctx ,ctx_type_to_graph_type (cparams .ctx_type )); 2447 2448res -> reset (); 2449 2450auto * gf = model .build_graph (gparams ); 2451 2452this -> n_outputs = save_n_outputs ; 2453 2454// initialize scheduler with the specified graph 2455if (split_only ) { 2456if (sizes ) { 2457ggml_backend_sched_reserve_size (sched .get (),gf ,sizes ); 2458 }else { 2459ggml_backend_sched_split_graph (sched .get (),gf ); 2460 } 2461 }else if (!ggml_backend_sched_reserve (sched .get (),gf )) { 2462GGML_ASSERT (!sizes ); 2463LLAMA_LOG_ERROR ("%s: failed to allocate compute buffers\n" ,__func__ ); 2464return nullptr ; 2465 } 2466 2467return gf ; 2468} 2469 2470llm_graph_params llama_context::graph_params ( 2471llm_graph_result * res , 2472const llama_ubatch & ubatch , 2473const llama_memory_context_i * mctx , 2474llm_graph_type gtype )const { 2475return { 2476/*.arch =*/ model .arch , 2477/*.hparams =*/ model .hparams , 2478/*.cparams =*/ cparams , 2479/*.ubatch =*/ ubatch , 2480/*.gtype =*/ gtype , 2481/*.sched =*/ sched .get (), 2482/*.backend_cpu =*/ backend_cpu , 2483/*.cvec =*/ cvec .get (), 2484/*.loras =*/ loras .get (), 2485/*.mctx =*/ mctx , 2486/*.cross =*/ & cross , 2487/*.samplers =*/ sampling .samplers , 2488/*.n_outputs =*/ n_outputs , 2489/*.cb =*/ graph_get_cb (), 2490/*.res =*/ res , 2491 }; 2492} 2493 2494ggml_status llama_context::graph_compute ( 2495ggml_cgraph * gf , 2496bool batched ) { 2497int n_threads = batched ?cparams .n_threads_batch :cparams .n_threads ; 2498ggml_threadpool_t tp = batched ?threadpool_batch :threadpool ; 2499 2500if (backend_cpu != nullptr ) { 2501auto * reg = ggml_backend_dev_backend_reg (ggml_backend_get_device (backend_cpu )); 2502auto * set_threadpool_fn = (decltype(ggml_backend_cpu_set_threadpool )* )ggml_backend_reg_get_proc_address (reg ,"ggml_backend_cpu_set_threadpool" ); 2503if (set_threadpool_fn ) { 2504set_threadpool_fn (backend_cpu ,tp ); 2505 } 2506 } 2507 2508// set the number of threads for all the backends 2509for (const auto & set_n_threads_fn :set_n_threads_fns ) { 2510set_n_threads_fn .second (set_n_threads_fn .first ,n_threads ); 2511 } 2512 2513auto status = ggml_backend_sched_graph_compute_async (sched .get (),gf ); 2514if (status != GGML_STATUS_SUCCESS ) { 2515LLAMA_LOG_ERROR ("%s: ggml_backend_sched_graph_compute_async failed with error %d\n" ,__func__ ,status ); 2516 } 2517 2518// fprintf(stderr, "splits: %d\n", ggml_backend_sched_get_n_splits(sched)); 2519 2520return status ; 2521} 2522 2523llm_graph_cb llama_context::graph_get_cb ()const { 2524return [& ](const llama_ubatch & ubatch ,ggml_tensor * cur ,const char * name ,int il ) { 2525if (il >=0 ) { 2526ggml_format_name (cur ,"%s-%d" ,name ,il ); 2527 }else { 2528ggml_set_name (cur ,name ); 2529 } 2530 2531// - norm may be automatically assigned to the backend of the previous layer, increasing data transfer between backends 2532// - force the last op of the layer on the specified backend to avoid running it on the backend of the next layer due to scheduling 2533// FIXME: fix in ggml_backend_sched 2534const bool full_offload = model .n_gpu_layers ()> model .hparams .n_layer_all ; 2535if (ubatch .n_tokens < 32 || full_offload ) { 2536if (il != -1 && (strcmp (name ,"norm" )== 0 || strcmp (name ,"l_last" )== 0 )) { 2537const auto & dev_layer = model .dev_layer (il ); 2538for (const auto & backend :backends ) { 2539if (ggml_backend_get_device (backend .get ())== dev_layer ) { 2540if (ggml_backend_supports_op (backend .get (),cur )) { 2541ggml_backend_sched_set_tensor_backend (sched .get (),cur ,backend .get ()); 2542 } 2543 } 2544 } 2545 } 2546 } 2547 }; 2548} 2549 2550// 2551// state save/load 2552// 2553 2554class llama_io_write_dummy :public llama_io_write_i { 2555public : 2556llama_io_write_dummy (bool skip_tensors ) :skip_tensors (skip_tensors ) {} 2557 2558void write (const void * /* src */ ,size_t size )override { 2559size_written += size ; 2560 } 2561 2562void write_tensor (ggml_tensor * /* tensor */ ,size_t /* offset */ ,size_t size )override { 2563if (skip_tensors ) { 2564return ; 2565 } 2566 2567size_written += size ; 2568 } 2569 2570size_t n_bytes ()override { 2571return size_written ; 2572 } 2573 2574private : 2575const bool skip_tensors ; 2576 2577size_t size_written = 0 ; 2578}; 2579 2580class llama_io_write_host :public llama_io_write_i { 2581public : 2582llama_io_write_host ( 2583uint8_t * p ,size_t len ) :ptr (p ),buf_size (len ) {} 2584 2585 ~llama_io_write_host () { 2586// TODO: add backend support to batch tensor_get? or some other way to speed this up 2587for (const auto & winfo :winfos ) { 2588ggml_backend_tensor_get (winfo .tensor ,winfo .ptr ,winfo .offset ,winfo .size ); 2589 } 2590 } 2591 2592void write (const void * src ,size_t size )override { 2593if (size > buf_size ) { 2594throw std::runtime_error ("unexpectedly reached end of buffer" ); 2595 } 2596memcpy (ptr ,src ,size ); 2597ptr += size ; 2598size_written += size ; 2599buf_size -= size ; 2600 } 2601 2602void write_tensor (ggml_tensor * tensor ,size_t offset ,size_t size )override { 2603if (size > buf_size ) { 2604throw std::runtime_error ("unexpectedly reached end of buffer" ); 2605 } 2606 2607// save the write for later during destruction 2608winfos .push_back ({tensor ,ptr ,size ,offset }); 2609 2610ptr += size ; 2611size_written += size ; 2612buf_size -= size ; 2613 } 2614 2615size_t n_bytes ()override { 2616return size_written ; 2617 } 2618 2619private : 2620uint8_t * ptr ; 2621size_t buf_size = 0 ; 2622size_t size_written = 0 ; 2623 2624struct write_info { 2625ggml_tensor * tensor ; 2626uint8_t * ptr ; 2627size_t size ; 2628size_t offset ; 2629 }; 2630 std::vector < write_info > winfos ; 2631}; 2632 2633class llama_io_read_host :public llama_io_read_i { 2634public : 2635llama_io_read_host (const uint8_t * p ,size_t len ) :ptr (p ),buf_size (len ) {} 2636 2637 ~llama_io_read_host () { 2638// flush the reads 2639for (const auto & rinfo :rinfos ) { 2640ggml_backend_tensor_set (rinfo .tensor ,rinfo .ptr ,rinfo .offset ,rinfo .size ); 2641 } 2642 } 2643 2644void read (void * dst ,size_t size )override { 2645if (size > buf_size ) { 2646throw std::runtime_error ("unexpectedly reached end of buffer" ); 2647 } 2648memcpy (dst ,ptr ,size ); 2649ptr += size ; 2650size_read += size ; 2651buf_size -= size ; 2652 } 2653 2654void read_tensor (ggml_tensor * tensor ,size_t offset ,size_t size )override { 2655if (size > buf_size ) { 2656throw std::runtime_error ("unexpectedly reached end of buffer" ); 2657 } 2658 2659// save for later during destruction 2660rinfos .push_back ({tensor ,ptr ,size ,offset }); 2661 2662ptr += size ; 2663size_read += size ; 2664buf_size -= size ; 2665 } 2666 2667size_t n_bytes ()override { 2668return size_read ; 2669 } 2670 2671private : 2672const uint8_t * ptr ; 2673size_t buf_size = 0 ; 2674size_t size_read = 0 ; 2675 2676struct read_info { 2677ggml_tensor * tensor ; 2678const uint8_t * ptr ; 2679size_t size ; 2680size_t offset ; 2681 }; 2682 std::vector < read_info > rinfos ; 2683}; 2684 2685class llama_io_write_file :public llama_io_write_i { 2686public : 2687llama_io_write_file (llama_file * f ) :file (f ) {} 2688 2689void write (const void * src ,size_t size )override { 2690file -> write_raw (src ,size ); 2691size_written += size ; 2692 } 2693 2694void write_tensor (ggml_tensor * tensor ,size_t offset ,size_t size )override { 2695temp_buffer .resize (size ); 2696ggml_backend_tensor_get (tensor ,temp_buffer .data (),offset ,size ); 2697write (temp_buffer .data (),temp_buffer .size ()); 2698 } 2699 2700size_t n_bytes ()override { 2701return size_written ; 2702 } 2703 2704private : 2705llama_file * file ; 2706size_t size_written = 0 ; 2707 std::vector < uint8_t > temp_buffer ; 2708}; 2709 2710class llama_io_read_file :public llama_io_read_i { 2711public : 2712llama_io_read_file (llama_file * f ) :file (f ) {} 2713 2714void read (void * dst ,size_t size )override { 2715file -> read_raw (dst ,size ); 2716size_read += size ; 2717 } 2718 2719void read_tensor (ggml_tensor * tensor ,size_t offset ,size_t size )override { 2720temp_buffer .resize (size ); 2721read (temp_buffer .data (),size ); 2722ggml_backend_tensor_set (tensor ,temp_buffer .data (),offset ,size ); 2723 } 2724 2725size_t n_bytes ()override { 2726return size_read ; 2727 } 2728 2729private : 2730llama_file * file ; 2731size_t size_read = 0 ; 2732 std::vector < uint8_t > temp_buffer ; 2733}; 2734 2735class llama_io_write_device :public llama_io_write_i { 2736public : 2737llama_io_write_device (uint8_t * p ,size_t len ,llama_memory_buffers & mbufs ) :ptr (p ),buf_size (len ),mbufs (mbufs ) { 2738 } 2739 2740 ~llama_io_write_device () { 2741llama_memory_buffers mbufs_new ; 2742 2743for (const auto & winfo :winfos ) { 2744auto * buft = ggml_backend_buffer_get_type (winfo .tensor -> buffer ); 2745 2746mbufs_new [buft ].n_tensors ++ ; 2747mbufs_new [buft ].total_size += winfo .size ; 2748 } 2749 2750for (auto & [buft ,mbuf ] :mbufs_new ) { 2751ggml_init_params params = { 2752/*.mem_size =*/ 2 * mbuf .n_tensors * ggml_tensor_overhead (), 2753/*.mem_buffer =*/ NULL , 2754/*.no_alloc =*/ true, 2755 }; 2756 2757mbuf .ctx .reset (ggml_init (params )); 2758 2759mbuf .org .reserve (mbuf .n_tensors ); 2760mbuf .cpy .reserve (mbuf .n_tensors ); 2761 } 2762 2763for (const auto & winfo :winfos ) { 2764auto * buft = ggml_backend_buffer_get_type (winfo .tensor -> buffer ); 2765 2766const int64_t n = winfo .size /ggml_element_size (winfo .tensor ); 2767 2768auto & mbuf = mbufs_new [buft ]; 2769 2770mbuf .org .push_back (ggml_view_1d (mbuf .ctx .get (),winfo .tensor ,n ,winfo .offset )); 2771mbuf .cpy .push_back (ggml_new_tensor_1d (mbuf .ctx .get (),winfo .tensor -> type ,n )); 2772 } 2773 2774for (auto & [buft ,mbuf ] :mbufs_new ) { 2775auto & mbuf_cur = mbufs [buft ]; 2776 2777bool need_alloc = false; 2778 2779need_alloc = need_alloc || (!mbuf_cur .buf ); 2780need_alloc = need_alloc || (mbuf_cur .org .size ()!= mbuf .org .size ()); 2781need_alloc = need_alloc || (mbuf_cur .total_size != mbuf .total_size ); 2782 2783if (!need_alloc ) { 2784for (size_t i = 0 ;i < mbuf_cur .org .size ();++ i ) { 2785auto * org0 = mbuf_cur .org [i ]; 2786auto * org1 = mbuf .org [i ]; 2787 2788if (!ggml_are_same_shape (org0 ,org1 )) { 2789need_alloc = true; 2790break ; 2791 } 2792 2793if (org0 -> view_src != org1 -> view_src || org0 -> view_offs != org1 -> view_offs ) { 2794need_alloc = true; 2795break ; 2796 } 2797 } 2798 } 2799 2800if (need_alloc ) { 2801if (!mbuf_cur .buf || mbuf_cur .total_size != mbuf .total_size ) { 2802mbuf_cur = std::move (mbuf ); 2803 2804mbuf_cur .buf .reset (ggml_backend_alloc_ctx_tensors_from_buft (mbuf_cur .ctx .get (),buft )); 2805 2806LLAMA_LOG_INFO ("%s: allocated '%s' buffer %.3f MiB\n" ,__func__ ,ggml_backend_buft_name (buft ),mbuf .total_size /1024.0 /1024.0 ); 2807 }else { 2808//LLAMA_LOG_INFO("%s: reallocating tensors in '%s' buffer %.3f MiB\n", __func__, ggml_backend_buft_name(buft), mbuf.total_size/1024.0/1024.0); 2809 2810// save the old buffer and allocate the new tensors in it 2811auto buf = std::move (mbuf_cur .buf ); 2812 2813mbuf_cur = std::move (mbuf ); 2814 2815ggml_tallocr talloc = ggml_tallocr_new (buf .get ()); 2816 2817for (size_t i = 0 ;i < mbuf_cur .org .size ();++ i ) { 2818ggml_backend_view_init (mbuf_cur .org [i ]); 2819ggml_tallocr_alloc (& talloc ,mbuf_cur .cpy [i ]); 2820 } 2821 2822mbuf_cur .buf = std::move (buf ); 2823 } 2824 } 2825 2826for (size_t i = 0 ;i < mbuf_cur .org .size ();++ i ) { 2827ggml_backend_tensor_copy (mbuf_cur .org [i ],mbuf_cur .cpy [i ]); 2828 } 2829 } 2830 } 2831 2832void write (const void * src ,size_t size )override { 2833if (size > buf_size ) { 2834throw std::runtime_error ("unexpectedly reached end of buffer" ); 2835 } 2836memcpy (ptr ,src ,size ); 2837ptr += size ; 2838size_written += size ; 2839buf_size -= size ; 2840 } 2841 2842void write_tensor (ggml_tensor * tensor ,size_t offset ,size_t size )override { 2843// save the write for later during destruction 2844winfos .push_back ({tensor ,ptr ,size ,offset }); 2845 } 2846 2847size_t n_bytes ()override { 2848return size_written ; 2849 } 2850 2851private : 2852uint8_t * ptr ; 2853size_t buf_size = 0 ; 2854size_t size_written = 0 ; 2855 2856struct write_info { 2857ggml_tensor * tensor ; 2858uint8_t * ptr ; 2859size_t size ; 2860size_t offset ; 2861 }; 2862 std::vector < write_info > winfos ; 2863 2864llama_memory_buffers & mbufs ; 2865}; 2866 2867class llama_io_read_device :public llama_io_read_i { 2868public : 2869llama_io_read_device (const uint8_t * p ,size_t len ,const llama_memory_buffers & mbufs ) :ptr (p ),buf_size (len ),mbufs (mbufs ) { 2870 } 2871 2872 ~llama_io_read_device () { 2873llama_memory_buffers mbufs_new ; 2874 2875for (const auto & rinfo :rinfos ) { 2876auto * buft = ggml_backend_buffer_get_type (rinfo .tensor -> buffer ); 2877 2878mbufs_new [buft ].n_tensors ++ ; 2879mbufs_new [buft ].total_size += rinfo .size ; 2880 } 2881 2882for (auto & [buft ,mbuf ] :mbufs_new ) { 2883ggml_init_params params = { 2884/*.mem_size =*/ mbuf .n_tensors * ggml_tensor_overhead (), 2885/*.mem_buffer =*/ NULL , 2886/*.no_alloc =*/ true, 2887 }; 2888 2889mbuf .ctx .reset (ggml_init (params )); 2890 2891mbuf .org .reserve (mbuf .n_tensors ); 2892 } 2893 2894for (const auto & rinfo :rinfos ) { 2895auto * buft = ggml_backend_buffer_get_type (rinfo .tensor -> buffer ); 2896 2897const int64_t n = rinfo .size /ggml_element_size (rinfo .tensor ); 2898 2899auto & mbuf = mbufs_new [buft ]; 2900 2901mbuf .org .push_back (ggml_view_1d (mbuf .ctx .get (),rinfo .tensor ,n ,rinfo .offset )); 2902 2903ggml_backend_view_init (mbuf .org .back ()); 2904 } 2905 2906for (auto & [buft ,mbuf ] :mbufs_new ) { 2907const auto & mbuf_cur = mbufs .at (buft ); 2908 2909if (!mbuf_cur .buf || mbuf_cur .total_size != mbuf .total_size ) { 2910GGML_ABORT ("%s: memory buffer mismatch\n" ,__func__ ); 2911 } 2912 2913if (mbuf_cur .n_tensors == mbuf .n_tensors ) { 2914// an equal tensor count does not imply the same chunking, e.g. save ranges [2,1] vs restore runs [1,2] 2915bool same_chunking = true; 2916for (size_t i = 0 ;i < mbuf_cur .org .size ();++ i ) { 2917if (ggml_nbytes (mbuf_cur .cpy [i ])!= ggml_nbytes (mbuf .org [i ])) { 2918same_chunking = false; 2919break ; 2920 } 2921 } 2922 2923if (same_chunking ) { 2924// same chunking: copy 1:1 by index 2925for (size_t i = 0 ;i < mbuf_cur .org .size ();++ i ) { 2926ggml_backend_tensor_copy (mbuf_cur .cpy [i ],mbuf .org [i ]); 2927 } 2928continue ; 2929 } 2930 } 2931 2932// different chunking: copy the write-side data (mbuf_cur.cpy) into the read-side targets (mbuf.org) 2933// with a byte cursor. Write and read enumerate the same logical data in the same order but may chunk 2934// it differently (even with an equal number of tensors), so copy across tensor boundaries rather than 2935// 1:1 by index. 2936const size_t total = mbuf_cur .total_size ; 2937 2938ggml_init_params params_scratch = { 2939/*.mem_size =*/ 2 * (mbuf_cur .cpy .size ()+ mbuf .org .size ())* ggml_tensor_overhead (), 2940/*.mem_buffer =*/ NULL , 2941/*.no_alloc =*/ true, 2942 }; 2943ggml_context * ctx_scratch = ggml_init (params_scratch ); 2944 2945size_t src_pos = 0 ; 2946size_t dst_pos = 0 ; 2947size_t src_j = 0 ; 2948size_t dst_i = 0 ; 2949size_t src_base = 0 ; 2950size_t dst_base = 0 ; 2951 2952while (src_pos < total ) { 2953const auto & src_t = mbuf_cur .cpy [src_j ]; 2954const auto & dst_t = mbuf .org [dst_i ]; 2955 2956const size_t src_size = ggml_nbytes (src_t ); 2957const size_t dst_size = ggml_nbytes (dst_t ); 2958 2959const size_t src_off = src_pos - src_base ; 2960const size_t dst_off = dst_pos - dst_base ; 2961 2962const size_t n_copy = std::min (src_size - src_off ,dst_size - dst_off ); 2963 2964const size_t el = ggml_element_size (src_t ); 2965const int64_t n_el = (int64_t ) (n_copy /el ); 2966 2967auto * src_v = ggml_view_1d (ctx_scratch ,src_t ,n_el ,src_off ); 2968ggml_backend_view_init (src_v ); 2969auto * dst_v = ggml_view_1d (ctx_scratch ,dst_t ,n_el ,dst_off ); 2970ggml_backend_view_init (dst_v ); 2971 2972ggml_backend_tensor_copy (src_v ,dst_v ); 2973 2974src_pos += n_copy ; 2975dst_pos += n_copy ; 2976 2977if (src_pos - src_base == src_size ) { 2978src_base = src_pos ; 2979++ src_j ; 2980 } 2981if (dst_pos - dst_base == dst_size ) { 2982dst_base = dst_pos ; 2983++ dst_i ; 2984 } 2985 } 2986 2987GGML_ASSERT (src_pos == total && dst_pos == total ); 2988// any tensors left unvisited hold no data 2989for (size_t i = src_j ;i < mbuf_cur .cpy .size ();++ i ) { 2990GGML_ASSERT (ggml_nbytes (mbuf_cur .cpy [i ])== 0 ); 2991 } 2992for (size_t i = dst_i ;i < mbuf .org .size ();++ i ) { 2993GGML_ASSERT (ggml_nbytes (mbuf .org [i ])== 0 ); 2994 } 2995 2996ggml_free (ctx_scratch ); 2997 } 2998 2999GGML_ASSERT (buf_size == 0 ); 3000 } 3001 3002void read (void * dst ,size_t size )override { 3003if (size > buf_size ) { 3004throw std::runtime_error ("unexpectedly reached end of buffer" ); 3005 } 3006memcpy (dst ,ptr ,size ); 3007ptr += size ; 3008size_read += size ; 3009buf_size -= size ; 3010 } 3011 3012void read_tensor (ggml_tensor * tensor ,size_t offset ,size_t size )override { 3013// save for later during destruction 3014rinfos .push_back ({tensor ,ptr ,size ,offset }); 3015 } 3016 3017size_t n_bytes ()override { 3018return size_read ; 3019 } 3020 3021private : 3022const uint8_t * ptr ; 3023size_t buf_size = 0 ; 3024size_t size_read = 0 ; 3025 3026struct read_info { 3027ggml_tensor * tensor ; 3028const uint8_t * ptr ; 3029size_t size ; 3030size_t offset ; 3031 }; 3032 std::vector < read_info > rinfos ; 3033 3034const llama_memory_buffers & mbufs ; 3035}; 3036 3037size_t llama_context::state_get_size () { 3038llama_io_write_dummy io (false); 3039try { 3040return state_write_data (io ); 3041 }catch (const std::exception & err ) { 3042LLAMA_LOG_ERROR ("%s: error getting state size: %s\n" ,__func__ ,err .what ()); 3043return 0 ; 3044 } 3045} 3046 3047size_t llama_context::state_get_data (uint8_t * dst ,size_t size ) { 3048llama_io_write_host io (dst ,size ); 3049try { 3050return state_write_data (io ); 3051 }catch (const std::exception & err ) { 3052LLAMA_LOG_ERROR ("%s: error saving state: %s\n" ,__func__ ,err .what ()); 3053return 0 ; 3054 } 3055} 3056 3057size_t llama_context::state_set_data (const uint8_t * src ,size_t size ) { 3058llama_io_read_host io (src ,size ); 3059try { 3060return state_read_data (io ); 3061 }catch (const std::exception & err ) { 3062LLAMA_LOG_ERROR ("%s: error loading state: %s\n" ,__func__ ,err .what ()); 3063return 0 ; 3064 } 3065} 3066 3067static constexpr uint32_t io_magic = 0xaf143cd8 ; 3068 3069size_t llama_context::state_seq_get_size (llama_seq_id seq_id ,llama_state_seq_flags flags ) { 3070llama_io_write_dummy io (flags & LLAMA_STATE_SEQ_FLAGS_ON_DEVICE ); 3071try { 3072io .write (& io_magic ,sizeof (io_magic )); 3073io .write (& seq_id ,sizeof (seq_id )); 3074 3075return state_seq_write_data (io ,seq_id ,flags ); 3076 }catch (const std::exception & err ) { 3077LLAMA_LOG_ERROR ("%s: error getting state size: %s\n" ,__func__ ,err .what ()); 3078return 0 ; 3079 } 3080} 3081 3082size_t llama_context::state_seq_get_data (llama_seq_id seq_id ,uint8_t * dst ,size_t size ,llama_state_seq_flags flags ) { 3083 std::unique_ptr < llama_io_write_i > io ; 3084if (flags & LLAMA_STATE_SEQ_FLAGS_ON_DEVICE ) { 3085io = std::make_unique < llama_io_write_device > (dst ,size ,mem_storage [seq_id ]); 3086 }else { 3087io = std::make_unique < llama_io_write_host > (dst ,size ); 3088 } 3089 3090try { 3091io -> write (& io_magic ,sizeof (io_magic )); 3092io -> write (& seq_id ,sizeof (seq_id )); 3093 3094return state_seq_write_data (* io ,seq_id ,flags ); 3095 }catch (const std::exception & err ) { 3096LLAMA_LOG_ERROR ("%s: error saving state: %s\n" ,__func__ ,err .what ()); 3097return 0 ; 3098 } 3099} 3100 3101size_t llama_context::state_seq_set_data (llama_seq_id seq_id ,const uint8_t * src ,size_t size ,llama_state_seq_flags flags ) { 3102 std::unique_ptr < llama_io_read_i > io ; 3103if (flags & LLAMA_STATE_SEQ_FLAGS_ON_DEVICE ) { 3104// create a temporary io to read the magic and the src seq_id 3105io = std::make_unique < llama_io_read_host > (src ,size ); 3106 3107uint32_t magic_read ; 3108io -> read (& magic_read ,sizeof (magic_read )); 3109if (io_magic != magic_read ) { 3110throw std::runtime_error ("wrong sequence state magic" ); 3111 } 3112 3113llama_seq_id seq_id_read ; 3114io -> read (& seq_id_read ,sizeof (seq_id_read )); 3115 3116GGML_ASSERT (mem_storage .find (seq_id_read )!= mem_storage .end ()); 3117 3118io = std::make_unique < llama_io_read_device > (src ,size ,mem_storage [seq_id_read ]); 3119 }else { 3120io = std::make_unique < llama_io_read_host > (src ,size ); 3121 } 3122 3123try { 3124uint32_t magic_read ; 3125io -> read (& magic_read ,sizeof (magic_read )); 3126if (io_magic != magic_read ) { 3127throw std::runtime_error ("wrong sequence state magic" ); 3128 } 3129 3130llama_seq_id seq_id_read ; 3131io -> read (& seq_id_read ,sizeof (seq_id_read )); 3132 3133return state_seq_read_data (* io ,seq_id ,flags ); 3134 }catch (const std::exception & err ) { 3135LLAMA_LOG_ERROR ("%s: error loading state: %s\n" ,__func__ ,err .what ()); 3136return 0 ; 3137 } 3138} 3139 3140bool llama_context::state_load_file (const char * filepath ,llama_token * tokens_out ,size_t n_token_capacity ,size_t * n_token_count_out ) { 3141llama_file file (filepath ,"rb" ); 3142 3143// sanity checks 3144 { 3145const uint32_t magic = file .read_u32 (); 3146const uint32_t version = file .read_u32 (); 3147 3148if (magic != LLAMA_SESSION_MAGIC || version != LLAMA_SESSION_VERSION ) { 3149LLAMA_LOG_ERROR ("%s: unknown (magic, version) for session file: %08x, %08x\n" ,__func__ ,magic ,version ); 3150return false; 3151 } 3152 } 3153 3154// load the prompt 3155 { 3156const uint32_t n_token_count = file .read_u32 (); 3157 3158if (n_token_count > n_token_capacity ) { 3159LLAMA_LOG_ERROR ("%s: token count in session file exceeded capacity! %u > %zu\n" ,__func__ ,n_token_count ,n_token_capacity ); 3160return false; 3161 } 3162 3163file .read_raw (tokens_out ,sizeof (llama_token )* n_token_count ); 3164* n_token_count_out = n_token_count ; 3165 } 3166 3167// restore the context state 3168 { 3169const size_t n_state_size_cur = file .size ()- file .tell (); 3170 3171llama_io_read_file io (& file ); 3172const size_t n_read = state_read_data (io ); 3173 3174if (n_read != n_state_size_cur ) { 3175LLAMA_LOG_ERROR ("%s: did not read all of the session file data! size %zu, got %zu\n" ,__func__ ,n_state_size_cur ,n_read ); 3176return false; 3177 } 3178 } 3179 3180return true; 3181} 3182 3183bool llama_context::state_save_file (const char * filepath ,const llama_token * tokens ,size_t n_token_count ) { 3184llama_file file (filepath ,"wb" ); 3185 3186file .write_u32 (LLAMA_SESSION_MAGIC ); 3187file .write_u32 (LLAMA_SESSION_VERSION ); 3188 3189// save the prompt 3190file .write_u32 ((uint32_t )n_token_count ); 3191file .write_raw (tokens ,sizeof (llama_token )* n_token_count ); 3192 3193// save the context state using stream saving 3194llama_io_write_file io (& file ); 3195state_write_data (io ); 3196 3197return true; 3198} 3199 3200size_t llama_context::state_seq_load_file (llama_seq_id seq_id ,const char * filepath ,llama_token * tokens_out ,size_t n_token_capacity ,size_t * n_token_count_out ) { 3201llama_file file (filepath ,"rb" ); 3202 3203// version checks 3204 { 3205const uint32_t magic = file .read_u32 (); 3206const uint32_t version = file .read_u32 (); 3207 3208if (magic != LLAMA_STATE_SEQ_MAGIC || version != LLAMA_STATE_SEQ_VERSION ) { 3209LLAMA_LOG_ERROR ("%s: unknown (magic, version) for sequence state file: %08x, %08x\n" ,__func__ ,magic ,version ); 3210return 0 ; 3211 } 3212 } 3213 3214// load the prompt 3215 { 3216const uint32_t n_token_count = file .read_u32 (); 3217 3218if (tokens_out == nullptr ) { 3219const size_t n_token_max = (file .size ()- file .tell ()) /sizeof (llama_token ); 3220if (n_token_count > n_token_max ) { 3221LLAMA_LOG_ERROR ("%s: token count in sequence state file exceeds the file size! %u > %zu\n" ,__func__ ,n_token_count ,n_token_max ); 3222return 0 ; 3223 } 3224 3225* n_token_count_out = n_token_count ; 3226return file .tell (); 3227 } 3228 3229if (n_token_count > n_token_capacity ) { 3230LLAMA_LOG_ERROR ("%s: token count in sequence state file exceeded capacity! %u > %zu\n" ,__func__ ,n_token_count ,n_token_capacity ); 3231return 0 ; 3232 } 3233 3234file .read_raw (tokens_out ,sizeof (llama_token )* n_token_count ); 3235* n_token_count_out = n_token_count ; 3236 } 3237 3238// restore the context state 3239 { 3240const size_t state_size = file .size ()- file .tell (); 3241llama_io_read_file io (& file ); 3242const size_t nread = state_seq_read_data (io ,seq_id ,0 ); 3243if (!nread ) { 3244LLAMA_LOG_ERROR ("%s: failed to restore sequence state\n" ,__func__ ); 3245return 0 ; 3246 } 3247GGML_ASSERT (nread <=state_size ); 3248GGML_ASSERT (nread + sizeof (uint32_t )* 3 + sizeof (llama_token )* * n_token_count_out == file .tell ()); 3249 } 3250 3251return file .tell (); 3252} 3253 3254size_t llama_context::state_seq_save_file (llama_seq_id seq_id ,const char * filepath ,const llama_token * tokens ,size_t n_token_count ) { 3255llama_file file (filepath ,"wb" ); 3256 3257file .write_u32 (LLAMA_STATE_SEQ_MAGIC ); 3258file .write_u32 (LLAMA_STATE_SEQ_VERSION ); 3259 3260// save the prompt 3261file .write_u32 ((uint32_t )n_token_count ); 3262file .write_raw (tokens ,sizeof (llama_token )* n_token_count ); 3263 3264// save the context state using stream saving 3265llama_io_write_file io (& file ); 3266state_seq_write_data (io ,seq_id ,0 ); 3267 3268const size_t res = file .tell (); 3269GGML_ASSERT (res == sizeof (uint32_t )* 3 + sizeof (llama_token )* n_token_count + io .n_bytes ()); 3270 3271return res ; 3272} 3273 3274size_t llama_context::state_write_data (llama_io_write_i & io ) { 3275LLAMA_LOG_DEBUG ("%s: writing state\n" ,__func__ ); 3276 3277// write model info 3278 { 3279LLAMA_LOG_DEBUG ("%s: - writing model info\n" ,__func__ ); 3280 3281const std::string arch_str = llm_arch_name (model .arch ); 3282io .write_string (arch_str ); 3283// TODO: add more model-specific info which should prevent loading the session file if not identical 3284 } 3285 3286if (memory != nullptr ) { 3287LLAMA_LOG_DEBUG ("%s: - writing memory module\n" ,__func__ ); 3288memory -> state_write (io ); 3289 } 3290 3291return io .n_bytes (); 3292} 3293 3294size_t llama_context::state_read_data (llama_io_read_i & io ) { 3295LLAMA_LOG_DEBUG ("%s: reading state\n" ,__func__ ); 3296 3297// read model info 3298 { 3299LLAMA_LOG_DEBUG ("%s: - reading model info\n" ,__func__ ); 3300 3301const std::string cur_arch_str = llm_arch_name (model .arch ); 3302 3303 std::string arch_str ; 3304io .read_string (arch_str ); 3305if (cur_arch_str != arch_str ) { 3306throw std::runtime_error (format ("wrong model arch: '%s' instead of '%s'" ,arch_str .c_str (),cur_arch_str .c_str ())); 3307 } 3308// TODO: add more info which needs to be identical but which is not verified otherwise 3309 } 3310 3311if (memory ) { 3312LLAMA_LOG_DEBUG ("%s: - reading memory module\n" ,__func__ ); 3313 3314memory -> state_read (io ); 3315 } 3316 3317return io .n_bytes (); 3318} 3319 3320size_t llama_context::state_seq_write_data (llama_io_write_i & io ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 3321if (memory ) { 3322memory -> state_write (io ,seq_id ,flags ); 3323 } 3324 3325return io .n_bytes (); 3326} 3327 3328size_t llama_context::state_seq_read_data (llama_io_read_i & io ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 3329if (memory ) { 3330memory -> state_read (io ,seq_id ,flags ); 3331 } 3332 3333return io .n_bytes (); 3334} 3335 3336// 3337// perf 3338// 3339 3340llama_perf_context_data llama_context::perf_get_data ()const { 3341llama_perf_context_data data = {}; 3342 3343data .t_start_ms = 1e-3 * t_start_us ; 3344data .t_load_ms = 1e-3 * t_load_us ; 3345data .t_p_eval_ms = 1e-3 * t_p_eval_us ; 3346data .t_eval_ms = 1e-3 * t_eval_us ; 3347data .n_p_eval = std::max (1 ,n_p_eval ); 3348data .n_eval = std::max (1 ,n_eval ); 3349data .n_reused = std::max (0 ,n_reused ); 3350 3351return data ; 3352} 3353 3354void llama_context::perf_reset () { 3355t_start_us = ggml_time_us (); 3356t_eval_us = n_eval = 0 ; 3357t_p_eval_us = n_p_eval = 0 ; 3358n_reused = 0 ; 3359} 3360 3361llama_memory_breakdown llama_context::memory_breakdown ()const { 3362 std::map < ggml_backend_buffer_type_t ,llama_memory_breakdown_data > ret ; 3363for (const auto & [buft ,size ] :model .memory_breakdown ()) { 3364ret [buft ].model += size ; 3365 } 3366if (memory ) { 3367for (const auto & [buft ,size ] :memory -> memory_breakdown ()) { 3368ret [buft ].context += size ; 3369 } 3370 } 3371if (model .hparams .no_alloc ) { 3372for (size_t i = 0 ;i < backends .size ();++ i ) { 3373ggml_backend_t backend = backends [i ].get (); 3374ggml_backend_buffer_type_t buft = ggml_backend_sched_get_buffer_type (sched .get (),backend ); 3375ret [buft ].compute += backend_buf_exp_size [i ]; 3376 } 3377 }else { 3378for (const auto & backend_ptr :backends ) { 3379ggml_backend_t backend = backend_ptr .get (); 3380ggml_backend_buffer_type_t buft = ggml_backend_sched_get_buffer_type (sched .get (),backend ); 3381ret [buft ].compute += ggml_backend_sched_get_buffer_size (sched .get (),backend ); 3382 } 3383 } 3384return ret ; 3385} 3386 3387// 3388// training 3389// 3390 3391static void llama_set_param (struct ggml_tensor * tensor ,llama_opt_param_filter param_filter ,void * userdata ) { 3392if (!tensor || tensor -> type != GGML_TYPE_F32 ) { 3393return ; 3394 } 3395if (!param_filter (tensor ,userdata )) { 3396return ; 3397 } 3398if (strcmp (tensor -> name ,"token_embd.weight" )== 0 ) { 3399return ;// FIXME 3400 } 3401if (strcmp (tensor -> name ,"rope_freqs.weight" )== 0 ) { 3402return ;// FIXME 3403 } 3404ggml_set_param (tensor ); 3405} 3406 3407void llama_context::opt_init (struct llama_model * model ,struct llama_opt_params lopt_params ) { 3408GGML_ASSERT (!opt_ctx ); 3409model -> hparams .n_ctx_train = lopt_params .n_ctx_train > 0 ?lopt_params .n_ctx_train :n_ctx (); 3410const uint32_t n_batch = std::min (this -> n_batch (),model -> hparams .n_ctx_train ); 3411const uint32_t n_ubatch = std::min (this -> n_ubatch (),n_batch ); 3412GGML_ASSERT (model -> hparams .n_ctx_train %n_batch == 0 ); 3413GGML_ASSERT (n_batch %n_ubatch == 0 ); 3414 3415if (cparams .flash_attn ) { 3416LLAMA_LOG_INFO ("%s: disabling flash attention, FLASH_ATTN_EXT has no backward pass\n" ,__func__ ); 3417cparams .flash_attn = false; 3418 3419// the graph changes without flash attention, need to reserve again 3420sched_need_reserve = true; 3421sched_reserve (); 3422 } 3423 3424ggml_opt_params opt_params = ggml_opt_default_params (sched .get (),GGML_OPT_LOSS_TYPE_CROSS_ENTROPY ); 3425opt_params .opt_period = n_batch /n_ubatch ; 3426opt_params .get_opt_pars = lopt_params .get_opt_pars ; 3427opt_params .get_opt_pars_ud = lopt_params .get_opt_pars_ud ; 3428opt_params .optimizer = lopt_params .optimizer_type ; 3429opt_ctx = ggml_opt_init (opt_params ); 3430 3431llama_opt_param_filter param_filter = lopt_params .param_filter ; 3432void * param_filter_ud = lopt_params .param_filter_ud ; 3433 3434//llama_set_param(model->tok_embd, param_filter, param_filter_ud); // FIXME 3435llama_set_param (model -> type_embd ,param_filter ,param_filter_ud ); 3436llama_set_param (model -> pos_embd ,param_filter ,param_filter_ud ); 3437llama_set_param (model -> tok_norm ,param_filter ,param_filter_ud ); 3438llama_set_param (model -> tok_norm_b ,param_filter ,param_filter_ud ); 3439llama_set_param (model -> output_norm ,param_filter ,param_filter_ud ); 3440llama_set_param (model -> output_norm_b ,param_filter ,param_filter_ud ); 3441llama_set_param (model -> output ,param_filter ,param_filter_ud ); 3442llama_set_param (model -> output_b ,param_filter ,param_filter_ud ); 3443llama_set_param (model -> output_norm_enc ,param_filter ,param_filter_ud ); 3444llama_set_param (model -> cls ,param_filter ,param_filter_ud ); 3445llama_set_param (model -> cls_b ,param_filter ,param_filter_ud ); 3446llama_set_param (model -> cls_out ,param_filter ,param_filter_ud ); 3447llama_set_param (model -> cls_out_b ,param_filter ,param_filter_ud ); 3448llama_set_param (model -> cls_norm ,param_filter ,param_filter_ud ); 3449 3450for (struct llama_layer & layer :model -> layers ) { 3451for (size_t i = 0 ;i < sizeof (layer )/sizeof (struct ggml_tensor * );++ i ) { 3452llama_set_param (reinterpret_cast < struct ggml_tensor **> (& layer )[i ],param_filter ,param_filter_ud ); 3453 } 3454 } 3455} 3456 3457void llama_context::opt_epoch_iter ( 3458ggml_opt_dataset_t dataset , 3459ggml_opt_result_t result , 3460const std::vector < llama_token > & tokens , 3461const std::vector < llama_token > & labels_sparse , 3462llama_batch & batch , 3463ggml_opt_epoch_callback callback , 3464bool train , 3465int64_t idata_in_loop , 3466int64_t ndata_in_loop , 3467int64_t t_loop_start ) { 3468GGML_ASSERT (opt_ctx ); 3469const uint32_t n_ctx = llama_model_n_ctx_train (& model ); 3470const uint32_t n_batch = std::min (this -> n_batch (),n_ctx ); 3471const uint32_t n_ubatch = std::min (this -> n_ubatch (),n_batch ); 3472 3473memory -> clear (true); 3474 3475for (uint32_t pos_ctx = 0 ;pos_ctx < n_ctx ;pos_ctx += n_batch ) { 3476batch .n_tokens = n_batch ; 3477for (uint32_t pos_batch = 0 ;pos_batch < n_batch ;++ pos_batch ) { 3478batch .token [pos_batch ]= tokens [pos_ctx + pos_batch ]; 3479batch .pos [pos_batch ]= pos_ctx + pos_batch ; 3480batch .n_seq_id [pos_batch ]= 1 ; 3481batch .seq_id [pos_batch ][0 ]= 0 ; 3482batch .logits [pos_batch ]= true; 3483 } 3484 3485if (!balloc -> init (batch ,model .vocab ,nullptr ,model .hparams .n_embd_inp (),cparams .kv_unified ?LLAMA_MAX_SEQ :cparams .n_seq_max , true)) { 3486LLAMA_LOG_ERROR ("%s: failed to initialize batch\n" ,__func__ ); 3487return ; 3488 } 3489 3490const uint32_t n_tokens_all = balloc -> get_n_tokens (); 3491 3492n_queued_tokens += n_tokens_all ; 3493 3494embd_seq .clear (); 3495 3496uint32_t n_outputs_all = n_tokens_all ; 3497 3498auto mctx = memory -> init_batch (* balloc ,cparams .n_ubatch , true); 3499if (!mctx || mctx -> get_status ()!= LLAMA_MEMORY_STATUS_SUCCESS ) { 3500LLAMA_LOG_ERROR ("%s: could not initialize batch\n" ,__func__ ); 3501break ; 3502 } 3503 3504// reserve output buffer 3505if (output_reserve (n_outputs_all )< n_outputs_all ) { 3506LLAMA_LOG_ERROR ("%s: could not reserve space for batch with %d outputs\n" ,__func__ ,n_outputs_all ); 3507GGML_ABORT ("TODO: handle this error" ); 3508 }; 3509 3510uint32_t pos_batch = 0 ; 3511do { 3512const auto & ubatch = mctx -> get_ubatch (); 3513 3514n_outputs = ubatch .n_tokens ; 3515 3516if (!mctx -> apply ()) { 3517LLAMA_LOG_ERROR ("%s: failed to update the memory context\n" ,__func__ ); 3518break ; 3519 } 3520 3521auto * res = gf_res_prev .get (); 3522 3523const auto gparams = graph_params (res ,ubatch ,mctx .get (),ctx_type_to_graph_type (cparams .ctx_type )); 3524 3525res -> reset (); 3526 3527auto * gf = model .build_graph (gparams ); 3528 3529struct ggml_context * ctx_compute_opt ; 3530 { 3531const size_t size_gf = ggml_graph_size (gf ); 3532const size_t size_meta = 4 * size_gf * ggml_tensor_overhead ()+ 2 * ggml_graph_overhead_custom (size_gf ,/*grads = */ true); 3533struct ggml_init_params params = { 3534/*.mem_size =*/ size_meta , 3535/*.mem_buffer =*/ nullptr , 3536/*.no_alloc =*/ true, 3537 }; 3538ctx_compute_opt = ggml_init (params ); 3539 } 3540ggml_opt_prepare_alloc (opt_ctx ,ctx_compute_opt ,gf ,res -> get_inp_tokens (),res -> get_logits ()); 3541ggml_opt_alloc (opt_ctx ,train ); 3542 3543res -> set_inputs (& ubatch ); 3544 { 3545struct ggml_tensor * labels = ggml_opt_labels (opt_ctx ); 3546GGML_ASSERT (labels -> ne [1 ]== n_ubatch ); 3547ggml_set_zero (labels ); 3548const float onef = 1.0f ; 3549for (uint32_t pos_ubatch = 0 ;pos_ubatch < n_ubatch ;++ pos_ubatch ) { 3550const uint32_t ilabel = pos_ctx + pos_batch + pos_ubatch ; 3551GGML_ASSERT (labels_sparse [ilabel ]< labels -> ne [0 ]); 3552ggml_backend_tensor_set (labels ,& onef , (pos_ubatch * labels -> ne [0 ]+ labels_sparse [ilabel ])* sizeof (float ),sizeof (float )); 3553 } 3554 } 3555ggml_opt_eval (opt_ctx ,result ); 3556if (callback ) { 3557callback (train ,opt_ctx ,dataset ,result ,idata_in_loop + (pos_ctx + pos_batch )/n_ubatch + 1 ,ndata_in_loop ,t_loop_start ); 3558 } 3559ggml_free (ctx_compute_opt ); 3560 3561pos_batch += ubatch .n_tokens ; 3562 }while (mctx -> next ()); 3563 } 3564} 3565 3566void llama_context::opt_epoch ( 3567ggml_opt_dataset_t dataset , 3568ggml_opt_result_t result_train , 3569ggml_opt_result_t result_eval , 3570int64_t idata_split , 3571ggml_opt_epoch_callback callback_train , 3572ggml_opt_epoch_callback callback_eval ) { 3573const uint32_t n_ctx = this -> n_ctx (); 3574const uint32_t n_batch = std::min (cparams .n_batch ,n_ctx ); 3575const uint32_t n_ubatch = std::min (cparams .n_ubatch ,n_batch ); 3576const int64_t ndata = ggml_opt_dataset_ndata (dataset ); 3577 3578GGML_ASSERT (idata_split >=0 ); 3579GGML_ASSERT (idata_split <=ndata ); 3580 3581const uint32_t ubatch_per_ctx = n_ctx /n_ubatch ; 3582 3583struct llama_batch batch = llama_batch_init (n_batch ,0 ,1 ); 3584 std::vector < llama_token > tokens (n_ctx ); 3585 std::vector < llama_token > labels_sparse (n_ctx ); 3586 3587int64_t idata = 0 ; 3588 3589int64_t t_loop_start = ggml_time_us (); 3590int64_t ndata_in_loop = idata_split * ubatch_per_ctx ; 3591for (;idata < idata_split ;++ idata ) { 3592constexpr bool train = true; 3593const int64_t idata_in_loop = idata * ubatch_per_ctx ; 3594 3595ggml_opt_dataset_get_batch_host (dataset ,tokens .data (),n_ctx * sizeof (llama_token ),labels_sparse .data (),idata ); 3596opt_epoch_iter (dataset ,result_train ,tokens ,labels_sparse ,batch , 3597callback_train ,train ,idata_in_loop ,ndata_in_loop ,t_loop_start ); 3598 } 3599 3600t_loop_start = ggml_time_us (); 3601ndata_in_loop = (ndata - idata_split )* ubatch_per_ctx ; 3602for (;idata < ndata ;++ idata ) { 3603constexpr bool train = false; 3604const int64_t idata_in_loop = (idata - idata_split )* ubatch_per_ctx ; 3605 3606ggml_opt_dataset_get_batch_host (dataset ,tokens .data (),n_ctx * sizeof (llama_token ),labels_sparse .data (),idata ); 3607opt_epoch_iter (dataset ,result_eval ,tokens ,labels_sparse ,batch , 3608callback_eval ,train ,idata_in_loop ,ndata_in_loop ,t_loop_start ); 3609 } 3610 3611llama_batch_free (batch ); 3612} 3613 3614// 3615// interface implementation 3616// 3617 3618llama_context_params llama_context_default_params () { 3619llama_context_params result = { 3620/*.n_ctx =*/ 512 , 3621/*.n_batch =*/ 2048 , 3622/*.n_ubatch =*/ 512 , 3623/*.n_seq_max =*/ 1 , 3624/*.n_rs_seq =*/ 0 , 3625/*.n_outputs_max =*/ 0 , 3626/*.n_outputs_max_per_seq =*/ 1 , 3627/*.n_threads =*/ GGML_DEFAULT_N_THREADS ,// TODO: better default 3628/*.n_threads_batch =*/ GGML_DEFAULT_N_THREADS , 3629/*.ctx_type =*/ LLAMA_CONTEXT_TYPE_DEFAULT , 3630/*.rope_scaling_type =*/ LLAMA_ROPE_SCALING_TYPE_UNSPECIFIED , 3631/*.pooling_type =*/ LLAMA_POOLING_TYPE_UNSPECIFIED , 3632/*.attention_type =*/ LLAMA_ATTENTION_TYPE_UNSPECIFIED , 3633/*.flash_attn_type =*/ LLAMA_FLASH_ATTN_TYPE_AUTO , 3634/*.rope_freq_base =*/ 0.0f , 3635/*.rope_freq_scale =*/ 0.0f , 3636/*.yarn_ext_factor =*/ -1.0f , 3637/*.yarn_attn_factor =*/ -1.0f , 3638/*.yarn_beta_fast =*/ -1.0f , 3639/*.yarn_beta_slow =*/ -1.0f , 3640/*.yarn_orig_ctx =*/ 0 , 3641/*.defrag_thold =*/ -1.0f , 3642/*.cb_eval =*/ nullptr , 3643/*.cb_eval_user_data =*/ nullptr , 3644/*.type_k =*/ GGML_TYPE_F16 , 3645/*.type_v =*/ GGML_TYPE_F16 , 3646/*.abort_callback =*/ nullptr , 3647/*.abort_callback_data =*/ nullptr , 3648/*.embeddings =*/ false, 3649/*.offload_kqv =*/ true, 3650/*.no_perf =*/ true, 3651/*.op_offload =*/ true, 3652/*.swa_full =*/ true, 3653/*.kv_unified =*/ false, 3654/*.sampler =*/ nullptr , 3655/*.n_sampler =*/ 0 , 3656/*.ctx_other =*/ nullptr , 3657 }; 3658 3659return result ; 3660} 3661 3662llama_context * llama_init_from_model ( 3663llama_model * model , 3664llama_context_params params ) { 3665if (!model ) { 3666LLAMA_LOG_ERROR ("%s: model cannot be NULL\n" ,__func__ ); 3667return nullptr ; 3668 } 3669 3670if (params .n_batch == 0 && params .n_ubatch == 0 ) { 3671LLAMA_LOG_ERROR ("%s: n_batch and n_ubatch cannot both be zero\n" ,__func__ ); 3672return nullptr ; 3673 } 3674 3675if (params .n_ctx == 0 && model -> hparams .n_ctx_train == 0 ) { 3676LLAMA_LOG_ERROR ("%s: n_ctx and model->hparams.n_ctx_train cannot both be zero\n" ,__func__ ); 3677return nullptr ; 3678 } 3679 3680if (params .flash_attn_type != LLAMA_FLASH_ATTN_TYPE_DISABLED && model -> arch == LLM_ARCH_GROK ) { 3681LLAMA_LOG_WARN ("%s: flash_attn is not compatible with Grok - forcing off\n" ,__func__ ); 3682params .flash_attn_type = LLAMA_FLASH_ATTN_TYPE_DISABLED ; 3683 } 3684 3685if (model -> split_mode ()== LLAMA_SPLIT_MODE_TENSOR ) { 3686if (params .flash_attn_type == LLAMA_FLASH_ATTN_TYPE_AUTO ) { 3687LLAMA_LOG_INFO ("%s: enabling flash_attn since it is required for SPLIT_MODE_TENSOR\n" ,__func__ ); 3688params .flash_attn_type = LLAMA_FLASH_ATTN_TYPE_ENABLED ; 3689 } 3690if (params .flash_attn_type != LLAMA_FLASH_ATTN_TYPE_ENABLED ) { 3691LLAMA_LOG_ERROR ("%s: SPLIT_MODE_TENSOR requires flash_attn to be enabled\n" ,__func__ ); 3692return nullptr ; 3693 } 3694if (model -> get_split_state_ud .n_devices == 1 ) { 3695LLAMA_LOG_WARN ("%s: SPLIT_MODE_TENSOR being used for a single device is not recommended\n" ,__func__ ); 3696 } 3697 } 3698 3699if ((model -> hparams .is_mla ()|| model -> arch == LLM_ARCH_DEEPSEEK4 )&& params .type_k != params .type_v ) { 3700LLAMA_LOG_ERROR ("%s: model does not support different K (%s) and V (%s) cache types\n" ,__func__ ,ggml_type_name (params .type_k ),ggml_type_name (params .type_v )); 3701return nullptr ; 3702 } 3703 3704if (ggml_is_quantized (params .type_v )&& params .flash_attn_type != LLAMA_FLASH_ATTN_TYPE_ENABLED ) { 3705if (params .flash_attn_type == LLAMA_FLASH_ATTN_TYPE_AUTO ) { 3706LLAMA_LOG_INFO ("%s: enabling flash_attn since it is required for quantized V cache\n" ,__func__ ); 3707params .flash_attn_type = LLAMA_FLASH_ATTN_TYPE_ENABLED ; 3708 } 3709if (params .flash_attn_type == LLAMA_FLASH_ATTN_TYPE_DISABLED ) { 3710LLAMA_LOG_ERROR ("%s: quantized V cache requires flash_attn to be enabled\n" ,__func__ ); 3711return nullptr ; 3712 } 3713 } 3714 3715if (params .flash_attn_type != LLAMA_FLASH_ATTN_TYPE_DISABLED && ggml_is_quantized (params .type_k )) { 3716const uint32_t blck_size = ggml_blck_size (params .type_k ); 3717for (uint32_t il = 0 ;il < model -> hparams .n_layer ();++ il ) { 3718if (model -> hparams .n_embd_head_k (il ) %blck_size != 0 ) { 3719LLAMA_LOG_ERROR ("%s: K cache type %s with block size %u does not divide n_embd_head_k=%u\n" , 3720__func__ ,ggml_type_name (params .type_k ),blck_size ,model -> hparams .n_embd_head_k (il )); 3721return nullptr ; 3722 } 3723 } 3724 } 3725 3726if (params .flash_attn_type != LLAMA_FLASH_ATTN_TYPE_DISABLED && ggml_is_quantized (params .type_v )) { 3727const uint32_t blck_size = ggml_blck_size (params .type_v ); 3728for (uint32_t il = 0 ;il < model -> hparams .n_layer ();++ il ) { 3729if (model -> hparams .n_embd_head_v (il ) %blck_size != 0 ) { 3730LLAMA_LOG_ERROR ("%s: V cache type %s with block size %u does not divide n_embd_head_v=%u\n" , 3731__func__ ,ggml_type_name (params .type_v ),blck_size ,model -> hparams .n_embd_head_v (il )); 3732return nullptr ; 3733 } 3734 } 3735 } 3736 3737if (params .pooling_type != LLAMA_POOLING_TYPE_UNSPECIFIED && 3738params .pooling_type != model -> hparams .pooling_type ) { 3739//user-specified pooling-type is different from the model default 3740LLAMA_LOG_WARN ("%s: model default pooling_type is [%d], but [%d] was specified\n" ,__func__ , 3741model -> hparams .pooling_type ,params .pooling_type ); 3742 } 3743 3744// router_layer >= 0 means n_layer_nextn is repurposed for a router layer, not real MTP 3745if (params .ctx_type == LLAMA_CONTEXT_TYPE_MTP && 3746 (model -> hparams .n_layer_nextn == 0 || model -> hparams .router_layer >=0 )) { 3747LLAMA_LOG_WARN ("%s: context type MTP requested but model doesn't contain MTP layers\n" ,__func__ ); 3748return nullptr ; 3749 } 3750 3751try { 3752auto * ctx = new llama_context (* model ,params ); 3753const auto & cparams = ctx -> get_cparams (); 3754 3755if (cparams .rope_scaling_type == LLAMA_ROPE_SCALING_TYPE_YARN && cparams .rope_freq_scale != model -> hparams .rope_freq_scale_train ) { 3756LLAMA_LOG_INFO ("%s: custom YaRN scaling detected, re-adjusting n_ctx_train(%u)...\n" ,__func__ ,model -> hparams .n_ctx_train ); 3757model -> hparams .n_ctx_train = cparams .n_ctx_orig_yarn /cparams .rope_freq_scale ; 3758LLAMA_LOG_INFO ("%s: n_ctx_train adjusted to %u\n" ,__func__ ,model -> hparams .n_ctx_train ); 3759 } 3760 3761return ctx ; 3762 }catch (const std::exception & err ) { 3763LLAMA_LOG_ERROR ("%s: failed to initialize the context: %s\n" ,__func__ ,err .what ()); 3764 } 3765 3766return nullptr ; 3767} 3768 3769// deprecated 3770llama_context * llama_new_context_with_model ( 3771llama_model * model , 3772llama_context_params params ) { 3773return llama_init_from_model (model ,params ); 3774} 3775 3776void llama_free (llama_context * ctx ) { 3777delete ctx ; 3778} 3779 3780uint32_t llama_n_ctx (const llama_context * ctx ) { 3781return ctx -> n_ctx (); 3782} 3783 3784uint32_t llama_n_ctx_seq (const llama_context * ctx ) { 3785return ctx -> n_ctx_seq (); 3786} 3787 3788uint32_t llama_n_batch (const llama_context * ctx ) { 3789return ctx -> n_batch (); 3790} 3791 3792uint32_t llama_n_ubatch (const llama_context * ctx ) { 3793return ctx -> n_ubatch (); 3794} 3795 3796uint32_t llama_n_seq_max (const llama_context * ctx ) { 3797return ctx -> n_seq_max (); 3798} 3799 3800uint32_t llama_n_rs_seq (const llama_context * ctx ) { 3801return ctx -> get_cparams ().n_rs_seq ; 3802} 3803 3804const llama_model * llama_get_model (const llama_context * ctx ) { 3805return & ctx -> get_model (); 3806} 3807 3808enum llama_pooling_type llama_pooling_type (const llama_context * ctx ) { 3809return ctx -> pooling_type (); 3810} 3811 3812void llama_attach_threadpool ( 3813llama_context * ctx , 3814ggml_threadpool_t threadpool , 3815ggml_threadpool_t threadpool_batch ) { 3816ctx -> attach_threadpool (threadpool ,threadpool_batch ); 3817} 3818 3819void llama_detach_threadpool (llama_context * ctx ) { 3820ctx -> detach_threadpool (); 3821} 3822 3823void llama_set_n_threads (llama_context * ctx ,int32_t n_threads ,int32_t n_threads_batch ) { 3824ctx -> set_n_threads (n_threads ,n_threads_batch ); 3825} 3826 3827int32_t llama_n_threads (llama_context * ctx ) { 3828return ctx -> n_threads (); 3829} 3830 3831int32_t llama_n_threads_batch (llama_context * ctx ) { 3832return ctx -> n_threads_batch (); 3833} 3834 3835void llama_set_abort_callback (llama_context * ctx ,bool (* abort_callback )(void * data ),void * abort_callback_data ) { 3836ctx -> set_abort_callback (abort_callback ,abort_callback_data ); 3837} 3838 3839void llama_set_embeddings (llama_context * ctx ,bool embeddings ) { 3840ctx -> set_embeddings (embeddings ); 3841} 3842 3843void llama_set_causal_attn (llama_context * ctx ,bool causal_attn ) { 3844ctx -> set_causal_attn (causal_attn ); 3845} 3846 3847void llama_set_warmup (llama_context * ctx ,bool warmup ) { 3848ctx -> set_warmup (warmup ); 3849} 3850 3851void llama_synchronize (llama_context * ctx ) { 3852ctx -> synchronize (); 3853} 3854 3855float * llama_get_logits (llama_context * ctx ) { 3856ctx -> synchronize (); 3857 3858return ctx -> get_logits (); 3859} 3860 3861float * llama_get_logits_ith (llama_context * ctx ,int32_t i ) { 3862ctx -> synchronize (); 3863 3864float * res = nullptr ; 3865 3866res = ctx -> get_sampled_logits_ith (i ); 3867 3868if (!res ) { 3869res = ctx -> get_logits_ith (i ); 3870 } 3871 3872return res ; 3873} 3874 3875float * llama_get_embeddings (llama_context * ctx ) { 3876ctx -> synchronize (); 3877 3878return ctx -> get_embeddings (); 3879} 3880 3881float * llama_get_embeddings_ith (llama_context * ctx ,int32_t i ) { 3882ctx -> synchronize (); 3883 3884return ctx -> get_embeddings_ith (i ); 3885} 3886 3887float * llama_get_embeddings_seq (llama_context * ctx ,llama_seq_id seq_id ) { 3888ctx -> synchronize (); 3889 3890return ctx -> get_embeddings_seq (seq_id ); 3891} 3892 3893void llama_set_embeddings_nextn (llama_context * ctx ,bool value ,bool masked ) { 3894ctx -> set_embeddings_nextn (value ,masked ); 3895} 3896 3897void llama_set_embeddings_layer_inp (llama_context * ctx ,uint32_t lid ,bool value ) { 3898ctx -> set_embeddings_layer_inp (lid ,value ); 3899} 3900 3901void llama_set_nextn_layer_offset (llama_context * ctx ,int32_t offset ) { 3902ctx -> set_nextn_layer_offset (offset ); 3903} 3904 3905llama_memory_t llama_get_memory (const struct llama_context * ctx ) { 3906if (!ctx ) { 3907return nullptr ; 3908 } 3909 3910return ctx -> get_memory (); 3911} 3912 3913float * llama_get_embeddings_nextn (llama_context * ctx ) { 3914ctx -> synchronize (); 3915 3916return ctx -> get_embeddings_nextn (); 3917} 3918 3919float * llama_get_embeddings_nextn_ith (llama_context * ctx ,int32_t i ) { 3920ctx -> synchronize (); 3921 3922return ctx -> get_embeddings_nextn_ith (i ); 3923} 3924 3925float * llama_get_embeddings_layer_inp (llama_context * ctx ,uint32_t lid ) { 3926ctx -> synchronize (); 3927 3928return ctx -> get_embeddings_layer_inp (lid ); 3929} 3930 3931bool llama_set_sampler (llama_context * ctx ,llama_seq_id seq_id ,llama_sampler * smpl ) { 3932return ctx -> set_sampler (seq_id ,smpl ); 3933} 3934 3935llama_token llama_get_sampled_token_ith (llama_context * ctx ,int32_t i ) { 3936ctx -> synchronize (); 3937 3938return ctx -> get_sampled_token_ith (i ); 3939} 3940 3941float * llama_get_sampled_probs_ith (llama_context * ctx ,int32_t i ) { 3942ctx -> synchronize (); 3943 3944return ctx -> get_sampled_probs_ith (i ); 3945} 3946 3947float * llama_get_sampled_logits_ith (llama_context * ctx ,int32_t i ) { 3948ctx -> synchronize (); 3949 3950return ctx -> get_sampled_logits_ith (i ); 3951} 3952 3953llama_token * llama_get_sampled_candidates_ith (llama_context * ctx ,int32_t i ) { 3954ctx -> synchronize (); 3955 3956return const_cast < llama_token *> (ctx -> get_sampled_candidates_ith (i )); 3957} 3958 3959uint32_t llama_get_sampled_candidates_count_ith (llama_context * ctx ,int32_t i ) { 3960ctx -> synchronize (); 3961 3962return static_cast < uint32_t > (ctx -> get_sampled_candidates_count (i )); 3963} 3964 3965uint32_t llama_get_sampled_logits_count_ith (llama_context * ctx ,int32_t i ) { 3966ctx -> synchronize (); 3967 3968return static_cast < uint32_t > (ctx -> get_sampled_logits_count (i )); 3969} 3970 3971uint32_t llama_get_sampled_probs_count_ith (llama_context * ctx ,int32_t i ) { 3972ctx -> synchronize (); 3973 3974return static_cast < uint32_t > (ctx -> get_sampled_probs_count (i )); 3975} 3976 3977struct ggml_cgraph * llama_graph_reserve ( 3978struct llama_context * ctx , 3979uint32_t n_tokens , 3980uint32_t n_seqs , 3981uint32_t n_outputs ) { 3982auto memory = ctx -> get_memory (); 3983llama_memory_context_ptr mctx ; 3984if (memory ) { 3985mctx = memory -> init_full (); 3986 } 3987return ctx -> graph_reserve (n_tokens ,n_seqs ,n_outputs ,mctx .get ()); 3988} 3989 3990// llama adapter API 3991 3992int32_t llama_set_adapters_lora ( 3993llama_context * ctx , 3994llama_adapter_lora ** adapters , 3995size_t n_adapters , 3996float * scales ) { 3997if (adapters == nullptr || scales == nullptr ) { 3998GGML_ASSERT (n_adapters == 0 && "invalid llama_set_adapters_lora call" ); 3999 } 4000 4001ctx -> set_adapters_lora (adapters ,n_adapters ,scales ); 4002 4003return 0 ; 4004} 4005 4006int32_t llama_set_adapter_cvec ( 4007llama_context * ctx , 4008const float * data , 4009size_t len , 4010int32_t n_embd , 4011int32_t il_start , 4012int32_t il_end ) { 4013bool res = ctx -> set_adapter_cvec (data ,len ,n_embd ,il_start ,il_end ); 4014 4015return res ?0 :-1 ; 4016} 4017 4018// 4019// memory 4020// 4021 4022void llama_memory_clear (llama_memory_t mem ,bool data ) { 4023if (!mem ) { 4024return ; 4025 } 4026 4027mem -> clear (data ); 4028} 4029 4030bool llama_memory_seq_rm ( 4031llama_memory_t mem , 4032llama_seq_id seq_id , 4033llama_pos p0 , 4034llama_pos p1 ) { 4035if (!mem ) { 4036return true; 4037 } 4038 4039return mem -> seq_rm (seq_id ,p0 ,p1 ); 4040} 4041 4042void llama_memory_seq_cp ( 4043llama_memory_t mem , 4044llama_seq_id seq_id_src , 4045llama_seq_id seq_id_dst , 4046llama_pos p0 , 4047llama_pos p1 ) { 4048if (!mem ) { 4049return ; 4050 } 4051 4052mem -> seq_cp (seq_id_src ,seq_id_dst ,p0 ,p1 ); 4053} 4054 4055void llama_memory_seq_keep ( 4056llama_memory_t mem , 4057llama_seq_id seq_id ) { 4058if (!mem ) { 4059return ; 4060 } 4061 4062mem -> seq_keep (seq_id ); 4063} 4064 4065void llama_memory_seq_add ( 4066llama_memory_t mem , 4067llama_seq_id seq_id , 4068llama_pos p0 , 4069llama_pos p1 , 4070llama_pos delta ) { 4071if (!mem ) { 4072return ; 4073 } 4074 4075mem -> seq_add (seq_id ,p0 ,p1 ,delta ); 4076} 4077 4078void llama_memory_seq_div ( 4079llama_memory_t mem , 4080llama_seq_id seq_id , 4081llama_pos p0 , 4082llama_pos p1 , 4083int d ) { 4084if (!mem ) { 4085return ; 4086 } 4087 4088mem -> seq_div (seq_id ,p0 ,p1 ,d ); 4089} 4090 4091llama_pos llama_memory_seq_pos_min ( 4092llama_memory_t mem , 4093llama_seq_id seq_id ) { 4094if (!mem ) { 4095return -1 ; 4096 } 4097 4098return mem -> seq_pos_min (seq_id ); 4099} 4100 4101llama_pos llama_memory_seq_pos_max ( 4102llama_memory_t mem , 4103llama_seq_id seq_id ) { 4104if (!mem ) { 4105return -1 ; 4106 } 4107 4108return mem -> seq_pos_max (seq_id ); 4109} 4110 4111bool llama_memory_can_shift (llama_memory_t mem ) { 4112if (!mem ) { 4113return false; 4114 } 4115 4116return mem -> get_can_shift (); 4117} 4118 4119// llama state API 4120 4121// deprecated 4122size_t llama_get_state_size (llama_context * ctx ) { 4123return llama_state_get_size (ctx ); 4124} 4125 4126// deprecated 4127size_t llama_copy_state_data (llama_context * ctx ,uint8_t * dst ) { 4128return llama_state_get_data (ctx ,dst ,-1 ); 4129} 4130 4131// deprecated 4132size_t llama_set_state_data (llama_context * ctx ,const uint8_t * src ) { 4133return llama_state_set_data (ctx ,src ,-1 ); 4134} 4135 4136// deprecated 4137bool llama_load_session_file (llama_context * ctx ,const char * path_session ,llama_token * tokens_out ,size_t n_token_capacity ,size_t * n_token_count_out ) { 4138return llama_state_load_file (ctx ,path_session ,tokens_out ,n_token_capacity ,n_token_count_out ); 4139} 4140 4141// deprecated 4142bool llama_save_session_file (llama_context * ctx ,const char * path_session ,const llama_token * tokens ,size_t n_token_count ) { 4143return llama_state_save_file (ctx ,path_session ,tokens ,n_token_count ); 4144} 4145 4146// Returns the *actual* size of the state. 4147// Intended to be used when saving to state to a buffer. 4148size_t llama_state_get_size (llama_context * ctx ) { 4149return ctx -> state_get_size (); 4150} 4151 4152size_t llama_state_get_data (llama_context * ctx ,uint8_t * dst ,size_t size ) { 4153ctx -> synchronize (); 4154 4155return ctx -> state_get_data (dst ,size ); 4156} 4157 4158// Sets the state reading from the specified source address 4159size_t llama_state_set_data (llama_context * ctx ,const uint8_t * src ,size_t size ) { 4160ctx -> synchronize (); 4161 4162return ctx -> state_set_data (src ,size ); 4163} 4164 4165bool llama_state_load_file (llama_context * ctx ,const char * path_session ,llama_token * tokens_out ,size_t n_token_capacity ,size_t * n_token_count_out ) { 4166ctx -> synchronize (); 4167 4168try { 4169return ctx -> state_load_file (path_session ,tokens_out ,n_token_capacity ,n_token_count_out ); 4170 }catch (const std::exception & err ) { 4171LLAMA_LOG_ERROR ("%s: error loading session file: %s\n" ,__func__ ,err .what ()); 4172return false; 4173 } 4174} 4175 4176bool llama_state_save_file (llama_context * ctx ,const char * path_session ,const llama_token * tokens ,size_t n_token_count ) { 4177ctx -> synchronize (); 4178 4179try { 4180return ctx -> state_save_file (path_session ,tokens ,n_token_count ); 4181 }catch (const std::exception & err ) { 4182LLAMA_LOG_ERROR ("%s: error saving session file: %s\n" ,__func__ ,err .what ()); 4183return false; 4184 } 4185} 4186 4187size_t llama_state_seq_get_size (llama_context * ctx ,llama_seq_id seq_id ) { 4188return llama_state_seq_get_size_ext (ctx ,seq_id ,0 ); 4189} 4190 4191size_t llama_state_seq_get_data (llama_context * ctx ,uint8_t * dst ,size_t size ,llama_seq_id seq_id ) { 4192return llama_state_seq_get_data_ext (ctx ,dst ,size ,seq_id ,0 ); 4193} 4194 4195size_t llama_state_seq_set_data (llama_context * ctx ,const uint8_t * src ,size_t size ,llama_seq_id seq_id ) { 4196return llama_state_seq_set_data_ext (ctx ,src ,size ,seq_id ,0 ); 4197} 4198 4199size_t llama_state_seq_get_size_ext (llama_context * ctx ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 4200return ctx -> state_seq_get_size (seq_id ,flags ); 4201} 4202 4203size_t llama_state_seq_get_data_ext (llama_context * ctx ,uint8_t * dst ,size_t size ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 4204ctx -> synchronize (); 4205 4206return ctx -> state_seq_get_data (seq_id ,dst ,size ,flags ); 4207} 4208size_t llama_state_seq_set_data_ext (llama_context * ctx ,const uint8_t * src ,size_t size ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 4209ctx -> synchronize (); 4210 4211return ctx -> state_seq_set_data (seq_id ,src ,size ,flags ); 4212} 4213 4214size_t llama_state_seq_save_file (llama_context * ctx ,const char * filepath ,llama_seq_id seq_id ,const llama_token * tokens ,size_t n_token_count ) { 4215ctx -> synchronize (); 4216 4217try { 4218return ctx -> state_seq_save_file (seq_id ,filepath ,tokens ,n_token_count ); 4219 }catch (const std::exception & err ) { 4220LLAMA_LOG_ERROR ("%s: error saving sequence state file: %s\n" ,__func__ ,err .what ()); 4221return 0 ; 4222 } 4223} 4224 4225size_t llama_state_seq_load_file (llama_context * ctx ,const char * filepath ,llama_seq_id dest_seq_id ,llama_token * tokens_out ,size_t n_token_capacity ,size_t * n_token_count_out ) { 4226ctx -> synchronize (); 4227 4228try { 4229return ctx -> state_seq_load_file (dest_seq_id ,filepath ,tokens_out ,n_token_capacity ,n_token_count_out ); 4230 }catch (const std::exception & err ) { 4231LLAMA_LOG_ERROR ("%s: error loading sequence state file: %s\n" ,__func__ ,err .what ()); 4232return 0 ; 4233 } 4234} 4235 4236/// 4237 4238int32_t llama_encode ( 4239llama_context * ctx , 4240llama_batch batch ) { 4241const int ret = ctx -> encode (batch ); 4242if (ret != 0 ) { 4243LLAMA_LOG_ERROR ("%s: failed to encode, ret = %d\n" ,__func__ ,ret ); 4244 } 4245 4246return ret ; 4247} 4248 4249int32_t llama_decode ( 4250llama_context * ctx , 4251llama_batch batch ) { 4252const int ret = ctx -> decode (batch ); 4253if (ret != 0 && ret != 1 ) { 4254LLAMA_LOG_ERROR ("%s: failed to decode, ret = %d\n" ,__func__ ,ret ); 4255 } 4256 4257return ret ; 4258} 4259 4260// 4261// perf 4262// 4263 4264llama_perf_context_data llama_perf_context (const llama_context * ctx ) { 4265llama_perf_context_data data = {}; 4266 4267if (ctx == nullptr ) { 4268return data ; 4269 } 4270 4271data = ctx -> perf_get_data (); 4272 4273return data ; 4274} 4275 4276void llama_perf_context_print (const llama_context * ctx ) { 4277const auto data = llama_perf_context (ctx ); 4278 4279const double t_end_ms = 1e-3 * ggml_time_us (); 4280 4281LLAMA_LOG_INFO ("%s: load time = %10.2f ms\n" ,__func__ ,data .t_load_ms ); 4282LLAMA_LOG_INFO ("%s: prompt eval time = %10.2f ms / %5d tokens (%8.2f ms per token, %8.2f tokens per second)\n" , 4283__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 ); 4284LLAMA_LOG_INFO ("%s: eval time = %10.2f ms / %5d runs (%8.2f ms per token, %8.2f tokens per second)\n" , 4285__func__ ,data .t_eval_ms ,data .n_eval ,data .t_eval_ms /data .n_eval ,1e3 /data .t_eval_ms * data .n_eval ); 4286LLAMA_LOG_INFO ("%s: total time = %10.2f ms / %5d tokens\n" ,__func__ , (t_end_ms - data .t_start_ms ), (data .n_p_eval + data .n_eval )); 4287LLAMA_LOG_INFO ("%s: graphs reused = %10d\n" ,__func__ ,data .n_reused ); 4288} 4289 4290void llama_perf_context_reset (llama_context * ctx ) { 4291ctx -> perf_reset (); 4292} 4293 4294// 4295// training 4296// 4297 4298bool llama_opt_param_filter_all (const struct ggml_tensor * tensor ,void * userdata ) { 4299GGML_UNUSED (tensor ); 4300GGML_UNUSED (userdata ); 4301return true; 4302} 4303 4304void llama_opt_init (struct llama_context * ctx ,struct llama_model * model ,struct llama_opt_params lopt_params ) { 4305ctx -> opt_init (model ,lopt_params ); 4306} 4307 4308void llama_opt_epoch ( 4309struct llama_context * ctx , 4310ggml_opt_dataset_t dataset , 4311ggml_opt_result_t result_train , 4312ggml_opt_result_t result_eval , 4313int64_t idata_split , 4314ggml_opt_epoch_callback callback_train , 4315ggml_opt_epoch_callback callback_eval ) { 4316ctx -> opt_epoch ( 4317dataset , 4318result_train , 4319result_eval , 4320idata_split , 4321callback_train , 4322callback_eval ); 4323} 4324 4325// 4326// ext 4327// 4328 4329llama_memory_breakdown llama_get_memory_breakdown (const struct llama_context * ctx ) { 4330return ctx -> memory_breakdown (); 4331} 4332 4333llama_context * llama_get_ctx_other (struct llama_context * ctx ) { 4334return ctx -> get_cparams ().ctx_other ; 4335}