Mila
Deep Neural Network Library
Loading...
Searching...
No Matches
Mila::Distribution::ModelStore Class Referenceexport

The local store of installed models. More...

Public Member Functions

 ModelStore (std::filesystem::path root=resolveStoreRoot())
std::filesystem::path adoptBlob (const std::string &description, const std::filesystem::path &source, const std::string &expected_sha256_hex, bool move_file=true)
 Take a file that is already on disk into the store, verifying it on the way.
std::filesystem::path blobPath (const std::string &sha256_hex) const
bool contains (const std::string &sha256_hex) const
StoredModel describe (const ModelRecord &record) const
 Resolve a record against the blob store without requiring it to be complete.
std::filesystem::path ensureBlob (const std::string &description, const std::string &expected_sha256_hex, const BlobFetcher &fetcher)
 Ensure a blob is present, fetching it if it is not.
StoredModel install (const ModelPackage &package, const InstallOptions &options={})
 Install one variant of a package, and record it.
std::vector< StoredModellist () const
 Every installed model, in directory order.
std::optional< StoredModellocate (const std::string &name) const
 Where an installed model's files are, or nothing.
RemovalReport prune (const PruneOptions &options={})
 Reclaim blobs no record names, rejected transfers, and abandoned locks.
std::optional< ModelRecordreadRecord (const std::string &name) const
std::filesystem::path recordPath (const std::string &name) const
RemovalReport remove (const std::string &name)
 Remove one installed model, then reclaim what nothing else references.
bool rename (const std::string &from, const std::string &to)
 Rename an installed model.
const std::filesystem::path & root () const noexcept
StoreUsage usage () const
 What the store holds and what could be reclaimed.
ModelRecord writeRecord (ModelRecord record)
 Write a record, stamping the install time.

Static Public Member Functions

static std::string foldName (std::string_view name)
 The case-folded form of a model name, which is what keys the store.

Detailed Description

The local store of installed models.

Layout:

*   models/<owner>/<repository>/<variant>.json   the records -- the index
*   blobs/sha256-<hex>                           the content
*   tmp/                                         in-flight transfers and their locks
* 

Member Function Documentation

◆ adoptBlob()

std::filesystem::path Mila::Distribution::ModelStore::adoptBlob ( const std::string & description,
const std::filesystem::path & source,
const std::string & expected_sha256_hex,
bool move_file = true )
inline

Take a file that is already on disk into the store, verifying it on the way.

The counterpart to ensureBlob for bytes that need no transfer. It hashes rather than trusting the caller, because the store's whole guarantee is that a path names its content – a blob adopted unverified would poison every later cache hit.

A move publishes by rename when the package and the store share a volume, which costs nothing whatever the file's size. Across volumes there is no atomic move, so the bytes go through tmp/ and are renamed from there: a partial copy must never occupy a path that implies verification.

Returns
Path to the verified blob.
Exceptions
std::runtime_erroron a digest mismatch or a lock held by another process.

◆ ensureBlob()

std::filesystem::path Mila::Distribution::ModelStore::ensureBlob ( const std::string & description,
const std::string & expected_sha256_hex,
const BlobFetcher & fetcher )
inline

Ensure a blob is present, fetching it if it is not.

Resumes from whatever a previous attempt left in tmp/, which is why the partial is named after the digest rather than randomly – a retry must be able to find it. The hash is recomputed over the resumed prefix before appending, because SHA-256 is sequential and cannot be restored from a byte offset alone.

A transfer lock arbitrates between processes. Chat and the inference server share one store, and the deterministic partial name that makes resume possible would otherwise let two of them append into a single file and interleave.

On a digest mismatch the partial is kept under a rejected name rather than destroyed: the bytes are known bad, but the byte count is the evidence that separates "altered in flight" from "a length bug", and destroying it destroys the diagnosis.

Parameters
descriptionWhat the blob is, for messages only – typically the file's path in the repository it came from. The store never interprets it.
expected_sha256_hexThe blob's digest, which is also its name under blobs/.
fetcherSupplies the bytes when the blob is absent, resuming from any partial.
Returns
Path to the verified blob.
Exceptions
std::runtime_erroron fetch failure, digest mismatch, or a lock held elsewhere.

◆ foldName()

std::string Mila::Distribution::ModelStore::foldName ( std::string_view name)
inlinestatic

The case-folded form of a model name, which is what keys the store.

A name is a filename, so without folding the store inherits the filesystem's opinion of case: /install Llama-3.1-8B resolves on Windows and fails on Linux, and the developer's platform is the forgiving one – so the failure only ever appears for someone else. Folding makes one name mean one model on both.

ASCII by hand rather than std::tolower, which is locale-dependent (a Turkish locale maps 'I' to a dotless form and would key the same model two ways). requireUsableName already restricts names to [A-Za-z0-9._-], so ASCII is the whole domain.

The record keeps the name as it was published – this folds the key, never the label.

◆ install()

StoredModel Mila::Distribution::ModelStore::install ( const ModelPackage & package,
const InstallOptions & options = {} )
inline

Install one variant of a package, and record it.

Publishing to the local store and publishing to a hub take the same directory: what differs is only where the bytes go. The record is written last, after every file has verified, so a failed install leaves nothing that looks installed.

The package is not validated first on purpose. Adoption hashes each file as it takes it, so a separate validate() pass would read every byte a second time – at 6.8 GB that is not a cost worth paying for a check that already happened.

Exceptions
std::runtime_errorif the variant does not exist, if it needs a newer Mila, if a file's digest disagrees with the manifest, or if the names do not form a coordinate.

◆ list()

std::vector< StoredModel > Mila::Distribution::ModelStore::list ( ) const
inline

Every installed model, in directory order.

A record whose blobs have gone missing is reported with complete false rather than omitted: a store that silently hides a broken entry cannot be repaired by its owner.

◆ locate()

std::optional< StoredModel > Mila::Distribution::ModelStore::locate ( const std::string & name) const
inline

Where an installed model's files are, or nothing.

Never consults a hub and never accepts a path: the store is the only thing a load reads from. A record whose blobs are incomplete resolves to nothing, because a caller that receives a path expects bytes behind it.

◆ prune()

RemovalReport Mila::Distribution::ModelStore::prune ( const PruneOptions & options = {})
inline

Reclaim blobs no record names, rejected transfers, and abandoned locks.

Mark-and-sweep over the record tree is exact and costs a directory walk: records are kilobytes, and the alternative – a reference count maintained by hand – is a number that can be wrong.

◆ remove()

RemovalReport Mila::Distribution::ModelStore::remove ( const std::string & name)
inline

Remove one installed model, then reclaim what nothing else references.

The sweep is what makes this safe. Deduplication means a tokenizer blob may back several models, so removal cannot delete a model's files simply because that model is going.

◆ rename()

bool Mila::Distribution::ModelStore::rename ( const std::string & from,
const std::string & to )
inline

Rename an installed model.

One record is rewritten and nothing else moves. The blobs are content-addressed, so what a model is called here has no bearing on where its bytes live; and origin is a field rather than a path segment, so a renamed model still says where it came from.

The install time is carried over: renaming is not reinstalling.

Returns
False when no model of that name is installed.
Exceptions
std::runtime_errorif the new name is unusable or already taken.

◆ writeRecord()

ModelRecord Mila::Distribution::ModelStore::writeRecord ( ModelRecord record)
inline

Write a record, stamping the install time.

Written to tmp/ and renamed, because a peer process may be listing the store while this one installs, and a half-written record must never be readable.

Persist a record, and hand back what was actually written.

Returns the record rather than void because the install time is stamped here: a caller that kept its own copy would hold one that disagrees with the store.


The documentation for this class was generated from the following file: