Skip to content

Commit bc4cd3d

Browse files
localai-botmudler
andauthored
feat(llama-cpp): bump to 1ec7ba0c, adapt grpc-server, expose new spec-decoding options (#9765)
* chore(llama.cpp): bump to 1ec7ba0c14f33f17e980daeeda5f35b225d41994 Picks up the upstream `spec : parallel drafting support` change (ggml-org/llama.cpp#22838) which reshapes the speculative-decoding API and `server_context_impl`. Adapt the grpc-server wrapper accordingly: * `common_params_speculative::type` (single enum) became `types` (`std::vector<common_speculative_type>`). Update both the "default to draft when a draft model is set" branch and the `spec_type`/`speculative_type` option parser. The parser now also tolerates comma-separated lists, mirroring the upstream `common_speculative_types_from_names` semantics. * `common_params_speculative_draft::n_ctx` is gone (draft now shares the target context size). Keep the `draft_ctx_size` option name for backward compatibility and ignore the value rather than failing. * `server_context_impl::model` was renamed to `model_tgt`; update the two reranker / model-metadata call sites. Replaces #9763. Builds cleanly under the linux/amd64 cpu-llama-cpp target locally. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * feat(llama-cpp): expose new speculative-decoding option keys Upstream `spec : parallel drafting support` (ggml-org/llama.cpp#22838) adds the `ngram_mod`, `ngram_map_k`, and `ngram_map_k4v` speculative families and beefs up the draft-model knobs. The previous bump only adapted the API; this exposes the new fields through the grpc-server options dictionary so model configs can drive them. New `options:` keys (all under `backend: llama-cpp`): ngram_mod (`ngram_mod` type): spec_ngram_mod_n_min / spec_ngram_mod_n_max / spec_ngram_mod_n_match ngram_map_k (`ngram_map_k` type): spec_ngram_map_k_size_n / spec_ngram_map_k_size_m / spec_ngram_map_k_min_hits ngram_map_k4v (`ngram_map_k4v` type): spec_ngram_map_k4v_size_n / spec_ngram_map_k4v_size_m / spec_ngram_map_k4v_min_hits ngram lookup caches (`ngram_cache` type): spec_lookup_cache_static / lookup_cache_static spec_lookup_cache_dynamic / lookup_cache_dynamic Draft-model tuning (active when `spec_type` is `draft`): draft_cache_type_k / spec_draft_cache_type_k draft_cache_type_v / spec_draft_cache_type_v draft_threads / spec_draft_threads draft_threads_batch / spec_draft_threads_batch draft_cpu_moe / spec_draft_cpu_moe (bool flag) draft_n_cpu_moe / spec_draft_n_cpu_moe (first N MoE layers on CPU) draft_override_tensor / spec_draft_override_tensor (comma-separated <tensor regex>=<buffer type>; re-implements upstream's static parse_tensor_buffer_overrides since it isn't exported) `spec_type` already accepted comma-separated lists after the previous commit, matching upstream's `common_speculative_types_from_names`. Docs: refresh `docs/content/advanced/model-configuration.md` with per-family tables and a note about multi-type chaining. Builds locally with `make docker-build-llama-cpp` (linux/amd64 cpu-llama-cpp AVX variant). Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(turboquant): bridge new llama.cpp spec API to the legacy fork layout The previous commits in this series adapted backend/cpp/llama-cpp/grpc-server.cpp to the post-#22838 (parallel drafting) llama.cpp API. The turboquant build reuses the same grpc-server.cpp through backend/cpp/turboquant/Makefile, which copies it into turboquant-<flavor>-build/ and runs patch-grpc-server.sh on the copy. The fork branched before the API refactor, so it errors out on: * `ctx_server.impl->model_tgt` (fork still has `model`) * `params.speculative.{ngram_mod,ngram_map_k,ngram_map_k4v,ngram_cache}.*` (none of these sub-structs exist in the fork) * `params.speculative.draft.{cache_type_k/v, cpuparams[, _batch].n_threads, tensor_buft_overrides}` (fork uses the pre-#22397 flat layout) * `params.speculative.types` vector / `common_speculative_types_from_names` (fork has a scalar `type` and only the singular helper) Approach: 1. backend/cpp/llama-cpp/grpc-server.cpp: introduce a single feature switch `LOCALAI_LEGACY_LLAMA_CPP_SPEC`. When defined, the two `speculative.type[s]` discriminations (the "default to draft when a draft model is set" branch and the `spec_type` / `speculative_type` option parser) fall back to the singular scalar form, and the entire new-option block (ngram_mod / map_k / map_k4v / ngram_cache / draft.{cache_type_*, cpuparams*, tensor_buft_overrides}) is preprocessed out. The macro is *not* defined in the source tree — stock llama-cpp builds get the full new API. 2. backend/cpp/turboquant/patch-grpc-server.sh: two new patch steps applied to the per-flavor build copy at turboquant-<flavor>-build/grpc-server.cpp: - substitute `ctx_server.impl->model_tgt` -> `ctx_server.impl->model` - inject `#define LOCALAI_LEGACY_LLAMA_CPP_SPEC 1` before the first `#include`, so the guarded blocks above drop out for the fork build. Both patches are idempotent and follow the existing sed/awk pattern in this script (KV cache types, `get_media_marker`, flat speculative renames). Stock llama-cpp's `grpc-server.cpp` is never touched. Drop both legacy patches once the turboquant fork rebases past ggml-org/llama.cpp#22397 / #22838. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(turboquant): close draft_ctx_size brace inside legacy guard The previous turboquant fix wrapped the new option-handler blocks in `#ifndef LOCALAI_LEGACY_LLAMA_CPP_SPEC ... #endif` but placed the guard in the middle of an `else if` chain — the `} else if` openings of the new blocks were responsible for closing the previous block's brace. With the macro defined the new blocks vanish, draft_ctx_size's `{` loses its closer, the for-loop's `}` is consumed instead, and the file ends with a stray opening brace — clang reports it as `function-definition is not allowed here before '{'` on the next top-level `int main(...)` and `expected '}' at end of input`. Move the chain split inside the draft_ctx_size branch: } else if (... "draft_ctx_size") { // ... #ifdef LOCALAI_LEGACY_LLAMA_CPP_SPEC } // legacy: chain ends here #else } else if (... "spec_ngram_mod_n_min") { // modern: chain continues ... } else if (... "draft_override_tensor") { ... } // closes last branch #endif } // closes for-loop Brace count is now balanced under both preprocessor branches (verified with `tr -cd '{' | wc -c` against the patched and unpatched outputs). Local `make docker-build-turboquant` builds the linux/amd64 cpu-llama-cpp `turboquant-avx` variant cleanly. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix(ci): forward AMDGPU_TARGETS into Dockerfile.turboquant builder-prebuilt Dockerfile.turboquant's `builder-prebuilt` stage was missing the `ARG AMDGPU_TARGETS` / `ENV AMDGPU_TARGETS=${AMDGPU_TARGETS}` pair that `builder-fromsource` already has (and that `Dockerfile.llama-cpp` mirrors across both stages). When CI uses the prebuilt base image (quay.io/go-skynet/ci-cache:base-grpc-*, the common path) the build-arg passed by the workflow never reaches the env inside the compile stage. backend/cpp/llama-cpp/Makefile:38 (introduced by #9626) errors out on hipblas builds when AMDGPU_TARGETS is empty, and the turboquant Makefile reuses backend/cpp/llama-cpp via a sibling build dir, so the same check fires from turboquant-fallback under BUILD_TYPE=hipblas: Makefile:38: *** AMDGPU_TARGETS is empty — set it to a comma-separated list of gfx targets e.g. gfx1100,gfx1101. Stop. make: *** [Makefile:66: turboquant-fallback] Error 2 The bug is latent on master because the docker layer cache stays warm across builds — the compile step rarely re-runs from scratch. The llama.cpp bump in this PR invalidates the cache, so the missing env var becomes load-bearing and the hipblas turboquant CI job fails. Mirror the existing pattern from Dockerfile.llama-cpp. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> --------- Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
1 parent 86a7f6c commit bc4cd3d

5 files changed

Lines changed: 295 additions & 10 deletions

File tree

backend/Dockerfile.turboquant

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ ARG CUDA_DOCKER_ARCH
117117
ENV CUDA_DOCKER_ARCH=${CUDA_DOCKER_ARCH}
118118
ARG CMAKE_ARGS
119119
ENV CMAKE_ARGS=${CMAKE_ARGS}
120+
# AMDGPU_TARGETS must be forwarded into the env here too — backend/cpp/llama-cpp/Makefile
121+
# (which the turboquant Makefile reuses via a sibling build dir) errors out when the var
122+
# is empty on a hipblas build, and the prebuilt path is what CI exercises most of the
123+
# time. The builder-fromsource stage above already does this; mirror it here.
124+
ARG AMDGPU_TARGETS
125+
ENV AMDGPU_TARGETS=${AMDGPU_TARGETS}
120126
ARG TARGETARCH
121127
ARG TARGETVARIANT
122128

backend/cpp/llama-cpp/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
LLAMA_VERSION?=389ff61d77b5c71cec0cf92fe4e5d01ace80b797
2+
LLAMA_VERSION?=1ec7ba0c14f33f17e980daeeda5f35b225d41994
33
LLAMA_REPO?=https://github.com/ggerganov/llama.cpp
44

55
CMAKE_ARGS?=

backend/cpp/llama-cpp/grpc-server.cpp

Lines changed: 190 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include <cstdlib>
3737
#include <fstream>
3838
#include <iterator>
39+
#include <list>
40+
#include <map>
3941
#include <mutex>
4042
#include <signal.h>
4143
#include <thread>
@@ -443,10 +445,22 @@ static void params_parse(server_context& /*ctx_server*/, const backend::ModelOpt
443445
// Draft model for speculative decoding
444446
if (!request->draftmodel().empty()) {
445447
params.speculative.draft.mparams.path = request->draftmodel();
446-
// Default to draft type if a draft model is set but no explicit type
448+
// Default to draft type if a draft model is set but no explicit type.
449+
// Upstream (post ggml-org/llama.cpp#22838) made the speculative type a
450+
// vector; the turboquant fork still uses the legacy scalar. The
451+
// LOCALAI_LEGACY_LLAMA_CPP_SPEC macro is injected by
452+
// backend/cpp/turboquant/patch-grpc-server.sh for fork builds only.
453+
#ifdef LOCALAI_LEGACY_LLAMA_CPP_SPEC
447454
if (params.speculative.type == COMMON_SPECULATIVE_TYPE_NONE) {
448455
params.speculative.type = COMMON_SPECULATIVE_TYPE_DRAFT;
449456
}
457+
#else
458+
const bool no_spec_type = params.speculative.types.empty() ||
459+
(params.speculative.types.size() == 1 && params.speculative.types[0] == COMMON_SPECULATIVE_TYPE_NONE);
460+
if (no_spec_type) {
461+
params.speculative.types = { COMMON_SPECULATIVE_TYPE_DRAFT };
462+
}
463+
#endif
450464
}
451465

452466
// params.model_alias ??
@@ -673,10 +687,35 @@ static void params_parse(server_context& /*ctx_server*/, const backend::ModelOpt
673687
}
674688
// Speculative decoding options
675689
} else if (!strcmp(optname, "spec_type") || !strcmp(optname, "speculative_type")) {
676-
auto type = common_speculative_type_from_name(optval_str);
690+
#ifdef LOCALAI_LEGACY_LLAMA_CPP_SPEC
691+
// Fork only knows a single scalar `type`. Take the first comma-
692+
// separated value and assign it via the singular helper.
693+
std::string first = optval_str;
694+
const auto comma = first.find(',');
695+
if (comma != std::string::npos) first = first.substr(0, comma);
696+
auto type = common_speculative_type_from_name(first);
677697
if (type != COMMON_SPECULATIVE_TYPE_COUNT) {
678698
params.speculative.type = type;
679699
}
700+
#else
701+
// Upstream switched to a vector of types (comma-separated for multi-type
702+
// chaining via common_speculative_types_from_names). We keep accepting a
703+
// single value here, but also tolerate comma-separated lists.
704+
std::vector<std::string> names;
705+
std::string item;
706+
for (char c : optval_str) {
707+
if (c == ',') {
708+
if (!item.empty()) { names.push_back(item); item.clear(); }
709+
} else {
710+
item.push_back(c);
711+
}
712+
}
713+
if (!item.empty()) names.push_back(item);
714+
auto parsed = common_speculative_types_from_names(names);
715+
if (!parsed.empty()) {
716+
params.speculative.types = parsed;
717+
}
718+
#endif
680719
} else if (!strcmp(optname, "spec_n_max") || !strcmp(optname, "draft_max")) {
681720
if (optval != NULL) {
682721
try { params.speculative.draft.n_max = std::stoi(optval_str); } catch (...) {}
@@ -710,10 +749,155 @@ static void params_parse(server_context& /*ctx_server*/, const backend::ModelOpt
710749
try { params.speculative.draft.n_gpu_layers = std::stoi(optval_str); } catch (...) {}
711750
}
712751
} else if (!strcmp(optname, "draft_ctx_size")) {
752+
// The draft context size is no longer a separate field upstream: the draft
753+
// shares the target context size. Accept the option for backward
754+
// compatibility but silently ignore it.
755+
756+
// Everything below relies on struct shape introduced in ggml-org/llama.cpp#22838
757+
// (parallel drafting): `ngram_mod`, `ngram_map_k`, `ngram_map_k4v`,
758+
// `ngram_cache`, and the `draft.{cache_type_*, cpuparams*, tensor_buft_overrides}`
759+
// fields. The turboquant fork branched before that, so its build defines
760+
// LOCALAI_LEGACY_LLAMA_CPP_SPEC via patch-grpc-server.sh and these option
761+
// keys become unrecognized (silently dropped, like any unknown opt) for it.
762+
//
763+
// The `#ifdef LOCALAI_LEGACY_LLAMA_CPP_SPEC` / `#else` split below sits at the
764+
// closing-brace position of the `draft_ctx_size` branch on purpose: in the
765+
// legacy build the chain ends here (the brace closes draft_ctx_size), and in
766+
// the modern build the chain continues with `} else if (...)` instead, so the
767+
// brace count stays balanced under both branches of the preprocessor.
768+
#ifdef LOCALAI_LEGACY_LLAMA_CPP_SPEC
769+
}
770+
#else
771+
// --- ngram_mod family (upstream --spec-ngram-mod-*) ---
772+
} else if (!strcmp(optname, "spec_ngram_mod_n_min")) {
713773
if (optval != NULL) {
714-
try { params.speculative.draft.n_ctx = std::stoi(optval_str); } catch (...) {}
774+
try { params.speculative.ngram_mod.n_min = std::stoi(optval_str); } catch (...) {}
715775
}
716-
}
776+
} else if (!strcmp(optname, "spec_ngram_mod_n_max")) {
777+
if (optval != NULL) {
778+
try { params.speculative.ngram_mod.n_max = std::stoi(optval_str); } catch (...) {}
779+
}
780+
} else if (!strcmp(optname, "spec_ngram_mod_n_match")) {
781+
if (optval != NULL) {
782+
try { params.speculative.ngram_mod.n_match = std::stoi(optval_str); } catch (...) {}
783+
}
784+
785+
// --- ngram_map_k family (upstream --spec-ngram-map-k-*) ---
786+
} else if (!strcmp(optname, "spec_ngram_map_k_size_n")) {
787+
if (optval != NULL) {
788+
try { params.speculative.ngram_map_k.size_n = (uint16_t)std::stoi(optval_str); } catch (...) {}
789+
}
790+
} else if (!strcmp(optname, "spec_ngram_map_k_size_m")) {
791+
if (optval != NULL) {
792+
try { params.speculative.ngram_map_k.size_m = (uint16_t)std::stoi(optval_str); } catch (...) {}
793+
}
794+
} else if (!strcmp(optname, "spec_ngram_map_k_min_hits")) {
795+
if (optval != NULL) {
796+
try { params.speculative.ngram_map_k.min_hits = (uint16_t)std::stoi(optval_str); } catch (...) {}
797+
}
798+
799+
// --- ngram_map_k4v family (upstream --spec-ngram-map-k4v-*) ---
800+
} else if (!strcmp(optname, "spec_ngram_map_k4v_size_n")) {
801+
if (optval != NULL) {
802+
try { params.speculative.ngram_map_k4v.size_n = (uint16_t)std::stoi(optval_str); } catch (...) {}
803+
}
804+
} else if (!strcmp(optname, "spec_ngram_map_k4v_size_m")) {
805+
if (optval != NULL) {
806+
try { params.speculative.ngram_map_k4v.size_m = (uint16_t)std::stoi(optval_str); } catch (...) {}
807+
}
808+
} else if (!strcmp(optname, "spec_ngram_map_k4v_min_hits")) {
809+
if (optval != NULL) {
810+
try { params.speculative.ngram_map_k4v.min_hits = (uint16_t)std::stoi(optval_str); } catch (...) {}
811+
}
812+
813+
// --- ngram lookup caches (upstream --lookup-cache-static / -dynamic) ---
814+
} else if (!strcmp(optname, "spec_lookup_cache_static") || !strcmp(optname, "lookup_cache_static")) {
815+
params.speculative.ngram_cache.lookup_cache_static = optval_str;
816+
} else if (!strcmp(optname, "spec_lookup_cache_dynamic") || !strcmp(optname, "lookup_cache_dynamic")) {
817+
params.speculative.ngram_cache.lookup_cache_dynamic = optval_str;
818+
819+
// --- draft model KV cache types (upstream --spec-draft-type-k / -v) ---
820+
} else if (!strcmp(optname, "draft_cache_type_k") || !strcmp(optname, "spec_draft_cache_type_k")) {
821+
params.speculative.draft.cache_type_k = kv_cache_type_from_str(optval_str);
822+
} else if (!strcmp(optname, "draft_cache_type_v") || !strcmp(optname, "spec_draft_cache_type_v")) {
823+
params.speculative.draft.cache_type_v = kv_cache_type_from_str(optval_str);
824+
825+
// --- draft model thread counts (upstream --spec-draft-threads / -batch) ---
826+
} else if (!strcmp(optname, "draft_threads") || !strcmp(optname, "spec_draft_threads")) {
827+
if (optval != NULL) {
828+
try {
829+
int n = std::stoi(optval_str);
830+
if (n <= 0) n = (int)std::thread::hardware_concurrency();
831+
params.speculative.draft.cpuparams.n_threads = n;
832+
} catch (...) {}
833+
}
834+
} else if (!strcmp(optname, "draft_threads_batch") || !strcmp(optname, "spec_draft_threads_batch")) {
835+
if (optval != NULL) {
836+
try {
837+
int n = std::stoi(optval_str);
838+
if (n <= 0) n = (int)std::thread::hardware_concurrency();
839+
params.speculative.draft.cpuparams_batch.n_threads = n;
840+
} catch (...) {}
841+
}
842+
843+
// --- draft model MoE on CPU (upstream --spec-draft-cpu-moe / --spec-draft-n-cpu-moe) ---
844+
} else if (!strcmp(optname, "draft_cpu_moe") || !strcmp(optname, "spec_draft_cpu_moe")) {
845+
// Bool-style flag: optval may be missing, "true"/"1"/"yes" enables.
846+
const bool enable = (optval == NULL) ||
847+
optval_str == "true" || optval_str == "1" || optval_str == "yes" ||
848+
optval_str == "on" || optval_str == "enabled";
849+
if (enable) {
850+
params.speculative.draft.tensor_buft_overrides.push_back(llm_ffn_exps_cpu_override());
851+
}
852+
} else if (!strcmp(optname, "draft_n_cpu_moe") || !strcmp(optname, "spec_draft_n_cpu_moe")) {
853+
if (optval != NULL) {
854+
try {
855+
int n = std::stoi(optval_str);
856+
if (n < 0) n = 0;
857+
// Keep override-name storage alive for the lifetime of the params struct
858+
// (mirrors upstream arg.cpp behavior with a function-local static).
859+
static std::list<std::string> buft_overrides_draft;
860+
for (int i = 0; i < n; ++i) {
861+
buft_overrides_draft.push_back(llm_ffn_exps_block_regex(i));
862+
params.speculative.draft.tensor_buft_overrides.push_back(
863+
{buft_overrides_draft.back().c_str(), ggml_backend_cpu_buffer_type()});
864+
}
865+
} catch (...) {}
866+
}
867+
868+
// --- draft model tensor buffer overrides (upstream --spec-draft-override-tensor) ---
869+
} else if (!strcmp(optname, "draft_override_tensor") || !strcmp(optname, "spec_draft_override_tensor")) {
870+
// Format: <tensor regex>=<buffer type>,<tensor regex>=<buffer type>,...
871+
// We replicate upstream's parse_tensor_buffer_overrides (static in arg.cpp).
872+
ggml_backend_load_all();
873+
std::map<std::string, ggml_backend_buffer_type_t> buft_list;
874+
for (size_t i = 0; i < ggml_backend_dev_count(); ++i) {
875+
auto * dev = ggml_backend_dev_get(i);
876+
auto * buft = ggml_backend_dev_buffer_type(dev);
877+
if (buft) {
878+
buft_list[ggml_backend_buft_name(buft)] = buft;
879+
}
880+
}
881+
static std::list<std::string> draft_override_names;
882+
std::string cur;
883+
auto flush = [&](const std::string & spec) {
884+
auto pos = spec.find('=');
885+
if (pos == std::string::npos) return;
886+
const std::string name = spec.substr(0, pos);
887+
const std::string type = spec.substr(pos + 1);
888+
auto it = buft_list.find(type);
889+
if (it == buft_list.end()) return; // unknown buffer type: ignore
890+
draft_override_names.push_back(name);
891+
params.speculative.draft.tensor_buft_overrides.push_back(
892+
{draft_override_names.back().c_str(), it->second});
893+
};
894+
for (char c : optval_str) {
895+
if (c == ',') { if (!cur.empty()) { flush(cur); cur.clear(); } }
896+
else { cur.push_back(c); }
897+
}
898+
if (!cur.empty()) flush(cur);
899+
}
900+
#endif // LOCALAI_LEGACY_LLAMA_CPP_SPEC — closes the `else`/`#ifdef` opened at draft_ctx_size
717901
}
718902

719903
// Set params.n_parallel from environment variable if not set via options (fallback)
@@ -2704,7 +2888,7 @@ class BackendServiceImpl final : public backend::Backend::Service {
27042888

27052889
tasks.reserve(documents.size());
27062890
for (size_t i = 0; i < documents.size(); i++) {
2707-
auto tmp = format_prompt_rerank(ctx_server.impl->model, ctx_server.impl->vocab, ctx_server.impl->mctx, request->query(), documents[i]);
2891+
auto tmp = format_prompt_rerank(ctx_server.impl->model_tgt, ctx_server.impl->vocab, ctx_server.impl->mctx, request->query(), documents[i]);
27082892
server_task task = server_task(SERVER_TASK_TYPE_RERANK);
27092893
task.id = rd.queue_tasks.get_new_id();
27102894
task.index = i;
@@ -2882,7 +3066,7 @@ class BackendServiceImpl final : public backend::Backend::Service {
28823066
// Get template source and reconstruct a common_chat_template for analysis
28833067
std::string tmpl_src = common_chat_templates_source(ctx_server.impl->chat_params.tmpls.get());
28843068
if (!tmpl_src.empty()) {
2885-
const auto * vocab = llama_model_get_vocab(ctx_server.impl->model);
3069+
const auto * vocab = llama_model_get_vocab(ctx_server.impl->model_tgt);
28863070
std::string token_bos, token_eos;
28873071
if (vocab) {
28883072
auto bos_id = llama_vocab_bos(vocab);

backend/cpp/turboquant/patch-grpc-server.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,47 @@ else
108108
echo "==> $SRC has no post-#22397 speculative field refs, skipping spec rename patch"
109109
fi
110110

111+
# 4. Revert the `ctx_server.impl->model_tgt` rename introduced by upstream
112+
# ggml-org/llama.cpp#22838 (parallel drafting). The turboquant fork still
113+
# exposes the field as `model` on `server_context_impl`. The two call sites
114+
# are in the Rerank and ModelMetadata RPC handlers.
115+
if grep -q 'ctx_server\.impl->model_tgt' "$SRC"; then
116+
echo "==> patching $SRC to revert ctx_server.impl->model_tgt -> ctx_server.impl->model"
117+
sed -E 's/ctx_server\.impl->model_tgt/ctx_server.impl->model/g' "$SRC" > "$SRC.tmp"
118+
mv "$SRC.tmp" "$SRC"
119+
echo "==> model_tgt rename OK"
120+
else
121+
echo "==> $SRC has no ctx_server.impl->model_tgt refs, skipping model_tgt rename patch"
122+
fi
123+
124+
# 5. Define LOCALAI_LEGACY_LLAMA_CPP_SPEC at the top of the file so the
125+
# grpc-server option parser skips the new option-handler blocks (ngram_mod,
126+
# ngram_map_k, ngram_map_k4v, ngram_cache, draft.cache_type_*, draft.cpuparams*,
127+
# draft.tensor_buft_overrides) introduced for the post-#22838 layout. Those
128+
# blocks reference struct fields that simply do not exist in the fork.
129+
if grep -q '^#define LOCALAI_LEGACY_LLAMA_CPP_SPEC' "$SRC"; then
130+
echo "==> $SRC already defines LOCALAI_LEGACY_LLAMA_CPP_SPEC, skipping"
131+
else
132+
echo "==> patching $SRC to define LOCALAI_LEGACY_LLAMA_CPP_SPEC at the top"
133+
# Insert the define before the very first `#include` so it precedes all the
134+
# speculative-decoding code paths.
135+
awk '
136+
!done && /^#include/ {
137+
print "#define LOCALAI_LEGACY_LLAMA_CPP_SPEC 1"
138+
print "// ^ injected by backend/cpp/turboquant/patch-grpc-server.sh"
139+
print ""
140+
done = 1
141+
}
142+
{ print }
143+
END {
144+
if (!done) {
145+
print "patch-grpc-server.sh: no #include anchor found to insert LOCALAI_LEGACY_LLAMA_CPP_SPEC" > "/dev/stderr"
146+
exit 1
147+
}
148+
}
149+
' "$SRC" > "$SRC.tmp"
150+
mv "$SRC.tmp" "$SRC"
151+
echo "==> LOCALAI_LEGACY_LLAMA_CPP_SPEC define OK"
152+
fi
153+
111154
echo "==> all patches applied"

0 commit comments

Comments
 (0)