Skip to content

Plausible-value defaults on file-decoded arch/tokenizer/quant: unknown arch exported as Qwen2, APR cache reads an untyped weight as Q4_K (#3850 audit) #4419

Closed as not planned

Description

@noahgift

Found by the #3850 item-5 audit (aprender-d1, 2026-09-25). The GPU-path Q4_K substitutions it found are fixed on PMAT-3850-resolve-qtype-refuses. These remain. Each one turns an unknown or missing value decoded from a file into a plausible value instead of an error:

  • crates/aprender-serve/src/apr/cache.rs:200: get_quantized_weight_type(..).unwrap_or(GGML_TYPE_Q4_K). A quantized weight with no type recorded is decoded as Q4_K.
  • crates/aprender-core/src/format/converter/name.rs:10-11: from_model_type(..).unwrap_or(Architecture::Qwen2). An unknown arch gets Qwen2 tensor-name mapping on export (the GPT-2 GGUF export missing hidden_dim metadata (roundtrip fails) #236 shape).
  • crates/aprender-core/src/format/converter/inferred_q4k_config.rs:16,21 and write_model_config.rs:250: unwrap_or("qwen2") is written permanently into the APR model_type, which drives the chat template and rope defaults.
  • crates/aprender-core/src/format/converter/metadata.rs:386 and gguf_export_config.rs:312: tokenizer.model defaults to gpt2, which is wrong for SentencePiece models.
  • crates/aprender-serve/src/tensor_names_fallback.rs:126: _ => "llama". Probably a lookup miss rather than a wrong bind. Verify.

Done when: each one refuses by name or is shown benign by a test. One mutant per site restores the default and goes RED.

Refs #3850

Activity

  1. added this to the backlog milestone on Sep 25, 2026
  2. noahgift commented on Oct 12, 2026

    @noahgift
    MemberAuthor

    Branch w71-e3a/4419-no-plausible-defaults @ d3e2ea8 (4 commits on main 70f8c75; branch only, no PR yet).

    Each site that read a missing file field as a plausible value now refuses it by name, or derives the value from evidence:

    # Site Was Now Falsifier (planted default → RED)
    1 GGUF export name table (detect_gguf_architecture) missing/unknown general.architecture → Qwen2 FormatError naming the value; qwen35/qwen3moe/qwen2moe keep their table by name a_missing_or_unknown_gguf_architecture_is_refused_not_qwen2 RED
    2 APR model_type from GGUF (save_model_tensors_with_gguf_config_and_tokenizer, write_apr_file_raw) → "qwen2" refused (gguf_model_type) a_missing_gguf_architecture_is_refused_not_written_as_qwen2 RED
    3 tokenizer.ggml.model on GGUF export (both writers) → "gpt2" recorded type wins (bpe→gpt2); else merges ⇒ gpt2; else key omitted + warning tokenizer_ggml_model_is_recorded_or_evidenced_never_guessed RED
    4 APR CUDA cache quantized GEMV type → Q4_K (12) refused (recorded_quant_type) an_unrecorded_quant_type_is_refused_not_q4k RED
    5 normalize_architecture _ => "llama" — unchanged: resolve_global only returns a tensor whose name exists in the file and errors with every tried name, so this is a lookup miss, not a wrong bind —

    Two existing tests pinned the old qwen2 default; one now records an architecture, the other asserts the refusal.

    The pre-commit complexity check reads cache.rs together with its include!d files. So the two GH-201 streaming loaders in cuda_streaming_weights.rs (cognitive 43 and 31, already there before this branch) are split into helpers that behave the same.

    Receipts (one host, 4 cores, at d3e2ea8 unless noted):

    • cargo check -p aprender-core -p aprender-serve --lib --tests: rc=0
    • cargo check/clippy -p aprender-serve --lib --features cuda: rc=0 (at 2635a1d, before two test-only commits)
    • cargo test -p aprender-core --lib format::: 4034 passed, 0 failed
    • cargo test -p aprender-serve --lib apr::dequant: 8 passed
    • clippy -D warnings --lib --tests --keep-going: no finding in any changed file. The other 165 findings are already on main, in other aprender-core test code.
    • 4/4 plants: the test ran and failed (not a build error); tree restored, porcelain 0.

    Not covered here: the GH-181 raw Q4K pass-through (converter/mod.rs, around :206) maps every GGUF name through Architecture::Qwen2.map_name, whatever the file's architecture. It is the same class of default, and I left it out of this branch.

  3. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    Folded into #5311 as a checklist row (TRIAGE-100, 2026-10-14): the open-ticket cap is 100, so this ticket is now tracked on that master and closed as not planned. Nothing is lost: reopen it when its work resumes, and an open PR for it reopens it. Pushed branch: w71-e3a/4419-no-plausible-defaults.

    Agent: aprender-clerk

  4. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    Row moved: #5311 was split into named masters (TRIAGE-100 master naming), so this ticket's checklist row is now on #5328.

    Agent: aprender-clerk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High prioritybugSomething isn't workingowner:la-0.71Owned by the 0.71 look-ahead slotsize:MK̂ 3-4 h

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions