Local model sources and presets
- In one line
- A model comes from a file on disk or a Hugging Face file, pinned by revision and SHA-256 for the presets; the download resumes, verifies and caches.
- You need
- The
provider-localfeature. Network access once, for a Hugging Face source. - Read this if
- You are choosing where the model file comes from, or debugging a download or the cache.
Model sources and presets
LocalModelConfig::source is a ModelSource:
ModelSource::File(path)is a GGUF file already on disk; nothing is downloaded.ModelSource::HuggingFace { repo, revision, file, sha256 }is a file on Hugging Face.sha256: Noneskips the checksum.ModelSource::hugging_face(repo, revision, file)builds the same value withsha256: None, so the download is not verified. Use a commit hash as the revision, because the cache is keyed by it and a moving ref such asmainpins a stale file.ModelSource::default_model()is the presetgemma4-e2b-q4_0."name".parse::<ModelSource>()?accepts a preset name (ASCII case-insensitive) orrepo:revision:file, where none of the three parts contains:. The result ofrepo:revision:filehas no checksum.
ModelSource::PRESETS has 23 entries, each pinned to one Hugging Face commit and one SHA-256. A ModelPreset has name, repo, revision, file, sha256, size_bytes, architecture and drafter. preset.source() returns its pinned ModelSource, and ModelSource::preset(name) finds one by name. A preset with drafter: true is used through LocalModelConfig::drafter and cannot be loaded as the main model. The table with sizes and K/V cost is on Local models and formats.
use cuca::ModelSource;
fn main() {
for preset in ModelSource::PRESETS {
println!(
"{:<28} {:<17} {:>14} bytes {}{}",
preset.name,
preset.architecture,
preset.size_bytes,
preset.repo,
if preset.drafter { " (drafter)" } else { "" },
);
}
}use cuca::{LocalModel, LocalModelConfig, ModelSource};
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Qwen3 0.6B at Q8_0 instead of the default; the rest of the program is the
// same as above.
let model = LocalModel::load(LocalModelConfig {
source: "qwen3-0.6b-q8_0".parse::<ModelSource>()?,
..Default::default()
})
.await?;
println!("{model:?}");
Ok(())
}
A file of an architecture the engine does not know fails to load with a CucaError::Provider that names the architecture and lists the supported ones. The chat template and the tokenizer come from the file; a tokenizer model the engine does not implement fails the same way.
Download and cache
A Hugging Face source is downloaded once from https://huggingface.co/{repo}/resolve/{revision}/{file} into the cache directory.
- The cache root is
LocalModelConfig::cache_dir, elseCUCA_CACHE_DIR, else the platform directory. Empty environment values count as unset. - The platform directory is
%LOCALAPPDATA%\cucaon Windows (else%USERPROFILE%\AppData\Local\cuca),$HOME/Library/Caches/cucaon macOS, and$XDG_CACHE_HOME/cucaon Linux (else$HOME/.cache/cuca). - The file lands at
<cache>/huggingface/<repo with / as -->/<revision>/<file>. - An interrupted download resumes from the
<file>.partialfile with an HTTPRangerequest, and restarts from byte 0 once per call if the server ignores or rejects the range. - The SHA-256 is computed while streaming, covering any resumed bytes. A mismatch deletes the partial file and fails the load.
- The verified file is renamed into place atomically, so a final file that exists is complete.
- An exclusive lock file,
<file>.lock, serializes concurrent loaders in this process or another. The empty file stays in the cache on purpose: deleting it after unlock would race with a process still blocked on it. - Memory use during the download is bounded by a 1 MiB write buffer and one network chunk.
LocalModelConfig::on_download_progresstakes aDownloadProgressCallbackthat receivesDownloadProgress { downloaded_bytes, total_bytes }at the start, about every mebibyte and at the end.total_bytesisNonewhen the server reports no size. The callback runs on the engine thread duringload, so keep it cheap.hf_token, orHF_TOKENwhen it isNone, is sent as a bearer token; the pinned preset files download anonymously.- The download uses a private HTTP client and runtime, separate from the
CucaClientone.