Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Java bindings for [llama.cpp](https://github.com/ggerganov/llama.cpp) via JNI, providing a high-level API for LLM inference in Java. The Java layer communicates with a native C++ library through JNI.

Current llama.cpp pinned version: **b9990**
Current llama.cpp pinned version: **b10015**

## Upgrading CUDA Version

Expand Down Expand Up @@ -421,7 +421,7 @@ needs no extra step here, `build-webui` re-reads the tag and rebuilds the matchi
ships no UI):
```bash
# needs node/npm + network; embed.cpp is plain C++17 (no npm)
git clone --depth 1 --branch b9990 https://github.com/ggml-org/llama.cpp /tmp/lc
git clone --depth 1 --branch b10015 https://github.com/ggml-org/llama.cpp /tmp/lc
( cd /tmp/lc/tools/ui && npm ci && npm run build \
&& ( cd dist && find . -type f -not -path './_gzip/*' \
| while read -r f; do mkdir -p "_gzip/$(dirname "$f")"; gzip -9 -c "$f" > "_gzip/$f"; done ) \
Expand Down Expand Up @@ -461,7 +461,7 @@ cache lives in **Depot Cache** over sccache's **WebDAV** backend:
- `SCCACHE_WEBDAV_TOKEN: ${{ secrets.DEPOT_TOKEN }}` — a Depot **organization** token, stored
as the repo secret **`DEPOT_TOKEN`**.

Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b9990`), the
Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b10015`), the
~280 upstream object files are byte-identical every run, so a warm cache recompiles only the
*changed* files. Depot's cache is **shared across all branches** (unlike GitHub's
per-branch `actions/cache`), so every branch builds incrementally; a `b<nnnn>` version bump
Expand Down Expand Up @@ -572,7 +572,7 @@ Current patches:
| `0001-win32-arg-parse-embed-guard.patch` | Windows JNI regression from llama.cpp **#24779** (introduced b9739): on Windows `common_params_parse` re-derived argv from the **process** command line (`GetCommandLineW`) and adopted it, so an embedded/JNI caller (`java.exe`) lost its `--model …` args → "Failed to parse model parameters". b9789 narrowed the unconditional override to a **count-guard** (`if (static_cast<int>(utf8.buf.size()) == argc) { argv = utf8.ptrs.data(); }`), but that is exactly the variant the project already found breaks its Windows server-integration tests (when the embedded argv length coincides with `java.exe`'s). The patch carries the **complete upstream change** (so it can be submitted to llama.cpp verbatim and then dropped here): **(1)** `common_params_parse` parses **exactly the argv it is given** (no `GetCommandLineW` magic) and a new `common_params_parse_main()` wrapper holds the UTF-8 recovery for the standalone tools' `main()` (`common/arg.{cpp,h}`); **(2)** the **~34 standalone `main()` call sites** (every `common_params_parse(argc, argv, …)` across `tools/*`, `examples/*` and the `tests/*` programs) flip to `common_params_parse_main()`; **(3)** a `tests/test-arg-parser.cpp` regression case pins that `common_params_parse` honors a caller-supplied argv. The embedded caller (`jllama.cpp`) keeps calling `common_params_parse` and is never overridden. **Our subproject build compiles only the `arg.{cpp,h}` core** — `LLAMA_BUILD_TOOLS`/`LLAMA_BUILD_TESTS` are OFF for a FetchContent subproject — so the flips + test are applied-but-not-compiled here; they were validated via a one-off `-DLLAMA_BUILD_TOOLS=ON -DLLAMA_BUILD_TESTS=ON` build (the new test compiles and its asserts pass; `test-arg-parser`'s only red there is the live `ggml.ai` download check, which is sandbox-network, not the patch). Because it spans **37 files** it must be refreshed on every llama.cpp bump (the applier fails loud). |
| `0002-server-preserve-caller-load-progress-callback.patch` | Load-progress-callback regression introduced in llama.cpp **b9789**: `server_context::load_model` (`tools/server/server-context.cpp`) now **unconditionally** installs the server's own load-progress reporter on `params_base.load_progress_callback` immediately before `common_init_from_params`, clobbering any callback the embedding caller already set. libjllama's `LoadProgressCallback` feature wires `common_params.load_progress_callback` to a JNI trampoline *before* calling `load_model`, so the bump silently killed it — `LoadProgressCallbackTest` saw zero progress updates and the abort-on-`false` path never threw. The patch guards the assignment with `if (params_base.load_progress_callback == nullptr)`, so the server installs its own reporter **only when the caller hasn't** — a caller-supplied callback survives and fires during load. Standalone `llama-server` (no caller callback, so the field is null) is unaffected. Same JNI-vs-standalone divergence class as `0001`. |
| `0003-pr22393-server-add-slot-prompt-similarity-getter-setter.patch` | **Upstream-PR carry** of [ggml-org/llama.cpp#22393](https://github.com/ggml-org/llama.cpp/pull/22393) ("server : add slot_prompt_similarity getter/setter") while it is still open upstream. Purely additive: adds `server_context::get_slot_prompt_similarity()` / `set_slot_prompt_similarity(float)` (`tools/server/server-context.{cpp,h}`) so an embedding/JNI caller can query and tune the slot-selection threshold at runtime without reloading the model. Verbatim copy of the PR — drop it once a pinned `b<nnnn>` includes the change. |
| `0007-server-attach-http-frontend.patch` | **Adds `llama_server_attach(argc, argv, server_context&)`** so the `NativeServer` *attach mode* can serve an **already-loaded `LlamaModel`** over the full upstream HTTP frontend — no second model load, no `start_loop()`; the LlamaModel's worker keeps driving the shared `server_context` and the HTTP routes post tasks to its queue (the queue is the synchronization point). Mechanically: (1) extracts the common route table + CORS-proxy/tools blocks out of `llama_server()` into `llama_server_register_common_routes(...)` (shared verbatim, so the entry points cannot drift; returns `false` on tools-setup failure); (2) adds `llama_server_attach`, which parses only the HTTP-side argv via `common_params_parse`, starts `g_stream_sessions` GC + `server_http_context`, registers the common routes plus the non-router resumable-streaming handlers, marks ready immediately (model already loaded), and blocks on the HTTP thread until `llama_server_request_shutdown()` — never calling `common_init()`, backend init, `ctx_server.terminate()` or `llama_backend_free()` (the embedding caller owns those). Applies after `0001`+`0006` (same file); closes the "NativeServer — reuse an already-loaded LlamaModel" TODO. Upstream-submittable ("server: let embedding callers attach the HTTP frontend to an existing server_context"). |
| `0007-server-attach-http-frontend.patch` | **Adds `llama_server_attach(argc, argv, server_context&)`** so the `NativeServer` *attach mode* can serve an **already-loaded `LlamaModel`** over the full upstream HTTP frontend — no second model load, no `start_loop()`; the LlamaModel's worker keeps driving the shared `server_context` and the HTTP routes post tasks to its queue (the queue is the synchronization point). Mechanically: (1) extracts the common route table + the CORS-proxy/tools **route bindings** out of `llama_server()` into `llama_server_register_common_routes(...)` (shared, so the entry points cannot drift; returns `false` on tools-setup failure) — the per-caller **experimental-feature warnings** (upstream's b10015/#25655 `cors_origins` security warning + the router/MCP/tools `warn_names` block) stay in `llama_server` since they depend on router state the shared helper does not carry; (2) adds `llama_server_attach`, which parses only the HTTP-side argv via `common_params_parse`, starts `g_stream_sessions` GC + `server_http_context`, registers the common routes plus the non-router resumable-streaming handlers, marks ready immediately (model already loaded), and blocks on the HTTP thread until `llama_server_request_shutdown()` — never calling `common_init()`, backend init, `ctx_server.terminate()` or `llama_backend_free()` (the embedding caller owns those). Applies after `0001`+`0006` (same file); closes the "NativeServer — reuse an already-loaded LlamaModel" TODO. Upstream-submittable ("server: let embedding callers attach the HTTP frontend to an existing server_context"). |
| `0008-server-models-worker-cmd-override.patch` | **Makes router mode usable in-JVM.** The router (`server-models.cpp`) spawns each model worker by re-executing its own binary (`get_server_exec_path()` = `/proc/self/exe` & friends) — inside a JVM that binary is `java`, not a llama-server, so embedded router workers could never start. The patch adds env `LLAMA_SERVER_WORKER_CMD` (whitespace-split; read in `server_model_meta::update_args`) which replaces only the leading binary-path token of the rendered worker args, letting an embedding host relaunch workers through its own bootstrap — e.g. `java -cp app.jar net.ladenthin.llama.server.NativeServer` (each worker is then a fresh JVM running the classic single-model `NativeServer`). Exposed in Java as `NativeServer.setWorkerCommand(String...)` (JNI `setenv`); exercised by `RouterModeIntegrationTest` (Linux CI). Upstream-submittable (also useful for containerized/wrapped deployments). |
| `0006-server-embed-native-server-jni.patch` | **Makes `server.cpp`'s `llama_server` embeddable in the JVM** so the `NativeServer` JNI bridge can run the full upstream HTTP server (WebUI included) inside `libjllama` — see "Two server modes" below. b9870 already exposes `int llama_server(int, char**)` (non-static; no `main` in the file), so the patch only adds embedded-mode support: (1) a `g_llama_server_embedded` flag + `llama_server_set_embedded()` / `llama_server_request_shutdown()` (declared in the committed `src/main/cpp/native_server_bridge.h`); (2) skips installing the process-wide SIGINT/SIGTERM handlers when embedded (they would hijack the JVM's); (3) in embedded mode parses the **forwarded** argv via `common_params_parse` instead of `common_params_parse_main` (whose `GetCommandLineW` recovery would pick up `java.exe`'s command line — the same Windows class of bug `0001` fixes). `llama_server_request_shutdown()` mirrors the SIGTERM path (invokes the installed `shutdown_handler` → `ctx_server.terminate()` unblocks `start_loop()`), giving JNI an out-of-band stop since `ctx_server` is loop-local. Applies **after `0001`** (which flips this call site to `common_params_parse_main`), so its context is the post-`0001` tree; regenerate against `0001`+source on a bump. Only touches `tools/server/server.cpp`. |

Expand Down Expand Up @@ -1254,7 +1254,7 @@ ctest --test-dir build --output-on-failure -R "ResultsToJson"

#### Upstream source location (in CMake build tree)

llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b9990`.
llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b10015`.

**GoogleTest** is a separate `BUILD_TESTING`-only FetchContent (`GIT_TAG v1.17.0`), used solely
by the `jllama_test` C++ unit-test binary — not by the shipped library, and not coupled to the
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
**Build:**
![Java 8+](https://img.shields.io/badge/Java-8%2B-informational)
![Platform](https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows%20%7C%20Android-lightgrey)
[![llama.cpp b9990](https://img.shields.io/badge/llama.cpp-%23b9990-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b9990)
[![llama.cpp b10015](https://img.shields.io/badge/llama.cpp-%23b10015-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b10015)
[![JPMS](https://img.shields.io/badge/JPMS-modular%20JAR-25A162)](https://openjdk.org/projects/jigsaw/)
![JUnit](https://img.shields.io/badge/tested%20with-JUnit6-25A162)
[![JSpecify](https://img.shields.io/badge/JSpecify-1.0.0%20%40NullMarked-25A162)](https://jspecify.dev)
Expand Down
4 changes: 4 additions & 0 deletions docs/history/llama-cpp-breaking-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,3 +491,7 @@ Used during `llama.cpp` version bumps: when upgrading, scan this file from the r
| b9982–b9984 | upstream verification (sandbox) | All **six** patches (`0001`–`0003`, `0006`–`0008`) re-verified against b9984: applied in filename order onto a clean b9984 checkout via a fresh `cmake -B build` (fail-loud `PATCH_COMMAND`), all clean. No OuteTTS generator anchor touched (`tools/tts/tts.cpp` unchanged — the generator extracted `tts.cpp @ b9984`). Full local verification: fresh configure (fail-loud patch apply + TTS extraction succeeded, `ggml commit e474bba7a`) + full `cmake --build` (`jllama` + `jllama_test` link cleanly) + `ctest` **485/485 passing**; per-platform confirmation by the CI pipeline. |
| b9984–b9986 | `common/{chat-auto-parser-generator.cpp,chat-diff-analyzer.cpp}` + `ggml/src/ggml-sycl/{backend.hpp,common.hpp,ggml-sycl.cpp,topk-moe.{cpp,hpp}}` + `tests/test-chat.cpp` | **Additive/tuning-only, no public-API surface (9 files, ~32 KiB excluding the auto-followed `tools/ui` WebUI rework, 2 commits).** `chat-auto-parser-generator.cpp`/`chat-diff-analyzer.cpp` fix a whitespace-trimming and preserved-tokens bug in the NVIDIA-Nemotron-Nano-v2 auto-parser profile (`reasoning.start` trimmed before use; `tools_array_wrapped` flag added; a stale `<SPECIAL_12>` preserved-token entry dropped) — neither file is a patch target or in the priority-8 header list, and this project links `chat.cpp`/`chat.h` (unchanged) rather than these newer split-out analyzer files directly, but they compile into the same upstream-compiled `llama-common` static lib either way. `tests/test-chat.cpp` gains matching regression cases for the fixed template output (not a patch target). `ggml/src/ggml-sycl/*` gains new top-k MoE (mixture-of-experts) kernels — entirely inside the SYCL backend's upstream-compiled TUs (this project's SYCL classifiers are build-only, no source touched). No `common/arg.*`, `tools/server/*`, or OuteTTS generator anchor (`tools/tts/tts.cpp` unchanged) touched; all eight priority-8 headers byte-identical. All **six** remaining patches (`0001`–`0003`, `0006`–`0008`) apply unchanged — confirmed via the upstream `b9984...b9986` compare diff. This chunk reaches the latest release at the time of the bump (b9986). |
| b9984–b9986 | upstream verification (sandbox) | All **six** patches (`0001`–`0003`, `0006`–`0008`) re-verified against b9986: applied in filename order onto a clean b9986 checkout via a fresh `cmake -B build` (fail-loud `PATCH_COMMAND`), all clean. No OuteTTS generator anchor touched (`tools/tts/tts.cpp` unchanged — the generator extracted `tts.cpp @ b9986`). Full local verification: fresh configure (fail-loud patch apply + TTS extraction succeeded, `ggml commit 91c631b21`) + full `cmake --build` (`jllama` + `jllama_test` link cleanly) + `ctest` **485/485 passing**; per-platform confirmation by the CI pipeline. |
| b9986–b9990 | `ggml/{include/gguf.h,src/gguf.cpp}` + `src/models/minimax-m2.cpp` + `tests/**` | **Additive-only, no public-API surface (8 files, ~2 KiB excluding the auto-followed `tools/ui` WebUI + upstream `README.md`, 4 commits).** `ggml/{include/gguf.h,src/gguf.cpp}` add a GGUF **tensor-shape accessor** (#24405) — purely additive API on the GGUF reader; `ggml/include/gguf.h` is not in the priority-8 review list and no existing signature changed. `src/models/minimax-m2.cpp` adds Minimax2 eagle3 speculative-decoding support (a model TU inside the upstream-compiled `llama` lib). `tests/**` (`test-alloc`/`test-backend-ops`/`test-gguf` header harmonization + a shape-accessor case) are upstream tools, not compiled or shipped here. No `common/arg.*`, `tools/server/*`, or OuteTTS generator anchor (`tools/tts/tts.cpp` unchanged) touched; all eight priority-8 headers byte-identical. All **six** patches (`0001`–`0003`, `0006`–`0008`) apply unchanged. |
| b9986–b9990 | upstream verification (compare diff) | All **six** patches (`0001`–`0003`, `0006`–`0008`) apply unchanged against b9990: the `b9986...b9990` compare diff touches no patch-target file (`common/arg.*`, `tools/server/*`) and no OuteTTS generator anchor (`tools/tts/tts.cpp` unchanged), and all eight priority-8 headers are byte-identical. b9990 was this session's starting pin (landed via PR #341) and configures/builds cleanly as the base from which the b9990→b10015 bump proceeded; the full local `cmake --build` + `ctest` **485/485** was run at b10015 (the rows below), not separately at b9990. Per-platform confirmation by the CI pipeline. (Backfilled — the b9986→b9990 bump omitted its history rows when it landed.) |
| b9990–b10015 | `common/{arg.cpp,common.h}` + `tools/server/{server.cpp,server-context.cpp,server-http.cpp,server-task.{cpp,h}}` + `ggml/src/{ggml-cpu/kleidiai/**,ggml-cuda/mmq*,ggml-metal/**,ggml-sycl/**,ggml-vulkan/**,ggml-opencl/**,ggml-hexagon/**}` + `src/{llama-arch.{cpp,h},llama-model.cpp,models/hy-v3.cpp}` + `tests/**` | **Additive + one patch-target restructure (85 files, ~7.7k insertions excluding the auto-followed `tools/ui` WebUI, 25 commits — the first 5-digit `b1nnnn` build number).** Priority-8 headers: `common/common.h` is **additive-only** (new `LLAMA_EXAMPLE_TOKENIZE` enumerator + `cors_*` server params for #25655 + `tokenize_*` params for #25516 — no field removed/renamed); `common/arg.cpp` gains the `--cors-*` options (#25655), the tokenize-CLI common-args alignment (#25516) and a one-line `common_log_flush(common_log_main())` before `exit(0)` (#25504) — all **outside** patch `0001`'s `common_params_parse`/`common_params_parse_main` region, so `0001` applies unchanged. **One patch-target restructure — `0007` REFRESHED:** upstream #25655 ("server: add --cors-* options") rewrote the CORS-proxy/tools warning region of `tools/server/server.cpp` that `0007`'s deletion hunk relocated (introducing a `warn_names` vector, an `is_router_server` branch and a new `cors_origins=='*'` security warning), so `0007` no longer applied. It was refreshed so `llama_server_register_common_routes()` now extracts only the **route bindings** (health…slots + GCP + `res_403` + CORS-proxy + tools setup), while the per-caller **experimental-feature warnings** (incl. upstream's new `cors_origins` warning) stay in `llama_server()` — they depend on router state the shared helper does not carry, and keeping them there preserves #25655 with no upstream-warning regression. **#25649 ("server: refactor prompt cache state ownership")** rewrote `server-context.cpp`'s `server_slot`/private-method regions — a different region than patch `0002`'s `load_model` load-progress-callback guard and `0003`'s `get/set_slot_prompt_similarity` getters (both untouched), so `0002`/`0003` apply unchanged. `server-http.cpp` (CORS-header plumbing) and `server-task.{cpp,h}` (prompt-cache-state fields) are not patch targets. The remaining ggml backend churn (kleidiai SME2 f32, CUDA MMQ config refactor, Metal Q2_0, SYCL Battlemage, Vulkan native mxfp4/nvfp4, OpenCL OOB/dp4a fixes, Hexagon) + new Hunyuan Hy3 (`hy_v3`) model support are inside upstream-compiled TUs. b10015 is the topmost release at bump time; the `b[0-9]+` bump tooling and the manual's `b<nnnn>` placeholder are digit-agnostic and handled the 4→5-digit crossover unchanged. |
| b9990–b10015 | upstream verification (sandbox) | **Six** patches re-verified against b10015 via a fresh `cmake -B build` (fail-loud `PATCH_COMMAND`): `0001`–`0003`, `0006`, `0008` apply **unchanged**; `0007` was **refreshed** for upstream #25655's CORS restructure (route bindings extracted to the shared helper, per-caller warnings kept in `llama_server()` — see the row above) and now applies clean. No OuteTTS generator anchor touched (`tools/tts/tts.cpp` unchanged — the generator extracted `tts.cpp @ b10015`). Full local verification: fresh configure (fail-loud patch apply + TTS extraction succeeded, `ggml commit 12127defd`) + full `cmake --build` (`jllama` + `jllama_test` link cleanly, confirming the refreshed `0007` `server.cpp` restructure compiles) + `ctest` **485/485 passing**; per-platform confirmation by the CI pipeline. |
Loading
Loading