66#include " llama.h"
77#include " chat.h"
88
9+ #include < algorithm>
910#include < clocale>
1011#include < cstdio>
1112#include < cstring>
@@ -33,6 +34,9 @@ int main(int argc, char ** argv) {
3334 return 1 ;
3435 }
3536
37+ params.kv_unified = true ;
38+ params.n_parallel = std::max (params.n_parallel , params.speculative .n_max + 2 );
39+
3640 // init llama.cpp
3741 llama_backend_init ();
3842 llama_numa_init (params.numa );
@@ -111,7 +115,7 @@ int main(int argc, char ** argv) {
111115 int n_predict = 0 ;
112116 int n_drafted = 0 ;
113117 int n_accept = 0 ;
114-
118+ int draft_len_slot[ 10 ] = { 0 };
115119 // used to determine end of generation
116120 bool has_eos = false ;
117121
@@ -150,6 +154,7 @@ int main(int argc, char ** argv) {
150154 llama_token id_last;
151155 llama_tokens prompt_tgt;
152156 int n_past;
157+ bool pending_first_token_print = false ;
153158
154159 // TODO: simplify
155160 if (params.speculative .eagle3 ) {
@@ -158,7 +163,7 @@ int main(int argc, char ** argv) {
158163
159164 id_last = common_sampler_sample (smpl, ctx_tgt, -1 );
160165 common_sampler_accept (smpl, id_last, true );
161- LOG ( " %s " , common_token_to_piece (ctx_tgt, id_last). c_str ()) ;
166+ pending_first_token_print = true ;
162167 n_predict++;
163168
164169 // all tokens currently in the target context
@@ -179,14 +184,18 @@ int main(int argc, char ** argv) {
179184 n_past = inp.size () - 1 ;
180185 }
181186
182- // init the speculator
183187 const auto & params_spec = params.speculative ;
184-
185188 struct common_speculative * spec = common_speculative_init (params.speculative , ctx_tgt);
186189
187190 common_speculative_begin (spec, prompt_tgt);
188191
192+ if (pending_first_token_print) {
193+ LOG (" %s" , common_token_to_piece (ctx_tgt, id_last).c_str ());
194+ pending_first_token_print = false ;
195+ }
196+
189197 llama_batch batch_tgt = llama_batch_init (llama_n_batch (ctx_tgt), 0 , 1 );
198+ llama_memory_t mem_tgt = llama_get_memory (ctx_tgt);
190199
191200 const auto t_enc_end = ggml_time_us ();
192201
@@ -200,37 +209,34 @@ int main(int argc, char ** argv) {
200209 // offloaded to a remote device. it doesn't even have to be based on an LLM. instead, it can provide tokens
201210 // from a cache or lookup tables.
202211 //
212+
213+
203214 llama_tokens draft = common_speculative_draft (spec, params_spec, prompt_tgt, id_last);
204215
205216 // LOG_DBG("draft: %s\n", string_from(ctx_dft, draft).c_str());
206217
207- // always have a token to evaluate from before - id_last
208- common_batch_clear (batch_tgt);
209- common_batch_add (batch_tgt, id_last, n_past++, { 0 }, true );
218+ // do not waste time on small drafts
219+ if (draft.size () < (size_t ) params_spec.n_min ) {
220+ draft.clear ();
221+ }
210222
211- // evaluate the target model on [id_last, draft0, draft1, ..., draftN-1]
212- {
213- // do not waste time on small drafts
214- if (draft.size () < (size_t ) params_spec.n_min ) {
215- draft.clear ();
216- }
223+ const int n_verify = (int ) draft.size () + 1 ;
217224
218- for (size_t i = 0 ; i < draft.size (); ++i) {
219- common_batch_add (batch_tgt, draft[i], n_past + i, { 0 }, true );
220- }
225+ common_batch_clear (batch_tgt);
221226
222- // LOG_DBG("target batch: %s\n", string_from(ctx_tgt, batch_tgt).c_str());
227+ if (!llama_memory_eagle3_recurrent_begin (mem_tgt, 0 , n_verify, n_past)) {
228+ LOG_ERR (" %s: failed to reserve EAGLE3 recurrent verification slots for depth %d\n " , __func__, n_verify);
229+ return 1 ;
230+ }
223231
224- llama_decode (ctx_tgt, batch_tgt);
232+ common_batch_add (batch_tgt, id_last, n_past++, { 0 }, true );
233+
234+ for (size_t i = 0 ; i < draft.size (); ++i) {
235+ common_batch_add (batch_tgt, draft[i], n_past + i, { 0 }, true );
225236 }
226237
227- // sample from the full target batch and return the accepted tokens based on the target sampler
228- //
229- // for each token to be accepted, the sampler would have to sample that same token
230- // in such cases, instead of decoding the sampled token as we normally do, we simply continue with the
231- // available logits from the batch and sample the next token until we run out of logits or the sampler
232- // disagrees with the draft
233- //
238+ llama_decode (ctx_tgt, batch_tgt);
239+
234240 const auto ids = common_sampler_sample_and_accept_n (smpl, ctx_tgt, draft);
235241
236242 // LOG_DBG("ids: %s\n", string_from(ctx_tgt, ids).c_str());
@@ -240,8 +246,11 @@ int main(int argc, char ** argv) {
240246 n_past += ids.size () - 1 ;
241247 n_drafted += draft.size (); // note: we ignore the discarded small drafts
242248 n_accept += ids.size () - 1 ;
249+ draft_len_slot[ids.size ()-1 ] += 1 ;
243250 n_predict += ids.size ();
244251
252+ common_speculative_accept (spec, ids.size () - 1 );
253+
245254 // process the accepted tokens and update contexts
246255 //
247256 // this is the standard token post-processing that we normally do
@@ -268,10 +277,11 @@ int main(int argc, char ** argv) {
268277
269278 LOG_DBG (" accepted %d/%d draft tokens, the last target token is: (%d)\n " , (int ) ids.size () - 1 , (int ) draft.size (), id_last);
270279
280+ GGML_ASSERT (llama_memory_eagle3_recurrent_promote (mem_tgt, 0 , ids.size ()));
281+
271282 {
272283 LOG_DBG (" clear kv cache from any extra tokens, n_past = %d\n " , n_past);
273-
274- llama_memory_seq_rm (llama_get_memory (ctx_tgt), 0 , n_past, -1 );
284+ llama_memory_seq_rm (mem_tgt, 0 , n_past, -1 );
275285 }
276286
277287 if ((params.n_predict >= 0 && n_predict > params.n_predict ) || has_eos) {
@@ -293,6 +303,13 @@ int main(int argc, char ** argv) {
293303 LOG_INF (" n_predict = %d\n " , n_predict);
294304 LOG_INF (" n_drafted = %d\n " , n_drafted);
295305 LOG_INF (" n_accept = %d\n " , n_accept);
306+
307+
308+ for (int j=0 ;j<10 ;j++){
309+ LOG_INF (" draft_len_slot[%d] = %d\n " ,j,draft_len_slot[j]);
310+
311+ }
312+
296313 LOG_INF (" accept = %.3f%%\n " , 100 .0f * n_accept / n_drafted);
297314
298315 LOG_INF (" \n " );
0 commit comments