char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
7798007a2
char/aliceai-t5-moe
1#include "models.h" 2 3// DeepSeek-V4-Flash-Vision encoder (deepseek4v) 4// 5// native-resolution ViT (RMSNorm, SwiGLU, 2D RoPE, no CLS / learned pos-embd) 6// then the "aligner": 3x3 patch merge (torch.nn.functional.unfold) + 2-layer GELU MLP 7// 8// the graph outputs the complete LLM token block, built from the aligner output and 4 learned sentinel embeddings: 9// 10// [PAD]*lead_pad [START] <interleaved rows> [PAD]*pad_last [END] 11// 12// each aligner row ends with a NEWLINE, an odd row count is padded with a full row of PADs 13// pairs of adjacent rows are interleaved column-wise ("N-layout") 14// the mapping is precomputed on CPU as the "layout_idx" input (see set_input in clip.cpp) 15// 16// ref: inference/vision.py and inference/image_processor.py in the HF repo 17 18ggml_cgraph * clip_graph_deepseek4v::build () { 19const int n_merge = hparams .n_merge ; 20 21// 2D input positions 22ggml_tensor * positions = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_patches * 4 ); 23ggml_set_name (positions ,"positions" ); 24ggml_set_input (positions ); 25 26int sections [4 ]= {d_head /4 ,d_head /4 ,0 ,0 }; 27auto add_pos = [& ](ggml_tensor * cur ,const clip_layer & ) { 28return ggml_rope_multi (ctx0 ,cur ,positions ,nullptr , 29d_head /2 ,sections ,GGML_ROPE_TYPE_VISION , 300 ,hparams .rope_theta ,1.0f ,0.0f ,1.0f ,0.0f ,0.0f ); 31 }; 32 33ggml_tensor * inp = build_inp (); 34ggml_tensor * cur = build_vit ( 35inp ,n_patches , 36NORM_TYPE_RMS , 37hparams .ffn_op , 38nullptr ,// no learned pos embd 39add_pos ); 40cb (cur ,"vit_out" ,-1 ); 41 42// aligner patch merge: zero-pad the patch grid to a multiple of n_merge 43// then F.unfold == im2col with a dummy kernel (same trick as pixtral) 44 { 45cur = ggml_reshape_3d (ctx0 ,cur ,n_embd ,n_patches_x ,n_patches_y ); 46cur = ggml_permute (ctx0 ,cur ,2 ,0 ,1 ,3 );// [x, y, n_embd] 47cur = ggml_cont (ctx0 ,cur ); 48 49const int pad_x = (n_merge - n_patches_x %n_merge ) %n_merge ; 50const int pad_y = (n_merge - n_patches_y %n_merge ) %n_merge ; 51if (pad_x || pad_y ) { 52cur = ggml_pad (ctx0 ,cur ,pad_x ,pad_y ,0 ,0 ); 53 } 54 55ggml_tensor * kernel = ggml_view_3d (ctx0 ,cur ,n_merge ,n_merge ,cur -> ne [2 ],0 ,0 ,0 ); 56cur = ggml_im2col (ctx0 ,kernel ,cur ,n_merge ,n_merge ,0 ,0 ,1 ,1 , true,inp -> type ); 57cur = ggml_reshape_2d (ctx0 ,cur ,cur -> ne [0 ],cur -> ne [1 ]* cur -> ne [2 ]); 58 59// aligner MLP (F.gelu in the reference == erf-based gelu) 60cur = build_ffn (cur , 61model .mm_1_w ,model .mm_1_b , 62nullptr ,nullptr , 63model .mm_2_w ,model .mm_2_b , 64FFN_GELU_ERF , 65-1 ); 66cb (cur ,"aligner_out" ,-1 ); 67 } 68 69// assemble the token block: append the sentinel embeddings as extra rows 70// then reorder everything with the precomputed layout index 71 { 72const int64_t n_embd_out = cur -> ne [0 ]; 73const int64_t n_grid = cur -> ne [1 ];// n_llm_w * n_llm_h 74 75// rows n_grid + 0..3, keep in sync with the index computation in set_input 76ggml_tensor * sentinels []= { 77model .token_embd_img_start , 78model .token_embd_img_end , 79model .image_newline , 80model .token_embd_img_pad , 81 }; 82for (ggml_tensor * tok :sentinels ) { 83cur = ggml_concat (ctx0 ,cur ,ggml_reshape_2d (ctx0 ,tok ,n_embd_out ,1 ),1 ); 84 } 85 86const int n_llm_w = CLIP_ALIGN (n_patches_x ,n_merge ) /n_merge ; 87const int n_llm_h = CLIP_ALIGN (n_patches_y ,n_merge ) /n_merge ; 88const int n_out = dsv4_get_block_layout (n_llm_w ,n_llm_h ,img .lead_pad ).n_out ; 89GGML_ASSERT (n_grid == n_llm_w * n_llm_h ); 90 91ggml_tensor * layout_idx = ggml_new_tensor_1d (ctx0 ,GGML_TYPE_I32 ,n_out ); 92ggml_set_name (layout_idx ,"layout_idx" ); 93ggml_set_input (layout_idx ); 94 95cur = ggml_get_rows (ctx0 ,cur ,layout_idx ); 96 } 97 98// build the graph 99ggml_build_forward_expand (gf ,cur ); 100 101return gf ; 102}