diff --git a/.github/build.sh b/.github/build.sh index 0ea4ba4b8..13b4f179b 100755 --- a/.github/build.sh +++ b/.github/build.sh @@ -194,3 +194,14 @@ if [ -n "$LAUNCH" ] && command -v sccache >/dev/null 2>&1; then fi fi fi + +# macOS: put the minimum OS each built dylib was linked for into the log. It is set by +# CMAKE_OSX_DEPLOYMENT_TARGET (llama/CMakeLists.txt, default 15.0); without it the linker takes the +# build host's own version, so moving a job to a newer runner image would silently raise the floor +# for every user. smoke-native-macos.sh checks the shipped dylib; this line only reports. +if [ "$(uname -s)" = "Darwin" ]; then + find src/main/natives -name 'libjllama.dylib' -print0 | while IFS= read -r -d '' lib; do + echo "== ${lib}: LC_BUILD_VERSION (minos = the oldest macOS it loads on) ==" + otool -l "$lib" | grep -A4 LC_BUILD_VERSION || echo "(no LC_BUILD_VERSION load command found)" + done +fi diff --git a/.github/smoke-native-macos.sh b/.github/smoke-native-macos.sh index 0d78c3eeb..f9dc46060 100755 --- a/.github/smoke-native-macos.sh +++ b/.github/smoke-native-macos.sh @@ -59,6 +59,23 @@ unzip -o -q "$JAR" "$DYLIB_ENTRY" -d "$WORK" \ DYLIB="$WORK/$DYLIB_ENTRY" echo "extracted: $(cd "$(dirname "$DYLIB")" && pwd)/$(basename "$DYLIB") ($(wc -c < "$DYLIB") bytes)" +# 0) The oldest macOS it loads on. CMAKE_OSX_DEPLOYMENT_TARGET (llama/CMakeLists.txt) pins it; +# without that pin the linker takes the build host's own version, so a build job moved to a +# newer runner image would ship a library newer macOS releases alone can load -- and nothing +# else in the pipeline would notice, since every test runs on that same newer image. +MAX_MINOS="${JLLAMA_MAX_MINOS:-15.0}" +echo "== LC_BUILD_VERSION (minos must be <= $MAX_MINOS) ==" +otool -l "$DYLIB" | grep -A4 LC_BUILD_VERSION \ + || fail "no LC_BUILD_VERSION load command in the dylib -- cannot tell which macOS it needs" +MINOS="$(otool -l "$DYLIB" | awk '/cmd LC_BUILD_VERSION/{f=1} f && $1=="minos"{print $2; exit}')" +[ -n "$MINOS" ] || fail "could not read minos from the dylib's LC_BUILD_VERSION" +awk -v have="$MINOS" -v max="$MAX_MINOS" 'BEGIN { + split(have, h, "."); split(max, m, ".") + for (i = 1; i <= 3; i++) { if (h[i] + 0 != m[i] + 0) exit (h[i] + 0 > m[i] + 0) } + exit 0 +}' || fail "the dylib needs macOS $MINOS, but macOS $MAX_MINOS is the supported floor (CMAKE_OSX_DEPLOYMENT_TARGET in llama/CMakeLists.txt)" +echo "minos $MINOS <= $MAX_MINOS: ok" + # 1) Signature vs. content. `--strict` re-hashes the code pages and compares them against the # signature's stored hashes, so a dylib assembled from two different builds fails here with the # exact page mismatch — the direct check for the shipped corruption. An ad-hoc signature (what diff --git a/.github/workflows/java-tests.yml b/.github/workflows/java-tests.yml index 2267a31e5..c3fd7ed79 100644 --- a/.github/workflows/java-tests.yml +++ b/.github/workflows/java-tests.yml @@ -16,7 +16,7 @@ on: workflow_call: inputs: runs-on: - description: The runner label (macos-14, macos-15, windows-2025-vs2026, ...). + description: The runner label (macos-15, macos-26, windows-2025-vs2026, ...). type: string required: true natives-artifact: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6ad4e21dc..f7d17e99b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1344,9 +1344,9 @@ jobs: path: ${{ github.workspace }}/llama/src/main/natives/net/ladenthin/llama/ build-macos-arm64-metal: - name: Build and Test macOS 14 arm64 (Metal) + name: Build and Test macOS 26 arm64 (Metal) needs: [startgate, build-webui] - runs-on: macos-14 + runs-on: macos-26 env: BUILD_JOBS: 2 SCCACHE_WEBDAV_TOKEN: ${{ secrets.DEPOT_TOKEN }} @@ -1378,7 +1378,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@v7 with: - name: macos-14-metal + name: macos-26-metal path: ${{ github.workspace }}/llama/src/main/natives/net/ladenthin/llama/ build-windows-x86_64-msvc: @@ -2377,14 +2377,14 @@ jobs: # called with the native build under test. The ids, names and needs stay here, so `package`, # the release gate and every reader of this file see the same jobs as before. test-java-macos-arm64-metal: - name: Java Tests macOS 14 arm64 (Metal) + name: Java Tests macOS 26 arm64 (Metal) needs: [build-macos-arm64-metal, verify-model-cache] uses: ./.github/workflows/java-tests.yml with: - runs-on: macos-14 - natives-artifact: macos-14-metal + runs-on: macos-26 + natives-artifact: macos-26-metal maven-args: -Dnet.ladenthin.llama.test.ngl=0 - error-artifact: error-log-macos-14-metal + error-artifact: error-log-macos-26-metal test-java-macos-arm64-no-metal: name: Java Tests macOS 15 arm64 (no Metal) @@ -2474,7 +2474,7 @@ jobs: # holds exactly the /// directory its name promises and that no path is # claimed twice, then merges. `merge-multiple: true` would silently overwrite -- and can # byte-level interleave -- two artifacts with the same path, which is how a corrupt macOS - # dylib shipped; the test-only macOS builds (macos-14-metal, macos-15-no-metal) are named + # dylib shipped; the test-only macOS builds (macos-26-metal, macos-15-no-metal) are named # outside the glob for that reason. - uses: actions/download-artifact@v8 with: @@ -2817,7 +2817,7 @@ jobs: # holds exactly the /// directory its name promises and that no path is # claimed twice, then merges. `merge-multiple: true` would silently overwrite -- and can # byte-level interleave -- two artifacts with the same path, which is how a corrupt macOS - # dylib shipped; the test-only macOS builds (macos-14-metal, macos-15-no-metal) are named + # dylib shipped; the test-only macOS builds (macos-26-metal, macos-15-no-metal) are named # outside the glob for that reason. - uses: actions/download-artifact@v8 with: @@ -3022,7 +3022,7 @@ jobs: # holds exactly the /// directory its name promises and that no path is # claimed twice, then merges. `merge-multiple: true` would silently overwrite -- and can # byte-level interleave -- two artifacts with the same path, which is how a corrupt macOS - # dylib shipped; the test-only macOS builds (macos-14-metal, macos-15-no-metal) are named + # dylib shipped; the test-only macOS builds (macos-26-metal, macos-15-no-metal) are named # outside the glob for that reason. - uses: actions/download-artifact@v8 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index ba21ddd5a..d77694129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,7 +45,16 @@ from version 5.0.0 onward. Pre-fork releases (`1.x`–`4.2.0`) were authored by core's; `check-natives.py` fails when they differ. ### Changed -- **Upgraded the pinned llama.cpp from b11320 to b11462**, in 23 reviewed steps, each ending at a tag. +- **The macOS library now names macOS 15.0 as its minimum, explicitly.** Nothing set a deployment + target before, so `libjllama.dylib` required whatever macOS the build runner had; moving a build + job to a newer image would have dropped the older release unnoticed. `CMAKE_OSX_DEPLOYMENT_TARGET` + is now `15.0`, every macOS build logs the dylib's `minos`, and the macOS smoke fails a shipped + library above 15.0. +- **CI: the host-native macOS Metal build and its Java tests moved from `macos-14` to `macos-26`.** + GitHub retires the `macos-14` image by 2026-11-02 and fails every `macos-14` job during its October + brownouts. The label is pinned rather than `macos-latest`, and it is not `macos-15`, which the + shipped Metal build and the no-Metal build already run on. +- **Upgraded the pinned llama.cpp from b11320 to b11474**, in 24 reviewed steps, each ending at a tag. Every carried patch that broke was traced to the one upstream commit that broke it, and the step containing that commit ends at the first tag after it: `0007` at #29818 (b11361) and #29895 (b11401), `0014` at #29895, `0008` at #29987 (the commit just before b11429), `0015` at #26610 (b11450). Each refresh moved context only, @@ -160,6 +169,16 @@ from version 5.0.0 onward. Pre-fork releases (`1.x`–`4.2.0`) were authored by 4.4.7 (none of the files the agent's carried JLine fixes touch changed between 4.4.6 and 4.4.7). ### Fixed +- **`SessionConcurrencyTest` timed out on `Java Tests macOS 15 arm64 (Metal)` from llama.cpp b11457 on** + (green through b11320, red in both runs since). Only this class slowed down -- about 130x, from + 0.45 s to 57-110 s per token, while every other class ran as fast as before. It is the one test + that loads the 7B model with a 4096-token context onto the GPU without `--fit`, so the weights + (~2.7 GB) plus the F16 KV cache (~2 GB) over-commit the runner's 4.7 GB Metal device. The context + is now 2048, which the longest transcript of the class (under 200 tokens) is far from. Which upstream + change made the over-commit expensive was not bisected. +- **Both CUDA build jobs failed** after the CCCL pin: CCCL calls `include(CTest)`, which turned our + later `option(BUILD_TESTING ... OFF)` into a no-op, so the GPU-less runners built `jllama_test` and + its test discovery could not load the CUDA driver. The option is now declared before any subproject. - **`ToolCallingIntegrationTest#requiredToolCallIsParsedFromStreamingResponse` failed on both Windows x86-64 jobs after the b11211 bump** (the Ubuntu run and the blocking twin stayed green). The streamed request generated its full 512 tokens without a tool call. The prompt ("Write an example") never asked diff --git a/CLAUDE.md b/CLAUDE.md index 10f838d1c..cfd3eb9d5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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: **b11462** +Current llama.cpp pinned version: **b11474** ## Natives jars: one directory per backend (`.github/natives.csv`) @@ -544,13 +544,18 @@ jar `metal-macos-aarch64` (directory `Mac/aarch64/metal/`, in `llama-platform`): | Job | Build flags | Artifact | Role | |---|---|---|---| | `build-macos-arm64-metal-15` (macos-15) | `-DLLAMA_METAL_EMBED_LIBRARY=ON -DGGML_NATIVE=OFF` | `natives-metal-macos-aarch64` | **shipped** | -| `build-macos-arm64-metal` (macos-14) | `-DLLAMA_METAL_EMBED_LIBRARY=ON` (host-native) | `macos-14-metal` | test-only | +| `build-macos-arm64-metal` (macos-26) | `-DLLAMA_METAL_EMBED_LIBRARY=ON` (host-native) | `macos-26-metal` | test-only | | `build-macos-arm64-no-metal` (macos-15) | `-DLLAMA_METAL=OFF -DGGML_NATIVE=OFF` | `macos-15-no-metal` | test-only (writes `Mac/aarch64/cpu/`) | The shipped variant is the metal-15 build because it is the only one with **both** Metal **and** `GGML_NATIVE=OFF` (portable across Apple-silicon generations); the other two exist to prove the -no-Metal path and the macos-14 SDK still build and pass the Java suite. The two Metal builds write +no-Metal path and the newest macOS SDK still build and pass the Java suite. The two Metal builds write the **same** directory, which is why the test-only artifacts are named outside the `natives-*` glob. +The host-native Metal build ran on `macos-14`, which GitHub retires by 2026-11-02 (with brownouts in +October 2026 that fail every `macos-14` job); it moved to a **pinned** +`macos-26`, not `macos-latest`, so the image cannot change under it unnoticed, and not to `macos-15`, +which the other two jobs already cover. Its Java test job runs with `-ngl 0`, so it exercises the +Metal-enabled build on the CPU; only `Java Tests macOS 15 arm64 (Metal)` offloads to the GPU. **Why that naming matters (the incident).** Two artifacts sharing a relative path, downloaded with one glob and merged, get extracted onto one file — and the survivor can be a **byte-level hybrid** of @@ -577,7 +582,17 @@ publish jobs) downloads `llama-jars` and runs `.github/smoke-native-macos.sh`, w dylib assembled from two builds) and a real JVM load via `.github/smoke/NativeLoadSmoke.java` (`java -cp …`, the JDK single-file source launcher), which forces `LlamaLoader.initialize() → System.load() → JNI_OnLoad` and then crosses JNI for -`getLlamaCppBuildInfo()`, checked against the `LlamaCppVersion` pin. +`getLlamaCppBuildInfo()`, checked against the `LlamaCppVersion` pin. A third check comes first: +the dylib's `minos` (`otool -l`, `LC_BUILD_VERSION`) must not exceed **15.0**, the supported floor. + +**Minimum macOS: 15.0, pinned, not inherited.** `llama/CMakeLists.txt` sets +`CMAKE_OSX_DEPLOYMENT_TARGET` to `15.0` before `project()` (an explicit `-D` or +`MACOSX_DEPLOYMENT_TARGET` still wins). Without it the linker takes the build host's own macOS +version, so moving the shipped build to a newer runner image would silently drop every user on the +older release, and no test would see it -- they all run on that same newer image. `build.sh` prints +`minos`/`sdk` of every dylib it builds, and the smoke above fails a shipped one above 15.0. Raise +the floor in both places together, deliberately: `JLLAMA_MAX_MINOS` in the smoke and the CMake +default. Two macOS specifics: it targets the **default** fat jar because there is no `all-macos-*` fat jar to target (macOS has no GPU backend besides Metal, which the default fat jar carries, so @@ -710,7 +725,7 @@ needs no extra step here, `build-webui` re-reads the tag and rebuilds the matchi ships no UI): ```bash # needs node/npm + network for the asset build; the embed step is plain cmake -P -git clone --depth 1 --branch b11462 https://github.com/ggml-org/llama.cpp /tmp/lc +git clone --depth 1 --branch b11474 https://github.com/ggml-org/llama.cpp /tmp/lc ( cd /tmp/lc/tools/ui && npm ci && npm run build ) mkdir -p webui-generated /tmp/ui-gen cmake -DUI_SOURCE_DIR=/tmp/lc/tools/ui -DUI_BINARY_DIR=/tmp/ui-gen \ @@ -750,7 +765,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 b11462`), the +Because `sccache` is **content-addressed** and llama.cpp is pinned (`GIT_TAG b11474`), 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` version bump @@ -1873,7 +1888,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 b11462`. +llama.cpp is fetched via CMake FetchContent, pinned to `GIT_TAG b11474`. **GoogleTest** is a separate `BUILD_TESTING`-only FetchContent (`GIT_TAG v1.18.0`), used solely by the `jllama_test` C++ unit-test binary — not by the shipped library, and not coupled to the diff --git a/README.md b/README.md index 514bd7f28..f876a88cf 100644 --- a/README.md +++ b/README.md @@ -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 b11462](https://img.shields.io/badge/llama.cpp-%23b11462-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b11462) +[![llama.cpp b11474](https://img.shields.io/badge/llama.cpp-%23b11474-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b11474) [![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) diff --git a/docs/history/llama-cpp-breaking-changes.md b/docs/history/llama-cpp-breaking-changes.md index bea39c106..8dc386fbc 100644 --- a/docs/history/llama-cpp-breaking-changes.md +++ b/docs/history/llama-cpp-breaking-changes.md @@ -830,5 +830,7 @@ Used during `llama.cpp` version bumps: when upgrading, scan this file from the r | b11454–b11457 | patches + upstream verification | **All nine patches apply unchanged**, verified in order against pristine b11457 with `git apply`. No patch-target file in the range; nothing under `common/` or `tools/server/` changed. Drop-checks against pristine b11457 -- the final state of the bump: `common_params_parse` still carries the `#ifdef _WIN32` `argv = utf8.ptrs.data()` override and `common_params_parse_main` is absent (`0001` needed); `load_progress_callback` still assigned unconditionally (`0002`); no slot-similarity getter (`0003`); no `llama_server_attach`, `LLAMA_SERVER_WORKER_CMD` or embedded-shutdown counterpart (`0006`-`0008`); no `split_sum == 0` guard (`0012`); no callback hook in `common/log.h` (`0014`); no `stop_server` and a `GGML_ABORT("Failed to connect` still present (`0015`). **Every carried patch is still needed.** Across the whole bump (b11320 → b11457) four patches broke, each at exactly one upstream commit: `0007` at #29818 (b11361) and #29895 (b11401), `0014` at #29895 (b11401), `0008` at #29987 (`4d60b4d08`, before b11429), `0015` at #26610 (b11450); every refresh moved context only. | | b11457–b11458 | One commit, 9 files, ~978/733 lines, **#30067 only**: the Hexagon backend's CPY/CONCAT/CONT/DUP overhaul (DMA/HVX for every path, `htp/hex-cpy-dma.h` renamed to `dma-copy.h`) plus its Snapdragon developer guide. No natives jar builds Hexagon, so **nothing in it reaches a shipped library**. At 112 KiB it is over the 100 KiB step threshold, but a single commit cannot be split further. **No project source change.** | | b11457–b11458 | patches + upstream verification | **All ten patches apply unchanged** (`0001`-`0016`, now including the Kolibri-1 carry `0016`), verified in order against pristine b11458 with `git apply`. No patch-target file and nothing under `src/`, `common/`, `tools/server/` or `include/` in the range. | -| b11458–b11462 | Four commits, 11 files, ~119/192 lines, backends only. **SYCL:** #27689 removes the separate flash-attention KV buffers (`fattn-buffers.{cpp,hpp}` deleted; `ggml-sycl/CMakeLists.txt` globs its sources, so nothing to wire) and #29500 adds an IQ3_S multi-column MMVQ kernel. **Vulkan:** #30049 skips the direct host read of uncached host-visible memory on AMD UMA devices (iGPUs), which is write-combined and slow to read, and takes the device-to-host copy path instead. **WebGPU:** #27069 (not built here). **No project source change.** This is the target of the bump: b11462 is the newest llama.cpp release. | +| b11458–b11462 | Four commits, 11 files, ~119/192 lines, backends only. **SYCL:** #27689 removes the separate flash-attention KV buffers (`fattn-buffers.{cpp,hpp}` deleted; `ggml-sycl/CMakeLists.txt` globs its sources, so nothing to wire) and #29500 adds an IQ3_S multi-column MMVQ kernel. **Vulkan:** #30049 skips the direct host read of uncached host-visible memory on AMD UMA devices (iGPUs), which is write-combined and slow to read, and takes the device-to-host copy path instead. **WebGPU:** #27069 (not built here). **No project source change.** | | b11458–b11462 | patches + upstream verification | **All ten patches apply unchanged**, verified in order against pristine b11462 with `git apply`. No patch-target file and nothing under `src/`, `common/`, `tools/server/` or `include/` in the range, so every drop-check of the b11457 row still holds unchanged; `git grep -i kolibri` finds nothing under `src/` at b11462, so `0016` is still needed too. No `.github/` change upstream either: OpenVINO, CCCL (`v3.4.3`) and the ROCm wheels stay where b11457 left them. | +| b11462–b11474 | Twelve commits, 21 files, ~544/233 lines (71 KiB, one step). **Sampling** (#29797): `common_sampler_init` now ends a chain whose last sampler is temperature 0 (or top-k 1) with the greedy sampler instead of `dist`, unless `n_probs` asks for probabilities; the token chosen is the same argmax either way, so temperature-0 tests keep their answers. **Vocab** (#30090): PLaMo-3 FIM tokens in `llama-vocab.cpp`'s FIM lists. **Models:** GLM5-Next MTP draft head (#29928, `src/models/glm5-next.cpp` + `models.h`). **Recurrent memory** (#29923): a partial rollback of a cell shared by several sequences now returns `false`. **cpp-httplib 0.60.0** (#30081): SSE-client `id` handling, redirects, certificate SAN parsing and one server-side change, a WebSocket subprotocol the client did not offer is no longer selected -- none of it on a path the embedded server uses. Plus `qwen3tts.py`/PLaMo converter fixes (Python, not built), imatrix, and the MUSA/SYCL/WebGPU backends. **No project source change.** This is the target of the bump: b11474 is the newest llama.cpp release. | +| b11462–b11474 | patches + upstream verification | **All ten patches apply unchanged**, verified by a fresh configure through the real `FetchContent` path. Two patch-target files are in the range -- `src/llama-vocab.cpp` and `src/models/models.h`, both touched by `0016` -- but the upstream hunks (the FIM token lists and the GLM5-Next structs) are away from `0016`'s, so only line offsets moved. The drop-checks hold: nothing under `tools/server/`, `include/`, `common/arg.cpp`, `common/log.{h,cpp}`, `src/llama-model.cpp` or `ggml/src/ggml-rpc/` changed, and `git grep -i kolibri` finds nothing under `src/` at b11474. No `.github/` change upstream: OpenVINO, CCCL (`v3.4.3`) and the ROCm wheels stay where b11457 left them. | diff --git a/llama/CMakeLists.txt b/llama/CMakeLists.txt index f99caeb91..ce9b070ec 100644 --- a/llama/CMakeLists.txt +++ b/llama/CMakeLists.txt @@ -1,5 +1,13 @@ cmake_minimum_required(VERSION 3.22) +# The oldest macOS the dylib loads on. Without it the linker takes the build host's own version, so +# moving a macOS job to a newer runner image would silently raise the floor for every user. Must be +# set before the first project(); a -DCMAKE_OSX_DEPLOYMENT_TARGET=... or MACOSX_DEPLOYMENT_TARGET +# from outside still wins. Ignored on every other platform. Checked by .github/smoke-native-macos.sh. +if(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET AND NOT DEFINED ENV{MACOSX_DEPLOYMENT_TARGET}) + set(CMAKE_OSX_DEPLOYMENT_TARGET "15.0" CACHE STRING "Minimum macOS version of libjllama.dylib") +endif() + project(jllama CXX) # Use static MSVC runtime (/MT) instead of the default DLL runtime (/MD). @@ -190,7 +198,7 @@ set(LLAMA_BUILD_APP OFF CACHE BOOL "" FORCE) FetchContent_Declare( llama.cpp GIT_REPOSITORY https://github.com/ggerganov/llama.cpp.git - GIT_TAG b11462 + GIT_TAG b11474 PATCH_COMMAND ${CMAKE_COMMAND} -DPATCH_DIR=${CMAKE_CURRENT_SOURCE_DIR}/patches -DLLAMA_SRC= diff --git a/llama/src/main/java/net/ladenthin/llama/value/LlamaCppVersion.java b/llama/src/main/java/net/ladenthin/llama/value/LlamaCppVersion.java index 84d6436e9..e06ee340e 100644 --- a/llama/src/main/java/net/ladenthin/llama/value/LlamaCppVersion.java +++ b/llama/src/main/java/net/ladenthin/llama/value/LlamaCppVersion.java @@ -9,13 +9,13 @@ * library was compiled against, exposed as a compile-time constant so callers can render a badge or * emit a startup log line without loading the native library. * - *

{@link #LLAMA_CPP_VERSION} is a pure-Java string ({@code "b11462"}) that mirrors the + *

{@link #LLAMA_CPP_VERSION} is a pure-Java string ({@code "b11474"}) that mirrors the * {@code GIT_TAG} in {@code llama/CMakeLists.txt}. It is available even when {@code libjllama} is * absent (pure-Java checkout, before {@code System.load}), which is what makes it suitable for a * lightweight version badge in Android or other UIs.

* *

For the authoritative value that is baked into the native binary — the build number - * plus the resolved upstream commit, e.g. {@code "b11462-"} — call + * plus the resolved upstream commit, e.g. {@code "b11474-"} — call * {@link net.ladenthin.llama.LlamaModel#getLlamaCppBuildInfo()} instead; that reads llama.cpp's own * {@code build-info} through JNI and therefore cannot drift from the compiled library (but requires * the native library to be loaded).

@@ -23,14 +23,14 @@ public final class LlamaCppVersion { /** - * The pinned llama.cpp release tag this library was built against, e.g. {@code "b11462"}. + * The pinned llama.cpp release tag this library was built against, e.g. {@code "b11474"}. * *

Kept in lockstep with {@code GIT_TAG} in {@code llama/CMakeLists.txt} — see the * "Upgrading/Downgrading llama.cpp Version" checklist in {@code CLAUDE.md}. This is the * compile-time pin; use {@link net.ladenthin.llama.LlamaModel#getLlamaCppBuildInfo()} for the * value actually linked into the native binary.

*/ - public static final String LLAMA_CPP_VERSION = "b11462"; + public static final String LLAMA_CPP_VERSION = "b11474"; // Constants holder — not instantiable. private LlamaCppVersion() {} diff --git a/llama/src/test/java/net/ladenthin/llama/SessionConcurrencyTest.java b/llama/src/test/java/net/ladenthin/llama/SessionConcurrencyTest.java index 28f006d14..6c185b382 100644 --- a/llama/src/test/java/net/ladenthin/llama/SessionConcurrencyTest.java +++ b/llama/src/test/java/net/ladenthin/llama/SessionConcurrencyTest.java @@ -57,8 +57,12 @@ public static void setup() { Assumptions.assumeTrue( new File(TestConstants.MODEL_PATH).exists(), "Model file not found, skipping SessionConcurrencyTest"); int gpuLayers = Integer.getInteger(TestConstants.PROP_TEST_NGL, TestConstants.DEFAULT_TEST_NGL); + // 2048, not 4096: the longest transcript any test here builds stays under 200 tokens, and + // with 4096 the 7B model (~2.7 GB) plus its F16 KV cache (~2 GB) over-committed the + // macOS 15 runner's 4.7 GB Metal device. From llama.cpp b11457 on that ran ~130x slower + // (0.45 s -> 57 s per token) and timed every test out; 2048 halves the cache. model = new LlamaModel(new ModelParameters() - .setCtxSize(4096) + .setCtxSize(2048) .setModel(TestConstants.MODEL_PATH) .setGpuLayers(gpuLayers) .setFit(false));