char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
c61b98b87
char/aliceai-t5-moe
1#include "models.h" 2 3#include "llama-impl.h" 4#include "llama-kv-cache.h" 5#include "llama-kv-cache-iswa.h" 6 7void llama_model_dflash::load_arch_hparams (llama_model_loader & ml ) { 8 9ml .get_key (LLM_KV_ATTENTION_LAYERNORM_RMS_EPS ,hparams .f_norm_rms_eps ); 10ml .get_key (LLM_KV_LOGIT_SCALE ,hparams .f_logit_scale , false); 11hparams .f_final_logit_softcapping = 0.0f ; 12ml .get_key (LLM_KV_FINAL_LOGIT_SOFTCAPPING ,hparams .f_final_logit_softcapping , false); 13 14// drafts for M-RoPE targets carry degenerate sections [n_rot/2, 0, 0, 0] 15ml .get_key_or_arr (LLM_KV_ROPE_DIMENSION_SECTIONS ,hparams .rope_sections ,4 , false); 16 17ml .get_key (LLM_KV_DFLASH_BLOCK_SIZE ,hparams .dflash_block_size , false); 18ml .get_key (LLM_KV_DFLASH_CONV_KERNEL_SIZE ,hparams .dflash_conv_kernel_size , false); 19ml .get_key (LLM_KV_DFLASH_CONV_GROUP_SIZE ,hparams .dflash_conv_group_size , false); 20ml .get_key (LLM_KV_DFLASH_SELECTOR_RANK ,hparams .dflash_selector_rank , false); 21ml .get_key (LLM_KV_DFLASH_SELECTOR_TOP_K ,hparams .dflash_selector_top_k , false); 22 23if (!ml .get_arr (LLM_KV_TARGET_LAYERS ,target_layer_ids , false)) { 24throw std::runtime_error ("DFlash model requires 'target_layers' in GGUF metadata" ); 25 } 26 27hparams .n_embd_inp_enc_impl = (uint32_t )target_layer_ids .size ()* hparams .n_embd ; 28 29 std::string layers ; 30const char * sep = "" ; 31for (const auto id :target_layer_ids ) { 32layers += sep ; 33layers += std::to_string (id ); 34sep = ", " ; 35 } 36LLAMA_LOG_INFO ("%s: DFlash extract_layers = [%s]\n" ,__func__ ,layers .c_str ()); 37 38// DeepSeek-V4 DSpark backbone: stages are full DSV4 blocks, uniform sliding window (the draft KV ring) 39ml .get_key (LLM_KV_HYPER_CONNECTION_COUNT ,hparams .dsv4_hc_mult , false); 40if (hparams .dsv4_hc_mult > 0 ) { 41ml .get_key (LLM_KV_ATTENTION_Q_LORA_RANK ,hparams .n_lora_q ); 42ml .get_key (LLM_KV_ATTENTION_SLIDING_WINDOW ,hparams .n_swa ); 43ml .get_key_or_arr (LLM_KV_EXPERT_FEED_FORWARD_LENGTH ,hparams .n_ff_exp_arr ,hparams .n_layer_all ); 44ml .get_key (LLM_KV_EXPERT_SHARED_COUNT ,hparams .n_expert_shared ); 45ml .get_key (LLM_KV_EXPERT_WEIGHTS_SCALE ,hparams .expert_weights_scale ); 46ml .get_key (LLM_KV_EXPERT_WEIGHTS_NORM ,hparams .expert_weights_norm ); 47ml .get_key (LLM_KV_EXPERT_GATING_FUNC ,hparams .expert_gating_func ); 48ml .get_key_or_arr (LLM_KV_SWIGLU_CLAMP_EXP ,hparams .swiglu_clamp_exp ,hparams .n_layer_all ); 49if (!ml .get_key_or_arr (LLM_KV_SWIGLU_CLAMP_SHEXP ,hparams .swiglu_clamp_shexp ,hparams .n_layer_all ,0 )) { 50hparams .swiglu_clamp_shexp = hparams .swiglu_clamp_exp ; 51 } 52ml .get_key (LLM_KV_ATTENTION_OUTPUT_GROUP_COUNT ,hparams .dsv4_o_group_count ); 53ml .get_key (LLM_KV_ATTENTION_OUTPUT_LORA_RANK ,hparams .dsv4_o_lora_rank ); 54ml .get_key (LLM_KV_HYPER_CONNECTION_SINKHORN_ITERATIONS ,hparams .dsv4_hc_sinkhorn_iters ); 55ml .get_key (LLM_KV_HYPER_CONNECTION_EPSILON ,hparams .dsv4_hc_eps ); 56ml .get_arr (LLM_KV_ATTENTION_COMPRESS_RATIOS ,hparams .dsv4_compress_ratios , false); 57 58GGML_ASSERT (hparams .dsv4_o_group_count > 0 );// avoid div by zero 59 60if (hparams .expert_gating_func != LLAMA_EXPERT_GATING_FUNC_TYPE_SQRT_SOFTPLUS ) { 61throw std::runtime_error ("DSpark DSV4 draft expects sqrtsoftplus MoE scoring" ); 62 } 63for (uint32_t il = 0 ;il < hparams .n_layer_all ;++ il ) { 64if (hparams .dsv4_compress_ratios [il ]!= 0 ) { 65throw std::runtime_error ("DSpark DSV4 draft expects uncompressed attention on all stages" ); 66 } 67 } 68 69GGML_ASSERT (hparams .n_swa > 0 ); 70hparams .swa_type = LLAMA_SWA_TYPE_STANDARD ; 71hparams .set_swa_pattern (0 ); 72for (uint32_t il = 0 ;il < hparams .n_layer_all ;++ il ) { 73hparams .is_swa_impl [il ]= true; 74 } 75hparams .rope_freq_base_train_swa = hparams .rope_freq_base_train ; 76hparams .rope_freq_scale_train_swa = hparams .rope_freq_scale_train ; 77 78type = LLM_TYPE_UNKNOWN ; 79return ; 80 } 81 82// optional interleaved sliding-window attention with per-layer pattern array. 83// DFlash has a single rope, so the SWA rope == main rope. 84if (ml .get_key (LLM_KV_ATTENTION_SLIDING_WINDOW ,hparams .n_swa , false)&& hparams .n_swa > 0 ) { 85hparams .swa_type = LLAMA_SWA_TYPE_STANDARD ; 86ml .get_arr (LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN ,hparams .is_swa_impl ); 87hparams .rope_freq_base_train_swa = hparams .rope_freq_base_train ; 88hparams .rope_freq_scale_train_swa = hparams .rope_freq_scale_train ; 89 } 90 91type = LLM_TYPE_UNKNOWN ; 92} 93 94void llama_model_dflash::load_arch_tensors (llama_model_loader & ) { 95LLAMA_LOAD_LOCALS ; 96 97const int64_t n_embd_inp = hparams .n_embd_inp_enc (); 98 99tok_embd = create_tensor (tn (LLM_TENSOR_TOKEN_EMBD ,"weight" ), {n_embd ,n_vocab },TENSOR_NOT_REQUIRED ); 100 101// reduced draft vocab (optional): d2t maps draft rows to target token ids 102int64_t n_vocab_draft = n_vocab ; 103const struct ggml_tensor * d2t_meta = ml -> get_tensor_meta ("d2t" ); 104if (d2t_meta ) { 105n_vocab_draft = d2t_meta -> ne [0 ]; 106d2t = create_tensor (tn (LLM_TENSOR_D2T ), {n_vocab_draft },0 ); 107LLAMA_LOG_INFO ("%s: DFlash using d2t mapping (draft_vocab_size = %lld)\n" ,__func__ , (long long )n_vocab_draft ); 108 } 109 110// DSpark = DFlash + a semi-autoregressive Markov head and Confidence head 111// 112// TODO: only Qwen3-style backbones are supported for now; other backbones (e.g. Gemma4) 113// need their own conversion path and graph tweaks 114const struct ggml_tensor * markov_meta = ml -> get_tensor_meta ("markov_w1.weight" ); 115if (markov_meta ) { 116const int64_t dspark_markov_rank = markov_meta -> ne [0 ]; 117 118dspark_markov_w1 = create_tensor (tn (LLM_TENSOR_DSPARK_MARKOV_W1 ,"weight" ), {dspark_markov_rank ,n_vocab },0 ); 119dspark_markov_w2 = create_tensor (tn (LLM_TENSOR_DSPARK_MARKOV_W2 ,"weight" ), {dspark_markov_rank ,n_vocab_draft },0 ); 120dspark_markov_w2_s = create_tensor (tn (LLM_TENSOR_DSPARK_MARKOV_W2 ,"scale" ), {1 },TENSOR_NOT_REQUIRED ); 121 122dspark_conf_proj = create_tensor (tn (LLM_TENSOR_DSPARK_CONF_PROJ ,"weight" ), {n_embd + dspark_markov_rank ,1 },TENSOR_NOT_REQUIRED ); 123dspark_conf_proj_b = create_tensor (tn (LLM_TENSOR_DSPARK_CONF_PROJ ,"bias" ), {1 },TENSOR_NOT_REQUIRED ); 124 125LLAMA_LOG_INFO ("%s: DFlash with DSpark markov head (rank = %lld)\n" ,__func__ , (long long )dspark_markov_rank ); 126 } 127 128const struct ggml_tensor * selector_meta = ml -> get_tensor_meta ("selector_hidden.weight" ); 129if (selector_meta ) { 130const int64_t rank = hparams .dflash_selector_rank ; 131if (rank <=0 || hparams .dflash_block_size <=0 || hparams .dflash_selector_top_k <=0 || 132hparams .dflash_conv_kernel_size <=0 || hparams .dflash_conv_group_size <=0 ) { 133throw std::runtime_error ("DFlash2 model is missing conv/selector metadata" ); 134 } 135if (n_embd %hparams .dflash_conv_group_size != 0 ) { 136throw std::runtime_error ("DFlash2 hidden size must be divisible by conv_group_size" ); 137 } 138if (n_embd < hparams .dflash_selector_top_k * (hparams .dflash_selector_top_k + 1 )) { 139throw std::runtime_error ("DFlash2 hidden size is too small for the selector lattice" ); 140 } 141 142dflash_selector_prev = create_tensor (tn (LLM_TENSOR_DFLASH_SELECTOR_PREV ,"weight" ), {rank ,n_vocab },0 ); 143dflash_selector_next = create_tensor (tn (LLM_TENSOR_DFLASH_SELECTOR_NEXT ,"weight" ), {rank ,n_vocab },0 ); 144dflash_selector_hidden = create_tensor (tn (LLM_TENSOR_DFLASH_SELECTOR_HIDDEN ,"weight" ), {n_embd ,rank },0 ); 145 146LLAMA_LOG_INFO ("%s: DFlash2 conv kernel = %u, group = %u, selector rank = %u, top-k = %u\n" ,__func__ , 147hparams .dflash_conv_kernel_size ,hparams .dflash_conv_group_size , 148hparams .dflash_selector_rank ,hparams .dflash_selector_top_k ); 149 } 150 151fc = create_tensor (tn (LLM_TENSOR_FC ,"weight" ), {n_embd_inp ,n_embd },0 ); 152fc_s = create_tensor (tn (LLM_TENSOR_FC ,"scale" ), {1 },TENSOR_NOT_REQUIRED ); 153output_norm_enc = create_tensor (tn (LLM_TENSOR_ENC_OUTPUT_NORM ,"weight" ), {n_embd },0 );// encoder hidden_norm (after fc) 154output_norm = create_tensor (tn (LLM_TENSOR_OUTPUT_NORM ,"weight" ), {n_embd },0 );// decoder final norm 155 156// optional: reduced-vocab drafts ship their own lm head, full-vocab drafts can share the target's via ctx_other 157// a draft with its own embeddings + head references no target tensors and can run on devices the target does not use (e.g. -devd with a tensor-split target) 158output = create_tensor (tn (LLM_TENSOR_OUTPUT ,"weight" ), {n_embd ,n_vocab_draft },TENSOR_NOT_REQUIRED ); 159 160if (hparams .dsv4_hc_mult > 0 ) { 161const int64_t q_lora_rank = hparams .n_lora_q ; 162const int64_t n_ff_exp = hparams .n_ff_exp (); 163const int64_t n_expert_shared = hparams .n_expert_shared ; 164const int64_t n_embd_head = hparams .n_embd_head_k (); 165const int64_t o_groups = hparams .dsv4_o_group_count ; 166const int64_t o_lora_rank = hparams .dsv4_o_lora_rank ; 167const int64_t hc_mult = hparams .dsv4_hc_mult ; 168const int64_t hc_dim = hc_mult * n_embd ; 169const int64_t hc_mix_dim = (2 + hc_mult )* hc_mult ; 170 171hc_head_fn = create_tensor (tn (LLM_TENSOR_HC_HEAD_FN ,"weight" ), {hc_dim ,hc_mult },0 ); 172hc_head_base = create_tensor (tn (LLM_TENSOR_HC_HEAD_BASE ,"weight" ), {hc_mult },0 ); 173hc_head_scale = create_tensor (tn (LLM_TENSOR_HC_HEAD_SCALE ,"weight" ), {1 },0 ); 174 175for (int i = 0 ;i < n_layer ;++ i ) { 176auto & layer = layers [i ]; 177 178layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },0 ); 179layer .attn_sinks = create_tensor (tn (LLM_TENSOR_ATTN_SINKS ,"weight" ,i ), {n_head },0 ); 180layer .wq_a = create_tensor (tn (LLM_TENSOR_ATTN_Q_A ,"weight" ,i ), {n_embd ,q_lora_rank },0 ); 181layer .attn_q_a_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_A_NORM ,"weight" ,i ), {q_lora_rank },0 ); 182layer .wq_b = create_tensor (tn (LLM_TENSOR_ATTN_Q_B ,"weight" ,i ), {q_lora_rank ,n_head * n_embd_head },0 ); 183layer .wkv = create_tensor (tn (LLM_TENSOR_ATTN_KV ,"weight" ,i ), {n_embd ,n_embd_head },0 ); 184layer .attn_kv_norm = create_tensor (tn (LLM_TENSOR_ATTN_KV_NORM ,"weight" ,i ), {n_embd_head },0 ); 185layer .wo_a = create_tensor (tn (LLM_TENSOR_ATTN_OUT_A ,"weight" ,i ), {n_head * n_embd_head /o_groups ,o_lora_rank ,o_groups },TENSOR_ALLOW_RESHAPE ); 186layer .wo_b = create_tensor (tn (LLM_TENSOR_ATTN_OUT_B ,"weight" ,i ), {o_groups * o_lora_rank ,n_embd },0 ); 187 188layer .hc_attn_fn = create_tensor (tn (LLM_TENSOR_HC_ATTN_FN ,"weight" ,i ), {hc_dim ,hc_mix_dim },0 ); 189layer .hc_attn_base = create_tensor (tn (LLM_TENSOR_HC_ATTN_BASE ,"weight" ,i ), {hc_mix_dim },0 ); 190layer .hc_attn_scale = create_tensor (tn (LLM_TENSOR_HC_ATTN_SCALE ,"weight" ,i ), {3 },0 ); 191layer .hc_ffn_fn = create_tensor (tn (LLM_TENSOR_HC_FFN_FN ,"weight" ,i ), {hc_dim ,hc_mix_dim },0 ); 192layer .hc_ffn_base = create_tensor (tn (LLM_TENSOR_HC_FFN_BASE ,"weight" ,i ), {hc_mix_dim },0 ); 193layer .hc_ffn_scale = create_tensor (tn (LLM_TENSOR_HC_FFN_SCALE ,"weight" ,i ), {3 },0 ); 194 195layer .ffn_gate_inp = create_tensor (tn (LLM_TENSOR_FFN_GATE_INP ,"weight" ,i ), {n_embd ,n_expert },0 ); 196layer .ffn_exp_probs_b = create_tensor (tn (LLM_TENSOR_FFN_EXP_PROBS_B ,"bias" ,i ), {n_expert },0 ); 197layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },0 ); 198 199layer .ffn_gate_exps = create_tensor (tn (LLM_TENSOR_FFN_GATE_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 200layer .ffn_down_exps = create_tensor (tn (LLM_TENSOR_FFN_DOWN_EXPS ,"weight" ,i ), {n_ff_exp ,n_embd ,n_expert },0 ); 201layer .ffn_up_exps = create_tensor (tn (LLM_TENSOR_FFN_UP_EXPS ,"weight" ,i ), {n_embd ,n_ff_exp ,n_expert },0 ); 202 203layer .ffn_gate_shexp = create_tensor (tn (LLM_TENSOR_FFN_GATE_SHEXP ,"weight" ,i ), {n_embd ,n_ff_exp * n_expert_shared },0 ); 204layer .ffn_down_shexp = create_tensor (tn (LLM_TENSOR_FFN_DOWN_SHEXP ,"weight" ,i ), {n_ff_exp * n_expert_shared ,n_embd },0 ); 205layer .ffn_up_shexp = create_tensor (tn (LLM_TENSOR_FFN_UP_SHEXP ,"weight" ,i ), {n_embd ,n_ff_exp * n_expert_shared },0 ); 206 } 207return ; 208 } 209 210for (int i = 0 ;i < n_layer ;++ i ) { 211auto & layer = layers [i ]; 212 213layer .attn_norm = create_tensor (tn (LLM_TENSOR_ATTN_NORM ,"weight" ,i ), {n_embd },0 ); 214 215layer .wq = create_tensor (tn (LLM_TENSOR_ATTN_Q ,"weight" ,i ), {n_embd ,n_embd_head_k * n_head },0 ); 216layer .wk = create_tensor (tn (LLM_TENSOR_ATTN_K ,"weight" ,i ), {n_embd ,n_embd_k_gqa },0 ); 217layer .wv = create_tensor (tn (LLM_TENSOR_ATTN_V ,"weight" ,i ), {n_embd ,n_embd_v_gqa },0 ); 218layer .wo = create_tensor (tn (LLM_TENSOR_ATTN_OUT ,"weight" ,i ), {n_embd_head_k * n_head ,n_embd },0 ); 219 220layer .attn_q_norm = create_tensor (tn (LLM_TENSOR_ATTN_Q_NORM ,"weight" ,i ), {n_embd_head_k },0 ); 221layer .attn_k_norm = create_tensor (tn (LLM_TENSOR_ATTN_K_NORM ,"weight" ,i ), {n_embd_head_k },0 ); 222 223// optional per-head attention sinks (e.g. Nemotron DSpark) 224layer .attn_sinks = create_tensor (tn (LLM_TENSOR_ATTN_SINKS ,"weight" ,i ), {n_head },TENSOR_NOT_REQUIRED ); 225 226layer .ffn_norm = create_tensor (tn (LLM_TENSOR_FFN_NORM ,"weight" ,i ), {n_embd },0 ); 227layer .ffn_gate = create_tensor (tn (LLM_TENSOR_FFN_GATE ,"weight" ,i ), {n_embd ,n_ff },0 ); 228layer .ffn_down = create_tensor (tn (LLM_TENSOR_FFN_DOWN ,"weight" ,i ), {n_ff ,n_embd },0 ); 229layer .ffn_up = create_tensor (tn (LLM_TENSOR_FFN_UP ,"weight" ,i ), {n_embd ,n_ff },0 ); 230 231if (selector_meta ) { 232const int64_t kernel = hparams .dflash_conv_kernel_size ; 233const int64_t groups = n_embd /hparams .dflash_conv_group_size ; 234const int64_t projected = 2 * kernel * groups ; 235layer .dflash_attn_conv_base = create_tensor (tn (LLM_TENSOR_DFLASH_ATTN_CONV_BASE ,i ), {n_embd ,kernel ,2 },0 ); 236layer .dflash_attn_conv_proj = create_tensor (tn (LLM_TENSOR_DFLASH_ATTN_CONV_PROJ ,"weight" ,i ), {n_embd ,projected },0 ); 237layer .dflash_ffn_conv_base = create_tensor (tn (LLM_TENSOR_DFLASH_FFN_CONV_BASE ,i ), {n_embd ,kernel ,2 },0 ); 238layer .dflash_ffn_conv_proj = create_tensor (tn (LLM_TENSOR_DFLASH_FFN_CONV_PROJ ,"weight" ,i ), {n_embd ,projected },0 ); 239 } 240 } 241} 242 243std::unique_ptr < llm_graph_context > llama_model_dflash::build_arch_graph (const llm_graph_params & params )const { 244switch (params .gtype ) { 245case LLM_GRAPH_TYPE_ENCODER : 246return std::make_unique < graph < true>> (* this ,params ); 247case LLM_GRAPH_TYPE_DEFAULT : 248case LLM_GRAPH_TYPE_DECODER : 249if (hparams .dsv4_hc_mult > 0 ) { 250return std::make_unique < graph_dsv4 > (* this ,params ); 251 } 252return std::make_unique < graph < false>> (* this ,params ); 253default : 254GGML_ABORT ("invalid graph type" ); 255 }; 256} 257 258template <> 259ggml_tensor * llama_model_dflash::graph < true> ::build_inp_embd_enc ()const { 260const int64_t n_embd_inp = hparams .n_embd_inp_enc (); 261auto inp_target = std::make_unique < llm_graph_input_embd > (n_embd_inp ); 262 263inp_target -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,n_embd_inp ,n_tokens ); 264ggml_set_input (inp_target -> embd ); 265 266ggml_tensor * cur = inp_target -> embd ; 267cb (cur ,"inp_embd" ,-1 ); 268 269res -> add_input (std::move (inp_target )); 270 271return cur ; 272} 273 274// DFlash Encoder: processes target model features through feature fusion layer 275template <> 276llama_model_dflash::graph < true> ::graph (const llama_model & model ,const llm_graph_params & params ) :llm_graph_context (params ) { 277ggml_tensor * cur = build_inp_embd_enc (); 278 279cur = build_lora_mm (model .fc ,cur ,model .fc_s ); 280cb (cur ,"fc_out" ,-1 ); 281 282cur = build_norm (cur ,model .output_norm_enc ,NULL ,LLM_NORM_RMS ,-1 ); 283cb (cur ,"enc_norm_out" ,-1 ); 284 285ggml_set_output (cur ); 286res -> t_h_nextn = cur ; 287 288ggml_build_forward_expand (gf ,cur ); 289} 290 291// DSpark (DFlash + Markov & Confidence head): Markov bias on the draft logits, chained per block position 292static void build_dspark_markov_head (llm_graph_context & g ,const llama_model & model ,ggml_tensor * tokens ) { 293ggml_context * ctx0 = g .ctx0 ; 294auto & res = g .res ; 295 296ggml_tensor * w1 = model .dspark_markov_w1 ; 297ggml_tensor * w2 = model .dspark_markov_w2 ; 298GGML_ASSERT (w1 && w2 && "DSpark markov weights not loaded" ); 299 300// confidence head is optional 301const bool has_conf = model .dspark_conf_proj != nullptr ; 302 303ggml_tensor * base = res -> t_logits ;// [n_vocab, n_tokens] 304const int64_t n_vocab = base -> ne [0 ]; 305const int64_t n_tok = base -> ne [1 ]; 306 307const auto it = model .gguf_kv .find ("dflash.block_size" ); 308GGML_ASSERT (it != model .gguf_kv .end ()&& "DSpark draft requires 'dflash.block_size' in GGUF metadata" ); 309const int64_t block_size = std::stoi (it -> second ); 310GGML_ASSERT (block_size > 0 ); 311 312// bonus anchor (SpecForge exports): slot 0 is a bonus token, not a prediction slot 313const auto it_anchor = model .gguf_kv .find ("dflash.sample_from_anchor" ); 314const bool sample_from_anchor = it_anchor == model .gguf_kv .end ()|| it_anchor -> second == "true" ; 315const int64_t i_draft_beg = sample_from_anchor ?0 :1 ; 316 317const int64_t n_blocks = g .ubatch .n_seqs_unq ; 318GGML_ASSERT (n_blocks > 0 && n_tok %n_blocks == 0 && "DSpark markov head requires equal-size blocks" ); 319// runtime tokens per block in this ubatch (anchor + drafted positions), bounded by training block_size 320const int64_t block_drafts = n_tok /n_blocks ; 321if (block_drafts > block_size ) { 322return ; 323 } 324 325// anchor (committed last) token of every block: token 0 of each block, i.e. a strided view 326const size_t token_stride = (size_t )block_drafts * tokens -> nb [0 ]; 327const size_t base_stride = (size_t )block_drafts * base -> nb [1 ]; 328 329ggml_tensor * prev = ggml_view_2d (ctx0 ,tokens ,1 ,n_blocks ,token_stride ,0 ); 330prev = ggml_cont_1d (ctx0 ,prev ,n_blocks ); 331 332ggml_tensor * cat = nullptr ; 333ggml_tensor * cat_conf = nullptr ; 334 335if (!sample_from_anchor ) { 336// bonus anchor slot: pass the logits through unbiased, pad the (unread) confidence column 337cat = ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,base ,n_vocab ,n_blocks ,base_stride ,0 )); 338if (has_conf ) { 339cat_conf = ggml_sigmoid (ctx0 ,ggml_cont (ctx0 ,ggml_view_2d (ctx0 ,base ,1 ,n_blocks ,base_stride ,0 ))); 340 } 341 } 342 343// TODO: the in-graph chain is greedy (argmax); sampling params affect only the final 344// token pick, not the Markov conditioning path 345for (int64_t i = i_draft_beg ;i < block_drafts ;++ i ) { 346ggml_tensor * w1_prev = ggml_get_rows (ctx0 ,w1 ,prev );// [R, n_blocks] 347ggml_tensor * bias = g .build_lora_mm (w2 ,w1_prev ,model .dspark_markov_w2_s );// [n_vocab_draft, n_blocks] 348if (model .d2t ) { 349// reduced draft vocab: scatter the bias to the target rows (base is -inf on the others) 350const int64_t n_draft_vocab = bias -> ne [0 ]; 351ggml_tensor * full = ggml_fill (ctx0 ,ggml_new_tensor_3d (ctx0 ,GGML_TYPE_F32 ,1 ,n_vocab ,n_blocks ),0.0f ); 352bias = ggml_set_rows (ctx0 ,full , 353ggml_reshape_3d (ctx0 ,bias ,1 ,n_draft_vocab ,n_blocks ), 354ggml_reshape_3d (ctx0 ,model .d2t ,n_draft_vocab ,1 ,1 )); 355bias = ggml_reshape_2d (ctx0 ,bias ,n_vocab ,n_blocks ); 356 } 357 358// position i of every block: strided view [n_vocab, n_blocks] 359ggml_tensor * base_i = ggml_view_2d (ctx0 ,base ,n_vocab ,n_blocks ,base_stride ,i * base -> nb [1 ]); 360ggml_tensor * col = ggml_add (ctx0 ,base_i ,bias ); 361 362cat = cat ?ggml_concat (ctx0 ,cat ,col ,1 ) :col ; 363 364if (has_conf ) { 365// confidence head input: predicts per-position acceptance 366ggml_tensor * conf_inp = res -> t_embd ;// [n_embd, n_tok] 367// conf(i) = sigmoid(conf_proj . [conf_inp(i); markov_w1[prev(i)]] + b) -- [1, n_blocks] 368ggml_tensor * conf_inp_i = ggml_view_2d (ctx0 ,conf_inp ,conf_inp -> ne [0 ],n_blocks , 369 (size_t )block_drafts * conf_inp -> nb [1 ],i * conf_inp -> nb [1 ]); 370ggml_tensor * feat = ggml_concat (ctx0 ,ggml_cont (ctx0 ,conf_inp_i ),w1_prev ,0 ); 371ggml_tensor * conf = ggml_mul_mat (ctx0 ,model .dspark_conf_proj ,feat ); 372if (model .dspark_conf_proj_b ) { 373conf = ggml_add (ctx0 ,conf ,model .dspark_conf_proj_b ); 374 } 375conf = ggml_sigmoid (ctx0 ,conf ); 376 377cat_conf = cat_conf ?ggml_concat (ctx0 ,cat_conf ,conf ,1 ) :conf ; 378 } 379 380if (i + 1 < block_drafts ) { 381prev = ggml_argmax (ctx0 ,col ); 382 } 383 } 384 385// cat is position-major; restore ubatch block-major order 386ggml_tensor * out = ggml_reshape_3d (ctx0 ,cat ,n_vocab ,n_blocks ,block_drafts ); 387out = ggml_cont (ctx0 ,ggml_permute (ctx0 ,out ,0 ,2 ,1 ,3 ));// [n_vocab, block_drafts, n_blocks] 388out = ggml_reshape_2d (ctx0 ,out ,n_vocab ,n_tok ); 389 390if (has_conf ) { 391ggml_tensor * conf = ggml_reshape_3d (ctx0 ,cat_conf ,1 ,n_blocks ,block_drafts ); 392conf = ggml_cont (ctx0 ,ggml_permute (ctx0 ,conf ,0 ,2 ,1 ,3 )); 393conf = ggml_reshape_2d (ctx0 ,conf ,1 ,n_tok ); 394 395// note: broadcast the [1, n_tok] confidences to n_embd-wide rows to be able to reuse `llama_get_embeddings_nextn` 396conf = ggml_repeat (ctx0 ,conf ,res -> t_embd ); 397res -> t_h_nextn = conf ; 398ggml_build_forward_expand (g .gf ,conf ); 399 } 400 401res -> t_logits = out ; 402ggml_build_forward_expand (g .gf ,out ); 403} 404 405static ggml_tensor * build_dflash2_conv ( 406llm_graph_context & g , 407ggml_tensor * hidden , 408ggml_tensor * dynamic , 409ggml_tensor * base , 410int side ) { 411const auto & hparams = g .hparams ; 412const int64_t hidden_size = hidden -> ne [0 ]; 413const int64_t n_tokens = hidden -> ne [1 ]; 414const int64_t n_blocks = g .ubatch .n_seqs_unq ; 415const int64_t kernel_size = hparams .dflash_conv_kernel_size ; 416const int64_t group_size = hparams .dflash_conv_group_size ; 417const int64_t n_groups = hidden_size /group_size ; 418 419GGML_ASSERT (n_blocks > 0 && n_tokens %n_blocks == 0 ); 420GGML_ASSERT (dynamic && base && side >=0 && side < 2 ); 421 422const int64_t block_size = n_tokens /n_blocks ; 423ggml_context * ctx0 = g .ctx0 ; 424// ggml_cont copies even when the tensor is already contiguous 425if (!ggml_is_contiguous (hidden )|| hidden -> ne [1 ]!= n_tokens ) { 426hidden = ggml_cont_2d (ctx0 ,hidden ,hidden_size ,n_tokens ); 427 } 428if (!ggml_is_contiguous (dynamic )|| dynamic -> ne [1 ]!= n_tokens ) { 429dynamic = ggml_cont_2d (ctx0 ,dynamic ,dynamic -> ne [0 ],n_tokens ); 430 } 431ggml_tensor * blocks = ggml_reshape_3d (ctx0 ,hidden ,hidden_size ,block_size ,n_blocks ); 432ggml_tensor * coeffs = ggml_reshape_4d (ctx0 ,dynamic ,n_groups ,kernel_size ,2 ,n_tokens ); 433ggml_tensor * coeffs_side = ggml_view_3d (ctx0 ,coeffs ,n_groups ,kernel_size ,n_tokens , 434coeffs -> nb [1 ],coeffs -> nb [3 ],side * coeffs -> nb [2 ]); 435 436ggml_tensor * coeff_all = ggml_cont (ctx0 ,coeffs_side ); 437coeff_all = ggml_reshape_4d (ctx0 ,coeff_all ,1 ,n_groups ,kernel_size ,n_tokens ); 438coeff_all = ggml_repeat_4d (ctx0 ,coeff_all ,group_size ,n_groups ,kernel_size ,n_tokens ); 439 440ggml_tensor * base_side = ggml_reshape_4d (ctx0 , 441ggml_view_1d (ctx0 ,base ,hidden_size * kernel_size ,side * base -> nb [2 ]), 442group_size ,n_groups ,kernel_size ,1 ); 443 444ggml_tensor * weight_all = ggml_add (ctx0 ,coeff_all ,base_side ); 445 446ggml_tensor * result = nullptr ; 447for (int64_t tap = 0 ;tap < kernel_size ;++ tap ) { 448ggml_tensor * values = blocks ; 449if (tap > 0 ) { 450ggml_tensor * zeros = ggml_fill (ctx0 , 451ggml_new_tensor_3d (ctx0 ,hidden -> type ,hidden_size , std::min (tap ,block_size ),n_blocks ),0.0f ); 452if (tap < block_size ) { 453ggml_tensor * previous = ggml_view_3d (ctx0 ,blocks ,hidden_size ,block_size - tap ,n_blocks , 454blocks -> nb [1 ],blocks -> nb [2 ],0 ); 455values = ggml_concat (ctx0 ,zeros ,previous ,1 ); 456 }else { 457values = zeros ; 458 } 459 } 460values = ggml_reshape_2d (ctx0 ,values ,hidden_size ,n_tokens ); 461 462ggml_tensor * weight = ggml_reshape_2d (ctx0 , 463ggml_cont (ctx0 ,ggml_view_4d (ctx0 ,weight_all ,group_size ,n_groups ,1 ,n_tokens , 464weight_all -> nb [1 ],weight_all -> nb [2 ],weight_all -> nb [3 ],tap * weight_all -> nb [2 ])), 465hidden_size ,n_tokens ); 466 467ggml_tensor * term = ggml_mul (ctx0 ,weight ,values ); 468result = result ?ggml_add (ctx0 ,result ,term ) :term ; 469 } 470return result ; 471} 472 473// DFlash2 selector: top-k candidates per block position plus the pairwise 474// transition scores, packed into the nextn output slot for the CPU-side walk. 475static void build_dflash2_selector (llm_graph_context & g ,const llama_model & model ,ggml_tensor * tokens ) { 476ggml_context * ctx0 = g .ctx0 ; 477auto & res = g .res ; 478 479const auto & hparams = g .hparams ; 480const int64_t n_tokens = g .n_tokens ; 481const int64_t n_embd = g .n_embd ; 482 483const int64_t top_k = hparams .dflash_selector_top_k ; 484const int64_t rank = hparams .dflash_selector_rank ; 485const int64_t n_blocks = g .ubatch .n_seqs_unq ; 486GGML_ASSERT (n_blocks > 0 && n_tokens %n_blocks == 0 ); 487GGML_ASSERT (res -> t_logits -> ne [1 ]== n_tokens ); 488if (!tokens ) { 489return ; 490 } 491 492const int64_t tokens_per_block = n_tokens /n_blocks ; 493const int64_t block_size = std::min < int64_t > (tokens_per_block ,hparams .dflash_block_size ); 494const int64_t row_used = top_k + top_k * top_k ; 495 496ggml_tensor * candidates = ggml_top_k (ctx0 ,res -> t_logits ,top_k ); 497ggml_tensor * logits_rows = ggml_reshape_3d (ctx0 ,res -> t_logits ,1 ,res -> t_logits -> ne [0 ],n_tokens ); 498ggml_tensor * unary = ggml_reshape_2d (ctx0 , 499ggml_get_rows (ctx0 ,logits_rows ,candidates ),top_k ,n_tokens ); 500ggml_tensor * gate = g .build_lora_mm (model .dflash_selector_hidden ,res -> t_embd ); 501 502// Everything below indexes [.., tokens_per_block, n_blocks]: the block 503// position varies fastest, sequences are the outer dimension. 504ggml_tensor * cand_blk = ggml_reshape_3d (ctx0 ,candidates ,top_k ,tokens_per_block ,n_blocks ); 505ggml_tensor * unary_blk = ggml_reshape_3d (ctx0 ,unary ,top_k ,tokens_per_block ,n_blocks ); 506ggml_tensor * gate_blk = ggml_reshape_3d (ctx0 ,gate ,rank ,tokens_per_block ,n_blocks ); 507 508// a position's score reads only the candidate sets at pos-1 and pos, so a run 509// of positions has no internal dependency and scores in one batched matmul 510auto score_run = [& ](int64_t beg_pos ,int64_t n_pos ,ggml_tensor * pred_ids ) { 511ggml_tensor * cand_run = ggml_cont (ctx0 ,ggml_view_3d (ctx0 ,cand_blk ,top_k ,n_pos ,n_blocks , 512cand_blk -> nb [1 ],cand_blk -> nb [2 ],beg_pos * cand_blk -> nb [1 ])); 513ggml_tensor * unary_run = ggml_cont (ctx0 ,ggml_view_3d (ctx0 ,unary_blk ,top_k ,n_pos ,n_blocks , 514unary_blk -> nb [1 ],unary_blk -> nb [2 ],beg_pos * unary_blk -> nb [1 ])); 515ggml_tensor * gate_run = ggml_cont (ctx0 ,ggml_view_3d (ctx0 ,gate_blk ,rank ,n_pos ,n_blocks , 516gate_blk -> nb [1 ],gate_blk -> nb [2 ],beg_pos * gate_blk -> nb [1 ])); 517 518const int64_t n_pred = pred_ids -> ne [0 ] / (n_pos * n_blocks ); 519 520ggml_tensor * successor = ggml_reshape_4d (ctx0 , 521ggml_get_rows (ctx0 ,model .dflash_selector_next ,ggml_reshape_1d (ctx0 ,cand_run ,top_k * n_pos * n_blocks )), 522rank ,top_k ,n_pos ,n_blocks ); 523ggml_tensor * predecessor = ggml_reshape_4d (ctx0 , 524ggml_get_rows (ctx0 ,model .dflash_selector_prev ,pred_ids ), 525rank ,n_pred ,n_pos ,n_blocks ); 526 527ggml_tensor * gate_bcast = ggml_reshape_4d (ctx0 ,gate_run ,rank ,1 ,n_pos ,n_blocks ); 528ggml_tensor * cond = ggml_mul (ctx0 ,predecessor ,ggml_repeat (ctx0 ,gate_bcast ,predecessor )); 529ggml_tensor * score = ggml_mul_mat (ctx0 ,successor ,cond ); 530if (n_pred == 1 ) { 531score = ggml_repeat_4d (ctx0 ,score ,top_k ,top_k ,n_pos ,n_blocks ); 532 } 533ggml_tensor * unary_bcast = ggml_reshape_4d (ctx0 ,unary_run ,top_k ,1 ,n_pos ,n_blocks ); 534score = ggml_add (ctx0 ,score ,ggml_repeat (ctx0 ,unary_bcast ,score )); 535 536ggml_tensor * row = ggml_concat (ctx0 , 537ggml_cast (ctx0 ,cand_run ,GGML_TYPE_F32 ), 538ggml_reshape_3d (ctx0 ,score ,top_k * top_k ,n_pos ,n_blocks ),0 ); 539return ggml_pad (ctx0 ,row ,n_embd - row_used ,0 ,0 ,0 ); 540 }; 541 542ggml_tensor * packed = ggml_fill (ctx0 , 543ggml_new_tensor_3d (ctx0 ,GGML_TYPE_F32 ,n_embd ,1 ,n_blocks ),0.0f ); 544 545if (block_size > 1 ) { 546// Position 1 alone: its predecessor is the anchor token, one id per 547// sequence rather than a candidate set. 548ggml_tensor * anchor_ids = ggml_cont_1d (ctx0 , 549ggml_view_2d (ctx0 ,tokens ,1 ,n_blocks ,tokens_per_block * tokens -> nb [0 ],0 ),n_blocks ); 550packed = ggml_concat (ctx0 ,packed ,score_run (1 ,1 ,anchor_ids ),1 ); 551 } 552if (block_size > 2 ) { 553ggml_tensor * prev_ids = ggml_reshape_1d (ctx0 , 554ggml_cont (ctx0 ,ggml_view_3d (ctx0 ,cand_blk ,top_k ,block_size - 2 ,n_blocks , 555cand_blk -> nb [1 ],cand_blk -> nb [2 ],cand_blk -> nb [1 ])), 556top_k * (block_size - 2 )* n_blocks ); 557packed = ggml_concat (ctx0 ,packed ,score_run (2 ,block_size - 2 ,prev_ids ),1 ); 558 } 559 560packed = ggml_reshape_2d (ctx0 ,packed ,n_embd ,block_size * n_blocks ); 561g .cb (packed ,"dflash2_lattice" ,-1 ); 562res -> t_h_nextn = packed ; 563ggml_build_forward_expand (g .gf ,packed ); 564} 565 566// DFlash decoder, dual-mode by batch type: 567// * embd batch -> fused target features: project + inject K/V into the cache. 568// * token batch -> noise-block diffusion: attend over [committed, MASK...] to generate draft tokens 569template <> 570llama_model_dflash::graph < false> ::graph (const llama_model & model ,const llm_graph_params & params ) :llm_graph_context (params ) { 571const int64_t n_embd_inp = hparams .n_embd_inp_enc (); 572const int64_t n_embd_head = hparams .n_embd_head_v (); 573 574GGML_ASSERT (n_embd_head == hparams .n_embd_head_k ()); 575 576ggml_tensor * inp_pos = build_inp_pos (); 577 578// optional iSWA: pick the matching attention input 579const bool use_iswa = hparams .swa_type != LLAMA_SWA_TYPE_NONE ; 580 581llm_graph_input_attn_kv * inp_attn = nullptr ; 582llm_graph_input_attn_kv_iswa * inp_attn_iswa = nullptr ; 583if (use_iswa ) { 584inp_attn_iswa = build_attn_inp_kv_iswa (); 585 }else { 586inp_attn = build_attn_inp_kv (); 587 } 588 589const float kq_scale = 1.0f /sqrtf (float (n_embd_head )); 590 591// drafts for M-RoPE targets use degenerate sections (temporal dim only) 592int sections [4 ]; 593 std::copy (std::begin (hparams .rope_sections ), std::begin (hparams .rope_sections )+ 4 ,sections ); 594 595auto build_rope = [& ](ggml_tensor * cur ,ggml_tensor * pos ) { 596return rope_type == GGML_ROPE_TYPE_MROPE 597 ?ggml_rope_multi (ctx0 ,cur ,pos ,nullptr , 598n_rot ,sections ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 599ext_factor ,attn_factor ,beta_fast ,beta_slow ) 600 :ggml_rope_ext (ctx0 ,cur ,pos ,nullptr , 601n_rot ,rope_type ,n_ctx_orig ,freq_base ,freq_scale , 602ext_factor ,attn_factor ,beta_fast ,beta_slow ); 603 }; 604 605// KV cache injection 606if (ubatch .embd ) { 607auto inp = std::make_unique < llm_graph_input_embd > (n_embd_inp ); 608 609inp -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,n_embd_inp ,n_tokens ); 610ggml_set_input (inp -> embd ); 611 612ggml_tensor * inp_target = inp -> embd ; 613cb (inp_target ,"inp_target_features" ,-1 ); 614 615res -> add_input (std::move (inp )); 616 617// fuse the target features through the encoder 618ggml_tensor * inp_g = build_lora_mm (model .fc ,inp_target ,model .fc_s ); 619inp_g = build_norm (inp_g ,model .output_norm_enc ,NULL ,LLM_NORM_RMS ,-1 ); 620cb (inp_g ,"inp_g_embeddings" ,-1 ); 621 622for (int il = 0 ;il < n_layer ;++ il ) { 623const auto & layer = model .layers [il ]; 624 625ggml_tensor * Kcur = build_lora_mm (layer .wk ,inp_g ,layer .wk_s ); 626ggml_tensor * Vcur = build_lora_mm (layer .wv ,inp_g ,layer .wv_s ); 627 628Kcur = ggml_reshape_3d (ctx0 ,Kcur ,n_embd_head ,n_head_kv ,n_tokens ); 629Vcur = ggml_reshape_3d (ctx0 ,Vcur ,n_embd_head ,n_head_kv ,n_tokens ); 630 631Kcur = build_norm (Kcur ,layer .attn_k_norm ,NULL ,LLM_NORM_RMS ,il ); 632Kcur = build_rope (Kcur ,inp_pos ); 633cb (Kcur ,"Kcur_injected" ,il ); 634cb (Vcur ,"Vcur_injected" ,il ); 635 636if (use_iswa ) { 637// route each layer's K/V to its sub-cache: SWA layers -> sliding cache, full -> dense 638const bool is_swa = hparams .is_swa (il ); 639const auto * kv = is_swa ?inp_attn_iswa -> mctx -> get_swa () :inp_attn_iswa -> mctx -> get_base (); 640ggml_tensor * k_idxs = is_swa ?inp_attn_iswa -> get_k_idxs_swa () :inp_attn_iswa -> get_k_idxs (); 641ggml_tensor * v_idxs = is_swa ?inp_attn_iswa -> get_v_idxs_swa () :inp_attn_iswa -> get_v_idxs (); 642// rotate K/V into the cache's rotated space 643ggml_tensor * k_rot = is_swa ?inp_attn_iswa -> self_k_rot_swa :inp_attn_iswa -> self_k_rot ; 644ggml_tensor * v_rot = is_swa ?inp_attn_iswa -> self_v_rot_swa :inp_attn_iswa -> self_v_rot ; 645if (k_rot ) { 646Kcur = llama_mul_mat_hadamard (ctx0 ,Kcur ,k_rot ); 647 } 648if (v_rot ) { 649Vcur = llama_mul_mat_hadamard (ctx0 ,Vcur ,v_rot ); 650 } 651ggml_build_forward_expand (gf ,kv -> cpy_k (ctx0 ,Kcur ,k_idxs ,il )); 652ggml_build_forward_expand (gf ,kv -> cpy_v (ctx0 ,Vcur ,v_idxs ,il )); 653 }else { 654// rotate K/V into the cache's rotated space 655if (inp_attn -> self_k_rot ) { 656Kcur = llama_mul_mat_hadamard (ctx0 ,Kcur ,inp_attn -> self_k_rot ); 657 } 658if (inp_attn -> self_v_rot ) { 659Vcur = llama_mul_mat_hadamard (ctx0 ,Vcur ,inp_attn -> self_v_rot ); 660 } 661ggml_build_forward_expand (gf ,inp_attn -> mctx -> cpy_k (ctx0 ,Kcur ,inp_attn -> get_k_idxs (),il )); 662ggml_build_forward_expand (gf ,inp_attn -> mctx -> cpy_v (ctx0 ,Vcur ,inp_attn -> get_v_idxs (),il )); 663 } 664 } 665 666res -> t_embd = inp_g ; 667 668ggml_build_forward_expand (gf ,inp_g ); 669return ; 670 } 671 672// tok_embd from the target model (shared via ctx_other) 673auto * tok_embd = model .tok_embd ; 674if (tok_embd == nullptr ) { 675GGML_ASSERT (cparams .ctx_other != nullptr ); 676const auto * model_other = llama_get_model (cparams .ctx_other ); 677 678GGML_ASSERT (model_other -> tok_embd != nullptr && "DFlash decoder requires the target model's token embeddings" ); 679tok_embd = model_other -> tok_embd ; 680 } 681 682auto inp = std::make_unique < llm_graph_input_embd > (n_embd ); 683 684inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_tokens ); 685ggml_set_input (inp -> tokens ); 686res -> t_inp_tokens = inp -> tokens ; 687 688ggml_tensor * inp_tokens = inp -> tokens ; 689 690ggml_tensor * inpL = ggml_get_rows (ctx0 ,tok_embd ,inp -> tokens ); 691cb (inpL ,"inp_noise_embd" ,-1 ); 692 693res -> add_input (std::move (inp )); 694 695for (int il = 0 ;il < n_layer ;++ il ) { 696const auto & layer = model .layers [il ]; 697 698ggml_tensor * noise_norm = build_norm (inpL ,layer .attn_norm ,NULL ,LLM_NORM_RMS ,il ); 699cb (noise_norm ,"noise_norm" ,il ); 700 701ggml_tensor * attn_dynamic = nullptr ; 702if (layer .dflash_attn_conv_proj ) { 703attn_dynamic = build_lora_mm (layer .dflash_attn_conv_proj ,noise_norm ); 704noise_norm = build_dflash2_conv (* this ,noise_norm ,attn_dynamic ,layer .dflash_attn_conv_base ,0 ); 705cb (noise_norm ,"attn_conv_in" ,il ); 706 } 707 708ggml_tensor * Qcur = build_lora_mm (layer .wq ,noise_norm ,layer .wq_s ); 709ggml_tensor * Kcur = build_lora_mm (layer .wk ,noise_norm ,layer .wk_s ); 710ggml_tensor * Vcur = build_lora_mm (layer .wv ,noise_norm ,layer .wv_s ); 711 712Qcur = ggml_reshape_3d (ctx0 ,Qcur ,n_embd_head ,n_head ,n_tokens ); 713Kcur = ggml_reshape_3d (ctx0 ,Kcur ,n_embd_head ,n_head_kv ,n_tokens ); 714Vcur = ggml_reshape_3d (ctx0 ,Vcur ,n_embd_head ,n_head_kv ,n_tokens ); 715 716Qcur = build_norm (Qcur ,layer .attn_q_norm ,NULL ,LLM_NORM_RMS ,il ); 717Kcur = build_norm (Kcur ,layer .attn_k_norm ,NULL ,LLM_NORM_RMS ,il ); 718 719Qcur = build_rope (Qcur ,inp_pos ); 720Kcur = build_rope (Kcur ,inp_pos ); 721cb (Qcur ,"Qcur" ,il ); 722cb (Kcur ,"Kcur" ,il ); 723cb (Vcur ,"Vcur" ,il ); 724 725// cache-aware, non-causal attention 726ggml_tensor * cur = use_iswa 727 ?build_attn (inp_attn_iswa ,layer .wo ,NULL ,layer .wo_s ,Qcur ,Kcur ,Vcur ,nullptr ,layer .attn_sinks ,nullptr ,kq_scale ,il ) 728 :build_attn (inp_attn ,layer .wo ,NULL ,layer .wo_s ,Qcur ,Kcur ,Vcur ,nullptr ,layer .attn_sinks ,nullptr ,kq_scale ,il ); 729 730if (attn_dynamic ) { 731cur = build_dflash2_conv (* this ,cur ,attn_dynamic ,layer .dflash_attn_conv_base ,1 ); 732cb (cur ,"attn_conv_out" ,il ); 733 } 734 735ggml_tensor * ffn_inp = ggml_add (ctx0 ,cur ,inpL ); 736cb (ffn_inp ,"ffn_inp" ,il ); 737 738cur = build_norm (ffn_inp ,layer .ffn_norm ,NULL ,LLM_NORM_RMS ,il ); 739cb (cur ,"ffn_norm" ,il ); 740 741ggml_tensor * ffn_dynamic = nullptr ; 742if (layer .dflash_ffn_conv_proj ) { 743ffn_dynamic = build_lora_mm (layer .dflash_ffn_conv_proj ,cur ); 744cur = build_dflash2_conv (* this ,cur ,ffn_dynamic ,layer .dflash_ffn_conv_base ,0 ); 745cb (cur ,"ffn_conv_in" ,il ); 746 } 747 748cur = build_ffn (cur , 749layer .ffn_up ,NULL ,layer .ffn_up_s , 750layer .ffn_gate ,NULL ,layer .ffn_gate_s , 751layer .ffn_down ,NULL ,layer .ffn_down_s , 752NULL , 753LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 754cb (cur ,"ffn_out" ,il ); 755 756if (ffn_dynamic ) { 757cur = build_dflash2_conv (* this ,cur ,ffn_dynamic ,layer .dflash_ffn_conv_base ,1 ); 758cb (cur ,"ffn_conv_out" ,il ); 759 } 760 761cur = ggml_add (ctx0 ,cur ,ffn_inp ); 762cb (cur ,"l_out" ,il ); 763 764inpL = cur ; 765 } 766 767ggml_tensor * cur = build_norm (inpL ,model .output_norm ,NULL ,LLM_NORM_RMS ,-1 ); 768cb (cur ,"result_norm" ,-1 ); 769 770res -> t_embd = cur ; 771 772// lm_head from the target model (shared via ctx_other) 773auto * output = model .output ; 774auto * output_s = model .output_s ; 775if (output == nullptr ) { 776GGML_ASSERT (cparams .ctx_other != nullptr ); 777const auto * model_other = llama_get_model (cparams .ctx_other ); 778GGML_ASSERT (model_other -> output != nullptr && "DFlash decoder requires the target model's output projection" ); 779output = model_other -> output ; 780output_s = model_other -> output_s ; 781 } 782 783cur = build_lora_mm (output ,cur ,output_s ); 784 785// DFlash2 feeds these logits to the selector, so they need the target's output 786// transforms; DFlash1 and DSpark read them through the sampler instead 787if (model .dflash_selector_hidden ) { 788if (hparams .f_logit_scale != 0.0f ) { 789cur = ggml_scale (ctx0 ,cur ,hparams .f_logit_scale ); 790 } 791if (hparams .f_final_logit_softcapping > 0.0f ) { 792cur = ggml_scale (ctx0 ,cur ,1.0f /hparams .f_final_logit_softcapping ); 793cur = ggml_tanh (ctx0 ,cur ); 794cur = ggml_scale (ctx0 ,cur ,hparams .f_final_logit_softcapping ); 795 } 796 } 797 798// reduced-draft-vocab exports: scatter the draft logits to the target vocabulary via d2t 799if (model .d2t ) { 800const int64_t n_draft_vocab = cur -> ne [0 ]; 801const int64_t n_outputs = cur -> ne [1 ]; 802const int64_t n_vocab = (int64_t )model .vocab .n_tokens (); 803 804GGML_ASSERT (model .d2t -> type == GGML_TYPE_I64 ); 805GGML_ASSERT (model .d2t -> ne [0 ]== n_draft_vocab ); 806 807ggml_tensor * logits = ggml_fill (ctx0 ,ggml_new_tensor_3d (ctx0 ,GGML_TYPE_F32 ,1 ,n_vocab ,n_outputs ),- INFINITY ); 808cur = ggml_set_rows (ctx0 ,logits , 809ggml_reshape_3d (ctx0 ,cur ,1 ,n_draft_vocab ,n_outputs ), 810ggml_reshape_3d (ctx0 ,model .d2t ,n_draft_vocab ,1 ,1 )); 811cur = ggml_reshape_2d (ctx0 ,cur ,n_vocab ,n_outputs ); 812 } 813cb (cur ,"result_output" ,-1 ); 814res -> t_logits = cur ; 815 816ggml_build_forward_expand (gf ,cur ); 817 818// DSpark: bias the draft logits with the Markov head 819if (model .dspark_markov_w1 ) { 820build_dspark_markov_head (* this ,model ,inp_tokens ); 821 } 822 823if (model .dflash_selector_hidden ) { 824build_dflash2_selector (* this ,model ,inp_tokens ); 825 } 826} 827 828// DSV4 DSpark decoder, dual-mode by batch type (see the DFlash decoder above): 829// * embd batch -> project main_x through each stage's wkv and inject K into the ring cache 830// * token batch -> noise block through 3 full DSV4 stages (hc + MLA + MoE), markov + confidence heads 831llama_model_dflash::graph_dsv4::graph_dsv4 (const llama_model & model ,const llm_graph_params & params ) : 832 llama_model_deepseek4::graph (params ) { 833const int64_t n_embd_inp = hparams .n_embd_inp_enc (); 834const int64_t n_embd_head = hparams .n_embd_head_k (); 835const int64_t n_embd_head_rope = hparams .n_rot (); 836const int64_t n_embd_head_nope = n_embd_head - n_embd_head_rope ; 837 838ggml_tensor * inp_pos = build_inp_pos (); 839 840llm_graph_input_attn_k_iswa * inp_attn = build_attn_inp_k_iswa (); 841 842// KV cache injection: fused target features from the encoder 843if (ubatch .embd ) { 844auto inp = std::make_unique < llm_graph_input_embd > (n_embd_inp ); 845 846inp -> embd = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,n_embd_inp ,n_tokens ); 847ggml_set_input (inp -> embd ); 848 849ggml_tensor * inp_target = inp -> embd ; 850cb (inp_target ,"inp_target_features" ,-1 ); 851 852res -> add_input (std::move (inp )); 853 854// fuse the target features through the encoder 855ggml_tensor * inp_g = build_lora_mm (model .fc ,inp_target ,model .fc_s ); 856inp_g = build_norm (inp_g ,model .output_norm_enc ,nullptr ,LLM_NORM_RMS ,-1 ); 857cb (inp_g ,"inp_g_embeddings" ,-1 ); 858 859for (int il = 0 ;il < n_layer ;++ il ) { 860const auto & layer = model .layers [il ]; 861 862// main-track KV: kv_norm(wkv(main_x)) with rope on the trailing dims, same 863// rope parameters as the uncompressed layers in build_attention_impl 864ggml_tensor * kv = build_lora_mm (layer .wkv ,inp_g ); 865kv = build_norm (kv ,layer .attn_kv_norm ,nullptr ,LLM_NORM_RMS ,il ); 866kv = ggml_reshape_3d (ctx0 ,kv ,n_embd_head ,1 ,n_tokens ); 867 868kv = ggml_rope_ext (ctx0 ,kv ,inp_pos ,nullptr ,n_embd_head_rope ,rope_type ,0 , 869freq_base ,1.0f ,0.0f ,1.0f ,0.0f ,0.0f ); 870kv = ggml_rope_set_offset (kv ,n_embd_head_nope ); 871cb (kv ,"kv_injected" ,il ); 872 873if (inp_attn -> self_k_rot_swa ) { 874kv = llama_mul_mat_hadamard (ctx0 ,kv ,inp_attn -> self_k_rot_swa ); 875 } 876ggml_build_forward_expand (gf ,inp_attn -> mctx -> get_swa ()-> cpy_k (ctx0 ,kv ,inp_attn -> get_k_idxs_swa (),il )); 877 } 878 879res -> t_embd = inp_g ; 880 881ggml_build_forward_expand (gf ,inp_g ); 882return ; 883 } 884 885// tok_embd from the target model (shared via ctx_other) 886auto * tok_embd = model .tok_embd ; 887if (tok_embd == nullptr ) { 888GGML_ASSERT (cparams .ctx_other != nullptr ); 889const auto * model_other = llama_get_model (cparams .ctx_other ); 890 891GGML_ASSERT (model_other -> tok_embd != nullptr && "DSpark decoder requires the target model's token embeddings" ); 892tok_embd = model_other -> tok_embd ; 893 } 894 895auto inp = std::make_unique < llm_graph_input_embd > (n_embd ); 896 897inp -> tokens = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_tokens ); 898ggml_set_input (inp -> tokens ); 899 900ggml_tensor * inp_tokens = inp -> tokens ; 901 902ggml_tensor * inpL = ggml_get_rows (ctx0 ,tok_embd ,inp -> tokens ); 903cb (inpL ,"inp_noise_embd" ,-1 ); 904 905res -> add_input (std::move (inp )); 906 907const int64_t hc = hparams .dsv4_hc_mult ; 908inpL = ggml_reshape_3d (ctx0 ,inpL ,n_embd ,1 ,n_tokens ); 909inpL = ggml_repeat_4d (ctx0 ,inpL ,n_embd ,hc ,n_tokens ,1 ); 910cb (inpL ,"hc_init" ,-1 ); 911 912for (int il = 0 ;il < n_layer ;++ il ) { 913const auto & layer = model .layers [il ]; 914 915ggml_tensor * residual = inpL ; 916ggml_tensor * post = nullptr ; 917ggml_tensor * comb = nullptr ; 918 919ggml_tensor * cur = build_hc_pre (inpL , 920layer .hc_attn_fn , 921layer .hc_attn_scale , 922layer .hc_attn_base , 923& post ,& comb ,il ); 924cb (cur ,"hc_attn_pre" ,il ); 925 926cur = build_norm (cur ,layer .attn_norm ,nullptr ,LLM_NORM_RMS ,il ); 927cb (cur ,"attn_norm" ,il ); 928 929cur = build_attention (model ,inp_attn ,cur ,inp_pos ,il ); 930 931inpL = build_hc_post (cur ,residual ,post ,comb ,il ); 932cb (inpL ,"hc_attn_post" ,il ); 933 934residual = inpL ; 935cur = build_hc_pre (inpL , 936layer .hc_ffn_fn , 937layer .hc_ffn_scale , 938layer .hc_ffn_base , 939& post ,& comb ,il ); 940cb (cur ,"hc_ffn_pre" ,il ); 941 942cur = build_norm (cur ,layer .ffn_norm ,nullptr ,LLM_NORM_RMS ,il ); 943cb (cur ,"ffn_norm" ,il ); 944 945ggml_tensor * moe_out = build_moe_ffn (cur , 946layer .ffn_gate_inp , 947layer .ffn_up_exps , 948layer .ffn_gate_exps , 949layer .ffn_down_exps , 950layer .ffn_exp_probs_b , 951n_expert ,hparams .n_expert_used (), 952LLM_FFN_SILU ,hparams .expert_weights_norm , 953hparams .expert_weights_scale , 954 (llama_expert_gating_func_type )hparams .expert_gating_func , 955il ); 956cb (moe_out ,"ffn_moe_out" ,il ); 957 958ggml_tensor * ffn_shexp = build_ffn (cur , 959layer .ffn_up_shexp ,nullptr ,nullptr , 960layer .ffn_gate_shexp ,nullptr ,nullptr , 961layer .ffn_down_shexp ,nullptr ,nullptr , 962nullptr ,LLM_FFN_SILU ,LLM_FFN_PAR ,il ); 963cb (ffn_shexp ,"ffn_shexp" ,il ); 964 965cur = ggml_add (ctx0 ,moe_out ,ffn_shexp ); 966cb (cur ,"ffn_out" ,il ); 967 968inpL = build_hc_post (cur ,residual ,post ,comb ,il ); 969cb (inpL ,"l_out" ,il ); 970 } 971 972ggml_tensor * cur = build_hc_head (inpL ,model .hc_head_fn ,model .hc_head_scale ,model .hc_head_base ); 973cb (cur ,"hc_head" ,-1 ); 974 975// confidence head input: the reference scores the pre-norm collapsed hidden state 976res -> t_embd = cur ; 977 978cur = build_norm (cur ,model .output_norm ,nullptr ,LLM_NORM_RMS ,-1 ); 979cb (cur ,"result_norm" ,-1 ); 980 981// lm_head from the target model (shared via ctx_other) 982auto * output = model .output ; 983auto * output_s = model .output_s ; 984if (output == nullptr ) { 985GGML_ASSERT (cparams .ctx_other != nullptr ); 986const auto * model_other = llama_get_model (cparams .ctx_other ); 987GGML_ASSERT (model_other -> output != nullptr && "DSpark decoder requires the target model's output projection" ); 988output = model_other -> output ; 989output_s = model_other -> output_s ; 990 } 991 992cur = build_lora_mm (output ,cur ,output_s ); 993cb (cur ,"result_output" ,-1 ); 994res -> t_logits = cur ; 995 996ggml_build_forward_expand (gf ,cur ); 997 998if (model .dspark_markov_w1 ) { 999build_dspark_markov_head (* this ,model ,inp_tokens ); 1000 } 1001}