Skip to content

Commit 6903324

Browse files
committed
fix(llama-cpp): guard score task for fork backends
TurboQuant and Bonsai reuse the primary gRPC server against llama.cpp forks that do not carry LocalAI's slot-based Score patches. Compile the Score integration only for the patched primary backend and return UNIMPLEMENTED from fork builds instead of referencing absent task types and common_params fields. Assisted-by: Codex:gpt-5 [gh] Signed-off-by: Richard Palethorpe <io@richiejp.com>
1 parent 6f7cf0d commit 6903324

4 files changed

Lines changed: 60 additions & 0 deletions

File tree

backend/cpp/bonsai/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ define bonsai-build
4141
# and are applied by apply-patches.sh below.
4242
rm -rf $(CURRENT_MAKEFILE_DIR)/../bonsai-$(1)-build/patches
4343
$(MAKE) -C $(CURRENT_MAKEFILE_DIR)/../bonsai-$(1)-build purge
44+
bash $(LLAMA_CPP_DIR)/disable-score-task.sh $(CURRENT_MAKEFILE_DIR)/../bonsai-$(1)-build/grpc-server.cpp
4445
$(info $(GREEN)I bonsai build info:$(1)$(RESET))
4546
LLAMA_REPO=$(LLAMA_REPO) LLAMA_VERSION=$(BONSAI_VERSION) \
4647
$(MAKE) -C $(CURRENT_MAKEFILE_DIR)/../bonsai-$(1)-build llama.cpp
@@ -77,6 +78,7 @@ bonsai-cpu-all:
7778
# and are applied by apply-patches.sh below.
7879
rm -rf $(CURRENT_MAKEFILE_DIR)/../bonsai-cpu-all-build/patches
7980
$(MAKE) -C $(CURRENT_MAKEFILE_DIR)/../bonsai-cpu-all-build purge
81+
bash $(LLAMA_CPP_DIR)/disable-score-task.sh $(CURRENT_MAKEFILE_DIR)/../bonsai-cpu-all-build/grpc-server.cpp
8082
$(info $(GREEN)I bonsai build info:cpu-all-variants$(RESET))
8183
LLAMA_REPO=$(LLAMA_REPO) LLAMA_VERSION=$(BONSAI_VERSION) \
8284
$(MAKE) -C $(CURRENT_MAKEFILE_DIR)/../bonsai-cpu-all-build llama.cpp
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/bin/bash
2+
# Mark a copied gRPC server as targeting a llama.cpp fork that does not carry
3+
# LocalAI's slot-based Score patches. The RPC remains present in the shared
4+
# protobuf service, but responds with UNIMPLEMENTED instead of referencing
5+
# server task types and common_params fields absent from those forks.
6+
7+
set -euo pipefail
8+
9+
if [[ $# -ne 1 ]]; then
10+
echo "usage: $0 <grpc-server.cpp>" >&2
11+
exit 2
12+
fi
13+
14+
SRC=$1
15+
16+
if [[ ! -f "$SRC" ]]; then
17+
echo "grpc-server.cpp not found at $SRC" >&2
18+
exit 2
19+
fi
20+
21+
if grep -q '^#define LOCALAI_LLAMA_CPP_NO_SCORE_TASK' "$SRC"; then
22+
echo "==> $SRC already disables the LocalAI score task, skipping"
23+
exit 0
24+
fi
25+
26+
awk '
27+
!done && /^#include/ {
28+
print "#define LOCALAI_LLAMA_CPP_NO_SCORE_TASK 1"
29+
print "// ^ injected by disable-score-task.sh for an unpatched llama.cpp fork"
30+
print ""
31+
done = 1
32+
}
33+
{ print }
34+
END {
35+
if (!done) {
36+
print "disable-score-task.sh: no #include anchor found" > "/dev/stderr"
37+
exit 1
38+
}
39+
}
40+
' "$SRC" > "$SRC.tmp"
41+
mv "$SRC.tmp" "$SRC"
42+
43+
echo "==> LocalAI score task disabled in $SRC"

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ static void params_parse(server_context& /*ctx_server*/, const backend::ModelOpt
690690
// If conversion fails, keep default value (0)
691691
}
692692
}
693+
#ifndef LOCALAI_LLAMA_CPP_NO_SCORE_TASK
693694
} else if (!strcmp(optname, "n_rs_seq") || !strcmp(optname, "rs_seq")) {
694695
// Recurrent-state rollback snapshots per sequence. Hybrid models
695696
// (deltanet/conv layers) cannot rewind their state, so without
@@ -704,6 +705,7 @@ static void params_parse(server_context& /*ctx_server*/, const backend::ModelOpt
704705
// If conversion fails, keep default value (0)
705706
}
706707
}
708+
#endif
707709
} else if (!strcmp(optname, "slot_prompt_similarity") || !strcmp(optname, "sps")) {
708710
if (optval != NULL) {
709711
try {
@@ -1344,6 +1346,7 @@ static void params_parse(server_context& /*ctx_server*/, const backend::ModelOpt
13441346
}
13451347
}
13461348

1349+
#ifndef LOCALAI_LLAMA_CPP_NO_SCORE_TASK
13471350
// Score-task suffix forking: reserve seq ids (and recurrent-state cells)
13481351
// beyond the slots so one scoring call decodes all candidate tails in a
13491352
// single batch (SERVER_TASK_TYPE_SCORE, patches/). Requires the unified
@@ -1352,6 +1355,7 @@ static void params_parse(server_context& /*ctx_server*/, const backend::ModelOpt
13521355
// passes so an explicit kv_unified:false wins and disables forking.
13531356
params.score_enabled = request->enablescore();
13541357
params.n_seq_score_forks = params.score_enabled && params.kv_unified ? SERVER_SCORE_FORK_SEQS : 0;
1358+
#endif
13551359

13561360
// Terminate/pad the override vectors only after BOTH the named-option loop
13571361
// and the generic passthrough (common_params_parse above) have pushed their
@@ -1409,13 +1413,15 @@ class BackendServiceImpl final : public backend::Backend::Service {
14091413
common_params params;
14101414
params_parse(ctx_server, request, params);
14111415

1416+
#ifndef LOCALAI_LLAMA_CPP_NO_SCORE_TASK
14121417
if (params.score_enabled && !params.kv_unified) {
14131418
const std::string error_msg =
14141419
"Score requires the unified KV cache; remove kv_unified:false or remove score from known_usecases";
14151420
result->set_message(error_msg);
14161421
result->set_success(false);
14171422
return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, error_msg);
14181423
}
1424+
#endif
14191425

14201426
common_init();
14211427
// Ensure debug logs are enabled after common_init() sets up logging
@@ -2912,6 +2918,12 @@ class BackendServiceImpl final : public backend::Backend::Service {
29122918
if (params_base.model.path.empty()) {
29132919
return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION, "Model not loaded");
29142920
}
2921+
#ifdef LOCALAI_LLAMA_CPP_NO_SCORE_TASK
2922+
(void) request;
2923+
(void) response;
2924+
return grpc::Status(grpc::StatusCode::UNIMPLEMENTED,
2925+
"Score is unavailable in this llama.cpp fork backend");
2926+
#else
29152927
if (!params_base.score_enabled) {
29162928
return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION,
29172929
"Score was not enabled when the model was loaded; add score to known_usecases");
@@ -3140,6 +3152,7 @@ class BackendServiceImpl final : public backend::Backend::Service {
31403152
}
31413153

31423154
return grpc::Status::OK;
3155+
#endif
31433156
}
31443157

31453158
grpc::Status TokenizeString(ServerContext* context, const backend::PredictOptions* request, backend::TokenizationResponse* response) override {

backend/cpp/turboquant/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ define turboquant-build
4747
# original under backend/cpp/llama-cpp/, so the stock llama-cpp build
4848
# stays compiling against vanilla upstream.
4949
bash $(CURRENT_MAKEFILE_DIR)/patch-grpc-server.sh $(CURRENT_MAKEFILE_DIR)/../turboquant-$(1)-build/grpc-server.cpp
50+
bash $(LLAMA_CPP_DIR)/disable-score-task.sh $(CURRENT_MAKEFILE_DIR)/../turboquant-$(1)-build/grpc-server.cpp
5051
$(info $(GREEN)I turboquant build info:$(1)$(RESET))
5152
LLAMA_REPO=$(LLAMA_REPO) LLAMA_VERSION=$(TURBOQUANT_VERSION) \
5253
$(MAKE) -C $(CURRENT_MAKEFILE_DIR)/../turboquant-$(1)-build llama.cpp
@@ -84,6 +85,7 @@ turboquant-cpu-all:
8485
rm -rf $(CURRENT_MAKEFILE_DIR)/../turboquant-cpu-all-build/patches
8586
$(MAKE) -C $(CURRENT_MAKEFILE_DIR)/../turboquant-cpu-all-build purge
8687
bash $(CURRENT_MAKEFILE_DIR)/patch-grpc-server.sh $(CURRENT_MAKEFILE_DIR)/../turboquant-cpu-all-build/grpc-server.cpp
88+
bash $(LLAMA_CPP_DIR)/disable-score-task.sh $(CURRENT_MAKEFILE_DIR)/../turboquant-cpu-all-build/grpc-server.cpp
8789
$(info $(GREEN)I turboquant build info:cpu-all-variants$(RESET))
8890
LLAMA_REPO=$(LLAMA_REPO) LLAMA_VERSION=$(TURBOQUANT_VERSION) \
8991
$(MAKE) -C $(CURRENT_MAKEFILE_DIR)/../turboquant-cpu-all-build llama.cpp

0 commit comments

Comments
 (0)