char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
7798007a2
char/aliceai-t5-moe
1#pragma once 2 3#include "ggml.h" 4#include "gguf.h" 5#include "clip.h" 6 7#include <array> 8#include <climits> 9#include <cmath> 10#include <cstdarg> 11#include <cinttypes> 12#include <string> 13#include <map> 14#include <sstream> 15#include <vector> 16#include <memory> 17#include <fstream> 18 19#ifdef _WIN32 20#ifndef NOMINMAX 21#define NOMINMAX 22#endif 23#include <windows.h> 24#endif 25 26// Internal header for clip.cpp 27 28#define MTMD_INTERNAL_HEADER 29 30#define KEY_FTYPE "general.file_type" 31#define KEY_NAME "general.name" 32#define KEY_DESCRIPTION "general.description" 33#define KEY_PROJ_TYPE "clip.projector_type" 34#define KEY_HAS_AUDIO_ENC "clip.has_audio_encoder" 35#define KEY_HAS_VISION_ENC "clip.has_vision_encoder" 36#define KEY_HAS_GEN_AUDIO_ENC "clip.has_gen_audio_encoder" 37#define KEY_USE_GELU "clip.use_gelu" 38#define KEY_USE_SILU "clip.use_silu" 39 40#define KEY_N_EMBD "clip.%s.embedding_length" 41#define KEY_N_FF "clip.%s.feed_forward_length" 42#define KEY_N_BLOCK "clip.%s.block_count" 43#define KEY_PROJ_DIM "clip.%s.projection_dim" 44#define KEY_N_HEAD "clip.%s.attention.head_count" 45#define KEY_N_HEAD_KV "clip.%s.attention.head_count_kv" 46#define KEY_N_EMBD_HEAD "clip.%s.attention.head_dim" 47#define KEY_LAYER_NORM_EPS "clip.%s.attention.layer_norm_epsilon" 48#define KEY_FEATURE_LAYERS "clip.%s.feature_layer" 49 50// vision-specific 51#define KEY_VISION_PROJ_TYPE "clip.vision.projector_type" // for models with mixed modalities 52#define KEY_IMAGE_SIZE "clip.vision.image_size" 53#define KEY_IMAGE_MIN_PIXELS "clip.vision.image_min_pixels" 54#define KEY_IMAGE_MAX_PIXELS "clip.vision.image_max_pixels" 55#define KEY_PREPROC_MIN_TILES "clip.vision.preproc_min_tiles" 56#define KEY_PREPROC_MAX_TILES "clip.vision.preproc_max_tiles" 57#define KEY_PREPROC_IMAGE_SIZE "clip.vision.preproc_image_size" 58#define KEY_PATCH_SIZE "clip.vision.patch_size" 59#define KEY_IMAGE_MEAN "clip.vision.image_mean" 60#define KEY_IMAGE_STD "clip.vision.image_std" 61#define KEY_PROJ_SCALE_FACTOR "clip.vision.projector.scale_factor" 62#define KEY_PROJ_SAMPLE_QUERY_SIDE "clip.vision.projector.query_side" 63#define KEY_PROJ_SAMPLE_WINDOW_SIDE "clip.vision.projector.window_side" 64#define KEY_PROJ_SPATIAL_OFFSETS "clip.vision.projector.spatial_offsets" 65#define KEY_SPATIAL_MERGE_SIZE "clip.vision.spatial_merge_size" 66 67#define KEY_MM_PATCH_MERGE_TYPE "clip.vision.mm_patch_merge_type" 68#define KEY_IMAGE_GRID_PINPOINTS "clip.vision.image_grid_pinpoints" 69#define KEY_WIN_ATTN_PATTERN "clip.vision.n_wa_pattern" 70#define KEY_WIN_ATTN_LAYER_INDEXES "clip.vision.wa_layer_indexes" 71#define KEY_WA_PATTERN_MODE "clip.vision.wa_pattern_mode" 72#define KEY_ATTN_WINDOW_SIZE "clip.vision.window_size" 73#define KEY_MINICPMV_VERSION "clip.minicpmv_version" 74#define KEY_MINICPMV_QUERY_NUM "clip.minicpmv_query_num" 75#define KEY_SAM_N_HEAD "clip.vision.sam.head_count" 76#define KEY_SAM_N_BLOCK "clip.vision.sam.block_count" 77#define KEY_SAM_N_EMBD "clip.vision.sam.embedding_length" 78#define KEY_VISION_N_EXPERT_USED "clip.vision.expert_used_count" 79// audio-specific 80#define KEY_AUDIO_PROJ_TYPE "clip.audio.projector_type" // for models with mixed modalities 81#define KEY_A_NUM_MEL_BINS "clip.audio.num_mel_bins" 82#define KEY_A_PROJ_STACK_FACTOR "clip.audio.projector.stack_factor" 83#define KEY_A_CHUNK_SIZE "clip.audio.chunk_size" 84#define KEY_A_CONV_KERNEL_SIZE "clip.audio.conv_kernel_size" 85#define KEY_A_MAX_POS_EMB "clip.audio.max_pos_emb" 86#define KEY_A_PROJ_WINDOW_SIZE "clip.audio.projector.window_size" 87#define KEY_A_PROJ_DOWNSAMPLE_RATE "clip.audio.projector.downsample_rate" 88#define KEY_A_PROJ_HEAD_COUNT "clip.audio.projector.head_count" 89#define KEY_A_RVQ_NUM_QUANTIZERS "clip.audio.rvq.num_quantizers" // mimo-audio-tokenizer 90#define KEY_A_RVQ_CODEBOOK_SIZE "clip.audio.rvq.codebook_size" // mimo-audio-tokenizer: per-quantizer bin count 91#define KEY_A_WA_PATTERN_MODE "clip.audio.wa_pattern_mode" // mimo-audio-tokenizer, per-layer -1 (full) / 0 (windowed) 92#define KEY_A_ATTN_WINDOW_SIZE "clip.audio.window_size" // mimo-audio-tokenizer: sliding-window radius 93#define KEY_A_LOCAL_BLOCK_COUNT "clip.audio.local_block_count" // mimo-v2.5: input_local_transformer layer count 94#define KEY_A_LOCAL_GROUP_SIZE "clip.audio.local_group_size" // mimo-v2.5: input_local_transformer grouping size 95// audio generation (gen-audio)-specific 96#define KEY_GEN_AUDIO_PROJ_TYPE "clip.gen.audio.projector_type" // for models with mixed modalities 97// name of the weight variant, for settings that are not in the checkpoint 98#define KEY_GEN_AUDIO_VARIANT "clip.gen.audio.model_variant" 99#define KEY_AUDIO_SUBSMPL_FACTOR "clip.audio.subsampling_factor" 100 101// 102// tensor name constants 103// 104 105#define TN_POS_EMBD "%s.position_embd.weight" 106#define TN_CLASS_EMBD "v.class_embd" 107#define TN_PATCH_EMBD "v.patch_embd.weight" // not rename tensor with ".0" postfix for backward compat 108#define TN_PATCH_EMBD_1 "v.patch_embd.weight.1" 109#define TN_PATCH_BIAS "v.patch_embd.bias" 110#define TN_NORM_EMBD "v.norm_embd.%s" 111#define TN_PATCH_NORM "v.patch_norm.%d.%s" 112#define TN_ATTN_QKV "%s.blk.%d.attn_qkv.%s" 113#define TN_ATTN_K "%s.blk.%d.attn_k.%s" 114#define TN_ATTN_Q "%s.blk.%d.attn_q.%s" 115#define TN_ATTN_V "%s.blk.%d.attn_v.%s" 116#define TN_ATTN_OUTPUT "%s.blk.%d.attn_out.%s" 117#define TN_ATTN_SINKS "%s.blk.%d.attn_sinks" 118#define TN_ATTN_K_NORM "%s.blk.%d.attn_k_norm.%s" 119#define TN_ATTN_Q_NORM "%s.blk.%d.attn_q_norm.%s" 120#define TN_FFN_DOWN "%s.blk.%d.ffn_down.%s" 121#define TN_FFN_GATE "%s.blk.%d.ffn_gate.%s" 122#define TN_FFN_UP "%s.blk.%d.ffn_up.%s" 123#define TN_FFN_GATE_INP "%s.blk.%d.ffn_gate_inp.%s" // MoE router (dots3note) 124#define TN_FFN_GATE_EXPS "%s.blk.%d.ffn_gate_exps.%s" 125#define TN_FFN_UP_EXPS "%s.blk.%d.ffn_up_exps.%s" 126#define TN_FFN_DOWN_EXPS "%s.blk.%d.ffn_down_exps.%s" 127#define TN_FFN_EXP_PROBS_B "%s.blk.%d.exp_probs_b.%s" 128#define TN_LN_1 "%s.blk.%d.ln1.%s" // layer norm 129#define TN_LN_2 "%s.blk.%d.ln2.%s" // layer norm 130#define TN_LS_1 "%s.blk.%d.ls1.%s" // layer scale 131#define TN_LS_2 "%s.blk.%d.ls2.%s" // layer scale 132#define TN_LS_OUT "%s.blk.%d.out_scale.%s" // layer out scale (gemma4) 133#define TN_ATTN_POST_NORM "%s.blk.%d.attn_post_norm.%s" // post-attn norm (gemma4) 134#define TN_FFN_POST_NORM "%s.blk.%d.ffn_post_norm.%s" // post-FFN norm (gemma4) 135#define TN_LN_PRE "%s.pre_ln.%s" 136#define TN_LN_POST "%s.post_ln.%s" 137#define TN_LLAVA_PROJ "mm.%d.%s" 138#define TN_MM_UP "mm.up.%s" 139#define TN_MM_GATE "mm.gate.%s" 140#define TN_MM_DOWN "mm.down.%s" 141#define TN_MM_POST_NORM "mm.post_norm.%s" 142#define TN_MVLM_PROJ_MLP "mm.model.mlp.%d.%s" 143#define TN_MVLM_PROJ_BLOCK "mm.model.mb_block.%d.block.%d.%s" 144#define TN_MVLM_PROJ_PEG "mm.model.peg.%d.%s" 145#define TN_IMAGE_NEWLINE "v.image_newline" 146#define TN_IMAGE_SEPERATOR "v.view_seperator" 147#define TN_MM_INP_NORM "mm.input_norm.weight" 148#define TN_MM_INP_NORM_B "mm.input_norm.bias" 149#define TN_MM_INP_PROJ "mm.input_projection.weight" // gemma3 150#define TN_MM_SOFT_EMB_N "mm.soft_emb_norm.weight" // gemma3 151#define TN_MM_PROJECTOR "mm.model.fc.%s" // idefics3, deepseekocr 152#define TN_MM_PATCH_MERGER "mm.patch_merger.%s" // mistral small 3.1, glm4v 153#define TN_MM_MERGER_FC1 "mm.merger.fc1.%s" // minimax-m3 patch-merge MLP 154#define TN_MM_MERGER_FC2 "mm.merger.fc2.%s" 155#define TN_TOK_IMG_BREAK "v.token_embd.img_break" // pixtral 156#define TN_TOK_IMG_START "v.token_embd.img_start" // deepseek4v 157#define TN_TOK_IMG_END "v.token_embd.img_end" // deepseek4v 158#define TN_TOK_IMG_PAD "v.token_embd.img_pad" // deepseek4v 159#define TN_TOK_GLM_BOI "adapter.boi" // glm-edge (these embeddings are not in text model) 160#define TN_TOK_GLM_EOI "adapter.eoi" // glm-edge (these embeddings are not in text model) 161#define TN_DEEPSTACK_NORM "v.deepstack.%d.norm.%s" // qwen3vl deepstack 162#define TN_DEEPSTACK_FC1 "v.deepstack.%d.fc1.%s" // qwen3vl deepstack 163#define TN_DEEPSTACK_FC2 "v.deepstack.%d.fc2.%s" // qwen3vl deepstack 164 165// mimicpmv 166#define TN_MINICPMV_POS_EMBD_K "resampler.pos_embed_k" 167#define TN_MINICPMV_QUERY "resampler.query" 168#define TN_MINICPMV_PROJ "resampler.proj.weight" 169#define TN_MINICPMV_KV_PROJ "resampler.kv.weight" 170#define TN_MINICPMV_ATTN "resampler.attn.%s.%s" 171#define TN_MINICPMV_LN "resampler.ln_%s.%s" 172 173// MiniCPM-V 4.6 ViT merger (window attention + MLP downsample), 174// matching the upstream `vit_merger` module name in transformers. 175#define TN_VIT_MERGER_LN1 "v.vit_merger.ln1.%s" 176#define TN_VIT_MERGER_ATTN_Q "v.vit_merger.attn_q.%s" 177#define TN_VIT_MERGER_ATTN_K "v.vit_merger.attn_k.%s" 178#define TN_VIT_MERGER_ATTN_V "v.vit_merger.attn_v.%s" 179#define TN_VIT_MERGER_ATTN_O "v.vit_merger.attn_out.%s" 180#define TN_VIT_MERGER_DS_LN "v.vit_merger.ds_ln.%s" 181#define TN_VIT_MERGER_DS_UP "v.vit_merger.ds_ffn_up.%s" 182#define TN_VIT_MERGER_DS_DOWN "v.vit_merger.ds_ffn_down.%s" 183 184#define TN_GLM_ADAPER_CONV "adapter.conv.%s" 185#define TN_GLM_ADAPTER_LINEAR "adapter.linear.linear.%s" 186#define TN_GLM_ADAPTER_NORM_1 "adapter.linear.norm1.%s" 187#define TN_GLM_ADAPTER_D_H_2_4H "adapter.linear.dense_h_to_4h.%s" 188#define TN_GLM_ADAPTER_GATE "adapter.linear.gate.%s" 189#define TN_GLM_ADAPTER_D_4H_2_H "adapter.linear.dense_4h_to_h.%s" 190 191// ultravox 192#define TN_CONV1D "a.conv1d.%d.%s" 193#define TN_CONV2D "a.conv2d.%d.%s" 194#define TN_CONV_OUT "a.conv_out.%s" 195#define TN_MM_AUDIO_MLP "mm.a.mlp.%d.%s" 196#define TN_MM_AUDIO_FC "mm.a.fc.%s" // fully connected layer 197#define TN_MM_NORM_PRE "mm.a.norm_pre.%s" 198#define TN_MM_NORM_MID "mm.a.norm_mid.%s" 199 200// mimo-audio-tokenizer 201#define TN_A_DOWNSAMPLE_CONV "a.downsample.conv.%s" 202#define TN_A_DOWNSAMPLE_NORM "a.downsample.norm.%s" 203#define TN_A_RVQ_CODEBOOK "a.rvq.codebook.%s" 204// mimo-v2.5: text-side RVQ code embedding ("text codebook") 205#define TN_MM_A_CODE_EMBD "mm.a.code_embd.%s" 206// mimo-v2.5: LLM-side connector (input_local_transformer) 207#define TN_MM_A_LOCAL_ATTN_Q "mm.a.local_blk.%d.attn_q.%s" 208#define TN_MM_A_LOCAL_ATTN_K "mm.a.local_blk.%d.attn_k.%s" 209#define TN_MM_A_LOCAL_ATTN_V "mm.a.local_blk.%d.attn_v.%s" 210#define TN_MM_A_LOCAL_ATTN_OUT "mm.a.local_blk.%d.attn_out.%s" 211#define TN_MM_A_LOCAL_FFN_GATE "mm.a.local_blk.%d.ffn_gate.%s" 212#define TN_MM_A_LOCAL_FFN_UP "mm.a.local_blk.%d.ffn_up.%s" 213#define TN_MM_A_LOCAL_FFN_DOWN "mm.a.local_blk.%d.ffn_down.%s" 214#define TN_MM_A_LOCAL_LN1 "mm.a.local_blk.%d.ln1.%s" 215#define TN_MM_A_LOCAL_LN2 "mm.a.local_blk.%d.ln2.%s" 216#define TN_MM_A_LOCAL_NORM "mm.a.local_norm.%s" 217 218// qwen3tts speaker encoder (ECAPA-TDNN) 219#define TN_A_SE_CONV1 "a.blk.%d.se_conv1.%s" 220#define TN_A_SE_CONV2 "a.blk.%d.se_conv2.%s" 221#define TN_A_CONV_RES2 "a.blk.%d.res2.%d.%s" 222#define TN_A_ASP_ATTN "a.asp_attn.%s" 223#define TN_A_ASP_TDNN "a.asp_tdnn.%s" 224 225// qwen3tts code_predictor 226#define TN_A_GEN_CODE_PROJ_IN "a.gen.code.proj_in.%s" 227#define TN_A_GEN_CODE_EMBD "a.gen.code.embd.%s" 228#define TN_A_GEN_CODE_HEAD "a.gen.code.head.%s" 229#define TN_A_GEN_CODE_OUT_EMBD "a.gen.code.out_embd.%s" 230#define TN_A_GEN_CODE_NORM "a.gen.code.output_norm.%s" 231 232// qwen3tts code2wav (RVQ codes -> raw PCM) 233// pre_transformer layers use the generic TN_ATTN_*/TN_FFN_*/TN_LN_*/TN_LS_* macros, prefix "a.gen.wav.tfm" 234#define TN_A_GEN_WAV_QUANT_FIRST_IN "a.gen.wav.quant.first.in_proj.%s" 235#define TN_A_GEN_WAV_QUANT_FIRST_OUT "a.gen.wav.quant.first.out_proj.%s" 236#define TN_A_GEN_WAV_QUANT_FIRST_CB "a.gen.wav.quant.first.codebook.%s" 237#define TN_A_GEN_WAV_QUANT_REST_IN "a.gen.wav.quant.rest.in_proj.%s" 238#define TN_A_GEN_WAV_QUANT_REST_OUT "a.gen.wav.quant.rest.out_proj.%s" 239#define TN_A_GEN_WAV_QUANT_REST_CB "a.gen.wav.quant.rest.codebook.%s" 240#define TN_A_GEN_WAV_PRE_CONV "a.gen.wav.pre_conv.%s" 241#define TN_A_GEN_WAV_TFM_IN_PROJ "a.gen.wav.tfm.in_proj.%s" 242#define TN_A_GEN_WAV_TFM_OUT_PROJ "a.gen.wav.tfm.out_proj.%s" 243#define TN_A_GEN_WAV_TFM_OUT_NORM "a.gen.wav.tfm.output_norm.%s" 244#define TN_A_GEN_WAV_UP_CONV "a.gen.wav.up.blk.%d.conv.%s" 245#define TN_A_GEN_WAV_UP_DWCONV "a.gen.wav.up.blk.%d.dwconv.%s" 246#define TN_A_GEN_WAV_UP_NORM "a.gen.wav.up.blk.%d.norm.%s" 247#define TN_A_GEN_WAV_UP_PW1 "a.gen.wav.up.blk.%d.pw1.%s" 248#define TN_A_GEN_WAV_UP_PW2 "a.gen.wav.up.blk.%d.pw2.%s" 249#define TN_A_GEN_WAV_UP_GAMMA "a.gen.wav.up.blk.%d.gamma" 250#define TN_A_GEN_WAV_DAC_ENTRY "a.gen.wav.dac.entry.%s" 251#define TN_A_GEN_WAV_DAC_SNAKE "a.gen.wav.dac.blk.%d.snake.%s" 252#define TN_A_GEN_WAV_DAC_CONV "a.gen.wav.dac.blk.%d.conv.%s" 253#define TN_A_GEN_WAV_DAC_RES_ACT1 "a.gen.wav.dac.blk.%d.res.%d.act1.%s" 254#define TN_A_GEN_WAV_DAC_RES_CONV1 "a.gen.wav.dac.blk.%d.res.%d.conv1.%s" 255#define TN_A_GEN_WAV_DAC_RES_ACT2 "a.gen.wav.dac.blk.%d.res.%d.act2.%s" 256#define TN_A_GEN_WAV_DAC_RES_CONV2 "a.gen.wav.dac.blk.%d.res.%d.conv2.%s" 257#define TN_A_GEN_WAV_DAC_POST_SNAKE "a.gen.wav.dac.post_snake.%s" 258#define TN_A_GEN_WAV_DAC_POST_CONV "a.gen.wav.dac.post_conv.%s" 259 260// pocket-tts 261#define TN_A_SEANET_CONV_IN "a.seanet.conv_in.%s" 262#define TN_A_SEANET_CONV_OUT "a.seanet.conv_out.%s" 263#define TN_A_SEANET_RES_CONV1 "a.seanet.blk.%d.res_conv1.%s" 264#define TN_A_SEANET_RES_CONV2 "a.seanet.blk.%d.res_conv2.%s" 265#define TN_A_SEANET_SCALE_CONV "a.seanet.blk.%d.scale_conv.%s" 266#define TN_A_SPEAKER_PROJ "a.speaker_proj.%s" 267#define TN_A_DOWNSAMPLE_CONV "a.downsample.conv.%s" 268#define TN_A_GEN_FLOW_INPUT_PROJ "a.gen.flow.input_proj.%s" 269#define TN_A_GEN_FLOW_COND_EMBD "a.gen.flow.cond_embd.%s" 270#define TN_A_GEN_FLOW_TIME_FREQS "a.gen.flow.time.%d.freqs" 271#define TN_A_GEN_FLOW_TIME_UP "a.gen.flow.time.%d.up.%s" 272#define TN_A_GEN_FLOW_TIME_DOWN "a.gen.flow.time.%d.down.%s" 273#define TN_A_GEN_FLOW_TIME_NORM "a.gen.flow.time.%d.norm" 274#define TN_A_GEN_FLOW_BLK_NORM "a.gen.flow.blk.%d.norm.%s" 275#define TN_A_GEN_FLOW_BLK_UP "a.gen.flow.blk.%d.up.%s" 276#define TN_A_GEN_FLOW_BLK_DOWN "a.gen.flow.blk.%d.down.%s" 277#define TN_A_GEN_FLOW_BLK_ADA "a.gen.flow.blk.%d.ada.%s" 278#define TN_A_GEN_FLOW_FINAL_ADA "a.gen.flow.final.ada.%s" 279#define TN_A_GEN_FLOW_FINAL_PROJ "a.gen.flow.final.proj.%s" 280#define TN_A_GEN_OUT_EOS "a.gen.out_eos.%s" 281#define TN_A_GEN_INPUT_LINEAR "a.gen.input_linear.%s" 282#define TN_A_GEN_EMB_MEAN "a.gen.emb_mean" 283#define TN_A_GEN_EMB_STD "a.gen.emb_std" 284#define TN_A_GEN_WAV_QUANT_OUT "a.gen.wav.quant_out.%s" 285#define TN_A_GEN_WAV_UPSAMPLE "a.gen.wav.upsample.%s" 286#define TN_A_GEN_WAV_SEANET_CONV_IN "a.gen.wav.seanet.conv_in.%s" 287#define TN_A_GEN_WAV_SEANET_CONV_OUT "a.gen.wav.seanet.conv_out.%s" 288#define TN_A_GEN_WAV_SEANET_RES_CONV1 "a.gen.wav.seanet.blk.%d.res_conv1.%s" 289#define TN_A_GEN_WAV_SEANET_RES_CONV2 "a.gen.wav.seanet.blk.%d.res_conv2.%s" 290#define TN_A_GEN_WAV_SEANET_SCALE_CONV "a.gen.wav.seanet.blk.%d.scale_conv.%s" 291 292// cogvlm 293#define TN_MM_POST_FC_NORM "mm.post_fc_norm.%s" 294#define TN_MM_H_TO_4H "mm.up.%s" 295#define TN_MM_GATE "mm.gate.%s" 296#define TN_MM_4H_TO_H "mm.down.%s" 297#define TN_TOK_BOI "v.boi" 298#define TN_TOK_EOI "v.eoi" 299 300// hunyuanvl (shared GGUF tensor names) 301#define TN_MM_PRE_NORM "mm.pre_norm.%s" 302#define TN_MM_IMG_BEGIN "mm.image_begin" // note: legacy name, new models should use v.token_embd.* 303#define TN_MM_IMG_END "mm.image_end" // note: legacy name, new models should use v.token_embd.* 304 305// deepseek-ocr 306#define TN_SAM_POS_EMBD "v.sam.pos_embd.%s" 307#define TN_SAM_PATCH_EMBD "v.sam.patch_embd.%s" 308#define TN_SAM_PRE_NORM "v.sam.blk.%d.pre_ln.%s" 309#define TN_SAM_POST_NORM "v.sam.blk.%d.post_ln.%s" 310#define TN_SAM_ATTN_POS_H "v.sam.blk.%d.attn.pos_h.%s" 311#define TN_SAM_ATTN_POS_W "v.sam.blk.%d.attn.pos_w.%s" 312#define TN_SAM_ATTN_QKV "v.sam.blk.%d.attn.qkv.%s" 313#define TN_SAM_ATTN_OUT "v.sam.blk.%d.attn.out.%s" 314#define TN_SAM_FFN_UP "v.sam.blk.%d.mlp.lin1.%s" 315#define TN_SAM_FFN_DOWN "v.sam.blk.%d.mlp.lin2.%s" 316#define TN_SAM_NECK "v.sam.neck.%d.%s" 317#define TN_SAM_NET "v.sam.net_%d.%s" 318// deepseek-ocr-2 319#define TN_RESMPL_QUERY "v.resample_query_%d.%s" 320// (conformer) lfm2 321#define TN_PRE_ENCODE_OUT "a.pre_encode.out.%s" 322#define TN_FFN_NORM "%s.blk.%d.ffn_norm.%s" 323#define TN_FFN_NORM_1 "%s.blk.%d.ffn_norm_1.%s" 324#define TN_FFN_UP_1 "%s.blk.%d.ffn_up_1.%s" 325#define TN_FFN_DOWN_1 "%s.blk.%d.ffn_down_1.%s" 326#define TN_POS_BIAS_U "%s.blk.%d.pos_bias_u" 327#define TN_POS_BIAS_V "%s.blk.%d.pos_bias_v" 328#define TN_NORM_CONV "%s.blk.%d.norm_conv.%s" 329#define TN_LINEAR_POS "%s.blk.%d.linear_pos.%s" 330#define TN_CONV_DW "%s.blk.%d.conv_dw.%s" 331#define TN_CONV_NORM "%s.blk.%d.conv_norm.%s" 332#define TN_CONV_PW1 "%s.blk.%d.conv_pw1.%s" 333#define TN_CONV_PW2 "%s.blk.%d.conv_pw2.%s" 334#define TN_INP_PROJ "a.input_projection.%s" 335#define TN_CTC_OUT "a.enc_ctc_out.%s" 336#define TN_CTC_OUT_MID "a.enc_ctc_out_mid.%s" 337#define TN_ATTN_REL_POS_EMB "%s.blk.%d.attn_rel_pos_emb" 338// qformer projector 339#define TN_QF_PROJ_QUERY "%s.proj_query" 340#define TN_QF_PROJ_NORM "%s.proj_norm.%s" 341#define TN_QF_PROJ_LINEAR "%s.proj_linear.%s" 342#define TN_QF_SELF_ATTN_Q "%s.proj_blk.%d.self_attn_q.%s" 343#define TN_QF_SELF_ATTN_K "%s.proj_blk.%d.self_attn_k.%s" 344#define TN_QF_SELF_ATTN_V "%s.proj_blk.%d.self_attn_v.%s" 345#define TN_QF_SELF_ATTN_O "%s.proj_blk.%d.self_attn_out.%s" 346#define TN_QF_SELF_ATTN_N "%s.proj_blk.%d.self_attn_norm.%s" 347#define TN_QF_CROSS_ATTN_Q "%s.proj_blk.%d.cross_attn_q.%s" 348#define TN_QF_CROSS_ATTN_K "%s.proj_blk.%d.cross_attn_k.%s" 349#define TN_QF_CROSS_ATTN_V "%s.proj_blk.%d.cross_attn_v.%s" 350#define TN_QF_CROSS_ATTN_O "%s.proj_blk.%d.cross_attn_out.%s" 351#define TN_QF_CROSS_ATTN_N "%s.proj_blk.%d.cross_attn_norm.%s" 352#define TN_QF_FFN_UP "%s.proj_blk.%d.ffn_up.%s" 353#define TN_QF_FFN_DOWN "%s.proj_blk.%d.ffn_down.%s" 354#define TN_QF_FFN_NORM "%s.proj_blk.%d.ffn_norm.%s" 355// multi-projector qformer (bid => projector ID) 356#define TN_MULTI_PROJ_IMG_POS "v.proj_blk.%d.img_pos" 357#define TN_MULTI_PROJ_QUERY "%s.proj_blk.%d.query" 358#define TN_MULTI_PROJ_LINEAR "%s.proj_blk.%d.linear.%s" 359#define TN_MULTI_PROJ_NORM "%s.proj_blk.%d.norm.%s" 360#define TN_MULTI_PROJ_POST_NORM "%s.proj_blk.%d.post_norm.%s" 361 362// gemma4 audio conformer 363#define TN_A_MM_INP_PROJ "mm.a.input_projection.%s" 364#define TN_A_MM_SOFT_EMB_N "mm.a.soft_emb_norm.%s" 365#define TN_A_INP_PROJ "a.input_projection.%s" 366#define TN_A_CONV1D "a.conv1d.%d.%s" 367#define TN_A_CONV1D_NORM "a.conv1d.%d.norm.%s" 368#define TN_A_OUT_PROJ "a.pre_encode.out.%s" 369#define TN_A_ATTN_PRE_NORM "%s.blk.%d.attn_pre_norm.%s" 370#define TN_A_ATTN_POST_NORM "%s.blk.%d.attn_post_norm.%s" 371#define TN_A_ATTN_K_REL "%s.blk.%d.attn_k_rel.%s" 372#define TN_A_PER_DIM_SCALE "%s.blk.%d.per_dim_scale.%s" 373#define TN_A_PER_DIM_K_SCALE "%s.blk.%d.per_dim_k_scale.%s" 374#define TN_A_FFN_POST_NORM "%s.blk.%d.ffn_post_norm.%s" 375#define TN_A_FFN_POST_NORM_1 "%s.blk.%d.ffn_post_norm_1.%s" 376 377// mobilenetv5 (gemma3n) definitions 378#define TN_MNV5_STEM_CONV "v.conv_stem.conv.weight" 379#define TN_MNV5_STEM_BIAS "v.conv_stem.conv.bias" 380#define TN_MNV5_STEM_BN "v.conv_stem.bn.weight" 381 382// Stage 0 Block (Edge Residual) 383#define TN_MNV5_BLK_S0_EXP_W "v.blk.%d.%d.conv_exp.weight" 384#define TN_MNV5_BLK_S0_BN1_W "v.blk.%d.%d.bn1.weight" 385#define TN_MNV5_BLK_S0_PWL_W "v.blk.%d.%d.conv_pwl.weight" 386#define TN_MNV5_BLK_S0_BN2_W "v.blk.%d.%d.bn2.weight" 387 388// Stage 1+ Block (Universal Inverted Residual) 389#define TN_MNV5_BLK_DW_START_W "v.blk.%d.%d.dw_start.conv.weight" 390#define TN_MNV5_BLK_DW_START_BN "v.blk.%d.%d.dw_start.bn.weight" 391#define TN_MNV5_BLK_DW_MID_W "v.blk.%d.%d.dw_mid.conv.weight" 392#define TN_MNV5_BLK_DW_MID_BN "v.blk.%d.%d.dw_mid.bn.weight" 393#define TN_MNV5_BLK_PW_EXP_W "v.blk.%d.%d.pw_exp.conv.weight" 394#define TN_MNV5_BLK_PW_EXP_BN "v.blk.%d.%d.pw_exp.bn.weight" 395#define TN_MNV5_BLK_PW_PROJ_W "v.blk.%d.%d.pw_proj.conv.weight" 396#define TN_MNV5_BLK_PW_PROJ_BN "v.blk.%d.%d.pw_proj.bn.weight" 397#define TN_MNV5_BLK_LAYER_SCALE "v.blk.%d.%d.layer_scale.gamma" 398 399// Attention Components 400#define TN_MNV5_ATTN_Q_W "v.blk.%d.%d.attn.query.proj.weight" 401#define TN_MNV5_ATTN_K_W "v.blk.%d.%d.attn.key.proj.weight" 402#define TN_MNV5_ATTN_V_W "v.blk.%d.%d.attn.value.proj.weight" 403#define TN_MNV5_ATTN_O_W "v.blk.%d.%d.attn.output.proj.weight" 404#define TN_MNV5_ATTN_K_DW "v.blk.%d.%d.attn.key.down_conv.weight" 405#define TN_MNV5_ATTN_K_NORM "v.blk.%d.%d.attn.key.norm.weight" 406#define TN_MNV5_ATTN_V_DW "v.blk.%d.%d.attn.value.down_conv.weight" 407#define TN_MNV5_ATTN_V_NORM "v.blk.%d.%d.attn.value.norm.weight" 408#define TN_MNV5_ATTN_NORM "v.blk.%d.%d.norm.weight" // Block norm used in attn blocks 409 410// MSFA 411#define TN_MNV5_MSFA_FFN_EXP_W "v.msfa.ffn.pw_exp.conv.weight" 412#define TN_MNV5_MSFA_FFN_EXP_BN "v.msfa.ffn.pw_exp.bn.weight" 413#define TN_MNV5_MSFA_FFN_PROJ_W "v.msfa.ffn.pw_proj.conv.weight" 414#define TN_MNV5_MSFA_FFN_PROJ_BN "v.msfa.ffn.pw_proj.bn.weight" 415#define TN_MNV5_MSFA_NORM "v.msfa.norm.weight" 416 417// gemma4 418#define TN_STD_BIAS "v.std_bias" 419#define TN_STD_SCALE "v.std_scale" 420 421// yasa2 422#define TN_YASA_PATCH_LN_W "v.patch_ln.weight" 423#define TN_YASA_PATCH_LN_B "v.patch_ln.bias" 424#define TN_YASA_BACKBONE_LN_W "v.backbone_ln.weight" 425#define TN_YASA_BACKBONE_LN_B "v.backbone_ln.bias" 426#define TN_YASA_POS_EMBD "v.vision_pos_embed" 427#define TN_YASA_STAGE_DOWN_LN "v.stage.%d.down.ln.%s" 428#define TN_YASA_STAGE_DOWN_CONV "v.stage.%d.down.conv.%s" 429#define TN_YASA_STAGE_BLK "v.stage.%d.blk.%d.%s.%s" 430 431// parakeet 432#define TN_MEL_FILTERS "a.mel_filters" 433#define TN_WINDOW "a.window" 434#define TN_CONV_NORM_MEAN "%s.blk.%d.conv_norm_mean" 435#define TN_CONV_NORM_VAR "%s.blk.%d.conv_norm_var" 436 437// align x to upper multiple of n 438#define CLIP_ALIGN (x ,n ) ((((x) + (n) - 1) / (n)) * (n)) 439 440// forward declaration 441// TODO: improve this later 442struct clip_ctx ; 443 444enum projector_type { 445PROJECTOR_TYPE_MLP , 446PROJECTOR_TYPE_MLP_NORM , 447PROJECTOR_TYPE_LDP , 448PROJECTOR_TYPE_LDPV2 , 449PROJECTOR_TYPE_MINICPMV , 450PROJECTOR_TYPE_GLM_EDGE , 451PROJECTOR_TYPE_QWEN2VL , 452PROJECTOR_TYPE_QWEN3VL , 453PROJECTOR_TYPE_STEP3VL , 454PROJECTOR_TYPE_GEMMA3 , 455PROJECTOR_TYPE_GEMMA3NV , 456PROJECTOR_TYPE_GEMMA3NA , 457PROJECTOR_TYPE_GEMMA4V , 458PROJECTOR_TYPE_GEMMA4A , 459PROJECTOR_TYPE_GEMMA4UV , 460PROJECTOR_TYPE_GEMMA4UA , 461PROJECTOR_TYPE_PHI4 , 462PROJECTOR_TYPE_IDEFICS3 , 463PROJECTOR_TYPE_PIXTRAL , 464PROJECTOR_TYPE_QWEN25VL , 465PROJECTOR_TYPE_ULTRAVOX , 466PROJECTOR_TYPE_INTERNVL , 467PROJECTOR_TYPE_LLAMA4 , 468PROJECTOR_TYPE_QWEN2A , 469PROJECTOR_TYPE_QWEN3A , 470PROJECTOR_TYPE_GLMA , 471PROJECTOR_TYPE_QWEN25O ,// will be replaced by QWEN2A or QWEN25VL depending on clip_ctx 472PROJECTOR_TYPE_VOXTRAL , 473PROJECTOR_TYPE_MERALION , 474PROJECTOR_TYPE_MUSIC_FLAMINGO , 475PROJECTOR_TYPE_LFM2 , 476PROJECTOR_TYPE_KIMIVL , 477PROJECTOR_TYPE_PADDLEOCR , 478PROJECTOR_TYPE_LIGHTONOCR , 479PROJECTOR_TYPE_COGVLM , 480PROJECTOR_TYPE_JANUS_PRO , 481PROJECTOR_TYPE_DOTS_OCR , 482PROJECTOR_TYPE_DOTS3NOTE_V , 483PROJECTOR_TYPE_DOTS3NOTE_A , 484PROJECTOR_TYPE_DEEPSEEKOCR , 485PROJECTOR_TYPE_DEEPSEEKOCR2 , 486PROJECTOR_TYPE_DEEPSEEK4V , 487PROJECTOR_TYPE_LFM2A , 488PROJECTOR_TYPE_GLM4V , 489PROJECTOR_TYPE_YOUTUVL , 490PROJECTOR_TYPE_YASA2 , 491PROJECTOR_TYPE_KIMIK25 , 492PROJECTOR_TYPE_NEMOTRON_V2_VL , 493PROJECTOR_TYPE_HUNYUANVL , 494PROJECTOR_TYPE_PARAKEET , 495PROJECTOR_TYPE_EXAONE4_5 , 496PROJECTOR_TYPE_MINICPMV4_6 , 497PROJECTOR_TYPE_GRANITE_SPEECH , 498PROJECTOR_TYPE_MIMOVL , 499PROJECTOR_TYPE_MINIMAX_M3 , 500PROJECTOR_TYPE_GRANITE4_VISION , 501PROJECTOR_TYPE_MIMO_AUDIO , 502PROJECTOR_TYPE_QWEN3TTS_SPKENC , 503PROJECTOR_TYPE_QWEN3TTS_GEN , 504PROJECTOR_TYPE_POCKETTTS_SPKENC , 505PROJECTOR_TYPE_POCKETTTS_GEN , 506PROJECTOR_TYPE_MUSE_GLIMMER , 507PROJECTOR_TYPE_UNKNOWN , 508}; 509 510static std ::map < projector_type ,std ::string > PROJECTOR_TYPE_NAMES = { 511 {PROJECTOR_TYPE_MLP ,"mlp" }, 512 {PROJECTOR_TYPE_LDP ,"ldp" }, 513 {PROJECTOR_TYPE_LDPV2 ,"ldpv2" }, 514 {PROJECTOR_TYPE_MINICPMV ,"resampler" }, 515 {PROJECTOR_TYPE_GLM_EDGE ,"adapter" }, 516 {PROJECTOR_TYPE_QWEN2VL ,"qwen2vl_merger" }, 517 {PROJECTOR_TYPE_QWEN25VL ,"qwen2.5vl_merger" }, 518 {PROJECTOR_TYPE_QWEN3VL ,"qwen3vl_merger" }, 519 {PROJECTOR_TYPE_STEP3VL ,"step3vl" }, 520 {PROJECTOR_TYPE_GEMMA3 ,"gemma3" }, 521 {PROJECTOR_TYPE_GEMMA3NV ,"gemma3nv" }, 522 {PROJECTOR_TYPE_GEMMA3NA ,"gemma3na" }, 523 {PROJECTOR_TYPE_GEMMA4V ,"gemma4v" }, 524 {PROJECTOR_TYPE_GEMMA4A ,"gemma4a" }, 525 {PROJECTOR_TYPE_GEMMA4UV ,"gemma4uv" }, 526 {PROJECTOR_TYPE_GEMMA4UA ,"gemma4ua" }, 527 {PROJECTOR_TYPE_PHI4 ,"phi4" }, 528 {PROJECTOR_TYPE_IDEFICS3 ,"idefics3" }, 529 {PROJECTOR_TYPE_PIXTRAL ,"pixtral" }, 530 {PROJECTOR_TYPE_ULTRAVOX ,"ultravox" }, 531 {PROJECTOR_TYPE_INTERNVL ,"internvl" }, 532 {PROJECTOR_TYPE_LLAMA4 ,"llama4" }, 533 {PROJECTOR_TYPE_QWEN2A ,"qwen2a" }, 534 {PROJECTOR_TYPE_QWEN3A ,"qwen3a" }, 535 {PROJECTOR_TYPE_GLMA ,"glma" }, 536 {PROJECTOR_TYPE_QWEN25O ,"qwen2.5o" }, 537 {PROJECTOR_TYPE_VOXTRAL ,"voxtral" }, 538 {PROJECTOR_TYPE_MERALION ,"meralion" }, 539 {PROJECTOR_TYPE_MUSIC_FLAMINGO ,"musicflamingo" }, 540 {PROJECTOR_TYPE_LFM2 ,"lfm2" }, 541 {PROJECTOR_TYPE_KIMIVL ,"kimivl" }, 542 {PROJECTOR_TYPE_PADDLEOCR ,"paddleocr" }, 543 {PROJECTOR_TYPE_LIGHTONOCR ,"lightonocr" }, 544 {PROJECTOR_TYPE_COGVLM ,"cogvlm" }, 545 {PROJECTOR_TYPE_JANUS_PRO ,"janus_pro" }, 546 {PROJECTOR_TYPE_DOTS_OCR ,"dots_ocr" }, 547 {PROJECTOR_TYPE_DOTS3NOTE_V ,"dots3note_v" }, 548 {PROJECTOR_TYPE_DOTS3NOTE_A ,"dots3note_a" }, 549 {PROJECTOR_TYPE_DEEPSEEKOCR ,"deepseekocr" }, 550 {PROJECTOR_TYPE_DEEPSEEKOCR2 ,"deepseekocr2" }, 551 {PROJECTOR_TYPE_DEEPSEEK4V ,"deepseek4v" }, 552 {PROJECTOR_TYPE_LFM2A ,"lfm2a" }, 553 {PROJECTOR_TYPE_GLM4V ,"glm4v" }, 554 {PROJECTOR_TYPE_YOUTUVL ,"youtuvl" }, 555 {PROJECTOR_TYPE_YASA2 ,"yasa2" }, 556 {PROJECTOR_TYPE_KIMIK25 ,"kimik25" }, 557 {PROJECTOR_TYPE_NEMOTRON_V2_VL ,"nemotron_v2_vl" }, 558 {PROJECTOR_TYPE_EXAONE4_5 ,"exaone4_5" }, 559 {PROJECTOR_TYPE_HUNYUANVL ,"hunyuanvl" }, 560 {PROJECTOR_TYPE_MINICPMV4_6 ,"minicpmv4_6" }, 561 {PROJECTOR_TYPE_GRANITE_SPEECH ,"granite_speech" }, 562 {PROJECTOR_TYPE_MIMOVL ,"mimovl" }, 563 {PROJECTOR_TYPE_MINIMAX_M3 ,"minimax_m3" }, 564 {PROJECTOR_TYPE_GRANITE4_VISION ,"granite4_vision" }, 565 {PROJECTOR_TYPE_MIMO_AUDIO ,"mimo_audio" }, 566 {PROJECTOR_TYPE_PARAKEET ,"parakeet" }, 567 {PROJECTOR_TYPE_QWEN3TTS_SPKENC ,"qwen3tts_spkenc" }, 568 {PROJECTOR_TYPE_QWEN3TTS_GEN ,"qwen3tts_gen" }, 569 {PROJECTOR_TYPE_POCKETTTS_SPKENC ,"pockettts_spkenc" }, 570 {PROJECTOR_TYPE_POCKETTTS_GEN ,"pockettts_gen" }, 571 {PROJECTOR_TYPE_MUSE_GLIMMER ,"muse-glimmer" }, 572}; 573 574static projector_type clip_projector_type_from_string (const std ::string & str ) { 575for (const auto& pair :PROJECTOR_TYPE_NAMES ) { 576if (pair .second == str ) { 577return pair .first ; 578 } 579 } 580return PROJECTOR_TYPE_UNKNOWN ; 581} 582 583// RGB uint8 image 584struct clip_image_u8 { 585clip_image_size get_size ()const { 586return {nx ,ny }; 587 } 588 589void set_size (clip_image_size size ,bool is_placeholder ) { 590nx = size .width ; 591ny = size .height ; 592if (is_placeholder ) { 593buf .clear (); 594 }else { 595buf .resize ((size_t )nx * (size_t )ny * 3 ); 596 } 597 } 598 599void cpy_buf (const std ::vector < uint8_t > & new_buf ) { 600buf = new_buf ; 601 } 602 603const std ::vector < uint8_t > & get_ro_buf ()const { 604if (is_placeholder ()) { 605throw std ::runtime_error ("this clip_image_u8 is a placeholder" ); 606 } 607return buf ; 608 } 609 610// note to contributors: NEVER add a get_rw_buf(), it is a DANGEROUS pattern. always use get_pixel / set_pixel for buffer manipulation 611 612bool is_placeholder ()const { 613return buf .empty (); 614 } 615 616std ::array < uint8_t ,3 > get_pixel (int x ,int y )const { 617if (is_placeholder ()) { 618// return a dummy value, so that legacy code can still process image without errors 619return {0 ,0 ,0 }; 620 } 621size_t idx = ((size_t )y * (size_t )nx + (size_t )x )* 3 ; 622return {buf [idx ],buf [idx + 1 ],buf [idx + 2 ] }; 623 } 624 625void set_pixel (int x ,int y ,const std ::array < uint8_t ,3 > & rgb ) { 626if (is_placeholder ()) { 627return ;// no-op 628 } 629size_t idx = ((size_t )y * (size_t )nx + (size_t )x )* 3 ; 630buf [idx ]= rgb [0 ]; 631buf [idx + 1 ]= rgb [1 ]; 632buf [idx + 2 ]= rgb [2 ]; 633 } 634 635size_t n_elements ()const { 636return n_pixels ()* 3 ; 637 } 638 639private : 640std ::vector < uint8_t > buf ; 641int nx = 0 ; 642int ny = 0 ; 643 644size_t n_pixels ()const { 645return (size_t )nx * (size_t )ny ; 646 } 647}; 648 649struct mtmd_serialization ;// forward declaration 650 651// For images, buf.size() == nx*ny*3 652// Memory layout: RGBRGBRGB... 653// For seq, buf.size() == nx*ny*3*nt 654// Memory layout: RGBRGB...RGBRGB... (nt times) 655// For audio, only one channel is used, buf.size() == nx*ny 656// nx will be n_frames and ny will be n_mel 657struct clip_image_f32 { 658// marks the global view in e.g., DeepSeek-OCR Models 659bool add_viewsep = false; 660// appends a learned newline (or EOI) token after the image 661// no model uses it now (Granite4 Vision moved to anyres), kept for future models 662bool add_newline = false; 663// deepseek4v: number of leading IMAGE_PAD embeddings, aligns IMAGE_START to the LLM compressor ratio 664// depends on the chunk position, set at tokenize time (see mtmd_tokenizer::add_media) 665int32_t lead_pad = 0 ; 666 667// llava-next "anyres" tiling, used by Granite4 Vision 668// the whole grid is encoded and assembled in a single graph 669// NOTE: excluded from serialized: a deserialized image is always a placeholder, which is never encoded 670struct anyres_info { 671int grid_x = 0 ;// tiles per row, 0 means the image is not tiled 672int grid_y = 0 ;// tiles per column 673int orig_nx = 0 ;// size of the source image, used to drop the padding tokens 674int orig_ny = 0 ; 675 676bool is_tiled ()const { 677return grid_x > 0 && grid_y > 0 ; 678 } 679 }; 680anyres_info anyres ; 681 682clip_image_size get_size ()const { 683return {nx_ ,ny_ }; 684 } 685 686int nx ()const {return nx_ ; } 687int ny ()const {return ny_ ; } 688 689void set_size (clip_image_size size ,bool is_placeholder ,bool is_audio ) { 690nx_ = size .width ; 691ny_ = size .height ; 692if (is_placeholder ) { 693buf .clear (); 694 }else { 695if (is_audio ) { 696buf .resize ((size_t )nx_ * (size_t )ny_ ); 697 }else { 698buf .resize ((size_t )nx_ * (size_t )ny_ * 3 ); 699 } 700 } 701 } 702 703void cpy_buf (const std ::vector < float > & new_buf ) { 704buf = new_buf ; 705 } 706 707void from_u8 (const clip_image_u8 & img ) { 708 autosize = img. get_size (); 709nx_ = size. width ; 710ny_ = size. height ; 711if (img. is_placeholder ()) { 712buf. clear (); 713return ; // no-op 714} 715buf. resize (img. n_elements ()); 716const auto & u8_buf = img. get_ro_buf (); 717for ( size_t i = 0 ; i < img. n_elements (); ++ i) { 718buf[i] = ( float ) u8_buf[i] / 255.0f ; 719} 720} 721 722size_t n_elements () const { 723return n_pixels () * 3 ; 724} 725 726void normalize ( const float mean[ 3 ], const float std[ 3 ]) { 727if ( is_placeholder ()) { 728return ; // no-op 729} 730for ( size_t i = 0 ; i < n_pixels (); ++ i) { 731buf[i * 3 + 0 ] = (buf[i * 3 + 0 ] - mean[ 0 ]) / std[ 0 ]; 732buf[i * 3 + 1 ] = (buf[i * 3 + 1 ] - mean[ 1 ]) / std[ 1 ]; 733buf[i * 3 + 2 ] = (buf[i * 3 + 2 ] - mean[ 2 ]) / std[ 2 ]; 734} 735} 736 737const std ::vector < float > & get_ro_buf () const { 738if ( is_placeholder ()) { 739throw std::runtime_error( "this clip_image_f32 is a placeholder" ); 740} 741return buf; 742} 743 744// note to contributors: NEVER add a get_rw_buf(), it is a DANGEROUS pattern 745 746bool is_placeholder () const { 747return buf. empty (); 748} 749 750void serialize ( struct mtmd_serialization & ser) const; 751void deserialize ( struct mtmd_serialization & ser); 752 753private : 754std ::vector < float > buf; 755int nx_ = 0 ; 756int ny_ = 0 ; 757 758size_t n_pixels () const { 759return ( size_t ) nx_ * ( size_t ) ny_; 760} 761}; 762 763// token area kept after removing the padding added by the anyres resize 764// ref: https://github.com/huggingface/transformers/blob/v5.0.0/src/transformers/models/llava_next/modeling_llava_next.py#L109 765static inline void clip_anyres_unpad ( int cur_w, int cur_h, int orig_w, int orig_h, 766int & off_x, int & off_y, int & out_w, int & out_h) { 767off_x = 0 ; 768off_y = 0 ; 769out_w = cur_w; 770out_h = cur_h; 771if (( float ) orig_w / orig_h > ( float ) cur_w / cur_h) { 772const int new_h = ( int ) std:: floor (( double ) orig_h * cur_w / orig_w + 1e-7 ); 773off_y = (cur_h - new_h) / 2 ; 774out_h = cur_h - 2 * off_y; 775} else { 776const int new_w = ( int ) std:: floor (( double ) orig_w * cur_h / orig_h + 1e-7 ); 777off_x = (cur_w - new_w) / 2 ; 778out_w = cur_w - 2 * off_x; 779} 780} 781 782// deepseek4v: layout of the LLM token block built from the aligner grid 783struct dsv4_block_layout { 784int rows ; // grid rows, padded to an even count 785int row_len ; // grid width + 1 newline 786int pad_last ; // trailing pads 787int n_out ; // total block size, including lead pads and the start/end sentinels 788}; 789static inline dsv4_block_layout dsv4_get_block_layout ( int n_llm_w, int n_llm_h, int lead_pad) { 790dsv4_block_layout bl; 791bl. rows = n_llm_h + (n_llm_h % 2 ); 792bl. row_len = n_llm_w + 1 ; 793bl. pad_last = (bl. rows / 2 * bl. row_len ) % 2 * 2 ; 794bl. n_out = lead_pad + 1 + bl. rows * bl. row_len + bl. pad_last + 1 ; 795return bl; 796} 797 798// 799// logging 800// 801 802static void clip_log_callback_default ( enum ggml_log_level level, const char * text, void * user_data) { 803( void ) level; 804( void ) user_data; 805fputs (text, stderr); 806fflush (stderr); 807} 808 809struct clip_logger_state { 810ggml_log_callback log_callback ; 811void * log_callback_user_data ; 812}; 813 814extern struct clip_logger_state g_logger_state; 815 816static void clip_log_internal_v ( enum ggml_log_level level, const char * format, va_list args) { 817if (format == NULL ) { 818return ; 819} 820va_list args_copy; 821va_copy (args_copy, args); 822char buffer[ 128 ]; 823int len = vsnprintf (buffer, 128 , format, args); 824if (len < 128 ) { 825g_logger_state. log_callback (level, buffer, g_logger_state. log_callback_user_data ); 826} else { 827char * buffer2 = ( char * ) calloc (len + 1 , sizeof ( char )); 828vsnprintf (buffer2, len + 1 , format, args_copy); 829buffer2[len] = 0 ; 830g_logger_state. log_callback (level, buffer2, g_logger_state. log_callback_user_data ); 831free (buffer2); 832} 833va_end (args_copy); 834} 835 836static void clip_log_internal ( enum ggml_log_level level, const char * format, ...) { 837va_list args; 838va_start (args, format); 839clip_log_internal_v (level, format, args); 840va_end (args); 841} 842 843#define LOG_TRC (...) clip_log_internal(GGML_LOG_LEVEL_DEBUG, __VA_ARGS__) 844#define LOG_DBG (...) clip_log_internal(GGML_LOG_LEVEL_DEBUG, __VA_ARGS__) 845#define LOG_INF (...) clip_log_internal(GGML_LOG_LEVEL_INFO, __VA_ARGS__) 846#define LOG_WRN (...) clip_log_internal(GGML_LOG_LEVEL_WARN, __VA_ARGS__) 847#define LOG_ERR (...) clip_log_internal(GGML_LOG_LEVEL_ERROR, __VA_ARGS__) 848#define LOG_CNT (...) clip_log_internal(GGML_LOG_LEVEL_CONT, __VA_ARGS__) 849 850// 851// cpp wrappers 852// 853 854struct clip_image_f32_batch { 855std :: vector < clip_image_f32 > entries ; 856bool is_audio = false; 857 858clip_image_f32_batch clone () const { 859clip_image_f32_batch new_batch{ 860/* entries */ {}, 861/* is_audio */ is_audio , 862}; 863new_batch . entries . reserve ( entries . size ()); 864for ( const auto & entry : entries) { 865new_batch . entries . emplace_back ( entry ); // copy 866} 867return new_batch; 868} 869 870void serialize ( struct mtmd_serialization & ser) const; 871void deserialize ( struct mtmd_serialization & ser); 872}; 873 874// 875// common utils 876// 877 878#ifdef _WIN32 879static std ::ifstream open_ifstream_binary ( const std ::string & fname) { 880int wlen = MultiByteToWideChar ( CP_UTF8 , 0 , fname. c_str (), -1 , NULL , 0 ); 881if (!wlen) { 882throw std::runtime_error( "failed to convert filename to UTF-16: " + fname); 883} 884std ::vector < wchar_t > wfname (wlen); 885( void ) MultiByteToWideChar ( CP_UTF8 , 0 , fname. c_str (), -1 , wfname. data (), wlen); 886return std:: ifstream (wfname. data (), std::ios::binary); 887} 888#else 889static std ::ifstream open_ifstream_binary ( const std ::string & fname) { 890return std:: ifstream (fname, std::ios::binary); 891} 892#endif 893 894// in test-mtmd-impl, we include woth common.h and this file, and these functions are duplicated 895// this is a quick fix to avoid compilation errors 896#ifndef DIRECTORY_SEPARATOR 897static std ::string string_format ( const char * fmt, ...) { 898va_list ap; 899va_list ap2; 900va_start (ap, fmt); 901va_copy (ap2, ap); 902int size = vsnprintf ( NULL , 0 , fmt, ap); 903GGML_ASSERT (size >= 0 && size < INT_MAX ); // NOLINT 904std ::vector < char > buf (size + 1 ); 905int size2 = vsnprintf (buf. data (), size + 1 , fmt, ap2); 906GGML_ASSERT (size2 == size); 907va_end (ap2); 908va_end (ap); 909return std:: string (buf. data (), buf. size ()); 910} 911 912static void string_replace_all ( std ::string & s, const std ::string & search, const std ::string & replace) { 913if (search. empty ()) { 914return ; 915} 916std :: string builder; 917builder. reserve (s. length ()); 918size_t pos = 0 ; 919size_t last_pos = 0 ; 920while ((pos = s. find (search, last_pos)) != std::string::npos) { 921builder. append (s, last_pos, pos - last_pos); 922builder. append (replace); 923last_pos = pos + search. length (); 924} 925builder. append (s, last_pos, std::string::npos); 926s = std:: move (builder); 927} 928 929// split string by a `std::string delim` instead of `char delim` 930static std ::vector < std::string > string_split_str ( std ::string s, const std ::string & delimiter) { 931std ::vector < std::string > tokens; 932size_t pos = 0 ; 933std :: string token; 934while ((pos = s. find (delimiter)) != std::string::npos) { 935token = s. substr ( 0 , pos); 936tokens. push_back (token); 937s. erase ( 0 , pos + delimiter. length ()); 938} 939tokens. push_back (s); 940return tokens; 941} 942 943// remove when moving to c++20 944inline bool string_starts_with ( std ::string_view str, std ::string_view prefix) { 945return str. size () >= prefix. size () && 946str. compare ( 0 , prefix. size (), prefix) == 0 ; 947} 948 949// remove when moving to c++20 950inline bool string_ends_with ( std ::string_view str, std ::string_view suffix) { 951return str. size () >= suffix. size () && 952str. compare (str. size () - suffix. size (), suffix. size (), suffix) == 0 ; 953} 954#endif 955 956// 957// gguf utils 958// 959 960static std ::string gguf_data_to_str ( enum gguf_type type, const void * data, int i) { 961switch (type) { 962case GGUF_TYPE_UINT8 : return std:: to_string ((( const uint8_t * )data)[i]); 963case GGUF_TYPE_INT8 : return std:: to_string ((( const int8_t * )data)[i]); 964case GGUF_TYPE_UINT16 : return std:: to_string ((( const uint16_t * )data)[i]); 965case GGUF_TYPE_INT16 : return std:: to_string ((( const int16_t * )data)[i]); 966case GGUF_TYPE_UINT32 : return std:: to_string ((( const uint32_t * )data)[i]); 967case GGUF_TYPE_INT32 : return std:: to_string ((( const int32_t * )data)[i]); 968case GGUF_TYPE_UINT64 : return std:: to_string ((( const uint64_t * )data)[i]); 969case GGUF_TYPE_INT64 : return std:: to_string ((( const int64_t * )data)[i]); 970case GGUF_TYPE_FLOAT32 : return std:: to_string ((( const float * )data)[i]); 971case GGUF_TYPE_FLOAT64 : return std:: to_string ((( const double * )data)[i]); 972case GGUF_TYPE_BOOL : return (( const int8_t * )data)[i] != 0 ? "true" : "false" ; 973default : return string_format ( "unknown type %d" , type); 974} 975} 976 977static std ::string gguf_kv_to_str ( const struct gguf_context * ctx_gguf, int i) { 978const enum gguf_type type = gguf_get_kv_type (ctx_gguf, i); 979 980switch (type) { 981case GGUF_TYPE_STRING : 982return gguf_get_val_str (ctx_gguf, i); 983case GGUF_TYPE_ARRAY : 984{ 985const enum gguf_type arr_type = gguf_get_arr_type (ctx_gguf, i); 986int arr_n = gguf_get_arr_n (ctx_gguf, i); 987const void * data = arr_type == GGUF_TYPE_STRING ? nullptr : gguf_get_arr_data (ctx_gguf, i); 988std :: stringstream ss; 989ss << "[" ; 990for ( int j = 0 ; j < arr_n; j ++ ) { 991if (arr_type == GGUF_TYPE_STRING ) { 992std :: string val = gguf_get_arr_str (ctx_gguf, i, j); 993// escape quotes 994string_replace_all (val, "\\" , "\\\\" ); 995string_replace_all (val, "\"" , "\\\"" ); 996ss << '"' << val << '"' ; 997} else if (arr_type == GGUF_TYPE_ARRAY ) { 998ss << "???" ; 999} else { 1000ss << gguf_data_to_str (arr_type, data, j); 1001} 1002if (j < arr_n - 1 ) { 1003ss << ", " ; 1004} 1005} 1006ss << "]" ; 1007return ss. str (); 1008} 1009default : 1010return gguf_data_to_str (type, gguf_get_val_data (ctx_gguf, i), 0 ); 1011} 1012} 1013 1014// 1015// debugging 1016// 1017 1018static void print_tensor_shape ( ggml_tensor * t) { 1019printf ( "%s.shape = [" , t -> name ); 1020for ( int i = 0 ; i < ggml_n_dims (t); ++ i) { 1021printf ( "%" PRId64, t -> ne [i]); 1022if (i < ggml_n_dims (t) - 1 ) { 1023printf ( ", " ); 1024} 1025} 1026printf ( "]\n" ); 1027} 1028 1029static void print_tensor_data ( ggml_tensor * t, uint8_t * data, int64_t n) { 1030ggml_type type = t -> type ; 1031int64_t * ne = t -> ne ; 1032size_t * nb = t -> nb ; 1033for ( int64_t i3 = 0 ; i3 < ne[ 3 ]; i3 ++ ) { 1034printf ( "%s.data: [\n" , t -> name ); 1035for ( int64_t i2 = 0 ; i2 < ne[ 2 ]; i2 ++ ) { 1036if (i2 == n && ne[ 2 ] > 2 * n) { 1037printf ( " ..., \n" ); 1038i2 = ne[ 2 ] - n; 1039} 1040printf ( " [\n" ); 1041for ( int64_t i1 = 0 ; i1 < ne[ 1 ]; i1 ++ ) { 1042if (i1 == n && ne[ 1 ] > 2 * n) { 1043printf ( " ..., \n" ); 1044i1 = ne[ 1 ] - n; 1045} 1046printf ( " [" ); 1047for ( int64_t i0 = 0 ; i0 < ne[ 0 ]; i0 ++ ) { 1048if (i0 == n && ne[ 0 ] > 2 * n) { 1049printf ( "..., " ); 1050i0 = ne[ 0 ] - n; 1051} 1052size_t i = i3 * nb[ 3 ] + i2 * nb[ 2 ] + i1 * nb[ 1 ] + i0 * nb[ 0 ]; 1053float v; 1054if (type == GGML_TYPE_F16 ) { 1055v = ggml_fp16_to_fp32 ( * ( ggml_fp16_t * ) & data[i]); 1056} else if (type == GGML_TYPE_F32 ) { 1057v = * ( float * ) & data[i]; 1058} else if (type == GGML_TYPE_I32 ) { 1059v = ( float ) * ( int32_t * ) & data[i]; 1060} else if (type == GGML_TYPE_I16 ) { 1061v = ( float ) * ( int16_t * ) & data[i]; 1062} else if (type == GGML_TYPE_I8 ) { 1063v = ( float ) * ( int8_t * ) & data[i]; 1064} else { 1065GGML_ABORT ( "fatal error" ); 1066} 1067printf ( "%8.4f" , v); 1068if (i0 < ne[ 0 ] - 1 ) printf ( ", " ); 1069} 1070printf ( "],\n" ); 1071} 1072printf ( " ],\n" ); 1073} 1074printf ( " ]\n" ); 1075} 1076} 1077 1078// 1079// API used internally with mtmd 1080// 1081 1082projector_type clip_get_projector_type ( const struct clip_ctx * ctx); 1083void clip_set_debug_output_embeddings ( struct clip_ctx * ctx, bool debug );