minseok
๐ Release BioPhys 6.0 Grand Master: 16GB (14.89GB) Gemma-4 100% Devour, Ecosystem Evolution, Solar MoE, SNN Autoregressive SDK, Dynamic PhaseVM
be99550 | //! BioPhys Neural ๊ฐ์ค์น ํ์ผ(.bpsn) ํ์ | |
| //! ํ์ผ ๊ตฌ์กฐ: [๋งค์ง(8B)][์ด๋ฆ๊ธธ์ด(4B)][์ด๋ฆ(NB)][๊ฐ์ค์น(0x55AA ํจํด)] | |
| use std::path::Path; | |
| use std::fs; | |
| /// BPSN ํ์ผ ๋งค์ง ๋๋ฒ | |
| const BPSN_MAGIC: &[u8] = b"BPSN4.0_"; | |
| /// ํ์ฑ๋ BioPhys ๋ ๋ชจ๋ธ | |
| 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 | |
| } | |