Kopitiam Runtime: native model file loaders.
This crate turns a GGUF or SafeTensors file on disk into a
format-agnostic description of what it contains: model-level
hyperparameters ([ModelMetadata]) and a directory of tensors, each
described by name, [kopitiam_core::DType], [kopitiam_core::Shape],
and its raw on-disk bytes ([TensorEntry], served through
[LoadedModel::tensor_bytes]).
Why this crate never constructs a Tensor
kopitiam-tensor — the crate that owns the Tensor type — is being
developed independently of this one. Depending on it here would couple
two crates whose APIs are each still settling, for a feature this crate
does not need: nothing a loader does requires an actual Tensor, only
the bytes, dtype and shape needed to build one. So this crate stops one
step short: [LoadedModel::tensor_bytes] hands back exactly those
bytes, and whoever does depend on kopitiam-tensor combines them with
the dtype and shape from [LoadedModel::tensor] to build the tensor on
their side of the boundary. Neither crate has to know the other's
internals for this to work.
Supported formats
- GGUF ([
GgufLoader], modulegguf) — thellama.cpp/ggmlformat. Note its on-disk dimension order is the reverse of this crate's [kopitiam_core::Shape] convention; see theggufmodule docs before touching anything shape-related there. - SafeTensors ([
SafeTensorsLoader], modulesafetensors) — Hugging Face's format. Its dimension order already matchesShape's convention directly.
[load_model] picks between the two by sniffing file content (GGUF has
a magic number; SafeTensors does not, so it is the fallback), so most
callers only need that one function.
Memory strategy
Model files are memory-mapped where possible rather than read fully
into a Vec<u8> — see the internal byte_source module's doc for why
that matters at multi-gigabyte model sizes and when this crate falls
back to a plain read instead.
Malformed input
Every parser in this crate treats its input as untrusted: truncated
files, offsets that point past end-of-file, and absurd counts that
would otherwise justify a huge allocation all become
[kopitiam_core::Error::MalformedModel] rather than a panic. A tensor
type or dtype this crate cannot represent becomes
[kopitiam_core::Error::UnsupportedModelFeature] instead of being
silently misdecoded as something else.