From 659b11c995ffdf0f9fdaf7f3cf4f39bc204678ec Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Fri, 9 Oct 2026 13:07:34 +0200 Subject: [PATCH] common : read a GGUF's trained context from its metadata common_get_gguf_n_ctx_train opens only the file's metadata (no_alloc, like common_get_decision_type) and reads .context_length, so a caller can learn the trained context without loading the model. It accepts both u32 and u64 values and returns 0 when the file is missing, unreadable, invalid, or reports no context length. Assisted-by: pi:zai-org/GLM-5.3-Flash --- common/common.cpp | 36 ++++++++++++++++++++++++++++++++++++ common/common.h | 4 ++++ 2 files changed, 40 insertions(+) diff --git a/common/common.cpp b/common/common.cpp index 48caa80c19..cfa892f61f 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -1230,6 +1230,42 @@ common_decision_type common_get_decision_type(const std::string & fname) { return common_decision_type_from_string(gguf_get_val_str(gguf_ctx.get(), type_id)); } +uint32_t common_get_gguf_n_ctx_train(const std::string & fname) { + struct gguf_init_params gguf_params = { + /* .no_alloc = */ true, + /* .ctx = */ nullptr, + }; + + gguf_context_ptr gguf_ctx(gguf_init_from_file(fname.c_str(), gguf_params)); + if (!gguf_ctx) { + return 0; // missing or unreadable file + } + + const int64_t arch_id = gguf_find_key(gguf_ctx.get(), "general.architecture"); + if (arch_id < 0 || gguf_get_kv_type(gguf_ctx.get(), arch_id) != GGUF_TYPE_STRING) { + return 0; + } + + const std::string key = std::string(gguf_get_val_str(gguf_ctx.get(), arch_id)) + ".context_length"; + const int64_t key_id = gguf_find_key(gguf_ctx.get(), key.c_str()); + if (key_id < 0) { + return 0; + } + + // writers are not strict about the width of the hparams, so accept both + switch (gguf_get_kv_type(gguf_ctx.get(), key_id)) { + case GGUF_TYPE_UINT32: + return gguf_get_val_u32(gguf_ctx.get(), key_id); + case GGUF_TYPE_UINT64: + { + const uint64_t val = gguf_get_val_u64(gguf_ctx.get(), key_id); + return val <= UINT32_MAX ? (uint32_t) val : 0; + } + default: + return 0; + } +} + common_init_result::common_init_result(common_params & params, bool model_only) : pimpl(new impl{}) { auto mparams = common_model_params_to_llama(params); diff --git a/common/common.h b/common/common.h index 557518e365..d8c05e7b7d 100644 --- a/common/common.h +++ b/common/common.h @@ -974,6 +974,10 @@ common_decision_type common_get_decision_type(const struct llama_model * model); // returns COMMON_DECISION_TYPE_UNKNOWN if the file is missing, unreadable, or invalid common_decision_type common_get_decision_type(const std::string & fname); +// reads the trained context of a GGUF file from its metadata; it does not load the model +// returns 0 if the file is missing, unreadable, invalid, or reports no context length +uint32_t common_get_gguf_n_ctx_train(const std::string & fname); + // note: defines the model, context, samplers, ets. lifetimes struct common_init_result { common_init_result(common_params & params, bool model_only = false);