Merge branch 'ggml-org:master' into master

This commit is contained in:
Ilya Maslennikov authored and GitHub committed 2026-09-24 09:05:19 +03:00
commit 0831f472a9
12 files changed
+151 -32

No files matched your search

+1 -1
View File
@@ -45,7 +45,7 @@ concurrency:
jobs:
server:
runs-on: hf-jobs-cpu-upgrade
runs-on: hf-jobs-cpu-xl
strategy:
matrix:
+2 -2
View File
@@ -4,8 +4,8 @@ include(CheckIncludeFileCXX)
### llama.cpp version
set(LLAMA_VERSION_MAJOR 0)
set(LLAMA_VERSION_MINOR 4)
set(LLAMA_VERSION_PATCH 1)
set(LLAMA_VERSION_MINOR 5)
set(LLAMA_VERSION_PATCH 0)
set(LLAMA_VERSION_BASE "${LLAMA_VERSION_MAJOR}.${LLAMA_VERSION_MINOR}.${LLAMA_VERSION_PATCH}")
# whether this is a development/nightly build
+15 -6
View File
@@ -30,8 +30,8 @@ namespace hf_cache {
namespace fs = std::filesystem;
std::string get_cache_path() {
static const std::string cache = []() {
static fs::path get_cache_directory() {
static const fs::path cache = []() {
struct {
const char * var;
fs::path path;
@@ -46,14 +46,14 @@ std::string get_cache_path() {
for (const auto & entry : entries) {
if (auto * p = std::getenv(entry.var); p && *p) {
fs::path base(p);
return (entry.path.empty() ? base : base / entry.path).string();
return entry.path.empty() ? base : base / entry.path;
}
}
#ifndef _WIN32
const struct passwd * pw = getpwuid(getuid());
if (pw && pw->pw_dir && *pw->pw_dir) {
return (fs::path(pw->pw_dir) / ".cache" / "huggingface" / "hub").string();
return fs::path(pw->pw_dir) / ".cache" / "huggingface" / "hub";
}
#endif
throw std::runtime_error("Failed to determine HF cache directory");
@@ -62,6 +62,15 @@ std::string get_cache_path() {
return cache;
}
std::string get_cache_path() {
#if defined(__cpp_lib_char8_t)
const std::u8string u8str = get_cache_directory().u8string();
return std::string(reinterpret_cast<const char *>(u8str.data()), u8str.size());
#else
return get_cache_directory().u8string();
#endif
}
static std::string folder_name_to_repo(const std::string & folder) {
constexpr std::string_view prefix = "models--";
if (folder.rfind(prefix, 0)) {
@@ -80,7 +89,7 @@ static std::string repo_to_folder_name(const std::string & repo_id) {
}
static fs::path get_repo_path(const std::string & repo_id) {
return fs::path(get_cache_path()) / repo_to_folder_name(repo_id);
return get_cache_directory() / repo_to_folder_name(repo_id);
}
static bool is_hex_char(const char c) {
@@ -393,7 +402,7 @@ static std::string get_cached_ref(const fs::path & repo_path) {
}
hf_files get_cached_files(const std::string & repo_id) {
const fs::path cache_path = get_cache_path();
const fs::path cache_path = get_cache_directory();
if (!fs::exists(cache_path)) {
return {};
}
+2 -15
View File
@@ -10,7 +10,7 @@ import torch
if TYPE_CHECKING:
from torch import Tensor
from .base import LazyTorchTensor, ModelBase, TextModel, gguf, logger
from .base import LazyTorchTensor, ModelBase, ModelType, TextModel, get_model_architecture, gguf, logger
@ModelBase.register("QWenLMHeadModel")
@@ -666,7 +666,7 @@ class DFlashModel(Qwen3Model):
from . import get_model_class
with open(self.target_model_dir / "config.json", "r", encoding="utf-8") as f:
target_hparams = json.load(f)
target_arch = target_hparams["architectures"][0]
target_arch = get_model_architecture(target_hparams, ModelType.TEXT)
target_cls = get_model_class(target_arch)
if target_cls is not type(self):
@@ -841,13 +841,6 @@ class DSparkModel(DFlashModel):
return None
return super().filter_tensors(item)
_ROPE_PERMUTE_SUFFIXES = (
"self_attn.q_proj.weight",
"self_attn.k_proj.weight",
"self_attn.q_norm.weight",
"self_attn.k_norm.weight",
)
def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iterable[tuple[str, Tensor]]:
if name == "model.d2t":
self._d2t = data_torch
@@ -856,12 +849,6 @@ class DSparkModel(DFlashModel):
if self._n_vocab_draft == self.hparams["vocab_size"] and name.endswith("lm_head.weight"):
return
# interleaved-rope checkpoints (rope_is_neox_style = false) -> NeoX layout: per head, even dims first then odd
if not self.hparams.get("rope_is_neox_style", True) and name.endswith(self._ROPE_PERMUTE_SUFFIXES):
head_dim = self.hparams["head_dim"]
shape = data_torch.shape
data_torch = data_torch.reshape(-1, head_dim // 2, 2, *shape[1:]).transpose(1, 2).reshape(shape)
yield from super().modify_tensors(data_torch, name, bid)
def prepare_tensors(self):
+1 -1
View File
@@ -5,7 +5,7 @@ project("ggml" C CXX ASM)
### GGML Version
set(GGML_VERSION_MAJOR 0)
set(GGML_VERSION_MINOR 25)
set(GGML_VERSION_PATCH 0)
set(GGML_VERSION_PATCH 1)
set(GGML_VERSION_BASE "${GGML_VERSION_MAJOR}.${GGML_VERSION_MINOR}.${GGML_VERSION_PATCH}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
+2
View File
@@ -3573,6 +3573,7 @@ static int ggml_cuda_try_fuse(ggml_backend_cuda_context * cuda_ctx, ggml_cgraph
ggml_cuda_topk_moe_args args;
const bool can_fuse = ggml_cuda_topk_moe_fusion(cgraph, i, args);
std::vector<ggml_op> ops;
ops.reserve(13); // max ops; avoids gcc -Wstringop-overflow false positive
if (can_fuse) {
const ggml_tensor * logits = node->src[0];
@@ -4642,6 +4643,7 @@ static void ggml_backend_cuda_graph_optimize(ggml_backend_t backend, ggml_cgraph
ggml_cuda_topk_moe_args args;
const bool can_fuse = ggml_cuda_topk_moe_fusion(cgraph, i, args);
std::vector<ggml_op> ops;
ops.reserve(13); // max ops; avoids gcc -Wstringop-overflow false positive
const ggml_tensor * node = cgraph->nodes[i];
+4
View File
@@ -5476,6 +5476,10 @@ static bool ggml_hexagon_supported_mul_mat_id(const struct ggml_hexagon_session
return false;
}
if (ggml_get_op_params_i32(op, 3) == GGML_PREC_F32) {
return false;
}
switch (src0->type) {
case GGML_TYPE_Q4_0:
case GGML_TYPE_Q4_1:
+81
View File
@@ -1259,6 +1259,7 @@ struct ggml_backend_opencl_context {
cl_kernel kernel_gemm_noshuffle_q6_K_f32;
cl_kernel kernel_gemm_noshuffle_q6_K_f32_cok;
cl_kernel kernel_gemm_noshuffle_q6_k_f32_32b_trans_ila_a8_bin;
cl_kernel kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin;
cl_kernel kernel_gemv_noshuffle_q6_k_f32_32b_trans;
cl_kernel kernel_gemv_noshuffle_q5_k_f32;
cl_kernel kernel_gemv_noshuffle_q5_k_f32_mc3; // multi-column (N=3) verify GEMV (spec/MTP)
@@ -4407,6 +4408,7 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
backend_ctx->kernel_gemv_noshuffle_q6_k_f32_32b_trans = nullptr;
backend_ctx->kernel_gemm_noshuffle_q6_k_f32_32b_trans_ila_a8_bin = nullptr;
backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin = nullptr;
if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::X2E) {
{
std::string opts = std::string("-cl-std=") + opencl_c_std +
@@ -4439,6 +4441,17 @@ static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx) {
CL_CHECK(clReleaseProgram(bin_prog));
GGML_LOG_CONT(".");
}
kernel_bin = (const char *)backend_ctx->get_adreno_bin_kernel("gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8", &bin_size);
if (kernel_bin && bin_size > 0) {
cl_program bin_prog =
build_program_from_binary(backend_ctx->context, backend_ctx->device, kernel_bin, "", bin_size);
CL_CHECK((backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin =
clCreateKernel(bin_prog, "kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8", &err), err));
CL_CHECK(clReleaseProgram(bin_prog));
GGML_LOG_CONT(".");
}
}
}
@@ -21919,6 +21932,74 @@ static void ggml_cl_mul_mat_q6_K_f32_adreno_ila(ggml_backend_t backend, const gg
const int gemm_tile_n = 64;
int N_pad = CEIL_DIV(N, gemm_tile_n) * gemm_tile_n;
static const char * q6_k_bin_dp4a_env = getenv("GGML_OPENCL_Q6_K_BIN_DP4A");
bool q6_k_bin_dp4a_on = q6_k_bin_dp4a_env
? (atoi(q6_k_bin_dp4a_env) != 0)
: true;
// dot prod has to be available
q6_k_bin_dp4a_on = backend_ctx->has_integer_dot && q6_k_bin_dp4a_on;
if (q6_k_bin_dp4a_on && backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin) {
const int dp4a_N_pad = CEIL_DIV(N, 32) * 32;
const size_t n_blocks = (size_t)dp4a_N_pad * (K / 32);
backend_ctx->prealloc_moe_qa.allocate(context, (size_t)dp4a_N_pad * K * sizeof(cl_char));
backend_ctx->prealloc_moe_da.allocate(context, n_blocks * sizeof(cl_half));
backend_ctx->prealloc_moe_sa.allocate(context, n_blocks * sizeof(cl_half));
cl_mem b_sub = nullptr;
region.origin = offset1;
region.size = (size_t)K * N * sizeof(float);
CL_CHECK((b_sub = clCreateSubBuffer(extra1->data_device, 0, CL_BUFFER_CREATE_TYPE_REGION, &region, &err), err));
cl_int tb = (cl_int)((size_t)N * (K / 32));
cl_kernel qk = backend_ctx->kernel_quant_a_q8_1;
CL_CHECK(clSetKernelArg(qk, 0, sizeof(cl_mem), &b_sub));
CL_CHECK(clSetKernelArg(qk, 1, sizeof(cl_mem), &backend_ctx->prealloc_moe_qa.buffer));
CL_CHECK(clSetKernelArg(qk, 2, sizeof(cl_mem), &backend_ctx->prealloc_moe_da.buffer));
CL_CHECK(clSetKernelArg(qk, 3, sizeof(cl_mem), &backend_ctx->prealloc_moe_sa.buffer));
CL_CHECK(clSetKernelArg(qk, 4, sizeof(cl_int), &tb));
size_t q_local[1] = { 64 };
size_t q_global[1] = { (size_t)CEIL_DIV(tb, 64) * 64 };
backend_ctx->enqueue_ndrange_kernel(qk, 1, q_global, q_local, dst);
cl_mem d_sub = nullptr;
cl_mem d_img = nullptr;
region.origin = offsetd;
region.size = (size_t)M * N * sizeof(float);
CL_CHECK((d_sub = clCreateSubBuffer(extrad->data_device, 0, CL_BUFFER_CREATE_TYPE_REGION, &region, &err), err));
img_fmt = { CL_R, CL_FLOAT };
memset(&img_desc, 0, sizeof(img_desc));
img_desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
img_desc.image_width = (size_t)M * N;
img_desc.buffer = d_sub;
CL_CHECK((d_img = clCreateImage(context, CL_MEM_WRITE_ONLY, &img_fmt, &img_desc, NULL, &err), err));
kernel = backend_ctx->kernel_gemm_noshuffle_q6_k_q8_1_dp4a_ila_a8_bin;
cl_uint k_arg = 0;
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->ql_img));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->qh));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->s));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q6_K->d));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &backend_ctx->prealloc_moe_qa.buffer));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &backend_ctx->prealloc_moe_da.buffer));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &d_img));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &K));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &M));
CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &N));
size_t local_work_size[3] = { 64, 1, 1 };
size_t global_work_size[3] = { 64, (size_t)(M / 64), (size_t)(dp4a_N_pad / 32) };
backend_ctx->enqueue_ndrange_kernel(kernel, 3, global_work_size, local_work_size, dst);
CL_CHECK(clReleaseMemObject(b_sub));
CL_CHECK(clReleaseMemObject(d_img));
CL_CHECK(clReleaseMemObject(d_sub));
return;
}
cl_mem b_sub_buf = nullptr;
cl_mem b_padded = nullptr;
cl_mem b_buf = nullptr;
+14 -1
View File
@@ -39,6 +39,15 @@ if ! git fetch --tags origin 2>/dev/null; then
echo "Warning: could not fetch tags from origin (local run?)"
fi
# Canonical https URL of this repository (from the origin remote), used to link the previous release.
# Left empty on local runs without an origin remote.
if ORIGIN_URL="$(git remote get-url origin 2>/dev/null)"; then
REPO_URL="https://$(printf '%s' "${ORIGIN_URL}" \
| sed -E -e 's#^git@([^:]+):#https://\1/#' -e 's#^https?://##' -e 's#\.git$##')"
else
REPO_URL=""
fi
# Release commit: the commit <version> points at when the tag exists, HEAD otherwise.
if ! RELEASE_COMMIT="$(git rev-parse -q --verify "refs/tags/${VERSION}^{commit}" 2>/dev/null)"; then
RELEASE_COMMIT="$(git rev-parse HEAD)"
@@ -53,7 +62,11 @@ PREV="$( { git tag --list; echo "${VERSION}"; } \
if [[ -n "${PREV}" ]]; then
CHANGELOG="$(git log --oneline "${PREV}..${RELEASE_COMMIT}")"
CHANGELOG_TITLE="Changelog since ${PREV}"
if [[ -n "${REPO_URL}" ]]; then
CHANGELOG_TITLE="Changelog since [${PREV}](${REPO_URL}/releases/tag/${PREV})"
else
CHANGELOG_TITLE="Changelog since ${PREV}"
fi
else
CHANGELOG="(no previous release tag found)"
CHANGELOG_TITLE="Changelog"
+1 -1
View File
@@ -1 +1 @@
cae37675560bce40e5e8b7a505cb0cd06d211a5c
e565a8f4ce2e462c4973a24c51098dd3c81c0256
+23 -3
View File
@@ -93,6 +93,7 @@ static void usage(char ** argv) {
LOG(" -d, --stdev <stdev> Set the standard deviation of the tensor initialization distribution (default: 0.1f)\n");
LOG(" -o, --out <dir> Save generated test models to <dir> instead of running backend tests\n");
LOG(" -v <N> Set log verbosity level\n");
LOG(" -b, --backend <backend> Run only on the given backend device\n");
LOG(" -h, --help Show this help message\n\n");
LOG("Examples:\n");
LOG(" %s\n", argv[0]);
@@ -704,7 +705,7 @@ static int save_models(const std::string & arch_filter, const size_t seed, const
return 0;
}
static int test_backends(const std::string & arch_filter, const size_t seed, const float stdev, const int verbosity) {
static int test_backends(const std::string & arch_filter, const size_t seed, const float stdev, const int verbosity, const char * target_backend) {
struct user_data_t {
struct {
ggml_log_callback callback;
@@ -746,6 +747,9 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
const size_t device_count = ggml_backend_dev_count();
for (size_t i = 0; i < device_count; i++) {
ggml_backend_dev_t dev = ggml_backend_dev_get(i);
if (target_backend != nullptr && strcmp(target_backend, ggml_backend_dev_name(dev)) != 0) {
continue;
}
dev_configs.emplace_back(std::vector<ggml_backend_dev_t>{dev}, ggml_backend_dev_description(dev), LLAMA_SPLIT_MODE_LAYER);
max_device_label_length = std::max(max_device_label_length, dev_configs.back().label.length());
@@ -756,7 +760,9 @@ static int test_backends(const std::string & arch_filter, const size_t seed, con
}
}
dev_configs.emplace_back(devices_meta, "Meta", LLAMA_SPLIT_MODE_TENSOR);
if (target_backend == nullptr) {
dev_configs.emplace_back(devices_meta, "Meta", LLAMA_SPLIT_MODE_TENSOR);
}
}
size_t max_arch_name_length = 0;
@@ -907,6 +913,7 @@ int main(int argc, char ** argv) {
size_t seed = rd();
float stdev = 0.1f;
std::string out;
const char * target_backend = nullptr;
int verbosity = LOG_LEVEL_ERROR;
@@ -961,6 +968,19 @@ int main(int argc, char ** argv) {
usage(argv);
return 1;
}
} else if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "--backend") == 0) {
if (i + 1 < argc) {
const char * backend_name = argv[++i];
ggml_backend_dev_t dev = ggml_backend_dev_by_name(backend_name);
if (dev == nullptr) {
LOG_ERR("%s: unknown backend device: %s\n", __func__, backend_name);
return 1;
}
target_backend = ggml_backend_dev_name(dev);
} else {
usage(argv);
return 1;
}
} else {
LOG_ERR("%s: unknown argument: %s\n", __func__, argv[i]);
usage(argv);
@@ -977,7 +997,7 @@ int main(int argc, char ** argv) {
if (!out.empty()) {
return save_models(arch_filter, seed, stdev, verbosity, out);
}
return test_backends(arch_filter, seed, stdev, verbosity);
return test_backends(arch_filter, seed, stdev, verbosity, target_backend);
} catch (const std::exception & err) {
fprintf(stderr, "encountered runtime error: %s\n", err.what());
return -1;
+5 -2
View File
@@ -467,7 +467,6 @@ static std::filesystem::path get_server_exec_path() {
}
static void unset_reserved_args(common_preset & preset, bool unset_model_args) {
preset.unset_option("LLAMA_ARG_LOG_FILE");
preset.unset_option("LLAMA_ARG_SSL_KEY_FILE");
preset.unset_option("LLAMA_ARG_SSL_CERT_FILE");
preset.unset_option("LLAMA_API_KEY");
@@ -585,8 +584,12 @@ server_models::server_models(
base_preset(ctx_preset.load_from_args(argc, argv)),
sched(std::make_unique<server_lru_sched>(*this)),
monitor(std::make_unique<server_monitor>(*this)) {
// clean up base preset
// propagate base params to child
unset_reserved_args(base_preset, true);
// do not propagate these options, but allow preset to explicitly set them
base_preset.unset_option("LLAMA_ARG_LOG_FILE");
// set binary path
try {
bin_path = get_server_exec_path().string();