char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
7a20b417f
char/aliceai-t5-moe
1#include "models.h" 2 3std::unique_ptr < llm_graph_context > llama_model_nemotron_h_moe::build_arch_graph (const llm_graph_params & params )const { 4if (params .gtype == LLM_GRAPH_TYPE_DECODER_MTP ) { 5return std::make_unique < graph_mtp > (* this ,params ); 6 } 7return std::make_unique < graph > (* this ,params ); 8} 9 10// MTP draft head for Nemotron-H MoE 11llama_model_nemotron_h_moe::graph_mtp::graph_mtp (const llama_model & model ,const llm_graph_params & params ) 12 :llm_graph_context (params ) { 13GGML_ASSERT (hparams .n_layer_nextn == 1 && "NEMOTRON_H_MOE MTP currently supports a single MTP block" ); 14 15const int64_t n_embd_head = hparams .n_embd_head_v (); 16GGML_ASSERT (n_embd_head == hparams .n_embd_head_k ()); 17 18const int il = hparams .n_layer (); 19const auto & layer = model .layers [il ]; 20 21GGML_ASSERT (layer .nextn .eh_proj && layer .nextn .enorm && layer .nextn .hnorm ); 22GGML_ASSERT (layer .ffn_gate_inp ); 23 24// token embedding weights 25ggml_tensor * tok_embd_w = layer .nextn .embed_tokens ?layer .nextn .embed_tokens :model .tok_embd ; 26GGML_ASSERT (tok_embd_w != nullptr && "NEMOTRON_H_MOE MTP requires token embeddings" ); 27 28auto inp = std::make_unique < llm_graph_input_embd_h > (hparams .n_embd ); 29 30inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_tokens ); 31ggml_set_input (inp -> tokens ); 32 33inp -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,hparams .n_embd_inp (),n_tokens ); 34ggml_set_input (inp -> embd ); 35 36ggml_tensor * tok_embd ; 37if (ubatch .token ) { 38tok_embd = ggml_get_rows (ctx0 ,tok_embd_w ,inp -> tokens ); 39 }else { 40tok_embd = inp -> embd ; 41 } 42cb (tok_embd ,"mtp_tok_embd" ,il ); 43 44inp -> h = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,hparams .n_embd ,n_tokens ); 45ggml_set_input (inp -> h ); 46ggml_set_name (inp -> h ,"mtp_h_input" ); 47 48ggml_tensor * h_embd = inp -> h ; 49 50res -> add_input (std::move (inp )); 51 52ggml_tensor * inp_out_ids = build_inp_out_ids (); 53 54// attention fills KV over all tokens, but the MoE is position-wise: gather output rows before 55// it to save FFN compute (unless unmasked embeddings_nextn needs the full-length hidden state) 56const bool emit_h_nextn = cparams .embeddings_nextn ; 57const bool crop_before_ffn = inp_out_ids && (!emit_h_nextn || cparams .embeddings_nextn_masked ); 58 59auto * inp_attn = build_attn_inp_kv (); 60 61ggml_tensor * h_norm = build_norm (h_embd ,layer .nextn .hnorm ,nullptr ,LLM_NORM_RMS ,il ); 62cb (h_norm ,"mtp_hnorm" ,il ); 63ggml_tensor * e_norm = build_norm (tok_embd ,layer .nextn .enorm ,nullptr ,LLM_NORM_RMS ,il ); 64cb (e_norm ,"mtp_enorm" ,il ); 65 66ggml_tensor * concat = ggml_concat (ctx0 ,e_norm ,h_norm ,/*dim=*/ 0 ); 67cb (concat ,"mtp_concat" ,il ); 68 69ggml_tensor * cur = build_lora_mm (layer .nextn .eh_proj ,concat ,layer .nextn .eh_proj_s ); 70cb (cur ,"mtp_eh_proj" ,il ); 71 72// dense NoPE attention sub-layer (mtp.layers.0) 73ggml_tensor * inpSA = cur ; 74cur = build_norm (cur ,layer .attn_norm ,nullptr ,LLM_NORM_RMS ,il ); 75cb (cur ,"mtp_attn_norm" ,il ); 76 77 { 78auto [Qcur ,Kcur ,Vcur ]= build_qkv (layer ,cur ,n_embd_head ,hparams .n_head (il ),hparams .n_head_kv (il ),il ); 79const float kq_scale = hparams .f_attention_scale == 0.0f 80 ?1.0f /sqrtf (float (n_embd_head )) :hparams .f_attention_scale ; 81cur = build_attn (inp_attn ,layer .wo ,layer .wo_b ,layer .wo_s , 82Qcur ,Kcur ,Vcur ,nullptr ,nullptr ,nullptr ,kq_scale ,il ); 83cb (cur ,"mtp_attn_out" ,il ); 84 } 85 86cur = ggml_add (ctx0 ,cur ,inpSA ); 87cb (cur ,"mtp_attn_residual" ,il ); 88 89// gather the output rows here so the MoE FFN below only runs on the positions we keep 90if (crop_before_ffn ) { 91cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 92 } 93 94// MoE FFN sub-layer (mtp.layers.1) 95ggml_tensor * ffn_residual = cur ; 96cur = build_norm (cur ,layer .attn_post_norm ,nullptr ,LLM_NORM_RMS ,il ); 97cb (cur ,"mtp_attn_post_norm" ,il ); 98 99 { 100ggml_tensor * router_logits = build_lora_mm (layer .ffn_gate_inp ,cur ); 101cb (router_logits ,"mtp_ffn_moe_logits" ,il ); 102 103ggml_tensor * moe_out = 104build_moe_ffn (cur , 105layer .ffn_gate_inp , 106layer .ffn_up_exps , 107nullptr ,// no gate 108layer .ffn_down_exps , 109layer .ffn_exp_probs_b , 110n_expert ,n_expert_used , 111LLM_FFN_RELU_SQR ,hparams .expert_weights_norm , 112hparams .expert_weights_scale , 113LLAMA_EXPERT_GATING_FUNC_TYPE_SIGMOID , 114il , 115router_logits ,nullptr , 116layer .ffn_up_exps_s , 117nullptr ,// no gate 118layer .ffn_down_exps_s ); 119cb (moe_out ,"mtp_ffn_moe_out" ,il ); 120 121ggml_tensor * ffn_shexp = build_ffn (cur , 122layer .ffn_up_shexp ,NULL ,layer .ffn_up_shexp_s , 123NULL ,NULL ,NULL , 124layer .ffn_down_shexp ,NULL ,layer .ffn_down_shexp_s , 125NULL , 126LLM_FFN_RELU_SQR ,LLM_FFN_PAR ,il ); 127cb (ffn_shexp ,"mtp_ffn_shexp" ,il ); 128 129cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 130cb (cur ,"mtp_ffn_out" ,il ); 131 } 132 133cur = ggml_add (ctx0 ,cur ,ffn_residual ); 134cb (cur ,"mtp_post_ffn" ,il ); 135 136// final head norm: the MTP head has its own LayerNorm 137GGML_ASSERT (layer .nextn .shared_head_norm && "NEMOTRON_H_MOE MTP: missing final head norm" ); 138cur = build_norm (cur ,layer .nextn .shared_head_norm ,nullptr ,LLM_NORM ,-1 ); 139 140cb (cur ,"h_nextn" ,-1 ); 141res -> t_h_nextn = cur ; 142 143if (!crop_before_ffn && inp_out_ids ) { 144cur = ggml_get_rows (ctx0 ,cur ,inp_out_ids ); 145 } 146 147// LM head 148ggml_tensor * head_w = layer .nextn .shared_head_head ?layer .nextn .shared_head_head :model .output ; 149ggml_tensor * head_s = layer .nextn .shared_head_head ?layer .nextn .shared_head_head_s :model .output_s ; 150GGML_ASSERT (head_w != nullptr && "NEMOTRON_H_MOE MTP requires an output projection" ); 151cur = build_lora_mm (head_w ,cur ,head_s ); 152cb (cur ,"result_output" ,-1 ); 153 154res -> t_logits = cur ; 155ggml_build_forward_expand (gf ,cur ); 156}