Pārlūkot izejas kodu

fix(llm): never compile llama.cpp at query time — prebuilt-only (i-tgac7ig3)

getLlama() used build:"autoAttempt", which compiles llama.cpp from source
per-GPU the moment a prebuilt fails to load. On the code LXC (libvulkan.so.1
present, no GPU device, no glslc) the GPU auto-probe picks Vulkan, the prebuilt
Vulkan binary is host-incompatible, and autoAttempt then runs a doomed cmake
build (no glslc) — a 30-60s+ blocking stall that hangs interactive 'qmd query'
and leaves a half-built localBuilds/ dir.

Switch to build:"never": node-llama-cpp loads prebuilt binaries only and falls
through the candidate list (Vulkan -> CUDA -> CPU) to the prebuilt CPU binary.
Verified on code: getLlama({build:"never",gpu:"auto"}) loads CPU in ~2.7s; a
full 'qmd query' runs in 6.3s and creates 0 localBuilds/ files. Completes
i-c28wngnd (which only covered the QMD_EMBED_ENDPOINT=cpu path) for the
interactive / gpu:"auto" path. Also fixes the same footgun in bench-rerank.ts.

Generated with [Claude Code](https://claude.ai/code)
via [Oivo](https://oivo.com)

Co-Authored-By: Claude <noreply@anthropic.com>
Session-Id: b6802844
Claude 3 nedēļas atpakaļ
vecāks
revīzija
649a30b420
3 mainītis faili ar 30 papildinājumiem un 4 dzēšanām
  1. 13 1
      dist/llm.js
  2. 4 2
      src/bench-rerank.ts
  3. 13 1
      src/llm.ts

+ 13 - 1
dist/llm.js

@@ -382,7 +382,19 @@ export class LlamaCpp {
             // probe GPU normally for legacy local-only setups.
             const gpuMode = resolveLlamaGpuMode(process.env);
             const loadLlama = async (gpu) => await getLlama({
-                build: "autoAttempt",
+                // `never` = load a prebuilt binary only; never invoke cmake at query
+                // time. When the GPU auto-probe picks a backend whose prebuilt binary
+                // is incompatible with the host (e.g. the `code` LXC has libvulkan.so.1
+                // but no GPU device and no glslc), `autoAttempt` would compile
+                // llama.cpp from source per-GPU — a 30-60s+ blocking stall that then
+                // fails for lack of glslc and leaves a half-built localBuilds/ dir,
+                // hanging interactive `qmd query`. `never` instead falls straight
+                // through the prebuilt candidate list (Vulkan -> CUDA -> CPU) and lands
+                // on the prebuilt CPU binary. node-llama-cpp ships prebuilts for every
+                // platform we deploy on, so the source-build fallback is dead weight.
+                // Completes i-c28wngnd (which only covered the QMD_EMBED_ENDPOINT=cpu
+                // path) for the interactive / gpu:"auto" path. (i-tgac7ig3)
+                build: "never",
                 logLevel: LlamaLogLevel.error,
                 gpu,
             });

+ 4 - 2
src/bench-rerank.ts

@@ -192,8 +192,10 @@ async function main() {
   console.log("═══════════════════════════════════════════════════════════════\n");
 
   const llama = await getLlama({
-    // attempt to build
-    build: "autoAttempt",
+    // Load prebuilt binaries only — never compile llama.cpp at runtime. See the
+    // detailed rationale in src/llm.ts: `autoAttempt` blocks on a doomed cmake
+    // build when the auto-probed GPU's prebuilt is host-incompatible. (i-tgac7ig3)
+    build: "never",
     logLevel: LlamaLogLevel.error
   });
   let gpuLabel: string = llama.gpu === false

+ 13 - 1
src/llm.ts

@@ -652,7 +652,19 @@ export class LlamaCpp implements LLM {
 
       const loadLlama = async (gpu: "auto" | false) =>
         await getLlama({
-          build: "autoAttempt",
+          // `never` = load a prebuilt binary only; never invoke cmake at query
+          // time. When the GPU auto-probe picks a backend whose prebuilt binary
+          // is incompatible with the host (e.g. the `code` LXC has libvulkan.so.1
+          // but no GPU device and no glslc), `autoAttempt` would compile
+          // llama.cpp from source per-GPU — a 30-60s+ blocking stall that then
+          // fails for lack of glslc and leaves a half-built localBuilds/ dir,
+          // hanging interactive `qmd query`. `never` instead falls straight
+          // through the prebuilt candidate list (Vulkan -> CUDA -> CPU) and lands
+          // on the prebuilt CPU binary. node-llama-cpp ships prebuilts for every
+          // platform we deploy on, so the source-build fallback is dead weight.
+          // Completes i-c28wngnd (which only covered the QMD_EMBED_ENDPOINT=cpu
+          // path) for the interactive / gpu:"auto" path. (i-tgac7ig3)
+          build: "never",
           logLevel: LlamaLogLevel.error,
           gpu,
         });