mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-07 16:37:57 +02:00
* Add Spark3 Model * rename spark3 -> spark2_5 Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co> Co-authored-by: dongjiang <dongjiang2010@gmail.com>
66 lines
2.8 KiB
Python
66 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
from collections.abc import Iterable
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from torch import Tensor
|
|
|
|
from .base import ModelBase, TextModel, gguf
|
|
|
|
|
|
@ModelBase.register("Spark2_5ForCausalLM")
|
|
@ModelBase.example("XHToken/Spark-X2.5-1.7B")
|
|
class Spark2_5Model(TextModel):
|
|
model_arch = gguf.MODEL_ARCH.SPARK2_5
|
|
|
|
def set_gguf_parameters(self) -> None:
|
|
super().set_gguf_parameters()
|
|
|
|
hparams = self.hparams
|
|
layer_types = hparams["layer_types"]
|
|
if len(layer_types) != self.block_count:
|
|
raise ValueError(
|
|
f"Spark2_5 layer_types length {len(layer_types)} != num_hidden_layers {self.block_count}"
|
|
)
|
|
if any(layer_type not in ("sliding_attention", "full_attention") for layer_type in layer_types):
|
|
raise ValueError(f"Spark2_5 has unsupported layer_types: {layer_types}")
|
|
if hparams.get("gate_attn_act_mode") != "sigmoid" or hparams.get("headwise_attn_output_gate") is not True:
|
|
raise ValueError("Spark2_5 conversion requires head-wise sigmoid attention gates")
|
|
if hparams.get("hidden_act") != "gelu":
|
|
raise ValueError(f"Spark2_5 conversion requires GELU, got {hparams.get('hidden_act')!r}")
|
|
|
|
self.gguf_writer.add_vocab_size(hparams["vocab_size"])
|
|
self.gguf_writer.add_sliding_window(hparams["sliding_window"])
|
|
self.gguf_writer.add_sliding_window_pattern(
|
|
[layer_type == "sliding_attention" for layer_type in layer_types]
|
|
)
|
|
|
|
head_dim = hparams["head_dim"]
|
|
full_rope = self.rope_parameters["full_attention"]
|
|
swa_rope = self.rope_parameters["sliding_attention"]
|
|
self.gguf_writer.add_rope_dimension_count(
|
|
int(head_dim * float(full_rope["partial_rotary_factor"]))
|
|
)
|
|
self.gguf_writer.add_rope_dimension_count_swa(
|
|
int(head_dim * float(swa_rope["partial_rotary_factor"]))
|
|
)
|
|
|
|
def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]:
|
|
if name.endswith(".self_attn.q_k_v_proj.weight"):
|
|
if bid is None:
|
|
raise ValueError(f"Spark2_5 fused QKV tensor has no block id: {name}")
|
|
yield self.format_tensor_name(gguf.MODEL_TENSOR.ATTN_QKV, bid), data_torch
|
|
return
|
|
|
|
if name.endswith(".self_attn.g_proj.weight"):
|
|
if bid is None:
|
|
raise ValueError(f"Spark2_5 attention gate tensor has no block id: {name}")
|
|
expected = self.hparams["num_attention_heads"]
|
|
if data_torch.shape[0] != expected:
|
|
raise ValueError(
|
|
f"Spark2_5 layer {bid} attention gate width {data_torch.shape[0]} != head count {expected}"
|
|
)
|
|
|
|
yield from super().modify_tensors(data_torch, name, bid)
|