fix(runtime): finalize HF model download (create snapshot symlink) — fixes model-not-found on every binary - #47
Merged
Conversation
Downloading a model from Hugging Face left the blob in the cache but the
resolved path dangling, so every run failed at warmup with:
embedding model not found after resolution:
.../snapshots/<rev>/<model>.gguf
resolve_hf_model called common_download_get_hf_plan + common_download_run_tasks
(which writes the blob to blobs/<sha>) but never called hf_cache::finalize_file
— the function that creates the snapshots/<rev>/<file> -> ../../blobs/<sha>
symlink and returns the usable path. llama.cpp's own common/arg.cpp does
get_hf_plan -> run_tasks -> finalize_file; the bridge skipped the last step (a
b9837 change split the snapshot bookkeeping out of run_tasks).
Call hf_cache::finalize_file(plan.primary) after the download and use its
return value: it creates the snapshot symlink, or returns the blob path
directly if symlinks are unavailable. This affects every backend, including
the shipped prebuilt binaries — HF model download was broken for all of them.
Verified: the bridge compiles against b9837 in both prebuilt and source modes,
and finalize_file resolves from hf-cache.h.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes Hugging Face model downloads in the llama.cpp bridge by ensuring the resolved snapshot path is actually materialized after downloading (preventing “model not found after resolution” failures in warmup for shipped binaries).
Changes:
- Include llama.cpp’s HF cache API header (
hf-cache.h) in the bridge. - After
common_download_run_tasks, callhf_cache::finalize_file(plan.primary)and use its returned path as the load path (creating thesnapshots/<rev>/<file> -> ../../blobs/<sha>symlink when supported).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Critical: HF model download is broken in every shipped binary
Any run that downloads a model from Hugging Face fails at warmup:
The download succeeds — the full GGUF blob lands in
blobs/<sha>— but the resolved path (snapshots/<rev>/<file>) is a symlink that never gets created, soModelHandle::load'spath.exists()check fails.Root cause
resolve_hf_modelin the bridge does:Since b9837, writing the blob and creating the
snapshots/<rev>/<file> → ../../blobs/<sha>symlink are separate steps. The symlink + path selection is done by the publichf_cache::finalize_file()(hf-cache.cpp). llama.cpp's owncommon/arg.cppdoesget_hf_plan → run_tasks → finalize_file; the bridge skipped that last step.Fix
Call
hf_cache::finalize_file(plan.primary)after the download and use its return value — it creates the snapshot symlink (or returns the blob path directly if symlinks are unavailable) and hands back the path to load. Exactly mirrors upstreamarg.cpp.Verification
finalize_fileresolves fromhf-cache.h.GGUFmagic) sitting inblobs/with an emptysnapshots/; manually creating the exact symlinkfinalize_filewould make lets the resolved path load.Impact / merge priority
This affects every backend, including the released prebuilt binaries — HF
--hf-repodownloads (the default onboarding path viaautocommit init) are broken without it. Worth merging ahead of av0.17.6tag.