char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
bf76ac77b
char/aliceai-t5-moe
1// Test for state restore with fragmented KV cache 2// This tests the fix for: https://github.com/ggml-org/llama.cpp/issues/17527 3// The issue was that state restore required contiguous KV cache slots, 4// which fails when the cache is fragmented. 5// 6// The fix changes find_slot(ubatch, true) to find_slot(ubatch, false) 7// in state_read_meta(), allowing non-contiguous slot allocation. 8 9#include "arg.h" 10#include "common.h" 11#include "llama.h" 12 13#include <vector> 14#include <cstdio> 15#include <cstring> 16 17int main (int argc ,char ** argv ) { 18common_params params ; 19 20params .sampling .seed = 1234 ; 21params .kv_unified = true; 22params .n_parallel = 3 ; 23params .n_ctx = 256 ; 24 25common_init (); 26 27if (!common_params_parse (argc ,argv ,params ,LLAMA_EXAMPLE_COMMON )) { 28return 1 ; 29 } 30 31// init 32 33ggml_backend_load_all (); 34 35common_init_result_ptr llama_init = common_init_from_params (params ); 36 37llama_model * model = llama_init -> model (); 38llama_context * ctx = llama_init -> context (); 39 40if (model == nullptr || ctx == nullptr ) { 41fprintf (stderr ,"%s : failed to init\n" ,__func__ ); 42return 1 ; 43 } 44 45GGML_UNUSED (model ); 46 47// tokenize prompt 48 std::vector < llama_token > tokens (70 ,1 ); 49 50// interleave the 3 sequences: 51// 01201230123... 52llama_batch batch = llama_batch_init (params .n_parallel * tokens .size (),0 ,1 ); 53for (size_t i = 0 ;i < tokens .size ();i ++ ) { 54for (int s = 0 ;s < params .n_parallel ;++ s ) { 55common_batch_add (batch ,tokens [i ],i , {s }, false); 56 } 57 } 58batch .logits [batch .n_tokens - 1 ]= true; 59 60if (llama_decode (ctx ,batch )) { 61fprintf (stderr ,"%s : failed to decode seq 0\n" ,__func__ ); 62return 1 ; 63 } 64 65fprintf (stderr ,"%s : processed prompt on seq 0, 1, 2 (%zu tokens each)\n" ,__func__ ,tokens .size ()); 66 67// Save state of seq 1 68 std::vector < uint8_t > seq_state (llama_state_seq_get_size (ctx ,1 )); 69const size_t ncopy = llama_state_seq_get_data (ctx ,seq_state .data (),seq_state .size (),1 ); 70if (ncopy != seq_state .size ()) { 71fprintf (stderr ,"%s : failed to save seq 1 state\n" ,__func__ ); 72return 1 ; 73 } 74fprintf (stderr ,"%s : saved seq 1 state, %zu bytes\n" ,__func__ ,ncopy ); 75 76// clear seq 1 to create a "hole" in the KV cache (fragmentation) 77// 0.20.20.20.2.... 78llama_memory_t mem = llama_get_memory (ctx ); 79llama_memory_seq_rm (mem ,1 ,-1 ,-1 ); 80fprintf (stderr ,"%s : cleared seq 1 to create fragmentation\n" ,__func__ ); 81 82// Now the cache has holes where seq 1 was 83// This creates fragmentation - there's no contiguous block large enough 84// for the seq 1 state if we only look for contiguous slots 85 86// Restore seq 1 state into seq 1 (should work with non-contiguous allocation) 87// We use seq 1 since it's a valid sequence ID (0 to n_parallel-1) 88// Before the fix, this would fail with "failed to find available cells in kv cache" 89const size_t nset = llama_state_seq_set_data (ctx ,seq_state .data (),seq_state .size (),1 ); 90if (nset != seq_state .size ()) { 91fprintf (stderr ,"%s : FAILED to restore seq state into fragmented cache (got %zu, expected %zu)\n" , 92__func__ ,nset ,seq_state .size ()); 93fprintf (stderr ,"%s : This is the bug - state restore fails with fragmented KV cache\n" ,__func__ ); 94llama_batch_free (batch ); 95return 1 ; 96 } 97fprintf (stderr ,"%s : restored state into seq 1, %zu bytes\n" ,__func__ ,nset ); 98 99// Verify we can decode with the restored state 100// Generate one token to verify the restored state is usable 101auto sparams = llama_sampler_chain_default_params (); 102llama_sampler * smpl = llama_sampler_chain_init (sparams ); 103llama_sampler_chain_add (smpl ,llama_sampler_init_dist (params .sampling .seed )); 104 105auto next_token = llama_sampler_sample (smpl ,ctx ,-1 ); 106auto next_token_str = common_token_to_piece (ctx ,next_token ); 107 108common_batch_clear (batch ); 109common_batch_add (batch ,next_token , (int )tokens .size (), {1 }, true); 110 111if (llama_decode (ctx ,batch )) { 112fprintf (stderr ,"%s : failed to decode with restored state\n" ,__func__ ); 113llama_sampler_free (smpl ); 114llama_batch_free (batch ); 115return 1 ; 116 } 117 118fprintf (stderr ,"%s : successfully decoded with restored state, generated: '%s'\n" ,__func__ ,next_token_str .c_str ()); 119fprintf (stderr ,"%s : SUCCESS - state restore works with fragmented KV cache\n" ,__func__ ); 120 121llama_sampler_free (smpl ); 122llama_batch_free (batch ); 123 124return 0 ; 125}