feat: update workspace paths and enhance gitignore
- Updated stablediffusion crate path from "../stable-diffusion-burn" to "./crates/stable-diffusion-burn" for proper workspace resolution - Enhanced .gitignore to include generated model files (.mpk, .pt, .bin, .safetensors, .ckpt) and user_data directory - Added Cargo.lock to gitignore with appropriate comment - Reorganized IDE files section in gitignore for better clarity - Added newline at end of file for proper formatting
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "safetensors-tests"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
burn = { path = "../../burn" }
|
||||
burn-ndarray = { path = "../../burn-ndarray" }
|
||||
burn-autodiff = { path = "../../burn-autodiff" }
|
||||
burn-store = { path = "../", features = ["std", "safetensors"] }
|
||||
serde = { workspace = true }
|
||||
float-cmp = { workspace = true }
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub type TestBackend = burn_ndarray::NdArray<f32>;
|
||||
@@ -0,0 +1,92 @@
|
||||
use burn::{
|
||||
module::Module,
|
||||
nn::{
|
||||
BatchNorm, BatchNormConfig, Linear, LinearConfig, PaddingConfig2d, Relu,
|
||||
conv::{Conv2d, Conv2dConfig},
|
||||
},
|
||||
tensor::{Tensor, backend::Backend},
|
||||
};
|
||||
|
||||
#[derive(Module, Debug)]
|
||||
pub struct Net<B: Backend> {
|
||||
conv1: Conv2d<B>,
|
||||
norm1: BatchNorm<B>,
|
||||
fc1: Linear<B>,
|
||||
relu: Relu,
|
||||
}
|
||||
|
||||
impl<B: Backend> Net<B> {
|
||||
pub fn new(device: &B::Device) -> Self {
|
||||
Self {
|
||||
conv1: Conv2dConfig::new([3, 4], [3, 3])
|
||||
.with_padding(PaddingConfig2d::Explicit(1, 1, 1, 1))
|
||||
.init(device),
|
||||
norm1: BatchNormConfig::new(4).init(device),
|
||||
fc1: LinearConfig::new(4 * 8 * 8, 16).init(device),
|
||||
relu: Relu::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Forward pass of the model.
|
||||
pub fn forward(&self, x: Tensor<B, 4>) -> Tensor<B, 2> {
|
||||
let x = self.conv1.forward(x);
|
||||
let x = self.norm1.forward(x);
|
||||
let x = self.relu.forward(x);
|
||||
// Flatten all dimensions except the batch dimension
|
||||
let x = x.flatten(1, 3);
|
||||
self.fc1.forward(x)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::backend::TestBackend;
|
||||
|
||||
use burn::tensor::Tolerance;
|
||||
use burn_store::{ModuleSnapshot, PyTorchToBurnAdapter, SafetensorsStore};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn multi_layer_model() {
|
||||
let device = Default::default();
|
||||
let mut model = Net::<TestBackend>::new(&device);
|
||||
let mut store = SafetensorsStore::from_file("tests/multi_layer/multi_layer.safetensors")
|
||||
.with_from_adapter(PyTorchToBurnAdapter);
|
||||
|
||||
model
|
||||
.load_from(&mut store)
|
||||
.expect("Should decode state successfully");
|
||||
|
||||
let input = Tensor::<TestBackend, 4>::ones([1, 3, 8, 8], &device);
|
||||
|
||||
let output = model.forward(input);
|
||||
|
||||
// Note: Expected values should be updated based on the actual output from the PyTorch model
|
||||
let expected = Tensor::<TestBackend, 2>::from_data(
|
||||
[[
|
||||
0.04971555,
|
||||
-0.16849735,
|
||||
0.05182848,
|
||||
-0.18032673,
|
||||
0.23138367,
|
||||
0.05041867,
|
||||
0.13005908,
|
||||
-0.32202929,
|
||||
-0.07915690,
|
||||
-0.03232457,
|
||||
-0.19790289,
|
||||
-0.17476529,
|
||||
-0.19627589,
|
||||
-0.21757686,
|
||||
-0.31376451,
|
||||
0.08377837,
|
||||
]],
|
||||
&device,
|
||||
);
|
||||
|
||||
output
|
||||
.to_data()
|
||||
.assert_approx_eq::<f32>(&expected.to_data(), Tolerance::default());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
from safetensors.torch import save_file
|
||||
|
||||
|
||||
class Model(nn.Module):
|
||||
def __init__(self):
|
||||
super(Model, self).__init__()
|
||||
self.conv1 = nn.Conv2d(3, 4, kernel_size=3, padding=1)
|
||||
self.norm1 = nn.BatchNorm2d(4)
|
||||
self.flatten = nn.Flatten()
|
||||
self.fc1 = nn.Linear(4 * 8 * 8, 16) # Changed for smaller input size
|
||||
|
||||
def forward(self, x):
|
||||
x = self.conv1(x)
|
||||
x = self.norm1(x)
|
||||
x = F.relu(x)
|
||||
x = self.flatten(x)
|
||||
x = self.fc1(x)
|
||||
return x
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
torch.set_printoptions(precision=8)
|
||||
torch.manual_seed(1)
|
||||
|
||||
model = Model().to(torch.device("cpu"))
|
||||
|
||||
# Use a smaller input size
|
||||
# 1 batch, 3 channels (RGB), 8x8 image (small input)
|
||||
x1 = torch.ones(1, 3, 8, 8)
|
||||
_ = model(x1)
|
||||
model.eval() # Set to eval mode to freeze running stats
|
||||
# Save the model to safetensors after the first forward
|
||||
save_file(model.state_dict(), "multi_layer.safetensors")
|
||||
|
||||
x2 = torch.ones(1, 3, 8, 8)
|
||||
print("Input shape: {}", x2.shape)
|
||||
output = model(x2)
|
||||
print("Output: {}", output)
|
||||
print("Output Shape: {}", output.shape)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,3 @@
|
||||
mod backend;
|
||||
|
||||
mod multi_layer;
|
||||
Reference in New Issue
Block a user