1use std::io::{Read, Seek};
2
3use anyhow::{Context, Result};
4use candle_core::quantized::gguf_file;
5use candle_core::{DType, Device, Tensor};
6
7pub fn load_tensor(
9 content: &gguf_file::Content,
10 reader: &mut (impl Read + Seek),
11 name: &str,
12 device: &Device,
13 dtype: DType,
14) -> Result<Tensor> {
15 let qt = content
16 .tensor(reader, name, device)
17 .with_context(|| format!("tensor '{name}' not found in GGUF"))?;
18 Ok(qt.dequantize(device)?.to_dtype(dtype)?)
19}
20
21pub fn try_load_tensor(
23 content: &gguf_file::Content,
24 reader: &mut (impl Read + Seek),
25 name: &str,
26 device: &Device,
27 dtype: DType,
28) -> Result<Option<Tensor>> {
29 match content.tensor(reader, name, device) {
30 Ok(qt) => Ok(Some(qt.dequantize(device)?.to_dtype(dtype)?)),
31 Err(_) => Ok(None),
32 }
33}
34
35pub fn load_weight(
39 content: &gguf_file::Content,
40 reader: &mut (impl Read + Seek),
41 name: &str,
42 expected_d_out: usize,
43 device: &Device,
44) -> Result<Tensor> {
45 let w = load_tensor(content, reader, name, device, DType::F32)?;
46 if w.dim(0)? != expected_d_out {
47 Ok(w.t()?.contiguous()?)
48 } else {
49 Ok(w)
50 }
51}
52
53pub fn load_vec(
55 content: &gguf_file::Content,
56 reader: &mut (impl Read + Seek),
57 name: &str,
58 device: &Device,
59) -> Result<Vec<f32>> {
60 Ok(load_tensor(content, reader, name, device, DType::F32)?
61 .flatten_all()?
62 .to_vec1()?)
63}