Skip to content

doctor cache check misses revision-pinned HF models that resolve offline #963

Description

@fuzziness

Summary

qmd doctor reports a revision-pinned Hugging Face model as missing from the model cache even when node-llama-cpp resolves the same full URI from that cache with download: false.

Observed with @tobilu/qmd 2.8.3 and Node 24.20.0 on macOS. The same filename-matching code is present on main at the time of this report.

Minimal offline reproduction

Run from a QMD checkout with dependencies installed. The four-byte file is a synthetic fixture for the cache lookup: QMD's current inspectGgufFile regards a file beginning with GGUF as valid for this diagnostic. No model is downloaded or loaded.

repro_root=$(mktemp -d)
qmd_binary="$(pwd)/bin/qmd"
model_uri='hf:example/model/fixture.gguf#0123456789abcdef0123456789abcdef01234567'
mkdir -p "$repro_root/project/.qmd" "$repro_root/cache/qmd/models"
cat > "$repro_root/project/.qmd/index.yml" <<YAML
models:
  embed: $model_uri
  generate: $model_uri
  rerank: $model_uri
YAML
printf 'GGUF' > "$repro_root/cache/qmd/models/hf_example_model_0123456789abcdef0123456789abcdef01234567_fixture.gguf"
node --input-type=module -e '
  import { resolveModelFile } from "node-llama-cpp";
  const found = await resolveModelFile(process.argv[1], {
    directory: process.argv[2], download: false, cli: false
  });
  console.log(found);
' "$model_uri" "$repro_root/cache/qmd/models"
(
  cd "$repro_root/project"
  XDG_CACHE_HOME="$repro_root/cache" QMD_TRUST_LOCAL_CONFIG=1 QMD_DOCTOR_DEVICE_PROBE=0 NO_COLOR=1 "$qmd_binary" doctor
)

The offline resolver returns the existing file. qmd doctor exits 0 and prints:

⚠ model cache: missing 1/1: embedding+generation+reranking: hf:example/model/fixture.gguf#0123456789abcdef0123456789abcdef01234567. Next: run `qmd pull`

I also repeated this with three real GGUF blobs under the exact filenames required by the offline resolver for three distinct revision-pinned URIs. All three resolved with download: false and began with the GGUF magic; qmd doctor still reported missing 3/3. The cache directory inventory was unchanged by doctor.

Reproduction after an actual qmd pull

I also tested a fresh download into an empty, isolated cache with the 1.8 MB shibatch/tiny1m GGUF. All three roles use the same pinned URI so only one file needs downloading:

repro_root=$(mktemp -d)
qmd_binary="$(pwd)/bin/qmd"
model_uri='hf:shibatch/tiny1m/tiny1m.F16.gguf#dac47035fa06aa22cd694b67b8b744fd24e56ec3'
mkdir -p "$repro_root/project/.qmd" "$repro_root/cache" "$repro_root/home" "$repro_root/config"
cat > "$repro_root/project/.qmd/index.yml" <<YAML
models:
  embed: $model_uri
  generate: $model_uri
  rerank: $model_uri
collections: {}
YAML
(
  cd "$repro_root/project"
  export HOME="$repro_root/home" XDG_CACHE_HOME="$repro_root/cache"
  export QMD_CONFIG_DIR="$repro_root/config" QMD_TRUST_LOCAL_CONFIG=1 NO_COLOR=1
  "$qmd_binary" update
  "$qmd_binary" pull
  QMD_DOCTOR_DEVICE_PROBE=0 "$qmd_binary" doctor
)

qmd pull exited 0 and placed a 1,886,272-byte GGUF in the previously empty cache under hf_shibatch_tiny1m_dac47035fa06aa22cd694b67b8b744fd24e56ec3_tiny1m.F16.gguf. The same URI resolved from that cache with resolveModelFile(..., {download: false}). Immediately afterward, qmd doctor exited 0 and reported ⚠ model cache: missing 1/1 and suggested running qmd pull again. This confirms the mismatch also occurs after a real download through QMD, not only with hand-placed files.

Likely cause

findCachedModelInspection takes model.split("/").pop() as filename and requires a cache entry to both contain that string and end in .gguf. For a URI ending in .gguf#<revision>, filename includes the revision fragment, while the resolved cache filename places the revision before the GGUF filename. The substring check cannot find that entry. See findCachedModelInspection in v2.8.3.

Could doctor use a read-only lookup that follows the same full-URI cache identity as model resolution, including the revision? The check should remain offline and should not download or alter cached models.

Activity

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions