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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ from version 5.0.0 onward. Pre-fork releases (`1.x`–`4.2.0`) were authored by
as Prometheus text; they now arrive in the JSON payload.

### Changed
- **Upgraded the pinned llama.cpp from b10679 to b10682.** No project-source change, and the range
cannot require one: the whole delta is ten files (575 insertions / 59 deletions, 53 KB) confined to
`ggml/src/` backend implementations — Metal flash-attention vec tunings for M1 Max
([ggml-org/llama.cpp#27932](https://github.com/ggml-org/llama.cpp/pull/27932)) and a Vulkan
`mul_mat_id` change that pads K rather than N
([ggml-org/llama.cpp#27925](https://github.com/ggml-org/llama.cpp/pull/27925)) — plus the Snapdragon
Windows SDK scripts ([ggml-org/llama.cpp#27903](https://github.com/ggml-org/llama.cpp/pull/27903)),
documentation, and one upstream test that this project never compiles. Nothing under `common/`,
`include/`, `tools/server/`, `tools/mtmd/` or `ggml/include/` moved, and the 42 files the eight
local patches touch have an empty intersection with the changed-file list, so all eight apply
unchanged. The Metal and Vulkan classifier artifacts pick the backend work up by rebuilding.
- **Deprecated `InferenceParameters.withTfsZ`, `withPenalizeNl` and both `withPenaltyPrompt` overloads.**
`tfs_z`, `penalize_nl` and `penalty_prompt` appear nowhere in upstream `common/` or `tools/server/`
at the pinned build, and the request schema discards unknown fields rather than rejecting them — so
Expand Down
8 changes: 4 additions & 4 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: **b10679**
Current llama.cpp pinned version: **b10682**

## Upgrading CUDA Version

Expand Down Expand Up @@ -490,7 +490,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 b10679 https://github.com/ggml-org/llama.cpp /tmp/lc
git clone --depth 1 --branch b10682 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 @@ -530,7 +530,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 b10679`), the
Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b10682`), 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 @@ -1451,7 +1451,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 b10679`.
llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b10682`.

**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 @@ -11,7 +11,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 b10679](https://img.shields.io/badge/llama.cpp-%23b10679-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b10679)
[![llama.cpp b10682](https://img.shields.io/badge/llama.cpp-%23b10682-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b10682)
[![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
2 changes: 2 additions & 0 deletions docs/history/llama-cpp-breaking-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -683,3 +683,5 @@ Used during `llama.cpp` version bumps: when upgrading, scan this file from the r
| b10644–b10649 | upstream verification (sandbox, target) | **Full local verification on the shipped tree.** Fresh `cmake -B build-b10649 -DBUILD_TESTING=ON` through the real `FetchContent` path: all **8** patches applied (stamp `head 2bb9bddafad44ecbb50889644ca47537ec11841b`), which was the first thing checked because six patch-target files changed in the range. The first build failed loud with the four signature breaks above; after adapting the call sites, Release build clean, `ctest` **516/516** (512 at the bump; the second audit added four `TrainParams` cases), `nm -D` **40** `Java_*` exports and **zero** C++-mangled, `NativeLibraryLoadSmokeTest` **3/3, 0 skipped** including the pin cross-check against the linked `build-info`. `ModelParametersTest` 77/77 with the five CPU-offload cases plus the three video-flag cases. **Feature exposure decided deliberately, not by default:** of the 6 new flags, only `--n-cpu-ffn` is genuinely new upstream, and it was added as `ModelParameters.setCpuFfnLayers`; `setCpuMoeLayers` was added alongside it for `--n-cpu-moe`, which has existed upstream since **b6089** (#15077, `ec428b02c`) but had never been exposed here — b10649 only refactored its lambda onto the shared `llm_add_n_cpu_ffn_overrides` helper; the two `--spec-synth-*` flags were refused as upstream marks them "benchmarking only"; and the three `--video-*` flags were initially refused as inert without a `ContentPart` video factory. **That refusal was wrong and was reversed by the follow-up audit:** they are not inert — `server_context::load_model` copies them into its own `init_opt` when the projector loads, and that `init_opt` is what `server-context.cpp` hands to `process_mtmd_prompt` on the very task path this binding drives (`task.cli_files`), so they take effect for any attached media; and video decoding really is compiled in (`MTMD_VIDEO` defaults `ON`, gated only on `LLAMA_SUBPROCESS` which is also `ON`, and the shipped `libjllama.so` carries the ffmpeg invocation strings). They are now `ModelParameters.setVideoFps` / `setVideoTimestampInterval` / `setVideoFfmpegDir`; `setVideoFfmpegDir` matters most, since upstream otherwise resolves `ffmpeg`/`ffprobe` from `PATH`, which a JVM process frequently lacks. Only the ergonomic `ContentPart.videoFile(...)` entry point is still outstanding (raw bytes already work — the decoder sniffs the container rather than trusting the MIME type). The `--spec-synth-*` refusal stands. Both are recorded in `TODO.md` with their reasoning. |
| b10649–b10679 | `common/arg.cpp` (**purely additive: 2 new flags, 0 removed or renamed**), `common/common.h` (**additive**: `common_params::lazy_mode`, `common_params::kv_unified_per_slot`), `common/common.cpp` (one line: `mparams.lazy_mode = params.lazy_mode`), `include/llama.h` (**additive**: new `llama_lazy_mode` enum, `llama_model_params::lazy_mode`, `llama_model_quantize_params::max_buf_size`), `common/speculative.cpp` (implementation only — `speculative.h` byte-identical), `tools/server/server-context.cpp` (**#24124: per-slot context cap**; private `get_slot_n_ctx()` renamed to `n_ctx_slot()` and made a recomputing accessor), `tools/server/server.cpp` (**KV-pool auto-sizing block**), `tools/server/README.md`, plus `tools/ui/**` and backend internals (auto-followed / not compiled here) | **No project-source change; two features deliberately exposed.** The in-scope delta is **8 files, 172 insertions and 15 deletions** out of a 159-file, 8045-insertion range — the remainder is `tools/ui` (rebuilt from `GIT_TAG` by CI, no source review) and backends the project does not build. **The three mechanical contract checks are moot, not merely passed**: `server-schema.cpp`, `server-task.cpp`, `server-common.cpp` and *all twelve* `tools/server/*.h` headers are **byte-identical** across the range (verified by comparing blob SHAs), so no request field, bound or response key can have moved; `common/chat.h` and `tools/mtmd/mtmd-helper.h` are byte-identical too, so the `getMetrics()`-class silent-contract break and the `tts_engine.cpp` surface are both out of scope. `common/common.h` is the only priority-table file that changed, and only by the two additive fields above. **Two additive upstream features, both now exposed** (deliberate decision, not default): `--kv-unified-per-slot` → `ModelParameters.setKvUnifiedPerSlot(int)`, and `--tensor-read-lazy` → `ModelParameters.setTensorReadLazy(TensorReadLazyMode)` over the new `net.ladenthin.llama.args.TensorReadLazyMode` enum, which mirrors `llama_lazy_mode` (`off`/`auto`/`on` = 0/1/2). **Both really reach this binding**, which is why they were exposed rather than refused: `--tensor-read-lazy` has no `set_examples()` restriction and `common_model_params_to_llama` copies `lazy_mode` into `llama_model_params`, so it applies to a plain `LlamaModel` load; `--kv-unified-per-slot` is `set_examples({LLAMA_EXAMPLE_SERVER})` and `jllama.cpp` parses with `LLAMA_EXAMPLE_SERVER`, so it registers, and its **cap** half is applied inside `server-context.cpp`'s `n_ctx_slot()` (`server-context.cpp:4189`), whose value the project reads through `server_context_meta::slot_n_ctx` — it becomes every `slot.n_ctx` and is the context budget `format_prompt_infill` is given (`jllama.cpp:1547`), so lowering it really does change what this binding does. **Not** via `eval_llama_cmpl_schema`: that lost its `n_ctx_slot` parameter at b10275 and takes four arguments at b10679, and `repeat_last_n` / `dry_penalty_last_n` carry `set_hard_limits(0, INT32_MAX)` since b10273, so no sentinel expands to a context size any more. (The first draft of this row said otherwise; it was corrected by the b10679 audit.) Its **pool-sizing** half lives in `llama_server()` and therefore applies only to `NativeServer` full mode; the Javadoc says so explicitly rather than implying the flag is self-sufficient. `llama_model_quantize_params::max_buf_size` needs **no** adaptation: `LlamaQuantizer` builds its params from `llama_model_quantize_default_params()`, so the new field is initialised by upstream. The `get_slot_n_ctx()` → `n_ctx_slot()` rename is a **private** member of the impl and is not called by the project. **Three patch-target files were touched** (`common/arg.cpp`, `server-context.cpp`, `server.cpp`) and **all 8 patches still apply with zero fuzz**; patch `0007`'s standing invariant survives because the new KV-pool-sizing block in `llama_server()` sits *before* the extracted route table, not inside it. **Patch `0001` shrank 37 → 36 files**: upstream rewrote `tests/test-save-load-state.cpp`'s `main()` to strip `--models DIR` into its own `filtered_argv` and call `common_params_parse(fargc, filtered_argv.data(), ...)`. By that patch's own rule — *embedded callers that build their own argv must call `common_params_parse` directly* — that call site no longer wants the `_main()` flip, so the hunk was **dropped, not refreshed**. The patch itself is **still required**: `common_params_parse` at b10679 still carries the count-guarded `GetCommandLineW` override, and `common_params_parse_main` does not exist in `b10679:common/arg.h` — upstream has not adopted either direction proposed in [ggml-org/llama.cpp#26416](https://github.com/ggml-org/llama.cpp/issues/26416). |
| b10649–b10679 | upstream verification (sandbox, target) | **Full local verification on the shipped tree.** Fresh `cmake -B build-b10679 -DBUILD_TESTING=ON` through the real `FetchContent` path, so the fail-loud `PATCH_COMMAND` ran for real against b10679 — a fresh build directory was mandatory, since the applier pins its stamp to the checked-out llama.cpp commit and aborts rather than guess when an existing stamp names a different one. All **8** patches applied (`0001` in its 36-file form). Release build clean, `ctest` **520/520**. Java: `mvn clean test` **1474 run / 0 failures / 17 model-gated skips**, with `NativeLibraryLoadSmokeTest` **3/3 and 0 skipped** — including `nativeBuildInfoMatchesPinnedVersionConstant`, the end-to-end cross-check that `LlamaCppVersion.LLAMA_CPP_VERSION` ("b10679") matches the `build-info` compiled into the freshly linked `libjllama.so`, which is what proves the four pin sites and the actual build agree. `ModelParametersTest` covers both new setters (exact flag spellings, the `<= 0` rejection on `--kv-unified-per-slot`) and `TensorReadLazyModeTest` pins all three enum wire strings under the PIT-gated `net.ladenthin.llama.args.*` package. `mvn spotless:apply` produced no changes beyond the edits themselves. **One documentation defect was found and fixed during this verification** and is worth recording as a class: the first draft of `setKvUnifiedPerSlot`'s Javadoc stated the pool-sizing effect unconditionally. Reading `tools/server/server.cpp` showed that half executes only in `llama_server()`, which a `ModelParameters`-loaded model never enters — an accurate-for-upstream sentence that would have been wrong for the API it documents. |
| b10679–b10682 | `ggml/src/ggml-metal/ggml-metal-tuning.cpp` (**#27932: flash-attention vec tunings for M1 Max**), `ggml/src/ggml-vulkan/ggml-vulkan.cpp` + three `vulkan-shaders/*.comp` (**#27925: `mul_mat_id` pads K rather than N**), `scripts/snapdragon/{build,sdk,setup-sdk}.py` + `docs/backend/snapdragon/windows.md` (**#27903: Windows SDK setup**), `tests/test-backend-ops.cpp` | **No project-source change, and the range cannot require one.** Ten files, 575 insertions / 59 deletions, 53 KB of diff — well under the runbook's 100 KiB chunking threshold, so this was taken as a single step. **Not one changed file is on the priority review list**: the delta is confined to `ggml/src/` backend implementations (Metal tuning tables, Vulkan matmul shaders), the Snapdragon build scripts (never compiled here), documentation, and an upstream test (`LLAMA_BUILD_TESTS` is OFF for a FetchContent subproject). Nothing under `common/`, `include/`, `tools/server/`, `tools/mtmd/` or `ggml/include/` moved, so the request-field set, its bounds, the emitted response keys, the `getMetrics()` class of silent contract break and the whole `mtmd_helper::gen_audio` surface are all provably out of scope rather than merely checked. The two ggml changes are backend-internal: neither `ggml_type` nor any `ggml-backend.h` type is touched, so the Metal and Vulkan classifier artifacts pick the work up by rebuilding, with no wiring change. |
| b10679–b10682 | patches + upstream verification | **Zero intersection with the patch set, established mechanically rather than by re-running the applier and hoping.** The 42 files the eight patches touch were intersected against the range's changed-file list: empty. No patch context can therefore have moved, and `0001` stays at its 37-file form. Confirmed by a real build: fresh `cmake -B build-b10682 -DBUILD_TESTING=ON` through the FetchContent `PATCH_COMMAND`, which is fail-loud and pins its stamp to the checked-out commit — a fresh build directory is mandatory for exactly that reason. Configure reported `ggml commit: 5ea1b124e`, Release build clean, **`ctest` 520/520**, Java **1476 run / 0 failures / 17 model-gated skips**, `NativeLibraryLoadSmokeTest` **4/4 with 0 skipped** — including the pin cross-check against the freshly linked `libjllama.so`. `mvn spotless:apply` produced no changes. **One diagnostic defect surfaced during this verification and was fixed.** The first (incremental) run of that cross-check failed with *"Linked build-info `b10682-5ea1b124e` must start with the pinned tag `b10679-`"* even though every pin site already read b10682. Cause: `LLAMA_CPP_VERSION` is a `static final String`, i.e. a **compile-time constant that javac inlines into every referencing class** — including the test itself. An incremental build recompiles the constant but not the test class, whose own source did not change, so the stale literal survived in its constant pool (verified with `strings` on the `.class`: the test bytecode was from the previous build and still carried `b10679-`). A `clean` build is green. The assertion message named only the drift cause, i.e. the one that did **not** apply, so it now names both and tells the reader which is which. CI cannot hit this — it always builds from a clean checkout. |
2 changes: 1 addition & 1 deletion llama/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ set(LLAMA_BUILD_APP OFF CACHE BOOL "" FORCE)
FetchContent_Declare(
llama.cpp
GIT_REPOSITORY https://github.com/ggerganov/llama.cpp.git
GIT_TAG b10679
GIT_TAG b10682
PATCH_COMMAND ${CMAKE_COMMAND}
-DPATCH_DIR=${CMAKE_CURRENT_SOURCE_DIR}/patches
-DLLAMA_SRC=<SOURCE_DIR>
Expand Down
10 changes: 5 additions & 5 deletions llama/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ SPDX-License-Identifier: MIT
<jspecify.version>1.0.1</jspecify.version>
<lombok.version>1.18.46</lombok.version>
<errorprone.version>2.50.0</errorprone.version>
<nullaway.version>0.13.8</nullaway.version>
<nullaway.version>0.14.0</nullaway.version>
<checker.version>4.2.2</checker.version>
<jackson.version>2.22.2</jackson.version>
<reactor.version>3.8.7</reactor.version>
Expand All @@ -70,7 +70,7 @@ SPDX-License-Identifier: MIT
<jmh.version>1.37</jmh.version>
<jcstress.version>0.16</jcstress.version>
<lincheck.version>3.7</lincheck.version>
<logcaptor.version>2.12.6</logcaptor.version>
<logcaptor.version>2.12.7</logcaptor.version>
<!-- log4j-api / log4j-to-slf4j arrive ONLY as test-scope transitives of
io.github.hakky54:logcaptor, which requests 2.25.3. That version is affected by
CVE-2026-49844 (GHSA-qv9r-c865-cp47, moderate): MapMessage.asJson() emits bare
Expand All @@ -90,8 +90,8 @@ SPDX-License-Identifier: MIT
<spotbugs.version>4.10.4.0</spotbugs.version>
<fb-contrib.version>7.7.4</fb-contrib.version>
<findsecbugs.version>1.14.0</findsecbugs.version>
<spotless.version>3.10.0</spotless.version>
<palantir-java-format.version>2.96.0</palantir-java-format.version>
<spotless.version>3.10.1</spotless.version>
<palantir-java-format.version>2.97.0</palantir-java-format.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputTimestamp>2026-07-07T07:32:17Z</project.build.outputTimestamp>
</properties>
Expand Down Expand Up @@ -375,7 +375,7 @@ SPDX-License-Identifier: MIT
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.25.9</version>
<version>1.30.0</version>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
Expand Down
Loading
Loading