khtst-rust / scripts /68_suite_v080.py
PowerMachine's picture
v0.8.0: análise/prova/teste das 4 propostas Qwen3.8 (r-33) — Newton analítico no verificador (convexidade em gamma=1/T), árvore pós-ordem iterativa bit-a-bit com detecção de ciclos, Cayley exato no FNH (4,1× mais rápido), MoE vetorizada com gradiente RESTAURADO (bug v080-1) — 85/85 gates, 99/99 cargo
28430a8 verified
Raw History Blame Contribute Delete
5.73 kB
#!/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()