char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
bf0a29cc1
char/aliceai-t5-moe
1#include "llama-kv-cache-dsv4.h" 2 3#include "ggml-backend.h" 4#include "llama-impl.h" 5#include "llama-batch.h" 6#include "llama-io.h" 7#include "llama-model.h" 8 9#include <algorithm> 10#include <cassert> 11#include <climits> 12#include <cstdlib> 13#include <cstring> 14#include <map> 15#include <sstream> 16#include <stdexcept> 17 18static constexpr uint32_t DSV4_CSA_RATIO = 4 ; 19static constexpr uint32_t DSV4_HCA_RATIO = 128 ; 20 21static constexpr uint32_t DSV4_STATE_MAGIC = 0x34565344 ;// DSV4 22static constexpr uint32_t DSV4_STATE_VERSION = 1 ; 23static constexpr uint32_t DSV4_STATE_MODE_FULL = 0 ; 24static constexpr uint32_t DSV4_STATE_MODE_PARTIAL = 1 ; 25static constexpr uint32_t DSV4_K_CACHE_STATE_VER = 2 ; 26static constexpr uint32_t DSV4_COMP_STATE_VER = 1 ; 27 28static uint32_t dsv4_comp_size (uint32_t kv_size ,uint32_t ratio ) { 29return std::max < uint32_t > (1 , (kv_size + ratio - 1 )/ratio ); 30} 31 32static void dsv4_clear_tensor_stream (ggml_tensor * tensor ,uint32_t stream ) { 33GGML_ASSERT (ggml_is_contiguous (tensor )); 34GGML_ASSERT (tensor -> ne [3 ]== 1 ); 35GGML_ASSERT (stream < (uint32_t )tensor -> ne [2 ]); 36 37const size_t stream_size = tensor -> nb [2 ]; 38ggml_backend_tensor_memset (tensor ,0 ,stream * stream_size ,stream_size ); 39} 40 41static uint32_t dsv4_state_n_used_k_rows (llama_pos pos_max ,uint32_t ratio ,uint32_t kv_size ) { 42if (pos_max < 0 ) { 43return 0 ; 44 } 45 46const uint64_t n_rows = ((uint64_t )pos_max + 1 )/ratio ; 47 48return (uint32_t ) std::min < uint64_t > (kv_size ,n_rows ); 49} 50 51static int64_t dsv4_stream_offset (uint32_t n_stream ,llama_seq_id seq_id ,uint32_t size ) { 52if (n_stream <=1 ) { 53return 0 ; 54 } 55if (seq_id < 0 || (uint32_t )seq_id >=n_stream ) { 56throw std::runtime_error ("DSV4 sequence id out of stream range" ); 57 } 58 59return (int64_t )seq_id * size ; 60} 61 62static bool dsv4_ubatch_has_coupled (const llama_ubatch & ubatch ) { 63for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 64if (ubatch .n_seq_id [i ]> 1 ) { 65return true; 66 } 67 } 68 69return false; 70} 71 72static bool dsv4_token_has_seq (const llama_ubatch & ubatch ,uint32_t i ,llama_seq_id seq_id ) { 73for (int32_t s = 0 ;s < ubatch .n_seq_id [i ];++ s ) { 74if (ubatch .seq_id [i ][s ]== seq_id ) { 75return true; 76 } 77 } 78 79return false; 80} 81 82static llama_ubatch dsv4_build_raw_write_ubatch (const llama_ubatch & ubatch ) { 83if (!dsv4_ubatch_has_coupled (ubatch )) { 84return ubatch ; 85 } 86if (ubatch .embd ) { 87throw std::runtime_error ("DSV4 coupled embedding ubatches are not supported" ); 88 } 89 90 std::vector < uint32_t > counts (ubatch .n_seqs_unq ,0 ); 91uint32_t n_tokens = 0 ; 92for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 93const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 94for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 95if (dsv4_token_has_seq (ubatch ,i ,seq_id )) { 96++ counts [s ]; 97++ n_tokens ; 98 } 99 } 100 } 101 102if (n_tokens == 0 ) { 103return ubatch ; 104 } 105 106const uint32_t n_seq_tokens = counts [0 ]; 107for (uint32_t s = 1 ;s < counts .size ();++ s ) { 108if (counts [s ]!= n_seq_tokens ) { 109throw std::runtime_error ("DSV4 coupled raw writes require equal sequence lengths" ); 110 } 111 } 112 113auto data = std::make_shared < llama_ubatch::data_t > (); 114data -> pos .resize ((size_t )n_tokens * ubatch .n_pos ); 115data -> n_seq_id .reserve (n_tokens ); 116data -> seq_id .reserve (n_tokens ); 117data -> seq_id_data .reserve (n_tokens ); 118data -> seq_id_unq .assign (ubatch .seq_id_unq ,ubatch .seq_id_unq + ubatch .n_seqs_unq ); 119data -> seq_idx .assign (LLAMA_MAX_SEQ ,-1 ); 120data -> output .assign (n_tokens ,0 ); 121if (ubatch .token ) { 122data -> token .reserve (n_tokens ); 123 } 124 125for (uint32_t s = 0 ;s < data -> seq_id_unq .size ();++ s ) { 126data -> seq_idx [data -> seq_id_unq [s ]]= s ; 127 } 128 129for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 130const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 131for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 132if (!dsv4_token_has_seq (ubatch ,i ,seq_id )) { 133continue ; 134 } 135 136const uint32_t dst = data -> n_seq_id .size (); 137if (ubatch .token ) { 138data -> token .push_back (ubatch .token [i ]); 139 } 140for (uint32_t p = 0 ;p < ubatch .n_pos ;++ p ) { 141data -> pos [(size_t )p * n_tokens + dst ]= ubatch .pos [(size_t )p * ubatch .n_tokens + i ]; 142 } 143data -> n_seq_id .push_back (1 ); 144data -> seq_id_data .push_back (seq_id ); 145 } 146 } 147 148for (uint32_t i = 0 ;i < n_tokens ;++ i ) { 149data -> seq_id .push_back (& data -> seq_id_data [i ]); 150 } 151 152llama_ubatch res { 153/*.b_equal_seqs =*/ true, 154/*.n_tokens =*/ n_tokens , 155/*.n_seq_tokens =*/ n_seq_tokens , 156/*.n_seqs =*/ ubatch .n_seqs_unq , 157/*.n_seqs_unq =*/ ubatch .n_seqs_unq , 158/*.n_pos =*/ ubatch .n_pos , 159/*.token =*/ data -> token .empty () ?nullptr :data -> token .data (), 160/*.embd =*/ nullptr , 161/*.pos =*/ data -> pos .data (), 162/*.n_seq_id =*/ data -> n_seq_id .data (), 163/*.seq_id =*/ data -> seq_id .data (), 164/*.seq_id_unq =*/ data -> seq_id_unq .data (), 165/*.seq_idx =*/ data -> seq_idx .data (), 166/*.output =*/ data -> output .data (), 167/*.data =*/ data , 168 }; 169 170return res ; 171} 172 173static std::vector < llama_ubatch > dsv4_build_raw_write_ubatches (const std::vector < llama_ubatch > & ubatches ) { 174 std::vector < llama_ubatch > res ; 175res .reserve (ubatches .size ()); 176for (const llama_ubatch & ubatch :ubatches ) { 177res .push_back (dsv4_build_raw_write_ubatch (ubatch )); 178 } 179return res ; 180} 181 182static bool dsv4_batch_has_coupled (const llama_batch & batch ) { 183if (!batch .n_seq_id ) { 184return false; 185 } 186 187for (int32_t i = 0 ;i < batch .n_tokens ;++ i ) { 188if (batch .n_seq_id [i ]> 1 ) { 189return true; 190 } 191 } 192 193return false; 194} 195 196static int64_t dsv4_comp_graph_n_stream (const llama_ubatch & ubatch ,uint32_t n_stream ) { 197// Coupled sequence sets must stay in one graph stream because their 198// compressed state is shared. Independent per-seq state can fan out. 199if (n_stream <=1 || ubatch .n_seqs_unq <=1 || dsv4_ubatch_has_coupled (ubatch )) { 200return 1 ; 201 } 202 203return ubatch .n_seqs_unq ; 204} 205 206static void dsv4_state_src_stream_range ( 207uint32_t n_stream , 208llama_seq_id seq_id , 209uint32_t & s0 , 210uint32_t & ns ) { 211if (seq_id >=0 && n_stream > 1 ) { 212if ((uint32_t )seq_id >=n_stream ) { 213throw std::runtime_error ("DSV4 state sequence id out of stream range" ); 214 } 215 216s0 = (uint32_t )seq_id ; 217ns = 1 ; 218return ; 219 } 220 221s0 = 0 ; 222ns = seq_id >=0 ?1 :n_stream ; 223} 224 225static void dsv4_state_dst_stream_range ( 226uint32_t n_stream , 227llama_seq_id seq_id , 228uint32_t ns , 229uint32_t & s0 ) { 230if (seq_id >=0 ) { 231if (ns != 1 ) { 232throw std::runtime_error ("DSV4 sequence state stream count mismatch" ); 233 } 234if (n_stream > 1 && (uint32_t )seq_id >=n_stream ) { 235throw std::runtime_error ("DSV4 state sequence id out of stream range" ); 236 } 237 238s0 = n_stream > 1 ? (uint32_t )seq_id :0 ; 239return ; 240 } 241 242if (ns != n_stream ) { 243throw std::runtime_error ("DSV4 full state stream count mismatch" ); 244 } 245 246s0 = 0 ; 247} 248 249static void dsv4_state_write_tensor_streams ( 250llama_io_write_i & io , 251ggml_tensor * tensor , 252uint32_t tensor_rows , 253uint32_t n_rows , 254uint32_t s0 , 255uint32_t ns , 256const std::vector < uint32_t > * stream_ids = nullptr ) { 257const int32_t type_i = (int32_t )tensor -> type ; 258const uint64_t ne0 = tensor -> ne [0 ]; 259const uint64_t rows = n_rows ; 260const uint64_t row_size = ggml_row_size (tensor -> type ,tensor -> ne [0 ]); 261 262if (n_rows > tensor_rows ) { 263throw std::runtime_error ("DSV4 state tensor row count exceeds storage" ); 264 } 265 266io .write (& type_i ,sizeof (type_i )); 267io .write (& ne0 ,sizeof (ne0 )); 268io .write (& rows ,sizeof (rows )); 269io .write (& row_size ,sizeof (row_size )); 270 271const size_t stream_stride = (size_t )tensor_rows * row_size ; 272const size_t size = (size_t )n_rows * row_size ; 273if (size == 0 ) { 274return ; 275 } 276 277if (stream_ids && stream_ids -> size ()!= ns ) { 278throw std::runtime_error ("DSV4 state tensor stream map size mismatch" ); 279 } 280 281for (uint32_t s = 0 ;s < ns ;++ s ) { 282const uint32_t stream = stream_ids ? (* stream_ids )[s ] :s0 + s ; 283if ((int64_t )stream >=tensor -> ne [2 ]) { 284throw std::runtime_error ("DSV4 state tensor stream out of range" ); 285 } 286const size_t offset = (size_t )stream * stream_stride ; 287io .write_tensor (tensor ,offset ,size ); 288 } 289} 290 291static void dsv4_state_read_tensor_streams ( 292llama_io_read_i & io , 293ggml_tensor * tensor , 294uint32_t tensor_rows , 295uint32_t n_rows , 296uint32_t s0 , 297uint32_t ns ) { 298int32_t type_i_ref ; 299uint64_t ne0_ref ; 300uint64_t rows_ref ; 301uint64_t row_size_ref ; 302 303io .read (& type_i_ref ,sizeof (type_i_ref )); 304io .read (& ne0_ref ,sizeof (ne0_ref )); 305io .read (& rows_ref ,sizeof (rows_ref )); 306io .read (& row_size_ref ,sizeof (row_size_ref )); 307 308const int32_t type_i = (int32_t )tensor -> type ; 309const uint64_t ne0 = tensor -> ne [0 ]; 310const uint64_t rows = n_rows ; 311const uint64_t row_size = ggml_row_size (tensor -> type ,tensor -> ne [0 ]); 312 313if (type_i != type_i_ref || ne0 != ne0_ref || rows != rows_ref || row_size != row_size_ref ) { 314throw std::runtime_error ("DSV4 state tensor metadata mismatch" ); 315 } 316if (n_rows > tensor_rows ) { 317throw std::runtime_error ("DSV4 state tensor row count exceeds storage" ); 318 } 319 320const size_t stream_stride = (size_t )tensor_rows * row_size ; 321const size_t size = (size_t )n_rows * row_size ; 322if (size == 0 ) { 323return ; 324 } 325 326for (uint32_t s = 0 ;s < ns ;++ s ) { 327const size_t offset = (size_t ) (s0 + s )* stream_stride ; 328io .read_tensor (tensor ,offset ,size ); 329 } 330} 331 332static void dsv4_state_write_k_cache ( 333llama_io_write_i & io , 334const llama_kv_cache * kv , 335llama_seq_id seq_id , 336llama_state_seq_flags flags , 337uint32_t n_rows ) { 338GGML_UNUSED (flags ); 339 340uint32_t s0 ; 341uint32_t ns ; 342dsv4_state_src_stream_range (kv -> get_n_stream (),seq_id ,s0 ,ns ); 343 344const uint32_t version = DSV4_K_CACHE_STATE_VER ; 345const uint32_t kv_size = kv -> get_size (); 346const auto layer_ids = kv -> get_layer_ids (); 347const uint32_t n_layer = layer_ids .size (); 348 349if (n_rows > kv_size ) { 350throw std::runtime_error ("DSV4 K-cache state row count exceeds cache size" ); 351 } 352 353io .write (& version ,sizeof (version )); 354io .write (& n_rows ,sizeof (n_rows )); 355io .write (& ns ,sizeof (ns )); 356io .write (& n_layer ,sizeof (n_layer )); 357 358for (uint32_t il :layer_ids ) { 359io .write (& il ,sizeof (il )); 360dsv4_state_write_tensor_streams (io ,kv -> get_k_storage (il ),kv_size ,n_rows ,s0 ,ns ); 361 } 362} 363 364static void dsv4_state_read_k_cache ( 365llama_io_read_i & io , 366llama_kv_cache * kv , 367llama_seq_id seq_id , 368llama_state_seq_flags flags ) { 369GGML_UNUSED (flags ); 370 371uint32_t version ; 372uint32_t n_rows_ref ; 373uint32_t ns ; 374uint32_t n_layer_ref ; 375 376io .read (& version ,sizeof (version )); 377io .read (& n_rows_ref ,sizeof (n_rows_ref )); 378io .read (& ns ,sizeof (ns )); 379io .read (& n_layer_ref ,sizeof (n_layer_ref )); 380 381if (version != 1 && version != DSV4_K_CACHE_STATE_VER ) { 382throw std::runtime_error ("DSV4 K-cache state version mismatch" ); 383 } 384 385const uint32_t kv_size = kv -> get_size (); 386if (version == 1 && n_rows_ref != kv_size ) { 387LLAMA_LOG_INFO ("kv size ref %d kv %d\n" ,n_rows_ref ,kv_size ); 388throw std::runtime_error ("DSV4 K-cache state size mismatch" ); 389 } 390if (n_rows_ref > kv_size ) { 391LLAMA_LOG_INFO ("kv rows ref %d kv %d\n" ,n_rows_ref ,kv_size ); 392throw std::runtime_error ("DSV4 K-cache state size mismatch" ); 393 } 394 395uint32_t s0 ; 396dsv4_state_dst_stream_range (kv -> get_n_stream (),seq_id ,ns ,s0 ); 397 398const auto layer_ids = kv -> get_layer_ids (); 399if (n_layer_ref != layer_ids .size ()) { 400throw std::runtime_error ("DSV4 K-cache layer count mismatch" ); 401 } 402 403for (uint32_t il :layer_ids ) { 404uint32_t il_ref ; 405io .read (& il_ref ,sizeof (il_ref )); 406if (il_ref != il ) { 407throw std::runtime_error ("DSV4 K-cache layer id mismatch" ); 408 } 409 410dsv4_state_read_tensor_streams (io ,kv -> get_k_storage (il ),kv_size ,n_rows_ref ,s0 ,ns ); 411 } 412} 413 414static std::string dsv4_plan_positions (const std::vector < int32_t > & values ) { 415 std::ostringstream ss ; 416ss <<"[" ; 417for (size_t i = 0 ;i < values .size ();++ i ) { 418if (i > 0 ) { 419ss <<", " ; 420 } 421ss <<values [i ]; 422 } 423ss <<"]" ; 424return ss .str (); 425} 426 427static llama_kv_cache_dsv4_context::comp_plan dsv4_build_comp_plan ( 428const llama_ubatch & ubatch , 429uint32_t ratio , 430bool overlap , 431uint32_t state_size , 432uint32_t kv_size , 433uint32_t n_stream , 434uint32_t n_rs_seq , 435const std::vector < uint32_t > & rs_idx ) { 436 llama_kv_cache_dsv4_context::comp_plan plan ; 437plan .n_visible .resize (ubatch .n_tokens ); 438plan .n_stream = dsv4_comp_graph_n_stream (ubatch ,n_stream ); 439 440// n_stream is the persistent cache/state layout; plan.n_stream is the 441// graph view for this ubatch and can be a subset of those streams. 442if (n_stream <=1 && ubatch .n_seqs_unq > 1 ) { 443throw std::runtime_error ("DSV4 single compressed stream cannot serve multiple sequences" ); 444 } 445 446const int64_t state_rows = (int64_t )state_size * n_stream ; 447 448struct persist_row { 449int32_t dst ; 450int32_t src ; 451llama_pos pos ; 452 }; 453 454 std::vector < persist_row > persist_rows ; 455 456// For the overlap compressor, build_overlap_compressed_kv_from_state() consumes 457// state_read_idxs as two contiguous halves: the first ratio*n_blocks entries are 458// the "previous-window" gather indices for every block, followed by the 459// "current-window" indices for every block. Collect them separately here and 460// append cur after prev once the loop has visited all completed blocks 461 std::vector < int32_t > overlap_prev_reads ; 462 std::vector < int32_t > overlap_cur_reads ; 463 464 std::map < std::pair < llama_seq_id ,llama_pos > ,int64_t > curr_token_idx_map ; 465 std::map < llama_seq_id ,uint32_t > state_write_counts ; 466 467for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 468for (int32_t s = 0 ;s < ubatch .n_seq_id [i ];++ s ) { 469curr_token_idx_map [std::make_pair (ubatch .seq_id [i ][s ],ubatch .pos [i ])]= i ; 470 } 471 } 472 473const auto state_source_idx = [& ](llama_seq_id seq_id ,llama_pos pos )-> int32_t { 474if (pos < 0 ) { 475// The overlap compressor needs a zero/-inf source for the first 476// block's previous half. The graph appends that row after the 477// current-ubatch scratch rows. 478return (int32_t ) (state_rows + ubatch .n_tokens ); 479 } 480 481const auto key = std::make_pair (seq_id ,pos ); 482if (curr_token_idx_map .find (key )!= curr_token_idx_map .end ()) { 483return (int32_t ) (state_rows + curr_token_idx_map .at (key )); 484 } 485 486const int64_t stream_off = dsv4_stream_offset (n_stream ,seq_id ,state_size ); 487return (int32_t ) (stream_off + pos %state_size ); 488 }; 489 490for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 491const llama_pos pos = ubatch .pos [i ]; 492 493if (pos < 0 ) { 494continue ; 495 } 496 497plan .state_pos .push_back ((int32_t ) (pos %ratio )); 498 499const int64_t n_visible = (int64_t ) (pos + 1 )/ratio ; 500plan .n_visible [i ]= (int32_t )n_visible ; 501plan .n_kv = std::max (plan .n_kv ,n_visible ); 502 503for (int32_t s = 0 ;s < ubatch .n_seq_id [i ];++ s ) { 504const llama_seq_id seq_id = ubatch .seq_id [i ][s ]; 505const int64_t stream_off = dsv4_stream_offset (n_stream ,seq_id ,state_size ); 506const int32_t state_idx = (int32_t ) (stream_off + pos %state_size ); 507 508const auto it = std::find_if (persist_rows .begin (),persist_rows .end (), 509 [state_idx ](const persist_row & row ) { 510return row .dst == state_idx ; 511 }); 512if (it == persist_rows .end ()) { 513persist_rows .push_back ({state_idx , (int32_t )i ,pos }); 514 }else if (pos > it -> pos ) { 515it -> src = (int32_t )i ; 516it -> pos = pos ; 517 } 518 519if ((pos + 1 ) %ratio != 0 ) { 520continue ; 521 } 522 523const llama_pos source_start = pos + 1 - ratio ; 524const int64_t cache_off = dsv4_stream_offset (n_stream ,seq_id ,kv_size ); 525 526plan .state_write_idxs .push_back (cache_off + pos /ratio ); 527plan .state_write_pos .push_back ((int32_t )source_start ); 528++ state_write_counts [seq_id ]; 529 530if (overlap ) { 531const llama_pos prev_start = source_start - ratio ; 532 533for (uint32_t j = 0 ;j < ratio ;++ j ) { 534overlap_prev_reads .push_back (state_source_idx (seq_id ,prev_start + j )); 535 } 536for (uint32_t j = 0 ;j < ratio ;++ j ) { 537overlap_cur_reads .push_back (state_source_idx (seq_id ,source_start + j )); 538 } 539 }else { 540for (uint32_t j = 0 ;j < ratio ;++ j ) { 541plan .state_read_idxs .push_back (state_source_idx (seq_id ,source_start + j )); 542 } 543 } 544 } 545 } 546 547if (ratio == DSV4_CSA_RATIO && !plan .state_pos .empty ()) { 548assert (kv_size > 0 ); 549 550// Pad each stream to the reserve plan's block count. 551const auto append_dummy_block = [& ](llama_seq_id seq_id ,uint32_t i ) { 552const int64_t cache_off = dsv4_stream_offset (n_stream ,seq_id ,kv_size ); 553const int32_t source_idx = state_source_idx (seq_id ,ubatch .pos [i ]); 554 555plan .state_write_idxs .push_back (cache_off + kv_size - 1 ); 556plan .state_write_pos .push_back (0 ); 557 558if (overlap ) { 559for (uint32_t j = 0 ;j < ratio ;++ j ) { 560overlap_prev_reads .push_back (source_idx ); 561overlap_cur_reads .push_back (source_idx ); 562 } 563 }else { 564for (uint32_t j = 0 ;j < ratio ;++ j ) { 565plan .state_read_idxs .push_back (source_idx ); 566 } 567 } 568 }; 569 570if (dsv4_ubatch_has_coupled (ubatch )) { 571if (plan .state_write_idxs .empty ()) { 572uint32_t i = 0 ; 573while (i < ubatch .n_tokens && ubatch .pos [i ]< 0 ) { 574++ i ; 575 } 576assert (i < ubatch .n_tokens ); 577append_dummy_block (ubatch .seq_id [i ][0 ],i ); 578 } 579 }else { 580const uint32_t n_blocks = (std::max < uint32_t > (1 ,ubatch .n_seq_tokens )+ ratio - 1 )/ratio ; 581 582for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 583const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 584const uint32_t n_writes = state_write_counts [seq_id ]; 585if (n_writes >=n_blocks ) { 586continue ; 587 } 588if (n_writes + 1 != n_blocks ) { 589throw std::runtime_error ("DSV4 CSA sequence positions are not contiguous" ); 590 } 591 592uint32_t i = 0 ; 593while (i < ubatch .n_tokens && (ubatch .pos [i ]< 0 || !dsv4_token_has_seq (ubatch ,i ,seq_id ))) { 594++ i ; 595 } 596assert (i < ubatch .n_tokens ); 597append_dummy_block (seq_id ,i ); 598 } 599 } 600 } 601 602if (ratio == DSV4_HCA_RATIO && !plan .state_pos .empty ()&& plan .state_write_idxs .empty ()) { 603assert (kv_size > 0 ); 604// the last slot must not be live, or the dummy write would corrupt it; 605// a full stream implies a completed block, which implies real writes 606assert (plan .n_kv < (int64_t )kv_size ); 607 608// Keep the compress/write ops in the graph when no HCA block completes 609// in this ubatch. The dummy block writes to the last cache slot and is 610// masked out. 611uint32_t i = 0 ; 612while (i < ubatch .n_tokens && ubatch .pos [i ]< 0 ) { 613++ i ; 614 } 615assert (i < ubatch .n_tokens ); 616 617const llama_seq_id seq_id = ubatch .seq_id [i ][0 ]; 618const int64_t cache_off = dsv4_stream_offset (n_stream ,seq_id ,kv_size ); 619const int32_t source_idx = state_source_idx (seq_id ,ubatch .pos [i ]); 620 621plan .state_write_idxs .push_back (cache_off + kv_size - 1 ); 622plan .state_write_pos .push_back (0 ); 623 624for (uint32_t j = 0 ;j < ratio ;++ j ) { 625plan .state_read_idxs .push_back (source_idx ); 626 } 627 } 628 629if (overlap ) { 630// [ all blocks' prev-window indices | all blocks' cur-window indices ] 631plan .state_read_idxs .reserve (overlap_prev_reads .size ()+ overlap_cur_reads .size ()); 632plan .state_read_idxs .insert (plan .state_read_idxs .end (), 633overlap_prev_reads .begin (),overlap_prev_reads .end ()); 634plan .state_read_idxs .insert (plan .state_read_idxs .end (), 635overlap_cur_reads .begin (),overlap_cur_reads .end ()); 636 } 637 638// Keep the mask (and with it the compressed-attention branch) present even 639// before the first block is visible, so the graph topology never changes. 640// Padded slots are masked out; comp cache buffers are zero-initialized. 641plan .n_kv = std::max < int64_t > (GGML_PAD (plan .n_kv ,256u ),256 ); 642 643 std::sort (persist_rows .begin (),persist_rows .end (), 644 [](const persist_row & a ,const persist_row & b ) { 645return a .dst < b .dst ; 646 }); 647 648for (const persist_row & row :persist_rows ) { 649plan .state_persist_src_idxs .push_back (row .src ); 650plan .state_persist_dst_idxs .push_back (row .dst ); 651 } 652 653if (n_rs_seq > 0 ) { 654// Emit restore/snapshot entries for all layout streams so that the 655// graph tensor sizes do not depend on the ubatch's sequence count. 656// Streams not present in the ubatch get no-op entries. 657for (uint32_t stream = 0 ;stream < n_stream ;++ stream ) { 658llama_seq_id seq_id = -1 ; 659if (n_stream == 1 ) { 660// a unified stream serves any single sequence 661seq_id = ubatch .n_seqs_unq > 0 ?ubatch .seq_id_unq [0 ] :-1 ; 662 }else { 663for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 664if (ubatch .seq_id_unq [s ]== (llama_seq_id )stream ) { 665seq_id = ubatch .seq_id_unq [s ]; 666break ; 667 } 668 } 669 } 670 671const int64_t stream_off = (int64_t )stream * state_size ; 672const uint32_t rollback = seq_id >=0 && (uint32_t )seq_id < rs_idx .size () ?rs_idx [seq_id ] :0 ; 673// Keep the restore graph fixed-width when no rollback is pending. 674const int64_t src_plane = rollback > 0 && rollback <=n_rs_seq ? (int64_t )rollback * state_rows :0 ; 675for (uint32_t r = 0 ;r < state_size ;++ r ) { 676plan .state_restore_src_idxs .push_back ((int32_t ) (src_plane + stream_off + r )); 677plan .state_restore_dst_idxs .push_back ((int32_t ) (stream_off + r )); 678 } 679 680 std::vector < uint32_t > token_idxs ; 681token_idxs .reserve (ubatch .n_tokens ); 682if (seq_id >=0 ) { 683for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 684if (dsv4_token_has_seq (ubatch ,i ,seq_id )) { 685token_idxs .push_back (i ); 686 } 687 } 688 } 689 690const uint32_t n_seq_tokens = (uint32_t )token_idxs .size (); 691const int64_t scratch_off = (int64_t )state_rows * (1 + n_rs_seq ); 692for (uint32_t d = 1 ;d <=n_rs_seq ;++ d ) { 693const int64_t dst_plane = (int64_t )d * state_rows ; 694const uint32_t prefix = d <=n_seq_tokens ?n_seq_tokens - d :0 ; 695 696for (uint32_t r = 0 ;r < state_size ;++ r ) { 697int32_t src = (int32_t ) (stream_off + r ); 698 699for (uint32_t j = 0 ;j < prefix ;++ j ) { 700const uint32_t i_tok = token_idxs [j ]; 701if (ubatch .pos [i_tok ] >=0 && (uint32_t ) (ubatch .pos [i_tok ]%state_size )== r ) { 702src = (int32_t ) (scratch_off + i_tok ); 703 } 704 } 705 706if (n_seq_tokens == 0 ) { 707// no-op: copy the snapshot plane onto itself 708src = (int32_t ) (dst_plane + stream_off + r ); 709 } 710 711plan .state_snapshot_src_idxs .push_back (src ); 712plan .state_snapshot_dst_idxs .push_back ((int32_t ) (dst_plane + stream_off + r )); 713 } 714 } 715 } 716 } 717 718static const bool debug = []() { 719const char * env = getenv ("LLAMA_DSV4_COMPRESS_DEBUG" ); 720return env && atoi (env )> 0 ; 721 }(); 722 723if (debug ) { 724LLAMA_LOG_DEBUG ("%s: ratio=%u, n_tokens=%u, n_seqs_unq=%u, state_persist_dst=%s, state_write_pos=%s\n" , 725__func__ ,ratio ,ubatch .n_tokens ,ubatch .n_seqs_unq , 726dsv4_plan_positions (plan .state_persist_dst_idxs ).c_str (), 727dsv4_plan_positions (plan .state_write_pos ).c_str ()); 728for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 729const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 730const uint32_t rollback = seq_id >=0 && (uint32_t )seq_id < rs_idx .size () ?rs_idx [seq_id ] :0 ; 731LLAMA_LOG_DEBUG ("%s: seq %d pos [%d, %d] rollback=%u\n" ,__func__ ,seq_id , 732ubatch .pos [0 ],ubatch .pos [ubatch .n_tokens - 1 ],rollback ); 733 } 734 } 735 736return plan ; 737} 738 739static std::vector < llama_kv_cache_dsv4_context::comp_plan > dsv4_build_comp_plans ( 740const std::vector < llama_ubatch > & ubatches , 741uint32_t ratio , 742bool overlap , 743uint32_t state_size , 744uint32_t kv_size , 745uint32_t n_stream , 746uint32_t n_rs_seq , 747const std::vector < uint32_t > & rs_idx ) { 748 std::vector < llama_kv_cache_dsv4_context::comp_plan > plans ; 749plans .reserve (ubatches .size ()); 750 751// the first ubatch touching a seq consumes its rollback restore 752 std::vector < uint32_t > rs (rs_idx ); 753for (const llama_ubatch & ubatch :ubatches ) { 754plans .push_back (dsv4_build_comp_plan (ubatch ,ratio ,overlap ,state_size ,kv_size ,n_stream ,n_rs_seq ,rs )); 755 756for (uint32_t s = 0 ;s < ubatch .n_seqs_unq ;++ s ) { 757const llama_seq_id seq_id = ubatch .seq_id_unq [s ]; 758if (seq_id >=0 && (size_t )seq_id < rs .size ()) { 759rs [seq_id ]= 0 ; 760 } 761 } 762 } 763 764return plans ; 765} 766 767static llama_kv_cache::slot_info_vec_t dsv4_build_comp_sinfos ( 768const std::vector < llama_ubatch > & ubatches , 769uint32_t n_stream ) { 770 llama_kv_cache::slot_info_vec_t sinfos ; 771sinfos .reserve (ubatches .size ()); 772 773for (const llama_ubatch & ubatch :ubatches ) { 774if (n_stream <=1 && ubatch .n_seqs_unq > 1 ) { 775throw std::runtime_error ("DSV4 single compressed stream cannot serve multiple sequences" ); 776 } 777 778const uint32_t ns = (uint32_t )dsv4_comp_graph_n_stream (ubatch ,n_stream ); 779 llama_kv_cache::slot_info sinfo ; 780sinfo .s0 = n_stream > 1 ?LLAMA_MAX_SEQ :0 ; 781sinfo .s1 = 0 ; 782sinfo .resize (ns ); 783 784for (uint32_t s = 0 ;s < ns ;++ s ) { 785const llama_seq_id seq_id = n_stream > 1 ?ubatch .seq_id_unq [s ] :0 ; 786const uint32_t strm = (uint32_t )dsv4_stream_offset (n_stream ,seq_id ,1 ); 787 788sinfo .s0 = std::min (sinfo .s0 ,strm ); 789sinfo .s1 = std::max (sinfo .s1 ,strm ); 790sinfo .strm [s ]= strm ; 791sinfo .idxs [s ].resize (1 ,0 ); 792 } 793 794if (n_stream > 1 && sinfo .s1 - sinfo .s0 + 1 != ns ) { 795throw std::runtime_error ("DSV4 compressed streams are not contiguous in ubatch" ); 796 } 797 798sinfos .push_back (std::move (sinfo )); 799 } 800 801return sinfos ; 802} 803 804static llama_kv_cache::slot_info_vec_t dsv4_build_raw_read_sinfos ( 805const llama_kv_cache::slot_info_vec_t & sinfos_write , 806const std::vector < llama_ubatch > & ubatches ) { 807 llama_kv_cache::slot_info_vec_t sinfos ; 808sinfos .reserve (ubatches .size ()); 809 810for (size_t i = 0 ;i < ubatches .size ();++ i ) { 811const llama_ubatch & ubatch = ubatches [i ]; 812const auto & sinfo_write = sinfos_write [i ]; 813 814if (!dsv4_ubatch_has_coupled (ubatch )) { 815sinfos .push_back (sinfo_write ); 816continue ; 817 } 818 819const llama_seq_id seq_id = ubatch .seq_id [0 ][0 ]; 820uint32_t i_stream = 0 ; 821for (;i_stream < sinfo_write .n_stream ();++ i_stream ) { 822if (sinfo_write .strm [i_stream ]== seq_id ) { 823break ; 824 } 825 } 826if (i_stream == sinfo_write .n_stream ()) { 827throw std::runtime_error ("DSV4 raw write stream not found for coupled read" ); 828 } 829 830 llama_kv_cache::slot_info sinfo ; 831sinfo .s0 = sinfo_write .strm [i_stream ]; 832sinfo .s1 = sinfo_write .strm [i_stream ]; 833sinfo .resize (1 ); 834sinfo .strm [0 ]= sinfo_write .strm [i_stream ]; 835sinfo .idxs [0 ]= sinfo_write .idxs [i_stream ]; 836sinfos .push_back (std::move (sinfo )); 837 } 838 839return sinfos ; 840} 841 842static llama_kv_cache_dsv4_context::comp_plan dsv4_build_reserve_comp_plan ( 843const llama_ubatch & ubatch , 844uint32_t ratio , 845bool overlap , 846uint32_t state_size , 847uint32_t kv_size , 848uint32_t n_stream , 849uint32_t n_rs_seq ) { 850 llama_kv_cache_dsv4_context::comp_plan plan ; 851plan .n_visible .resize (ubatch .n_tokens ); 852plan .n_stream = dsv4_comp_graph_n_stream (ubatch ,n_stream ); 853plan .n_kv = kv_size ; 854 855if (ubatch .n_tokens == 0 ) { 856return plan ; 857 } 858 859// worst case over every seq split: sum of per-seq ceil(tokens/ratio) is at 860// most floor(n_tokens/ratio) + n_seqs 861const uint32_t n_seqs = std::max < uint32_t > (1 ,ubatch .n_seqs ); 862const size_t n_blocks = (size_t )ubatch .n_tokens /ratio + n_seqs ; 863 864const uint64_t state_rows = (uint64_t )state_size * n_stream ; 865const size_t n_persist = (size_t ) std::min < uint64_t > (ubatch .n_tokens ,state_rows ); 866const size_t n_restore = n_rs_seq > 0 ? (size_t )state_size * n_stream :0 ; 867const size_t n_snapshot = (size_t )n_rs_seq * state_size * n_stream ; 868 869plan .state_pos .resize (ubatch .n_tokens ); 870plan .state_persist_src_idxs .resize (n_persist ); 871plan .state_persist_dst_idxs .resize (n_persist ); 872plan .state_restore_src_idxs .resize (n_restore ); 873plan .state_restore_dst_idxs .resize (n_restore ); 874plan .state_snapshot_src_idxs .resize (n_snapshot ); 875plan .state_snapshot_dst_idxs .resize (n_snapshot ); 876plan .state_read_idxs .resize ((overlap ?2u :1u )* ratio * n_blocks ); 877plan .state_write_idxs .resize (n_blocks ); 878plan .state_write_pos .resize (n_blocks ); 879 880return plan ; 881} 882 883static void dsv4_make_k_only (llama_hparams & hparams ) { 884// llama_kv_cache uses hparams.is_mla() to allocate K-only storage. 885hparams .n_embd_head_k_mla_impl = hparams .n_embd_head_k (); 886hparams .n_embd_head_v_mla_impl = hparams .n_embd_head_k (); 887} 888 889// 890// llama_dsv4_comp_state 891// 892 893llama_dsv4_comp_state::llama_dsv4_comp_state ( 894const llama_model & model , 895bool offload , 896bool unified , 897uint32_t n_seq_max , 898uint32_t ratio , 899uint32_t state_size , 900uint32_t n_embd_state , 901uint32_t n_rs_seq , 902const char * name , 903const llama_memory_i::layer_filter_cb & filter ) : 904ratio (ratio ), 905state_size (state_size ), 906n_embd_state (n_embd_state ), 907n_stream (unified ?1 :n_seq_max ), 908n_rs_seq (n_rs_seq ) { 909const llama_hparams & hparams = model .hparams ; 910 911struct ggml_backend_buft_comparator { 912bool operator()(const ggml_backend_buffer_type_t & lhs ,const ggml_backend_buffer_type_t & rhs )const { 913return strcmp (ggml_backend_buft_name (lhs ),ggml_backend_buft_name (rhs ))< 0 ; 914 } 915 }; 916 917 std::map < ggml_backend_buffer_type_t ,ggml_context_ptr ,ggml_backend_buft_comparator > ctx_map ; 918 919auto ctx_for_buft = [& ](ggml_backend_buffer_type_t buft )-> ggml_context * { 920auto it = ctx_map .find (buft ); 921if (it == ctx_map .end ()) { 922ggml_init_params params = { 923/*.mem_size =*/ size_t (2u * (1 + n_stream )* hparams .n_layer ()* ggml_tensor_overhead ()), 924/*.mem_buffer =*/ NULL , 925/*.no_alloc =*/ true, 926 }; 927 928ggml_context * ctx = ggml_init (params ); 929if (!ctx ) { 930return nullptr ; 931 } 932 933ctx_map .emplace (buft ,ctx ); 934 935return ctx ; 936 } 937 938return it -> second .get (); 939 }; 940 941for (uint32_t il = 0 ;il < hparams .n_layer ();++ il ) { 942if (filter && !filter (il )) { 943continue ; 944 } 945 946const char * dev_name = "CPU" ; 947 948ggml_backend_buffer_type_t buft = ggml_backend_cpu_buffer_type (); 949 950if (offload ) { 951auto * dev = model .dev_layer (il ); 952buft = ggml_backend_dev_buffer_type (dev ); 953 954dev_name = ggml_backend_dev_name (dev ); 955 } 956 957LLAMA_LOG_DEBUG ("%s: layer %3d: dev = %s\n" ,__func__ ,il ,dev_name ); 958 959ggml_context * ctx = ctx_for_buft (buft ); 960if (!ctx ) { 961throw std::runtime_error ("failed to create ggml context for DSV4 compressor state" ); 962 } 963 964const uint32_t n_planes = n_stream * (1 + n_rs_seq ); 965ggml_tensor * kv = ggml_new_tensor_3d (ctx ,GGML_TYPE_F32 ,n_embd_state ,state_size ,n_planes ); 966ggml_tensor * score = ggml_new_tensor_3d (ctx ,GGML_TYPE_F32 ,n_embd_state ,state_size ,n_planes ); 967 968ggml_format_name (kv ,"dsv4_%s_state_kv_l%d" ,name ,il ); 969ggml_format_name (score ,"dsv4_%s_state_score_l%d" ,name ,il ); 970 971 std::vector < ggml_tensor *> kv_stream ; 972 std::vector < ggml_tensor *> score_stream ; 973 974for (uint32_t s = 0 ;s < n_stream ;++ s ) { 975kv_stream .push_back (ggml_view_2d (ctx ,kv ,n_embd_state ,state_size ,kv -> nb [1 ],s * kv -> nb [2 ])); 976score_stream .push_back (ggml_view_2d (ctx ,score ,n_embd_state ,state_size ,score -> nb [1 ],s * score -> nb [2 ])); 977 } 978 979map_layer_ids [il ]= layers .size (); 980 981layers .push_back ({il ,kv ,score , std::move (kv_stream ), std::move (score_stream ) }); 982 } 983 984for (auto & [buft ,ctx ] :ctx_map ) { 985ggml_backend_buffer_t buf = ggml_backend_alloc_ctx_tensors_from_buft (ctx .get (),buft ); 986if (!buf ) { 987throw std::runtime_error ("failed to allocate buffer for DSV4 compressor state" ); 988 } 989 990ggml_backend_buffer_clear (buf ,0 ); 991 992LLAMA_LOG_INFO ("%s: %10s DSV4 %s state buffer size = %8.2f MiB\n" , 993__func__ ,ggml_backend_buffer_name (buf ),name ,ggml_backend_buffer_get_size (buf )/1024.0 /1024.0 ); 994 995ctxs_bufs .emplace_back (std::move (ctx ),buf ); 996 } 997 998LLAMA_LOG_INFO ("%s: %s ratio = %u, state = %u x %u, streams = %u, rs_seq = %u, layers = %zu, size = %7.2f MiB\n" , 999__func__ ,name ,ratio ,state_size ,n_embd_state ,n_stream ,n_rs_seq ,layers .size (),total_size ()/1024.0 /1024.0 ); 1000} 1001 1002void llama_dsv4_comp_state::clear (llama_seq_id seq_id ,bool data ) { 1003if (!data ) { 1004return ; 1005 } 1006 1007if (seq_id >=0 ) { 1008GGML_ASSERT ((uint32_t )seq_id < n_stream ); 1009 1010for (const auto & layer :layers ) { 1011for (uint32_t d = 0 ;d <=n_rs_seq ;++ d ) { 1012const uint32_t stream = d * n_stream + (uint32_t )seq_id ; 1013dsv4_clear_tensor_stream (layer .kv ,stream ); 1014dsv4_clear_tensor_stream (layer .score ,stream ); 1015 } 1016 } 1017return ; 1018 } 1019 1020for (auto & [_ ,buf ] :ctxs_bufs ) { 1021ggml_backend_buffer_clear (buf .get (),0 ); 1022 } 1023} 1024 1025void llama_dsv4_comp_state::seq_cp (llama_seq_id seq_id_src ,llama_seq_id seq_id_dst ) { 1026GGML_ASSERT (seq_id_src >=0 && (uint32_t )seq_id_src < n_stream ); 1027GGML_ASSERT (seq_id_dst >=0 && (uint32_t )seq_id_dst < n_stream ); 1028 1029if (seq_id_src == seq_id_dst ) { 1030return ; 1031 } 1032 1033clear (seq_id_dst , true); 1034 1035sc_info .ssrc .push_back ((uint32_t )seq_id_src ); 1036sc_info .sdst .push_back ((uint32_t )seq_id_dst ); 1037} 1038 1039void llama_dsv4_comp_state::apply_copies (const stream_copy_info & sc_info )const { 1040for (size_t i = 0 ;i < sc_info .ssrc .size ();++ i ) { 1041const uint32_t ssrc = sc_info .ssrc [i ]; 1042const uint32_t sdst = sc_info .sdst [i ]; 1043 1044for (const auto & layer :layers ) { 1045ggml_backend_tensor_copy (layer .kv_stream [ssrc ],layer .kv_stream [sdst ]); 1046ggml_backend_tensor_copy (layer .score_stream [ssrc ],layer .score_stream [sdst ]); 1047 } 1048 } 1049} 1050 1051uint32_t llama_dsv4_comp_state::get_ratio ()const { 1052return ratio ; 1053} 1054 1055uint32_t llama_dsv4_comp_state::get_state_size ()const { 1056return state_size ; 1057} 1058 1059uint32_t llama_dsv4_comp_state::get_n_stream ()const { 1060return n_stream ; 1061} 1062 1063uint32_t llama_dsv4_comp_state::get_n_rs_seq ()const { 1064return n_rs_seq ; 1065} 1066 1067uint32_t llama_dsv4_comp_state::get_n_rows ()const { 1068return state_size * n_stream ; 1069} 1070 1071std::map < ggml_backend_buffer_type_t ,size_t > llama_dsv4_comp_state::memory_breakdown ()const { 1072 std::map < ggml_backend_buffer_type_t ,size_t > ret ; 1073for (const auto & [_ ,buf ] :ctxs_bufs ) { 1074ggml_backend_buffer_type_t buft = ggml_backend_buffer_get_type (buf .get ()); 1075ret [buft ]+= ggml_backend_buffer_get_size (buf .get ()); 1076 } 1077return ret ; 1078} 1079 1080void llama_dsv4_comp_state::state_write ( 1081llama_io_write_i & io , 1082llama_seq_id seq_id , 1083llama_state_seq_flags flags , 1084const std::vector < uint32_t > & rs_idx )const { 1085GGML_UNUSED (flags ); 1086 1087uint32_t s0 ; 1088uint32_t ns ; 1089dsv4_state_src_stream_range (n_stream ,seq_id ,s0 ,ns ); 1090 1091 std::vector < uint32_t > stream_ids (ns ); 1092for (uint32_t s = 0 ;s < ns ;++ s ) { 1093const uint32_t seq = seq_id >=0 ? (uint32_t )seq_id :s0 + s ; 1094if (seq >=rs_idx .size ()|| rs_idx [seq ]> n_rs_seq ) { 1095throw std::runtime_error ("DSV4 recurrent state rollback index out of range" ); 1096 } 1097stream_ids [s ]= rs_idx [seq ]* n_stream + s0 + s ; 1098 } 1099 1100const uint32_t version = DSV4_COMP_STATE_VER ; 1101const uint32_t n_layer = layers .size (); 1102 1103io .write (& version ,sizeof (version )); 1104io .write (& ratio ,sizeof (ratio )); 1105io .write (& state_size ,sizeof (state_size )); 1106io .write (& n_embd_state ,sizeof (n_embd_state )); 1107io .write (& ns ,sizeof (ns )); 1108io .write (& n_layer ,sizeof (n_layer )); 1109 1110for (const auto & layer :layers ) { 1111io .write (& layer .il ,sizeof (layer .il )); 1112 1113dsv4_state_write_tensor_streams (io ,layer .kv ,state_size ,state_size ,s0 ,ns ,& stream_ids ); 1114dsv4_state_write_tensor_streams (io ,layer .score ,state_size ,state_size ,s0 ,ns ,& stream_ids ); 1115 } 1116} 1117 1118void llama_dsv4_comp_state::state_read (llama_io_read_i & io ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 1119GGML_UNUSED (flags ); 1120 1121uint32_t version ; 1122uint32_t ratio_ref ; 1123uint32_t state_size_ref ; 1124uint32_t n_embd_state_ref ; 1125uint32_t ns ; 1126uint32_t n_layer_ref ; 1127 1128io .read (& version ,sizeof (version )); 1129io .read (& ratio_ref ,sizeof (ratio_ref )); 1130io .read (& state_size_ref ,sizeof (state_size_ref )); 1131io .read (& n_embd_state_ref ,sizeof (n_embd_state_ref )); 1132io .read (& ns ,sizeof (ns )); 1133io .read (& n_layer_ref ,sizeof (n_layer_ref )); 1134 1135if (version != DSV4_COMP_STATE_VER ) { 1136throw std::runtime_error ("DSV4 compressor state version mismatch" ); 1137 } 1138if (ratio_ref != ratio || state_size_ref != state_size || n_embd_state_ref != n_embd_state ) { 1139throw std::runtime_error ("DSV4 compressor state metadata mismatch" ); 1140 } 1141if (n_layer_ref != layers .size ()) { 1142throw std::runtime_error ("DSV4 compressor state layer count mismatch" ); 1143 } 1144 1145uint32_t s0 ; 1146dsv4_state_dst_stream_range (n_stream ,seq_id ,ns ,s0 ); 1147 1148for (const auto & layer :layers ) { 1149uint32_t il_ref ; 1150io .read (& il_ref ,sizeof (il_ref )); 1151if (il_ref != layer .il ) { 1152throw std::runtime_error ("DSV4 compressor state layer id mismatch" ); 1153 } 1154 1155dsv4_state_read_tensor_streams (io ,layer .kv ,state_size ,state_size ,s0 ,ns ); 1156dsv4_state_read_tensor_streams (io ,layer .score ,state_size ,state_size ,s0 ,ns ); 1157 } 1158} 1159 1160ggml_tensor * llama_dsv4_comp_state::get_kv_all (ggml_context * ctx ,int32_t il )const { 1161const int32_t ids = map_layer_ids .at (il ); 1162ggml_tensor * state = layers [ids ].kv ; 1163 1164return ggml_view_2d (ctx ,state ,state -> ne [0 ],get_n_rows ()* (1 + n_rs_seq ),state -> nb [1 ],0 ); 1165} 1166 1167ggml_tensor * llama_dsv4_comp_state::get_score_all (ggml_context * ctx ,int32_t il )const { 1168const int32_t ids = map_layer_ids .at (il ); 1169ggml_tensor * state = layers [ids ].score ; 1170 1171return ggml_view_2d (ctx ,state ,state -> ne [0 ],get_n_rows ()* (1 + n_rs_seq ),state -> nb [1 ],0 ); 1172} 1173 1174ggml_tensor * llama_dsv4_comp_state::get_kv (ggml_context * ctx ,int32_t il )const { 1175ggml_tensor * state = get_kv_all (ctx ,il ); 1176const size_t row_size = ggml_row_size (state -> type ,state -> ne [0 ]); 1177 1178return ggml_view_2d (ctx ,state ,state -> ne [0 ],get_n_rows (),state -> nb [1 ],0 * row_size ); 1179} 1180 1181ggml_tensor * llama_dsv4_comp_state::get_score (ggml_context * ctx ,int32_t il )const { 1182ggml_tensor * state = get_score_all (ctx ,il ); 1183const size_t row_size = ggml_row_size (state -> type ,state -> ne [0 ]); 1184 1185return ggml_view_2d (ctx ,state ,state -> ne [0 ],get_n_rows (),state -> nb [1 ],0 * row_size ); 1186} 1187 1188ggml_tensor * llama_dsv4_comp_state::cpy_kv (ggml_context * ctx ,ggml_tensor * cur ,ggml_tensor * idxs ,int32_t il )const { 1189return ggml_set_rows (ctx ,get_kv_all (ctx ,il ),cur ,idxs ); 1190} 1191 1192ggml_tensor * llama_dsv4_comp_state::cpy_score (ggml_context * ctx ,ggml_tensor * cur ,ggml_tensor * idxs ,int32_t il )const { 1193return ggml_set_rows (ctx ,get_score_all (ctx ,il ),cur ,idxs ); 1194} 1195 1196size_t llama_dsv4_comp_state::total_size ()const { 1197size_t size = 0 ; 1198 1199for (const auto & [_ ,buf ] :ctxs_bufs ) { 1200size += ggml_backend_buffer_get_size (buf .get ()); 1201 } 1202 1203return size ; 1204} 1205 1206// 1207// llama_kv_cache_dsv4 1208// 1209 1210llama_kv_cache_dsv4::llama_kv_cache_dsv4 ( 1211const llama_model & model , 1212ggml_type type_k , 1213ggml_type type_v , 1214bool v_trans , 1215bool offload , 1216bool swa_full , 1217bool unified , 1218uint32_t kv_size , 1219uint32_t n_seq_max , 1220uint32_t n_ubatch , 1221uint32_t n_pad , 1222uint32_t n_rs_seq , 1223const layer_filter_cb & filter , 1224const layer_reuse_cb & reuse ) : 1225hparams_raw (model .hparams ), 1226hparams_csa (model .hparams ), 1227hparams_hca (model .hparams ), 1228hparams_lid (model .hparams ), 1229n_seq_max (n_seq_max ), 1230n_rs_seq (n_rs_seq ), 1231rs_idx (n_seq_max ,0 ) { 1232 1233const layer_filter_cb filter_raw = [& ](int32_t il ) { 1234if (filter && !filter (il )) { 1235return false; 1236 } 1237 1238return true; 1239 }; 1240 1241GGML_UNUSED (unified ); 1242 1243// Keep DSV4 KV/state streams per sequence even when public KV mode is unified. 1244const bool unified_raw = false; 1245 1246hparams_raw .n_layer_nextn = 0 ; 1247hparams_csa .n_layer_nextn = 0 ; 1248hparams_hca .n_layer_nextn = 0 ; 1249hparams_lid .n_layer_nextn = 0 ; 1250 1251LLAMA_LOG_INFO ("%s: creating DSV4 raw KV cache\n" ,__func__ ); 1252 1253dsv4_make_k_only (hparams_raw ); 1254 1255kv_raw = std::make_unique < llama_kv_cache_iswa > ( 1256model ,hparams_raw ,type_k ,type_v , 1257v_trans ,offload ,swa_full ,unified_raw ,kv_size ,n_seq_max ,n_ubatch ,n_pad , 1258nullptr ,filter_raw ,reuse ,nullptr ); 1259 1260dsv4_make_k_only (hparams_csa ); 1261dsv4_make_k_only (hparams_hca ); 1262 1263 std::fill (hparams_lid .n_head_kv_arr .begin (),hparams_lid .n_head_kv_arr .end (),1 ); 1264hparams_lid .n_embd_head_k_full = model .hparams .indexer_head_size ; 1265hparams_lid .n_embd_head_v_full = model .hparams .indexer_head_size ; 1266hparams_lid .n_embd_head_k_swa = model .hparams .indexer_head_size ; 1267hparams_lid .n_embd_head_v_swa = model .hparams .indexer_head_size ; 1268hparams_lid .rope_type = LLAMA_ROPE_TYPE_NEOX ; 1269dsv4_make_k_only (hparams_lid ); 1270 1271const layer_filter_cb filter_csa = [& ](int32_t il ) { 1272if (filter && !filter (il )) { 1273return false; 1274 } 1275 1276return model .hparams .dsv4_compress_ratios [il ]== DSV4_CSA_RATIO ; 1277 }; 1278 1279const layer_filter_cb filter_hca = [& ](int32_t il ) { 1280if (filter && !filter (il )) { 1281return false; 1282 } 1283 1284return model .hparams .dsv4_compress_ratios [il ]== DSV4_HCA_RATIO ; 1285 }; 1286 1287const bool unified_compressed = false; 1288 1289LLAMA_LOG_INFO ("%s: creating DSV4 CSA compressed KV cache, size = %u cells\n" , 1290__func__ ,dsv4_comp_size (kv_size ,DSV4_CSA_RATIO )); 1291 1292kv_csa = std::make_unique < llama_kv_cache > ( 1293model ,hparams_csa ,type_k ,type_v , 1294v_trans ,offload ,unified_compressed ,GGML_PAD (dsv4_comp_size (kv_size ,DSV4_CSA_RATIO ),256u ),n_seq_max ,n_pad , 12950 ,LLAMA_SWA_TYPE_NONE ,nullptr ,filter_csa ,nullptr ,nullptr ); 1296 1297LLAMA_LOG_INFO ("%s: creating DSV4 HCA compressed KV cache, size = %u cells\n" , 1298__func__ ,dsv4_comp_size (kv_size ,DSV4_HCA_RATIO )); 1299 1300kv_hca = std::make_unique < llama_kv_cache > ( 1301model ,hparams_hca ,type_k ,type_v , 1302v_trans ,offload ,unified_compressed ,GGML_PAD (dsv4_comp_size (kv_size ,DSV4_HCA_RATIO ),256u ),n_seq_max ,n_pad , 13030 ,LLAMA_SWA_TYPE_NONE ,nullptr ,filter_hca ,nullptr ,nullptr ); 1304 1305LLAMA_LOG_INFO ("%s: creating DSV4 lightning-indexer KV cache, size = %u cells\n" , 1306__func__ ,dsv4_comp_size (kv_size ,DSV4_CSA_RATIO )); 1307 1308kv_lid = std::make_unique < llama_kv_cache > ( 1309model ,hparams_lid ,type_k ,type_v , 1310v_trans ,offload ,unified_compressed ,GGML_PAD (dsv4_comp_size (kv_size ,DSV4_CSA_RATIO ),256u ),n_seq_max ,n_pad , 13110 ,LLAMA_SWA_TYPE_NONE ,nullptr ,filter_csa ,nullptr ,nullptr ); 1312 1313LLAMA_LOG_INFO ("%s: creating DSV4 CSA compressor state\n" ,__func__ ); 1314 1315csa_state = std::make_unique < llama_dsv4_comp_state > ( 1316model ,offload ,unified_compressed ,n_seq_max ,DSV4_CSA_RATIO ,2 * DSV4_CSA_RATIO , 13172 * model .hparams .n_embd_head_k (),n_rs_seq ,"csa" ,filter_csa ); 1318 1319LLAMA_LOG_INFO ("%s: creating DSV4 HCA compressor state\n" ,__func__ ); 1320 1321hca_state = std::make_unique < llama_dsv4_comp_state > ( 1322model ,offload ,unified_compressed ,n_seq_max ,DSV4_HCA_RATIO ,DSV4_HCA_RATIO , 1323model .hparams .n_embd_head_k (),n_rs_seq ,"hca" ,filter_hca ); 1324 1325LLAMA_LOG_INFO ("%s: creating DSV4 lightning-indexer compressor state\n" ,__func__ ); 1326 1327lid_state = std::make_unique < llama_dsv4_comp_state > ( 1328model ,offload ,unified_compressed ,n_seq_max ,DSV4_CSA_RATIO ,2 * DSV4_CSA_RATIO , 13292 * model .hparams .indexer_head_size ,n_rs_seq ,"lid" ,filter_csa ); 1330 1331// DSV4 attention reads compressed-K / compressor-state rows that the current 1332// graph does not necessarily overwrite; uninitialized buffer contents would 1333// otherwise leak in (instance-specific garbage) and corrupt recall. Zero all 1334// compressed buffers up front so reads of un-written rows are deterministic. 1335clear_compressed (-1 , true); 1336} 1337 1338llama_memory_context_ptr llama_kv_cache_dsv4::init_batch ( 1339llama_batch_allocr & balloc , 1340uint32_t n_ubatch , 1341bool embd_all ) { 1342GGML_UNUSED (embd_all ); 1343 1344const bool raw_per_seq = kv_raw -> get_base ()-> get_n_stream ()!= 1 ; 1345const bool comp_per_seq = csa_state -> get_n_stream ()> 1 ; 1346const bool has_coupled = dsv4_batch_has_coupled (balloc .get_batch ()); 1347 1348const auto make_context = [& ](std::vector < llama_ubatch > ubatches )-> llama_memory_context_ptr { 1349auto ubatches_raw = dsv4_build_raw_write_ubatches (ubatches ); 1350 1351auto sinfos_raw_base_write = kv_raw -> get_base ()-> prepare (ubatches_raw ); 1352if (sinfos_raw_base_write .empty ()) { 1353return nullptr ; 1354 } 1355 1356auto sinfos_raw_swa_write = kv_raw -> get_swa ()-> prepare (ubatches_raw ); 1357if (sinfos_raw_swa_write .empty ()) { 1358return nullptr ; 1359 } 1360 1361auto sinfos_raw_swa_read = dsv4_build_raw_read_sinfos (sinfos_raw_swa_write ,ubatches ); 1362 1363return std::make_unique < llama_kv_cache_dsv4_context > ( 1364this , 1365 std::move (sinfos_raw_base_write ), 1366 std::move (sinfos_raw_swa_write ), 1367 std::move (sinfos_raw_swa_read ), 1368 std::move (ubatches ), 1369 std::move (ubatches_raw )); 1370 }; 1371 1372// Match llama_kv_cache_iswa splitting when DSV4 compressed state does not 1373// require per-sequence graph layout. 1374do { 1375if (raw_per_seq || comp_per_seq ) { 1376break ; 1377 } 1378 1379balloc .split_reset (); 1380 1381 std::vector < llama_ubatch > ubatches ; 1382while (true) { 1383auto ubatch = balloc .split_simple (n_ubatch ); 1384if (ubatch .n_tokens == 0 ) { 1385break ; 1386 } 1387ubatches .push_back (std::move (ubatch ));// NOLINT 1388 } 1389 1390if (balloc .get_n_used ()< balloc .get_n_tokens ()) { 1391break ; 1392 } 1393 1394if (auto ctx = make_context (std::move (ubatches ))) { 1395return ctx ; 1396 } 1397 }while (false); 1398 1399// When raw or compressed state is per-sequence, independent sequences can 1400// share an equal-length ubatch. Coupled sequence sets still serialize until 1401// DSV4 has explicit shared-state handling for compressed streams. 1402do { 1403balloc .split_reset (); 1404 1405 std::vector < llama_ubatch > ubatches ; 1406while (true) { 1407llama_ubatch ubatch ; 1408if (has_coupled ) { 1409ubatch = balloc .split_seq (n_ubatch ); 1410 }else { 1411// [TAG_RECURRENT_ROLLBACK_SPLITS] 1412// the trailing (1 + n_rs_seq) tokens of each seq must stay in the same ubatch 1413ubatch = balloc .split_equal (n_ubatch ,raw_per_seq || comp_per_seq ,n_rs_seq > 0 ?n_rs_seq + 1 :0 ); 1414 } 1415 1416if (ubatch .n_tokens == 0 ) { 1417break ; 1418 } 1419ubatches .push_back (std::move (ubatch ));// NOLINT 1420 } 1421 1422if (balloc .get_n_used ()< balloc .get_n_tokens ()) { 1423break ; 1424 } 1425 1426if (auto ctx = make_context (std::move (ubatches ))) { 1427return ctx ; 1428 } 1429 }while (false); 1430 1431return std::make_unique < llama_kv_cache_dsv4_context > (LLAMA_MEMORY_STATUS_FAILED_PREPARE ); 1432} 1433 1434llama_memory_context_ptr llama_kv_cache_dsv4::init_full () { 1435return std::make_unique < llama_kv_cache_dsv4_context > (this ); 1436} 1437 1438llama_memory_context_ptr llama_kv_cache_dsv4::init_update (llama_context * lctx ,bool optimize ) { 1439return std::make_unique < llama_kv_cache_dsv4_context > ( 1440this , 1441lctx , 1442optimize , 1443 std::move (csa_state -> sc_info ), 1444 std::move (hca_state -> sc_info ), 1445 std::move (lid_state -> sc_info )); 1446} 1447 1448bool llama_kv_cache_dsv4::get_can_shift ()const { 1449// Compressed row metadata uses block-derived positions. Keep shifting 1450// disabled until DSV4 compressed-cache shift semantics are wired. 1451return false; 1452} 1453 1454void llama_kv_cache_dsv4::clear (bool data ) { 1455kv_raw -> clear (data ); 1456clear_compressed (-1 , true);// DSV4 compressed buffers must never expose stale/uninit rows 1457} 1458 1459bool llama_kv_cache_dsv4::seq_rm (llama_seq_id seq_id ,llama_pos p0 ,llama_pos p1 ) { 1460if (p1 >=0 ) { 1461return false; 1462 } 1463 1464if (p0 > 0 ) { 1465if (seq_id < 0 || (uint32_t )seq_id >=n_seq_max ) { 1466return false; 1467 } 1468 1469const llama_pos pos_max = kv_raw -> seq_pos_max (seq_id ); 1470if (p0 > pos_max ) { 1471bool res = true; 1472 1473res = res & kv_raw -> seq_rm (seq_id ,p0 ,-1 ); 1474res = res & kv_csa -> seq_rm (seq_id ,p0 /DSV4_CSA_RATIO ,-1 ); 1475res = res & kv_hca -> seq_rm (seq_id ,p0 /DSV4_HCA_RATIO ,-1 ); 1476res = res & kv_lid -> seq_rm (seq_id ,p0 /DSV4_CSA_RATIO ,-1 ); 1477 1478return res ; 1479 } 1480 1481if (n_rs_seq == 0 ) { 1482return false; 1483 } 1484 1485const llama_pos rollback = pos_max - (p0 - 1 ); 1486if (rollback < 1 || rollback > (llama_pos )n_rs_seq ) { 1487return false; 1488 } 1489 1490// pending rollback is single-use: stacked partial removals don't compose 1491if (rs_idx [seq_id ]!= 0 ) { 1492return false; 1493 } 1494 1495const bool res = kv_raw -> seq_rm (seq_id ,p0 ,p1 ); 1496if (res ) { 1497rs_idx [seq_id ]= (uint32_t )rollback ; 1498 } 1499 1500return res ; 1501 } 1502 1503const bool res = kv_raw -> seq_rm (seq_id ,p0 ,p1 ); 1504 1505if (res ) { 1506clear_compressed (seq_id , true); 1507 } 1508 1509return res ; 1510} 1511 1512void llama_kv_cache_dsv4::seq_cp (llama_seq_id seq_id_src ,llama_seq_id seq_id_dst ,llama_pos p0 ,llama_pos p1 ) { 1513GGML_ASSERT (p0 <=0 && p1 < 0 && "DSV4 only supports full sequence copies" ); 1514 1515kv_raw -> seq_cp (seq_id_src ,seq_id_dst ,p0 ,p1 ); 1516kv_csa -> seq_cp (seq_id_src ,seq_id_dst ,-1 ,-1 ); 1517kv_hca -> seq_cp (seq_id_src ,seq_id_dst ,-1 ,-1 ); 1518kv_lid -> seq_cp (seq_id_src ,seq_id_dst ,-1 ,-1 ); 1519 1520csa_state -> seq_cp (seq_id_src ,seq_id_dst ); 1521hca_state -> seq_cp (seq_id_src ,seq_id_dst ); 1522lid_state -> seq_cp (seq_id_src ,seq_id_dst ); 1523 1524if (seq_id_src != seq_id_dst ) { 1525rs_idx [seq_id_dst ]= 0 ; 1526 } 1527} 1528 1529void llama_kv_cache_dsv4::seq_keep (llama_seq_id seq_id ) { 1530GGML_ASSERT (seq_id >=0 && (uint32_t )seq_id < n_seq_max ); 1531 1532kv_raw -> seq_keep (seq_id ); 1533 1534for (llama_seq_id id = 0 ;id < (llama_seq_id )n_seq_max ;++ id ) { 1535if (id == seq_id ) { 1536continue ; 1537 } 1538 1539kv_raw -> seq_rm (id ,-1 ,-1 ); 1540clear_compressed (id , true); 1541 } 1542} 1543 1544void llama_kv_cache_dsv4::seq_add (llama_seq_id seq_id ,llama_pos p0 ,llama_pos p1 ,llama_pos shift ) { 1545kv_raw -> seq_add (seq_id ,p0 ,p1 ,shift ); 1546} 1547 1548void llama_kv_cache_dsv4::seq_div (llama_seq_id seq_id ,llama_pos p0 ,llama_pos p1 ,int d ) { 1549kv_raw -> seq_div (seq_id ,p0 ,p1 ,d ); 1550} 1551 1552llama_pos llama_kv_cache_dsv4::seq_pos_min (llama_seq_id seq_id )const { 1553if (seq_id < 0 || (uint32_t )seq_id >=n_seq_max ) { 1554return -1 ; 1555 } 1556 1557// The raw SWA cache may contain a wider window, but the compressed DSV4 1558// state cannot be rolled back within that window. Report only the current 1559// boundary so server-context uses checkpoints for rollback. 1560return kv_raw -> seq_pos_max (seq_id ); 1561} 1562 1563llama_pos llama_kv_cache_dsv4::seq_pos_max (llama_seq_id seq_id )const { 1564if (seq_id < 0 || (uint32_t )seq_id >=n_seq_max ) { 1565return -1 ; 1566 } 1567 1568return kv_raw -> seq_pos_max (seq_id ); 1569} 1570 1571std::map < ggml_backend_buffer_type_t ,size_t > llama_kv_cache_dsv4::memory_breakdown ()const { 1572 std::map < ggml_backend_buffer_type_t ,size_t > mb = kv_raw -> memory_breakdown (); 1573for (const auto & buft_size :kv_csa -> memory_breakdown ()) { 1574mb [buft_size .first ]+= buft_size .second ; 1575 } 1576for (const auto & buft_size :kv_hca -> memory_breakdown ()) { 1577mb [buft_size .first ]+= buft_size .second ; 1578 } 1579for (const auto & buft_size :kv_lid -> memory_breakdown ()) { 1580mb [buft_size .first ]+= buft_size .second ; 1581 } 1582for (const auto & buft_size :csa_state -> memory_breakdown ()) { 1583mb [buft_size .first ]+= buft_size .second ; 1584 } 1585for (const auto & buft_size :hca_state -> memory_breakdown ()) { 1586mb [buft_size .first ]+= buft_size .second ; 1587 } 1588for (const auto & buft_size :lid_state -> memory_breakdown ()) { 1589mb [buft_size .first ]+= buft_size .second ; 1590 } 1591return mb ; 1592} 1593 1594void llama_kv_cache_dsv4::state_write (llama_io_write_i & io ,llama_seq_id seq_id ,llama_state_seq_flags flags )const { 1595const bool partial_only = flags & LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY ; 1596 1597const uint32_t magic = DSV4_STATE_MAGIC ; 1598const uint32_t version = DSV4_STATE_VERSION ; 1599const uint32_t mode = partial_only ?DSV4_STATE_MODE_PARTIAL :DSV4_STATE_MODE_FULL ; 1600 1601io .write (& magic ,sizeof (magic )); 1602io .write (& version ,sizeof (version )); 1603io .write (& mode ,sizeof (mode )); 1604 1605kv_raw -> state_write (io ,seq_id ,flags ); 1606 1607if (!partial_only ) { 1608const llama_pos pos_max = seq_id >=0 ?kv_raw -> seq_pos_max (seq_id ) :-1 ; 1609 1610//FIXME : note that we conflate token positions with rows, which is not true for multi-modal case. 1611const uint32_t n_rows_csa = seq_id >=0 ? 1612dsv4_state_n_used_k_rows (pos_max ,DSV4_CSA_RATIO ,kv_csa -> get_size ()) :kv_csa -> get_size (); 1613const uint32_t n_rows_hca = seq_id >=0 ? 1614dsv4_state_n_used_k_rows (pos_max ,DSV4_HCA_RATIO ,kv_hca -> get_size ()) :kv_hca -> get_size (); 1615const uint32_t n_rows_lid = seq_id >=0 ? 1616dsv4_state_n_used_k_rows (pos_max ,DSV4_CSA_RATIO ,kv_lid -> get_size ()) :kv_lid -> get_size (); 1617 1618dsv4_state_write_k_cache (io ,kv_csa .get (),seq_id ,flags ,n_rows_csa ); 1619dsv4_state_write_k_cache (io ,kv_hca .get (),seq_id ,flags ,n_rows_hca ); 1620dsv4_state_write_k_cache (io ,kv_lid .get (),seq_id ,flags ,n_rows_lid ); 1621 } 1622 1623csa_state -> state_write (io ,seq_id ,flags ,rs_idx ); 1624hca_state -> state_write (io ,seq_id ,flags ,rs_idx ); 1625lid_state -> state_write (io ,seq_id ,flags ,rs_idx ); 1626} 1627 1628void llama_kv_cache_dsv4::state_read (llama_io_read_i & io ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 1629uint32_t magic ; 1630uint32_t version ; 1631uint32_t mode = DSV4_STATE_MODE_FULL ; 1632 1633io .read (& magic ,sizeof (magic )); 1634io .read (& version ,sizeof (version )); 1635 1636if (magic != DSV4_STATE_MAGIC ) { 1637throw std::runtime_error ("DSV4 state magic mismatch" ); 1638 } 1639if (version != DSV4_STATE_VERSION ) { 1640throw std::runtime_error ("DSV4 state version mismatch" ); 1641 } 1642 1643io .read (& mode ,sizeof (mode )); 1644if (mode != DSV4_STATE_MODE_FULL && mode != DSV4_STATE_MODE_PARTIAL ) { 1645throw std::runtime_error ("DSV4 state mode mismatch" ); 1646 } 1647 1648const bool partial_only = mode == DSV4_STATE_MODE_PARTIAL ; 1649if (partial_only != !!(flags & LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY )) { 1650throw std::runtime_error ("DSV4 state flags mismatch" ); 1651 } 1652 1653kv_raw -> state_read (io ,seq_id ,flags ); 1654 1655if (!partial_only ) { 1656clear_compressed (seq_id , true); 1657 1658dsv4_state_read_k_cache (io ,kv_csa .get (),seq_id ,flags ); 1659dsv4_state_read_k_cache (io ,kv_hca .get (),seq_id ,flags ); 1660dsv4_state_read_k_cache (io ,kv_lid .get (),seq_id ,flags ); 1661 } 1662 1663csa_state -> state_read (io ,seq_id ,flags ); 1664hca_state -> state_read (io ,seq_id ,flags ); 1665lid_state -> state_read (io ,seq_id ,flags ); 1666 1667if (seq_id >=0 ) { 1668GGML_ASSERT ((uint32_t )seq_id < n_seq_max ); 1669rs_idx [seq_id ]= 0 ; 1670 }else { 1671 std::fill (rs_idx .begin (),rs_idx .end (),0 ); 1672 } 1673} 1674 1675llama_kv_cache_iswa * llama_kv_cache_dsv4::get_raw ()const { 1676return kv_raw .get (); 1677} 1678 1679llama_kv_cache * llama_kv_cache_dsv4::get_csa ()const { 1680return kv_csa .get (); 1681} 1682 1683llama_kv_cache * llama_kv_cache_dsv4::get_hca ()const { 1684return kv_hca .get (); 1685} 1686 1687llama_kv_cache * llama_kv_cache_dsv4::get_lid ()const { 1688return kv_lid .get (); 1689} 1690 1691llama_dsv4_comp_state * llama_kv_cache_dsv4::get_csa_state ()const { 1692return csa_state .get (); 1693} 1694 1695llama_dsv4_comp_state * llama_kv_cache_dsv4::get_hca_state ()const { 1696return hca_state .get (); 1697} 1698 1699llama_dsv4_comp_state * llama_kv_cache_dsv4::get_lid_state ()const { 1700return lid_state .get (); 1701} 1702 1703uint32_t llama_kv_cache_dsv4::get_n_rs_seq ()const { 1704return n_rs_seq ; 1705} 1706 1707const std::vector < uint32_t > & llama_kv_cache_dsv4::get_rs_idx ()const { 1708return rs_idx ; 1709} 1710 1711void llama_kv_cache_dsv4::reset_rs_idx_for_ubatches (const std::vector < llama_ubatch > & ubatches ) { 1712if (n_rs_seq == 0 ) { 1713return ; 1714 } 1715 1716for (const llama_ubatch & ubatch :ubatches ) { 1717for (uint32_t i = 0 ;i < ubatch .n_tokens ;++ i ) { 1718for (int32_t s = 0 ;s < ubatch .n_seq_id [i ];++ s ) { 1719const llama_seq_id seq_id = ubatch .seq_id [i ][s ]; 1720if (seq_id >=0 && (uint32_t )seq_id < n_seq_max ) { 1721rs_idx [seq_id ]= 0 ; 1722 } 1723 } 1724 } 1725 } 1726} 1727 1728void llama_kv_cache_dsv4::clear_compressed (llama_seq_id seq_id ,bool data ) { 1729if (seq_id < 0 ) { 1730kv_csa -> clear (data ); 1731kv_hca -> clear (data ); 1732kv_lid -> clear (data ); 1733 }else { 1734GGML_ASSERT ((uint32_t )seq_id < n_seq_max ); 1735 1736const auto clear_seq = [seq_id ,data ](llama_kv_cache * kv ) { 1737kv -> seq_rm (seq_id ,-1 ,-1 ); 1738 1739if (data ) { 1740//TODO: do not clear the kv-cache during `seq_rm`, ref: https://github.com/ggml-org/llama.cpp/pull/26490#discussion_r3798143663 1741for (uint32_t il :kv -> get_layer_ids ()) { 1742dsv4_clear_tensor_stream (kv -> get_k_storage (il ), (uint32_t )seq_id ); 1743 } 1744 } 1745 }; 1746 1747clear_seq (kv_csa .get ()); 1748clear_seq (kv_hca .get ()); 1749clear_seq (kv_lid .get ()); 1750 } 1751 1752csa_state -> clear (seq_id ,data ); 1753hca_state -> clear (seq_id ,data ); 1754lid_state -> clear (seq_id ,data ); 1755 1756if (seq_id >=0 ) { 1757rs_idx [seq_id ]= 0 ; 1758 }else { 1759 std::fill (rs_idx .begin (),rs_idx .end (),0 ); 1760 } 1761} 1762 1763// 1764// llama_kv_cache_dsv4_raw_context 1765// 1766 1767static llama_kv_cache::slot_info dsv4_build_full_sinfo (const llama_kv_cache * kv ) { 1768const uint32_t n_stream = kv -> get_n_stream (); 1769 1770 llama_kv_cache::slot_info sinfo ; 1771sinfo .s0 = 0 ; 1772sinfo .s1 = n_stream - 1 ; 1773sinfo .resize (n_stream ); 1774for (uint32_t s = 0 ;s < n_stream ;++ s ) { 1775sinfo .strm [s ]= s ; 1776sinfo .idxs [s ].resize (1 ,0 ); 1777 } 1778 1779return sinfo ; 1780} 1781 1782llama_kv_cache_dsv4_raw_context::llama_kv_cache_dsv4_raw_context (llama_kv_cache_iswa * kv ) : 1783kv_swa (kv -> get_swa ()), 1784ctx_base_mem (nullptr ), 1785ctx_swa_mem (nullptr ), 1786n_kv (kv_swa -> get_size ()), 1787status (LLAMA_MEMORY_STATUS_SUCCESS ) { 1788sinfos_read .push_back (dsv4_build_full_sinfo (kv_swa )); 1789sinfos_write = sinfos_read ; 1790} 1791 1792llama_kv_cache_dsv4_raw_context::llama_kv_cache_dsv4_raw_context ( 1793llama_kv_cache_iswa * kv , 1794llama_context * lctx , 1795bool optimize ) : 1796kv_swa (kv -> get_swa ()), 1797ctx_base_mem (kv -> get_base ()-> init_update (lctx ,optimize )), 1798ctx_swa_mem (kv -> get_swa ()-> init_update (lctx ,optimize )), 1799n_kv (kv_swa -> get_size ()), 1800status (llama_memory_status_combine (ctx_base_mem -> get_status (),ctx_swa_mem -> get_status ())) { 1801} 1802 1803llama_kv_cache_dsv4_raw_context::llama_kv_cache_dsv4_raw_context ( 1804llama_kv_cache_iswa * kv , 1805slot_info_vec_t sinfos_base_write , 1806slot_info_vec_t sinfos_swa_write , 1807slot_info_vec_t sinfos_swa_read , 1808 std::vector < llama_ubatch > ubatches , 1809 std::vector < llama_ubatch > ubatches_write ) : 1810kv_swa (kv -> get_swa ()), 1811sinfos_write (std::move (sinfos_swa_write )), 1812sinfos_read (std::move (sinfos_swa_read )), 1813ubatches (std::move (ubatches )), 1814ubatches_write (std::move (ubatches_write )), 1815ctx_base_mem (std::make_unique < llama_kv_cache_context > ( 1816kv -> get_base (), std::move (sinfos_base_write ),this -> ubatches_write )), 1817ctx_swa_mem (nullptr ), 1818n_kv (kv_swa -> get_size ()), 1819status (LLAMA_MEMORY_STATUS_SUCCESS ) { 1820} 1821 1822bool llama_kv_cache_dsv4_raw_context::next () { 1823if (ubatches .empty ()) { 1824return true; 1825 } 1826 1827if (ctx_base_mem ) { 1828ctx_base_mem -> next (); 1829 } 1830 1831if (++ i_next >=ubatches .size ()) { 1832return false; 1833 } 1834 1835return true; 1836} 1837 1838bool llama_kv_cache_dsv4_raw_context::apply () { 1839bool res = true; 1840 1841if (ctx_base_mem ) { 1842res = res & ctx_base_mem -> apply (); 1843 } 1844if (ctx_swa_mem ) { 1845res = res & ctx_swa_mem -> apply (); 1846 } 1847if (!ubatches_write .empty ()) { 1848kv_swa -> apply_ubatch (sinfos_write [i_next ],ubatches_write [i_next ]); 1849n_kv = kv_swa -> get_n_kv (sinfos_read [i_next ]); 1850 } 1851 1852return res ; 1853} 1854 1855llama_memory_status llama_kv_cache_dsv4_raw_context::get_status ()const { 1856return status ; 1857} 1858 1859const llama_ubatch & llama_kv_cache_dsv4_raw_context::get_ubatch ()const { 1860assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 1861 1862return ubatches [i_next ]; 1863} 1864 1865uint32_t llama_kv_cache_dsv4_raw_context::get_n_kv ()const { 1866return n_kv ; 1867} 1868 1869uint32_t llama_kv_cache_dsv4_raw_context::get_n_write ()const { 1870if (ubatches_write .empty ()) { 1871return 0 ; 1872 } 1873 1874return ubatches_write [i_next ].n_tokens ; 1875} 1876 1877ggml_tensor * llama_kv_cache_dsv4_raw_context::get_k (ggml_context * ctx ,int32_t il )const { 1878return kv_swa -> get_k (ctx ,il ,n_kv ,sinfos_read [i_next ]); 1879} 1880 1881ggml_tensor * llama_kv_cache_dsv4_raw_context::cpy_k (ggml_context * ctx ,ggml_tensor * k_cur ,ggml_tensor * k_idxs ,int32_t il )const { 1882const auto & sinfo = sinfos_write [i_next ]; 1883 1884if (k_cur -> ne [2 ]== k_idxs -> ne [0 ]) { 1885return kv_swa -> cpy_k (ctx ,k_cur ,k_idxs ,il ,sinfo ); 1886 } 1887 1888// k_idxs may be expanded to one block per stream while k_cur is only 1889// the token block. Keep zero deps on all copies so each write executes. 1890const int64_t n_fanout = (int64_t )sinfo .size ()* sinfo .n_stream (); 1891 1892GGML_ASSERT (sinfo .n_stream ()> 1 ); 1893GGML_ASSERT (k_cur -> ne [2 ]== (int64_t )sinfo .size ()); 1894GGML_ASSERT (k_idxs -> ne [0 ]== n_fanout ); 1895 1896ggml_tensor * res = nullptr ; 1897for (uint32_t s = 0 ;s < sinfo .n_stream ();++ s ) { 1898ggml_tensor * k_idxs_s = ggml_view_1d (ctx ,k_idxs ,sinfo .size (),s * sinfo .size ()* ggml_element_size (k_idxs )); 1899ggml_tensor * cur = kv_swa -> cpy_k (ctx ,k_cur ,k_idxs_s ,il ,sinfo ); 1900if (res == nullptr ) { 1901res = cur ; 1902 }else { 1903res = ggml_add (ctx ,res ,ggml_sub (ctx ,cur ,cur )); 1904 } 1905 } 1906 1907return res ; 1908} 1909 1910ggml_tensor * llama_kv_cache_dsv4_raw_context::build_input_k_idxs (ggml_context * ctx ,const llama_ubatch & ubatch )const { 1911const uint32_t n_tokens = ubatches_write .empty () ?ubatch .n_tokens :ubatches_write [i_next ].n_tokens ; 1912 1913ggml_tensor * k_idxs = ggml_new_tensor_1d (ctx ,GGML_TYPE_I64 ,n_tokens ); 1914ggml_set_input (k_idxs ); 1915 1916return k_idxs ; 1917} 1918 1919ggml_tensor * llama_kv_cache_dsv4_raw_context::build_input_k_rot (ggml_context * ctx )const { 1920return kv_swa -> build_input_k_rot (ctx ); 1921} 1922 1923void llama_kv_cache_dsv4_raw_context::set_input_k_idxs (ggml_tensor * dst )const { 1924kv_swa -> set_input_k_idxs (dst ,& ubatches_write [i_next ],sinfos_write [i_next ]); 1925} 1926 1927void llama_kv_cache_dsv4_raw_context::set_input_kq_mask (ggml_tensor * dst ,const llama_ubatch * ubatch ,bool causal_attn )const { 1928kv_swa -> set_input_kq_mask (dst ,ubatch ,causal_attn ); 1929} 1930 1931void llama_kv_cache_dsv4_raw_context::set_input_k_rot (ggml_tensor * dst )const { 1932kv_swa -> set_input_k_rot (dst ); 1933} 1934 1935// 1936// llama_kv_cache_dsv4_comp_context 1937// 1938 1939llama_kv_cache_dsv4_comp_context::llama_kv_cache_dsv4_comp_context (llama_kv_cache * kv ) :kv (kv ),n_kv (kv -> get_size ()) { 1940const uint32_t n_stream = kv -> get_n_stream (); 1941 1942sinfos .resize (1 ); 1943sinfos [0 ].s0 = 0 ; 1944sinfos [0 ].s1 = n_stream - 1 ; 1945sinfos [0 ].idxs .resize (n_stream ); 1946for (uint32_t s = 0 ;s < n_stream ;++ s ) { 1947sinfos [0 ].strm .push_back (s ); 1948sinfos [0 ].idxs [s ].resize (1 ,0 ); 1949 } 1950} 1951 1952llama_kv_cache_dsv4_comp_context::llama_kv_cache_dsv4_comp_context ( 1953llama_kv_cache * kv , 1954slot_info_vec_t sinfos , 1955 std::vector < llama_ubatch > ubatches ) : 1956kv (kv ), 1957sinfos (std::move (sinfos )), 1958ubatches (std::move (ubatches )), 1959n_kv (kv -> get_size ()) { 1960} 1961 1962bool llama_kv_cache_dsv4_comp_context::next () { 1963if (ubatches .empty ()) { 1964return true; 1965 } 1966 1967if (++ i_cur >=ubatches .size ()) { 1968return false; 1969 } 1970 1971return true; 1972} 1973 1974uint32_t llama_kv_cache_dsv4_comp_context::get_n_kv ()const { 1975return n_kv ; 1976} 1977 1978ggml_tensor * llama_kv_cache_dsv4_comp_context::get_k (ggml_context * ctx ,int32_t il )const { 1979return kv -> get_k (ctx ,il ,n_kv ,sinfos [i_cur ]); 1980} 1981 1982ggml_tensor * llama_kv_cache_dsv4_comp_context::cpy_k (ggml_context * ctx ,ggml_tensor * k_cur ,ggml_tensor * k_idxs ,int32_t il )const { 1983return kv -> cpy_k (ctx ,k_cur ,k_idxs ,il ,sinfos [i_cur ]); 1984} 1985 1986ggml_tensor * llama_kv_cache_dsv4_comp_context::build_input_k_rot (ggml_context * ctx )const { 1987return kv -> build_input_k_rot (ctx ); 1988} 1989 1990void llama_kv_cache_dsv4_comp_context::set_input_k_rot (ggml_tensor * dst )const { 1991kv -> set_input_k_rot (dst ); 1992} 1993 1994// 1995// llama_kv_cache_dsv4_context 1996// 1997 1998llama_kv_cache_dsv4_context::llama_kv_cache_dsv4_context (llama_memory_status status ) :status (status ) {} 1999 2000llama_kv_cache_dsv4_context::llama_kv_cache_dsv4_context ( 2001llama_kv_cache_dsv4 * kv ) : 2002ctx_raw (std::make_unique < llama_kv_cache_dsv4_raw_context > (kv -> get_raw ())), 2003ctx_csa_mem (kv -> get_csa ()-> init_full ()), 2004ctx_hca_mem (kv -> get_hca ()-> init_full ()), 2005ctx_lid_mem (kv -> get_lid ()-> init_full ()), 2006ctx_csa (std::make_unique < llama_kv_cache_dsv4_comp_context > (kv -> get_csa ())), 2007ctx_hca (std::make_unique < llama_kv_cache_dsv4_comp_context > (kv -> get_hca ())), 2008ctx_lid (std::make_unique < llama_kv_cache_dsv4_comp_context > (kv -> get_lid ())), 2009csa_state (kv -> get_csa_state ()), 2010hca_state (kv -> get_hca_state ()), 2011lid_state (kv -> get_lid_state ()), 2012reserve_plans (true), 2013status (llama_memory_status_combine ( 2014llama_memory_status_combine (ctx_raw -> get_status (),ctx_csa_mem -> get_status ()), 2015llama_memory_status_combine (ctx_hca_mem -> get_status (),ctx_lid_mem -> get_status ()))) { 2016} 2017 2018llama_kv_cache_dsv4_context::llama_kv_cache_dsv4_context ( 2019llama_kv_cache_dsv4 * kv , 2020llama_context * lctx , 2021bool optimize , 2022stream_copy_info sc_info_csa , 2023stream_copy_info sc_info_hca , 2024stream_copy_info sc_info_lid ) : 2025ctx_raw (std::make_unique < llama_kv_cache_dsv4_raw_context > (kv -> get_raw (),lctx ,optimize )), 2026ctx_csa_mem (kv -> get_csa ()-> init_update (lctx ,optimize )), 2027ctx_hca_mem (kv -> get_hca ()-> init_update (lctx ,optimize )), 2028ctx_lid_mem (kv -> get_lid ()-> init_update (lctx ,optimize )), 2029csa_state (kv -> get_csa_state ()), 2030hca_state (kv -> get_hca_state ()), 2031lid_state (kv -> get_lid_state ()), 2032sc_info_csa (std::move (sc_info_csa )), 2033sc_info_hca (std::move (sc_info_hca )), 2034sc_info_lid (std::move (sc_info_lid )), 2035status (llama_memory_status_combine ( 2036llama_memory_status_combine ( 2037llama_memory_status_combine (ctx_raw -> get_status (),ctx_csa_mem -> get_status ()), 2038llama_memory_status_combine (ctx_hca_mem -> get_status (),ctx_lid_mem -> get_status ())), 2039this -> sc_info_csa .empty ()&& this -> sc_info_hca .empty ()&& this -> sc_info_lid .empty () ? 2040LLAMA_MEMORY_STATUS_NO_UPDATE :LLAMA_MEMORY_STATUS_SUCCESS )) { 2041} 2042 2043llama_kv_cache_dsv4_context::llama_kv_cache_dsv4_context ( 2044llama_kv_cache_dsv4 * kv , 2045slot_info_vec_t sinfos_raw_base_write , 2046slot_info_vec_t sinfos_raw_swa_write , 2047slot_info_vec_t sinfos_raw_swa_read , 2048 std::vector < llama_ubatch > ubatches , 2049 std::vector < llama_ubatch > ubatches_raw ) : 2050ubatches (std::move (ubatches )), 2051plans_csa (dsv4_build_comp_plans (this -> ubatches ,DSV4_CSA_RATIO , true, 2052kv -> get_csa_state ()-> get_state_size (),kv -> get_csa ()-> get_size (),kv -> get_csa_state ()-> get_n_stream (), 2053kv -> get_n_rs_seq (),kv -> get_rs_idx ())), 2054plans_hca (dsv4_build_comp_plans (this -> ubatches ,DSV4_HCA_RATIO , false, 2055kv -> get_hca_state ()-> get_state_size (),kv -> get_hca ()-> get_size (),kv -> get_hca_state ()-> get_n_stream (), 2056kv -> get_n_rs_seq (),kv -> get_rs_idx ())), 2057plans_lid (dsv4_build_comp_plans (this -> ubatches ,DSV4_CSA_RATIO , true, 2058kv -> get_lid_state ()-> get_state_size (),kv -> get_lid ()-> get_size (),kv -> get_lid_state ()-> get_n_stream (), 2059kv -> get_n_rs_seq (),kv -> get_rs_idx ())), 2060ctx_raw (std::make_unique < llama_kv_cache_dsv4_raw_context > ( 2061kv -> get_raw (), 2062 std::move (sinfos_raw_base_write ), 2063 std::move (sinfos_raw_swa_write ), 2064 std::move (sinfos_raw_swa_read ), 2065this -> ubatches , 2066 std::move (ubatches_raw ))), 2067ctx_csa_mem (nullptr ), 2068ctx_hca_mem (nullptr ), 2069ctx_lid_mem (nullptr ), 2070ctx_csa (std::make_unique < llama_kv_cache_dsv4_comp_context > ( 2071kv -> get_csa (), 2072dsv4_build_comp_sinfos (this -> ubatches ,kv -> get_csa ()-> get_n_stream ()), 2073this -> ubatches )), 2074ctx_hca (std::make_unique < llama_kv_cache_dsv4_comp_context > ( 2075kv -> get_hca (), 2076dsv4_build_comp_sinfos (this -> ubatches ,kv -> get_hca ()-> get_n_stream ()), 2077this -> ubatches )), 2078ctx_lid (std::make_unique < llama_kv_cache_dsv4_comp_context > ( 2079kv -> get_lid (), 2080dsv4_build_comp_sinfos (this -> ubatches ,kv -> get_lid ()-> get_n_stream ()), 2081this -> ubatches )), 2082csa_state (kv -> get_csa_state ()), 2083hca_state (kv -> get_hca_state ()), 2084lid_state (kv -> get_lid_state ()), 2085status (ctx_raw -> get_status ()) { 2086kv -> reset_rs_idx_for_ubatches (this -> ubatches ); 2087} 2088 2089llama_kv_cache_dsv4_context::~llama_kv_cache_dsv4_context ()= default ; 2090 2091bool llama_kv_cache_dsv4_context::next () { 2092assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2093 2094ctx_raw -> next (); 2095ctx_csa -> next (); 2096ctx_hca -> next (); 2097ctx_lid -> next (); 2098 2099if (++ i_next >=ubatches .size ()) { 2100return false; 2101 } 2102 2103return true; 2104} 2105 2106bool llama_kv_cache_dsv4_context::apply () { 2107assert (!llama_memory_status_is_fail (status )); 2108 2109bool res = true; 2110 2111res = res & ctx_raw -> apply (); 2112 2113if (ctx_csa_mem ) { 2114res = res & ctx_csa_mem -> apply (); 2115res = res & ctx_hca_mem -> apply (); 2116res = res & ctx_lid_mem -> apply (); 2117 } 2118 2119if (ubatches .empty ()) { 2120csa_state -> apply_copies (sc_info_csa ); 2121hca_state -> apply_copies (sc_info_hca ); 2122lid_state -> apply_copies (sc_info_lid ); 2123 } 2124 2125return res ; 2126} 2127 2128llama_memory_status llama_kv_cache_dsv4_context::get_status ()const { 2129return status ; 2130} 2131 2132const llama_ubatch & llama_kv_cache_dsv4_context::get_ubatch ()const { 2133assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2134 2135return ubatches [i_next ]; 2136} 2137 2138const llama_kv_cache_dsv4_raw_context * llama_kv_cache_dsv4_context::get_raw ()const { 2139assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2140 2141return ctx_raw .get (); 2142} 2143 2144const llama_kv_cache_dsv4_comp_context * llama_kv_cache_dsv4_context::get_csa ()const { 2145assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2146 2147return ctx_csa .get (); 2148} 2149 2150const llama_kv_cache_dsv4_comp_context * llama_kv_cache_dsv4_context::get_hca ()const { 2151assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2152 2153return ctx_hca .get (); 2154} 2155 2156const llama_kv_cache_dsv4_comp_context * llama_kv_cache_dsv4_context::get_lid ()const { 2157assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2158 2159return ctx_lid .get (); 2160} 2161 2162const llama_dsv4_comp_state * llama_kv_cache_dsv4_context::get_csa_state ()const { 2163assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2164 2165return csa_state ; 2166} 2167 2168const llama_dsv4_comp_state * llama_kv_cache_dsv4_context::get_hca_state ()const { 2169assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2170 2171return hca_state ; 2172} 2173 2174const llama_dsv4_comp_state * llama_kv_cache_dsv4_context::get_lid_state ()const { 2175assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2176 2177return lid_state ; 2178} 2179 2180const llama_kv_cache_dsv4_context::comp_plan & llama_kv_cache_dsv4_context::get_csa_plan ()const { 2181assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2182 2183static const comp_plan empty ; 2184if (plans_csa .empty ()) { 2185return empty ; 2186 } 2187 2188return plans_csa [i_next ]; 2189} 2190 2191const llama_kv_cache_dsv4_context::comp_plan & llama_kv_cache_dsv4_context::get_hca_plan ()const { 2192assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2193 2194static const comp_plan empty ; 2195if (plans_hca .empty ()) { 2196return empty ; 2197 } 2198 2199return plans_hca [i_next ]; 2200} 2201 2202const llama_kv_cache_dsv4_context::comp_plan & llama_kv_cache_dsv4_context::get_lid_plan ()const { 2203assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2204 2205static const comp_plan empty ; 2206if (plans_lid .empty ()) { 2207return empty ; 2208 } 2209 2210return plans_lid [i_next ]; 2211} 2212 2213const llama_kv_cache_dsv4_context::comp_plan & llama_kv_cache_dsv4_context::get_csa_plan (const llama_ubatch & ubatch )const { 2214assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2215 2216if (!reserve_plans ) { 2217return get_csa_plan (); 2218 } 2219 2220reserve_plan_csa = dsv4_build_reserve_comp_plan ( 2221ubatch ,DSV4_CSA_RATIO , true, 2222csa_state -> get_state_size (),get_csa ()-> get_n_kv (),csa_state -> get_n_stream (),csa_state -> get_n_rs_seq ()); 2223 2224return reserve_plan_csa ; 2225} 2226 2227const llama_kv_cache_dsv4_context::comp_plan & llama_kv_cache_dsv4_context::get_hca_plan (const llama_ubatch & ubatch )const { 2228assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2229 2230if (!reserve_plans ) { 2231return get_hca_plan (); 2232 } 2233 2234reserve_plan_hca = dsv4_build_reserve_comp_plan ( 2235ubatch ,DSV4_HCA_RATIO , false, 2236hca_state -> get_state_size (),get_hca ()-> get_n_kv (),hca_state -> get_n_stream (),hca_state -> get_n_rs_seq ()); 2237 2238return reserve_plan_hca ; 2239} 2240 2241const llama_kv_cache_dsv4_context::comp_plan & llama_kv_cache_dsv4_context::get_lid_plan (const llama_ubatch & ubatch )const { 2242assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 2243 2244if (!reserve_plans ) { 2245return get_lid_plan (); 2246 } 2247 2248reserve_plan_lid = dsv4_build_reserve_comp_plan ( 2249ubatch ,DSV4_CSA_RATIO , true, 2250lid_state -> get_state_size (),get_lid ()-> get_n_kv (),lid_state -> get_n_stream (),lid_state -> get_n_rs_seq ()); 2251 2252return reserve_plan_lid ; 2253}