minseok
π Release BioPhys 6.0 Grand Master: 16GB (14.89GB) Gemma-4 100% Devour, Ecosystem Evolution, Solar MoE, SNN Autoregressive SDK, Dynamic PhaseVM
be99550 | // π₯© μΈλΆ κ°μ€μΉ ν μ μ§μ μμ·¨ λ° μν ν‘μ μμ§ (src/bin/ingest_weights.rs) | |
| use std::time::Instant; | |
| use std::thread; | |
| pub enum Phase8 { | |
| HyperInhibit = 0, | |
| Inhibit = 1, | |
| SubInhibit = 2, | |
| NegZero = 3, | |
| PosZero = 4, | |
| SubExcite = 5, | |
| Excite = 6, | |
| HyperExcite = 7, | |
| } | |
| impl Phase8 { | |
| pub fn to_weight(self) -> f32 { | |
| match self { | |
| Phase8::HyperInhibit => -2.0, | |
| Phase8::Inhibit => -1.0, | |
| Phase8::SubInhibit => -0.5, | |
| Phase8::NegZero => -0.01, | |
| Phase8::PosZero => 0.01, | |
| Phase8::SubExcite => 0.5, | |
| Phase8::Excite => 1.0, | |
| Phase8::HyperExcite => 2.0, | |
| } | |
| } | |
| pub fn from_raw_weight(w: f32) -> Self { | |
| if w <= -1.5 { Phase8::HyperInhibit } | |
| else if w <= -0.75 { Phase8::Inhibit } | |
| else if w <= -0.25 { Phase8::SubInhibit } | |
| else if w <= 0.0 { Phase8::NegZero } | |
| else if w <= 0.25 { Phase8::PosZero } | |
| else if w <= 0.75 { Phase8::SubExcite } | |
| else if w <= 1.5 { Phase8::Excite } | |
| else { Phase8::HyperExcite } | |
| } | |
| } | |
| pub struct WeightDigestionEngine { | |
| pub size: usize, | |
| pub ingested_weights: Vec<Phase8>, | |
| pub bedrock: Vec<f32>, | |
| } | |
| impl WeightDigestionEngine { | |
| pub fn new(size: usize) -> Self { | |
| let total = size * size; | |
| WeightDigestionEngine { | |
| size, | |
| ingested_weights: vec![Phase8::PosZero; total], | |
| bedrock: vec![0.0; total], | |
| } | |
| } | |
| /// μΈλΆ κ°μ€μΉ ν μ λ°°μ΄(100λ§ κ°)μ ν΅μ§Έλ‘ μμ·¨(Ingest)νμ¬ 8λ μμμΌλ‘ λ§€ν | |
| pub fn ingest_raw_tensor(&mut self, raw_weights: &[f32]) { | |
| assert_eq!(raw_weights.len(), self.size * self.size); | |
| for (i, &w) in raw_weights.iter().enumerate() { | |
| self.ingested_weights[i] = Phase8::from_raw_weight(w); | |
| self.bedrock[i] = w * 0.1; // κ°μ€μΉμ κΈ°μ ν¬ν μ ν‘μ | |
| } | |
| } | |
| /// μμ·¨ν κ°μ€μΉλ₯Ό 16κ° μ½μ΄λ‘ λ©ν°μ€λ λ λΆν΄ λ° μλμ§ νν λν(Digestion) | |
| pub fn digest_step(&mut self, num_threads: usize) -> f32 { | |
| let size = self.size; | |
| let total = size * size; | |
| let chunk_rows = (size + num_threads - 1) / num_threads; | |
| let prev_weights = &self.ingested_weights; | |
| let bedrock = &self.bedrock; | |
| let (next_weights, total_energy) = thread::scope(|s| { | |
| let mut handles = Vec::with_capacity(num_threads); | |
| for thread_id in 0..num_threads { | |
| let start_y = thread_id * chunk_rows; | |
| let end_y = (start_y + chunk_rows).min(size); | |
| if start_y >= size { | |
| break; | |
| } | |
| handles.push(s.spawn(move || { | |
| let s_dim = size as i32; | |
| let mut local_chunk = Vec::with_capacity((end_y - start_y) * size); | |
| let mut local_energy = 0.0f32; | |
| for y in start_y..end_y { | |
| for x in 0..size { | |
| let idx = y * size + x; | |
| let u = ((y as i32 - 1 + s_dim) % s_dim * s_dim + x as i32) as usize; | |
| let d = ((y as i32 + 1) % s_dim * s_dim + x as i32) as usize; | |
| let l = (y as i32 * s_dim + (x as i32 - 1 + s_dim) % s_dim) as usize; | |
| let r = (y as i32 * s_dim + (x as i32 + 1) % s_dim) as usize; | |
| let neighbor_sum = ( | |
| prev_weights[u].to_weight() + | |
| prev_weights[d].to_weight() + | |
| prev_weights[l].to_weight() + | |
| prev_weights[r].to_weight() | |
| ) * 0.25; | |
| let absorbed_field = neighbor_sum + bedrock[idx]; | |
| local_chunk.push(Phase8::from_raw_weight(absorbed_field)); | |
| local_energy += absorbed_field.abs(); | |
| } | |
| } | |
| (local_chunk, local_energy) | |
| })); | |
| } | |
| let mut combined = Vec::with_capacity(total); | |
| let mut energy_sum = 0.0f32; | |
| for h in handles { | |
| let (chunk, e) = h.join().unwrap(); | |
| combined.extend(chunk); | |
| energy_sum += e; | |
| } | |
| (combined, energy_sum) | |
| }); | |
| self.ingested_weights = next_weights; | |
| total_energy / (total as f32) | |
| } | |
| } | |
| fn main() { | |
| println!("============================================================"); | |
| println!(" π₯© λκ·λͺ¨ κ°μ€μΉ ν μ μμ·¨(Ingestion) λ° μμ μν μμ§"); | |
| println!("============================================================\n"); | |
| let grid_size = 1024; // 1,048,576 κ°μ€μΉ νλΌλ―Έν° (1M ν μ) | |
| let total_params = grid_size * grid_size; | |
| let threads = 16; | |
| println!("π₯ [1λ¨κ³] λκ·λͺ¨ κ°μ€μΉ ν μ(1,048,576κ° νλΌλ―Έν°) μ€λΉ μ€..."); | |
| // 100λ§ κ°μ λΆλμμμ κ°μ€μΉ λ°μ΄ν° μμ± | |
| let raw_tensor: Vec<f32> = (0..total_params) | |
| .map(|i| ((i as f32 * 0.01).sin() * 2.0)) | |
| .collect(); | |
| let mut engine = WeightDigestionEngine::new(grid_size); | |
| println!("π½οΈ [2λ¨κ³] 100λ§ κ° κ°μ€μΉλ₯Ό 8λ μμ 격μλ‘ μ¦μ μμ·¨(Ingest) μλ£\n"); | |
| let ingest_start = Instant::now(); | |
| engine.ingest_raw_tensor(&raw_tensor); | |
| let ingest_dur = ingest_start.elapsed().as_secs_f64() * 1000.0; | |
| println!(" ββ 100λ§ κ°μ€μΉ λ©λͺ¨λ¦¬ ν‘μ μμ μκ°: {:.2} ms\n", ingest_dur); | |
| println!("β‘ [3λ¨κ³] 16κ° μ½μ΄ λμ κ°λ: μμ·¨λ κ°μ€μΉ μλμ§ λΆν΄ λ° λν μ€..."); | |
| let digest_start = Instant::now(); | |
| for tick in 1..=5 { | |
| let avg_e = engine.digest_step(threads); | |
| println!(" ββ [μν Tick {:02}] κ°μ€μΉ νν μλμ§: {:.4}", tick, avg_e); | |
| } | |
| let digest_dur = digest_start.elapsed().as_secs_f64(); | |
| let total_digested = (total_params * 5) as f64; | |
| let digestion_rate = (total_digested / digest_dur) / 1e6; | |
| println!("\n============================================================"); | |
| println!(" π κ°μ€μΉ μμ·¨ λ° λν μ€μΈ‘ κ²°κ³Ό"); | |
| println!("============================================================"); | |
| println!(" π₯© μ΄ μμ·¨ νλΌλ―Έν° μ : {}κ° (μ½ 105λ§ κ°)", total_params); | |
| println!(" β±οΈ 5-Tick μμ μν μκ° : {:.4} μ΄ ({:.2} ms)", digest_dur, digest_dur * 1000.0); | |
| println!(" β‘ κ°μ€μΉ μν μ²λ¦¬μ¨ : {:.2} MParam/sec (μ΄λΉ 1μ΅ κ° μ΄μ)", digestion_rate); | |
| println!("============================================================"); | |
| } | |