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
1 change: 0 additions & 1 deletion .github/verify-patches-applied.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#
# 0003, 0006, 0007, 0008 -> jllama.cpp / native_server.cpp call the symbols they add,
# so dropping one is a compile or link error.
# 0011 -> the ContentOnlyParseUtf8 tests in src/test/cpp/test_utils.cpp.
# 0012 -> src/test/cpp/test_model_split.cpp.
# 0001, 0002 -> model-gated Java jobs (Windows argv, LoadProgressCallbackTest).
#
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ from version 5.0.0 onward. Pre-fork releases (`1.x`–`4.2.0`) were authored by
where the backend cannot provide it, `OFF` disables it.

### Changed
- **llama.cpp `b11062` → `b11069`, and local patch `0011` dropped — malformed UTF-8 in a
completion is now replaced, not truncated.** Seven upstream commits, 57 KiB, no project-source
change; the one that matters is llama.cpp #29161 ("common/peg : handle invalid utf-8 sequences in
the AST", first tagged b11063). It fixes the failure `0011` had carried since 5.1.0 — a single
undecodable byte in the model's output made the content-only parse `FAIL` and the request 500 —
independently and more broadly than the patch did, so the patch no longer applies and was dropped
rather than refreshed (the `0009`/`0013` precedent). The observable difference: `0011` returned the
text *up to* the bad byte, whereas upstream consumes every undecodable run and substitutes exactly
one U+FFFD for it (the Unicode "maximal subpart" rule — `\xE4\xB8` followed by `c` is one run,
`\xFF\xFE` is two), so the text *after* the byte is now delivered too. A trailing sequence that is
still incomplete at the end of the input keeps being withheld, as before. The `ContentOnlyParseUtf8`
C++ tests that guarded the patch now pin upstream's replacement contract on every platform. The
rest of the range is CUDA/Metal/WebGPU kernel tuning and a converter flag; `tools/server/`,
`common/arg.*`, `src/llama-model.*` and `ggml/include` are byte-identical across it, so the other
eight patches apply unchanged and the server wire contract cannot have moved.
- **llama.cpp `b10731` → `b10850`.** No project-source change: every header move in the range is
additive or a **widening** const-qualification, and the server wire contract is byte-identical
(request-field set, `set_hard_limits` bounds and response keys all verified mechanically, which is
Expand Down
37 changes: 30 additions & 7 deletions CLAUDE.md

Large diffs are not rendered by default.

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 b11062](https://img.shields.io/badge/llama.cpp-%23b11062-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b11062)
[![llama.cpp b11069](https://img.shields.io/badge/llama.cpp-%23b11069-informational)](https://github.com/ggml-org/llama.cpp/releases/tag/b11069)
[![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
11 changes: 5 additions & 6 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,18 @@ be described here as "drops automatically when that merges"; it will not.)
- **`0010` cast `vocab_type` for `common_json`** (one line; upstream regressed `GET /models` +
`GET /v1/models` to emit `true`/`false` instead of the numeric vocab type when they flipped the
`json` alias to `common_json` at b10585/#27511). **Not yet filed upstream.**
- **`0011` lenient invalid-UTF-8 in the PEG parser** (one malformed byte from the model turns a
finished generation into an HTTP 500; the `INVALID` branch ignores leniency while the `INCOMPLETE`
branch beside it honours it). Ships an upstream `tests/peg-parser/test-unicode.cpp` case.
**Not yet filed upstream.**
- **`0012` guard the zero split-sum and name the device index** (a GPU reporting zero free memory —
or a cancelling `--tensor-split` such as `-ts 1,-1` on any backend — makes every model load fail
with the unactionable `error loading model: vector`). Ships an upstream `tests/test-model-split.cpp`.
**Not yet filed upstream.**

(`0009` is **not** in this list and the number is burned: upstream merged the subprocess.h fix via
ggml-org/llama.cpp#26606, so the patch was dropped at the b10280 bump. `0013` is likewise gone —
upstream merged this project's own PR ggml-org/llama.cpp#28775 and it was dropped at b10948. Both
drops are recorded in `CLAUDE.md` under the patch table.)
upstream merged this project's own PR ggml-org/llama.cpp#28775 and it was dropped at b10948. `0011`
went the same way at b11069: upstream fixed the invalid-UTF-8 PEG-parser failure independently and
more broadly via ggml-org/llama.cpp#29161 (one U+FFFD per undecodable run, text after it kept) before
the patch was ever filed, so the `ContentOnlyParseUtf8` guard now pins upstream's contract instead.
All three drops are recorded in `CLAUDE.md` under the patch table.)

### llama.cpp upstream feature exposure (queued, deferred by policy)

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 @@ -740,3 +740,5 @@ Used during `llama.cpp` version bumps: when upgrading, scan this file from the r
| b11012–b11018 | patches + upstream verification | **Nine patches, none touched and none droppable.** No patch-target file appears anywhere in the range, so `common/arg.{cpp,h}`, `common/peg-parser.cpp`, every `tools/server/*.cpp`, `src/llama-model.{cpp,h}` and `tests/CMakeLists.txt` are byte-unchanged. **All six standing drop-checks still say "still required"**, run against the pristine tag because the fail-loud applier detects "does not apply" but never "upstream already fixed this": `0001` (`common_params_parse_main` 0 occurrences in `b11018:common/arg.h`; WIN32 override still at `common/arg.cpp:1282`), `0002` (`params_base.load_progress_callback` still unguarded at `server-context.cpp:1095`), `0010` (`{"vocab_type", meta.model_vocab_type}` still uncast at `server-context.cpp:4554`), `0012` (bare `splits[i] /= split_sum;` still at `src/llama-model.cpp:1518` — unmoved from b11012), and `0003`/`0006`/`0008` (`get_slot_prompt_similarity`, `llama_server_set_embedded`, `LLAMA_SERVER_WORKER_CMD` all absent from `b11018:tools/server/`). Verified from a fresh configure: stamp at head `c9a5eeeb3` with nine SHA-256 lines, `verify-patches-applied.sh` green, extraction unchanged at **138 CLI / 57 request / 15 trainer** names, Release build clean with zero errors and zero warnings, `ctest` **551/551**, `nm -D` **40** `Java_*` exports and **0** mangled, `NativeLibraryLoadSmokeTest` **4/4, 0 skipped** after a `clean`, full `mvn test` **1763/0**, SpotBugs **0**, spotless clean. **Context worth recording: the previous range's PR run (#958, the b11012 PR) was the first full-matrix execution since b10948** — 66 jobs, **58 success / 2 failure / 6 skipped**, the two failures being the `Verify GPG signing key` pair that `publish.yml` documents as an expected red on a `pull_request` event (the `maven-central` environment withholds secrets there). That run is what first exercised the trainer-model wiring, `verify-test-counts.sh` and both aarch64 fat-jar smoke jobs added earlier in the same session; all passed. |
| b11018–b11062 | 36 commits, **1 347 KiB**, and the chunking is the first thing worth recording: the range was walked in **nine** steps — `b11018→b11020` (10 KiB / 2 commits), `→b11022` (579 / 2), `→b11024` (224 / 2), `→b11042` (87 / 18), `→b11045` (98 / 3), `→b11050` (57 / 5), `→b11052` (115 / 2), `→b11055` (97 / 3) and `→b11062` (84 / 7). **Three steps break the 100 KiB rule and all three are irreducible**: b11021, b11023 and b11051 do not exist as tags, so each of those steps is a *single* upstream commit with no smaller step available — **#28732** (Vulkan: split `ggml-vulkan.cpp` into buffers/debug translation units plus three shared headers, ~5.4k lines moved, `ggml-vulkan/CMakeLists.txt` gains exactly the five new files), **#29009** (OpenVINO update to 2026.4, entirely inside `ggml/src/ggml-openvino/**`), and **#28948** (Metal MoE + SSM_CONV fusion, new `argsort.metal`). **The review surface is 43 files, all additive or implementation-only.** `include/llama.h` gains two things and loses nothing: `LLAMA_VOCAB_TYPE_TEST = 7` (a tail append — no existing enumerator renumbers, and this project reads `vocab_type` as a raw int in `ModelMeta.getVocabType()` and emits it `static_cast<int>`-ed in `jllama.cpp`, so no Java-side constant can go stale) and `llama_adapter_lora_init_from_file_ptr` (#28993, additive; adapters are loaded by path here, never by `FILE*`). `common/chat.cpp` picks up a Ling 3.0 / Bailing V3 detection arm and `common/parsers/ling3.cpp` (#28682), and `common/parsers/gemma4.cpp` **fixes a real bug on a path this project serves**: with `tool_choice == required` the grammar now terminates at the tool call instead of falling through to the content scan (#29115). `common/json-schema-to-grammar.cpp` fixes a second one — `gbnf_escape_length()` now accepts `\-`, so a JSON-schema `pattern` containing an escaped hyphen no longer produces a grammar the parser rejects (#29127). `src/llama-model.{cpp,h}` gain `load_swa_pattern()` with 20 `src/models/*.cpp` architectures rewritten onto it and `TENSOR_SKIP` honoured in `create_tensor_gate_up_exps()` (#29042, #29014); `tools/mtmd/clip.cpp` returns false instead of proceeding when `ggml_backend_sched_alloc_graph()` fails (#28149 / #26070). **`ggml/include` is byte-identical across the whole range**, so no ggml public API moved at all. |
| b11018–b11062 | patches + upstream verification | **Nine patches still, none dropped — but two needed a refresh, the first in several ranges.** One upstream commit is responsible: **#29125** ("server : improve startup log messages", first tagged b11053) adds an `SRV_INF("initializing ...")` line immediately above `llama_server()`'s argv parse and a two-line `TODO` comment above `common_params_parse()` in `common/arg.h`. `0001` anchors hunks on both spots and `0006` replaces the very line `0001` flips, so both went stale **on context only** — the refresh changes `@@` line numbers, three context lines and the index blob hashes, and not one added or removed line. Replayed in filename order against pristine **b11055 and b11062**: all nine apply clean at both. **`0007`'s standing invariant is intact and provably so** — its `-` side is a verbatim copy of the route table it factors out of `llama_server()`, so a clean apply *is* the proof upstream did not touch that block; #29125's edits sit above it (the CORS warning) and below it (the `warn_names` loop), never inside. **The three mechanical `tools/server/` contract greps have no input** despite `tools/server/` being touched: `server-schema.cpp`, `server-task.cpp` and `server-context.cpp` are byte-identical b11018→b11062, verified by blob hash rather than by reading a diff, so the request-field set, the field bounds and the response-key set cannot have moved. **All standing drop-checks still say "still required"**, run against the pristine tag because the fail-loud applier detects "does not apply" but never "upstream already fixed this": `0001` (`common_params_parse_main` 0 occurrences in `b11062:common/arg.h`, WIN32 override still at `common/arg.cpp:1282`), `0002` (`params_base.load_progress_callback = load_progress_callback` still unguarded at `server-context.cpp:1095`), `0010` (`{"vocab_type", meta.model_vocab_type}` still uncast at `server-context.cpp:4554`), `0011` (the `common_peg_until_parser` `INVALID` branch still returns `FAIL` unconditionally, ignoring `ctx.is_lenient()`, while the `INCOMPLETE` branch right above it honours it), `0012` (bare `splits[i] /= split_sum` at `llama-model.cpp:1518`, no zero guard), and `0003`/`0006`/`0007`/`0008` absent upstream. **Verified at the target from a fresh configure**: stamp head `3cf03257f` with nine SHA-256 lines, `verify-patches-applied.sh` green (9 applied, 0010 cast present), extraction unchanged at 138 CLI / 57 request / 15 trainer names, Release build clean (0 errors, 0 warnings), `ctest` 551/551, `nm -D` 40 `Java_*` exports and 0 mangled, `NativeLibraryLoadSmokeTest` 4/4 with 0 skipped after a `mvn clean`, `mvn test` 1763/0 (269 model-gated skips in a HF-blocked sandbox), `verify-test-counts.sh` 1763 across 119 classes, SpotBugs 0, spotless clean. **The OpenVINO SDK pin moved with it**: #29009 takes upstream's own `OPENVINO_VERSION_MAJOR`/`OPENVINO_VERSION_FULL` to 2026.4, and this project's two OpenVINO classifier jobs — which had drifted two releases behind at 2026.2.1 — now install `2026.4` / `2026.4.0.22959.99c81491cc3` from the same URL template upstream's `{linux,windows}-setup-openvino` actions use. ggml-openvino is developed against whatever pair upstream pins, so tracking it is the cheaper end of the trade: a lagging pin does not fail on the bump that introduces the drift, it fails on some later one, in a job whose runner has no Intel GPU to reproduce on. **Not verifiable from the bump sandbox** — `storage.openvinotoolkit.org` is blocked by the network policy, so neither archive URL could be HEAD-checked here; the evidence they resolve is that upstream's own release jobs download exactly these two URLs at b11062. Per the classifier policy the step is fail-loud, so a wrong URL reds the job rather than shipping a backend-less jar. Both jobs now carry a keep-in-sync note naming upstream's two variables as the source of truth, so the next bump has somewhere to look instead of rediscovering the coupling. |
| b11062–b11069 | Seven commits, 21 files, **57 KiB** (`tools/ui` untouched, so the WebUI-excluded figure is the same). One touches a priority-list neighbourhood and a patch target: **#29161** ("common/peg : handle invalid utf-8 sequences in the AST", first tagged **b11063**) rewrites `common/peg-parser.{cpp,h}`, `common/unicode.{cpp,h}`, `common/chat-peg-parser.cpp` and the two upstream tests. Everything else is backend-internal: CUDA (#28912 MMVQ→MMQ crossover for SM70, #29152 FA tuning for Gemma 4 on Ampere+), Metal (#29169 arbitrary `hc` in `dsv4_hc_pre`, #29136 macOS 27 SDK deprecation warnings — warnings only, no API), WebGPU (#28976 fused GDN + cpy; not a backend this project builds), and the Python converter (#29203, not compiled). | **No project-source change, but one patch dropped.** `common/peg-parser.h` grows additively — a new `common_peg_invalid_utf8 {pos, len}` record, an `invalid_utf8` vector plus `sanitized_text()` on `common_peg_ast_node`, and a defaulted trailing parameter on `common_peg_ast_arena::add_node` and the four-argument `common_peg_parse_result` constructor — and it is on the *safe-to-skip* list anyway (nothing in `src/main/cpp` names a PEG type; `jllama.cpp` reaches the parser only through `common_chat_parse`). `common/unicode.h` changes one *comment*: `utf8_parse_result::bytes_consumed` now carries the valid-prefix length on `INVALID`/`INCOMPLETE` results instead of `0`. Neither `common/chat.h` nor any other priority row moves. **`tools/server/` is untouched** (no file in the range), so the three mechanical contract greps have no input. **`ggml/include` is byte-identical.** The behavioural change is the one `patches/0011` existed for — see the patch row below. |
| b11062–b11069 | patches + upstream verification | **Eight patches now: `0011` dropped, the other eight apply unchanged.** #29161 deleted the very `INVALID` branch of `common_peg_until_parser` that `0011` patched: the until-parser now consumes an undecodable run in every mode (strict included), records it on the result, and `common_chat_peg_mapper` renders the node through `sanitized_text()` — one U+FFFD per run, per the Unicode "maximal subpart" rule (`\xE4\xB8` + `c` → one replacement, `\xFF\xFE` → two), with the text after the run kept. `0011` had returned only the text *before* the byte. The lenient incomplete-at-end branch is unchanged (trailing bytes withheld). So the applier failed loud — `patch failed: common/peg-parser.cpp:680` — exactly as designed, and the patch was **dropped, not refreshed**, per the `0009`/`0013` precedent; it had never been filed upstream, so nothing to close. Its runnable guard was kept and re-pointed: `ContentOnlyParseUtf8` in `src/test/cpp/test_utils.cpp` now pins upstream's replacement contract (six cases, one more than before, the extra one pinning the run boundary `\xFF\xFE` → two U+FFFD), so a future upstream revert to `FAIL` still reds `C++ Tests` everywhere. **Replayed in filename order against pristine b11069**: `0001` `0002` `0003` `0006` `0007` `0008` `0010` `0012` apply clean, `0011` is the only failure. **All standing drop-checks still say "still required"** at the pristine tag: `0001` (`common_params_parse_main` 0 occurrences in `b11069:common/arg.h`; the count-guarded `argv = utf8.ptrs.data()` override still at `common/arg.cpp:1281` — i.e. [ggml-org/llama.cpp#26416](https://github.com/ggml-org/llama.cpp/issues/26416) remains open upstream and is **not** what this range fixed), `0002` (`params_base.load_progress_callback = load_progress_callback` still unguarded at `server-context.cpp:1095`), `0010` (`{"vocab_type", meta.model_vocab_type}` still uncast at `server-context.cpp:4554`), `0012` (bare `splits[i] /= split_sum` at `llama-model.cpp:1518`), and `0003`/`0006`/`0007`/`0008` absent upstream. `.github/verify-patches-applied.sh`'s header comment no longer lists `0011`. **Verified at the target from a fresh configure** (`rm -rf build && cmake -B build -DBUILD_TESTING=ON`, the real `FetchContent` path): stamp head `68d9053af` with **eight** SHA-256 lines, `verify-patches-applied.sh` green (8 applied, tree dirty, 0010 cast present), extraction unchanged at 138 CLI / 57 request / 15 trainer names, Release build clean, `ctest` **552/552** (551 → 552: the re-pointed guard gained one case), `nm -D` 40 `Java_*` exports and 0 mangled, `NativeLibraryLoadSmokeTest` **4/4, 0 skipped** after a `mvn clean` — `nativeBuildInfoMatchesPinnedVersionConstant` confirms `LlamaCppVersion.LLAMA_CPP_VERSION` (`b11069`) against the linked `build-info`. `test_utils.cpp` is clean under the CI-pinned clang-format 23.1.1; `spotless:check` clean. Model-backed Java tests were not run (HF-blocked sandbox); `NativeServerAttachIntegrationTest.completion_overHttp_served`, the test that first surfaced the `0011` failure, is the CI-side confirmation for this drop. |
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 b11062
GIT_TAG b11069
PATCH_COMMAND ${CMAKE_COMMAND}
-DPATCH_DIR=${CMAKE_CURRENT_SOURCE_DIR}/patches
-DLLAMA_SRC=<SOURCE_DIR>
Expand Down
Loading
Loading