BioPhys-Neural-Agent / src /bpsn_loader.rs
minseok
๐ŸŒŒ Release BioPhys 6.0 Grand Master: 16GB (14.89GB) Gemma-4 100% Devour, Ecosystem Evolution, Solar MoE, SNN Autoregressive SDK, Dynamic PhaseVM
be99550
Raw
History Blame Contribute Delete
3.7 kB
//! BioPhys Neural ๊ฐ€์ค‘์น˜ ํŒŒ์ผ(.bpsn) ํŒŒ์„œ
//! ํŒŒ์ผ ๊ตฌ์กฐ: [๋งค์ง(8B)][์ด๋ฆ„๊ธธ์ด(4B)][์ด๋ฆ„(NB)][๊ฐ€์ค‘์น˜(0x55AA ํŒจํ„ด)]
use std::path::Path;
use std::fs;
/// BPSN ํŒŒ์ผ ๋งค์ง ๋„˜๋ฒ„
const BPSN_MAGIC: &[u8] = b"BPSN4.0_";
/// ํŒŒ์‹ฑ๋œ BioPhys ๋‡Œ ๋ชจ๋ธ
#[derive(Debug, Clone)]
pub struct BpsnModel {
pub name: String,
pub weights: Vec<u32>, // 2-bit ํŒจํ‚น ๊ฐ€์ค‘์น˜ (uint32 = 16์ฟผํฌ)
pub weight_count: usize,
pub size_mb: f32,
}
impl BpsnModel {
/// .bpsn ํŒŒ์ผ ๋กœ๋”ฉ ๋ฐ ํŒŒ์‹ฑ
pub fn load(path: &Path) -> Result<Self, String> {
let bytes = fs::read(path)
.map_err(|e| format!("ํŒŒ์ผ ์ฝ๊ธฐ ์‹คํŒจ: {}", e))?;
// ๋งค์ง ๋„˜๋ฒ„ ๊ฒ€์ฆ
if bytes.len() < 12 || &bytes[0..8] != BPSN_MAGIC {
return Err(format!("์œ ํšจํ•˜์ง€ ์•Š์€ BPSN ํŒŒ์ผ: {:?}", path));
}
// ๋ชจ๋ธ๋ช… ๊ธธ์ด (bytes[8..12] = u32 LE)
let name_len = u32::from_le_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]) as usize;
// ๋ชจ๋ธ๋ช… ํŒŒ์‹ฑ
let name_start = 12;
let name_end = (name_start + name_len).min(bytes.len());
let name = String::from_utf8_lossy(&bytes[name_start..name_end])
.trim_end_matches('\0')
.to_string();
// ๊ฐ€์ค‘์น˜ ๋ฐ์ดํ„ฐ (์ด๋ฆ„ ์ดํ›„ ๋‚˜๋จธ์ง€ ์ „๋ถ€)
let weight_start = name_start + name_len;
let weight_bytes = &bytes[weight_start..];
// u8 โ†’ u32 ํŒจํ‚น (4๋ฐ”์ดํŠธ = 1 ์ฟผํฌ ํŒจํ‚ท = 16๊ฐœ 2-bit ๊ฐ€์ค‘์น˜)
let weights: Vec<u32> = weight_bytes
.chunks(4)
.filter(|c| c.len() == 4)
.map(|c| u32::from_le_bytes([c[0], c[1], c[2], c[3]]))
.collect();
let weight_count = weights.len();
let size_mb = bytes.len() as f32 / 1024.0 / 1024.0;
Ok(BpsnModel { name, weights, weight_count, size_mb })
}
/// ๊ฐ€์ค‘์น˜๋ฅผ ๋ฐ”์ดํŠธ ์Šฌ๋ผ์ด์Šค๋กœ ๋ฐ˜ํ™˜ (GPU ์—…๋กœ๋“œ์šฉ)
pub fn weights_as_bytes(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(
self.weights.as_ptr() as *const u8,
self.weights.len() * 4,
)
}
}
/// ์ดˆ๋ˆ ๊ณต๋ช… ์—ฐ์‚ฐ (CPU ํด๋ฐฑ)
pub fn superstring_spin(&self, input_idx: usize, wave: u32) -> f32 {
if input_idx >= self.weights.len() { return 0.0; }
let quark = self.weights[input_idx] ^ wave;
quark.count_ones() as f32 * 1.414
}
/// ๋ชจ๋ธ ์š”์•ฝ ์ถœ๋ ฅ
pub fn summary(&self) {
println!(" ๐Ÿ“ฆ [BPSN] ๋ชจ๋ธ: {}", self.name);
println!(" ๐Ÿ“ฆ ๊ฐ€์ค‘์น˜ ํŒจํ‚ท: {}๊ฐœ ({}ร—16 = {}๊ฐœ ์ฟผํฌ)",
self.weight_count,
self.weight_count,
self.weight_count * 16);
println!(" ๐Ÿ“ฆ ํŒŒ์ผ ํฌ๊ธฐ: {:.3}MB", self.size_mb);
println!(" ๐Ÿ“ฆ ์ƒ˜ํ”Œ[0]: 0x{:08X} ({:08b}...)",
self.weights.get(0).copied().unwrap_or(0),
self.weights.get(0).copied().unwrap_or(0));
}
}
/// ๋ชจ๋“  .bpsn ๋ชจ๋ธ ์ผ๊ด„ ๋กœ๋”ฉ
pub fn load_all_brains(dir: &Path) -> Vec<BpsnModel> {
let mut models = Vec::new();
let pattern = dir.join("*_8state.bpsn");
if let Ok(entries) = fs::read_dir(dir) {
for entry in entries.flatten() {
let p = entry.path();
if p.extension().map(|e| e == "bpsn").unwrap_or(false) {
match BpsnModel::load(&p) {
Ok(m) => { println!(" โœ… ๋กœ๋”ฉ ์™„๋ฃŒ: {}", m.name); models.push(m); },
Err(e) => println!(" โŒ ๋กœ๋”ฉ ์‹คํŒจ: {} โ†’ {}", p.display(), e),
}
}
}
}
models
}