//! `python::nlp_nlg` — 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::*; /// Demo/gate das unidades NLP/NLG sobre estados ocultos sintéticos /// (nascimento neutro + gates + coerência de bigramas + especulativo). #[pyfunction] #[pyo3(signature = (d=32, t=6, seed=11))] pub(crate) fn demo_nlp_nlg(py: Python, d: usize, t: usize, seed: u64) -> PyResult { let dev = candle_core::Device::Cpu; let mut rng = rng::RngDeterministico::novo(seed); let v: Vec = (0..2 * t * d).map(|_| rng.normal_padrao() as f32).collect(); let h = candle_core::Tensor::from_vec(v, (2, t, d), &dev).map_err(py_err)?; // NLP: enriquecimento aditivo — neutro no nascimento let mut nlp = nlp::UnidadeNlp::nova(d, &dev).map_err(|e| { pyo3::exceptions::PyRuntimeError::new_err(format!("nlp (d%4): {e}")) })?; let h_enr = nlp.enriquecer(&h).map_err(py_err)?; let dif_nlp = (&h).sub(&h_enr).map_err(py_err)?.abs().map_err(py_err)?.max_all().map_err(py_err)?.to_scalar::().map_err(py_err)? as f64; // intenção let (intencoes, confs) = nlp.intencao_argmax(&h).map_err(py_err)?; // NLG: plano + condicionamento neutro + coerência let mut nlg = nlg::UnidadeNlg::nova(d, 4096, &dev).map_err(py_err)?; let plano = nlg.plano(&h).map_err(py_err)?; let p8 = candle_core::Tensor::randn(0f32, 1f32, (nlg::N_EIXOS_ESTILO,), &dev).map_err(py_err)?; let p01 = candle_nn::ops::sigmoid(&p8).map_err(py_err)?; let h_cond = nlg.condicionar(&h, Some(&p01)).map_err(py_err)?; let dif_nlg = (&h).sub(&h_cond).map_err(py_err)?.abs().map_err(py_err)?.max_all().map_err(py_err)?.to_scalar::().map_err(py_err)? as f64; // coerência: contexto observado vs candidato novo let ctx = vec![5u32, 6, 7, 8, 9]; nlg.observar_contexto(&ctx); let s_mesmo = nlg.score_coerencia(&ctx); let s_novo = nlg.score_coerencia(&[50u32, 51, 52, 53]); // especulativo: aceitação típica + stats let mut espec = nlg::DecodificadorEspeculativo::novo(4, 0.95, 10); let logits = candle_core::Tensor::from_vec(vec![3.0f32, 0.2, 0.1, 0.05], (4,), &dev) .map_err(py_err)?; let mut aceites = 0usize; for _ in 0..30 { let (_, ok) = espec.verificar_e_corrigir(&logits, &[0, 1]).map_err(py_err)?; if ok { aceites += 1; } } let d_ = serde_json::json!({ "versao": "nlp-nlg-0.7.0", "nlp_gate_medio": nlp.gate_medio, "nlp_dif_nascimento": dif_nlp, "nlp_intencoes": intencoes, "nlp_confiancas": confs, "nlg_plano_forma": plano.dims(), "nlg_dif_nascimento": dif_nlg, "nlg_coerencia_mesmo": s_mesmo, "nlg_coerencia_novo": s_novo, "espec_aceitacao_media": espec.stats.aceitacao_media, "espec_speedup": espec.stats.speedup_estimado, "espec_aceites_30": aceites, "gates": { "nlp_neutro": dif_nlp == 0.0, "nlg_neutro": dif_nlg == 0.0, "gate_medio_ok": (nlp.gate_medio - 0.119).abs() < 0.05, "coerencia_ok": s_mesmo > 0.9 && s_novo < 0.1, "espec_ok": espec.stats.aceitacao_media > 0.8, }, }); Ok(pythonize::pythonize(py, &d_)?.into()) }