use std::error::Error; use std::io::Read; use npy::{self, NpyData}; use num_traits::cast::ToPrimitive; use burn::{ config::Config, module::{Module, Param}, nn::{self, conv}, tensor::{ backend::Backend, Tensor, Data, }, }; use burn::tensor::ElementConversion; pub fn numpy_to_tensor(numpy_data: NpyData, device: &B::Device) -> Tensor { let mut v = numpy_data.to_vec(); let shape: Vec<_> = v[0..D].into_iter().map(|&v| v as usize).collect(); let data: Vec = v[D..].into_iter().map(|e| e.elem()).collect(); Tensor::from_data_device(Data::new(data, shape.into()), device) } pub fn load_tensor(name: &str, path: &str, device: &B::Device) -> Result, Box> { let tensor_path = format!("{}/{}.npy", path, name); let mut buf = vec![]; std::fs::File::open(&tensor_path)? .read_to_end(&mut buf)?; let tensor_numpy: NpyData = NpyData::from_bytes(&buf)?; let tensor = numpy_to_tensor(tensor_numpy, device); println!("{}", tensor_path); Ok(tensor) } pub fn load_f32(name: &str, path: &str, device: &B::Device) -> Result> { load_tensor::(name, path, device).map(|t| t.into_scalar().to_f32().unwrap()) } pub fn load_usize(name: &str, path: &str, device: &B::Device) -> Result> { load_tensor::(name, path, device).map(|t| t.into_scalar().to_usize().unwrap()) } pub fn load_linear(path: &str, device: &B::Device) -> Result, Box> { let weight = load_tensor::("weight", path, device)?; let bias = load_tensor::("bias", path, device).ok(); let record = nn::LinearRecord { weight: weight.into(), bias: bias.map(|t| t.into()), }; let linear: nn::Linear = nn::LinearConfig::new(3, 3).init_with(record); Ok(linear) } pub fn load_embedding(path: &str, device: &B::Device) -> Result, Box> { let weight = load_tensor::("weight", path, device)?; let [n_vocab, n_state] = weight.dims(); let record = nn::EmbeddingRecord { weight: weight.into(), }; let embedding = nn::EmbeddingConfig::new(n_vocab, n_state).init_with(record); Ok(embedding) } pub fn load_layer_norm(path: &str, device: &B::Device) -> Result, Box> { let weight = load_tensor::("weight", path, device)?; let bias = load_tensor::("bias", path, device)?; let eps = load_f32::("eps", path, device)? as f64; let [n_state] = weight.dims(); let record = nn::LayerNormRecord { gamma: weight.into(), beta: bias.into(), epsilon: >::into_record(eps), }; let layer_norm: nn::LayerNorm = nn::LayerNormConfig::new(n_state).init_with(record); Ok(layer_norm) } /*pub fn load_rmsnorm(path: &str, device: &B::Device) -> Result, Box> { let weight = load_tensor::("weight", path, device)?; let eps = load_f32::("eps", path, device)?.into(); let rmsnorm = RMSNorm { weight: weight.into(), eps: eps }; Ok(rmsnorm) }*/ pub fn load_conv2d(path: &str, device: &B::Device) -> Result, Box> { let weight = load_tensor::("weight", path, device)?; let bias = load_tensor::("bias", path, device).ok(); let has_bias = bias.is_some(); let stride = load_tensor::("stride", path, device)?; let stride = tensor_to_array_2(stride); let kernel_size = load_tensor::("kernel_size", path, device)?; let kernel_size = tensor_to_array_2(kernel_size); let dilation = load_tensor::("dilation", path, device)?; let dilation = tensor_to_array_2(dilation); let n_group = load_usize::("n_group", path, device)?.into(); let n_channels_in = load_usize::("n_channels_in", path, device)?.into(); let n_channels_out = load_usize::("n_channels_out", path, device)?.into(); let padding = load_tensor::("padding", path, device)?; let padding = tensor_to_array_2(padding); let padding = nn::PaddingConfig2d::Explicit(padding[0], padding[1]); let record = conv::Conv2dRecord { weight: weight.into(), bias: bias.map(|t| t.into()), stride: <[usize; 2] as Module>::into_record(stride), kernel_size: <[usize; 2] as Module>::into_record(kernel_size), dilation: <[usize; 2] as Module>::into_record(dilation), groups: >::into_record(n_group), padding: >::into_record(padding.clone()), }; let conv2d: conv::Conv2d = conv::Conv2dConfig::new([n_channels_in, n_channels_out], kernel_size) .with_stride(stride) .with_dilation(dilation) .with_groups(n_group) .with_padding(padding) .with_bias(has_bias) .init_with(record); Ok(conv2d) } pub fn tensor_to_array_2(x: Tensor) -> [usize; 2] { let vec = x.into_data().value; assert!(vec.len() == 2, "Tensor length must be 2."); [vec[0].to_usize().unwrap(), vec[1].to_usize().unwrap()] } pub fn tensor_to_array(x: Tensor) -> [usize; N] { let vec = x.into_data().value; assert!(vec.len() == N, "Tensor length must be {}.", N); let mut arr = [0; N]; for (a, t) in arr.iter_mut().zip(vec) { *a = t.to_usize().unwrap(); } arr }