char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
de699957b
char/aliceai-t5-moe
1#include "models.h" 2 3ggml_cgraph * clip_graph_minicpmv::build () { 4GGML_ASSERT (model .class_embedding == nullptr ); 5const int n_pos = n_patches ; 6const int n_embd_proj = n_mmproj_embd ; 7 8// position embeddings for the projector (not for ViT) 9// see: https://huggingface.co/openbmb/MiniCPM-o-2_6/blob/main/resampler.py#L70 10// base frequency omega 11ggml_tensor * omega = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_F32 ,n_embd_proj /4 ); 12ggml_set_name (omega ,"omega" ); 13ggml_set_input (omega ); 14 15// 2D input positions (using float for sinusoidal embeddings) 16ggml_tensor * pos_h = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,1 ,n_pos ); 17ggml_set_name (pos_h ,"pos_h" ); 18ggml_set_input (pos_h ); 19ggml_tensor * pos_w = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,1 ,n_pos ); 20ggml_set_name (pos_w ,"pos_w" ); 21ggml_set_input (pos_w ); 22 23// for selecting learned pos embd, used by ViT 24struct ggml_tensor * positions = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_pos ); 25ggml_set_name (positions ,"positions" ); 26ggml_set_input (positions ); 27 28ggml_tensor * learned_pos_embd = ggml_get_rows (ctx0 ,model .position_embeddings ,positions ); 29 30ggml_tensor * inp = build_inp (); 31ggml_tensor * embeddings = build_vit ( 32inp ,n_pos , 33NORM_TYPE_NORMAL , 34hparams .ffn_op , 35learned_pos_embd , 36nullptr ); 37 38// resampler projector (it is just another transformer) 39 40ggml_tensor * q = model .mm_model_query ; 41ggml_tensor * v = build_mm (model .mm_model_kv_proj ,embeddings ); 42 43// norm 44q = build_norm (q ,model .mm_model_ln_q_w ,model .mm_model_ln_q_b ,NORM_TYPE_NORMAL ,eps ,-1 ); 45v = build_norm (v ,model .mm_model_ln_kv_w ,model .mm_model_ln_kv_b ,NORM_TYPE_NORMAL ,eps ,-1 ); 46 47// calculate sinusoidal pos embd 48ggml_tensor * pos_embed = nullptr ; 49 { 50// outer product 51ggml_tensor * omega_b = ggml_repeat_4d (ctx0 ,omega ,omega -> ne [0 ],n_pos ,1 ,1 );// n_pos rows 52ggml_tensor * theta_x = ggml_mul (ctx0 ,omega_b ,pos_w ); 53ggml_tensor * theta_y = ggml_mul (ctx0 ,omega_b ,pos_h ); 54// sin and cos 55ggml_tensor * pos_embd_x = ggml_concat ( 56ctx0 , 57ggml_sin (ctx0 ,theta_x ), 58ggml_cos (ctx0 ,theta_x ), 590 // concat on first dim 60 ); 61ggml_tensor * pos_embd_y = ggml_concat ( 62ctx0 , 63ggml_sin (ctx0 ,theta_y ), 64ggml_cos (ctx0 ,theta_y ), 650 // concat on first dim 66 ); 67pos_embed = ggml_concat (ctx0 ,pos_embd_x ,pos_embd_y ,0 ); 68 } 69 70// k = v + pos_embed 71ggml_tensor * k = ggml_add (ctx0 ,v ,pos_embed ); 72 73// attention 74 { 75const int d_head = 128 ; 76int n_head = n_embd_proj /d_head ; 77// Use actual config value if available, otherwise fall back to hardcoded values 78int num_query = hparams .minicpmv_query_num ; 79ggml_tensor * Q = ggml_add (ctx0 , 80build_mm (model .mm_model_attn_q_w ,q ), 81model .mm_model_attn_q_b ); 82ggml_tensor * K = ggml_add (ctx0 , 83build_mm (model .mm_model_attn_k_w ,k ), 84model .mm_model_attn_k_b ); 85ggml_tensor * V = ggml_add (ctx0 , 86build_mm (model .mm_model_attn_v_w ,v ), 87model .mm_model_attn_v_b ); 88 89Q = ggml_reshape_3d (ctx0 ,Q ,d_head ,n_head ,num_query ); 90K = ggml_reshape_3d (ctx0 ,K ,d_head ,n_head ,n_pos ); 91V = ggml_reshape_3d (ctx0 ,V ,d_head ,n_head ,n_pos ); 92 93cb (Q ,"resampler_Q" ,-1 ); 94cb (K ,"resampler_K" ,-1 ); 95cb (V ,"resampler_V" ,-1 ); 96 97float resampler_kq_scale = 1.0f /sqrtf (float (d_head )); 98embeddings = build_attn ( 99model .mm_model_attn_o_w , 100model .mm_model_attn_o_b , 101Q ,K ,V ,nullptr ,resampler_kq_scale ,-1 ); 102cb (embeddings ,"resampler_attn_out" ,-1 ); 103 } 104// layernorm 105embeddings = build_norm (embeddings ,model .mm_model_ln_post_w ,model .mm_model_ln_post_b ,NORM_TYPE_NORMAL ,eps ,-1 ); 106 107// projection 108embeddings = build_mm (model .mm_model_proj ,embeddings ); 109 110// build the graph 111ggml_build_forward_expand (gf ,embeddings ); 112 113return gf ; 114} 115 116ggml_cgraph * clip_graph_minicpmv4_6::build () { 117const bool is_4x = hparams .n_merge == 2 ; 118const int n_pos = n_patches ; 119const int half_h = n_patches_y /2 ; 120const int half_w = n_patches_x /2 ; 121const int n_ds = half_h * half_w ; 122const int n_out = is_4x ?n_ds : (half_h /2 )* (half_w /2 ); 123 124auto add_i32_input = [& ](const char * name ,int n ) { 125ggml_tensor * t = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n ); 126ggml_set_name (t ,name ); 127ggml_set_input (t ); 128return t ; 129 }; 130 131// position indices for ViT learned positional embeddings 132ggml_tensor * positions = add_i32_input ("positions" ,n_pos ); 133ggml_tensor * learned_pos_embd = ggml_get_rows (ctx0 ,model .position_embeddings ,positions ); 134 135ggml_tensor * vit_merger_window_idx = nullptr ; 136ggml_tensor * vit_merger_inv_window_idx = nullptr ; 137ggml_tensor * vit_merger_window_mask = nullptr ; 138ggml_tensor * vit_merger_ds_idx_0 = nullptr ; 139ggml_tensor * vit_merger_ds_idx_1 = nullptr ; 140ggml_tensor * vit_merger_ds_idx_2 = nullptr ; 141ggml_tensor * vit_merger_ds_idx_3 = nullptr ; 142 143if (!is_4x ) { 144// ViT merger window reorder indices + block-diagonal mask 145// (mask layout follows qwen2vl: -inf except for 4x4 blocks on the diagonal, 146// so each window-major group of 4 tokens only attends to itself) 147vit_merger_window_idx = add_i32_input ("vit_merger_window_idx" ,n_pos ); 148vit_merger_inv_window_idx = add_i32_input ("vit_merger_inv_window_idx" ,n_pos ); 149vit_merger_window_mask = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_F32 ,n_pos ,n_pos ); 150ggml_set_name (vit_merger_window_mask ,"vit_merger_window_mask" ); 151ggml_set_input (vit_merger_window_mask ); 152if (flash_attn_type == CLIP_FLASH_ATTN_TYPE_ENABLED ) { 153vit_merger_window_mask = ggml_cast (ctx0 ,vit_merger_window_mask ,GGML_TYPE_F16 ); 154 } 155 156// ViT merger 2x2 downsample gather indices 157vit_merger_ds_idx_0 = add_i32_input ("vit_merger_ds_idx_0" ,n_ds ); 158vit_merger_ds_idx_1 = add_i32_input ("vit_merger_ds_idx_1" ,n_ds ); 159vit_merger_ds_idx_2 = add_i32_input ("vit_merger_ds_idx_2" ,n_ds ); 160vit_merger_ds_idx_3 = add_i32_input ("vit_merger_ds_idx_3" ,n_ds ); 161 } 162 163// final merger 2x2 downsample gather indices 164ggml_tensor * merger_ds_idx_0 = add_i32_input ("merger_ds_idx_0" ,n_out ); 165ggml_tensor * merger_ds_idx_1 = add_i32_input ("merger_ds_idx_1" ,n_out ); 166ggml_tensor * merger_ds_idx_2 = add_i32_input ("merger_ds_idx_2" ,n_out ); 167ggml_tensor * merger_ds_idx_3 = add_i32_input ("merger_ds_idx_3" ,n_out ); 168 169// patch embedding + positional embedding 170ggml_tensor * inp = build_inp (); 171inp = ggml_add (ctx0 ,inp ,learned_pos_embd ); 172cb (inp ,"pos_embed" ,-1 ); 173 174ggml_tensor * inpL = inp ; 175if (model .pre_ln_w ) { 176inpL = build_norm (inpL ,model .pre_ln_w ,model .pre_ln_b ,NORM_TYPE_NORMAL ,eps ,-1 ); 177cb (inpL ,"pre_ln" ,-1 ); 178 } 179 180auto build_vit_layers = [& ](ggml_tensor * input ,int il_begin ,int il_end ,int64_t n_pos_layer ) { 181for (int il = il_begin ;il < il_end ;il ++ ) { 182auto & layer = model .layers [il ]; 183ggml_tensor * cur = input ; 184 185cur = build_norm (cur ,layer .ln_1_w ,layer .ln_1_b ,NORM_TYPE_NORMAL ,eps ,il ); 186cb (cur ,"layer_inp_normed" ,il ); 187 188 { 189ggml_tensor * Qcur = build_mm (layer .q_w ,cur ); 190if (layer .q_b ) { 191Qcur = ggml_add (ctx0 ,Qcur ,layer .q_b ); 192 } 193ggml_tensor * Kcur = build_mm (layer .k_w ,cur ); 194if (layer .k_b ) { 195Kcur = ggml_add (ctx0 ,Kcur ,layer .k_b ); 196 } 197ggml_tensor * Vcur = build_mm (layer .v_w ,cur ); 198if (layer .v_b ) { 199Vcur = ggml_add (ctx0 ,Vcur ,layer .v_b ); 200 } 201 202Qcur = ggml_reshape_3d (ctx0 ,Qcur ,d_head ,n_head ,n_pos_layer ); 203Kcur = ggml_reshape_3d (ctx0 ,Kcur ,d_head ,n_head ,n_pos_layer ); 204Vcur = ggml_reshape_3d (ctx0 ,Vcur ,d_head ,n_head ,n_pos_layer ); 205cb (Qcur ,"Qcur" ,il ); 206cb (Kcur ,"Kcur" ,il ); 207cb (Vcur ,"Vcur" ,il ); 208 209cur = build_attn (layer .o_w ,layer .o_b ,Qcur ,Kcur ,Vcur ,nullptr ,kq_scale ,il ); 210cb (cur ,"attn_out" ,il ); 211 } 212 213if (layer .ls_1_w ) { 214cur = ggml_mul (ctx0 ,cur ,layer .ls_1_w ); 215cb (cur ,"attn_out_scaled" ,il ); 216 } 217cur = ggml_add (ctx0 ,cur ,input ); 218input = cur ; 219cb (cur ,"ffn_inp" ,il ); 220 221cur = build_norm (cur ,layer .ln_2_w ,layer .ln_2_b ,NORM_TYPE_NORMAL ,eps ,il ); 222cb (cur ,"ffn_inp_normed" ,il ); 223 224cur = build_ffn (cur ,layer .ff_up_w ,layer .ff_up_b ,layer .ff_gate_w ,layer .ff_gate_b , 225layer .ff_down_w ,layer .ff_down_b ,hparams .ffn_op ,il ); 226cb (cur ,"ffn_out" ,il ); 227 228if (layer .ls_2_w ) { 229cur = ggml_mul (ctx0 ,cur ,layer .ls_2_w ); 230cb (cur ,"ffn_out_scaled" ,il ); 231 } 232input = ggml_add (ctx0 ,input ,cur ); 233cb (input ,"layer_out" ,il ); 234 } 235return input ; 236 }; 237 238if (!is_4x ) { 239const int insert_lid = hparams .insert_layer_id ; 240 241inpL = build_vit_layers (inpL ,0 ,insert_lid + 1 ,n_pos ); 242 243// ViT merger: window self-attention 244// Tokens are reordered to window-major (4 tokens per window are contiguous), 245// and a block-diagonal mask restricts attention to within each window. This 246// mirrors the qwen2vl windowed-attention pattern so build_attn() can pick the 247// flash-attention path when available. 248 { 249ggml_tensor * residual = inpL ; 250ggml_tensor * cur = build_norm (inpL , 251model .vit_merger_ln1_w ,model .vit_merger_ln1_b , 252NORM_TYPE_NORMAL ,eps ,-1 ); 253cb (cur ,"vit_merger_attn_inp_normed" ,-1 ); 254 255cur = ggml_get_rows (ctx0 ,cur ,vit_merger_window_idx ); 256cb (cur ,"vit_merger_window_reorder" ,-1 ); 257 258ggml_tensor * Qcur = build_mm (model .vit_merger_attn_q_w ,cur ); 259if (model .vit_merger_attn_q_b ) { 260Qcur = ggml_add (ctx0 ,Qcur ,model .vit_merger_attn_q_b ); 261 } 262ggml_tensor * Kcur = build_mm (model .vit_merger_attn_k_w ,cur ); 263if (model .vit_merger_attn_k_b ) { 264Kcur = ggml_add (ctx0 ,Kcur ,model .vit_merger_attn_k_b ); 265 } 266ggml_tensor * Vcur = build_mm (model .vit_merger_attn_v_w ,cur ); 267if (model .vit_merger_attn_v_b ) { 268Vcur = ggml_add (ctx0 ,Vcur ,model .vit_merger_attn_v_b ); 269 } 270 271Qcur = ggml_reshape_3d (ctx0 ,Qcur ,d_head ,n_head ,n_pos ); 272Kcur = ggml_reshape_3d (ctx0 ,Kcur ,d_head ,n_head ,n_pos ); 273Vcur = ggml_reshape_3d (ctx0 ,Vcur ,d_head ,n_head ,n_pos ); 274cb (Qcur ,"vit_merger_Qcur" ,-1 ); 275cb (Kcur ,"vit_merger_Kcur" ,-1 ); 276cb (Vcur ,"vit_merger_Vcur" ,-1 ); 277 278cur = build_attn (model .vit_merger_attn_o_w ,model .vit_merger_attn_o_b , 279Qcur ,Kcur ,Vcur ,vit_merger_window_mask ,kq_scale ,-1 ); 280cb (cur ,"vit_merger_attn_out" ,-1 ); 281 282cur = ggml_get_rows (ctx0 ,cur ,vit_merger_inv_window_idx ); 283inpL = ggml_add (ctx0 ,cur ,residual ); 284cb (inpL ,"vit_merger_attn_residual" ,-1 ); 285 } 286 287// ViT merger: 2x2 spatial downsample + MLP (4 tokens -> 1) 288 { 289ggml_tensor * p0 = ggml_get_rows (ctx0 ,inpL ,vit_merger_ds_idx_0 ); 290ggml_tensor * p1 = ggml_get_rows (ctx0 ,inpL ,vit_merger_ds_idx_1 ); 291ggml_tensor * p2 = ggml_get_rows (ctx0 ,inpL ,vit_merger_ds_idx_2 ); 292ggml_tensor * p3 = ggml_get_rows (ctx0 ,inpL ,vit_merger_ds_idx_3 ); 293 294ggml_tensor * mean_res = ggml_add (ctx0 ,p0 ,p1 ); 295mean_res = ggml_add (ctx0 ,mean_res ,p2 ); 296mean_res = ggml_add (ctx0 ,mean_res ,p3 ); 297mean_res = ggml_scale (ctx0 ,mean_res ,0.25f ); 298cb (mean_res ,"vit_merger_ds_mean_res" ,-1 ); 299 300ggml_tensor * cat = ggml_concat (ctx0 ,p0 ,p1 ,0 ); 301cat = ggml_concat (ctx0 ,cat ,p2 ,0 ); 302cat = ggml_concat (ctx0 ,cat ,p3 ,0 ); 303 304ggml_tensor * cur = build_norm (cat , 305model .vit_merger_ds_ln_w ,model .vit_merger_ds_ln_b , 306NORM_TYPE_NORMAL ,eps ,-1 ); 307cb (cur ,"vit_merger_ds_normed" ,-1 ); 308 309// ViTWindowAttentionMerger downsample MLP uses gelu_pytorch_tanh (FFN_GELU) 310cur = build_ffn (cur , 311model .vit_merger_ds_up_w ,model .vit_merger_ds_up_b , 312nullptr ,nullptr , 313model .vit_merger_ds_down_w ,model .vit_merger_ds_down_b , 314FFN_GELU ,-1 ); 315cb (cur ,"vit_merger_ds_mlp_out" ,-1 ); 316 317inpL = ggml_add (ctx0 ,cur ,mean_res ); 318cb (inpL ,"vit_merger_ds_out" ,-1 ); 319 } 320 321inpL = build_vit_layers (inpL ,insert_lid + 1 ,n_layer ,n_ds ); 322 }else { 323inpL = build_vit_layers (inpL ,0 ,n_layer ,n_pos ); 324 } 325 326if (model .post_ln_w ) { 327inpL = build_norm (inpL ,model .post_ln_w ,model .post_ln_b ,NORM_TYPE_NORMAL ,eps ,-1 ); 328cb (inpL ,"post_ln" ,-1 ); 329 } 330 331// Final Merger (DownsampleMLP): another 2x2 spatial merge -> projector embedding 332 { 333ggml_tensor * p0 = ggml_get_rows (ctx0 ,inpL ,merger_ds_idx_0 ); 334ggml_tensor * p1 = ggml_get_rows (ctx0 ,inpL ,merger_ds_idx_1 ); 335ggml_tensor * p2 = ggml_get_rows (ctx0 ,inpL ,merger_ds_idx_2 ); 336ggml_tensor * p3 = ggml_get_rows (ctx0 ,inpL ,merger_ds_idx_3 ); 337 338ggml_tensor * cat = ggml_concat (ctx0 ,p0 ,p1 ,0 ); 339cat = ggml_concat (ctx0 ,cat ,p2 ,0 ); 340cat = ggml_concat (ctx0 ,cat ,p3 ,0 ); 341 342ggml_tensor * cur = build_norm (cat , 343model .mm_input_norm_w ,model .mm_input_norm_b , 344NORM_TYPE_NORMAL ,eps ,-1 ); 345cb (cur ,"merger_normed" ,-1 ); 346 347// MiniCPMV4_6DownsampleMLP uses nn.GELU() (erf-based, FFN_GELU_ERF) 348cur = build_ffn (cur , 349model .mm_ffn_up_w ,model .mm_ffn_up_b , 350nullptr ,nullptr , 351model .mm_ffn_down_w ,model .mm_ffn_down_b , 352FFN_GELU_ERF ,-1 ); 353cb (cur ,"merger_out" ,-1 ); 354 355inpL = cur ; 356 } 357 358ggml_build_forward_expand (gf ,inpL ); 359return gf ; 360}