aurora-multimodal-ptbr / scripts /06_publicar_hf.py
PowerMachine's picture
AURORA v7 — RETREINO OBSERVADO: estados antigos apagados; treino do zero com monitor de RAM integral (Agente Engenheiro); métricas de tests/test_aurora_v6.py comparadas com o treino anterior; gráficos de desempenho publicados no card
7eea4b4 verified
Raw History Blame Contribute Delete
7 kB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Publica o AURORA v7 no HuggingFace de modo ORGANIZADO e COMPLETO:
README.md (model card v7 COM GRÁFICOS DE DESEMPENHO) · LICENSE · configs/ ·
src/aurora/ · scripts/ · docs/matematica/ (provas 00–18) · tests/ · evidências
de treino/avaliação/comparação · estados/fase-v7/ (pesos finais + meta SHA-256)
REGRAS DO HUB (escopo v5): publicação em UM ÚNICO COMMIT COMPLETO —
`upload_folder` com `delete_patterns=["*"]` substitui ATOMICAMENTE todo o
conteúdo do repo (arquivos antigos somem no MESMO commit; nunca há uploads
parciais em sequência curta — o Hub bloqueia esse padrão).
SEGURANÇA: token EXCLUSIVAMENTE da variável HF_TOKEN — nunca gravado em
arquivo, log ou repo. A publicação NUNCA inclui: cache_dados, telemetria_out,
estados_local, stage_publicar, arquivos com o token.
Verificações de porta do Agente Engenheiro (pré-publicação):
• nenhum segredo no stage (regex hf_[A-Za-z0-9]{30,});
• nenhum resíduo proibido (bugwatch, estados_hf, __pycache__, .pt).
Uso: HF_TOKEN=... python3 06_publicar_hf.py [--repo PowerMachine/aurora-multimodal-ptbr]
"""
import argparse
import os
import re
import shutil
import sys
RAIZ = "/home/z/my-project/aurora"
STAGE = "/home/z/my-project/aurora/stage_publicar"
PASTA_ESTADO = "estados/fase-v7" # ÚNICO estado publicado (pesos finais)
IGNORAR_DIRS = {"__pycache__", "cache_dados", "telemetria_out",
"cache_hub_tmp", ".git", "build", "estados_local",
"estados_local_teste", "stage_publicar", "hf_stage",
"download", "upload"}
IGNORAR_EXT = (".pt", ".pyc", ".pt.tmp")
PADRAO_TOKEN = re.compile(r"hf_[A-Za-z0-9]{30,}")
RESIDUOS_PROIBIDOS = ("bugwatch", "estados_hf")
def preparar_stage() -> int:
if os.path.exists(STAGE):
shutil.rmtree(STAGE)
n = 0
for raiz, dirs, arquivos in os.walk(RAIZ):
dirs[:] = [d for d in dirs if d not in IGNORAR_DIRS]
rel = os.path.relpath(raiz, RAIZ)
alvo_raiz = os.path.join(STAGE, rel) if rel != "." else STAGE
os.makedirs(alvo_raiz, exist_ok=True)
for a in arquivos:
if a.endswith(IGNORAR_EXT) or a.startswith("."):
continue
if any(r in a.lower() for r in RESIDUOS_PROIBIDOS):
print(f" porta do Agente: arquivo proibido ignorado: {a}")
continue
shutil.copy2(os.path.join(raiz, a), os.path.join(alvo_raiz, a))
n += 1
# evidências de treino/avaliação (artefatos de 1ª classe, v7)
for nome in ("avaliacao_v7.json", "resumo_treino_v7.json",
"relatorio_agente_engenheiro.json",
"comparacao_treino_v7.json", "test_aurora_v6_pos_treino.txt"):
fonte = os.path.join(RAIZ, "telemetria_out", nome)
if os.path.exists(fonte):
shutil.copy2(fonte, os.path.join(STAGE, nome))
n += 1
# v7 — GRÁFICOS DE DESEMPENHO (publicados APENAS no card HF — README.md)
dir_graf = os.path.join(RAIZ, "graficos")
if os.path.isdir(dir_graf):
os.makedirs(os.path.join(STAGE, "graficos"), exist_ok=True)
for a in sorted(os.listdir(dir_graf)):
if a.endswith(".png"):
shutil.copy2(os.path.join(dir_graf, a),
os.path.join(STAGE, "graficos", a))
n += 1
# ÚNICO estado (pesos finais) via GestorCheckpoints (doc 16 §8)
sys.path.insert(0, os.path.join(RAIZ, "src"))
from aurora.dados.checkpoints import GestorCheckpoints
from aurora.config import Config
gestor = GestorCheckpoints(dir_local=Config().checkpoints.dir_local,
pasta_publicacao=PASTA_ESTADO)
if gestor.preparar_para_publicacao(STAGE):
n += 2
print(f"estado final incluído: {PASTA_ESTADO}/modelo.safetensors")
else:
print("AVISO: sem checkpoint local — publicando só código/docs")
return n
def auditoria_segredos() -> list[str]:
suspeitos = []
for raiz, dirs, arquivos in os.walk(STAGE):
for a in arquivos:
if not a.endswith((".json", ".md", ".py", ".txt", ".yaml", ".yml")):
continue
caminho = os.path.join(raiz, a)
try:
with open(caminho, encoding="utf-8", errors="ignore") as f:
if PADRAO_TOKEN.search(f.read()):
suspeitos.append(caminho)
except Exception:
pass
return suspeitos
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--repo", default="PowerMachine/aurora-multimodal-ptbr")
args = ap.parse_args()
token = os.environ.get("HF_TOKEN")
if not token:
print("ERRO: defina HF_TOKEN no ambiente (nunca em arquivo).")
sys.exit(1)
n = preparar_stage()
print(f"stage: {n} arquivos (sem caches/segredos/resíduos)")
suspeitos = auditoria_segredos()
if suspeitos:
print("ERRO: possíveis segredos detectados:", suspeitos)
sys.exit(1)
from huggingface_hub import HfApi
api = HfApi(token=token)
api.create_repo(args.repo, repo_type="model", exist_ok=True, private=False)
# PUBLICAÇÃO ÚNICA E COMPLETA: delete_patterns=["*"] remove no MESMO commit
# qualquer arquivo antigo — nada de uploads parciais em sequência
api.upload_folder(
folder_path=STAGE, repo_id=args.repo, repo_type="model",
commit_message="AURORA v7 — RETREINO OBSERVADO: estados antigos apagados; "
"treino do zero com monitor de RAM integral (Agente Engenheiro); "
"métricas de tests/test_aurora_v6.py comparadas com o treino "
"anterior; gráficos de desempenho publicados no card",
delete_patterns=["*"],
allow_patterns=["*.py", "*.md", "*.json", "*.yaml", "*.yml",
"*.txt", "*.png", "*.safetensors", "LICENSE*"])
print("✓ PUBLICAÇÃO ÚNICA COMPLETA (1 commit; antigos removidos "
"atomicamente)")
# verificação final: resíduos proibidos não podem existir no repo
arquivos = api.list_repo_files(args.repo, repo_type="model")
restos = [f for f in arquivos
if any(r in f.lower() for r in RESIDUOS_PROIBIDOS)
or "__pycache__" in f or f.endswith(".pt")]
if restos:
print("ERRO: resíduos no repo:", restos)
sys.exit(1)
parciais = [f for f in arquivos if f.startswith("estados/")
and "fase-v7" not in f]
print(f"✓ verificação: {len(arquivos)} arquivos no repo; "
f"resíduos=0; estados parciais={len(parciais)} (0 esperado)")
print(f"REPO: https://huggingface.co/{args.repo}")
print("Higienização: unset HF_TOKEN && python3 -m pip show huggingface_hub "
">/dev/null && python3 -c 'from huggingface_hub import HfApi; "
"HfApi().logout()'")
if __name__ == "__main__":
main()