use crate::error::{Error, Result};
use candle_core::{DType, Device, Tensor};
use std::collections::HashMap;
use std::path::Path;
pub fn load_mmaped_safetensors<P: AsRef<Path>>(
file_path: P,
device: &Device,
dtype: DType,
) -> Result<HashMap<String, Tensor>> {
load_regular_safetensors(file_path, device, dtype)
}
pub fn load_regular_safetensors<P: AsRef<Path>>(
file_path: P,
device: &Device,
dtype: DType,
) -> Result<HashMap<String, Tensor>> {
let file_path = file_path.as_ref();
let tensors = candle_core::safetensors::load(file_path, device).map_err(|e| {
Error::model_loading(format!("Failed to load {}: {}", file_path.display(), e))
})?;
convert_tensors_dtype(tensors, dtype)
}
fn convert_tensors_dtype(
tensors: HashMap<String, Tensor>,
target_dtype: DType,
) -> Result<HashMap<String, Tensor>> {
let mut converted = HashMap::new();
for (name, tensor) in tensors {
let converted_tensor = if tensor.dtype() != target_dtype {
tensor.to_dtype(target_dtype).map_err(|e| {
Error::model_loading(format!(
"Failed to convert tensor '{}' from {:?} to {:?}: {}",
name,
tensor.dtype(),
target_dtype,
e
))
})?
} else {
tensor
};
converted.insert(name, converted_tensor);
}
Ok(converted)
}
pub fn get_safetensors_tensor_names<P: AsRef<Path>>(file_path: P) -> Result<Vec<String>> {
let file_path = file_path.as_ref();
let tensors =
candle_core::safetensors::load(file_path, &candle_core::Device::Cpu).map_err(|e| {
Error::model_loading(format!("Failed to load {}: {}", file_path.display(), e))
})?;
Ok(tensors.keys().cloned().collect())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dtype_conversion() {
let empty_tensors: HashMap<String, Tensor> = HashMap::new();
let result = convert_tensors_dtype(empty_tensors, DType::F16);
assert!(result.is_ok());
assert_eq!(result.unwrap().len(), 0);
}
}