Skip to main content

combs_models/
lib.rs

1//! # combs-models
2//!
3//! Model architecture registry. The runtime drives any architecture through
4//! the fixed [`GenerativeModel`] contract (MLC's `embed/prefill/decode/
5//! create_kv_cache` function set); architectures register themselves in the
6//! [`ModelRegistry`]. Phase 1 ships the Llama family (incl. SmolLM2).
7
8mod act;
9mod archspec;
10mod kv;
11mod llama;
12mod matmul;
13mod norm;
14mod precision;
15mod qkernel;
16mod qlinear;
17mod qmatmul;
18mod quant_linear;
19mod registry;
20mod rope;
21mod smolvlm;
22mod traits;
23mod whisper;
24
25pub use archspec::{ArchSpec, LayerKind, NormFlavor};
26pub use kv::{CacheConfig, CacheKind, ContiguousKVCache, KVCache, PageStats, PagedKVCache};
27pub use llama::LlamaModel;
28pub use norm::rms_norm;
29pub use qlinear::{Linear, QuantLinearOp, try_quant_linear};
30pub use qmatmul::{
31    Q4KWeight, Q5KWeight, Q6KWeight, Q40Weight, Q50Weight, Q80Weight, dequantize_q4_0_gpu,
32    dequantize_q4_k_gpu, dequantize_q5_0_gpu, dequantize_q5_k_gpu, dequantize_q6_k_gpu,
33    dequantize_q8_0_gpu,
34    repack_q4_0, repack_q4_k, repack_q5_0, repack_q6_k, repack_q8_0,
35};
36pub use quant_linear::QuantizedLinear;
37pub use registry::ModelRegistry;
38pub use rope::RotaryEmbedding;
39pub use smolvlm::{SmolVlmModel, image_prompt_expansion, pixels_to_tensor};
40pub use whisper::{WhisperModel, load_speech_model};
41pub use traits::{GenerativeModel, SpeechToTextModel};
42
43/// Errors produced while constructing or running models.
44#[derive(Debug, thiserror::Error)]
45pub enum ModelError {
46    /// A format-adapter error.
47    #[error(transparent)]
48    Format(#[from] combs_formats::FormatError),
49
50    /// No registered architecture matches the source metadata.
51    #[error("unsupported architecture: {0}")]
52    UnsupportedArchitecture(String),
53
54    /// Media input (image/audio) was passed to a model that cannot take it.
55    #[error("unsupported media input: {0}")]
56    UnsupportedMedia(String),
57
58    /// The model does not implement an optional capability (e.g. hidden
59    /// states for embeddings).
60    #[error("unsupported operation: {0}")]
61    Unsupported(String),
62
63    /// A required weight tensor is missing from the source.
64    #[error("missing weight tensor: {0}")]
65    MissingTensor(String),
66
67    /// A weight tensor has an unexpected shape.
68    #[error("bad shape for {tensor}: expected {expected:?}, got {got:?}")]
69    BadShape {
70        /// Tensor name.
71        tensor: String,
72        /// Expected shape.
73        expected: Vec<usize>,
74        /// Actual shape.
75        got: Vec<usize>,
76    },
77}
78
79/// Convenient result alias for this crate.
80pub type Result<T> = std::result::Result<T, ModelError>;
81
82/// Test-only guard: true (after logging) when the machine has no wgpu
83/// adapter, so GPU-dependent tests can skip instead of panicking inside
84/// cubecl's device worker. Real GPU coverage is unaffected wherever an
85/// adapter exists — CI's macOS runners included.
86#[cfg(test)]
87pub(crate) fn skip_no_gpu() -> bool {
88    if combs_core::gpu_available() {
89        return false;
90    }
91    eprintln!("skipped: no wgpu adapter on this machine");
92    true
93}