mod flatbuf;
mod gguf;
mod litertlm;
mod metadata;
mod protomin;
mod safetensors;
mod source;
mod spm;
mod tflite;
mod tokenizer;
pub use gguf::GgufSource;
pub mod quants {
pub use crate::gguf::{
dequantize_q4_0, dequantize_q4_k, dequantize_q5_0, dequantize_q5_k, dequantize_q6_k,
dequantize_q8_0,
};
}
pub use metadata::{Activation, AttentionPattern, ModelMetadata, RopeScaling, VisionConfig};
pub use safetensors::SafetensorsSource;
pub use litertlm::{SectionInfo, read_sections as litertlm_read_sections};
pub use source::{ModelSource, QuantFormat, QuantTensor, SamplerConfig, TensorDtype, TensorReader};
pub use spm::{ensure_tokenizer_json_from_spm, spm_added_tokens};
pub use tflite::TfliteSource;
pub use tokenizer::TokenizerSpec;
use std::path::Path;
pub fn open_model_source(path: impl AsRef<Path>) -> Result<Box<dyn ModelSource>> {
let path = path.as_ref();
if path.is_file() && path.extension().is_some_and(|e| e == "gguf") {
return Ok(Box::new(GgufSource::load(path)?));
}
if path.is_file() && path.extension().is_some_and(|e| e == "task" || e == "tflite") {
return Ok(Box::new(TfliteSource::load(path)?));
}
if path.is_file() && path.extension().is_some_and(|e| e == "litertlm") {
return litertlm::open_litertlm(path);
}
if path.is_dir() {
return Ok(Box::new(SafetensorsSource::load(path)?));
}
Err(FormatError::MissingFile(path.display().to_string()))
}
#[derive(Debug, thiserror::Error)]
pub enum FormatError {
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("json error in {context}: {source}")]
Json {
context: String,
source: serde_json::Error,
},
#[error("safetensors error: {0}")]
Safetensors(String),
#[error("tensor not found: {0}")]
TensorNotFound(String),
#[error("unsupported dtype for tensor {tensor}: {dtype}")]
UnsupportedDtype {
tensor: String,
dtype: String,
},
#[error("missing file: {0}")]
MissingFile(String),
#[error("missing config field: {0}")]
MissingField(String),
}
pub type Result<T> = std::result::Result<T, FormatError>;