File size: 5,728 Bytes
28430a8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | #!/usr/bin/env python3
"""68_suite_v080.py — v0.8.0: VEREDITO CONSOLIDADO das propostas Qwen3.8.
Executa demo_qwen_v080 TRÊS vezes (a ablação JEPA usa o RNG global do candle
na inicialização — gates direcionais agregados sobre execuções), herda os 73
gates da v0.7.0 (suite_v070_final.json) e adiciona os gates das 4 propostas
analisadas/provadas/testadas em r-33:
1. Newton analítico (verificador) — N-1..N-4
2. Árvore pós-ordem iterativa — T-A7..T-A9
3. Cayley exato (FNH) — F-9..F-12
4. MoE vetorizada com gradiente restaurado (bug v080-1) — M-R6..M-R8
"""
import json, os, sys
def main():
pasta = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
R = os.path.join(pasta, "resultados")
rel = {"versao": "0.8.0", "blocos": {}, "gates": {}}
def carrega(arq):
p = os.path.join(R, arq)
if os.path.exists(p):
with open(p) as f:
return json.load(f)
return None
# ---- bloco legado v0.7.0 (se presente)
legado = carrega("suite_v070_final.json")
if legado:
g_legado = legado.get("gates", legado)
ok = sum(1 for v in g_legado.values() if v is True)
rel["blocos"]["legado_v070"] = f"{ok}/{len(g_legado)}"
for k, v in g_legado.items():
rel["gates"][f"legado_{k}"] = v
# ---- demos v0.8.0 (3 execuções)
import khtst_rust as k
execucoes = [k.demo_qwen_v080() for _ in range(3)]
# (1) Newton vs golden
nvg = execucoes[0]["newton_vs_golden"]
for nome, val in nvg["gates"].items():
rel["gates"][f"q1_newton_{nome}"] = val
rel["blocos"]["q1_newton"] = f"{sum(1 for v in nvg['gates'].values() if v)}/{len(nvg['gates'])}"
rel["medicoes"] = {
"q1": {kk: nvg[kk] for kk in
("t_golden", "t_newton", "n_aval_newton", "nll_golden", "nll_newton",
"tempo_golden_s", "tempo_newton_s")},
}
# (2) Cayley vs polar
cvp = execucoes[0]["cayley_vs_polar"]
for nome, val in cvp["gates"].items():
rel["gates"][f"q3_cayley_{nome}"] = val
rel["blocos"]["q3_cayley"] = f"{sum(1 for v in cvp['gates'].values() if v)}/{len(cvp['gates'])}"
rel["medicoes"]["q3"] = {kk: cvp[kk] for kk in
("delta_ort_polar", "delta_ort_cayley",
"tempo_polar_s", "tempo_cayley_s", "speedup")}
# (3) árvore iterativa
arv = execucoes[0]["arvore_iter_vs_rec"]
for nome, val in arv["gates"].items():
rel["gates"][f"q2_arvore_{nome}"] = val
rel["blocos"]["q2_arvore"] = f"{sum(1 for v in arv['gates'].values() if v)}/{len(arv['gates'])}"
rel["medicoes"]["q2"] = {kk: arv[kk] for kk in
("n_nos", "total_iter", "tempo_iter_s", "tempo_rec_s")}
# (4) MoE vetorizada (determinística — valores/gradientes)
moe = execucoes[0]["moe_vetorizada"]
for nome, val in moe["gates"].items():
rel["gates"][f"q4_moe_{nome}"] = val
rel["blocos"]["q4_moe"] = f"{sum(1 for v in moe['gates'].values() if v)}/{len(moe['gates'])}"
rel["medicoes"]["q4"] = {kk: moe[kk] for kk in
("max_dif_valores", "tempo_ref_s", "tempo_vet_s",
"grad_roteador_vet", "grad_especialistas_vet")}
# (5) ablação JEPA 3 braços — gates DIRECIONAIS nas 3 execuções
quedas_moe, quedas_peq, quedas_den = [], [], []
for ex in execucoes:
ab = ex["ablacao_jepa_3_bracos_v080"]
quedas_moe.append(ab["moe"]["queda_pct"])
quedas_peq.append(ab["pequena"]["queda_pct"])
quedas_den.append(ab["densa"]["queda_pct"])
moe_min = min(quedas_moe)
peq_max = max(quedas_peq)
rel["gates"]["q5_ablacao_moe_aprende_3x"] = all(q > 30.0 for q in quedas_moe)
rel["gates"]["q5_ablacao_moe_domina_pequena_3x"] = moe_min > peq_max
rel["medicoes"]["q5"] = {
"quedas_moe_pct": quedas_moe, "quedas_pequena_pct": quedas_peq,
"quedas_densa_pct": quedas_den,
"nota": "inicialização via RNG global do candle — gates direcionais",
}
rel["blocos"]["q5_ablacao"] = (
f"{sum(1 for v in (rel['gates']['q5_ablacao_moe_aprende_3x'], rel['gates']['q5_ablacao_moe_domina_pequena_3x']) if v)}/2")
# ---- provas cargo (contagem)
try:
import subprocess, re
res = subprocess.run(
["cargo", "test", "--manifest-path", os.path.join(pasta, "Cargo.toml")],
capture_output=True, text=True, timeout=1800,
env={**os.environ, "PATH": os.environ["PATH"] + ":" + os.path.expanduser("~/.cargo/bin")},
)
saida = res.stdout + res.stderr
linhas = [l for l in saida.splitlines() if "test result:" in l]
m = re.search(r"(\d+) passed; (\d+) failed", linhas[0] if linhas else "")
if m:
total_c = int(m.group(1)) + int(m.group(2))
rel["blocos"]["cargo"] = f"{m.group(1)}/{total_c}"
rel["gates"]["cargo_todos_verdes"] = m.group(2) == "0"
else:
rel["blocos"]["cargo"] = "sem resultado"
rel["gates"]["cargo_todos_verdes"] = False
except Exception as e:
rel["blocos"]["cargo"] = f"erro: {e}"
rel["gates"]["cargo_todos_verdes"] = False
# ---- veredito
total = len(rel["gates"])
ok = sum(1 for v in rel["gates"].values() if v is True)
rel["veredito"] = f"{ok}/{total}"
with open(os.path.join(R, "suite_v080_final.json"), "w") as f:
json.dump(rel, f, indent=1, ensure_ascii=False)
print(json.dumps({"blocos": rel["blocos"], "veredito": rel["veredito"]},
indent=1, ensure_ascii=False))
sys.exit(0 if ok == total else 1)
if __name__ == "__main__":
main()
|