use anyhow::{Context, Result};
use mlx_native::gguf::GgufFile;
use crate::serve::gpu::GpuContext;
use super::cache::{CacheError, Deepseek4Cache, Deepseek4CachePlan};
use super::{Deepseek4Config, Deepseek4Weights};
pub struct Deepseek4Model {
pub cfg: Deepseek4Config,
pub weights: Deepseek4Weights,
pub ctx: GpuContext,
}
impl Deepseek4Model {
pub fn load_from_gguf(gguf: &GgufFile) -> Result<Self> {
let cfg = Deepseek4Config::from_gguf(gguf).context("Deepseek4Config::from_gguf")?;
let ctx = GpuContext::new()
.map_err(|source| anyhow::anyhow!("DeepSeek-V4 Metal initialization: {source}"))?;
let weights = Deepseek4Weights::load_from_gguf(gguf, &cfg, ctx.device().clone())
.context("Deepseek4Weights::load_from_gguf")?;
Ok(Self { cfg, weights, ctx })
}
pub fn load_config_only(gguf: &GgufFile) -> Result<Deepseek4Config> {
Deepseek4Config::from_gguf(gguf)
}
pub fn cache_plan(&self, context_length: usize) -> Result<Deepseek4CachePlan, CacheError> {
Deepseek4CachePlan::for_context(&self.cfg, context_length)
}
pub fn allocate_cache(&self, context_length: usize) -> Result<Deepseek4Cache, CacheError> {
let plan = self.cache_plan(context_length)?;
Deepseek4Cache::allocate(&plan, self.ctx.device().clone())
}
pub fn allocate_logical_cache(
&self,
context_length: usize,
) -> Result<Deepseek4Cache, CacheError> {
let plan = self.cache_plan(context_length)?;
Deepseek4Cache::allocate_logical(&plan, self.ctx.device().clone())
}
}