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/python/demos_qwen.rs from PowerMachine/khtst-rust: direct link, hf CLI and curl.
- Browser
- Download file 16 kB
-
https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/python/demos_qwen.rs
- Command line
-
hf download hf://PowerMachine/khtst-rust/src/python/demos_qwen.rs
-
curl -L -o demos_qwen.rs https://huggingface.co/PowerMachine/khtst-rust/resolve/main/src/python/demos_qwen.rs
16 kB
| //! `python::demos_qwen` — 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::*; | |
| /// **v0.8.0 — análise/prova/teste das 4 propostas Qwen3.8** (r-33): mede | |
| /// custo e exatidão de (1) Newton analítico vs golden-section (verificador), | |
| /// (2) Cayley vs polar (FNH), (3) árvore pós-ordem iterativa vs recursiva, | |
| /// (4) MoE vetorizada vs referência (valores + gradiente restaurado — bug | |
| /// v080-1), e re-executa a ablação JEPA de 3 braços com a correção. | |
| // mede o bug v080-1 intencionalmente (fwd = oráculo) | |
| pub(crate) fn demo_qwen_v080(py: Python) -> PyResult<PyObject> { | |
| use candle_core::{Device, Tensor}; | |
| use std::time::Instant; | |
| let dev = Device::Cpu; | |
| // ---------- (1) Newton vs golden-section (verificador) ---------- | |
| let mut rng = crate::rng::RngDeterministico::novo(808); | |
| let (n, k) = (1024usize, 32usize); | |
| let mut lv = Vec::with_capacity(n * k); | |
| let mut av = Vec::with_capacity(n); | |
| for _ in 0..n { | |
| let alvo = rng.inteiro(k) as u32; | |
| av.push(alvo); | |
| for j in 0..k { | |
| let base = if j as u32 == alvo { 3.0 } else { 0.0 }; | |
| lv.push(base + rng.normal(0.0, 1.0) as f32); | |
| } | |
| } | |
| let lt = Tensor::from_vec(lv, (n, k), &dev).unwrap(); | |
| let at = Tensor::from_vec(av, (n,), &dev).unwrap(); | |
| let t0 = Instant::now(); | |
| let (t_g, _, nll_g) = verificador::calibrar_temperatura(<, &at).unwrap(); | |
| let tempo_golden = t0.elapsed().as_secs_f64(); | |
| let t0 = Instant::now(); | |
| let (t_n, _, nll_n, n_aval) = | |
| verificador::calibrar_temperatura_newton(<, &at, 40).unwrap(); | |
| let tempo_newton = t0.elapsed().as_secs_f64(); | |
| // ---------- (2) Cayley vs polar (FNH) ---------- | |
| let n_rot = 16usize; | |
| let r = fnh::RotacaoSkew::nova(n_rot, &dev).unwrap(); | |
| let th: Vec<f32> = (0..n_rot * (n_rot - 1) / 2) | |
| .map(|i| ((i as f32) * 0.11) % 0.5) | |
| .collect(); | |
| r.theta | |
| .set(&Tensor::from_vec(th, (n_rot * (n_rot - 1) / 2,), &dev).unwrap()) | |
| .unwrap(); | |
| let rep = 25usize; | |
| let t0 = Instant::now(); | |
| let mut delta_polar = 0.0; | |
| for _ in 0..rep { | |
| delta_polar = crate::stiefel::erro_ortogonalidade(&r.rotacao_polar().unwrap()).unwrap(); | |
| } | |
| let tempo_polar = t0.elapsed().as_secs_f64() / rep as f64; | |
| let t0 = Instant::now(); | |
| let mut delta_cayley = 0.0; | |
| for _ in 0..rep { | |
| delta_cayley = crate::stiefel::erro_ortogonalidade(&r.rotacao_cayley().unwrap()).unwrap(); | |
| } | |
| let tempo_cayley = t0.elapsed().as_secs_f64() / rep as f64; | |
| // ---------- (3) árvore iterativa vs recursiva ---------- | |
| let mut arv = arvore_pesos::ArvorePesos::nova(&std::collections::HashMap::new()); | |
| let mut pai = 1usize; | |
| for i in 0..20_000u32 { | |
| pai = arv.anexar_filho(pai, &format!("c{i}"), 1); | |
| } | |
| arv.nos[pai].metricas.insert("m".into(), 1.0); | |
| let t0 = Instant::now(); | |
| let total_it = arv.agregar_fundo_topo("m"); | |
| let tempo_arv_it = t0.elapsed().as_secs_f64(); | |
| // repõe TODAS as métricas locais (a agregação sobrescreveu com os | |
| // agregados) — só a folha tem valor; o resto volta a 0 — e roda a | |
| // recursiva (profundidade 20k ok na thread principal do Python) | |
| for no in arv.nos.iter_mut() { | |
| no.metricas.insert("m".into(), 0.0); | |
| } | |
| arv.nos[pai].metricas.insert("m".into(), 1.0); | |
| let t0 = Instant::now(); | |
| let total_rec = arv.agregar_fundo_topo_rec("m"); | |
| let tempo_arv_rec = t0.elapsed().as_secs_f64(); | |
| // ---------- (4) MoE vetorizada: valores + gradiente + custo ---------- | |
| let (nm, dm, em) = (256usize, 32usize, 8usize); | |
| let xv: Vec<f32> = (0..nm * dm).map(|_| rng.normal(0.0, 1.0) as f32).collect(); | |
| let x = Tensor::from_vec(xv, (nm, dm), &dev).unwrap(); | |
| let moe = moe_redirecionavel::MoeRedirecionavel::novo(dm, em, 2, nm, &dev).unwrap(); | |
| let s_ref = moe.fwd(&x, moe_redirecionavel::Papel::Codificador).unwrap(); | |
| let s_vet = moe.forward(&x, moe_redirecionavel::Papel::Codificador).unwrap(); | |
| let dif_moe = (&s_ref.saida - &s_vet.saida) | |
| .unwrap() | |
| .abs() | |
| .unwrap() | |
| .max_all() | |
| .unwrap() | |
| .to_scalar::<f32>() | |
| .unwrap() as f64; | |
| let rep_moe = 10usize; | |
| let t0 = Instant::now(); | |
| for _ in 0..rep_moe { | |
| let _ = moe.fwd(&x, moe_redirecionavel::Papel::Codificador).unwrap(); | |
| } | |
| let tempo_moe_ref = t0.elapsed().as_secs_f64() / rep_moe as f64; | |
| let t0 = Instant::now(); | |
| for _ in 0..rep_moe { | |
| let _ = moe.forward(&x, moe_redirecionavel::Papel::Codificador).unwrap(); | |
| } | |
| let tempo_moe_vet = t0.elapsed().as_secs_f64() / rep_moe as f64; | |
| // normas de gradiente (bug v080-1: fwd = 0; vetorizada > 0) | |
| let norma = |vet: bool| -> (f64, f64) { | |
| let s = if vet { | |
| moe.forward(&x, moe_redirecionavel::Papel::Codificador).unwrap() | |
| } else { | |
| moe.fwd(&x, moe_redirecionavel::Papel::Codificador).unwrap() | |
| }; | |
| let perda = s.saida.sqr().unwrap().sum_all().unwrap(); | |
| let gs = perda.backward().unwrap(); | |
| let mut nr = 0.0; | |
| for v in moe.roteador.vars() { | |
| if let Some(g) = gs.get(&v) { | |
| nr += g.sqr().unwrap().sum_all().unwrap().to_scalar::<f32>().unwrap() as f64; | |
| } | |
| } | |
| let mut ne = 0.0; | |
| for e in &moe.especialistas { | |
| for v in e.vars() { | |
| if let Some(g) = gs.get(&v) { | |
| ne += g.sqr().unwrap().sum_all().unwrap().to_scalar::<f32>().unwrap() as f64; | |
| } | |
| } | |
| } | |
| (nr, ne) | |
| }; | |
| let (grad_ref_r, grad_ref_e) = norma(false); | |
| let (grad_vet_r, grad_vet_e) = norma(true); | |
| // ---------- (5) re-ablação JEPA 3 braços (gradiente restaurado) ---------- | |
| let xv: Vec<f32> = (0..64 * 12).map(|_| rng.normal(0.0, 1.0) as f32).collect(); | |
| let xj = Tensor::from_vec(xv, (64, 12), &dev).unwrap(); | |
| let mut ablac = serde_json::Map::new(); | |
| for modo in ["pequena", "densa", "moe"] { | |
| let rj = moe_redirecionavel::treinar_jepa_com_moe(&xj, modo, 120, 0.5, 42).unwrap(); | |
| ablac.insert( | |
| modo.into(), | |
| serde_json::json!({ | |
| "perda_inicial": rj.perda_pred_inicial, | |
| "perda_final": rj.perda_pred_final, | |
| "queda_pct": 100.0 * (1.0 - rj.perda_pred_final / rj.perda_pred_inicial.max(1e-9)), | |
| }), | |
| ); | |
| } | |
| let d_ = serde_json::json!({ | |
| "versao": "qwen-v080-1.0", | |
| "newton_vs_golden": { | |
| "t_golden": t_g, "t_newton": t_n, "dif_t": (t_g - t_n).abs(), | |
| "nll_golden": nll_g, "nll_newton": nll_n, | |
| "nll_dif": (nll_g - nll_n).abs(), | |
| "n_aval_newton": n_aval, | |
| "tempo_golden_s": tempo_golden, "tempo_newton_s": tempo_newton, | |
| "speedup": tempo_golden / tempo_newton.max(1e-9), | |
| "gates": { | |
| "mesmo_t": (t_g - t_n).abs() < 1e-3, | |
| "nll_nao_piora": nll_n <= nll_g + 1e-4, | |
| "menos_avaliacoes": n_aval < 36, | |
| }, | |
| }, | |
| "cayley_vs_polar": { | |
| "delta_ort_polar": delta_polar, "delta_ort_cayley": delta_cayley, | |
| "tempo_polar_s": tempo_polar, "tempo_cayley_s": tempo_cayley, | |
| "speedup": tempo_polar / tempo_cayley.max(1e-9), | |
| "gates": { | |
| "ambos_exatos": delta_polar < 1e-6 && delta_cayley < 1e-6, | |
| "cayley_mais_rapido": tempo_cayley < tempo_polar, | |
| }, | |
| }, | |
| "arvore_iter_vs_rec": { | |
| "n_nos": arv.n_nos(), | |
| "total_iter": total_it, "total_rec": total_rec, | |
| "bit_a_bit": total_it.to_bits() == total_rec.to_bits(), | |
| "tempo_iter_s": tempo_arv_it, "tempo_rec_s": tempo_arv_rec, | |
| "gates": { "iguais_bit_a_bit": total_it == total_rec }, | |
| }, | |
| "moe_vetorizada": { | |
| "max_dif_valores": dif_moe, | |
| "tempo_ref_s": tempo_moe_ref, "tempo_vet_s": tempo_moe_vet, | |
| "grad_roteador_ref": grad_ref_r, "grad_especialistas_ref": grad_ref_e, | |
| "grad_roteador_vet": grad_vet_r, "grad_especialistas_vet": grad_vet_e, | |
| "gates": { | |
| "valores_iguais": dif_moe < 1e-4, | |
| "bug_v080_1_confirmado": grad_ref_r == 0.0 && grad_ref_e == 0.0, | |
| "gradiente_restaurado": grad_vet_r > 0.0 && grad_vet_e > 0.0, | |
| }, | |
| }, | |
| "ablacao_jepa_3_bracos_v080": ablac, | |
| }); | |
| Ok(pythonize::pythonize(py, &d_)?.into()) | |
| } | |
| /// **v0.9.0 — veredito executável das críticas Qwen3.8 (r-34):** mede os | |
| /// aprimoramentos contra as referências v0.8.0 (oráculos preservados): | |
| /// (1) skew O(n²) via index_add — bit-a-bit + tempo + memória analítica; | |
| /// (2) calibrar vetorial — bit-a-bit em 3 passos EMA + tempo; | |
| /// (3) forward canônico (ex-fwd_vetorizado) — regressão de valores e | |
| /// gradiente; | |
| /// (4) newtypes de domínio — rejeição de fora-de-domínio. | |
| pub(crate) fn demo_criticas_v090(py: Python) -> PyResult<PyObject> { | |
| use candle_core::{Device, Tensor}; | |
| use std::time::Instant; | |
| let dev = Device::Cpu; | |
| let mut rng = crate::rng::RngDeterministico::novo(909); | |
| // ---------- (1) skew: index_add O(n²) vs matmul de seleção O(n⁴) ---------- | |
| let mut skew_rel = serde_json::Map::new(); | |
| let mut bits_todos = true; | |
| for &n in &[16usize, 64, 128] { | |
| let r = fnh::RotacaoSkew::nova(n, &dev).unwrap(); | |
| let m = n * (n - 1) / 2; | |
| let th: Vec<f32> = (0..m).map(|_| rng.uniforme_intervalo(-0.9, 0.9) as f32).collect(); | |
| r.theta.set(&Tensor::from_vec(th, (m,), &dev).unwrap()).unwrap(); | |
| // bit-a-bit (F-13) | |
| let an = r.skew().unwrap().flatten_all().unwrap().to_vec1::<f32>().unwrap(); | |
| let ar = r.skew_matmul_referencia().unwrap().flatten_all().unwrap().to_vec1::<f32>().unwrap(); | |
| let bits_iguais = an.iter().zip(ar.iter()).all(|(a, b)| a.to_bits() == b.to_bits()); | |
| bits_todos &= bits_iguais; | |
| // tempo (referência esquentada 1×; média de 5) | |
| let _ = r.skew_matmul_referencia().unwrap(); | |
| let t0 = Instant::now(); | |
| for _ in 0..5 { let _ = r.skew_matmul_referencia().unwrap(); } | |
| let t_ref = t0.elapsed().as_secs_f64() / 5.0; | |
| let _ = r.skew().unwrap(); | |
| let t0 = Instant::now(); | |
| for _ in 0..5 { let _ = r.skew().unwrap(); } | |
| let t_novo = t0.elapsed().as_secs_f64() / 5.0; | |
| let bytes_ref = (m * n * n * 4) as f64; | |
| let bytes_novo = ((n * n + 3 * m) * 4 + 2 * m * 4) as f64; | |
| skew_rel.insert( | |
| format!("n_{n}"), | |
| serde_json::json!({ | |
| "tempo_ref_s": t_ref, "tempo_novo_s": t_novo, | |
| "speedup": t_ref / t_novo.max(1e-12), | |
| "bytes_ref_selecao": bytes_ref, "bytes_novo": bytes_novo, | |
| "razao_memoria": bytes_ref / bytes_novo, | |
| "bits_iguais": bits_iguais, | |
| }), | |
| ); | |
| } | |
| // ---------- (2) calibrar: tensor vs laços nativos ---------- | |
| let (d_out, d_in, n_lin) = (512usize, 512usize, 4096usize); | |
| let wv: Vec<f32> = (0..d_out * d_in).map(|_| rng.uniforme_intervalo(-2.0, 2.0) as f32).collect(); | |
| let w = Tensor::from_vec(wv, (d_out, d_in), &dev).unwrap(); | |
| let xv: Vec<f32> = (0..n_lin * d_in).map(|_| rng.uniforme_intervalo(-3.0, 3.0) as f32).collect(); | |
| let x = Tensor::from_vec(xv, (n_lin, d_in), &dev).unwrap(); | |
| let mut s_novo = fnh::SuavizadorQuant::novo(0.5, 0.98); | |
| let mut s_tens = fnh::SuavizadorQuant::novo(0.5, 0.98); | |
| let mut s_ref = fnh::SuavizadorQuant::novo(0.5, 0.98); | |
| let mut bits_cal = true; | |
| for _ in 0..3 { | |
| s_novo.calibrar(&w, &x).unwrap(); | |
| s_tens.calibrar_tensor(&w, &x).unwrap(); | |
| s_ref.calibrar_referencia(&w, &x).unwrap(); | |
| for (a, b) in s_novo.w_max.as_ref().unwrap().iter().zip(s_ref.w_max.as_ref().unwrap()) { | |
| bits_cal &= a.to_bits() == b.to_bits(); | |
| } | |
| for (a, b) in s_novo.x_max.as_ref().unwrap().iter().zip(s_ref.x_max.as_ref().unwrap()) { | |
| bits_cal &= a.to_bits() == b.to_bits(); | |
| } | |
| } | |
| // tempo (esquentadas 1×; média de 5) | |
| let _ = s_ref.calibrar_referencia(&w, &x); | |
| let t0 = Instant::now(); | |
| for _ in 0..5 { s_ref.calibrar_referencia(&w, &x).unwrap(); } | |
| let t_cal_ref = t0.elapsed().as_secs_f64() / 5.0; | |
| let _ = s_novo.calibrar(&w, &x); | |
| let t0 = Instant::now(); | |
| for _ in 0..5 { s_novo.calibrar(&w, &x).unwrap(); } | |
| let t_cal_novo = t0.elapsed().as_secs_f64() / 5.0; | |
| let _ = s_tens.calibrar_tensor(&w, &x); | |
| let t0 = Instant::now(); | |
| for _ in 0..5 { s_tens.calibrar_tensor(&w, &x).unwrap(); } | |
| let t_cal_tens = t0.elapsed().as_secs_f64() / 5.0; | |
| // ---------- (3) forward: regressão de valores + gradiente ---------- | |
| let (nm, dm, em) = (256usize, 32usize, 8usize); | |
| let xv2: Vec<f32> = (0..nm * dm).map(|_| rng.normal(0.0, 1.0) as f32).collect(); | |
| let x2 = Tensor::from_vec(xv2, (nm, dm), &dev).unwrap(); | |
| // oráculo do bug v080-1 (r-33 §5) | |
| let moe = moe_redirecionavel::MoeRedirecionavel::novo(dm, em, 2, nm, &dev).unwrap(); | |
| let s_refm = moe.fwd(&x2, moe_redirecionavel::Papel::Codificador).unwrap(); | |
| let s_fwd = moe.forward(&x2, moe_redirecionavel::Papel::Codificador).unwrap(); | |
| let dif_moe = (&s_refm.saida - &s_fwd.saida).unwrap().abs().unwrap() | |
| .max_all().unwrap().to_scalar::<f32>().unwrap() as f64; | |
| let perda = s_fwd.saida.sqr().unwrap().sum_all().unwrap(); | |
| let gs = perda.backward().unwrap(); | |
| let mut gr = 0.0f64; | |
| for v in moe.roteador.vars() { | |
| if let Some(g) = gs.get(&v) { | |
| gr += g.sqr().unwrap().sum_all().unwrap().to_scalar::<f32>().unwrap() as f64; | |
| } | |
| } | |
| let mut ge = 0.0f64; | |
| for e in &moe.especialistas { | |
| for v in e.vars() { | |
| if let Some(g) = gs.get(&v) { | |
| ge += g.sqr().unwrap().sum_all().unwrap().to_scalar::<f32>().unwrap() as f64; | |
| } | |
| } | |
| } | |
| // ---------- (4) newtypes de domínio (T-V1) ---------- | |
| let rejeita = crate::tipos::Probabilidade::novo(7.0).is_err() | |
| && crate::tipos::Probabilidade::novo(-0.5).is_err() | |
| && crate::tipos::Probabilidade::novo(f64::NAN).is_err() | |
| && crate::tipos::GateAtivacao::novo(1.5).is_err(); | |
| let aceita = crate::tipos::Probabilidade::novo(0.37).unwrap().valor() == 0.37; | |
| let gate_tipado = fnh::GatePunicao::default() | |
| .valor_tipado(&crate::tipos::Probabilidade::novo(0.9).unwrap()) | |
| .valor(); | |
| let d_ = serde_json::json!({ | |
| "versao": "criticas-v090-1.0", | |
| "skew_index_add": { | |
| "por_n": skew_rel, | |
| "gates": { | |
| "bits_iguais_todos_n": bits_todos, | |
| }, | |
| }, | |
| "calibrar_zero_copia": { | |
| "bits_iguais_3_passos": bits_cal, | |
| "tempo_ref_s": t_cal_ref, "tempo_novo_s": t_cal_novo, | |
| "tempo_tensor_s": t_cal_tens, | |
| "speedup_zero_copia": t_cal_ref / t_cal_novo.max(1e-12), | |
| "razao_tensor_vs_zero_copia": t_cal_tens / t_cal_novo.max(1e-12), | |
| "gates": { "bit_a_bit": bits_cal, "nao_regride": t_cal_novo <= t_cal_ref * 1.05 }, | |
| }, | |
| "forward_canonico": { | |
| "max_dif_valores_vs_oraculo": dif_moe, | |
| "grad_roteador": gr, "grad_especialistas": ge, | |
| "gates": { | |
| "valores_iguais": dif_moe < 1e-4, | |
| "gradiente_ativo": gr > 0.0 && ge > 0.0, | |
| }, | |
| }, | |
| "newtypes_dominio": { | |
| "rejeita_fora_do_dominio": rejeita, | |
| "aceita_dentro": aceita, | |
| "gate_tipado_em_0_9": gate_tipado, | |
| "gates": { "fronteira_validada": rejeita && aceita }, | |
| }, | |
| }); | |
| Ok(pythonize::pythonize(py, &d_)?.into()) | |
| } | |