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