fix!: retire the CLI flags llama.cpp's server parser rejects, and guard the contract - #426
Merged
Merged
Conversation
…rd the contract
`LlamaModel.loadModel(parameters.toArray())` hands the ModelParameters map to
`common_params_parse(..., LLAMA_EXAMPLE_SERVER)` as argv, where an unregistered
option is a hard error rather than a warning. Seven flags the Java layer emitted
are no longer registered, so every caller of the matching builder method got
"Failed to parse model parameters" instead of a loaded model.
Two of them are fresh: b10878 deleted `--mlock` and `--no-mmap` (deprecated at
b10092 -- the whole deprecation window opened and closed inside eight tags).
Those have a faithful replacement, so nothing is lost: a new `args.LoadMode`
enum + `ModelParameters.setLoadMode(LoadMode)` expose upstream's `-lm`/
`--load-mode`, and `enableMlock()`/`disableMmap()` keep working, re-pointed to
`LoadMode.MLOCK` / `LoadMode.NONE` -- the exact mapping upstream's own
deprecation shim used. Both are now `@Deprecated`.
Five were already dead: `--dump-kv-cache`, `--hf-repo-v` and `--hf-file-v` are
gone from llama.cpp entirely; `--grp-attn-n` and `--grp-attn-w` are still in
`arg.cpp` but `set_examples()`-scoped to LLAMA_EXAMPLE_COMPLETION/PASSKEY, so
the server parser rejects them exactly like a deleted flag. Their setters are
now `@Deprecated` no-ops that write nothing, keeping call sites compiling *and*
loading. `ModelFlag.MLOCK`/`NO_MMAP`/`DUMP_KV_CACHE` are removed from the enum
so the broken argv is not reachable through `setFlag` either -- the same
reasoning that already excluded `FLASH_ATTN`.
No Java test could catch any of this: `ModelFlagTest` and
`ModelParametersExtendedTest` assert the string mapping (`hasKey("--mlock")`),
never that llama.cpp still accepts the string, so they stayed green while the
flags were dead. The guard closes that:
- `cmake/extract-java-cli-flags.cmake` extracts every `"--flag"` literal
`ModelFlag.java`/`ModelParameters.java` can emit into a generated header at
configure time, so the Java sources stay the single source of truth.
- `src/test/cpp/test_model_flags.cpp` asserts each one is registered in the
real `common_params_parser_init(params, LLAMA_EXAMPLE_SERVER).options`,
exempting only `--vocab-only` (a project pseudo-flag `strip_flag_from_argv`
removes before the parse). It also checks the oracle and the exemption list
themselves, so an empty option table or a stale exemption cannot make it
pass vacuously.
A grep over `arg.cpp` would not have worked -- it is structurally blind to
example scoping, which is exactly where `--grp-attn-n`/`-w` hid. Run against the
pre-fix sources the test named all seven; after the fix it is green.
Verified locally: ctest 531/531 (was 527), `mvn test` 1759 tests green,
PIT 320/320 killed with 0 NO_COVERAGE, spotbugs clean (`setLoadMode` added to
the design-intent OCP suppression list), spotless, clang-format and
`javadoc:jar` all clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AnNYn8W1xuVxVJtyL34GyH
bernardladenthin
had a problem deploying
to
maven-central
September 9, 2026 19:46 — with
GitHub Actions
Failure
bernardladenthin
had a problem deploying
to
startgate
September 9, 2026 19:46 — with
GitHub Actions
Error
bernardladenthin
had a problem deploying
to
maven-central
September 9, 2026 19:46 — with
GitHub Actions
Failure
|
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
LlamaModel.loadModel(parameters.toArray())hands theModelParametersmap tocommon_params_parse(..., LLAMA_EXAMPLE_SERVER)as argv, and an unregistered option there is a hard error —arg.cppthrows,common_params_parsereturns false,load_model_implthrowsLlamaException("Failed to parse model parameters").--mlockand--no-mmap, deprecated at b10092 — the whole deprecation window opened and closed inside eight tags. These have a faithful replacement, so no API is lost: a newargs.LoadModeenum +ModelParameters.setLoadMode(LoadMode)expose upstream's-lm/--load-mode, andenableMlock()/disableMmap()keep working, re-pointed toLoadMode.MLOCK/LoadMode.NONE— the exact mapping upstream's own deprecation shim used (LLAMA_LOAD_MODE_MLOCK/LLAMA_LOAD_MODE_NONE), so behaviour is unchanged. Both are now@Deprecated.@Deprecatedno-ops that write nothing, keeping existing call sites compiling and loading.ModelFlag.MLOCK/NO_MMAP/DUMP_KV_CACHEare removed from the enum so the broken argv is not reachable throughsetFlageither — the same reasoning that already excludedFLASH_ATTN.ModelFlagTestandModelParametersExtendedTestassert the string mapping (hasKey("--mlock")), never that llama.cpp still accepts the string, so they stayed green for as long as the flags were dead.The seven, and why each is dead
--mlockenableMlock(),ModelFlag.MLOCK--load-mode mlock--no-mmapdisableMmap(),ModelFlag.NO_MMAP--load-mode none--dump-kv-cacheenableDumpKvCache(),ModelFlag.DUMP_KV_CACHE--hf-repo-vsetHfRepoV(String)--hf-file-vsetHfFileV(String)--grp-attn-nsetGrpAttnN(int)arg.cpp,set_examples({COMPLETION, PASSKEY})--grp-attn-wsetGrpAttnW(int)arg.cpp,set_examples({COMPLETION})The last two are the interesting ones: they exist in
common/arg.cppat every tag this project has pinned, so any textual sweep reports them alive.common_params_parser_init'sadd_optfilters by example at registration time, so they are never registered forLLAMA_EXAMPLE_SERVER— the example this binding parses with — and the parser rejects them exactly like a deleted flag. That is precisely why the guard below drives the real option table instead of grepping upstream sources.The guard
llama/cmake/extract-java-cli-flags.cmake— at configure time, extracts every"--flag"string literalModelFlag.java+ModelParameters.javacan emit into a generated header. Line-oriented so Javadoc mentions ({@code --flash-attn}, prose naming--mlock) are dropped, while enum constants,putScalar/putEnumkeys,parameters.putkeys and the privateARG_*constants all survive. The Java sources stay the single source of truth, so the two halves cannot drift; it fails loud below a 50-flag floor so a broken extractor cannot make the test vacuously pass.llama/src/test/cpp/test_model_flags.cpp(4 tests) — asserts each extracted flag is present incommon_params_parser_init(params, LLAMA_EXAMPLE_SERVER).options. Hermetic: no model, no JVM, no network —common_params_parser_initonly fills a struct. It also checks the oracle (the option table must be plausibly large and contain--model) and that the exemption list has not rotted, so neither an empty table nor a stale exemption can hide a real failure.--vocab-onlyis the one exemption, and deliberately so: it is a project pseudo-flag thatjllama.cppremoves viastrip_flag_from_argvbeforecommon_params_parsesees the argv, to select the vocab-only path.Falsified before it was trusted. Built against the pre-fix Java sources, the test named exactly the seven flags above — including the two
set_examples()-scoped ones my own grep-based audit had missed. After the fix it is green.Test plan
Run locally on Linux x86_64:
mvn test1759 tests, 0 failures, 0 errorsNO_COVERAGE, test strength 100% (args.*is a gate target atmutationThreshold100, soLoadModeneededLoadModeTest— added, mirroringLazyModeTest)spotbugs:checkclean —setLoadModeadded to the design-intentOCP_OVERLY_CONCRETE_PARAMETERlist inllama/spotbugs-exclude.xml, the trapCLAUDE.mddocuments for any new enum-valuedModelParameterssetterspotless:check, clang-format 22.1.8, andjavadoc:jarall cleanNot verified locally, and the reason to watch CI here: the CMake extractor uses
file(STRINGS)+while(... MATCHES ...)and has only been exercised on Linux with CMake 3.28. macOS, both Windows generators, aarch64, s390x (cross + qemu) and Android are unproven until this PR'sC++ Testsmatrix runs. That is the main risk in this change.Also updated:
CLAUDE.md(test-file table, total 527 → 531, the SpotBugs rename/addition note),TODO.md(the "five CLI flags" entry closed, corrected to seven), and the b10870–b10878 row indocs/history/llama-cpp-breaking-changes.md, which had explicitly deferred this public-API decision to a follow-up.Related issues / PRs
Refs #425 (the b10878 bump that deleted
--mlock/--no-mmap). Implements the fix prescribed by the "ModelParametersemits five CLI flags the server arg parser rejects" entry inTODO.md, added during the b10649 review (#403).Checklist
CONTRIBUTING.mdandCODE_OF_CONDUCT.mdBreaking change
ModelFlag.MLOCK,ModelFlag.NO_MMAPandModelFlag.DUMP_KV_CACHEare removed (source-breaking for anyone callingsetFlag(ModelFlag.MLOCK)), andModelFlag.values().lengthdrops 34 → 31. Every affected constant guaranteed a failed model load, so there is no working behaviour being taken away. All seven builder methods are retained and still compile.🤖 Generated with Claude Code
https://claude.ai/code/session_01AnNYn8W1xuVxVJtyL34GyH
Generated by Claude Code