feat(rpc): #470 Phase 1 — GGUF-derived model identity getters, remove model_hash - #63
Conversation
Replace model_hash (SHA-256 of GGUF file, changes on rebuild) with GGUF-derived semantic identity for cross-model KV safety and capability awareness in STATE_GET/STATE_PUT/STATE_META/PREFILL/DECODE responses. New public API (include/llama.h): - llama_model_get_tokenizer_model() — reads tokenizer.ggml.model - llama_model_get_display_name() — reads general.base_model.0.name with fallback to general.name (avoids 'Safetensors' artifact) - llama_model_get_quant_label() — derives human-readable label from general.file_type via llama_ftype enum mapping - llama_model_get_capabilities_bitfield() — bitfield derived from GGUF: bit 0 MTP (<arch>.nextn_predict_layers > 0) bit 1 VISION (reserved, unset — needs mmproj) bit 2 REASONING (general.tags contains 'reasoning') bit 3 TOOL_USE (heuristic from tags/display name) bit 4 CODE (heuristic from tags/display name) GGUF dump validation (3 in-fleet files): - Qwopus3.6-35B-A3B-v1-APEX-MTP-I-Balanced.gguf: arch=qwen35moe, MTP=1, tags=[reasoning,...], ftype=17 - Qwopus3.6-35B-A3B-v1-APEX-I-Balanced.gguf: arch=qwen35moe, MTP=absent, tags=[reasoning,...], ftype=17 - Qwopus3.6-27B-Coder-Compat-MTP-Q5_K_M.gguf: arch=qwen35, MTP=1, tags=absent, name='Qwopus3.6 27B Coder...' Closes ggml-org#470 (Phase 1).
Review — Phase 1 of ggml-org#470 rolloutVerdict: REQUEST_CHANGES Verified against the actual diff ( Findings
Everything else checked out: MTP-bit derivation correctly uses the arch-suffixed Cross-repo note: capability bit values (MTP=0x01, VISION=0x02, REASONING=0x04, TOOL_USE=0x08, CODE=0x10) were confirmed to match Core PR ggml-org#489's |
- Replace raw substring find() with explicit kCodeTags/kToolTags sets to eliminate false positives on 'decoder-only', 'encoder', 'autoencoder' - Fix display-name fallback to skip empty values (match getter logic) - Add CamelCase-aware word-boundary check for display names - Add test-model-identity: 28 tests for capability bitfield derivation logic Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Part of ggml-org#470 ("Merged P/D StatePut + Decode with GGUF-derived model identity"), Phase 1 of a 4-phase rollout. Companion PR on the Core side: ddvnguyen/hydra_vortex#489 (Phase 3, Store schema + CrossModelGuard).
Replaces the RPC wire's
model_hash(SHA-256 of the GGUF file) with 4 GGUF-derived semantic identity fields:tokenizer,model_name,model_quant,model_capabilities(bitfield: MTP/VISION/REASONING/TOOL_USE/CODE). A file hash changes on rebuild even when content is unchanged, and gives no information about model capabilities — which matters for deciding whether it's safe to reuse a KV cache across a prefill/decode split.model_hashis removed entirely from the RPC wire and theserver_task_result_hydra_state/server_task_result_hydra_enginestructs — not kept as a fallback.llama_model_hash()itself is left in place (still used elsewhere); only its RPC-layer call sites are removed.Getter design (grounded in real GGUF metadata, not the spec assumption)
I dumped 3 in-fleet production GGUFs with
gguf_dump.pybefore finalizing the bit derivation, since the original design assumed ageneral.capabilitieskey that does not exist in any of them:nextn_predict_layers)general.namebase_model.0.nameSafetensors(useless)Qwen3.6 35B A3BSafetensors(useless)Qwen3.6 35B A3BQwopus3.6 27B Coder...(useful)Key findings that shaped the implementation:
general.nameis frequently a conversion-tool artifact ("Safetensors") — not usable as the primary display-name source.llama_model_get_display_name()prefersgeneral.base_model.0.name, falling back togeneral.nameonly when the former is absent (validated against the 27B file, where the fallback is the useful one).<arch>.nextn_predict_layersGGUF key (via the existingLLM_KV(arch)(...)arch-suffix lookup pattern, not hardcoded to one architecture) — confirmed present/absent correctly across MTP and non-MTP variants of the same model family.--mmprojGGUFs in this codebase, not embedded).Changes
include/llama.h— 4 new public getters:llama_model_get_tokenizer_model,llama_model_get_display_name,llama_model_get_quant_label,llama_model_get_capabilities_bitfield.src/llama-model.h/.cpp— implementations; addedgguf_tagsfield (thegeneral.tagsarray is skipped by the genericgguf_kvscalar loop, needed its own read).tools/server/server-task.h/.cpp—model_hashremoved from both hydra result structs; new fields added.tools/server/server-context.cpp— all 5 RPC responsemeta_jsites (STATE_GET/PUT/META/PREFILL) + population sites + log lines updated.Test plan
cmake --build build --target llama llama-server-impl— clean compile, verified independently by me (reviewer), not just agent self-report. Only pre-existing warnings (unrelated deprecated-API and format-string warnings already present before this change).Notes for reviewer
Does not touch DECODE (0x43) handler internals or
hydra_classify_config_key()— those are Phase 2 (separate PR, depends on this one for the new identity getters).🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com