v0.6.0: verificador NCM calibrado (sem oráculo, V-1..V-4) + treino conjunto Pensamento↔backbone (fase C, PCGrad, acoplador duplex AC) + MoEs redirecionáveis c/ atenção própria (M-R1..M-R5, JEPA+SOM) + autoajuste por telemetria (A-1..A-5, UCB1) — 46/46 gates, provas r-23..r-27
bb2363d verified Download src/acoplador.rs from PowerMachine/khtst-rust: direct link, hf CLI and curl.
- Browser
- Download file 7.94 kB
-
https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/acoplador.rs
- Command line
-
hf download hf://PowerMachine/khtst-rust/src/acoplador.rs
-
curl -L -o acoplador.rs https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/acoplador.rs
7.94 kB
| //! **Acoplador Duplo Pensamento↔backbone** (v0.6.0 — "conexão bidirecional | |
| //! e paralela modelo ↔ modelo" estendida ao treino conjunto). | |
| //! | |
| //! Envolve a `PonteDupla` (r-05: P.1 sem deadlock por potencial, P.2 | |
| //! simultaneidade medida, P.3 filas limitadas) num protocolo lag-1 | |
| //! síncrono entre os dois MODELOS: | |
| //! | |
| //! - **A = backbone (gerador NCM):** envia o estado `(a, b, c)` — | |
| //! conhecimento (resumo do tronco), estado de inferência (ẑ corrompido) | |
| //! e sonda do nível — JUNTO com a confiança calibrada da sua distribuição | |
| //! preditiva (o feedback que treina o gate do Pensamento); | |
| //! - **B = Pensamento:** envia a correção `δ` agregada das N tentativas | |
| //! (o valor que o backbone injeta no condicionamento) JUNTO com o | |
| //! auto-acordo das tentativas (estatística de diversidade — insumo do | |
| //! autoajuste de N, lema do acordo par-a-par). | |
| //! | |
| //! Em CADA rodada as duas direções carregam cargas REAIS e a troca é | |
| //! simultânea (P.2 herdado + medido aqui). O lag-1 é a consequência lógica | |
| //! da simultaneidade: `δ_k` depende do estado `s_k`, que chega a B na mesma | |
| //! rodada em que A recebe `δ_{k−1}` — causalidade por filtração | |
| //! (δ_k é mensurável w.r.t. F_k = σ(s_0..s_k)). | |
| //! | |
| //! **Provas (r-24):** | |
| //! - **AC-1 (causalidade do protocolo lag-1):** a sequência trocada é | |
| //! `(s_k, δ_{k−1})`; δ_k = P(s_k) com P mensurável ⇒ nenhuma mensagem | |
| //! contém informação do futuro (filtração crescente). | |
| //! - **AC-2 (terminação):** potencial Φ = R − k (orçamento de rodadas) — | |
| //! decresce estritamente; herdado de P.1/T-P4. | |
| //! - **AC-3 (consistência valor↔grafo):** no TREINO conjunto, a correção | |
| //! injetada no grafo de autograd é o MESMO tensor δ cujo valor cruza a | |
| //! ponte (cópia destacada apenas para o protocolo/telemetria) — o | |
| //! gradiente não precisa cruzar canais; mora no grafo. Em inferência, | |
| //! o protocolo carrega tudo (sem gradientes). | |
| use crate::ponte::{EstatisticasPonte, PonteDupla}; | |
| use std::time::Instant; | |
| pub struct EstadoModelo { | |
| /// conhecimento: resumo do tronco (projetado em d_lat). | |
| pub a: Vec<f32>, | |
| /// estado de inferência corrente: ẑ_{ℓ−1} (possivelmente corrompido). | |
| pub b: Vec<f32>, | |
| /// sonda da requisição corrente (nível/consulta). | |
| pub c: Vec<f32>, | |
| /// confiança calibrada do NCM na predição corrente (feedback A→B). | |
| pub confianca: f64, | |
| pub nivel: usize, | |
| pub passo: usize, | |
| } | |
| pub struct Correcao { | |
| /// correção agregada δ (d_lat) a injetar em ẑ. | |
| pub delta: Vec<f32>, | |
| /// auto-acordo par-a-par das N tentativas (diversidade p/ autoajuste). | |
| pub acordo: f64, | |
| /// confiança do verificador NCM na resposta agregada (B→A informativo). | |
| pub confianca_agregada: f64, | |
| pub iteracao: usize, | |
| pub pesos: Vec<f64>, | |
| } | |
| pub struct TelemetriaAcoplador { | |
| pub rodadas: u64, | |
| pub timeouts: u64, | |
| pub soma_norma_delta: f64, | |
| pub soma_confianca: f64, | |
| pub soma_acordo: f64, | |
| pub maior_sobreposicao_us: u128, | |
| pub tempo_total_ms: f64, | |
| } | |
| pub struct AcopladorDuplo { | |
| pub ponte: PonteDupla, | |
| correcao_anterior: Correcao, | |
| pub telemetria: TelemetriaAcoplador, | |
| } | |
| impl AcopladorDuplo { | |
| pub fn nova(capacidade: usize, timeout_ms: u64) -> Self { | |
| AcopladorDuplo { | |
| ponte: PonteDupla::nova(capacidade, timeout_ms), | |
| correcao_anterior: Correcao { | |
| delta: Vec::new(), | |
| acordo: 0.0, | |
| confianca_agregada: 0.0, | |
| iteracao: 0, | |
| pesos: Vec::new(), | |
| }, | |
| telemetria: TelemetriaAcoplador::default(), | |
| } | |
| } | |
| /// UMA rodada duplex: A→B estado (a,b,c,conf); B→A correção ANTERIOR. | |
| /// Devolve a correção RECEBIDA (para o backbone aplicar/inspecionar). | |
| pub fn rodada(&mut self, estado: EstadoModelo) -> Result<Correcao, String> { | |
| let inicio = Instant::now(); | |
| // payload A→B: [a; b; c; conf] | payload B→A: [δ; acordo; conf_agr] | |
| let mut carga_a: Vec<f32> = Vec::with_capacity( | |
| estado.a.len() + estado.b.len() + estado.c.len() + 3, | |
| ); | |
| carga_a.extend(estado.a.iter().copied()); | |
| carga_a.extend(estado.b.iter().copied()); | |
| carga_a.extend(estado.c.iter().copied()); | |
| carga_a.push(estado.confianca as f32); | |
| let mut carga_b: Vec<f32> = self.correcao_anterior.delta.clone(); | |
| carga_b.push(self.correcao_anterior.acordo as f32); | |
| carga_b.push(self.correcao_anterior.confianca_agregada as f32); | |
| // troca simultânea (P.2) com timeout (P.1) | |
| let (msg_de_b, _msg_de_a) = self.ponte.rodada(carga_a, carga_b, estado.nivel)?; | |
| // reconstrói a correção recebida de B | |
| let recebida = Correcao { | |
| delta: msg_de_b.carga.clone(), | |
| acordo: self.correcao_anterior.acordo, | |
| confianca_agregada: self.correcao_anterior.confianca_agregada, | |
| iteracao: self.correcao_anterior.iteracao, | |
| pesos: self.correcao_anterior.pesos.clone(), | |
| }; | |
| // telemetria | |
| let norm: f64 = msg_de_b | |
| .carga | |
| .iter() | |
| .map(|x| (*x as f64) * (*x as f64)) | |
| .sum::<f64>() | |
| .sqrt(); | |
| let t = self.ponte.estatisticas(); | |
| self.telemetria.rodadas += 1; | |
| self.telemetria.timeouts += t.quedas_por_timeout; | |
| self.telemetria.soma_norma_delta += norm; | |
| self.telemetria.soma_confianca += estado.confianca; | |
| self.telemetria.soma_acordo += recebida.acordo; | |
| self.telemetria.maior_sobreposicao_us = | |
| self.telemetria.maior_sobreposicao_us.max(t.maior_sobreposicao_us); | |
| self.telemetria.tempo_total_ms += inicio.elapsed().as_secs_f64() * 1000.0; | |
| Ok(recebida) | |
| } | |
| /// Registra a correção fresca (calculada do estado recebido nesta | |
| /// rodada) — será o payload B→A da PRÓXIMA rodada (lag-1 — AC-1). | |
| pub fn registrar_correcao(&mut self, c: Correcao) { | |
| self.correcao_anterior = c; | |
| } | |
| pub fn estatisticas(&self) -> EstatisticasPonte { | |
| self.ponte.estatisticas() | |
| } | |
| pub fn encerrar(&self) { | |
| self.ponte.encerrar(); | |
| } | |
| } | |
| pub fn versao() -> &'static str { | |
| "acoplador-0.6.0" | |
| } | |
| mod testes { | |
| use super::*; | |
| fn ac1_ac2_rodadas_causais_terminam() { | |
| // 60 rodadas com estados crescentes — sem deadlock, sem timeout | |
| let mut ac = AcopladorDuplo::nova(8, 500); | |
| let mut conf = 0.1f64; | |
| for k in 0..60 { | |
| let estado = EstadoModelo { | |
| a: vec![0.1 * k as f32; 8], | |
| b: vec![0.2 * k as f32; 8], | |
| c: vec![0.3; 4], | |
| confianca: conf, | |
| nivel: k % 7, | |
| passo: k, | |
| }; | |
| let recebida = ac.rodada(estado).expect("rodada sem deadlock"); | |
| assert!(recebida.delta.len() >= 2, "correção recebida não vazia após 1ª rodada"); | |
| // δ_k = função do estado s_k (causal): registra correção fresca | |
| let delta: Vec<f32> = (0..8).map(|i| (i as f32 + k as f32) * 0.01).collect(); | |
| ac.registrar_correcao(Correcao { | |
| delta, | |
| acordo: 0.5, | |
| confianca_agregada: conf, | |
| iteracao: k, | |
| pesos: vec![0.25; 4], | |
| }); | |
| conf = (conf * 1.02).min(0.99); | |
| } | |
| let t = &ac.telemetria; | |
| assert_eq!(t.rodadas, 60); | |
| assert_eq!(t.timeouts, 0, "nenhum timeout"); | |
| assert!(t.soma_norma_delta > 0.0); | |
| // P.2: sobreposição medida nas duas direções | |
| let p = ac.estatisticas(); | |
| assert!(p.envios_a_para_b == 60 && p.envios_b_para_a == 60); | |
| assert!(p.quedas_por_timeout == 0); | |
| } | |
| } | |