char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
5a32f7b66
char/aliceai-t5-moe
1#include "llama-kv-cache-dsa-iswa.h" 2 3#include "llama-impl.h" 4#include "llama-batch.h" 5#include "llama-model.h" 6 7#include <algorithm> 8#include <cassert> 9 10// 11// llama_kv_cache_dsa_iswa 12// 13 14llama_kv_cache_dsa_iswa::llama_kv_cache_dsa_iswa ( 15const llama_model & model , 16ggml_type type_k , 17ggml_type type_v , 18bool v_trans , 19bool offload , 20bool swa_full , 21bool unified , 22uint32_t kv_size , 23uint32_t n_seq_max , 24uint32_t n_ubatch , 25uint32_t n_pad , 26const layer_filter_cb & filter_mla , 27const layer_filter_cb & filter_lid , 28const layer_reuse_cb & reuse ) :unified (unified ) { 29 30const auto & hparams = model .hparams ; 31 32// chain filters 33const layer_filter_cb filter_dsa = [& ](int32_t il ) { 34if (filter_mla && !filter_mla (il )) { 35return false; 36 } 37 38return !hparams .is_swa (il ); 39 }; 40 41const layer_filter_cb filter_swa = [& ](int32_t il ) { 42if (filter_mla && !filter_mla (il )) { 43return false; 44 } 45 46return hparams .is_swa (il ); 47 }; 48 49const uint32_t size_dsa = kv_size ; 50 51// note: the SWA cache is always padded to 256 for performance 52// https://github.com/ggml-org/llama.cpp/issues/17037 53uint32_t size_swa = GGML_PAD (std::min (size_dsa ,hparams .n_swa * (unified ?n_seq_max :1 )+ n_ubatch ),256 ); 54 55// when using full-size SWA cache, we set the SWA cache size to be equal to the base cache size 56if (swa_full ) { 57LLAMA_LOG_WARN ("%s: using full-size SWA cache (ref: %s)\n" , 58__func__ ,"https://github.com/ggml-org/llama.cpp/pull/13194#issuecomment-2868343055" ); 59 60size_swa = size_dsa ; 61 } 62 63LLAMA_LOG_INFO ("%s: creating DSA KV cache, size = %u cells\n" ,__func__ ,size_dsa ); 64 65kv_dsa = std::make_unique < llama_kv_cache_dsa > ( 66model ,type_k ,type_v , 67v_trans ,offload ,unified ,size_dsa ,n_seq_max ,n_pad , 680 ,LLAMA_SWA_TYPE_NONE ,filter_dsa ,filter_lid ,reuse ); 69 70LLAMA_LOG_INFO ("%s: creating SWA KV cache, size = %u cells\n" ,__func__ ,size_swa ); 71 72kv_swa = std::make_unique < llama_kv_cache > ( 73model ,hparams ,type_k ,type_v , 74v_trans ,offload ,unified ,size_swa ,n_seq_max ,n_pad , 75hparams .n_swa ,hparams .swa_type ,nullptr ,filter_swa ,reuse ,nullptr ); 76} 77 78void llama_kv_cache_dsa_iswa::clear (bool data ) { 79kv_dsa -> clear (data ); 80kv_swa -> clear (data ); 81} 82 83bool llama_kv_cache_dsa_iswa::seq_rm (llama_seq_id seq_id ,llama_pos p0 ,llama_pos p1 ) { 84bool res = true; 85 86res = res & kv_dsa -> seq_rm (seq_id ,p0 ,p1 ); 87res = res & kv_swa -> seq_rm (seq_id ,p0 ,p1 ); 88 89return res ; 90} 91 92void llama_kv_cache_dsa_iswa::seq_cp (llama_seq_id seq_id_src ,llama_seq_id seq_id_dst ,llama_pos p0 ,llama_pos p1 ) { 93kv_dsa -> seq_cp (seq_id_src ,seq_id_dst ,p0 ,p1 ); 94kv_swa -> seq_cp (seq_id_src ,seq_id_dst ,p0 ,p1 ); 95} 96 97void llama_kv_cache_dsa_iswa::seq_keep (llama_seq_id seq_id ) { 98kv_dsa -> seq_keep (seq_id ); 99kv_swa -> seq_keep (seq_id ); 100} 101 102void llama_kv_cache_dsa_iswa::seq_add (llama_seq_id seq_id ,llama_pos p0 ,llama_pos p1 ,llama_pos shift ) { 103kv_dsa -> seq_add (seq_id ,p0 ,p1 ,shift ); 104kv_swa -> seq_add (seq_id ,p0 ,p1 ,shift ); 105} 106 107void llama_kv_cache_dsa_iswa::seq_div (llama_seq_id seq_id ,llama_pos p0 ,llama_pos p1 ,int d ) { 108kv_dsa -> seq_div (seq_id ,p0 ,p1 ,d ); 109kv_swa -> seq_div (seq_id ,p0 ,p1 ,d ); 110} 111 112llama_pos llama_kv_cache_dsa_iswa::seq_pos_min (llama_seq_id seq_id )const { 113// the DSA cache is a superset of the SWA cache, so we can just check the SWA cache 114return kv_swa -> seq_pos_min (seq_id ); 115} 116 117llama_pos llama_kv_cache_dsa_iswa::seq_pos_max (llama_seq_id seq_id )const { 118return kv_swa -> seq_pos_max (seq_id ); 119} 120 121std::map < ggml_backend_buffer_type_t ,size_t > llama_kv_cache_dsa_iswa::memory_breakdown ()const { 122 std::map < ggml_backend_buffer_type_t ,size_t > mb = kv_dsa -> memory_breakdown (); 123for (const auto & buft_size :kv_swa -> memory_breakdown ()) { 124mb [buft_size .first ]+= buft_size .second ; 125 } 126return mb ; 127} 128 129llama_memory_context_ptr llama_kv_cache_dsa_iswa::init_batch (llama_batch_allocr & balloc ,uint32_t n_ubatch ,bool embd_all ) { 130GGML_UNUSED (embd_all ); 131 132// first try simple split 133do { 134if (!unified ) { 135// requires equal splits, so we skip the simple split 136break ; 137 } 138 139balloc .split_reset (); 140 141 std::vector < llama_ubatch > ubatches ; 142while (true) { 143auto ubatch = balloc .split_simple (n_ubatch ); 144 145if (ubatch .n_tokens == 0 ) { 146break ; 147 } 148 149ubatches .push_back (std::move (ubatch ));// NOLINT 150 } 151 152if (balloc .get_n_used ()< balloc .get_n_tokens ()) { 153// failed to find a suitable split 154break ; 155 } 156 157auto sinfos_mla = kv_dsa -> get_mla ()-> prepare (ubatches ); 158if (sinfos_mla .empty ()) { 159break ; 160 } 161 162auto sinfos_lid = kv_dsa -> get_lid ()-> prepare (ubatches ); 163if (sinfos_lid .empty ()) { 164break ; 165 } 166 167auto sinfos_swa = kv_swa -> prepare (ubatches ); 168if (sinfos_swa .empty ()) { 169break ; 170 } 171 172assert (sinfos_mla .size ()== sinfos_swa .size ()); 173 174return std::make_unique < llama_kv_cache_dsa_iswa_context > ( 175this , std::move (sinfos_mla ), std::move (sinfos_lid ), std::move (sinfos_swa ), std::move (ubatches )); 176 }while (false); 177 178// if it fails, try equal split 179do { 180balloc .split_reset (); 181 182 std::vector < llama_ubatch > ubatches ; 183while (true) { 184auto ubatch = balloc .split_equal (n_ubatch , !unified ,0 ); 185 186if (ubatch .n_tokens == 0 ) { 187break ; 188 } 189 190ubatches .push_back (std::move (ubatch ));// NOLINT 191 } 192 193if (balloc .get_n_used ()< balloc .get_n_tokens ()) { 194// failed to find a suitable split 195break ; 196 } 197 198auto sinfos_mla = kv_dsa -> get_mla ()-> prepare (ubatches ); 199if (sinfos_mla .empty ()) { 200break ; 201 } 202 203auto sinfos_lid = kv_dsa -> get_lid ()-> prepare (ubatches ); 204if (sinfos_lid .empty ()) { 205break ; 206 } 207 208auto sinfos_swa = kv_swa -> prepare (ubatches ); 209if (sinfos_swa .empty ()) { 210break ; 211 } 212 213assert (sinfos_mla .size ()== sinfos_swa .size ()); 214 215return std::make_unique < llama_kv_cache_dsa_iswa_context > ( 216this , std::move (sinfos_mla ), std::move (sinfos_lid ), std::move (sinfos_swa ), std::move (ubatches )); 217 }while (false); 218 219return std::make_unique < llama_kv_cache_dsa_iswa_context > (LLAMA_MEMORY_STATUS_FAILED_PREPARE ); 220} 221 222llama_memory_context_ptr llama_kv_cache_dsa_iswa::init_full () { 223return std::make_unique < llama_kv_cache_dsa_iswa_context > (this ); 224} 225 226llama_memory_context_ptr llama_kv_cache_dsa_iswa::init_update (llama_context * lctx ,bool optimize ) { 227return std::make_unique < llama_kv_cache_dsa_iswa_context > (this ,lctx ,optimize ); 228} 229 230bool llama_kv_cache_dsa_iswa::get_can_shift ()const { 231return kv_dsa -> get_can_shift ()&& 232kv_swa -> get_can_shift ()&& 233kv_dsa -> get_mla ()-> get_size ()== kv_swa -> get_size (); 234} 235 236void llama_kv_cache_dsa_iswa::state_write (llama_io_write_i & io ,llama_seq_id seq_id ,llama_state_seq_flags flags )const { 237if ((flags & LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY )== 0 ) { 238kv_dsa -> state_write (io ,seq_id ,flags ); 239 } 240 241kv_swa -> state_write (io ,seq_id ,flags ); 242} 243 244void llama_kv_cache_dsa_iswa::state_read (llama_io_read_i & io ,llama_seq_id seq_id ,llama_state_seq_flags flags ) { 245if ((flags & LLAMA_STATE_SEQ_FLAGS_PARTIAL_ONLY )== 0 ) { 246kv_dsa -> state_read (io ,seq_id ,flags ); 247 } 248 249kv_swa -> state_read (io ,seq_id ,flags ); 250} 251 252llama_kv_cache_dsa * llama_kv_cache_dsa_iswa::get_dsa ()const { 253return kv_dsa .get (); 254} 255 256llama_kv_cache * llama_kv_cache_dsa_iswa::get_swa ()const { 257return kv_swa .get (); 258} 259 260// 261// llama_kv_cache_dsa_iswa_context 262// 263 264llama_kv_cache_dsa_iswa_context::llama_kv_cache_dsa_iswa_context (llama_memory_status status ) :status (status ) {} 265 266llama_kv_cache_dsa_iswa_context::llama_kv_cache_dsa_iswa_context ( 267llama_kv_cache_dsa_iswa * kv ) : 268ctx_dsa (kv -> get_dsa ()-> init_full ()), 269ctx_swa (kv -> get_swa ()-> init_full ()), 270status (llama_memory_status_combine (ctx_dsa -> get_status (),ctx_swa -> get_status ())) { 271} 272 273llama_kv_cache_dsa_iswa_context::llama_kv_cache_dsa_iswa_context ( 274llama_kv_cache_dsa_iswa * kv , 275llama_context * lctx , 276bool optimize ) : 277ctx_dsa (kv -> get_dsa ()-> init_update (lctx ,optimize )), 278ctx_swa (kv -> get_swa ()-> init_update (lctx ,optimize )), 279status (llama_memory_status_combine (ctx_dsa -> get_status (),ctx_swa -> get_status ())) { 280} 281 282llama_kv_cache_dsa_iswa_context::llama_kv_cache_dsa_iswa_context ( 283llama_kv_cache_dsa_iswa * kv , 284slot_info_vec_t sinfos_mla , 285slot_info_vec_t sinfos_lid , 286slot_info_vec_t sinfos_swa , 287 std::vector < llama_ubatch > ubatches ) : 288ubatches (std::move (ubatches )), 289// note: here we copy the ubatches. not sure if this is ideal 290ctx_dsa (new llama_kv_cache_dsa_context (kv -> get_dsa (), std::move (sinfos_mla ), std::move (sinfos_lid ),this -> ubatches )), 291ctx_swa (new llama_kv_cache_context (kv -> get_swa (), std::move (sinfos_swa ),this -> ubatches )), 292status (llama_memory_status_combine (ctx_dsa -> get_status (),ctx_swa -> get_status ())) { 293} 294 295llama_kv_cache_dsa_iswa_context:: ~llama_kv_cache_dsa_iswa_context ()= default ; 296 297bool llama_kv_cache_dsa_iswa_context::next () { 298assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 299 300ctx_dsa -> next (); 301ctx_swa -> next (); 302 303if (++ i_next >=ubatches .size ()) { 304return false; 305 } 306 307return true; 308} 309 310bool llama_kv_cache_dsa_iswa_context::apply () { 311assert (!llama_memory_status_is_fail (status )); 312 313bool res = true; 314 315res = res & ctx_dsa -> apply (); 316res = res & ctx_swa -> apply (); 317 318return res ; 319} 320 321llama_memory_status llama_kv_cache_dsa_iswa_context::get_status ()const { 322return status ; 323} 324 325const llama_ubatch & llama_kv_cache_dsa_iswa_context::get_ubatch ()const { 326assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 327 328return ubatches [i_next ]; 329} 330 331const llama_kv_cache_dsa_context * llama_kv_cache_dsa_iswa_context::get_dsa ()const { 332assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 333 334return static_cast < const llama_kv_cache_dsa_context *> (ctx_dsa .get ()); 335} 336 337const llama_kv_cache_context * llama_kv_cache_dsa_iswa_context::get_swa ()const { 338assert (status == LLAMA_MEMORY_STATUS_SUCCESS ); 339 340return static_cast < const llama_kv_cache_context *> (ctx_swa .get ()); 341}