v0.10.0: análise/prova/teste das críticas de engenharia Qwen3.8 lote 3 (r-35) — divisão SRP dos monólitos jepa/pensamento/moe/python em 26 submódulos (API estável via re-exports; 'Amdahl de compilação' refutada por experimento controlado, builds frios neutros), checkpoints atômicos SHA-256 puro FIPS 180-4 + fsync + rename + manifesto (CP-1..CP-3; correções da proposta: sem destruir estado anterior, manifesto com barreira, sem bincode/unwrap), TemperaturaInversa T-V3 (fronteira tipada da convexidade N-2; alegação compile-time corrigida), trait CamadaKhtst+CamadaHomeostatica (premissa do controlador refutada no fonte; Vec<Var>; adaptador MoeComPapel bit-a-bit), CLI Typer 75 (fachada aditiva com resume verificado por hash) — 123/123 cargo, 107/107 gates, treino real Wikipédia PT-BR com checkpoints íntegros
06e4b6f verified Download src/jepa/sonic_moe.rs from PowerMachine/khtst-rust: direct link, hf CLI and curl.
- Browser
- Download file 6.5 kB
-
https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/jepa/sonic_moe.rs
- Command line
-
hf download hf://PowerMachine/khtst-rust/src/jepa/sonic_moe.rs
-
curl -L -o sonic_moe.rs https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/jepa/sonic_moe.rs
6.5 kB
| //! `jepa::sonic_moe` — extraído do monólito na v0.10.0 | |
| //! (divisão SRP, crítica Qwen3.8 lote 3 nº 1; r-35 §2). | |
| use super::*; | |
| // --------------------------------------------------------------------------- | |
| // Parte 5 — SonicMoE (IO/tile-aware) | |
| // --------------------------------------------------------------------------- | |
| /// MoE top-k com capacidade por especialista e perda de balanceamento. | |
| /// | |
| /// **Prova SM-1 (limite de capacidade):** o roteamento tile-aware mantém no | |
| /// máximo `C` tokens por especialista por ladrilho — o drop é determinístico | |
| /// (ordem de chegada) e o nº de tokens descartados é `Σ_e max(0, load_e − C)`. | |
| /// | |
| /// **Prova SM-2 (balanceamento):** `L_aux = E·Σ_e f_e·p_e`; com roteamento | |
| /// auto-consistente (`f = p`), `L_aux = E·Σ p_e² ≥ 1` com igualdade sse | |
| /// `p_e = 1/E` (Cauchy–Schchwarz) — o mínimo força o roteador uniforme. | |
| pub struct SonicMoe { | |
| pub roteador: Linear, // d → E | |
| pub especialistas: Vec<MlpJepa>, // E experts d → d | |
| pub n_top: usize, | |
| pub capacidade: usize, | |
| pub lambda_aux: f64, | |
| } | |
| pub struct SaidaMoe { | |
| pub saida: Tensor, | |
| pub perda_aux: Tensor, | |
| pub carga: Vec<usize>, // tokens efetivamente processados por especialista | |
| pub descartados: usize, // tokens com especialistas cortados pela capacidade | |
| } | |
| impl SonicMoe { | |
| pub fn novo(d: usize, n_expertos: usize, n_top: usize, capacidade: usize, dev: &Device) -> Result<Self> { | |
| let roteador = Linear::sem_vies(d, n_expertos, 0.1, dev)?; | |
| let especialistas = (0..n_expertos) | |
| .map(|_| MlpJepa::novo(d, 2 * d, d, dev)) | |
| .collect::<Result<Vec<_>>>()?; | |
| Ok(Self { roteador, especialistas, n_top, capacidade, lambda_aux: 0.01 }) | |
| } | |
| pub fn vars(&self) -> Vec<Var> { | |
| let mut v = self.roteador.vars(); | |
| for e in &self.especialistas { | |
| v.extend(e.vars()); | |
| } | |
| v | |
| } | |
| /// Forward tile-aware: (n, d) → (n, d). | |
| pub fn fwd(&self, x: &Tensor) -> Result<SaidaMoe> { | |
| let n = x.dim(0)?; | |
| let d = x.dim(1)?; | |
| let e = self.especialistas.len(); | |
| let dev = x.device(); | |
| let logits = self.roteador.fwd(x)?; // (n, E) | |
| let probs = candle_nn::ops::softmax(&logits, candle_core::D::Minus1)?; | |
| // top-k por token (não diferenciável — pesos do top-k são dif. via probs) | |
| let probs_v = probs.to_vec2::<f32>()?; | |
| let mut carga = vec![0usize; e]; | |
| let mut descartados = 0usize; | |
| // acumulador de saída (n, d) — construído por soma de contribuições | |
| let mut saida = Tensor::zeros((n, d), candle_core::DType::F32, &dev)?; | |
| let mut peso_total = Tensor::zeros((n, 1), candle_core::DType::F32, &dev)?; | |
| // por especialista (tile): tokens cujo top-k contém e e com carga < C | |
| for ei in 0..e { | |
| // candidatos: tokens ordenados por prob do especialista ei | |
| let mut cand: Vec<(usize, f32)> = (0..n) | |
| .map(|i| (i, probs_v[i][ei])) | |
| .collect(); | |
| cand.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap()); | |
| let mut escolhidos: Vec<usize> = Vec::new(); | |
| for (i, _) in cand { | |
| if carga[ei] >= self.capacidade { | |
| break; | |
| } | |
| // verifica se ei está no top-k do token i | |
| let mut ordem: Vec<(f32, usize)> = | |
| (0..e).map(|k| (probs_v[i][k], k)).collect(); | |
| ordem.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap()); | |
| let top: Vec<usize> = ordem.iter().rev().take(self.n_top).map(|(_, k)| *k).collect(); | |
| if top.contains(&ei) { | |
| escolhidos.push(i); | |
| carga[ei] += 1; | |
| } | |
| } | |
| if escolhidos.is_empty() { | |
| continue; | |
| } | |
| // tile do especialista: uma única passagem em lote | |
| let idx: Vec<u32> = escolhidos.iter().map(|&i| i as u32).collect(); | |
| let n_e = idx.len(); | |
| let idx_t = Tensor::from_vec(idx, (n_e,), &dev)?; | |
| let tile = x.index_select(&idx_t, 0)?; | |
| let y = self.especialistas[ei].fwd(&tile)?; // (m, d) | |
| // pesos: prob do especialista ei para cada token escolhido | |
| let w: Vec<f32> = escolhidos.iter().map(|&i| probs_v[i][ei]).collect(); | |
| let n_w = escolhidos.len(); | |
| let w_t = Tensor::from_vec(w.clone(), (n_w, 1), &dev)?; | |
| let contrib = y.broadcast_mul(&w_t)?; | |
| // scatter-add: acumula nas posições | |
| let mut buf = saida.to_vec2::<f32>()?; | |
| let contrib_v = contrib.to_vec2::<f32>()?; | |
| for (k, &i) in escolhidos.iter().enumerate() { | |
| for j in 0..d { | |
| buf[i][j] += contrib_v[k][j]; | |
| } | |
| } | |
| saida = Tensor::from_vec( | |
| buf.into_iter().flatten().collect::<Vec<f32>>(), | |
| (n, d), | |
| &dev, | |
| )?; | |
| let mut pt = peso_total.to_vec2::<f32>()?; | |
| for (k, &i) in escolhidos.iter().enumerate() { | |
| pt[i][0] += w[k]; | |
| } | |
| peso_total = Tensor::from_vec( | |
| pt.into_iter().flatten().collect::<Vec<f32>>(), | |
| (n, 1), | |
| &dev, | |
| )?; | |
| } | |
| // tokens sem especialista (todos cortados) → descartados; saída 0 | |
| let pt_v = peso_total.to_vec2::<f32>()?; | |
| for i in 0..n { | |
| if pt_v[i][0] == 0.0 { | |
| descartados += 1; | |
| } | |
| } | |
| // renormaliza pelo peso efetivo (evita viés da capacidade) | |
| let denom = peso_total.clamp(1e-6, f64::INFINITY)?; | |
| let saida = saida.broadcast_div(&denom)?; | |
| // perda auxiliar: E·Σ f_e·p_e (f = fração de tokens cujo top-1 é e) | |
| let mut f = vec![0f32; e]; | |
| for i in 0..n { | |
| let (mut melhor, mut mp) = (0usize, f32::NEG_INFINITY); | |
| for k in 0..e { | |
| if probs_v[i][k] > mp { | |
| mp = probs_v[i][k]; | |
| melhor = k; | |
| } | |
| } | |
| f[melhor] += 1.0 / n as f32; | |
| } | |
| let f_t = Tensor::from_vec(f, (e,), &dev)?; | |
| let p_media = probs.mean(0)?; // (E,) | |
| let perda_aux = ((&f_t * &p_media)?.sum_all()? * (e as f64))?; | |
| Ok(SaidaMoe { saida, perda_aux, carga, descartados }) | |
| } | |
| } | |