Skip to content

Commit 7bfe60f

Browse files
ManaEstraswendadawen
andauthored
mtmd, llama : Update HunyuanVL vision-language model support (ggml-org#22037)
* mtmd, llama : add HunyuanVL vision-language model support - add LLM_ARCH_HUNYUAN_VL with M-RoPE (XD-RoPE) support - add PROJECTOR_TYPE_HUNYUANVL with PatchMerger vision encoder - add HunyuanVL-specific M-RoPE position encoding for image tokens - add GGUF conversion for HunyuanVL vision and text models - add smoke test in tools/mtmd/tests.sh * fix: fix HunyuanVL XD-RoPE h/w section order * fix: Remove redundant code * convert : fix HunyuanOCR / HunyuanVL conversion - Tested locally: both HunyuanOCR and HunyuanVL-4B convert to GGUF - successfully and produce correct inference output on Metal (F16 / Q8_0). * clip : fix -Werror=misleading-indentation in bilinear resize * fix CI: convert_hf_to_gguf type check error - convert_hf_to_gguf.py: give HunyuanVLTextModel.__init__ an explicit `dir_model: Path` parameter so ty can infer the type for load_hparams instead of reporting `Unknown | None`. --------- Co-authored-by: wendadawen <wendadawen@tencent.com>
1 parent 750579f commit 7bfe60f

13 files changed

Lines changed: 336 additions & 27 deletions

File tree

convert_hf_to_gguf.py

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11855,7 +11855,7 @@ def prepare_tensors(self):
1185511855
raise ValueError(f"Unprocessed experts: {experts}")
1185611856

1185711857

11858-
@ModelBase.register("HunYuanDenseV1ForCausalLM", "HunYuanVLForConditionalGeneration")
11858+
@ModelBase.register("HunYuanDenseV1ForCausalLM")
1185911859
class HunYuanModel(TextModel):
1186011860
model_arch = gguf.MODEL_ARCH.HUNYUAN_DENSE
1186111861

@@ -11994,40 +11994,125 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter
1199411994

1199511995

1199611996
@ModelBase.register("HunYuanVLForConditionalGeneration")
11997-
class HunyuanOCRVisionModel(MmprojModel):
11997+
class HunyuanVLVisionModel(MmprojModel):
11998+
# Handles both HunyuanOCR and HunyuanVL, which share the HF architecture name
11999+
# "HunYuanVLForConditionalGeneration" and the `vit.perceive.*` vision layout.
12000+
# Each variant maps to a different projector type in clip.cpp so image
12001+
# preprocessing follows the correct code path.
12002+
1199812003
def __init__(self, *args, **kwargs):
1199912004
super().__init__(*args, **kwargs)
1200012005
assert self.hparams_vision is not None
12001-
# HunyuanOCR uses max_image_size instead of image_size
12006+
# HunyuanOCR / HunyuanVL uses max_image_size instead of image_size
1200212007
if "image_size" not in self.hparams_vision:
1200312008
self.hparams_vision["image_size"] = self.hparams_vision.get("max_image_size", 2048)
1200412009

12010+
@staticmethod
12011+
def is_ocr_variant(hparams: dict) -> bool:
12012+
"""Return True for HunyuanOCR, False for HunyuanVL.
12013+
12014+
The projector's output dim must equal the text model's hidden_size by
12015+
construction (that's what "projector" means). HunyuanOCR pairs a 1B text
12016+
backbone (hidden=1024); HunyuanVL pairs a 4B one (hidden=3072). So the
12017+
ViT -> LLM projection dim is a hard architectural signature, not a
12018+
magic number.
12019+
"""
12020+
vision_out = int((hparams.get("vision_config") or {}).get("out_hidden_size", 0))
12021+
return vision_out == 1024
12022+
1200512023
def set_gguf_parameters(self):
1200612024
super().set_gguf_parameters()
1200712025
assert self.hparams_vision is not None
12008-
hparams = self.hparams_vision
12009-
self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.HUNYUANOCR)
12010-
self.gguf_writer.add_vision_use_gelu(True)
12011-
self.gguf_writer.add_vision_attention_layernorm_eps(hparams.get("rms_norm_eps", 1e-5))
12012-
self.gguf_writer.add_vision_spatial_merge_size(hparams.get("spatial_merge_size", 2))
12013-
self.gguf_writer.add_vision_min_pixels(self.preprocessor_config["min_pixels"])
12014-
self.gguf_writer.add_vision_max_pixels(self.preprocessor_config["max_pixels"])
12026+
vcfg = self.hparams_vision
12027+
12028+
if self.is_ocr_variant(self.global_config):
12029+
# --- HunyuanOCR ---
12030+
self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.HUNYUANOCR)
12031+
self.gguf_writer.add_vision_use_gelu(True)
12032+
self.gguf_writer.add_vision_attention_layernorm_eps(vcfg.get("rms_norm_eps", 1e-5))
12033+
self.gguf_writer.add_vision_spatial_merge_size(vcfg.get("spatial_merge_size", 2))
12034+
self.gguf_writer.add_vision_min_pixels(self.preprocessor_config["min_pixels"])
12035+
self.gguf_writer.add_vision_max_pixels(self.preprocessor_config["max_pixels"])
12036+
return
12037+
12038+
# --- HunyuanVL ---
12039+
self.gguf_writer.add_clip_projector_type(gguf.VisionProjectorType.HUNYUANVL)
12040+
self.gguf_writer.add_vision_use_gelu(str(vcfg["hidden_act"]).lower() == "gelu")
12041+
self.gguf_writer.add_vision_attention_layernorm_eps(float(vcfg["rms_norm_eps"]))
12042+
self.gguf_writer.add_vision_spatial_merge_size(int(vcfg["spatial_merge_size"]))
12043+
self.gguf_writer.add_vision_min_pixels(int(self.preprocessor_config["min_pixels"]))
12044+
self.gguf_writer.add_vision_max_pixels(int(self.preprocessor_config["max_pixels"]))
1201512045

1201612046
def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]:
1201712047
if not name.startswith("vit."):
12018-
return # skip text tensors
12048+
return
1201912049
# strip CLS token (row 0) from position embeddings so resize_position_embeddings works
1202012050
if "position_embedding" in name:
1202112051
data_torch = data_torch[1:] # [n_patches+1, n_embd] -> [n_patches, n_embd]
1202212052
yield from super().modify_tensors(data_torch, name, bid)
1202312053

1202412054
def tensor_force_quant(self, name, new_name, bid, n_dims):
1202512055
# force conv weights to F32 or F16 to avoid BF16 IM2COL issues on Metal
12056+
# Both HunyuanOCR and HunyuanVL emit the ViT -> LLM projection as mm.0/mm.2.
1202612057
if ("mm.0." in new_name or "mm.2." in new_name) and new_name.endswith(".weight"):
1202712058
return gguf.GGMLQuantizationType.F16 if self.ftype == gguf.LlamaFileType.MOSTLY_F16 else gguf.GGMLQuantizationType.F32
1202812059
return super().tensor_force_quant(name, new_name, bid, n_dims)
1202912060

1203012061

12062+
@ModelBase.register("HunYuanVLForConditionalGeneration")
12063+
class HunyuanVLTextModel(HunYuanModel):
12064+
# The "HunYuanVLForConditionalGeneration" HF architecture covers both HunyuanOCR
12065+
# and HunyuanVL. HunyuanOCR reuses the HunYuan-Dense text backbone (standard RoPE),
12066+
# while HunyuanVL introduces a new LLM arch with XD-RoPE. Detect the variant from
12067+
# the config and pick the matching GGUF architecture.
12068+
model_arch = gguf.MODEL_ARCH.HUNYUAN_VL
12069+
12070+
@staticmethod
12071+
def _is_ocr_config(hparams: dict) -> bool:
12072+
# OCR pairs a 1B text backbone (hidden=1024) with a ViT projector that
12073+
# outputs 1024-d; HunyuanVL uses 3072-d. Keep in sync with
12074+
# HunyuanVLVisionModel.is_ocr_variant.
12075+
return int((hparams.get("vision_config") or {}).get("out_hidden_size", 0)) == 1024
12076+
12077+
def __init__(self, dir_model: Path, *args, **kwargs):
12078+
raw_hparams = kwargs.get("hparams") or ModelBase.load_hparams(dir_model, is_mistral_format=False)
12079+
if self._is_ocr_config(raw_hparams):
12080+
self.model_arch = gguf.MODEL_ARCH.HUNYUAN_DENSE
12081+
else:
12082+
self.model_arch = gguf.MODEL_ARCH.HUNYUAN_VL
12083+
super().__init__(dir_model, *args, **kwargs)
12084+
12085+
def set_gguf_parameters(self):
12086+
super().set_gguf_parameters()
12087+
12088+
# Only emit XD-RoPE metadata for the HunyuanVL backbone; HunyuanOCR uses
12089+
# the HunYuan-Dense arch which already handles standard rope in super().
12090+
if self.model_arch != gguf.MODEL_ARCH.HUNYUAN_VL:
12091+
return
12092+
12093+
if self.rope_parameters.get("rope_type") != "xdrope":
12094+
return
12095+
12096+
# defaults for HunyuanVL. The C++ side later computes:
12097+
# freq_base = rope_theta * alpha ** (head_dim / (head_dim - 2))
12098+
self.gguf_writer.add_rope_freq_base(float(self.rope_parameters["rope_theta"]))
12099+
self.gguf_writer.add_rope_scaling_alpha(float(self.rope_parameters["alpha"]))
12100+
self.gguf_writer.add_rope_scaling_type(gguf.RopeScalingType.NONE)
12101+
self.gguf_writer.add_rope_scaling_factor(float(self.rope_parameters.get("factor", 1)))
12102+
12103+
ctx_len = int(self.hparams["max_position_embeddings"])
12104+
self.gguf_writer.add_rope_scaling_orig_ctx_len(ctx_len)
12105+
self.gguf_writer.add_context_length(ctx_len)
12106+
12107+
self.gguf_writer.add_rope_dimension_sections(list(self.rope_parameters["xdrope_section"]))
12108+
12109+
def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]:
12110+
# Skip vision tensors — they are written by HunyuanVLVisionModel
12111+
if name.startswith("vit."):
12112+
return
12113+
yield from super().modify_tensors(data_torch, name, bid)
12114+
12115+
1203112116
@ModelBase.register("SmolLM3ForCausalLM")
1203212117
class SmolLM3Model(LlamaModel):
1203312118
model_arch = gguf.MODEL_ARCH.SMOLLM3

gguf-py/gguf/constants.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ class Rope:
197197
FREQ_BASE_SWA = "{arch}.rope.freq_base_swa"
198198
SCALING_TYPE = "{arch}.rope.scaling.type"
199199
SCALING_FACTOR = "{arch}.rope.scaling.factor"
200+
SCALING_ALPHA = "{arch}.rope.scaling.alpha"
200201
SCALING_ATTN_FACTOR = "{arch}.rope.scaling.attn_factor"
201202
SCALING_ORIG_CTX_LEN = "{arch}.rope.scaling.original_context_length"
202203
SCALING_FINETUNED = "{arch}.rope.scaling.finetuned"
@@ -471,6 +472,7 @@ class MODEL_ARCH(IntEnum):
471472
ERNIE4_5_MOE = auto()
472473
HUNYUAN_MOE = auto()
473474
HUNYUAN_DENSE = auto()
475+
HUNYUAN_VL = auto()
474476
SMOLLM3 = auto()
475477
GPT_OSS = auto()
476478
LFM2 = auto()
@@ -957,6 +959,7 @@ class MODEL_TENSOR(IntEnum):
957959
MODEL_ARCH.FALCON_H1: "falcon-h1",
958960
MODEL_ARCH.HUNYUAN_MOE: "hunyuan-moe",
959961
MODEL_ARCH.HUNYUAN_DENSE: "hunyuan-dense",
962+
MODEL_ARCH.HUNYUAN_VL: "hunyuan_vl",
960963
MODEL_ARCH.SMOLLM3: "smollm3",
961964
MODEL_ARCH.GPT_OSS: "gpt-oss",
962965
MODEL_ARCH.LFM2: "lfm2",
@@ -3489,6 +3492,22 @@ class MODEL_TENSOR(IntEnum):
34893492
MODEL_TENSOR.FFN_DOWN,
34903493
MODEL_TENSOR.FFN_UP,
34913494
],
3495+
MODEL_ARCH.HUNYUAN_VL: [
3496+
MODEL_TENSOR.TOKEN_EMBD,
3497+
MODEL_TENSOR.OUTPUT_NORM,
3498+
MODEL_TENSOR.OUTPUT,
3499+
MODEL_TENSOR.ATTN_NORM,
3500+
MODEL_TENSOR.ATTN_Q,
3501+
MODEL_TENSOR.ATTN_Q_NORM,
3502+
MODEL_TENSOR.ATTN_K,
3503+
MODEL_TENSOR.ATTN_K_NORM,
3504+
MODEL_TENSOR.ATTN_V,
3505+
MODEL_TENSOR.ATTN_OUT,
3506+
MODEL_TENSOR.FFN_NORM,
3507+
MODEL_TENSOR.FFN_GATE,
3508+
MODEL_TENSOR.FFN_DOWN,
3509+
MODEL_TENSOR.FFN_UP,
3510+
],
34923511
MODEL_ARCH.SMOLLM3: [
34933512
MODEL_TENSOR.TOKEN_EMBD,
34943513
MODEL_TENSOR.OUTPUT_NORM,
@@ -4138,6 +4157,7 @@ class VisionProjectorType:
41384157
YOUTUVL = "youtuvl"
41394158
NEMOTRON_V2_VL = "nemotron_v2_vl"
41404159
HUNYUANOCR = "hunyuanocr"
4160+
HUNYUANVL = "hunyuanvl"
41414161

41424162

41434163
# Items here are (block size, type size)

gguf-py/gguf/gguf_writer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,9 @@ def add_rope_scaling_type(self, value: RopeScalingType) -> None:
973973
def add_rope_scaling_factor(self, value: float) -> None:
974974
self.add_float32(Keys.Rope.SCALING_FACTOR.format(arch=self.arch), value)
975975

976+
def add_rope_scaling_alpha(self, value: float) -> None:
977+
self.add_float32(Keys.Rope.SCALING_ALPHA.format(arch=self.arch), value)
978+
976979
def add_rope_scaling_attn_factors(self, value: float) -> None:
977980
self.add_float32(Keys.Rope.SCALING_ATTN_FACTOR.format(arch=self.arch), value)
978981

src/llama-arch.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static const std::map<llm_arch, const char *> LLM_ARCH_NAMES = {
109109
{ LLM_ARCH_ERNIE4_5_MOE, "ernie4_5-moe" },
110110
{ LLM_ARCH_HUNYUAN_MOE, "hunyuan-moe" },
111111
{ LLM_ARCH_HUNYUAN_DENSE, "hunyuan-dense" },
112+
{ LLM_ARCH_HUNYUAN_VL, "hunyuan_vl" },
112113
{ LLM_ARCH_SMOLLM3, "smollm3" },
113114
{ LLM_ARCH_OPENAI_MOE, "gpt-oss" },
114115
{ LLM_ARCH_LFM2, "lfm2" },
@@ -250,6 +251,7 @@ static const std::map<llm_kv, const char *> LLM_KV_NAMES = {
250251
{ LLM_KV_ROPE_SCALE_LINEAR, "%s.rope.scale_linear" },
251252
{ LLM_KV_ROPE_SCALING_TYPE, "%s.rope.scaling.type" },
252253
{ LLM_KV_ROPE_SCALING_FACTOR, "%s.rope.scaling.factor" },
254+
{ LLM_KV_ROPE_SCALING_ALPHA, "%s.rope.scaling.alpha" },
253255
{ LLM_KV_ROPE_SCALING_ATTN_FACTOR, "%s.rope.scaling.attn_factor" },
254256
{ LLM_KV_ROPE_SCALING_ORIG_CTX_LEN, "%s.rope.scaling.original_context_length" },
255257
{ LLM_KV_ROPE_SCALING_FINETUNED, "%s.rope.scaling.finetuned" },

src/llama-arch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ enum llm_arch {
113113
LLM_ARCH_ERNIE4_5_MOE,
114114
LLM_ARCH_HUNYUAN_MOE,
115115
LLM_ARCH_HUNYUAN_DENSE,
116+
LLM_ARCH_HUNYUAN_VL,
116117
LLM_ARCH_SMOLLM3,
117118
LLM_ARCH_OPENAI_MOE,
118119
LLM_ARCH_LFM2,
@@ -254,6 +255,7 @@ enum llm_kv {
254255
LLM_KV_ROPE_SCALE_LINEAR,
255256
LLM_KV_ROPE_SCALING_TYPE,
256257
LLM_KV_ROPE_SCALING_FACTOR,
258+
LLM_KV_ROPE_SCALING_ALPHA,
257259
LLM_KV_ROPE_SCALING_ATTN_FACTOR,
258260
LLM_KV_ROPE_SCALING_ORIG_CTX_LEN,
259261
LLM_KV_ROPE_SCALING_FINETUNED,

src/llama-hparams.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct llama_hparams {
116116
float rope_freq_base_train_swa = 10000.0f;
117117
float rope_freq_scale_train;
118118
float rope_freq_scale_train_swa = 1.0f;
119+
float rope_scaling_alpha = 0.0f; // NTK-aware alpha for XDRoPE
119120

120121
uint32_t n_ctx_orig_yarn;
121122
float rope_yarn_log_mul = 0.0f;

src/llama-model.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,13 @@ void llama_model::load_hparams(llama_model_loader & ml) {
737737
ml.get_key(LLM_KV_EXPERT_GROUP_COUNT, hparams.n_expert_groups, false);
738738
ml.get_key(LLM_KV_EXPERT_GROUP_USED_COUNT, hparams.n_group_used, false);
739739

740+
if (arch == LLM_ARCH_HUNYUAN_VL || arch == LLM_ARCH_HUNYUAN_DENSE) {
741+
if (hparams.n_expert <= 1) {
742+
hparams.n_expert = 0;
743+
hparams.n_expert_used = 0;
744+
}
745+
}
746+
740747
if (arch == LLM_ARCH_WAVTOKENIZER_DEC) {
741748
ml.get_key(LLM_KV_FEATURES_LENGTH, hparams.n_embd);
742749
ml.get_key(LLM_KV_EMBEDDING_LENGTH, hparams.n_embd_out_impl);
@@ -815,6 +822,7 @@ void llama_model::load_hparams(llama_model_loader & ml) {
815822
hparams.rope_freq_scale_train = ropescale == 0.0f ? 1.0f : 1.0f/ropescale;
816823

817824
ml.get_key(LLM_KV_ROPE_SCALING_ATTN_FACTOR, hparams.rope_attn_factor, false);
825+
ml.get_key(LLM_KV_ROPE_SCALING_ALPHA, hparams.rope_scaling_alpha, false);
818826

819827
// non-transformer models do not have attention heads
820828
if (hparams.n_head() > 0) {
@@ -2592,9 +2600,18 @@ void llama_model::load_hparams(llama_model_loader & ml) {
25922600
default: type = LLM_TYPE_UNKNOWN;
25932601
}
25942602
} break;
2603+
case LLM_ARCH_HUNYUAN_VL:
25952604
case LLM_ARCH_HUNYUAN_DENSE:
25962605
{
25972606
ml.get_key(LLM_KV_ATTENTION_LAYERNORM_RMS_EPS, hparams.f_norm_rms_eps);
2607+
ml.get_key_or_arr(LLM_KV_ROPE_DIMENSION_SECTIONS, hparams.rope_sections, 4, false);
2608+
2609+
// XDRoPE / NTK-aware scaling: base = rope_theta * alpha^(dim / (dim - 2))
2610+
if (hparams.rope_scaling_alpha > 0.0f) {
2611+
const int dim = hparams.n_embd_head_k();
2612+
hparams.rope_freq_base_train = hparams.rope_freq_base_train
2613+
* powf(hparams.rope_scaling_alpha, (float)dim / (float)(dim - 2));
2614+
}
25982615

25992616
switch (hparams.n_embd) {
26002617
case 1024: type = LLM_TYPE_0_5B; break;
@@ -6947,6 +6964,7 @@ bool llama_model::load_tensors(llama_model_loader & ml) {
69476964
layer.ffn_down_shexp = create_tensor(tn(LLM_TENSOR_FFN_DOWN_SHEXP, "weight", i), {n_ff_shexp, n_embd}, 0);
69486965
}
69496966
} break;
6967+
case LLM_ARCH_HUNYUAN_VL:
69506968
case LLM_ARCH_HUNYUAN_DENSE:
69516969
{
69526970
tok_embd = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), {n_embd, n_vocab}, 0);
@@ -8967,6 +8985,7 @@ ggml_cgraph * llama_model::build_graph(const llm_graph_params & params) const {
89678985
{
89688986
llm = std::make_unique<llm_build_hunyuan_moe>(*this, params);
89698987
} break;
8988+
case LLM_ARCH_HUNYUAN_VL:
89708989
case LLM_ARCH_HUNYUAN_DENSE:
89718990
{
89728991
llm = std::make_unique<llm_build_hunyuan_dense>(*this, params);
@@ -9316,6 +9335,9 @@ llama_rope_type llama_model_rope_type(const llama_model * model) {
93169335
case LLM_ARCH_GLM4_MOE:
93179336
return model->hparams.use_mrope() ? LLAMA_ROPE_TYPE_MROPE : LLAMA_ROPE_TYPE_NEOX;
93189337

9338+
case LLM_ARCH_HUNYUAN_VL:
9339+
return model->hparams.use_mrope() ? LLAMA_ROPE_TYPE_MROPE : LLAMA_ROPE_TYPE_NEOX;
9340+
93199341
// all model arches should be listed explicitly here
93209342
case LLM_ARCH_UNKNOWN:
93219343
GGML_ABORT("unknown architecture");

src/models/hunyuan-dense.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ llm_build_hunyuan_dense::llm_build_hunyuan_dense(const llama_model & model, cons
66
GGML_ASSERT(n_embd_head == hparams.n_embd_head_k());
77
GGML_ASSERT(n_embd_head == n_rot);
88

9+
const bool use_mrope = hparams.use_mrope();
10+
11+
int sections[4];
12+
std::copy(std::begin(hparams.rope_sections), std::begin(hparams.rope_sections) + 4, sections);
13+
914
ggml_tensor * cur;
1015
ggml_tensor * inpL;
1116

@@ -37,22 +42,36 @@ llm_build_hunyuan_dense::llm_build_hunyuan_dense(const llama_model & model, cons
3742
auto [Qcur, Kcur, Vcur] = build_qkv(model.layers[il], cur,
3843
n_embd_head, n_head, n_head_kv, il);
3944

40-
Qcur = ggml_rope_ext(
41-
ctx0, Qcur, inp_pos, rope_factors,
42-
n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
43-
ext_factor, attn_factor, beta_fast, beta_slow
44-
);
45+
if (use_mrope) {
46+
Qcur = ggml_rope_multi(
47+
ctx0, Qcur, inp_pos, rope_factors,
48+
n_rot, sections, rope_type, n_ctx_orig, freq_base, freq_scale,
49+
ext_factor, attn_factor, beta_fast, beta_slow
50+
);
51+
52+
Kcur = ggml_rope_multi(
53+
ctx0, Kcur, inp_pos, rope_factors,
54+
n_rot, sections, rope_type, n_ctx_orig, freq_base, freq_scale,
55+
ext_factor, attn_factor, beta_fast, beta_slow
56+
);
57+
} else {
58+
Qcur = ggml_rope_ext(
59+
ctx0, Qcur, inp_pos, rope_factors,
60+
n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
61+
ext_factor, attn_factor, beta_fast, beta_slow
62+
);
63+
64+
Kcur = ggml_rope_ext(
65+
ctx0, Kcur, inp_pos, rope_factors,
66+
n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
67+
ext_factor, attn_factor, beta_fast, beta_slow
68+
);
69+
}
4570

4671
cb(Qcur, "Qcur", il);
4772
cb(Kcur, "Kcur", il);
4873
cb(Vcur, "Vcur", il);
4974

50-
Kcur = ggml_rope_ext(
51-
ctx0, Kcur, inp_pos, rope_factors,
52-
n_rot, rope_type, n_ctx_orig, freq_base, freq_scale,
53-
ext_factor, attn_factor, beta_fast, beta_slow
54-
);
55-
5675
Kcur = build_norm(Kcur,
5776
model.layers[il].attn_k_norm, nullptr,
5877
LLM_NORM_RMS, il);

0 commit comments

Comments
 (0)