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/pensamento/quebra_cabeca.rs from PowerMachine/khtst-rust: direct link, hf CLI and curl.
- Browser
- Download file 9.25 kB
-
https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/pensamento/quebra_cabeca.rs
- Command line
-
hf download hf://PowerMachine/khtst-rust/src/pensamento/quebra_cabeca.rs
-
curl -L -o quebra_cabeca.rs https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/pensamento/quebra_cabeca.rs
9.25 kB
| //! `pensamento::quebra_cabeca` — 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::*; | |
| // --------------------------------------------------------------------------- | |
| // QUEBRA-CABEÇA pós-treinamento (v0.7.0 — inovação com o conhecimento | |
| // treinado; requisito do usuário; provas Q-1..Q-6 em r-31) | |
| // --------------------------------------------------------------------------- | |
| /// Configuração do quebra-cabeça (r-28 §4.3). | |
| pub struct ConfigQuebraCabeca { | |
| /// K peças em que o conhecimento é quebrado. | |
| pub n_pecas: usize, | |
| /// orçamento B de rodadas (terminação Q-4). | |
| pub n_rodadas_max: usize, | |
| /// limiar de validade (mesmo τ_c calibrado do verificador — Q-2). | |
| pub tau_c: f64, | |
| /// teto do ajuste por componente na árvore (regulação). | |
| pub delta_max: f64, | |
| /// remonta as peças com mistura ORTOGONAL por peça (rotação/ortogonalidade). | |
| pub rotacao_ortogonal: bool, | |
| /// para a execução após este nº de rodadas consecutivas sem aceite. | |
| pub paciencia: usize, | |
| } | |
| impl Default for ConfigQuebraCabeca { | |
| fn default() -> Self { | |
| ConfigQuebraCabeca { | |
| n_pecas: 4, | |
| n_rodadas_max: 12, | |
| tau_c: 0.55, | |
| delta_max: 0.05, | |
| rotacao_ortogonal: true, | |
| paciencia: 5, | |
| } | |
| } | |
| } | |
| impl ConfigQuebraCabeca { | |
| pub fn novo(n_pecas: usize, n_rodadas: usize, tau_c: f64) -> Self { | |
| ConfigQuebraCabeca { | |
| n_pecas, | |
| n_rodadas_max: n_rodadas, | |
| tau_c, | |
| delta_max: 0.05, | |
| rotacao_ortogonal: true, | |
| paciencia: (n_rodadas / 2).max(2), | |
| } | |
| } | |
| } | |
| /// Uma rodada do quebra-cabeça. | |
| pub struct RodadaQuebraCabeca { | |
| pub rodada: usize, | |
| /// permutação das peças aplicada na remontagem (reordenação). | |
| pub permutacao_pecas: Vec<usize>, | |
| /// confiança NCM do candidato remontado (reavaliação). | |
| pub confianca: f64, | |
| /// conf ≥ τ_c ⇒ VÁLIDO (ajusta a árvore); senão PUNIDO (descarta). | |
| pub aceito: bool, | |
| /// delta aplicado na árvore (0 quando descartado). | |
| pub delta_aplicado: f64, | |
| /// rotações ortogonais usadas (quando ativas) — por peça. | |
| pub usou_rotacao: bool, | |
| } | |
| /// Resultado consolidado do quebra-cabeça. | |
| pub struct ResultadoQuebraCabeca { | |
| pub rodadas: Vec<RodadaQuebraCabeca>, | |
| pub aceitos: usize, | |
| pub rejeitados: usize, | |
| pub confianca_base: f64, | |
| pub confianca_melhor: f64, | |
| pub telemetria: HashMap<String, f64>, | |
| } | |
| /// **Quebra-cabeça de inovação pós-treinamento** (r-28 §4.3): | |
| /// 1. quebra o conhecimento treinado `conceitos` (m, d) em K peças por | |
| /// permutação aleatória das linhas (Fisher–Yates com RNG determinístico); | |
| /// 2. remonta as peças em nova ordem (e com mistura ortogonal por peça | |
| /// quando `rotacao_ortogonal`) — "descobrir novas possibilidades"; | |
| /// 3. reavalia cada remontagem pelo verificador NCM (calibrado — V-2); | |
| /// VÁLIDO (conf ≥ τ_c) ⇒ ajuste regulado na árvore de pesos indexada | |
| /// (nó "pensamento", crédito fundo-topo); PUNIDO ⇒ descarta e o incremento | |
| /// de punição sobe no nó (alimenta o gate do FNH — integração v0.7.0); | |
| /// 4. repete até o orçamento B ou a paciência esgotar (Q-4). | |
| /// | |
| /// **Provas (r-31):** Q-1 cobertura (permutações uniformes ⇒ S_K no suporte; | |
| /// rotações varrem O(d)); Q-2 soundness herdada (mesmo limiar calibrado do | |
| /// verificador — P(aceite inválido) ≤ 1−τ_c+ECE); Q-3 potencial monotônico | |
| /// (Φ_r = Σ conf dos aceitos é não-decrescente; rejeições não tocam Φ); | |
| /// Q-4 terminação (B finito, rodadas O(m·d)); Q-5 invariantes da árvore | |
| /// preservadas (ajustes só tocam métricas, nunca a estrutura — T-A1 intacto; | |
| /// agregação pós-ajuste mantém T-A2); Q-6 causalidade (permutação e confiança | |
| /// medidas antes do ajuste — filtração F_r). | |
| pub fn quebra_cabeca_inovar( | |
| conceitos: &Tensor, | |
| verificador: &crate::verificador::VerificadorNcm, | |
| logits_fn: &dyn Fn(&Tensor) -> Result<Tensor>, | |
| arvore: &mut crate::arvore_pesos::ArvorePesos, | |
| cfg: &ConfigQuebraCabeca, | |
| rng: &mut RngDeterministico, | |
| ) -> Result<ResultadoQuebraCabeca> { | |
| let dev = conceitos.device().clone(); | |
| let (m, d) = (conceitos.dims()[0], conceitos.dims()[1]); | |
| let k = cfg.n_pecas.clamp(1, m); | |
| let no_pens = arvore.no("pensamento").unwrap_or(0); | |
| // linha de base: confiança do conhecimento original (agregado médio) | |
| let base_agg = conceitos.mean(0)?; | |
| let conf_base = { | |
| let lg = logits_fn(&base_agg)?; | |
| verificador.confianca_1d(&lg)? | |
| }; | |
| let mut rodadas = Vec::new(); | |
| let mut aceitos = 0usize; | |
| let mut rejeitados = 0usize; | |
| let mut conf_melhor = conf_base; | |
| let mut sem_aceite = 0usize; | |
| for r in 1..=cfg.n_rodadas_max { | |
| if sem_aceite >= cfg.paciencia { | |
| break; | |
| } | |
| // (1) QUEBRA: permutação de linhas Fisher–Yates (Q-6: amostrada ANTES) | |
| let mut perm: Vec<usize> = (0..m).collect(); | |
| for i in (1..m).rev() { | |
| let j = rng.inteiro(i + 1); | |
| perm.swap(i, j); | |
| } | |
| // fatia em K peças contíguas (tamanhos quase iguais) | |
| let tamanho = (m + k - 1) / k; | |
| let mut pecas = Vec::with_capacity(k); | |
| let mut ini = 0usize; | |
| while ini < m { | |
| let fim = (ini + tamanho).min(m); | |
| let idx: Vec<u32> = perm[ini..fim].iter().map(|&x| x as u32).collect(); | |
| let pedaco = conceitos.index_select(&Tensor::from_vec(idx, (fim - ini,), &dev)?, 0)?; | |
| pecas.push(pedaco); | |
| ini = fim; | |
| } | |
| // (2) REMONTA: nova ordem aleatória das peças (permutação de peças) | |
| let mut perm_pecas: Vec<usize> = (0..pecas.len()).collect(); | |
| for i in (1..pecas.len()).rev() { | |
| let j = rng.inteiro(i + 1); | |
| perm_pecas.swap(i, j); | |
| } | |
| let mut remontada = Vec::with_capacity(pecas.len()); | |
| for &pi in &perm_pecas { | |
| let mut pedaco = pecas[pi].clone(); | |
| if cfg.rotacao_ortogonal && d >= 2 { | |
| // mistura ortogonal da peça: Q ∈ O(d) via polar de gaussiana | |
| // do RNG determinístico (preserva normas — ‖xQ‖_F = ‖x‖_F) | |
| let q = q_ortogonal_deterministica(d, rng, &dev)?; | |
| pedaco = pedaco.matmul(&q)?; | |
| } | |
| remontada.push(pedaco); | |
| } | |
| let candidata = Tensor::cat(&remontada, 0)?; // (m, d) remontado | |
| // (3) REAVALIAÇÃO pelo verificador NCM (Q-2: mesmo limiar calibrado) | |
| let agg = candidata.mean(0)?; | |
| let lg = logits_fn(&agg)?; | |
| let conf = verificador.confianca_1d(&lg)?; | |
| let aceito = conf >= cfg.tau_c; | |
| let delta = if aceito { | |
| // VÁLIDO: ajusta a árvore bidirecional (indexada, com teto) | |
| let escalado = (conf - cfg.tau_c).min(cfg.delta_max); | |
| arvore.aplicar_ajuste_indexado(no_pens, "confianca", escalado, cfg.delta_max) | |
| } else { | |
| // PUNIDO: descarta; a punição sobe no nó (sinal para o gate FNH) | |
| rejeitados += 1; | |
| sem_aceite += 1; | |
| arvore.aplicar_ajuste_indexado(no_pens, "punicao", cfg.delta_max * 0.5, cfg.delta_max); | |
| 0.0 | |
| }; | |
| if aceito { | |
| aceitos += 1; | |
| sem_aceite = 0; | |
| conf_melhor = conf_melhor.max(conf); | |
| } | |
| rodadas.push(RodadaQuebraCabeca { | |
| rodada: r, | |
| permutacao_pecas: perm_pecas, | |
| confianca: conf, | |
| aceito, | |
| delta_aplicado: delta, | |
| usou_rotacao: cfg.rotacao_ortogonal, | |
| }); | |
| } | |
| // crédito fundo-topo após todas as rodadas (T-A2) | |
| arvore.agregar_fundo_topo("confianca"); | |
| arvore.agregar_fundo_topo("punicao"); | |
| let n_rod = rodadas.len(); | |
| let mut telemetria = HashMap::new(); | |
| telemetria.insert("rodadas".into(), n_rod as f64); | |
| telemetria.insert("aceitos".into(), aceitos as f64); | |
| telemetria.insert("rejeitados".into(), rejeitados as f64); | |
| telemetria.insert("confianca_base".into(), conf_base); | |
| telemetria.insert("confianca_melhor".into(), conf_melhor); | |
| telemetria.insert( | |
| "taxa_aceitacao".into(), | |
| if n_rod > 0 { aceitos as f64 / n_rod as f64 } else { 0.0 }, | |
| ); | |
| telemetria.insert("rotacao_ativa".into(), if cfg.rotacao_ortogonal { 1.0 } else { 0.0 }); | |
| Ok(ResultadoQuebraCabeca { | |
| rodadas, | |
| aceitos, | |
| rejeitados, | |
| confianca_base: conf_base, | |
| confianca_melhor: conf_melhor, | |
| telemetria, | |
| }) | |
| } | |
| /// Q ∈ O(d) determinística: gaussiana do RNG próprio → retração polar. | |
| /// Ortogonal EXATA (δ_ort ≤ 1e-6) e reprodutível (mesma semente ⇒ mesmo Q). | |
| pub fn q_ortogonal_deterministica( | |
| d: usize, | |
| rng: &mut RngDeterministico, | |
| dev: &Device, | |
| ) -> Result<Tensor> { | |
| let n = d * d; | |
| let v: Vec<f32> = (0..n).map(|_| rng.normal_padrao() as f32).collect(); | |
| let g = Tensor::from_vec(v, (d, d), dev)?; | |
| crate::stiefel::retrair_polar_frobenius(&g, 90) | |
| } | |