char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
f87067841
char/aliceai-t5-moe
1#include "models.h" 2 3void llama_model_eagle3::load_arch_hparams (llama_model_loader & ml ) { 4ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 5 6if (!ml .get_arr (LLM_KV_TARGET_LAYERS ,target_layer_ids , false)) { 7throw std::runtime_error ("EAGLE3 model requires 'extract_layers' in GGUF metadata" ); 8 } 9if (target_layer_ids .size ()!= 3 ) { 10throw std::runtime_error ("EAGLE3 requires exactly 3 entries in 'extract_layers'" ); 11 } 12LLAMA_LOG_INFO ("%s: EAGLE3 extract_layers = [%d, %d, %d]\n" ,__func__ , 13target_layer_ids [0 ], 14target_layer_ids [1 ], 15target_layer_ids [2 ]); 16 17uint32_t n_embd_tgt = 0 ; 18 19ml .get_key (LLM_KV_TARGET_HIDDEN_SIZE ,n_embd_tgt ); 20LLAMA_LOG_INFO ("%s: EAGLE3 n_embd_tgt = %u (draft n_embd = %u)\n" ,__func__ ,n_embd_tgt ,hparams .n_embd ); 21 22hparams .n_embd_inp_enc_impl = (uint32_t )target_layer_ids .size ()* n_embd_tgt ; 23 24// eagle3 norm_before_residual (optional, default false) 25// compatible with Readhat eagle3 speculator model 26ml .get_key (LLM_KV_NORM_BEFORE_RESIDUAL ,hparams .norm_before_residual , false); 27if (hparams .norm_before_residual ) { 28LLAMA_LOG_INFO ("%s: EAGLE3gnorm_before_residual = true\n" ,__func__ ); 29 } 30 31// eagle3 norm_before_fc (optional, default false) 32// compatible with eagle3.1 (e.g. nvidia/gpt-oss-120b-Eagle3-v3) 33ml .get_key (LLM_KV_NORM_BEFORE_FC ,hparams .norm_before_fc , false); 34 35type = LLM_TYPE_UNKNOWN ; 36} 37 38void llama_model_eagle3::load_arch_tensors (llama_model_loader & ) { 39LLAMA_LOAD_LOCALS ; 40 41const int64_t n_embd_inp = hparams .n_embd_inp_enc (); 42const int64_t n_embd_attn_input = 2 * n_embd ; 43 44// Get vocab size from the d2t tensor in the GGUF file (optional - only needed if eagle3 has different vocab_size than target) 45// d2t: draft to target vocabulary mapping 46int64_t n_draft_vocab = n_vocab ;// Default: same as target vocab 47const struct ggml_tensor * d2t_meta = ml -> get_tensor_meta ("d2t" ); 48if (d2t_meta ) { 49n_draft_vocab = d2t_meta -> ne [0 ];// update draft vocab size 50d2t = create_tensor (tn (LLM_TENSOR_D2T ), {n_draft_vocab },0 ); 51LLAMA_LOG_INFO ("%s: EAGLE3 using d2t mapping (draft_vocab_size = %lld)\n" ,__func__ , (long long )n_draft_vocab ); 52 }else { 53d2t = nullptr ;// no d2t, use default vocab size 54LLAMA_LOG_INFO ("%s: EAGLE3 without d2t - sharing same vocab_size with target (vocab_size = %lld)\n" ,__func__ , (long long )n_draft_vocab ); 55 } 56 57// Feature fusion layer: projects 3 target layers to draft hidden size 58fc = create_tensor (tn (LLM_TENSOR_FC ,"weight" ), {n_embd_inp ,n_embd },0 ); 59 60// RMSNorm on the fused target features (input to fc), only when norm_before_fc is set. 61if (hparams .norm_before_fc ) { 62output_norm_enc = create_tensor (tn (LLM_TENSOR_ENC_OUTPUT_NORM ,"weight" ), {n_embd_inp },0 ); 63 } 64 65// Output layer (uses draft vocab size) 66output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 ); 67output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_draft_vocab },TENSOR_NOT_REQUIRED ); 68 69// Token embeddings (optional - Llama 3.3 70B EAGLE3 has its own) 70const struct ggml_tensor * tok_embd_meta = ml -> get_tensor_meta (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ).str ().c_str ()); 71if (tok_embd_meta ) { 72const int64_t n_target_vocab = tok_embd_meta -> ne [1 ]; 73tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_target_vocab },0 ); 74LLAMA_LOG_INFO ("%s: EAGLE3 using its own token_embd (vocab = %lld)\n" ,__func__ , (long long )n_target_vocab ); 75 } 76 77// Single decoder layer 78for (int i = 0 ;i < n_layer ;++ i ) { 79auto & layer = layers [i ]; 80 81// input_layernorm: applied to token embeddings 82layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },0 ); 83 84// eagle3 specific: hidden_norm applied to fused target features 85layer .attn_norm_2 = create_tensor (tn (LLM_TENSOR_ATTN_NORM_2 ,"weight" ,i ), {n_embd },0 ); 86 87// Attention takes input_embeds_normed + fused_target_normed as input 88layer .wq = create_tensor (tn (LLM_TENSOR_ATTN_Q ,"weight" ,i ), {n_embd_attn_input ,n_embd_head_k * n_head },0 ); 89layer .wk = create_tensor (tn (LLM_TENSOR_ATTN_K ,"weight" ,i ), {n_embd_attn_input ,n_embd_k_gqa },0 ); 90layer .wv = create_tensor (tn (LLM_TENSOR_ATTN_V ,"weight" ,i ), {n_embd_attn_input ,n_embd_v_gqa },0 ); 91layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_embd_head_k * n_head ,n_embd },0 ); 92 93layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },0 ); 94layer .ffn_gate = create_tensor (tn (LLM_TENSOR_FFN_GATE ,"weight" ,i ), {n_embd ,n_ff },0 ); 95layer .ffn_down = create_tensor (tn (LLM_TENSOR_FFN_DOWN ,"weight" ,i ), {n_ff ,n_embd },0 ); 96layer .ffn_up = create_tensor (tn (LLM_TENSOR_FFN_UP ,"weight" ,i ), {n_embd ,n_ff },0 ); 97 98// rope_freqs for llama3 rope scaling (optional - only if eagle3 config has rope_scaling) 99layer .rope_freqs = create_tensor (tn (LLM_TENSOR_ROPE_FREQS ,"weight" ,i ), {n_rot /2 },TENSOR_NOT_REQUIRED ); 100 } 101} 102 103std::unique_ptr < llm_graph_context > llama_model_eagle3::build_arch_graph (const llm_graph_params & params )const { 104switch (params .gtype ) { 105case LLM_GRAPH_TYPE_ENCODER : 106return std::make_unique < graph < true>> (* this ,params ); 107case LLM_GRAPH_TYPE_DEFAULT : 108case LLM_GRAPH_TYPE_DECODER : 109return std::make_unique < graph < false>> (* this ,params ); 110default : 111GGML_ABORT ("invalid graph type" ); 112 }; 113} 114 115template <> 116ggml_tensor * llama_model_eagle3::graph < true> ::build_inp_embd_enc ()const { 117ggml_tensor * cur = nullptr ; 118 119// Input: Target model features (3 layers concatenated: low, mid, high) 120// Data will be provided via ubatch->embd in encode_eagle3_features() 121auto inp_target = std::make_unique < llm_graph_input_embd > (hparams .n_embd_inp_enc ()); 122inp_target -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,hparams .n_embd_inp_enc (),n_tokens ); 123ggml_set_input (inp_target -> embd ); 124 125cur = inp_target -> embd ; 126cb (cur ,"inp_embd" ,-1 ); 127 128res -> add_input (std::move (inp_target )); 129 130return cur ; 131} 132 133// eagle3 Encoder: processes target model features through feature fusion layer 134// Input: target_features e.g. [12288, n_tokens] from target model layers low, middle, high 135// Output: g_embeddings e.g. [4096, n_tokens] stored in context 136template <> 137llama_model_eagle3::graph < true> ::graph (const llama_model & model ,const llm_graph_params & params ) :llm_graph_context (params ) { 138ggml_tensor * cur = nullptr ; 139 140cur = build_inp_embd_enc (); 141 142// RMSNorm on the fused target features before fc 143if (hparams .norm_before_fc ) { 144cur = build_norm (cur ,model .output_norm_enc ,NULL ,LLM_NORM_RMS ,-1 ); 145cb (cur ,"enc_input_norm" ,-1 ); 146 } 147 148// Feature fusion layer 149cur = build_lora_mm (model .fc ,cur ); 150cb (cur ,"fc_out" ,-1 ); 151 152// Output: g_embeddings e.g. [4096, n_tokens] 153// store in t_h_nextn (same as MTP) so can be read via llama_get_embeddings_nextn(ctx_dft) 154ggml_set_output (cur ); 155res -> t_h_nextn = cur ; 156 157ggml_build_forward_expand (gf ,cur ); 158} 159 160// eagle3 Decoder: processes draft tokens using g_embeddings from encoder 161// Input: draft tokens + g_embeddings from encoder 162// Output: draft logits 163template <> 164llama_model_eagle3::graph < false> ::graph (const llama_model & model ,const llm_graph_params & params ) :llm_graph_context (params ) { 165const int64_t n_embd_head = hparams .n_embd_head_v (); 166 167GGML_ASSERT (n_embd_head == hparams .n_embd_head_k ()); 168GGML_ASSERT (n_layer == 1 );// eagle3 has only one decoder layer 169 170ggml_tensor * cur ; 171ggml_tensor * inpL ; 172 173// eagle3 Decoder receives: 174// 1. Token embeddings (e.g.from eagle3's own tok_embd for Llama 3.3 70B, or target model for Llama 3.1 8B) 175// 2. g_embeddings from encoder 176auto * tok_embd = model .tok_embd ; 177if (model .tok_embd == nullptr ) { 178GGML_ASSERT (cparams .ctx_other != nullptr ); 179const auto * model_other = llama_get_model (cparams .ctx_other ); 180 181GGML_ASSERT (model_other -> tok_embd != nullptr && "EAGLE3 decoder requires token embeddings (own or from target model)" ); 182tok_embd = model_other -> tok_embd ; 183 } 184 185auto inp = std::make_unique < llm_graph_input_embd > (n_embd ); 186 187inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_tokens ); 188ggml_set_input (inp -> tokens ); 189 190inp -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,n_embd ,n_tokens ); 191ggml_set_input (inp -> embd ); 192 193ggml_tensor * inp_embd = ggml_get_rows (ctx0 ,tok_embd ,inp -> tokens ); 194cb (inp_embd ,"inp_embd" ,-1 ); 195 196ggml_tensor * inp_g = inp -> embd ; 197cb (inp_g ,"inp_g_embeddings" ,-1 ); 198 199res -> add_input (std::move (inp )); 200 201inpL = inp_g ; 202 203// inp_pos - contains the positions 204ggml_tensor * inp_pos = build_inp_pos (); 205 206auto * inp_attn = build_attn_inp_kv (); 207 208const float kq_scale = 1.0f /sqrtf (float (n_embd_head )); 209 210// Single decoder layer (il = 0) 211const int il = 0 ; 212 { 213// Apply input_layernorm to the token embeddings 214ggml_tensor * embd_norm = build_norm (inp_embd , 215model .layers [il ].attn_norm ,NULL , 216LLM_NORM_RMS ,il ); 217cb (embd_norm ,"embd_norm" ,il ); 218 219// Apply hidden_norm to inp_g 220ggml_tensor * g_norm = build_norm (inp_g , 221model .layers [il ].attn_norm_2 ,NULL , 222LLM_NORM_RMS ,-1 ); 223cb (g_norm ,"g_norm" ,il ); 224 225// norm_before_residual: determines what goes into the residual connection (compatible with Readhat eagle3 speculator model) 226// - false (default): use raw inp_g for residual 227// - true: use normalized g_norm for residual 228// inpL is the concatenated input (normalized inp_embd + normalized inp_g) 229ggml_tensor * inpSA = hparams .norm_before_residual ?g_norm :inpL ; 230 231// Concatenate normalized inp_embd and normalized inp_g 232cur = ggml_concat (ctx0 ,embd_norm ,g_norm ,il ); 233cb (cur ,"concat_embd" ,il ); 234 235// Self-attention with concatenated input 236ggml_tensor * Qcur = build_lora_mm (model .layers [il ].wq ,cur ); 237cb (Qcur ,"Qcur" ,il ); 238 239ggml_tensor * Kcur = build_lora_mm (model .layers [il ].wk ,cur ); 240cb (Kcur ,"Kcur" ,il ); 241 242ggml_tensor * Vcur = build_lora_mm (model .layers [il ].wv ,cur ); 243cb (Vcur ,"Vcur" ,il ); 244 245Qcur = ggml_reshape_3d (ctx0 ,Qcur ,n_embd_head ,n_head ,n_tokens ); 246Kcur = ggml_reshape_3d (ctx0 ,Kcur ,n_embd_head ,n_head_kv ,n_tokens ); 247Vcur = ggml_reshape_3d (ctx0 ,Vcur ,n_embd_head ,n_head_kv ,n_tokens ); 248 249// rope freq factors, returns nullptr if not available 250ggml_tensor * rope_factors = model .get_rope_factors (cparams ,il ); 251 252// RoPE 253Qcur = ggml_rope_ext ( 254ctx0 ,Qcur ,inp_pos ,rope_factors , 255n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 256ext_factor ,attn_factor ,beta_fast ,beta_slow 257 ); 258Kcur = ggml_rope_ext ( 259ctx0 ,Kcur ,inp_pos ,rope_factors , 260n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 261ext_factor ,attn_factor ,beta_fast ,beta_slow 262 ); 263 264cb (Qcur ,"Qcur_rope" ,il ); 265cb (Kcur ,"Kcur_rope" ,il ); 266 267cur = build_attn (inp_attn , 268model .layers [il ].wo ,NULL ,nullptr , 269Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr ,kq_scale ,il ); 270 271// Add residual and update it 272ggml_tensor * ffn_inp = ggml_add (ctx0 ,cur ,inpSA ); 273cb (ffn_inp ,"ffn_inp" ,il ); 274 275// Apply FFN norm to the sum 276cur = build_norm (ffn_inp , 277model .layers [il ].ffn_norm ,NULL , 278LLM_NORM_RMS ,il ); 279cb (cur ,"post_attn_norm" ,il ); 280 281cur = build_ffn (cur , 282model .layers [il ].ffn_up ,NULL ,NULL , 283model .layers [il ].ffn_gate ,NULL ,NULL , 284model .layers [il ].ffn_down ,NULL ,NULL , 285NULL , 286LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 287cb (cur ,"ffn_out" ,il ); 288 289// Output norm with residual 290cur = ggml_add (ctx0 ,cur ,ffn_inp ); 291cb (cur ,"eagle3_prenorm" ,il ); 292 293inpL = cur ; 294 } 295 296cur = inpL ; 297 298// Output prenorm state (for next token's g_embeddings in autoregressive generation) 299ggml_set_output (cur ); 300res -> t_h_nextn = cur ; 301 302cur = build_norm (cur , 303model .output_norm ,NULL , 304LLM_NORM_RMS ,-1 ); 305cb (cur ,"result_norm" ,-1 ); 306 307// lm_head - projects to draft vocabulary 308// if the draft has no own output projection, inherit the target model's lm_head 309auto * output = model .output ; 310if (output == nullptr ) { 311GGML_ASSERT (cparams .ctx_other != nullptr ); 312const auto * model_other = llama_get_model (cparams .ctx_other ); 313 314GGML_ASSERT (model_other -> output != nullptr && "EAGLE3 decoder requires an output projection (own or from target model)" ); 315output = model_other -> output ; 316 } 317cur = build_lora_mm (output ,cur ); 318 319if (model .d2t ) { 320const int64_t n_draft_vocab = cur -> ne [0 ]; 321const int64_t n_outputs = cur -> ne [1 ]; 322const int64_t n_vocab = (int64_t )model .vocab .n_tokens (); 323 324GGML_ASSERT (model .d2t -> type == GGML_TYPE_I64 ); 325GGML_ASSERT (model .d2t -> ne [0 ]== n_draft_vocab ); 326 327ggml_tensor * logits = ggml_fill (ctx0 ,ggml_new_tensor_3d (ctx0 ,GGML_TYPE_F32 ,1 ,n_vocab ,n_outputs ),- INFINITY ); 328cur = ggml_set_rows (ctx0 ,logits , 329ggml_reshape_3d (ctx0 ,cur ,1 ,n_draft_vocab ,n_outputs ), 330ggml_reshape_3d (ctx0 ,model .d2t ,n_draft_vocab ,1 ,1 )); 331cur = ggml_reshape_2d (ctx0 ,cur ,n_vocab ,n_outputs ); 332 } 333 334cb (cur ,"result_output" ,-1 ); 335res -> t_logits = cur ; 336 337ggml_build_forward_expand (gf ,cur ); 338}