char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
9d57ce456
char/aliceai-t5-moe
1#include "models.h" 2#include "../clip-impl.h" 3#include "../clip-model.h" 4 5#include <algorithm> 6#include <cmath> 7#include <cstring> 8#include <string> 9#include <vector> 10 11/* 12* Granite Vision 4.1 clip graph 13* 14* Stage 1a: SigLIP vision tower (N layers, post-norm) 15* Stage 1b: WindowQFormer blocks (deepstack + spatial) 16* Stage 1c: Concatenate and pack outputs 17* Stage 1d: Assemble the anyres tiles into one token sequence 18*/ 19 20// --------------------------------------------------------------------------- 21// Member method implementations 22// --------------------------------------------------------------------------- 23 24// split the stacked tiles into the batch axis, then run the usual patch embedding 25ggml_tensor * clip_graph_granite4_vision::build_tile_inp () { 26ggml_tensor * inp_raw = build_inp_raw (); 27 28if (n_tiles > 1 ) { 29const int px = img .nx (); 30inp_raw = ggml_reshape_4d (ctx0 ,inp_raw ,px * px ,n_tiles ,3 ,1 ); 31inp_raw = ggml_cont (ctx0 ,ggml_permute (ctx0 ,inp_raw ,0 ,2 ,1 ,3 )); 32inp_raw = ggml_reshape_4d (ctx0 ,inp_raw ,px ,px ,3 ,n_tiles ); 33 } 34 35ggml_tensor * inp = ggml_conv_2d (ctx0 ,model .patch_embeddings_0 ,inp_raw ,patch_size ,patch_size ,0 ,0 ,1 ,1 ); 36inp = ggml_reshape_3d (ctx0 ,inp ,tile_side * tile_side ,n_embd ,n_tiles ); 37inp = ggml_cont (ctx0 ,ggml_transpose (ctx0 ,inp )); 38if (model .patch_bias ) { 39inp = ggml_add (ctx0 ,inp ,model .patch_bias ); 40 } 41return inp ; 42} 43 44ggml_tensor * clip_graph_granite4_vision::gather ( 45ggml_tensor * src , 46const std::string & name , 47int idx_len ) { 48// one index row per tile, all rows hold the same permutation 49ggml_tensor * idx = ggml_new_tensor_2d (ctx0 ,GGML_TYPE_I32 ,idx_len ,n_tiles ); 50ggml_set_name (idx ,name .c_str ()); 51ggml_set_input (idx ); 52return ggml_get_rows (ctx0 ,src ,idx ); 53} 54 55ggml_tensor * clip_graph_granite4_vision::interp_down ( 56ggml_tensor * src , 57int side , 58int new_side ) { 59const int n_embd = src -> ne [0 ]; 60ggml_tensor * t = ggml_reshape_4d (ctx0 ,src ,n_embd ,side ,side ,n_tiles ); 61t = ggml_cont (ctx0 ,ggml_permute (ctx0 ,t ,2 ,0 ,1 ,3 )); 62// fold the tile axis into the channel axis, ggml_pool_2d only pools the first two axes 63t = ggml_reshape_3d (ctx0 ,t ,side ,side ,n_embd * n_tiles ); 64const int kernel = side /new_side ; 65t = ggml_pool_2d (ctx0 ,t ,GGML_OP_POOL_AVG ,kernel ,kernel ,kernel ,kernel ,0 ,0 ); 66t = ggml_reshape_4d (ctx0 ,t ,new_side ,new_side ,n_embd ,n_tiles ); 67t = ggml_cont (ctx0 ,ggml_permute (ctx0 ,t ,1 ,2 ,0 ,3 )); 68return ggml_reshape_3d (ctx0 ,t ,n_embd ,new_side * new_side ,n_tiles ); 69} 70 71// --------------------------------------------------------------------------- 72// build_block - WindowQFormer block implementation 73// --------------------------------------------------------------------------- 74 75ggml_tensor * clip_graph_granite4_vision::build_block ( 76const qf_block & blk , 77ggml_tensor * h , 78int bid , 79int spatial_offset , 80int image_side , 81int window_side , 82int query_side , 83float qformer_eps ) { 84 85const int n_embd = h -> ne [0 ]; 86GGML_ASSERT (h -> ne [1 ]== image_side * image_side ); 87const int n = image_side /window_side ; 88const int new_side = n * query_side ; 89const int n_windows = n * n ; 90const int n_win_all = n_windows * n_tiles ;// windows of every tile, batched together 91const int enc_len = window_side * window_side ; 92const int query_len = query_side * query_side ; 93 94auto cbx = [& ](ggml_tensor * & t ,const char * step ) { 95const std::string name = "g4v_blk" + std::to_string (bid )+ "_" + step ; 96ggml_set_name (t ,name .c_str ()); 97 }; 98 99// 1. Top-level LN 100cbx (h ,"inp" ); 101ggml_tensor * x = build_norm (h ,blk .qf_proj_norm_w ,blk .qf_proj_norm_b ,NORM_TYPE_NORMAL ,eps ,bid ); 102cbx (x ,"norm" ); 103 104// 2. enc = _win(x, image_side, window_side) 105ggml_tensor * enc ; 106 { 107ggml_tensor * enc_flat = gather (x , 108"g4v_blk" + std::to_string (bid )+ "_win_idx" , 109image_side * image_side ); 110enc = ggml_reshape_3d (ctx0 ,enc_flat ,n_embd ,enc_len ,n_win_all ); 111 } 112cbx (enc ,"enc" ); 113 114// 3. downsampled = downsampler(x) 115ggml_tensor * d ; 116 (void )spatial_offset ; 117if (spatial_offset >=0 ) { 118d = gather (x , 119"g4v_blk" + std::to_string (bid )+ "_spatial_idx" , 120new_side * new_side ); 121 }else { 122d = interp_down (x ,image_side ,new_side ); 123 } 124cbx (d ,"downsampled" ); 125 126// 4. query_embeds = query + _win(d, new_side, query_side) 127ggml_tensor * q_in ; 128 { 129ggml_tensor * dw_flat = gather (d , 130"g4v_blk" + std::to_string (bid )+ "_qwin_idx" , 131new_side * new_side ); 132ggml_tensor * dw = ggml_reshape_3d (ctx0 ,dw_flat ,n_embd ,query_len ,n_win_all ); 133q_in = ggml_add (ctx0 ,dw ,blk .qf_proj_query ); 134 } 135cbx (q_in ,"query_embeds" ); 136 137// 5. encoder_embeds = enc + image_positions → (C, enc_len, n_windows) 138ggml_tensor * e_in = ggml_add (ctx0 ,enc ,blk .qf_proj_img_pos ); 139cbx (e_in ,"encoder_embeds" ); 140 141// 6. Qformer forward. 142ggml_tensor * q = build_norm (q_in ,blk .qf_proj_post_norm_w ,blk .qf_proj_post_norm_b ,NORM_TYPE_NORMAL ,qformer_eps ,bid ); 143 144// Helper for linear projections with window batching 145auto linear = [& ](ggml_tensor * x ,ggml_tensor * w ,ggml_tensor * b )-> ggml_tensor * { 146ggml_tensor * t = ggml_reshape_2d (ctx0 ,x ,x -> ne [0 ],x -> ne [1 ]* x -> ne [2 ]); 147t = build_mm (w ,t ); 148if (b )t = ggml_add (ctx0 ,t ,b ); 149return t ; 150 }; 151 152// Get the single QFormer layer 153GGML_ASSERT (blk .qf_proj_layers .size ()== 1 ); 154const auto & pl = blk .qf_proj_layers [0 ]; 155 156// 6a. Self-attention 157ggml_tensor * sa_out ; 158 { 159const int d_h = 64 ; 160const int n_head = n_embd /d_h ; 161const int nq = q -> ne [1 ]; 162const float scale = 1.0f / std::sqrt ((float )d_h ); 163 164ggml_tensor * Q = linear (q ,pl .q_w ,pl .q_b ); 165ggml_tensor * K = linear (q ,pl .k_w ,pl .k_b ); 166ggml_tensor * V = linear (q ,pl .v_w ,pl .v_b ); 167 168Q = ggml_reshape_4d (ctx0 ,Q ,d_h ,n_head ,nq ,n_win_all ); 169K = ggml_reshape_4d (ctx0 ,K ,d_h ,n_head ,nq ,n_win_all ); 170V = ggml_reshape_4d (ctx0 ,V ,d_h ,n_head ,nq ,n_win_all ); 171 172sa_out = build_attn (pl .o_w ,pl .o_b ,Q ,K ,V ,nullptr ,scale ,bid ); 173sa_out = ggml_reshape_3d (ctx0 ,sa_out ,n_embd ,nq ,n_win_all ); 174 175sa_out = ggml_add (ctx0 ,sa_out ,q ); 176sa_out = build_norm (sa_out ,pl .ln_1_w ,pl .ln_1_b , 177NORM_TYPE_NORMAL ,qformer_eps ,bid ); 178 } 179cbx (sa_out ,"sa_out" ); 180 181// 6b. Cross-attention 182ggml_tensor * ca_out ; 183 { 184const int d_h = 64 ; 185const int n_head = n_embd /d_h ; 186const int nq = sa_out -> ne [1 ]; 187const int nkv = e_in -> ne [1 ]; 188const float scale = 1.0f / std::sqrt ((float )d_h ); 189 190ggml_tensor * Q = linear (sa_out ,pl .cross_attn_q_w ,pl .cross_attn_q_b ); 191ggml_tensor * K = linear (e_in ,pl .cross_attn_k_w ,pl .cross_attn_k_b ); 192ggml_tensor * V = linear (e_in ,pl .cross_attn_v_w ,pl .cross_attn_v_b ); 193 194Q = ggml_reshape_4d (ctx0 ,Q ,d_h ,n_head ,nq ,n_win_all ); 195K = ggml_reshape_4d (ctx0 ,K ,d_h ,n_head ,nkv ,n_win_all ); 196V = ggml_reshape_4d (ctx0 ,V ,d_h ,n_head ,nkv ,n_win_all ); 197 198ca_out = build_attn (pl .cross_attn_o_w ,pl .cross_attn_o_b , 199Q ,K ,V ,nullptr ,scale ,bid ); 200ca_out = ggml_reshape_3d (ctx0 ,ca_out ,n_embd ,nq ,n_win_all ); 201 202ca_out = ggml_add (ctx0 ,ca_out ,sa_out ); 203ca_out = build_norm (ca_out ,pl .cross_attn_norm_w ,pl .cross_attn_norm_b , 204NORM_TYPE_NORMAL ,qformer_eps ,bid ); 205 } 206cbx (ca_out ,"ca_out" ); 207 208// 6c. FFN 209ggml_tensor * ffn ; 210 { 211ggml_tensor * t = ggml_reshape_2d (ctx0 ,ca_out ,n_embd ,query_len * n_win_all ); 212t = build_mm (pl .ff_up_w ,t ); 213if (pl .ff_up_b )t = ggml_add (ctx0 ,t ,pl .ff_up_b ); 214t = ggml_gelu_erf (ctx0 ,t ); 215t = build_mm (pl .ff_down_w ,t ); 216if (pl .ff_down_b )t = ggml_add (ctx0 ,t ,pl .ff_down_b ); 217t = ggml_reshape_3d (ctx0 ,t ,n_embd ,query_len ,n_win_all ); 218ffn = ggml_add (ctx0 ,t ,ca_out ); 219ffn = build_norm (ffn ,pl .ln_2_w ,pl .ln_2_b ,NORM_TYPE_NORMAL ,qformer_eps ,bid ); 220 } 221cbx (ffn ,"qformer_out" ); 222 223// 7. _unwin back to raster 224ggml_tensor * unwinned ; 225 { 226ggml_tensor * flat = ggml_reshape_3d (ctx0 ,ffn ,n_embd ,query_len * n_windows ,n_tiles ); 227unwinned = gather (flat , 228"g4v_blk" + std::to_string (bid )+ "_unwin_idx" , 229new_side * new_side ); 230 } 231cbx (unwinned ,"unwin" ); 232 233// 8. out_linear 234ggml_tensor * out = build_mm (blk .qf_proj_linear_w ,unwinned ); 235if (blk .qf_proj_linear_b )out = ggml_add (ctx0 ,out ,blk .qf_proj_linear_b ); 236cbx (out ,"out" ); 237 238return out ; 239} 240 241// --------------------------------------------------------------------------- 242// build() - top-level graph 243// --------------------------------------------------------------------------- 244 245// Build the K-tiled, base-scaled newline row tensor. 246// Shape: (n_mmproj_embd, 1) 247ggml_tensor * clip_graph_granite4_vision::build_newline_row (ggml_context * ctx0 ) { 248const int K = (int )model .qf_proj_blocks .size (); 249GGML_ASSERT (K > 0 ); 250GGML_ASSERT (n_mmproj_embd %K == 0 ); 251const int projection_dim = n_mmproj_embd /K ; 252GGML_ASSERT (model .image_newline != nullptr ); 253GGML_ASSERT (ggml_nelements (model .image_newline )== projection_dim ); 254 255// Build newline_row[k*projection_dim + d] = nl[d] * (k == 0 ? base : 1.0) 256ggml_tensor * nl = model .image_newline ;// (projection_dim,) 257ggml_tensor * nl_first_2d = ggml_reshape_2d (ctx0 ,nl ,projection_dim ,1 ); 258ggml_tensor * nl_row_2d ; 259if (K == 1 ) { 260nl_row_2d = nl_first_2d ; 261 }else { 262ggml_tensor * nl_2d = ggml_reshape_2d (ctx0 ,nl ,projection_dim ,1 ); 263ggml_tensor * rest_template = ggml_new_tensor_2d ( 264ctx0 ,GGML_TYPE_F32 ,projection_dim ,K - 1 ); 265ggml_tensor * nl_rest = ggml_repeat (ctx0 ,nl_2d ,rest_template ); 266nl_row_2d = ggml_concat (ctx0 ,nl_first_2d ,nl_rest ,1 );// (projection_dim, K) 267 } 268nl_row_2d = ggml_cont (ctx0 ,nl_row_2d ); 269return ggml_reshape_2d (ctx0 ,nl_row_2d ,n_mmproj_embd ,1 ); 270} 271 272// Assemble [overview, tile(0,0), tile(0,1), ...] into one token sequence: 273// the overview tokens first, then the tile grid read in raster order with one newline per row. 274// ref: https://github.com/huggingface/transformers/blob/v5.0.0/src/transformers/models/llava_next/modeling_llava_next.py#L266 275ggml_tensor * clip_graph_granite4_vision::build_anyres_assembly (ggml_tensor * cur ,int out_side ) { 276const int n_dim = cur -> ne [0 ]; 277const int grid_x = anyres .grid_x ; 278const int grid_y = anyres .grid_y ; 279const int cur_w = grid_x * out_side ; 280const int cur_h = grid_y * out_side ; 281GGML_ASSERT (cur -> ne [1 ]== out_side * out_side ); 282GGML_ASSERT (cur -> ne [2 ]== 1 + grid_x * grid_y ); 283 284ggml_tensor * base = ggml_view_2d (ctx0 ,cur ,n_dim ,out_side * out_side ,cur -> nb [1 ],0 ); 285 286ggml_tensor * tiles = ggml_view_3d (ctx0 ,cur ,n_dim ,out_side * out_side ,grid_x * grid_y , 287cur -> nb [1 ],cur -> nb [2 ],cur -> nb [2 ]); 288 289// (n_dim*out_side, out_side, grid_x, grid_y) -> interleave the tiles of a grid row 290tiles = ggml_reshape_4d (ctx0 ,tiles ,n_dim * out_side ,out_side ,grid_x ,grid_y ); 291tiles = ggml_cont (ctx0 ,ggml_permute (ctx0 ,tiles ,0 ,2 ,1 ,3 )); 292tiles = ggml_reshape_3d (ctx0 ,tiles ,n_dim ,cur_w ,cur_h ); 293 294// drop the tokens that only cover the padding added when resizing to the grid 295int off_x ,off_y ,w ,h ; 296clip_anyres_unpad (cur_w ,cur_h ,anyres .orig_nx ,anyres .orig_ny ,off_x ,off_y ,w ,h ); 297if (w != cur_w || h != cur_h ) { 298tiles = ggml_cont (ctx0 ,ggml_view_3d (ctx0 ,tiles ,n_dim ,w ,h , 299tiles -> nb [1 ],tiles -> nb [2 ], 300off_x * tiles -> nb [1 ]+ off_y * tiles -> nb [2 ])); 301 } 302 303ggml_tensor * nl = ggml_repeat_4d (ctx0 ,build_newline_row (ctx0 ),n_dim ,1 ,h ,1 ); 304tiles = ggml_concat (ctx0 ,tiles ,nl ,1 ); 305tiles = ggml_reshape_2d (ctx0 ,tiles ,n_dim , (w + 1 )* h ); 306 307return ggml_concat (ctx0 ,base ,tiles ,1 ); 308} 309 310ggml_cgraph * clip_graph_granite4_vision::build () { 311GGML_ASSERT (model .patch_embeddings_0 != nullptr ); 312GGML_ASSERT (model .position_embeddings != nullptr ); 313GGML_ASSERT (model .class_embedding == nullptr ); 314GGML_ASSERT (!model .qf_proj_blocks .empty ()); 315 316// --- Stage 1a: SigLIP encoder producing intermediate hidden states --- 317ggml_tensor * inp = build_tile_inp (); 318inp = ggml_add (ctx0 ,inp ,model .position_embeddings ); 319cb (inp ,"pos_embed" ,-1 ); 320 321const int tile_n_patches = tile_side * tile_side ; 322 323ggml_tensor * inpL = inp ; 324 std::vector < ggml_tensor *> layer_outs (n_layer ,nullptr ); 325 326for (int il = 0 ;il < n_layer ;++ il ) { 327const auto & layer = model .layers [il ]; 328ggml_tensor * cur = inpL ; 329 330cur = build_norm (cur ,layer .ln_1_w ,layer .ln_1_b ,NORM_TYPE_NORMAL ,eps ,il ); 331 332// Self-attention 333ggml_tensor * Qcur = build_mm (layer .q_w ,cur ); 334if (layer .q_b )Qcur = ggml_add (ctx0 ,Qcur ,layer .q_b ); 335ggml_tensor * Kcur = build_mm (layer .k_w ,cur ); 336if (layer .k_b )Kcur = ggml_add (ctx0 ,Kcur ,layer .k_b ); 337ggml_tensor * Vcur = build_mm (layer .v_w ,cur ); 338if (layer .v_b )Vcur = ggml_add (ctx0 ,Vcur ,layer .v_b ); 339 340Qcur = ggml_reshape_4d (ctx0 ,Qcur ,d_head ,n_head ,tile_n_patches ,n_tiles ); 341Kcur = ggml_reshape_4d (ctx0 ,Kcur ,d_head ,n_head ,tile_n_patches ,n_tiles ); 342Vcur = ggml_reshape_4d (ctx0 ,Vcur ,d_head ,n_head ,tile_n_patches ,n_tiles ); 343 344cur = build_attn (layer .o_w ,layer .o_b , 345Qcur ,Kcur ,Vcur ,nullptr ,kq_scale ,il ); 346cur = ggml_reshape_3d (ctx0 ,cur ,n_embd ,tile_n_patches ,n_tiles ); 347 348cur = ggml_add (ctx0 ,cur ,inpL ); 349inpL = cur ; 350 351cur = build_norm (cur ,layer .ln_2_w ,layer .ln_2_b ,NORM_TYPE_NORMAL ,eps ,il ); 352cur = build_ffn (cur , 353layer .ff_up_w ,layer .ff_up_b , 354layer .ff_gate_w ,layer .ff_gate_b , 355layer .ff_down_w ,layer .ff_down_b , 356hparams .ffn_op ,il ); 357cur = ggml_add (ctx0 ,inpL ,cur ); 358cb (cur ,"layer_out" ,il ); 359layer_outs [il ]= cur ; 360inpL = cur ; 361 } 362 363// --- Stage 1b/1c: WindowQFormer blocks --- 364const int projector_count = hparams .feature_layers .size (); 365const float qformer_eps = 1e-12f ; 366 367ggml_tensor * mmproj = nullptr ; 368for (int bid = 0 ;bid < projector_count ;++ bid ) { 369const auto & blk = model .qf_proj_blocks [bid ]; 370 371int vlayer = hparams .feature_layers [bid ]; 372GGML_ASSERT (vlayer >=0 && vlayer < n_layer ); 373ggml_tensor * h = layer_outs [vlayer ]; 374 375ggml_tensor * stream = build_block ( 376blk ,h ,bid , 377hparams .proj_spatial_offsets [bid ], 378tile_side , 379hparams .downsample_window_side , 380hparams .downsample_query_side , 381qformer_eps ); 382cb (stream , (std::string ("proj_" )+ std::to_string (bid )+ std::string ("_v_out" )).c_str (),vlayer ); 383mmproj = mmproj ?ggml_concat (ctx0 ,mmproj ,stream ,0 ) :stream ; 384 } 385 386// --- Stage 1d: assemble the tiles and weave in the newline tokens --- 387if (anyres .is_tiled ()) { 388const int out_side = tile_side /hparams .downsample_window_side * hparams .downsample_query_side ; 389mmproj = build_anyres_assembly (mmproj ,out_side ); 390ggml_set_name (mmproj ,"g4v_mmproj_out_anyres" ); 391 }else { 392ggml_set_name (mmproj ,"g4v_mmproj_out" ); 393 } 394ggml_build_forward_expand (gf ,mmproj ); 395 396return gf ; 397}