khtst-rust / scripts /71_treino_v090.py
PowerMachine's picture
v0.9.0: análise/prova/teste das críticas Qwen3.8 lote 2 (r-34) — SIMD com despacho em runtime bit-a-bit (X-1), oráculo candle_nn::optim::AdamW (nosso 1,53× mais rápido), Thompson Sampling (regret 0,0019 vs UCB1 0,0156), GNG por entropia com piso (T-G1'), JEPA de fração adaptativa (bit-a-bit com 1 braço), configs tipadas, entrada numpy (2008× na fronteira), avaliação com dados reais — 104/104 gates, 111/111 cargo
d444358 verified
Raw History Blame Contribute Delete
6.95 kB
#!/usr/bin/env python3
"""71_treino_v090.py — AVALIAÇÃO COM DADOS REAIS dos mecanismos v0.9.0.
Pipeline (dados: Wikipédia PT-BR, wikimedia/wikipedia 20231101.pt):
1. Fases A/B/C CURTAS com entrada NUMPY (novo caminho _np — exercita a
fronteira rust-numpy em treino real);
2. JEPA-T sobre LATENTES REAIS do tokenizador treinado: fração adaptativa
(Thompson, 4 braços) vs fração fixa 0,35 — mesma semente, mesmas épocas;
3. GNG sobre latentes reais: critério padrão (erro máximo) vs
entropia_com_piso (T-G1') no mesmo orçamento de vértices;
4. Painel de telemetria v090 (despacho SIMD agregado).
"""
import json, os, sys, time
import numpy as np
def main():
pasta = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, pasta)
os.makedirs(os.path.join(pasta, "resultados"), exist_ok=True)
import khtst_rust as K
cfg = K.Config(os.path.join(pasta, "configs", "base_rust.json"))
ck_tok = os.path.join(pasta, "resultados", "tokenizador_conceitos.json")
ck_ger = os.path.join(pasta, "resultados", "gerador_conceitos.json")
tel_c = os.path.join(pasta, "resultados", "telemetria_fase_c.jsonl")
bpe = K.Bpe.carregar(os.path.join(pasta, "dados", "bpe.json"))
seqs = []
with open(os.path.join(pasta, "dados", "shard_treino.jsonl")) as f:
for linha in f:
ids = bpe.codificar(json.loads(linha)["texto"])
for i in range(0, max(1, len(ids) - 256), 128):
seqs.append(ids[i:i + 256])
seqs = seqs[:1400]
PAD = 0 # crate::tokens::PAD
largura = max(len(s) for s in seqs)
seqs_np = np.array(
[s + [PAD] * (largura - len(s)) for s in seqs], dtype=np.uint32
)
rel = {
"versao": "0.9.0",
"dados": {"sequencias": len(seqs), "fonte": "wikimedia/wikipedia 20231101.pt"},
"fases": {},
}
print(f"sequências: {len(seqs)} (ctx=256) | numpy {seqs_np.shape}", flush=True)
# -------------------------------- fase A (numpy)
if not os.path.exists(ck_tok):
print("=== FASE A — tokenizador (entrada NUMPY) ===", flush=True)
t0 = time.time()
saida = K.treinar_fase_a_np(cfg, seqs_np, None, ck_tok, None, 200.0)
rel["fases"]["a"] = {**saida["resumo"], "tempo_s": round(time.time() - t0, 1)}
print(json.dumps(rel["fases"]["a"], indent=1, ensure_ascii=False), flush=True)
else:
print("fase A: checkpoint presente", flush=True)
# -------------------------------- fase B (numpy)
if not os.path.exists(ck_ger):
print("=== FASE B — gerador (entrada NUMPY) ===", flush=True)
t0 = time.time()
saida_b = K.treinar_fase_b_np(cfg, seqs_np, ck_tok, None, ck_ger, teto_seg=200.0)
rel["fases"]["b"] = {**saida_b["resumo"], "tempo_s": round(time.time() - t0, 1)}
print(json.dumps(rel["fases"]["b"], indent=1, ensure_ascii=False), flush=True)
else:
print("fase B: checkpoint presente", flush=True)
# -------------------------------- fase C (numpy, curta)
print("=== FASE C — conjunto (entrada NUMPY, 60 passos) ===", flush=True)
t0 = time.time()
saida_c = K.treinar_fase_c(cfg, seqs, ck_tok, passos=60, caminho_gerador=ck_ger,
caminho_telemetria=tel_c, teto_seg=120.0)
rc = saida_c["resumo"]
rc["tempo_s"] = round(time.time() - t0, 1)
rel["fases"]["c"] = rc
print(json.dumps({k: rc[k] for k in list(rc)[:8]}, indent=1, ensure_ascii=False), flush=True)
# -------------------------------- latentes reais
print("=== LATENTES REAIS (tokenizador treinado) ===", flush=True)
lat = K.codificar_latentes(cfg, ck_tok, seqs_np[:64])
print(f"latentes: {lat.shape} {lat.dtype}", flush=True)
# -------------------------------- JEPA-T real: adaptativa vs fixa
print("=== JEPA-T REAL — fração adaptativa vs fixa ===", flush=True)
cfg_j = json.dumps({"epocas": 40, "d_emb": 48, "semente": 42, "lr": 2e-3})
resultados_j = {}
# um JEPA por janela (8 janelas) — patches = latentes da janela (256, d_lat)
quedas_fix, quedas_ada = [], []
for w in range(4):
janela = lat[w].astype(float).tolist() # (256, d_lat)
fixo = K.treinar_jepa(janela, [256], "tjepa", cfg_j)
ada = K.treinar_jepa_adaptativa(
janela, [256], "tjepa", [0.2, 0.35, 0.5, 0.65], cfg_j)
quedas_fix.append(fixo["queda_pct"])
quedas_ada.append(ada["queda_pct"])
if w == 0:
resultados_j["janela0"] = {
"fixa": {"perda_ini": fixo["perda_pred_inicial"], "perda_fim": fixo["perda_pred_final"],
"queda_pct": fixo["queda_pct"]},
"adaptativa": {"perda_ini": ada["perda_pred_final"] and ada["perda_pred_inicial"],
"perda_fim": ada["perda_pred_final"], "queda_pct": ada["queda_pct"],
"jogadas": ada["jogadas_por_braco"], "posterior": ada["posterior"]},
}
media_fix = sum(quedas_fix) / len(quedas_fix)
media_ada = sum(quedas_ada) / len(quedas_ada)
resultados_j["media_queda_fixa_pct"] = media_fix
resultados_j["media_queda_adaptativa_pct"] = media_ada
resultados_j["por_janela"] = {"fixa": quedas_fix, "adaptativa": quedas_ada}
rel["jepa_real"] = resultados_j
print(f" queda média: fixa {media_fix:.1f}% | adaptativa {media_ada:.1f}%", flush=True)
# -------------------------------- GNG real: padrão vs entropia_com_piso
print("=== GNG REAL — erro máximo vs entropia+piso ===", flush=True)
# nuvem = latentes achatados (256×256, d_lat) subamostrados
nuvem = lat.reshape(-1, lat.shape[-1])
sel = np.random.default_rng(3).choice(len(nuvem), 2000, replace=False)
nuvem_list = nuvem[sel].astype(float).tolist()
cfg_g = json.dumps({"passos": 4000, "max_vertices": 48, "semente": 42})
g_pad = K.treinar_gng(nuvem_list, cfg_g)
g_piso = K.treinar_gng(nuvem_list, json.dumps({
"passos": 4000, "max_vertices": 48, "semente": 42, "criterio": "entropia_com_piso"}))
rel["gng_real"] = {
"padrao": {"vertices": g_pad["vertices"], "eq": g_pad["eq_medio"], "insercoes": g_pad["insercoes"]},
"entropia_piso": {"vertices": g_piso["vertices"], "eq": g_piso["eq_medio"],
"insercoes": g_piso["insercoes"], "bloqueadas": g_piso["insercoes_bloqueadas_entropia"]},
"eq_ratio_piso_vs_padrao": (g_piso["eq_medio"] / g_pad["eq_medio"]) if g_pad["eq_medio"] > 0 else None,
}
print(json.dumps(rel["gng_real"], indent=1, ensure_ascii=False), flush=True)
# -------------------------------- painel v090
rel["simd"] = K.simd_relatorio()
with open(os.path.join(pasta, "resultados", "treino_v090.json"), "w") as f:
json.dump(rel, f, indent=1, ensure_ascii=False)
print("salvo: resultados/treino_v090.json", flush=True)
if __name__ == "__main__":
main()