-
Notifications
You must be signed in to change notification settings - Fork 13.9k
mtmd: Add DeepSeekOCR Support #17400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
43a130b
b6b9f02
85c7cda
578c8d7
2aab52e
eab28ed
7630587
2de3436
e8b2610
97e0907
13dc6fb
b32bb5e
790bbb9
cec9a5c
8b3d319
1e08157
331cea8
6c0715b
a65ddf5
63a042f
89afda8
88032f4
1268dc3
68b206b
8bce66d
5e6cf3c
7e9fbec
0f5587d
7b8d735
86f111f
effe669
f8f66a1
3fcfc3a
ee8a148
4cfa15f
3f71188
a594990
6dfda99
7941f5d
206f8ab
40e7e6e
81533e4
8810940
a488b49
ccb2f23
841a4a8
ed3b7f1
5543094
c5f4c64
95239f9
6b0e7cd
6634166
c914e05
e20857b
43dfc0c
b696c54
b26b507
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -697,6 +697,9 @@ def load_hparams(dir_model: Path, is_mistral_format: bool): | |||||||||||||||||||||||||||||||||||||||||||||||
| if "thinker_config" in config: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # rename for Qwen2.5-Omni | ||||||||||||||||||||||||||||||||||||||||||||||||
| config["text_config"] = config["thinker_config"]["text_config"] | ||||||||||||||||||||||||||||||||||||||||||||||||
| if "language_config" in config: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # rename for DeepSeekOCR | ||||||||||||||||||||||||||||||||||||||||||||||||
| config["text_config"] = config["language_config"] | ||||||||||||||||||||||||||||||||||||||||||||||||
| return config | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| @classmethod | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1531,7 +1534,7 @@ class MmprojModel(ModelBase): | |||||||||||||||||||||||||||||||||||||||||||||||
| preprocessor_config: dict[str, Any] | ||||||||||||||||||||||||||||||||||||||||||||||||
| global_config: dict[str, Any] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| n_block_keys = ["n_layers", "num_hidden_layers", "n_layer", "num_layers", "depth"] | ||||||||||||||||||||||||||||||||||||||||||||||||
| n_block_keys = ["n_layers", "num_hidden_layers", "n_layer", "num_layers", "depth", "layers"] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| has_vision_encoder: bool = True # by default | ||||||||||||||||||||||||||||||||||||||||||||||||
| has_audio_encoder: bool = False | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1577,6 +1580,14 @@ def __init__(self, *args, **kwargs): | |||||||||||||||||||||||||||||||||||||||||||||||
| # TODO @ngxson : this is a hack to support both vision and audio encoders | ||||||||||||||||||||||||||||||||||||||||||||||||
| have_multiple_encoders = self.has_audio_encoder and self.has_vision_encoder | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.block_count = 128 if have_multiple_encoders else self.find_hparam(self.n_block_keys, True) | ||||||||||||||||||||||||||||||||||||||||||||||||
| # FIXME: DeepseekOCRVisionModel specific hack | ||||||||||||||||||||||||||||||||||||||||||||||||
| if self.block_count is None: | ||||||||||||||||||||||||||||||||||||||||||||||||
| if isinstance(self, DeepseekOCRVisionModel): | ||||||||||||||||||||||||||||||||||||||||||||||||
| clip_block_count = self.hparams['layers'] | ||||||||||||||||||||||||||||||||||||||||||||||||
| if clip_block_count is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.block_count = clip_block_count | ||||||||||||||||||||||||||||||||||||||||||||||||
| if self.block_count is None: | ||||||||||||||||||||||||||||||||||||||||||||||||
| raise KeyError(f"could not find block count using any of: {self.n_block_keys}") | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.tensor_map = gguf.get_tensor_name_map(gguf.MODEL_ARCH.MMPROJ, self.block_count) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| # load preprocessor config | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -5990,6 +6001,99 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter | |||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| return [] # skip other tensors | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| @ModelBase.register("DeepseekOCRForCausalLM") | ||||||||||||||||||||||||||||||||||||||||||||||||
| class DeepseekOCRVisionModel(MmprojModel): | ||||||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self, *args, **kwargs): | ||||||||||||||||||||||||||||||||||||||||||||||||
| super().__init__(*args, **kwargs) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| proc_fname = self.dir_model / "processor_config.json" | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if proc_fname.is_file(): | ||||||||||||||||||||||||||||||||||||||||||||||||
| with open(proc_fname, "r") as f: | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.preprocessor_config = json.load(f) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| def set_gguf_parameters(self): | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+6006
to
+6016
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
No longer required, already handled. |
||||||||||||||||||||||||||||||||||||||||||||||||
| super().set_gguf_parameters() | ||||||||||||||||||||||||||||||||||||||||||||||||
| hparams = self.hparams | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.DEEPSEEKOCR) | ||||||||||||||||||||||||||||||||||||||||||||||||
| # default values below are taken from HF tranformers code | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_vision_attention_layernorm_eps(hparams.get("layer_norm_eps", 1e-6)) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_vision_use_gelu(True) | ||||||||||||||||||||||||||||||||||||||||||||||||
| # calculate proj_scale_factor (used by tinygemma3 test model) | ||||||||||||||||||||||||||||||||||||||||||||||||
| image_seq_length = self.preprocessor_config.get("image_seq_length", 256) | ||||||||||||||||||||||||||||||||||||||||||||||||
| n_per_side = int(image_seq_length ** 0.5) | ||||||||||||||||||||||||||||||||||||||||||||||||
| image_size = self.hparams["image_size"] | ||||||||||||||||||||||||||||||||||||||||||||||||
| patch_size = self.hparams["patch_size"] | ||||||||||||||||||||||||||||||||||||||||||||||||
| proj_scale_factor = (image_size // patch_size) // n_per_side | ||||||||||||||||||||||||||||||||||||||||||||||||
| if proj_scale_factor > 0 and proj_scale_factor != 4: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # we only need to write this if it's not the default value | ||||||||||||||||||||||||||||||||||||||||||||||||
| # in this case, we are converting a test model | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_vision_projector_scale_factor(proj_scale_factor) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| # SAM configuration | ||||||||||||||||||||||||||||||||||||||||||||||||
| sam_hparams = hparams['sam'] | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_vision_sam_layers_count(sam_hparams['layers']) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_vision_sam_embedding_length(sam_hparams['width']) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| def get_vision_config(self) -> dict[str, Any]: | ||||||||||||||||||||||||||||||||||||||||||||||||
| vision_config: dict[str, Any] | None = self.global_config.get("vision_config") | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if not vision_config: | ||||||||||||||||||||||||||||||||||||||||||||||||
| raise ValueError("DeepseekOCR model requires 'vision_config' in the model configuration, but it was not found") | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| vision_config['sam'] = vision_config['width']['sam_vit_b'] | ||||||||||||||||||||||||||||||||||||||||||||||||
| vision_config.update(vision_config['width']['clip-l-14-224']) | ||||||||||||||||||||||||||||||||||||||||||||||||
| vision_config['hidden_size'] = vision_config['width'] | ||||||||||||||||||||||||||||||||||||||||||||||||
| vision_config['num_heads'] = vision_config['heads'] | ||||||||||||||||||||||||||||||||||||||||||||||||
| vision_config['intermediate_size'] = vision_config['heads'] * 4 | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| return vision_config | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| def tensor_force_quant(self, name, new_name, bid, n_dims): | ||||||||||||||||||||||||||||||||||||||||||||||||
| # TODO: increase numercial stability. maybe delete later. | ||||||||||||||||||||||||||||||||||||||||||||||||
| return gguf.GGMLQuantizationType.F32 | ||||||||||||||||||||||||||||||||||||||||||||||||
| # related to https://github.com/ggml-org/llama.cpp/issues/13025 | ||||||||||||||||||||||||||||||||||||||||||||||||
| # if "input_projection" in name: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # return gguf.GGMLQuantizationType.F16 | ||||||||||||||||||||||||||||||||||||||||||||||||
| # if ".embeddings." in name: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # return gguf.GGMLQuantizationType.F32 | ||||||||||||||||||||||||||||||||||||||||||||||||
| # return super().tensor_force_quant(name, new_name, bid, n_dims) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # Only process vision-related tensors, skip language model tensors | ||||||||||||||||||||||||||||||||||||||||||||||||
| # Vision components: sam_model, vision_model, projector, image_newline, view_seperator | ||||||||||||||||||||||||||||||||||||||||||||||||
| # Language model components to skip: lm_head, embed_tokens, layers, norm | ||||||||||||||||||||||||||||||||||||||||||||||||
| if name.startswith(("lm_head.", "model.embed_tokens.", "model.layers.", "model.norm.")): | ||||||||||||||||||||||||||||||||||||||||||||||||
| return [] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if ".attn.rel_pos_h" in name or ".attn.rel_pos_w" in name: | ||||||||||||||||||||||||||||||||||||||||||||||||
| return [(self.map_tensor_name(name, try_suffixes=("",)), data_torch)] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if name.startswith("model.vision_model.transformer.layers."): | ||||||||||||||||||||||||||||||||||||||||||||||||
| # process visual tensors | ||||||||||||||||||||||||||||||||||||||||||||||||
| # split QKV tensors if needed | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to split. you can see an example of how fused qkv can be used in Qwen3 model |
||||||||||||||||||||||||||||||||||||||||||||||||
| if ".qkv_proj." in name: | ||||||||||||||||||||||||||||||||||||||||||||||||
| if data_torch.ndim == 2: # weight | ||||||||||||||||||||||||||||||||||||||||||||||||
| c3, _ = data_torch.shape | ||||||||||||||||||||||||||||||||||||||||||||||||
| else: # bias | ||||||||||||||||||||||||||||||||||||||||||||||||
| c3 = data_torch.shape[0] | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert c3 % 3 == 0 | ||||||||||||||||||||||||||||||||||||||||||||||||
| c = c3 // 3 | ||||||||||||||||||||||||||||||||||||||||||||||||
| wq = data_torch[:c] | ||||||||||||||||||||||||||||||||||||||||||||||||
| wk = data_torch[c: c * 2] | ||||||||||||||||||||||||||||||||||||||||||||||||
| wv = data_torch[c * 2:] | ||||||||||||||||||||||||||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||||||||||||||||||||||||||
| (self.map_tensor_name(name.replace("qkv", "q")), wq), | ||||||||||||||||||||||||||||||||||||||||||||||||
| (self.map_tensor_name(name.replace("qkv", "k")), wk), | ||||||||||||||||||||||||||||||||||||||||||||||||
| (self.map_tensor_name(name.replace("qkv", "v")), wv), | ||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||
| return [(self.map_tensor_name(name), data_torch)] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| return [(self.map_tensor_name(name), data_torch)] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+6074
to
+6095
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Please don't do this, create views instead. |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| @ModelBase.register("Gemma3nForConditionalGeneration") | ||||||||||||||||||||||||||||||||||||||||||||||||
| class Gemma3NModel(Gemma3Model): | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -7159,6 +7263,7 @@ def prepare_tensors(self): | |||||||||||||||||||||||||||||||||||||||||||||||
| @ModelBase.register( | ||||||||||||||||||||||||||||||||||||||||||||||||
| "DeepseekV2ForCausalLM", | ||||||||||||||||||||||||||||||||||||||||||||||||
| "DeepseekV3ForCausalLM", | ||||||||||||||||||||||||||||||||||||||||||||||||
| "DeepseekOCRForCausalLM", | ||||||||||||||||||||||||||||||||||||||||||||||||
| "KimiVLForConditionalGeneration", | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||
| class DeepseekV2Model(TextModel): | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -7219,31 +7324,49 @@ def set_vocab(self): | |||||||||||||||||||||||||||||||||||||||||||||||
| raise NotImplementedError(f"Deepseek pre-tokenizer {tokpre!r} is not supported yet!") | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| def set_gguf_parameters(self): | ||||||||||||||||||||||||||||||||||||||||||||||||
| is_ocr = (self.hparams["num_hidden_layers"] == 12) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| # note: deepseek2 using MLA converts into MQA (ie: GQA with 1 group) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.hparams["num_key_value_heads"] = 1 | ||||||||||||||||||||||||||||||||||||||||||||||||
| if is_ocr: | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.hparams['rope_theta'] = self.hparams.get('rope_theta', 10000.0) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.hparams['rms_norm_eps'] = self.hparams.get('rms_norm_eps', 1e-6) | ||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # note: deepseek2 using MLA converts into MQA (ie: GQA with 1 group) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.hparams["num_key_value_heads"] = 1 | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| super().set_gguf_parameters() | ||||||||||||||||||||||||||||||||||||||||||||||||
| hparams = self.hparams | ||||||||||||||||||||||||||||||||||||||||||||||||
| kv_lora_rank = hparams["q_lora_rank"] if hparams["q_lora_rank"] is not None else 512 | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||
| routed_scaling_factor = hparams.get("routed_scaling_factor", 1.0) | ||||||||||||||||||||||||||||||||||||||||||||||||
| norm_topk_prob = hparams.get("norm_topk_prob", False) | ||||||||||||||||||||||||||||||||||||||||||||||||
| scoring_func = hparams.get("scoring_func", "softmax") | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Already handled. |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_leading_dense_block_count(hparams["first_k_dense_replace"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_vocab_size(hparams["vocab_size"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| if "q_lora_rank" in hparams and hparams["q_lora_rank"] is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_q_lora_rank(hparams["q_lora_rank"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_kv_lora_rank(hparams["kv_lora_rank"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| if "kv_lora_rank" in hparams and hparams["kv_lora_rank"] is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_kv_lora_rank(kv_lora_rank) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| # note: deepseek2 using MLA converts into MQA with larger heads, then decompresses to MHA | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_key_length(hparams["kv_lora_rank"] + hparams["qk_rope_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_value_length(hparams["kv_lora_rank"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_key_length_mla(hparams["qk_nope_head_dim"] + hparams["qk_rope_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_value_length_mla(hparams["v_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| if not is_ocr: | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_key_length(kv_lora_rank + hparams["qk_rope_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_value_length(kv_lora_rank) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_key_length_mla(hparams["qk_nope_head_dim"] + hparams["qk_rope_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_value_length_mla(hparams["v_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_rope_dimension_count(hparams["qk_rope_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_feed_forward_length(hparams["moe_intermediate_size"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_count(hparams["n_routed_experts"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_shared_count(hparams["n_shared_experts"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_weights_scale(hparams["routed_scaling_factor"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_weights_norm(hparams["norm_topk_prob"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_weights_scale(routed_scaling_factor) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_weights_norm(norm_topk_prob) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if scoring_func == "sigmoid": | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_gating_func(gguf.ExpertGatingFuncType.SIGMOID) | ||||||||||||||||||||||||||||||||||||||||||||||||
| elif scoring_func == "softmax": | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_expert_gating_func(gguf.ExpertGatingFuncType.SOFTMAX) | ||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||
| raise ValueError(f"Unsupported scoring_func value: {scoring_func}") | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+7364
to
+7369
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Already handled. |
||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_rope_dimension_count(hparams["qk_rope_head_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| rope_scaling = self.hparams.get("rope_scaling") or {} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -7252,12 +7375,14 @@ def set_gguf_parameters(self): | |||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_rope_scaling_factor(rope_scaling["factor"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_rope_scaling_orig_ctx_len(rope_scaling["original_max_position_embeddings"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_rope_scaling_yarn_log_mul(0.1 * rope_scaling["mscale_all_dim"]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.gguf_writer.add_layer_norm_rms_eps(self.hparams.get("rms_norm_eps", 1e-6)) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| _experts: list[dict[str, Tensor]] | None = None | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # skip vision tensors and remove "language_model." for Kimi-VL | ||||||||||||||||||||||||||||||||||||||||||||||||
| if "vision_tower" in name or "multi_modal_projector" in name: | ||||||||||||||||||||||||||||||||||||||||||||||||
| if "vision_" in name or "multi_modal_projector" in name \ | ||||||||||||||||||||||||||||||||||||||||||||||||
| or "image_newline" in name or "model.projector" in name or "sam_model" in name or "view_seperator" in name: | ||||||||||||||||||||||||||||||||||||||||||||||||
| return [] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if name.startswith("language_model."): | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revert changes. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -302,6 +302,10 @@ class Attention: | |
| class Projector: | ||
| SCALE_FACTOR = "clip.vision.projector.scale_factor" | ||
|
|
||
| class SAM: | ||
| BLOCK_COUNT = "clip.vision.sam.block_count" | ||
| EMBEDDING_LENGTH = "clip.vision.sam.embedding_length" | ||
|
|
||
| class ClipAudio: | ||
| NUM_MEL_BINS = "clip.audio.num_mel_bins" | ||
| EMBEDDING_LENGTH = "clip.audio.embedding_length" | ||
|
|
@@ -685,6 +689,22 @@ class MODEL_TENSOR(IntEnum): | |
| V_MM_GATE = auto() # cogvlm | ||
| V_TOK_BOI = auto() # cogvlm | ||
| V_TOK_EOI = auto() # cogvlm | ||
| V_SAM_POS_EMBD = auto() # Deepseek-OCR | ||
| V_SAM_PATCH_EMBD = auto() # Deepseek-OCR | ||
| V_SAM_PRE_NORM = auto() # Deepseek-OCR | ||
| V_SAM_POST_NORM = auto() # Deepseek-OCR | ||
| V_SAM_ATTN_POS_H = auto() # Deepseek-OCR | ||
| V_SAM_ATTN_POS_W = auto() # Deepseek-OCR | ||
| V_SAM_ATTN_QKV = auto() # Deepseek-OCR | ||
| V_SAM_ATTN_OUT = auto() # Deepseek-OCR | ||
| V_SAM_MLP_LIN_1 = auto() # Deepseek-OCR | ||
| V_SAM_MLP_LIN_2 = auto() # Deepseek-OCR | ||
| V_SAM_NECK = auto() # Deepseek-OCR | ||
| V_SAM_NET_2 = auto() # Deepseek-OCR | ||
| V_SAM_NET_3 = auto() # Deepseek-OCR | ||
| V_ENC_EMBD_IMGNL = auto() # Deepseek-OCR | ||
| V_ENC_EMBD_VSEP = auto() # Deepseek-OCR | ||
|
|
||
| # audio (mtmd) | ||
| A_ENC_EMBD_POS = auto() | ||
| A_ENC_CONV1D = auto() | ||
|
|
@@ -1057,6 +1077,22 @@ class MODEL_TENSOR(IntEnum): | |
| MODEL_TENSOR.V_MM_GATE: "mm.gate", | ||
| MODEL_TENSOR.V_TOK_BOI: "v.boi", | ||
| MODEL_TENSOR.V_TOK_EOI: "v.eoi", | ||
| # DeepSeek-OCR sam_model | ||
| MODEL_TENSOR.V_SAM_POS_EMBD: "v.sam.pos_embd", | ||
| MODEL_TENSOR.V_SAM_PATCH_EMBD: "v.sam.patch_embd", | ||
| MODEL_TENSOR.V_SAM_PRE_NORM: "v.sam.blk.{bid}.pre_ln", | ||
| MODEL_TENSOR.V_SAM_POST_NORM: "v.sam.blk.{bid}.post_ln", | ||
| MODEL_TENSOR.V_SAM_ATTN_POS_H: "v.sam.blk.{bid}.attn.pos_h", | ||
| MODEL_TENSOR.V_SAM_ATTN_POS_W: "v.sam.blk.{bid}.attn.pos_w", | ||
| MODEL_TENSOR.V_SAM_ATTN_QKV: "v.sam.blk.{bid}.attn.qkv", | ||
| MODEL_TENSOR.V_SAM_ATTN_OUT: "v.sam.blk.{bid}.attn.out", | ||
| MODEL_TENSOR.V_SAM_MLP_LIN_1: "v.sam.blk.{bid}.mlp.lin1", | ||
| MODEL_TENSOR.V_SAM_MLP_LIN_2: "v.sam.blk.{bid}.mlp.lin2", | ||
| MODEL_TENSOR.V_SAM_NECK: "v.sam.neck.{bid}", | ||
| MODEL_TENSOR.V_SAM_NET_2: "v.sam.net_2", | ||
| MODEL_TENSOR.V_SAM_NET_3: "v.sam.net_3", | ||
| MODEL_TENSOR.V_ENC_EMBD_IMGNL: "model.image_newline", # Deepseek-OCR | ||
| MODEL_TENSOR.V_ENC_EMBD_VSEP: "model.view_seperator", # Deepseek-OCR | ||
|
Comment on lines
+1094
to
+1095
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please prefix any vision-related tensor with |
||
| # audio (mtmd) | ||
| MODEL_TENSOR.A_ENC_EMBD_POS: "a.position_embd", | ||
| MODEL_TENSOR.A_ENC_CONV1D: "a.conv1d.{bid}", | ||
|
|
@@ -1093,6 +1129,8 @@ class MODEL_TENSOR(IntEnum): | |
| MODEL_TENSOR.V_ENC_EMBD_CLS, | ||
| MODEL_TENSOR.V_ENC_EMBD_PATCH, | ||
| MODEL_TENSOR.V_ENC_EMBD_POS, | ||
| MODEL_TENSOR.V_ENC_EMBD_IMGNL, | ||
| MODEL_TENSOR.V_ENC_EMBD_VSEP, | ||
| MODEL_TENSOR.V_ENC_INPUT_NORM, | ||
| MODEL_TENSOR.V_ENC_ATTN_QKV, | ||
| MODEL_TENSOR.V_ENC_ATTN_Q, | ||
|
|
@@ -1135,6 +1173,19 @@ class MODEL_TENSOR(IntEnum): | |
| MODEL_TENSOR.V_MM_GATE, | ||
| MODEL_TENSOR.V_TOK_BOI, | ||
| MODEL_TENSOR.V_TOK_EOI, | ||
| MODEL_TENSOR.V_SAM_POS_EMBD, | ||
| MODEL_TENSOR.V_SAM_PATCH_EMBD, | ||
| MODEL_TENSOR.V_SAM_PRE_NORM, | ||
| MODEL_TENSOR.V_SAM_POST_NORM, | ||
| MODEL_TENSOR.V_SAM_ATTN_POS_H, | ||
| MODEL_TENSOR.V_SAM_ATTN_POS_W, | ||
| MODEL_TENSOR.V_SAM_ATTN_QKV, | ||
| MODEL_TENSOR.V_SAM_ATTN_OUT, | ||
| MODEL_TENSOR.V_SAM_MLP_LIN_1, | ||
| MODEL_TENSOR.V_SAM_MLP_LIN_2, | ||
| MODEL_TENSOR.V_SAM_NECK, | ||
| MODEL_TENSOR.V_SAM_NET_2, | ||
| MODEL_TENSOR.V_SAM_NET_3, | ||
| # audio | ||
| MODEL_TENSOR.A_ENC_EMBD_POS, | ||
| MODEL_TENSOR.A_ENC_CONV1D, | ||
|
|
@@ -2303,7 +2354,9 @@ class MODEL_TENSOR(IntEnum): | |
| MODEL_TENSOR.ATTN_Q_B, | ||
| MODEL_TENSOR.ATTN_KV_A_MQA, | ||
| MODEL_TENSOR.ATTN_KV_B, | ||
| MODEL_TENSOR.ATTN_K, | ||
| MODEL_TENSOR.ATTN_K_B, | ||
| MODEL_TENSOR.ATTN_V, | ||
| MODEL_TENSOR.ATTN_V_B, | ||
| MODEL_TENSOR.ATTN_Q_A_NORM, | ||
| MODEL_TENSOR.ATTN_KV_A_NORM, | ||
|
|
@@ -3327,6 +3380,7 @@ class VisionProjectorType: | |
| LIGHTONOCR = "lightonocr" | ||
| COGVLM = "cogvlm" | ||
| JANUS_PRO = "janus_pro" | ||
| DEEPSEEKOCR = "deepseekocr" | ||
|
|
||
|
|
||
| # Items here are (block size, type size) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1127,6 +1127,12 @@ def add_vision_n_wa_pattern(self, value: int) -> None: | |||||||||||
| def add_vision_is_deepstack_layers(self, layers: Sequence[bool]) -> None: | ||||||||||||
| self.add_array(Keys.ClipVision.IS_DEEPSTACK_LAYERS, layers) | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| def add_vision_sam_layers_count(self, value: int) -> None: | ||||||||||||
|
Comment on lines
+1130
to
+1131
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| self.add_uint32(Keys.ClipVision.SAM.BLOCK_COUNT, value) | ||||||||||||
|
|
||||||||||||
| def add_vision_sam_embedding_length(self, value: int) -> None: | ||||||||||||
| self.add_uint32(Keys.ClipVision.SAM.EMBEDDING_LENGTH, value) | ||||||||||||
| # audio models | ||||||||||||
|
Comment on lines
+1135
to
1136
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
|
||||||||||||
| def add_audio_projection_dim(self, value: int) -> None: | ||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since
layerswas added ton_block_keysand those are now required (not sure why they were optional before, makes no sense), this is no-op.