embeddings: GGUF inputs longer than n_batch crashed the whole engine

llama.cpp embedding mode SIGABRTs (GGML_ASSERT out_ids == n_outputs)
when an input exceeds the batch size — with the default n_batch=512 any
long listing killed the radeon engine (front kept respawning it).
Size n_batch/n_ubatch to n_ctx at load, and truncate each input to the
context window before embed so no accepted input can trip the assert.
Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014S8VtAvG499SsCbeESRK7V
parent 18ab5ad1
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# Canonical product version for CoderAI — single source of truth. Both the API # Canonical product version for CoderAI — single source of truth. Both the API
# metadata and the admin web UI read from here. # metadata and the admin web UI read from here.
__version__ = "0.1.38" __version__ = "0.1.39"
# Configure the CUDA caching allocator BEFORE torch is imported anywhere. # Configure the CUDA caching allocator BEFORE torch is imported anywhere.
# expandable_segments lets the allocator return freed pages to the driver even # expandable_segments lets the allocator return freed pages to the driver even
......
...@@ -180,6 +180,13 @@ def _load_embedding_model(model_name: str, device: str, model_config: dict = Non ...@@ -180,6 +180,13 @@ def _load_embedding_model(model_name: str, device: str, model_config: dict = Non
model_path=model_name, model_path=model_name,
embedding=True, embedding=True,
n_ctx=n_ctx, n_ctx=n_ctx,
# CRITICAL: embedding mode asserts (SIGABRT, killing the whole
# engine) when an input has more tokens than the batch —
# GGML_ASSERT(out_ids.size() == n_outputs). Size both batches
# to the full context so any input we accept can be processed;
# _embed_texts truncates inputs to n_ctx to close the loop.
n_batch=n_ctx,
n_ubatch=n_ctx,
n_gpu_layers=int(n_gpu_layers if n_gpu_layers is not None else -1), n_gpu_layers=int(n_gpu_layers if n_gpu_layers is not None else -1),
verbose=False, verbose=False,
) )
...@@ -435,7 +442,20 @@ def _embed_texts(model_obj, texts: List[str], dimensions=None) -> List[List[floa ...@@ -435,7 +442,20 @@ def _embed_texts(model_obj, texts: List[str], dimensions=None) -> List[List[floa
# those. Normalize either way (llama.cpp does not normalize). # those. Normalize either way (llama.cpp does not normalize).
import math import math
results = [] results = []
try:
_tok_limit = max(16, model.n_ctx() - 8)
except Exception:
_tok_limit = 2040
for t in texts: for t in texts:
# Truncate to the context window — an over-long input would abort
# llama.cpp (GGML_ASSERT) and take the whole engine down with it.
try:
_toks = model.tokenize(t.encode('utf-8', 'ignore'),
add_bos=True, special=False)
if len(_toks) > _tok_limit:
t = model.detokenize(_toks[:_tok_limit]).decode('utf-8', 'ignore')
except Exception:
pass
emb = model.embed(t) emb = model.embed(t)
if emb and isinstance(emb[0], (list, tuple)): if emb and isinstance(emb[0], (list, tuple)):
n = len(emb) n = len(emb)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment