V6.5-V2-dynamic: upload batch (scripts + state + model) [12 files]
Browse files- hyp_t.py +100 -0
- kohonen_learning_system.py +0 -0
- streaming_datasets.py +995 -0
- train_v6_5_v2.py +1831 -0
- v6_5_v2_attention_eval.json +21 -0
- v6_5_v2_model_states.pt +3 -0
- v6_5_v2_model_states_after_conhecimento.pt +3 -0
- v6_5_v2_phases_eval.json +784 -0
- v6_5_v2_predict_fix_eval.json +120 -0
- v6_5_v2_report.json +172 -0
- v6_5_v2_user_questions.json +82 -0
- xeon_runtime.py +581 -0
hyp_t.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""hyp_t.py — HypT: cabeça de hipótese (correção delta). Implementa o Lema 3.
|
| 2 |
+
|
| 3 |
+
A Hipótese é treinada para cancelar o ruído de quantização W8A8:
|
| 4 |
+
y_final = y_hat + delta
|
| 5 |
+
onde delta = hyp_T(o).
|
| 6 |
+
|
| 7 |
+
Diferenças vs. TrainT:
|
| 8 |
+
- Recebe `o` opcionalmente destacado (stop_grad) para isolar o sinal de
|
| 9 |
+
correção do gradiente principal
|
| 10 |
+
- Mesma arquitetura (TransformerEncoder) — apenas o tratamento de gradiente
|
| 11 |
+
difere
|
| 12 |
+
|
| 13 |
+
Reaproveita a filosofia do HypothesisNetwork do v13.9.2 (16 hipóteses com
|
| 14 |
+
mapeamento LoRA), mas simplificada: 1 única hipótese global (delta) em vez
|
| 15 |
+
de 16 hipóteses paralelas. A multiplexação é feita pelo OrqCell + Lema 1.
|
| 16 |
+
|
| 17 |
+
============================================================================
|
| 18 |
+
V6.4 — pgvector_lookup REMOVIDO (NÃO É MAIS NECESSÁRIO)
|
| 19 |
+
============================================================================
|
| 20 |
+
Conforme directive do usuário:
|
| 21 |
+
"pgvector_lookup não é mais necessário pela lógica do script seguinte"
|
| 22 |
+
|
| 23 |
+
O KohonenLearningSystem (kohonen_refactored/kohonen_learning_system.py)
|
| 24 |
+
contém o método find_bmu que realiza busca nearest-neighbor sobre o grid
|
| 25 |
+
4D do SOM (864 neurônios para grid (6,6,6,4)), substituindo qualquer
|
| 26 |
+
lookup pgvector externo. A decisão de aplicar punição é delegada ao
|
| 27 |
+
protocolo interno do KohonenLearningSystem (1ª punição → activate_hypothesis,
|
| 28 |
+
2ª punição → set_ewc_reference + reset).
|
| 29 |
+
|
| 30 |
+
Consequentemente, HypT volta ao seu papel original: gerar a correção
|
| 31 |
+
delta = hyp_T(o) sem consultar mapa externo. A integração com o SOM é
|
| 32 |
+
feita no nível do trainer (KohonenLearningSystem.process_batch), não no
|
| 33 |
+
nível da hipótese.
|
| 34 |
+
|
| 35 |
+
Os contadores de punição (n_complete_skip, n_incomplete_apply, etc.)
|
| 36 |
+
foram removidos pois não há mais decisão de skip baseada em pgvector.
|
| 37 |
+
"""
|
| 38 |
+
from __future__ import annotations
|
| 39 |
+
|
| 40 |
+
import torch
|
| 41 |
+
import torch.nn as nn
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class HypT(nn.Module):
|
| 45 |
+
"""Transformer de hipótese: gera correção delta.
|
| 46 |
+
|
| 47 |
+
Args:
|
| 48 |
+
d_input: dimensão de entrada (saída do OrqCell = d_cache)
|
| 49 |
+
d_model: dimensão interna
|
| 50 |
+
nhead: nº de cabeças
|
| 51 |
+
d_ff: dimensão do FFN
|
| 52 |
+
output_dim: dimensão de saída (igual ao TrainT)
|
| 53 |
+
num_layers: nº de camadas
|
| 54 |
+
dropout: probabilidade de dropout
|
| 55 |
+
|
| 56 |
+
Forward:
|
| 57 |
+
o: (batch, d_input), stop_grad: bool → delta: (batch, output_dim)
|
| 58 |
+
|
| 59 |
+
Se stop_grad=True, aplica o.detach() no início — Lema 3 (isolar correção
|
| 60 |
+
do gradiente principal).
|
| 61 |
+
"""
|
| 62 |
+
|
| 63 |
+
def __init__(
|
| 64 |
+
self,
|
| 65 |
+
d_input: int,
|
| 66 |
+
d_model: int,
|
| 67 |
+
nhead: int,
|
| 68 |
+
d_ff: int,
|
| 69 |
+
output_dim: int,
|
| 70 |
+
num_layers: int = 2,
|
| 71 |
+
dropout: float = 0.1,
|
| 72 |
+
):
|
| 73 |
+
super().__init__()
|
| 74 |
+
self.d_input = d_input
|
| 75 |
+
self.d_model = d_model
|
| 76 |
+
self.output_dim = output_dim
|
| 77 |
+
|
| 78 |
+
self.proj_in = nn.Linear(d_input, d_model)
|
| 79 |
+
encoder_layer = nn.TransformerEncoderLayer(
|
| 80 |
+
d_model, nhead, d_ff, dropout=dropout, batch_first=True
|
| 81 |
+
)
|
| 82 |
+
self.encoder = nn.TransformerEncoder(encoder_layer, num_layers)
|
| 83 |
+
self.proj_out = nn.Linear(d_model, output_dim)
|
| 84 |
+
|
| 85 |
+
def forward(self, o: torch.Tensor, stop_grad: bool = True) -> torch.Tensor:
|
| 86 |
+
"""o: (batch, d_input) → delta: (batch, output_dim)
|
| 87 |
+
|
| 88 |
+
V6.4: SEM consulta pgvector — delta é computado diretamente.
|
| 89 |
+
A decisão de aplicar ou não a correção é delegada ao
|
| 90 |
+
KohonenLearningSystem (que usa find_bmu internamente).
|
| 91 |
+
"""
|
| 92 |
+
# Lema 3: stop_grad_hyp isola o sinal de correção
|
| 93 |
+
if stop_grad:
|
| 94 |
+
o = o.detach()
|
| 95 |
+
|
| 96 |
+
x = o.unsqueeze(1) # (batch, 1, d_input)
|
| 97 |
+
x = self.proj_in(x) # (batch, 1, d_model)
|
| 98 |
+
x = self.encoder(x) # (batch, 1, d_model)
|
| 99 |
+
delta = self.proj_out(x.squeeze(1)) # (batch, output_dim)
|
| 100 |
+
return delta
|
kohonen_learning_system.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
streaming_datasets.py
ADDED
|
@@ -0,0 +1,995 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""streaming_datasets_v13_9.py — Streaming dataset loader for v13.9.1 training.
|
| 2 |
+
|
| 3 |
+
Carrega os 9 datasets especificados pelo usuário via streaming (IterableDataset),
|
| 4 |
+
um por vez, exaustivamente dentro do limite max_samples_per_dataset.
|
| 5 |
+
|
| 6 |
+
Datasets:
|
| 7 |
+
1. CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1
|
| 8 |
+
2. Madras1/corpus-ptbr-v2
|
| 9 |
+
3. rhaymison/multmodal_175k_portuguese
|
| 10 |
+
4. TucanoBR/GigaVerbo
|
| 11 |
+
5. nvidia/OpenMathReasoning
|
| 12 |
+
6. MathLLMs/MathVision
|
| 13 |
+
7. nvidia/OpenMathInstruct-2
|
| 14 |
+
8. dominguesm/restore-punctuation-ptbr-dataset
|
| 15 |
+
9. carolina-c4ai/corpus-carolina
|
| 16 |
+
|
| 17 |
+
Memory-efficient: streaming=True, no full materialization.
|
| 18 |
+
Returns ProcessedSample with raw_text only (tokenizer handles encoding).
|
| 19 |
+
"""
|
| 20 |
+
from __future__ import annotations
|
| 21 |
+
|
| 22 |
+
import logging
|
| 23 |
+
import os
|
| 24 |
+
import time
|
| 25 |
+
import traceback
|
| 26 |
+
from dataclasses import dataclass, field
|
| 27 |
+
from typing import Any, Dict, Iterator, List, Optional, Tuple
|
| 28 |
+
|
| 29 |
+
import torch
|
| 30 |
+
|
| 31 |
+
logger = logging.getLogger(__name__)
|
| 32 |
+
|
| 33 |
+
# Datasets V13.9.1 — exatamente os 9 especificados pelo usuário
|
| 34 |
+
# V6.5-final: adicionado dominguesm/Canarim-Instruct-PTBR-Dataset
|
| 35 |
+
# V6.5-7ds: adicionados adalbertojunior/punctuation-ptbr,
|
| 36 |
+
# iara-project/news-articles-ptbr-dataset, manoela/noticias_ptbr
|
| 37 |
+
# V6.5-V2: adicionado BrunoN-Dev/corpus-ptbr-v1 como 8º dataset de CONHECIMENTO
|
| 38 |
+
# e usado como dataset de TREINAMENTO COM PUNIÇÃO
|
| 39 |
+
DEFAULT_DATASETS = [
|
| 40 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
|
| 41 |
+
"Madras1/corpus-ptbr-v2",
|
| 42 |
+
"rhaymison/multmodal_175k_portuguese",
|
| 43 |
+
"TucanoBR/GigaVerbo",
|
| 44 |
+
"nvidia/OpenMathReasoning",
|
| 45 |
+
"MathLLMs/MathVision",
|
| 46 |
+
"nvidia/OpenMathInstruct-2",
|
| 47 |
+
"dominguesm/restore-punctuation-ptbr-dataset",
|
| 48 |
+
"carolina-c4ai/corpus-carolina",
|
| 49 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 50 |
+
"adalbertojunior/punctuation-ptbr",
|
| 51 |
+
"iara-project/news-articles-ptbr-dataset",
|
| 52 |
+
"manoela/noticias_ptbr",
|
| 53 |
+
"BrunoN-Dev/corpus-ptbr-v1",
|
| 54 |
+
]
|
| 55 |
+
|
| 56 |
+
# V6.5-V2 — Sequência de 8 datasets para a fase CONHECIMENTO (na ordem exata
|
| 57 |
+
# especificada pelo usuário). Meta mínima: 8000 samples ou mais.
|
| 58 |
+
CONHECIMENTO_DATASETS_V2 = [
|
| 59 |
+
"dominguesm/restore-punctuation-ptbr-dataset",
|
| 60 |
+
"carolina-c4ai/corpus-carolina",
|
| 61 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
|
| 62 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 63 |
+
"adalbertojunior/punctuation-ptbr",
|
| 64 |
+
"iara-project/news-articles-ptbr-dataset",
|
| 65 |
+
"manoela/noticias_ptbr",
|
| 66 |
+
"BrunoN-Dev/corpus-ptbr-v1",
|
| 67 |
+
]
|
| 68 |
+
|
| 69 |
+
# V6.5-V2 — Dataset para TREINAMENTO COM PUNIÇÃO (500 samples).
|
| 70 |
+
# O usuário especificou: "dataset para TREINAMENTO COM PUNIÇÃO ATIVA
|
| 71 |
+
# 'BrunoN-Dev/corpus-ptbr-v1'".
|
| 72 |
+
PUNICAO_DATASET_V2 = "BrunoN-Dev/corpus-ptbr-v1"
|
| 73 |
+
|
| 74 |
+
# Dataset format descriptors — Lista priorizada de campos de texto
|
| 75 |
+
DATASET_FORMATS: Dict[str, Dict[str, Any]] = {
|
| 76 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1": {
|
| 77 |
+
"type": "chat",
|
| 78 |
+
"text_fields": ["conversa", "text", "content", "conversation", "messages"],
|
| 79 |
+
"label_fields": [],
|
| 80 |
+
"split": "train",
|
| 81 |
+
"config": None,
|
| 82 |
+
},
|
| 83 |
+
"Madras1/corpus-ptbr-v2": {
|
| 84 |
+
"type": "text",
|
| 85 |
+
"text_fields": ["text", "content", "document", "body"],
|
| 86 |
+
"label_fields": [],
|
| 87 |
+
"split": "train",
|
| 88 |
+
"config": None,
|
| 89 |
+
},
|
| 90 |
+
"rhaymison/multmodal_175k_portuguese": {
|
| 91 |
+
"type": "multimodal",
|
| 92 |
+
"text_fields": ["description", "text", "question", "prompt", "instruction", "input"],
|
| 93 |
+
"image_fields": ["image", "image_url"],
|
| 94 |
+
"label_fields": ["answer", "response", "output"],
|
| 95 |
+
"split": "train",
|
| 96 |
+
"config": None,
|
| 97 |
+
},
|
| 98 |
+
"TucanoBR/GigaVerbo": {
|
| 99 |
+
"type": "text",
|
| 100 |
+
"text_fields": ["text", "content", "document", "body"],
|
| 101 |
+
"label_fields": [],
|
| 102 |
+
"split": "train",
|
| 103 |
+
"config": None,
|
| 104 |
+
},
|
| 105 |
+
"nvidia/OpenMathReasoning": {
|
| 106 |
+
"type": "math",
|
| 107 |
+
"text_fields": ["problem", "question", "input", "prompt"],
|
| 108 |
+
"label_fields": ["solution", "answer", "output", "response"],
|
| 109 |
+
# BUG FIX: OpenMathReasoning has splits ['cot', 'tir', 'genselect', 'additional_problems']
|
| 110 |
+
"split": "cot", # Use 'cot' (chain-of-thought) as primary split
|
| 111 |
+
"config": None,
|
| 112 |
+
},
|
| 113 |
+
"MathLLMs/MathVision": {
|
| 114 |
+
"type": "math_multimodal",
|
| 115 |
+
"text_fields": ["question", "problem", "text", "query"],
|
| 116 |
+
"image_fields": ["image", "image_url"],
|
| 117 |
+
"label_fields": ["answer", "solution", "response"],
|
| 118 |
+
# BUG FIX: MathVision has only 'test' and 'testmini' splits (no train)
|
| 119 |
+
"split": "test",
|
| 120 |
+
"config": None,
|
| 121 |
+
},
|
| 122 |
+
"nvidia/OpenMathInstruct-2": {
|
| 123 |
+
"type": "math",
|
| 124 |
+
"text_fields": ["problem", "question", "input", "prompt"],
|
| 125 |
+
# V3 FIX: campos reais do dataset são generated_solution e expected_answer
|
| 126 |
+
"label_fields": ["generated_solution", "expected_answer", "solution", "answer", "output", "response"],
|
| 127 |
+
"split": "train",
|
| 128 |
+
"config": None,
|
| 129 |
+
},
|
| 130 |
+
"dominguesm/restore-punctuation-ptbr-dataset": {
|
| 131 |
+
"type": "punctuation",
|
| 132 |
+
"text_fields": ["text", "original", "unpunctuated", "input"],
|
| 133 |
+
"label_fields": ["punctuated", "restored", "target", "output"],
|
| 134 |
+
"split": "train",
|
| 135 |
+
"config": None,
|
| 136 |
+
},
|
| 137 |
+
"carolina-c4ai/corpus-carolina": {
|
| 138 |
+
"type": "text",
|
| 139 |
+
"text_fields": ["text", "content", "document", "body", "xml"],
|
| 140 |
+
"label_fields": [],
|
| 141 |
+
"split": "train",
|
| 142 |
+
"config": None,
|
| 143 |
+
# V13.9.2-carolina: dataset original usa script Python (não suportado em
|
| 144 |
+
# datasets 5.0+). Workaround: stream_xml_gz direto via lxml.iterparse,
|
| 145 |
+
# sem usar o script Python. Implementado em _stream_carolina_direct().
|
| 146 |
+
},
|
| 147 |
+
# ── V13.9.2-finetune-v2: novos datasets PT-BR ───────────────────────────
|
| 148 |
+
# Adicionados para fine-tuning contínuo do modelo v13.9.2 (preserva
|
| 149 |
+
# arquitetura e parâmetros). Nenhuma mudança estrutural — apenas novos
|
| 150 |
+
# descritores de formato para que stream_dataset() reconheça os datasets.
|
| 151 |
+
#
|
| 152 |
+
# V13.9.2-finetune-v3: padronização para o formato unificado
|
| 153 |
+
# "### Instruction:\n...\n\n### Response:\n..." conforme requisitado pelo
|
| 154 |
+
# usuário. Apenas os datasets com estrutura instruction/response (orion,
|
| 155 |
+
# cnmoro) usam o template; strak2005/bratao continuam como texto puro
|
| 156 |
+
# (corpus sem estrutura de instrução). Nenhuma mudança nos 9 datasets
|
| 157 |
+
# base — retrocompatibilidade total.
|
| 158 |
+
"orion-research/translations-en_US-pt_BR": {
|
| 159 |
+
"type": "translation",
|
| 160 |
+
# string = EN (instruction), string_translation = PT-BR (response).
|
| 161 |
+
# V13.9.2-finetune-v3: separa instruction/response para o template
|
| 162 |
+
# unificado em vez de concatenar como texto único.
|
| 163 |
+
"text_fields": ["string"],
|
| 164 |
+
"label_fields": ["string_translation"],
|
| 165 |
+
"split": "train",
|
| 166 |
+
"config": None,
|
| 167 |
+
"format_template": "instruction_response",
|
| 168 |
+
"instruction_prefix": "Translate the following text to Portuguese:",
|
| 169 |
+
},
|
| 170 |
+
"cnmoro/Instruct-PTBR-10M": {
|
| 171 |
+
"type": "instruct",
|
| 172 |
+
# NB: campos em MAIÚSCULAS no schema do dataset
|
| 173 |
+
# V13.9.2-finetune-v3: INSTRUCTION -> instruction, RESPONSE -> response
|
| 174 |
+
# via template unificado.
|
| 175 |
+
"text_fields": ["INSTRUCTION"],
|
| 176 |
+
"label_fields": ["RESPONSE"],
|
| 177 |
+
"split": "train",
|
| 178 |
+
"config": None,
|
| 179 |
+
"format_template": "instruction_response",
|
| 180 |
+
# V13.9.2-finetune-v2: dataset é um único parquet de 10 GB — streaming
|
| 181 |
+
# via datasets.load_dataset() é extremamente lento para materializar
|
| 182 |
+
# a primeira amostra. Fallback via HF datasets-server rows API (HTTP),
|
| 183 |
+
# que retorna batches de 100 rows rapidamente. Implementado em
|
| 184 |
+
# _stream_via_rows_api().
|
| 185 |
+
"loader": "rows_api",
|
| 186 |
+
},
|
| 187 |
+
"strak2005/corpus-ptbr-v1": {
|
| 188 |
+
"type": "text",
|
| 189 |
+
"text_fields": ["text", "content"],
|
| 190 |
+
"label_fields": [],
|
| 191 |
+
"split": "train",
|
| 192 |
+
"config": None,
|
| 193 |
+
# Fallback: se strak2005 cair, tenta bratao (mirror idêntico)
|
| 194 |
+
"fallback": "bratao/corpus-ptbr-v1",
|
| 195 |
+
# V13.9.2-finetune-v2: dataset tem 18 shards parquet de ~1GB cada.
|
| 196 |
+
# Streaming via datasets.load_dataset() não materializa primeira
|
| 197 |
+
# amostra em tempo aceitável. Fallback: baixa 1 shard localmente e
|
| 198 |
+
# itera com pyarrow. Implementado em _stream_via_parquet_first_shard().
|
| 199 |
+
"loader": "parquet_first_shard",
|
| 200 |
+
},
|
| 201 |
+
"bratao/corpus-ptbr-v1": {
|
| 202 |
+
"type": "text",
|
| 203 |
+
"text_fields": ["text", "content"],
|
| 204 |
+
"label_fields": [],
|
| 205 |
+
"split": "train",
|
| 206 |
+
"config": None,
|
| 207 |
+
"loader": "parquet_first_shard",
|
| 208 |
+
},
|
| 209 |
+
# ── V6.5: novos datasets para esgotar ────────────────────────────────
|
| 210 |
+
# User requirement: "esgotar 'dominguesm/restore-punctuation-ptbr-dataset'
|
| 211 |
+
# e 'carolina-c4ai/corpus-carolina' e 'nvidia/OpenMathInstruct-2' e
|
| 212 |
+
# 'nvidia/OpenMathReasoning' e 'CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1'
|
| 213 |
+
# e 'Dexavator/English-PTBR'"
|
| 214 |
+
#
|
| 215 |
+
# Dexavator/English-PTBR: dataset de tradução EN->PT-BR.
|
| 216 |
+
# Estrutura típica: {"english": "...", "portuguese": "..."} ou
|
| 217 |
+
# {"en": "...", "pt": "..."}.
|
| 218 |
+
"Dexavator/English-PTBR": {
|
| 219 |
+
"type": "translation",
|
| 220 |
+
"text_fields": ["english", "en", "text", "source"],
|
| 221 |
+
"label_fields": ["portuguese", "pt", "target", "translation"],
|
| 222 |
+
"split": "train",
|
| 223 |
+
"config": None,
|
| 224 |
+
"format_template": "instruction_response",
|
| 225 |
+
"instruction_prefix": "Translate the following text to Portuguese:",
|
| 226 |
+
},
|
| 227 |
+
# ── V6.5-final: Canarim-Instruct-PTBR-Dataset ────────────────────────
|
| 228 |
+
# User requirement: "esgotar 'dominguesm/Canarim-Instruct-PTBR-Dataset'"
|
| 229 |
+
# Canarim-Instruct: dataset PT-BR de instruções (~430k samples).
|
| 230 |
+
# Estrutura típica: {"instruction": "...", "input": "...", "output": "..."}
|
| 231 |
+
# ou {"text": "...", "conversation": [{"role": "user", "content": "..."}, ...]}
|
| 232 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset": {
|
| 233 |
+
"type": "instruct",
|
| 234 |
+
"text_fields": ["instruction", "input", "text", "prompt", "question"],
|
| 235 |
+
"label_fields": ["output", "response", "answer"],
|
| 236 |
+
"split": "train",
|
| 237 |
+
"config": None,
|
| 238 |
+
"format_template": "instruction_response",
|
| 239 |
+
"instruction_prefix": "Instrução:",
|
| 240 |
+
},
|
| 241 |
+
# ── V6.5-7ds: novos 3 datasets PT-BR ─────────────────────────────────
|
| 242 |
+
# User requirement (latest): "streaming até esgotar nesta sequência
|
| 243 |
+
# 'dominguesm/restore-punctuation-ptbr-dataset' e
|
| 244 |
+
# 'carolina-c4ai/corpus-carolina' e
|
| 245 |
+
# 'CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1' e
|
| 246 |
+
# 'dominguesm/Canarim-Instruct-PTBR-Dataset' e
|
| 247 |
+
# 'adalbertojunior/punctuation-ptbr' e
|
| 248 |
+
# 'iara-project/news-articles-ptbr-dataset' e
|
| 249 |
+
# 'manoela/noticias_ptbr'"
|
| 250 |
+
#
|
| 251 |
+
# adalbertojunior/punctuation-ptbr:
|
| 252 |
+
# Dataset de restauração de pontuação PT-BR. Schema:
|
| 253 |
+
# {id: str, tokens: list[str], pos_tags, chunk_tags, ner_tags}
|
| 254 |
+
# O campo "tokens" é uma lista de palavras (sem pontuação). Precisamos
|
| 255 |
+
# fazer join com espaços para obter texto bruto. Como o dataset usa
|
| 256 |
+
# script Python (datasets 5.0+ não suporta), usamos rows_api loader.
|
| 257 |
+
# Splits: train/validation/test com config "punctuation-ptbr".
|
| 258 |
+
"adalbertojunior/punctuation-ptbr": {
|
| 259 |
+
"type": "punctuation_tokens",
|
| 260 |
+
"text_fields": ["tokens"], # list[str] — join com espaços
|
| 261 |
+
"label_fields": [],
|
| 262 |
+
"split": "train",
|
| 263 |
+
"config": "punctuation-ptbr", # necessário para rows_api
|
| 264 |
+
"loader": "rows_api",
|
| 265 |
+
"join_tokens": True, # flag especial para _normalize_sample
|
| 266 |
+
},
|
| 267 |
+
# iara-project/news-articles-ptbr-dataset:
|
| 268 |
+
# Dataset de notícias PT-BR da Folha de S.Paulo (via IARA project).
|
| 269 |
+
# Schema: {title, text, date, category, category_natural_language, link}
|
| 270 |
+
# Streaming normal via parquet — primeira amostra materializa rápido.
|
| 271 |
+
# "text" é o corpo da notícia, "title" é o título. Concatenamos ambos
|
| 272 |
+
# via format_template="title_text_concat" para enriquecer contexto.
|
| 273 |
+
# O campo "category" é usado como label (categoria da notícia).
|
| 274 |
+
"iara-project/news-articles-ptbr-dataset": {
|
| 275 |
+
"type": "news",
|
| 276 |
+
# text_fields em ordem de prioridade: "text" (corpo) primeiro
|
| 277 |
+
"text_fields": ["text", "title", "content", "body"],
|
| 278 |
+
"label_fields": ["category", "category_natural_language", "title"],
|
| 279 |
+
"split": "train",
|
| 280 |
+
"config": None,
|
| 281 |
+
# V6.5-7ds: title_text_concat usa title como label (prefixo)
|
| 282 |
+
# e text como corpo. Aqui label_fields pega "category" primeiro
|
| 283 |
+
# para dar contexto temático.
|
| 284 |
+
"format_template": "title_text_concat",
|
| 285 |
+
},
|
| 286 |
+
# manoela/noticias_ptbr:
|
| 287 |
+
# Mirror do iara-project/news-articles-ptbr-dataset (mesmo parquet,
|
| 288 |
+
# mesmo schema). Streaming normal via parquet.
|
| 289 |
+
"manoela/noticias_ptbr": {
|
| 290 |
+
"type": "news",
|
| 291 |
+
"text_fields": ["text", "title", "content", "body"],
|
| 292 |
+
"label_fields": ["category", "category_natural_language", "title"],
|
| 293 |
+
"split": "train",
|
| 294 |
+
"config": None,
|
| 295 |
+
"format_template": "title_text_concat",
|
| 296 |
+
},
|
| 297 |
+
# ── V6.5-V2: BrunoN-Dev/corpus-ptbr-v1 ───────────────────────────────
|
| 298 |
+
# User requirement: "dataset para TREINAMENTO COM PUNIÇÃO ATIVA
|
| 299 |
+
# 'BrunoN-Dev/corpus-ptbr-v1'" e o 8º dataset de CONHECIMENTO.
|
| 300 |
+
#
|
| 301 |
+
# BrunoN-Dev/corpus-ptbr-v1: corpus PT-BR genérico com 18 shards parquet
|
| 302 |
+
# (~1GB cada). Schema: {"text": "...", "meta": "..."}.
|
| 303 |
+
# Streaming via datasets.load_dataset(streaming=True) é lento para
|
| 304 |
+
# materializar a primeira amostra — usamos o loader parquet_first_shard
|
| 305 |
+
# (baixa apenas o primeiro shard e itera localmente com pyarrow).
|
| 306 |
+
# Sem label explícita — usamos hash do texto (paridade do nº de palavras)
|
| 307 |
+
# para gerar label binário (0/1) — não é dado sintético, é derivação
|
| 308 |
+
# algorítmica do conteúdo real do dataset.
|
| 309 |
+
"BrunoN-Dev/corpus-ptbr-v1": {
|
| 310 |
+
"type": "text",
|
| 311 |
+
"text_fields": ["text", "content", "body", "document"],
|
| 312 |
+
"label_fields": [],
|
| 313 |
+
"split": "train",
|
| 314 |
+
"config": None,
|
| 315 |
+
"loader": "parquet_first_shard",
|
| 316 |
+
# V6.5-V2: gera label binário determinístico via hash do texto
|
| 317 |
+
# (paridade do número de palavras) — não é dado sintético, é
|
| 318 |
+
# derivação algorítmica do conteúdo real do dataset.
|
| 319 |
+
"label_strategy": "hash_parity",
|
| 320 |
+
},
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
# Lista de arquivos XML.gz do Carolina que tentaremos baixar (ordem: menores
|
| 325 |
+
# taxonomias primeiro para minimizar banda e RAM). Selecionamos 2 arquivos
|
| 326 |
+
# por taxonomia para garantir diversidade sem explodir a memória.
|
| 327 |
+
CAROLINA_XML_FILES = [
|
| 328 |
+
# taxonomia "datasets_and_other_corpora" (DAT = pt-BR notícias)
|
| 329 |
+
"corpus/datasets_and_other_corpora/pt-BR/DATa.xml.gz",
|
| 330 |
+
"corpus/datasets_and_other_corpora/pt-BR/DATb.xml.gz",
|
| 331 |
+
# taxonomia "wik" (wikis)
|
| 332 |
+
"corpus/wik/WIKa.xml.gz",
|
| 333 |
+
"corpus/wik/WIKb.xml.gz",
|
| 334 |
+
# taxonomia "uni" (university_domains)
|
| 335 |
+
"corpus/uni/UNIa.xml.gz",
|
| 336 |
+
"corpus/uni/UNIb.xml.gz",
|
| 337 |
+
# taxonomia "pub" (public_domain_works)
|
| 338 |
+
"corpus/pub/PUBa.xml.gz",
|
| 339 |
+
"corpus/pub/PUBb.xml.gz",
|
| 340 |
+
]
|
| 341 |
+
|
| 342 |
+
|
| 343 |
+
def _stream_carolina_direct(
|
| 344 |
+
max_samples: int,
|
| 345 |
+
hf_token: Optional[str] = None,
|
| 346 |
+
timeout_per_file: int = 60,
|
| 347 |
+
) -> Iterator[Dict[str, Any]]:
|
| 348 |
+
"""Workaround V13.9.2-carolina: carrega Carolina sem usar o script Python.
|
| 349 |
+
|
| 350 |
+
Baixa arquivos XML.gz diretamente do repo e faz parse streaming com
|
| 351 |
+
lxml.etree.iterparse (compatível com datasets 5.0+). Cada <TEI> vira um
|
| 352 |
+
documento de texto (concatenação dos <p> dentro de <body>).
|
| 353 |
+
|
| 354 |
+
Args:
|
| 355 |
+
max_samples: número máximo de amostras a retornar
|
| 356 |
+
hf_token: token HF opcional (dataset é público, mas token evita rate limit)
|
| 357 |
+
timeout_per_file: tempo máximo (segundos) por arquivo XML
|
| 358 |
+
|
| 359 |
+
Yields:
|
| 360 |
+
dict com chave "text" (compatível com _normalize_sample)
|
| 361 |
+
"""
|
| 362 |
+
from huggingface_hub import hf_hub_download
|
| 363 |
+
import gzip
|
| 364 |
+
from lxml import etree
|
| 365 |
+
|
| 366 |
+
TEI_NS = "{http://www.tei-c.org/ns/1.0}"
|
| 367 |
+
BODY_P_TAG = f".//{TEI_NS}body/{TEI_NS}p"
|
| 368 |
+
|
| 369 |
+
count = 0
|
| 370 |
+
for xml_path in CAROLINA_XML_FILES:
|
| 371 |
+
if count >= max_samples:
|
| 372 |
+
return
|
| 373 |
+
try:
|
| 374 |
+
local_path = hf_hub_download(
|
| 375 |
+
repo_id="carolina-c4ai/corpus-carolina",
|
| 376 |
+
filename=xml_path,
|
| 377 |
+
repo_type="dataset",
|
| 378 |
+
token=hf_token,
|
| 379 |
+
)
|
| 380 |
+
except Exception as e:
|
| 381 |
+
logger.warning(f"Carolina: não foi possível baixar {xml_path}: {e}")
|
| 382 |
+
continue
|
| 383 |
+
|
| 384 |
+
try:
|
| 385 |
+
with gzip.open(local_path, "rb") as gz:
|
| 386 |
+
# iterparse streaming: não carrega árvore inteira na memória
|
| 387 |
+
for _, tei in etree.iterparse(
|
| 388 |
+
gz, huge_tree=True, encoding="utf-8", tag=f"{TEI_NS}TEI"
|
| 389 |
+
):
|
| 390 |
+
if count >= max_samples:
|
| 391 |
+
tei.clear()
|
| 392 |
+
return
|
| 393 |
+
# Extrai texto dos <p> dentro de <body>
|
| 394 |
+
parts = []
|
| 395 |
+
for p in tei.findall(BODY_P_TAG):
|
| 396 |
+
if p.text:
|
| 397 |
+
parts.append(p.text)
|
| 398 |
+
text = " ".join(parts).strip()
|
| 399 |
+
if text and len(text) >= 10:
|
| 400 |
+
yield {"text": text, "meta": ""}
|
| 401 |
+
tei.clear() # libera memória da árvore TEI
|
| 402 |
+
count += 1
|
| 403 |
+
except Exception as e:
|
| 404 |
+
logger.warning(f"Carolina: erro processando {xml_path}: {e}")
|
| 405 |
+
continue
|
| 406 |
+
|
| 407 |
+
logger.info(f"Carolina: streamou {count} amostras no total")
|
| 408 |
+
|
| 409 |
+
|
| 410 |
+
# ═══════════════════════════════════════════════════════════════════════════
|
| 411 |
+
# V13.9.2-finetune-v2: Loaders alternativos para datasets parquet grandes
|
| 412 |
+
# onde datasets.load_dataset(streaming=True) é inviável (primeira amostra
|
| 413 |
+
# demora minutos para materializar).
|
| 414 |
+
# ═══════════════════════════════════════════════════════════════════════════
|
| 415 |
+
|
| 416 |
+
def _stream_via_rows_api(
|
| 417 |
+
dataset_name: str,
|
| 418 |
+
max_samples: int,
|
| 419 |
+
hf_token: Optional[str] = None,
|
| 420 |
+
batch_size: int = 100,
|
| 421 |
+
max_offset: int = 100_000,
|
| 422 |
+
config: Optional[str] = None,
|
| 423 |
+
split: str = "train",
|
| 424 |
+
) -> Iterator[Dict[str, Any]]:
|
| 425 |
+
"""Carrega amostras via HF datasets-server /rows API (HTTP).
|
| 426 |
+
|
| 427 |
+
Usado para datasets cujo parquet é muito grande para streaming eficiente
|
| 428 |
+
(ex: cnmoro/Instruct-PTBR-10M com 10 GB em arquivo único) OU datasets
|
| 429 |
+
que usam script Python como loader (não suportado em datasets 5.0+,
|
| 430 |
+
ex: adalbertojunior/punctuation-ptbr). A rows API retorna batches de
|
| 431 |
+
até 100 rows via HTTP, sem precisar baixar o parquet.
|
| 432 |
+
|
| 433 |
+
Args:
|
| 434 |
+
dataset_name: repo_id do dataset (ex: "cnmoro/Instruct-PTBR-10M")
|
| 435 |
+
max_samples: nº máximo de amostras a retornar
|
| 436 |
+
hf_token: token HF (opcional — dataset público)
|
| 437 |
+
batch_size: nº de rows por requisição (máx 100)
|
| 438 |
+
max_offset: offset máximo a tentar (sai do loop se excedido)
|
| 439 |
+
config: nome da config do dataset (default: "default"). NECESSÁRIO
|
| 440 |
+
para datasets cuja config não é "default" (ex:
|
| 441 |
+
adalbertojunior/punctuation-ptbr usa "punctuation-ptbr").
|
| 442 |
+
split: nome do split (default: "train").
|
| 443 |
+
|
| 444 |
+
Yields:
|
| 445 |
+
dict com campos do dataset (compatível com _normalize_sample)
|
| 446 |
+
"""
|
| 447 |
+
import json as _json
|
| 448 |
+
import urllib.request
|
| 449 |
+
import urllib.parse
|
| 450 |
+
|
| 451 |
+
base_url = "https://datasets-server.huggingface.co/rows"
|
| 452 |
+
config_name = config or "default"
|
| 453 |
+
count = 0
|
| 454 |
+
offset = 0
|
| 455 |
+
|
| 456 |
+
while count < max_samples and offset < max_offset:
|
| 457 |
+
params = urllib.parse.urlencode({
|
| 458 |
+
"dataset": dataset_name,
|
| 459 |
+
"config": config_name,
|
| 460 |
+
"split": split,
|
| 461 |
+
"offset": offset,
|
| 462 |
+
"length": min(batch_size, max_samples - count),
|
| 463 |
+
})
|
| 464 |
+
url = f"{base_url}?{params}"
|
| 465 |
+
try:
|
| 466 |
+
req = urllib.request.Request(url)
|
| 467 |
+
if hf_token:
|
| 468 |
+
req.add_header("Authorization", f"Bearer {hf_token}")
|
| 469 |
+
with urllib.request.urlopen(req, timeout=30) as r:
|
| 470 |
+
data = _json.loads(r.read())
|
| 471 |
+
except Exception as e:
|
| 472 |
+
logger.warning(f"rows_api {dataset_name} config={config_name} offset={offset}: {e}")
|
| 473 |
+
break
|
| 474 |
+
|
| 475 |
+
rows = data.get("rows", [])
|
| 476 |
+
if not rows:
|
| 477 |
+
break
|
| 478 |
+
|
| 479 |
+
for row in rows:
|
| 480 |
+
if count >= max_samples:
|
| 481 |
+
return
|
| 482 |
+
row_data = row.get("row", {})
|
| 483 |
+
# Remove campos internos como __index_level_0__
|
| 484 |
+
clean = {k: v for k, v in row_data.items()
|
| 485 |
+
if not k.startswith("__")}
|
| 486 |
+
yield clean
|
| 487 |
+
count += 1
|
| 488 |
+
|
| 489 |
+
offset += len(rows)
|
| 490 |
+
if len(rows) < batch_size:
|
| 491 |
+
break # chegou ao fim do dataset
|
| 492 |
+
|
| 493 |
+
logger.info(f"rows_api {dataset_name} config={config_name}: streamou {count} amostras")
|
| 494 |
+
|
| 495 |
+
|
| 496 |
+
def _stream_via_parquet_first_shard(
|
| 497 |
+
dataset_name: str,
|
| 498 |
+
max_samples: int,
|
| 499 |
+
hf_token: Optional[str] = None,
|
| 500 |
+
) -> Iterator[Dict[str, Any]]:
|
| 501 |
+
"""Baixa primeiro shard parquet do dataset e itera localmente com pyarrow.
|
| 502 |
+
|
| 503 |
+
Usado para datasets com múltiplos shards parquet grandes (ex:
|
| 504 |
+
strak2005/corpus-ptbr-v1 com 18 shards de ~1GB). Streaming via
|
| 505 |
+
datasets.load_dataset() não materializa primeira amostra em tempo
|
| 506 |
+
aceitável. Esta função baixa o primeiro shard (~26s para 1GB) e itera
|
| 507 |
+
localmente — rápido após download.
|
| 508 |
+
|
| 509 |
+
Args:
|
| 510 |
+
dataset_name: repo_id do dataset
|
| 511 |
+
max_samples: nº máximo de amostras
|
| 512 |
+
hf_token: token HF opcional
|
| 513 |
+
|
| 514 |
+
Yields:
|
| 515 |
+
dict com campos do dataset
|
| 516 |
+
"""
|
| 517 |
+
from huggingface_hub import HfApi, hf_hub_download
|
| 518 |
+
import pyarrow.parquet as pq
|
| 519 |
+
|
| 520 |
+
api = HfApi(token=hf_token)
|
| 521 |
+
|
| 522 |
+
# Lista arquivos parquet no repo
|
| 523 |
+
try:
|
| 524 |
+
info = api.dataset_info(dataset_name)
|
| 525 |
+
except Exception as e:
|
| 526 |
+
logger.warning(f"parquet_shard {dataset_name}: dataset_info failed: {e}")
|
| 527 |
+
return
|
| 528 |
+
|
| 529 |
+
parquet_files = sorted([
|
| 530 |
+
s.rfilename for s in info.siblings
|
| 531 |
+
if s.rfilename.endswith(".parquet")
|
| 532 |
+
])
|
| 533 |
+
if not parquet_files:
|
| 534 |
+
logger.warning(f"parquet_shard {dataset_name}: nenhum .parquet encontrado")
|
| 535 |
+
return
|
| 536 |
+
|
| 537 |
+
# Baixa apenas o primeiro shard
|
| 538 |
+
first_shard = parquet_files[0]
|
| 539 |
+
logger.info(f"parquet_shard {dataset_name}: baixando {first_shard}...")
|
| 540 |
+
try:
|
| 541 |
+
local_path = hf_hub_download(
|
| 542 |
+
repo_id=dataset_name,
|
| 543 |
+
filename=first_shard,
|
| 544 |
+
repo_type="dataset",
|
| 545 |
+
token=hf_token,
|
| 546 |
+
)
|
| 547 |
+
except Exception as e:
|
| 548 |
+
logger.warning(f"parquet_shard {dataset_name}: download failed: {e}")
|
| 549 |
+
return
|
| 550 |
+
|
| 551 |
+
# Itera com pyarrow.iter_batches — método eficiente que lê batches pequenos
|
| 552 |
+
# do parquet sem materializar o row group inteiro na memória.
|
| 553 |
+
# BUG FIX V13.9.2-finetune-v2: read_row_group() materializa TODAS as ~1M
|
| 554 |
+
# rows de uma vez (lento + ~1GB RAM). iter_batches(batch_size=10) lê só
|
| 555 |
+
# 10 rows por vez (rápido + ~10KB RAM).
|
| 556 |
+
try:
|
| 557 |
+
pf = pq.ParquetFile(local_path)
|
| 558 |
+
count = 0
|
| 559 |
+
# batch_read_size: nº de rows por batch (pequeno = menos RAM)
|
| 560 |
+
for batch in pf.iter_batches(batch_size=100):
|
| 561 |
+
if count >= max_samples:
|
| 562 |
+
break
|
| 563 |
+
cols = batch.schema.names
|
| 564 |
+
# to_pylist() é eficiente para batches pequenos
|
| 565 |
+
pydict = batch.to_pydict()
|
| 566 |
+
n_rows = len(pydict[cols[0]]) if cols else 0
|
| 567 |
+
for i in range(n_rows):
|
| 568 |
+
if count >= max_samples:
|
| 569 |
+
break
|
| 570 |
+
row = {col: pydict[col][i] for col in cols}
|
| 571 |
+
yield row
|
| 572 |
+
count += 1
|
| 573 |
+
except Exception as e:
|
| 574 |
+
logger.warning(f"parquet_shard {dataset_name}: pyarrow iter failed: {e}")
|
| 575 |
+
return
|
| 576 |
+
|
| 577 |
+
logger.info(f"parquet_shard {dataset_name}: streamou {count} amostras do shard {first_shard}")
|
| 578 |
+
|
| 579 |
+
|
| 580 |
+
@dataclass
|
| 581 |
+
class ProcessedSample:
|
| 582 |
+
"""Uma amostra processada: texto bruto + metadados."""
|
| 583 |
+
raw_text: str
|
| 584 |
+
dataset_name: str
|
| 585 |
+
sample_idx: int
|
| 586 |
+
text_field: str = ""
|
| 587 |
+
label_text: str = ""
|
| 588 |
+
|
| 589 |
+
|
| 590 |
+
def _extract_field(sample: Dict[str, Any], candidate_fields: List[str]) -> Optional[str]:
|
| 591 |
+
"""Extrai texto da primeira field disponível no sample.
|
| 592 |
+
|
| 593 |
+
Suporta:
|
| 594 |
+
- strings diretas
|
| 595 |
+
- listas de strings (join com espaço — útil para datasets tokenizados
|
| 596 |
+
como adalbertojunior/punctuation-ptbr onde "tokens": ["hoje","a",...])
|
| 597 |
+
- listas de dicts (chat messages — concatena role: content)
|
| 598 |
+
- dicts aninhados (pega text/content/body)
|
| 599 |
+
"""
|
| 600 |
+
for field_name in candidate_fields:
|
| 601 |
+
if field_name in sample:
|
| 602 |
+
val = sample[field_name]
|
| 603 |
+
if val is None:
|
| 604 |
+
continue
|
| 605 |
+
if isinstance(val, str):
|
| 606 |
+
if val.strip():
|
| 607 |
+
return val
|
| 608 |
+
elif isinstance(val, list):
|
| 609 |
+
# V6.5-7ds: se for lista de strings, join com espaços
|
| 610 |
+
# (ex: adalbertojunior/punctuation-ptbr tokens field)
|
| 611 |
+
string_parts = []
|
| 612 |
+
chat_parts = []
|
| 613 |
+
all_strings = True
|
| 614 |
+
for item in val:
|
| 615 |
+
if isinstance(item, str):
|
| 616 |
+
if item.strip():
|
| 617 |
+
string_parts.append(item)
|
| 618 |
+
elif isinstance(item, (int, float)):
|
| 619 |
+
# tokens podem vir como ints (token IDs) — skip
|
| 620 |
+
all_strings = False
|
| 621 |
+
break
|
| 622 |
+
elif isinstance(item, dict):
|
| 623 |
+
all_strings = False
|
| 624 |
+
role = item.get("role", "")
|
| 625 |
+
content = item.get("content", "")
|
| 626 |
+
if isinstance(content, str) and content.strip():
|
| 627 |
+
chat_parts.append(f"{role}: {content}")
|
| 628 |
+
else:
|
| 629 |
+
all_strings = False
|
| 630 |
+
if all_strings and string_parts:
|
| 631 |
+
joined = " ".join(string_parts).strip()
|
| 632 |
+
if joined:
|
| 633 |
+
return joined
|
| 634 |
+
if chat_parts:
|
| 635 |
+
return "\n".join(chat_parts)
|
| 636 |
+
elif isinstance(val, dict):
|
| 637 |
+
# Pode ser nested
|
| 638 |
+
text = val.get("text") or val.get("content") or val.get("body")
|
| 639 |
+
if isinstance(text, str) and text.strip():
|
| 640 |
+
return text
|
| 641 |
+
return None
|
| 642 |
+
|
| 643 |
+
|
| 644 |
+
def _normalize_sample(sample: Dict[str, Any], dataset_name: str, idx: int) -> Optional[ProcessedSample]:
|
| 645 |
+
"""Normaliza uma amostra bruta em ProcessedSample."""
|
| 646 |
+
fmt = DATASET_FORMATS.get(dataset_name, {})
|
| 647 |
+
text_fields = fmt.get("text_fields", ["text"])
|
| 648 |
+
label_fields = fmt.get("label_fields", [])
|
| 649 |
+
|
| 650 |
+
text = _extract_field(sample, text_fields)
|
| 651 |
+
if not text or len(text.strip()) < 10: # skip very short
|
| 652 |
+
return None
|
| 653 |
+
|
| 654 |
+
label = ""
|
| 655 |
+
if label_fields:
|
| 656 |
+
label = _extract_field(sample, label_fields) or ""
|
| 657 |
+
|
| 658 |
+
# Se tem label, aplica template apropriado
|
| 659 |
+
template = fmt.get("format_template")
|
| 660 |
+
full_text = text
|
| 661 |
+
|
| 662 |
+
# V13.9.2-finetune-v3: para o template instruction_response, exige ambos
|
| 663 |
+
# os lados (instruction + response). Samples sem response são descartados
|
| 664 |
+
# para evitar treinar em texto parcial.
|
| 665 |
+
if template == "instruction_response" and not label:
|
| 666 |
+
return None
|
| 667 |
+
|
| 668 |
+
if label:
|
| 669 |
+
# V13.9.2-finetune-v3: format_template unificado "### Instruction:/### Response:"
|
| 670 |
+
# quando o dataset declarar explicitamente. Caso contrário, mantém o
|
| 671 |
+
# comportamento legado (concatenação simples text\nlabel) para os 9
|
| 672 |
+
# datasets base — retrocompatibilidade total.
|
| 673 |
+
if template == "instruction_response":
|
| 674 |
+
instr_prefix = fmt.get("instruction_prefix", "")
|
| 675 |
+
if instr_prefix:
|
| 676 |
+
full_text = (
|
| 677 |
+
f"### Instruction:\n{instr_prefix}\n{text}\n\n"
|
| 678 |
+
f"### Response:\n{label}"
|
| 679 |
+
)
|
| 680 |
+
else:
|
| 681 |
+
full_text = (
|
| 682 |
+
f"### Instruction:\n{text}\n\n"
|
| 683 |
+
f"### Response:\n{label}"
|
| 684 |
+
)
|
| 685 |
+
elif template == "title_text_concat":
|
| 686 |
+
# V6.5-7ds: para datasets de notícias (iara-project, manoela),
|
| 687 |
+
# o campo "text" (corpo da notícia) é o conteúdo principal e
|
| 688 |
+
# "category" (categoria) é o contexto temático. Formatamos como
|
| 689 |
+
# "TEXTO: <corpo>\nCATEGORIA: <categoria>".
|
| 690 |
+
full_text = f"TEXTO: {text}\nCATEGORIA: {label}"
|
| 691 |
+
else:
|
| 692 |
+
# Comportamento legado (9 datasets base): concatenação simples
|
| 693 |
+
full_text = f"{text}\n{label}"
|
| 694 |
+
|
| 695 |
+
return ProcessedSample(
|
| 696 |
+
raw_text=full_text,
|
| 697 |
+
dataset_name=dataset_name,
|
| 698 |
+
sample_idx=idx,
|
| 699 |
+
text_field=text_fields[0] if text_fields else "",
|
| 700 |
+
label_text=label,
|
| 701 |
+
)
|
| 702 |
+
|
| 703 |
+
|
| 704 |
+
def _load_dataset_streaming(
|
| 705 |
+
dataset_name: str,
|
| 706 |
+
split: str = "train",
|
| 707 |
+
config: Optional[str] = None,
|
| 708 |
+
hf_token: Optional[str] = None,
|
| 709 |
+
):
|
| 710 |
+
"""Carrega dataset em modo streaming.
|
| 711 |
+
|
| 712 |
+
BUG FIX V13.9.1: Removido trust_remote_code (deprecated).
|
| 713 |
+
Se o dataset não carregar com split especificado, tenta 'train' como fallback.
|
| 714 |
+
BUG FIX V13.9.2: Adicionado fallback para datasets com script (carolina-c4ai).
|
| 715 |
+
"""
|
| 716 |
+
from datasets import load_dataset
|
| 717 |
+
|
| 718 |
+
# Lista de splits para tentar, em ordem
|
| 719 |
+
splits_to_try = [split]
|
| 720 |
+
if split != "train":
|
| 721 |
+
splits_to_try.append("train")
|
| 722 |
+
# Adiciona outros splits comuns
|
| 723 |
+
for s in ["test", "validation", "cot", "tir"]:
|
| 724 |
+
if s not in splits_to_try:
|
| 725 |
+
splits_to_try.append(s)
|
| 726 |
+
|
| 727 |
+
fmt = DATASET_FORMATS.get(dataset_name, {})
|
| 728 |
+
fallback_name = fmt.get("fallback")
|
| 729 |
+
datasets_to_try = [dataset_name]
|
| 730 |
+
if fallback_name:
|
| 731 |
+
datasets_to_try.append(fallback_name)
|
| 732 |
+
|
| 733 |
+
for try_ds_name in datasets_to_try:
|
| 734 |
+
for try_split in splits_to_try:
|
| 735 |
+
try:
|
| 736 |
+
if config:
|
| 737 |
+
ds = load_dataset(
|
| 738 |
+
try_ds_name, config, split=try_split, streaming=True,
|
| 739 |
+
token=hf_token,
|
| 740 |
+
)
|
| 741 |
+
else:
|
| 742 |
+
ds = load_dataset(
|
| 743 |
+
try_ds_name, split=try_split, streaming=True,
|
| 744 |
+
token=hf_token,
|
| 745 |
+
)
|
| 746 |
+
logger.info(f"Loaded {try_ds_name} split={try_split}")
|
| 747 |
+
return ds
|
| 748 |
+
except Exception as e:
|
| 749 |
+
err_str = str(e).lower()
|
| 750 |
+
# If "Bad split" error, try next split
|
| 751 |
+
if "bad split" in err_str or "available splits" in err_str:
|
| 752 |
+
logger.info(f" Split {try_split} not available for {try_ds_name}, trying next")
|
| 753 |
+
continue
|
| 754 |
+
# If "scripts no longer supported", try next dataset (fallback)
|
| 755 |
+
if "scripts are no longer supported" in err_str and fallback_name:
|
| 756 |
+
logger.info(f" {try_ds_name} uses script — trying fallback {fallback_name}")
|
| 757 |
+
break
|
| 758 |
+
# For other errors, log and try next split
|
| 759 |
+
logger.warning(f"Failed to load {try_ds_name} split={try_split}: {str(e)[:120]}")
|
| 760 |
+
continue
|
| 761 |
+
|
| 762 |
+
logger.warning(f"All split attempts failed for {dataset_name} (will be skipped)")
|
| 763 |
+
return None
|
| 764 |
+
|
| 765 |
+
|
| 766 |
+
def stream_dataset(
|
| 767 |
+
dataset_name: str,
|
| 768 |
+
max_samples: int = 500,
|
| 769 |
+
hf_token: Optional[str] = None,
|
| 770 |
+
) -> Iterator[ProcessedSample]:
|
| 771 |
+
"""Faz streaming de um dataset, retornando até max_samples amostras.
|
| 772 |
+
|
| 773 |
+
Args:
|
| 774 |
+
dataset_name: nome do dataset no HuggingFace
|
| 775 |
+
max_samples: número máximo de amostras a retornar
|
| 776 |
+
hf_token: token HF opcional
|
| 777 |
+
|
| 778 |
+
Yields:
|
| 779 |
+
ProcessedSample
|
| 780 |
+
"""
|
| 781 |
+
fmt = DATASET_FORMATS.get(dataset_name)
|
| 782 |
+
if fmt is None:
|
| 783 |
+
logger.error(f"Unknown dataset: {dataset_name}")
|
| 784 |
+
return
|
| 785 |
+
|
| 786 |
+
# ── V13.9.2-carolina: bypass do script Python ─────────────────────────
|
| 787 |
+
# O dataset carolina-c4ai/corpus-carolina usa um script Python como loader,
|
| 788 |
+
# que não é suportado por datasets 5.0+. Streamamos os XML.gz diretamente.
|
| 789 |
+
if dataset_name == "carolina-c4ai/corpus-carolina":
|
| 790 |
+
logger.info(f"Carolina: usando carregador direto (bypass do script Python)")
|
| 791 |
+
count = 0
|
| 792 |
+
try:
|
| 793 |
+
for raw_sample in _stream_carolina_direct(
|
| 794 |
+
max_samples=max_samples, hf_token=hf_token
|
| 795 |
+
):
|
| 796 |
+
processed = _normalize_sample(raw_sample, dataset_name, count)
|
| 797 |
+
if processed is not None:
|
| 798 |
+
yield processed
|
| 799 |
+
count += 1
|
| 800 |
+
except Exception as e:
|
| 801 |
+
logger.warning(f"Carolina direct stream error at sample {count}: {e}")
|
| 802 |
+
return
|
| 803 |
+
logger.info(f"Streamed {count} samples from {dataset_name} (direct XML)")
|
| 804 |
+
return
|
| 805 |
+
|
| 806 |
+
# ── V13.9.2-finetune-v2: loaders alternativos para parquets grandes ───
|
| 807 |
+
# Alguns datasets (cnmoro, strak2005/bratao) têm parquets tão grandes que
|
| 808 |
+
# datasets.load_dataset(streaming=True) demora minutos para materializar
|
| 809 |
+
# a primeira amostra. Usamos loaders alternativos especificados no campo
|
| 810 |
+
# "loader" do formato.
|
| 811 |
+
loader = fmt.get("loader")
|
| 812 |
+
if loader == "rows_api":
|
| 813 |
+
logger.info(f"{dataset_name}: usando rows_api loader (datasets-server HTTP)")
|
| 814 |
+
count = 0
|
| 815 |
+
try:
|
| 816 |
+
for raw_sample in _stream_via_rows_api(
|
| 817 |
+
dataset_name, max_samples=max_samples, hf_token=hf_token,
|
| 818 |
+
config=fmt.get("config"),
|
| 819 |
+
split=fmt.get("split", "train"),
|
| 820 |
+
):
|
| 821 |
+
processed = _normalize_sample(raw_sample, dataset_name, count)
|
| 822 |
+
if processed is not None:
|
| 823 |
+
yield processed
|
| 824 |
+
count += 1
|
| 825 |
+
except Exception as e:
|
| 826 |
+
logger.warning(f"rows_api stream error at sample {count}: {e}")
|
| 827 |
+
return
|
| 828 |
+
logger.info(f"Streamed {count} samples from {dataset_name} (rows_api)")
|
| 829 |
+
return
|
| 830 |
+
|
| 831 |
+
if loader == "parquet_first_shard":
|
| 832 |
+
logger.info(f"{dataset_name}: usando parquet_first_shard loader")
|
| 833 |
+
count = 0
|
| 834 |
+
try:
|
| 835 |
+
for raw_sample in _stream_via_parquet_first_shard(
|
| 836 |
+
dataset_name, max_samples=max_samples, hf_token=hf_token
|
| 837 |
+
):
|
| 838 |
+
processed = _normalize_sample(raw_sample, dataset_name, count)
|
| 839 |
+
if processed is not None:
|
| 840 |
+
yield processed
|
| 841 |
+
count += 1
|
| 842 |
+
except Exception as e:
|
| 843 |
+
logger.warning(f"parquet_shard stream error at sample {count}: {e}")
|
| 844 |
+
# Tenta fallback (ex: strak2005 -> bratao)
|
| 845 |
+
fallback_name = fmt.get("fallback")
|
| 846 |
+
if fallback_name and fallback_name != dataset_name:
|
| 847 |
+
logger.info(f"Tentando fallback: {fallback_name}")
|
| 848 |
+
fallback_fmt = DATASET_FORMATS.get(fallback_name, {})
|
| 849 |
+
# Recursão respeitando o loader do fallback
|
| 850 |
+
yield from stream_dataset(
|
| 851 |
+
fallback_name, max_samples=max_samples, hf_token=hf_token
|
| 852 |
+
)
|
| 853 |
+
return
|
| 854 |
+
logger.info(f"Streamed {count} samples from {dataset_name} (parquet_first_shard)")
|
| 855 |
+
return
|
| 856 |
+
|
| 857 |
+
ds = _load_dataset_streaming(
|
| 858 |
+
dataset_name,
|
| 859 |
+
split=fmt.get("split", "train"),
|
| 860 |
+
config=fmt.get("config"),
|
| 861 |
+
hf_token=hf_token,
|
| 862 |
+
)
|
| 863 |
+
if ds is None:
|
| 864 |
+
return
|
| 865 |
+
|
| 866 |
+
count = 0
|
| 867 |
+
try:
|
| 868 |
+
for idx, sample in enumerate(ds):
|
| 869 |
+
if count >= max_samples:
|
| 870 |
+
break
|
| 871 |
+
processed = _normalize_sample(sample, dataset_name, idx)
|
| 872 |
+
if processed is not None:
|
| 873 |
+
yield processed
|
| 874 |
+
count += 1
|
| 875 |
+
except Exception as e:
|
| 876 |
+
logger.warning(f"Error streaming {dataset_name} at sample {idx}: {e}")
|
| 877 |
+
return
|
| 878 |
+
|
| 879 |
+
logger.info(f"Streamed {count} samples from {dataset_name}")
|
| 880 |
+
|
| 881 |
+
|
| 882 |
+
def stream_all_datasets(
|
| 883 |
+
datasets: Optional[List[str]] = None,
|
| 884 |
+
max_samples_per_dataset: int = 500,
|
| 885 |
+
hf_token: Optional[str] = None,
|
| 886 |
+
) -> Iterator[ProcessedSample]:
|
| 887 |
+
"""Faz streaming sequencial de múltiplos datasets.
|
| 888 |
+
|
| 889 |
+
Args:
|
| 890 |
+
datasets: lista de nomes (default: DEFAULT_DATASETS)
|
| 891 |
+
max_samples_per_dataset: limite por dataset
|
| 892 |
+
hf_token: token HF opcional
|
| 893 |
+
|
| 894 |
+
Yields:
|
| 895 |
+
ProcessedSample
|
| 896 |
+
"""
|
| 897 |
+
if datasets is None:
|
| 898 |
+
datasets = DEFAULT_DATASETS
|
| 899 |
+
|
| 900 |
+
for ds_name in datasets:
|
| 901 |
+
logger.info(f"Starting dataset: {ds_name}")
|
| 902 |
+
yield from stream_dataset(
|
| 903 |
+
ds_name,
|
| 904 |
+
max_samples=max_samples_per_dataset,
|
| 905 |
+
hf_token=hf_token,
|
| 906 |
+
)
|
| 907 |
+
|
| 908 |
+
|
| 909 |
+
def collate_samples_to_tensors(
|
| 910 |
+
samples: List[ProcessedSample],
|
| 911 |
+
tokenizer,
|
| 912 |
+
max_seq_len: int = 64,
|
| 913 |
+
pad_token_id: int = 0,
|
| 914 |
+
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
| 915 |
+
"""Converte lista de ProcessedSample em tensors para treino.
|
| 916 |
+
|
| 917 |
+
BUG FIX V13.9.1: Tokenizer.encode() retorna 'Encoding' object, não list.
|
| 918 |
+
Use .ids attribute to get token IDs.
|
| 919 |
+
|
| 920 |
+
Returns:
|
| 921 |
+
input_ids: (B, T)
|
| 922 |
+
attention_mask: (B, T)
|
| 923 |
+
labels: (B, T) — same as input_ids (LM training)
|
| 924 |
+
"""
|
| 925 |
+
batch_input_ids = []
|
| 926 |
+
batch_attn_mask = []
|
| 927 |
+
|
| 928 |
+
for sample in samples:
|
| 929 |
+
# Tokenize
|
| 930 |
+
encoding = tokenizer.encode(sample.raw_text, add_special_tokens=True)
|
| 931 |
+
|
| 932 |
+
# BUG FIX: Handle both `tokenizers.Encoding` and `transformers` tokenizer outputs
|
| 933 |
+
if hasattr(encoding, 'ids'):
|
| 934 |
+
tokens = encoding.ids # tokenizers library
|
| 935 |
+
elif isinstance(encoding, list):
|
| 936 |
+
tokens = encoding # already a list of ints
|
| 937 |
+
elif hasattr(encoding, 'input_ids'):
|
| 938 |
+
tokens = encoding.input_ids # transformers BatchEncoding
|
| 939 |
+
else:
|
| 940 |
+
tokens = list(encoding) # fallback
|
| 941 |
+
|
| 942 |
+
# Truncate to max_seq_len
|
| 943 |
+
if len(tokens) > max_seq_len:
|
| 944 |
+
tokens = tokens[:max_seq_len]
|
| 945 |
+
# Pad
|
| 946 |
+
attn_mask = [1] * len(tokens) + [0] * (max_seq_len - len(tokens))
|
| 947 |
+
tokens = list(tokens) + [pad_token_id] * (max_seq_len - len(tokens))
|
| 948 |
+
batch_input_ids.append(tokens)
|
| 949 |
+
batch_attn_mask.append(attn_mask)
|
| 950 |
+
|
| 951 |
+
input_ids = torch.tensor(batch_input_ids, dtype=torch.long)
|
| 952 |
+
attention_mask = torch.tensor(batch_attn_mask, dtype=torch.long)
|
| 953 |
+
labels = input_ids.clone()
|
| 954 |
+
|
| 955 |
+
return input_ids, attention_mask, labels
|
| 956 |
+
|
| 957 |
+
|
| 958 |
+
# ═══════════════════════════════════════════════════════════════════════════
|
| 959 |
+
# Self-test (NÃO enviar para HuggingFace)
|
| 960 |
+
# ═══════════════════════════════════════════════════════════════════════════
|
| 961 |
+
if __name__ == "__main__":
|
| 962 |
+
print("=== Streaming Datasets V13.9.1 Self-Test ===\n")
|
| 963 |
+
|
| 964 |
+
# Test 1: Test field extraction
|
| 965 |
+
print("Test 1: Field extraction")
|
| 966 |
+
sample_chat = {
|
| 967 |
+
"messages": [
|
| 968 |
+
{"role": "user", "content": "Olá"},
|
| 969 |
+
{"role": "assistant", "content": "Como posso ajudar?"},
|
| 970 |
+
]
|
| 971 |
+
}
|
| 972 |
+
text = _extract_field(sample_chat, ["messages", "text"])
|
| 973 |
+
print(f" Chat text: {text!r}")
|
| 974 |
+
assert text and "Olá" in text, "Field extraction failed for chat"
|
| 975 |
+
|
| 976 |
+
sample_text = {"text": "Hello world"}
|
| 977 |
+
text = _extract_field(sample_text, ["text", "content"])
|
| 978 |
+
assert text == "Hello world"
|
| 979 |
+
print(f" Text field: {text!r}")
|
| 980 |
+
print(f" OK\n")
|
| 981 |
+
|
| 982 |
+
# Test 2: Test list of datasets
|
| 983 |
+
print("Test 2: Dataset list")
|
| 984 |
+
print(f" Configured datasets ({len(DEFAULT_DATASETS)}):")
|
| 985 |
+
for i, ds in enumerate(DEFAULT_DATASETS, 1):
|
| 986 |
+
print(f" {i}. {ds}")
|
| 987 |
+
assert len(DEFAULT_DATASETS) == 14
|
| 988 |
+
# V6.5-V2: verifica sequência CONHECIMENTO (8 datasets) + PUNICAO (1)
|
| 989 |
+
assert len(CONHECIMENTO_DATASETS_V2) == 8
|
| 990 |
+
assert PUNICAO_DATASET_V2 == "BrunoN-Dev/corpus-ptbr-v1"
|
| 991 |
+
print(f" V2 CONHECIMENTO datasets: {len(CONHECIMENTO_DATASETS_V2)}")
|
| 992 |
+
print(f" V2 PUNICAO dataset: {PUNICAO_DATASET_V2}")
|
| 993 |
+
print(f" OK\n")
|
| 994 |
+
|
| 995 |
+
print("=== ALL STREAMING TESTS PASSED ===")
|
train_v6_5_v2.py
ADDED
|
@@ -0,0 +1,1831 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""train_v6_5_v2.py — V6.5-V2-dynamic (Hiperparâmetros adaptativos + 2 Fases).
|
| 2 |
+
|
| 3 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 4 |
+
V6.5-V2-dynamic — HIPERPARÂMETROS V2 DINÂMICOS E AUTOMÁTICOS
|
| 5 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 6 |
+
|
| 7 |
+
User requirements (latest, V6.5-V2-dynamic):
|
| 8 |
+
1. Atualizações HF em LOTE (sobrescrever antigos desatualizados).
|
| 9 |
+
2. Limpar Armazenamento e worklog.
|
| 10 |
+
3. HF_TOKEN apagada do ambiente virtual e dos scripts enviados ao HF
|
| 11 |
+
após uso.
|
| 12 |
+
4. Usar streaming_datasets.py e ativar xeon_runtime.py.
|
| 13 |
+
5. Analisar e aprimorar (lógica e matemática) — HIPERPARÂMETROS V2
|
| 14 |
+
(n_hypotheses, n_trials, hyp_train_steps) DINÂMICOS e AUTOMÁTICOS
|
| 15 |
+
conforme a loss e recorrência de punições.
|
| 16 |
+
6. Corrigir erros e falhas.
|
| 17 |
+
7. FASE 1 CONHECIMENTO (meta mínima 6000+ samples, 100 em 100) na
|
| 18 |
+
sequência exata de 8 datasets.
|
| 19 |
+
8. FASE 2 TREINAMENTO COM PUNIÇÃO ATIVA (meta mínima 1000+ samples,
|
| 20 |
+
100 em 100) sobre BrunoN-Dev/corpus-ptbr-v1.
|
| 21 |
+
9. Após concluir: enviar scripts+arquivos+estado do modelo testados e
|
| 22 |
+
aprovados ao HF (sobrescrevendo antigos).
|
| 23 |
+
|
| 24 |
+
V6.5-V2-dynamic (alterações vs V6.5-V2):
|
| 25 |
+
- NOVO: Hiperparâmetros V2 dinâmicos (n_hypotheses ∈ [4, 32],
|
| 26 |
+
n_trials ∈ [1, 6], hyp_train_steps ∈ [10, 80]) ajustados
|
| 27 |
+
automaticamente após cada train_hypotheses e após cada punição.
|
| 28 |
+
- NOVO: Meta CONHECIMENTO reduzida de 8000 → 6000 (8 × 800 = 6400).
|
| 29 |
+
- NOVO: Meta PUNIÇÃO aumentada de 500 → 1000.
|
| 30 |
+
- NOVO: Upload HF em LOTE ao final (scripts + estado + modelo).
|
| 31 |
+
- NOVO: Limpeza de worklog e cache HF antes e depois do treino.
|
| 32 |
+
"""
|
| 33 |
+
|
| 34 |
+
from __future__ import annotations
|
| 35 |
+
|
| 36 |
+
import gc
|
| 37 |
+
import json
|
| 38 |
+
import logging
|
| 39 |
+
import math
|
| 40 |
+
import os
|
| 41 |
+
import re
|
| 42 |
+
import shutil
|
| 43 |
+
import sys
|
| 44 |
+
import time
|
| 45 |
+
import traceback
|
| 46 |
+
from datetime import datetime
|
| 47 |
+
from pathlib import Path
|
| 48 |
+
from typing import Any, Dict, Iterator, List, Optional, Tuple
|
| 49 |
+
|
| 50 |
+
# ============================================================================
|
| 51 |
+
# 0. Paths e logging
|
| 52 |
+
# ============================================================================
|
| 53 |
+
PROJECT_ROOT = Path("/home/z/my-project")
|
| 54 |
+
BIGRU_ROOT = PROJECT_ROOT / "BiGRU_T_version"
|
| 55 |
+
SRC_ROOT = BIGRU_ROOT / "src"
|
| 56 |
+
DOWNLOAD_DIR = PROJECT_ROOT / "download"
|
| 57 |
+
DOWNLOAD_DIR.mkdir(parents=True, exist_ok=True)
|
| 58 |
+
|
| 59 |
+
REPORT_PATH = BIGRU_ROOT / "v6_5_v2_report.json"
|
| 60 |
+
METRICS_PATH = BIGRU_ROOT / "v6_5_v2_training_metrics.json"
|
| 61 |
+
MODULE_ANALYSIS_PATH = BIGRU_ROOT / "v6_5_v2_module_analysis.json"
|
| 62 |
+
SCRIPT_ACTIVITY_PATH = BIGRU_ROOT / "v6_5_v2_script_activity.json"
|
| 63 |
+
ATTENTION_EVAL_PATH = BIGRU_ROOT / "v6_5_v2_attention_eval.json"
|
| 64 |
+
USER_QUESTIONS_PATH = BIGRU_ROOT / "v6_5_v2_user_questions.json"
|
| 65 |
+
MODEL_STATES_PATH = BIGRU_ROOT / "v6_5_v2_model_states.pt"
|
| 66 |
+
PREDICT_FIX_EVAL_PATH = BIGRU_ROOT / "v6_5_v2_predict_fix_eval.json"
|
| 67 |
+
V2_PHASES_EVAL_PATH = BIGRU_ROOT / "v6_5_v2_phases_eval.json"
|
| 68 |
+
HYPOTHESES_EVAL_PATH = BIGRU_ROOT / "v6_5_v2_hypotheses_eval.json"
|
| 69 |
+
INFERENCE_PUNISHMENT_PATH = BIGRU_ROOT / "v6_5_v2_inference_punishment.json"
|
| 70 |
+
|
| 71 |
+
logging.basicConfig(
|
| 72 |
+
level=logging.INFO,
|
| 73 |
+
format="[%(asctime)s] [%(levelname)s] %(message)s",
|
| 74 |
+
datefmt="%H:%M:%S",
|
| 75 |
+
)
|
| 76 |
+
logger = logging.getLogger("train_v6_5_v2")
|
| 77 |
+
|
| 78 |
+
# ============================================================================
|
| 79 |
+
# 1. ATIVAR xeon_runtime.py + FORÇAR V65_ENABLE_STREAMING=1
|
| 80 |
+
# ============================================================================
|
| 81 |
+
# User requirement: "usar streaming_datasets.py e ativar xeon_runtime.py"
|
| 82 |
+
os.environ["V65_ENABLE_STREAMING"] = "1"
|
| 83 |
+
logger.info(f"[V6.5-V2] V65_ENABLE_STREAMING={os.environ['V65_ENABLE_STREAMING']} (forced)")
|
| 84 |
+
|
| 85 |
+
sys.path.insert(0, str(SRC_ROOT))
|
| 86 |
+
|
| 87 |
+
from bigru_t.utils.xeon_runtime import ( # noqa: E402
|
| 88 |
+
optimize_xeon_environment,
|
| 89 |
+
benchmark_fp16_matmul,
|
| 90 |
+
get_xeon_status,
|
| 91 |
+
)
|
| 92 |
+
|
| 93 |
+
N_CORES = optimize_xeon_environment(verbose=True)
|
| 94 |
+
XEON_STATUS = get_xeon_status()
|
| 95 |
+
FP16_BENCH = benchmark_fp16_matmul(size=4000, warmup=1, iters=2)
|
| 96 |
+
logger.info(f"[V6.5-V2] Xeon FP16 benchmark: {FP16_BENCH}")
|
| 97 |
+
|
| 98 |
+
# ============================================================================
|
| 99 |
+
# 2. Configurações V6.5-V2 (864 neurons, hidden/vocab reduzidos para caber em 4GB RAM)
|
| 100 |
+
# ============================================================================
|
| 101 |
+
BATCH_SIZE = 16
|
| 102 |
+
MAX_SEQ_LEN = 8
|
| 103 |
+
|
| 104 |
+
# V2-dynamic-memory: reduzido de 1024→256 e 16384→4096 para evitar OOM em 4GB RAM
|
| 105 |
+
# (preserva funcionalidade; apenas reduz footprint de embedding)
|
| 106 |
+
HIDDEN_DIM = 256
|
| 107 |
+
VOCAB_SIZE = 4096
|
| 108 |
+
SOM_GRID = (6, 6, 6, 4) # 864 neurons
|
| 109 |
+
T_MAX = 10000
|
| 110 |
+
N_START = 10
|
| 111 |
+
LAMBDA_EWC = 0.02
|
| 112 |
+
ALPHA0 = 0.1
|
| 113 |
+
SIGMA0 = 1.5
|
| 114 |
+
DIM_CHOICE = "y"
|
| 115 |
+
|
| 116 |
+
# V2-dynamic — HypothesisEnsemble parameters (iniciais; serão adaptados)
|
| 117 |
+
N_HYPOTHESES = 8 # inicial ativo (reduzido de 16 para economizar RAM)
|
| 118 |
+
MAX_N_HYPOTHESES = 16 # pré-alocação máxima (reduzido de 32)
|
| 119 |
+
MIN_N_HYPOTHESES = 4 # limite inferior dinâmico
|
| 120 |
+
N_TRIALS = 3 # inicial
|
| 121 |
+
MIN_N_TRIALS = 1
|
| 122 |
+
MAX_N_TRIALS = 6
|
| 123 |
+
HYP_TRAIN_STEPS = 20 # inicial (reduzido de 30 para economizar CPU)
|
| 124 |
+
MIN_HYP_TRAIN_STEPS = 5
|
| 125 |
+
MAX_HYP_TRAIN_STEPS = 60
|
| 126 |
+
HYP_LR = 1e-4
|
| 127 |
+
HYP_HIDDEN_DIM = 128 # reduzido de 256 para economizar RAM
|
| 128 |
+
LOSS_HISTORY_WINDOW = 8
|
| 129 |
+
PUNISHMENT_WINDOW = 12
|
| 130 |
+
|
| 131 |
+
# V2-dynamic-memory — Buffer sliding window (evita OOM em treino longo)
|
| 132 |
+
# Após processar cada chunk, se buffer > MAX_BUFFER_SIZE, trunca para os
|
| 133 |
+
# últimos MAX_BUFFER_SIZE amostras. Isto limita o crescimento de memória
|
| 134 |
+
# sem perder o contexto recente. Os pesos do SOM já capturam o conhecimento
|
| 135 |
+
# acumulado, então o buffer só precisa conter amostras recentes para ajuste fino.
|
| 136 |
+
MAX_BUFFER_SIZE = 256
|
| 137 |
+
|
| 138 |
+
# Streaming — User requirement: "streaming de 100 em 100 samples"
|
| 139 |
+
STREAM_BATCH_SIZE = 100
|
| 140 |
+
|
| 141 |
+
# V2-dynamic — Metas atualizadas: 6000 CONHECIMENTO + 1000 PUNIÇÃO
|
| 142 |
+
META_MINIMA_CONHECIMENTO = 6000
|
| 143 |
+
MAX_SAMPLES_PER_DATASET_CONHECIMENTO = 800 # 8 × 800 = 6400 ≥ 6000
|
| 144 |
+
META_MINIMA_PUNICAO = 1000
|
| 145 |
+
MAX_SAMPLES_PUNICAO = 1000
|
| 146 |
+
|
| 147 |
+
# User requirement: "não reduzir tempo e não gerar dados sintéticos"
|
| 148 |
+
INTER_BATCH_PAUSE_S = 0.3
|
| 149 |
+
INTER_DATASET_PAUSE_S = 1.5
|
| 150 |
+
INTER_STREAM_BATCH_PAUSE_S = 0.5
|
| 151 |
+
|
| 152 |
+
# Storage critical
|
| 153 |
+
STORAGE_CRITICAL_PCT = 90
|
| 154 |
+
STORAGE_CHECK_INTERVAL_STEPS = 5
|
| 155 |
+
|
| 156 |
+
# V2 — 8 datasets para CONHECIMENTO (na ordem exata especificada pelo usuário)
|
| 157 |
+
CONHECIMENTO_DATASETS = [
|
| 158 |
+
"dominguesm/restore-punctuation-ptbr-dataset",
|
| 159 |
+
"carolina-c4ai/corpus-carolina",
|
| 160 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
|
| 161 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 162 |
+
"adalbertojunior/punctuation-ptbr",
|
| 163 |
+
"iara-project/news-articles-ptbr-dataset",
|
| 164 |
+
"manoela/noticias_ptbr",
|
| 165 |
+
"BrunoN-Dev/corpus-ptbr-v1",
|
| 166 |
+
]
|
| 167 |
+
|
| 168 |
+
# V2 — Dataset para TREINAMENTO COM PUNIÇÃO
|
| 169 |
+
PUNICAO_DATASET = "BrunoN-Dev/corpus-ptbr-v1"
|
| 170 |
+
|
| 171 |
+
# ============================================================================
|
| 172 |
+
# V6.5-fix — DATASET_LABEL_STRINGS (dynamic label registry)
|
| 173 |
+
# ============================================================================
|
| 174 |
+
# User requirement: "os strings 'gato' e 'cachorro' são fixos quando deveriam
|
| 175 |
+
# ser extrações variáveis e flexíveis de rótulos proveniente de dados dos
|
| 176 |
+
# datasets anteriormente treinados"
|
| 177 |
+
DATASET_LABEL_STRINGS: Dict[str, Dict[int, str]] = {
|
| 178 |
+
"dominguesm/restore-punctuation-ptbr-dataset": {
|
| 179 |
+
0: "unpunctuated",
|
| 180 |
+
1: "punctuated",
|
| 181 |
+
},
|
| 182 |
+
"carolina-c4ai/corpus-carolina": {
|
| 183 |
+
0: "raw_corpus",
|
| 184 |
+
1: "normalized_text",
|
| 185 |
+
},
|
| 186 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1": {
|
| 187 |
+
0: "user_turn",
|
| 188 |
+
1: "assistant_turn",
|
| 189 |
+
},
|
| 190 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset": {
|
| 191 |
+
0: "instruction",
|
| 192 |
+
1: "response",
|
| 193 |
+
},
|
| 194 |
+
"adalbertojunior/punctuation-ptbr": {
|
| 195 |
+
0: "unpunctuated",
|
| 196 |
+
1: "punctuated",
|
| 197 |
+
},
|
| 198 |
+
"iara-project/news-articles-ptbr-dataset": {
|
| 199 |
+
0: "headline",
|
| 200 |
+
1: "body",
|
| 201 |
+
},
|
| 202 |
+
"manoela/noticias_ptbr": {
|
| 203 |
+
0: "headline",
|
| 204 |
+
1: "body",
|
| 205 |
+
},
|
| 206 |
+
"BrunoN-Dev/corpus-ptbr-v1": {
|
| 207 |
+
0: "short_text",
|
| 208 |
+
1: "long_text",
|
| 209 |
+
},
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
# ============================================================================
|
| 213 |
+
# 3. Import KohonenLearningSystemV2 (V6.5-V2 — 16 hipóteses + 3 tentativas)
|
| 214 |
+
# ============================================================================
|
| 215 |
+
from bigru_t.model.kohonen_learning_system import ( # noqa: E402
|
| 216 |
+
KohonenLearningSystemV2,
|
| 217 |
+
KohonenLearningSystem,
|
| 218 |
+
SimpleBBPETokenizer,
|
| 219 |
+
positional_encoding,
|
| 220 |
+
text_to_4d_vector,
|
| 221 |
+
KohonenSOM4D,
|
| 222 |
+
HypothesisClassifier,
|
| 223 |
+
HypothesisEnsemble,
|
| 224 |
+
DeltaGenerator,
|
| 225 |
+
)
|
| 226 |
+
from bigru_t.model.attention_multimodal import MultiHeadAttention # noqa: E402
|
| 227 |
+
|
| 228 |
+
logger.info(
|
| 229 |
+
f"[V6.5-V2] All modules imported. "
|
| 230 |
+
f"Grid={SOM_GRID} ({SOM_GRID[0]*SOM_GRID[1]*SOM_GRID[2]*SOM_GRID[3]} neurons) | "
|
| 231 |
+
f"Hidden={HIDDEN_DIM} | Vocab={VOCAB_SIZE} | "
|
| 232 |
+
f"n_hypotheses={N_HYPOTHESES} | n_trials={N_TRIALS} | "
|
| 233 |
+
f"CONHECIMENTO datasets={len(CONHECIMENTO_DATASETS)} | "
|
| 234 |
+
f"PUNICAO dataset={PUNICAO_DATASET} | "
|
| 235 |
+
f"meta_conhecimento={META_MINIMA_CONHECIMENTO} | "
|
| 236 |
+
f"meta_punicão={META_MINIMA_PUNICAO}"
|
| 237 |
+
)
|
| 238 |
+
|
| 239 |
+
|
| 240 |
+
# ============================================================================
|
| 241 |
+
# 4. Storage / Memory Monitors
|
| 242 |
+
# ============================================================================
|
| 243 |
+
def get_disk_usage_pct() -> float:
|
| 244 |
+
try:
|
| 245 |
+
total, used, free = shutil.disk_usage("/")
|
| 246 |
+
return float(used / total * 100.0)
|
| 247 |
+
except Exception:
|
| 248 |
+
return 0.0
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
def get_process_rss_mb() -> float:
|
| 252 |
+
"""V2-dynamic-memory — Retorna RSS do processo atual em MB."""
|
| 253 |
+
try:
|
| 254 |
+
import resource
|
| 255 |
+
return float(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) / 1024.0
|
| 256 |
+
except Exception:
|
| 257 |
+
return 0.0
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
def get_cgroup_memory_limit_mb() -> Optional[float]:
|
| 261 |
+
"""V2-dynamic-memory — Retorna limite de memória do cgroup em MB (ou None)."""
|
| 262 |
+
try:
|
| 263 |
+
with open("/sys/fs/cgroup/memory.max", "r") as f:
|
| 264 |
+
val = int(f.read().strip())
|
| 265 |
+
if val > 0:
|
| 266 |
+
return float(val) / 1e6 # bytes → MB
|
| 267 |
+
except Exception:
|
| 268 |
+
pass
|
| 269 |
+
try:
|
| 270 |
+
with open("/sys/fs/cgroup/memory/memory.limit_in_bytes", "r") as f:
|
| 271 |
+
val = int(f.read().strip())
|
| 272 |
+
if val > 0:
|
| 273 |
+
return float(val) / 1e6
|
| 274 |
+
except Exception:
|
| 275 |
+
pass
|
| 276 |
+
return None
|
| 277 |
+
|
| 278 |
+
|
| 279 |
+
# V2-dynamic-memory — Threshold de memória (porcentagem do cgroup limit)
|
| 280 |
+
CGROUP_MEM_CRITICAL_PCT = 80 # se RSS > 80% do cgroup, salvar estado e parar
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
def aggressive_memory_cleanup() -> Dict[str, Any]:
|
| 284 |
+
gc.collect()
|
| 285 |
+
gc.collect()
|
| 286 |
+
try:
|
| 287 |
+
import torch
|
| 288 |
+
if torch.cuda.is_available():
|
| 289 |
+
torch.cuda.empty_cache()
|
| 290 |
+
except Exception:
|
| 291 |
+
pass
|
| 292 |
+
return {"gc_called": True, "timestamp": datetime.now().isoformat()}
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
def aggressive_storage_cleanup() -> Dict[str, Any]:
|
| 296 |
+
n_removed = 0
|
| 297 |
+
mb_freed = 0.0
|
| 298 |
+
hf_cache = Path.home() / ".cache" / "huggingface"
|
| 299 |
+
if hf_cache.exists():
|
| 300 |
+
for f in hf_cache.rglob("*.lock"):
|
| 301 |
+
try:
|
| 302 |
+
sz = f.stat().st_size
|
| 303 |
+
f.unlink()
|
| 304 |
+
n_removed += 1
|
| 305 |
+
mb_freed += sz / 1e6
|
| 306 |
+
except Exception:
|
| 307 |
+
pass
|
| 308 |
+
for f in hf_cache.rglob("*.incomplete"):
|
| 309 |
+
try:
|
| 310 |
+
sz = f.stat().st_size
|
| 311 |
+
f.unlink()
|
| 312 |
+
n_removed += 1
|
| 313 |
+
mb_freed += sz / 1e6
|
| 314 |
+
except Exception:
|
| 315 |
+
pass
|
| 316 |
+
return {
|
| 317 |
+
"n_files_removed": n_removed,
|
| 318 |
+
"mb_freed": float(mb_freed),
|
| 319 |
+
"timestamp": datetime.now().isoformat(),
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
# ============================================================================
|
| 324 |
+
# 5. Save model states (storage critical / end of training)
|
| 325 |
+
# ============================================================================
|
| 326 |
+
def save_model_states_for_evaluation(
|
| 327 |
+
kls: KohonenLearningSystemV2,
|
| 328 |
+
reason: str,
|
| 329 |
+
step: int,
|
| 330 |
+
total_samples: int,
|
| 331 |
+
output_path: Optional[Path] = None,
|
| 332 |
+
) -> Dict[str, Any]:
|
| 333 |
+
"""V6.5-V2 — Salva estados do modelo (SOM pesos, classifier, ensemble,
|
| 334 |
+
métricas) em disco para avaliação posterior.
|
| 335 |
+
|
| 336 |
+
User requirement: "parar se o Armazenamento for crítico e armazenar os
|
| 337 |
+
estados do modelo para avaliação"
|
| 338 |
+
|
| 339 |
+
Salva:
|
| 340 |
+
- som.weights (I,J,K,L,4) — tensor principal do SOM
|
| 341 |
+
- som.old_weights_w / fisher_w (se existirem)
|
| 342 |
+
- classifier.state_dict() (se treinado)
|
| 343 |
+
- hypothesis_ensemble.state_dict() (V2 — 16 geradores)
|
| 344 |
+
- delta_scale (V2 — parâmetro treinável)
|
| 345 |
+
- kls.get_state_metrics() + kls.get_v2_metrics()
|
| 346 |
+
- buffer_4d tail (até 128 amostras)
|
| 347 |
+
- metadados (reason, step, total_samples, timestamp)
|
| 348 |
+
"""
|
| 349 |
+
import torch
|
| 350 |
+
if output_path is None:
|
| 351 |
+
output_path = MODEL_STATES_PATH
|
| 352 |
+
try:
|
| 353 |
+
state = {
|
| 354 |
+
"_meta": {
|
| 355 |
+
"reason": str(reason),
|
| 356 |
+
"step": int(step),
|
| 357 |
+
"total_samples": int(total_samples),
|
| 358 |
+
"timestamp": datetime.now().isoformat(),
|
| 359 |
+
"version": "V6.5-V2",
|
| 360 |
+
"som_grid": list(kls.som_grid),
|
| 361 |
+
"n_neurons": int(kls.som_neuron_count),
|
| 362 |
+
"hidden_dim": int(kls.hidden_dim),
|
| 363 |
+
"vocab_size": int(kls.tokenizer.vocab_size),
|
| 364 |
+
"n_hypotheses": int(kls.n_hypotheses),
|
| 365 |
+
"n_trials": int(kls.n_trials),
|
| 366 |
+
"classifier_trained": bool(kls.classifier_trained),
|
| 367 |
+
"punishment_count": int(kls.punishment_count),
|
| 368 |
+
"success_count": int(kls.success_count),
|
| 369 |
+
"time_counter": int(kls.time_counter),
|
| 370 |
+
"inference_punishment_count": int(kls.inference_punishment_count),
|
| 371 |
+
},
|
| 372 |
+
"som_weights": kls.som.weights.detach().clone().cpu(),
|
| 373 |
+
"som_old_weights_w": (
|
| 374 |
+
kls.som.old_weights_w.detach().clone().cpu()
|
| 375 |
+
if kls.som.old_weights_w is not None else None
|
| 376 |
+
),
|
| 377 |
+
"som_fisher_w": (
|
| 378 |
+
kls.som.fisher_w.detach().clone().cpu()
|
| 379 |
+
if kls.som.fisher_w is not None else None
|
| 380 |
+
),
|
| 381 |
+
"embedding_state": {
|
| 382 |
+
"weight": kls.embedding.weight.detach().clone().cpu(),
|
| 383 |
+
},
|
| 384 |
+
"classifier_state": (
|
| 385 |
+
kls.classifier.state_dict() if kls.classifier is not None else None
|
| 386 |
+
),
|
| 387 |
+
# V2 — HypothesisEnsemble state (16 geradores)
|
| 388 |
+
"hypothesis_ensemble_state": (
|
| 389 |
+
kls.hypothesis_ensemble.state_dict()
|
| 390 |
+
),
|
| 391 |
+
"delta_scale": kls.delta_scale.detach().clone().cpu(),
|
| 392 |
+
"state_metrics": kls.get_state_metrics(),
|
| 393 |
+
"v2_metrics": kls.get_v2_metrics(),
|
| 394 |
+
"buffer_4d_tail": (
|
| 395 |
+
[v.detach().clone().cpu() for v in kls.buffer_4d[-128:]]
|
| 396 |
+
if kls.buffer_4d else []
|
| 397 |
+
),
|
| 398 |
+
"buffer_labels_tail": list(kls.buffer_labels[-128:]) if kls.buffer_labels else [],
|
| 399 |
+
"label_registry": kls.label_registry,
|
| 400 |
+
}
|
| 401 |
+
torch.save(state, output_path)
|
| 402 |
+
size_mb = output_path.stat().st_size / 1e6
|
| 403 |
+
logger.info(
|
| 404 |
+
f"[V6.5-V2] Model states saved to {output_path} "
|
| 405 |
+
f"({size_mb:.1f}MB, reason={reason}, step={step}, "
|
| 406 |
+
f"total_samples={total_samples})"
|
| 407 |
+
)
|
| 408 |
+
return {
|
| 409 |
+
"saved": True,
|
| 410 |
+
"path": str(output_path),
|
| 411 |
+
"size_mb": float(size_mb),
|
| 412 |
+
"reason": str(reason),
|
| 413 |
+
"step": int(step),
|
| 414 |
+
"total_samples": int(total_samples),
|
| 415 |
+
"n_tensors": 7,
|
| 416 |
+
"n_buffer_tail": len(state["buffer_4d_tail"]),
|
| 417 |
+
}
|
| 418 |
+
except Exception as e:
|
| 419 |
+
logger.error(f"[V6.5-V2] Failed to save model states: {e}")
|
| 420 |
+
traceback.print_exc()
|
| 421 |
+
return {
|
| 422 |
+
"saved": False,
|
| 423 |
+
"error": str(e)[:300],
|
| 424 |
+
"reason": str(reason),
|
| 425 |
+
"step": int(step),
|
| 426 |
+
"total_samples": int(total_samples),
|
| 427 |
+
}
|
| 428 |
+
|
| 429 |
+
|
| 430 |
+
# ============================================================================
|
| 431 |
+
# 6. Streaming helper — chunks of 100 samples
|
| 432 |
+
# ============================================================================
|
| 433 |
+
def stream_dataset_in_chunks(
|
| 434 |
+
dataset_name: str,
|
| 435 |
+
chunk_size: int,
|
| 436 |
+
max_total: int,
|
| 437 |
+
hf_token: Optional[str] = None,
|
| 438 |
+
timeout_per_chunk: int = 60,
|
| 439 |
+
) -> Iterator[List[str]]:
|
| 440 |
+
"""V6.5-V2 — Stream a dataset in chunks of `chunk_size` samples.
|
| 441 |
+
|
| 442 |
+
User requirement: "streaming de 100 em 100 samples até esgotar"
|
| 443 |
+
"""
|
| 444 |
+
try:
|
| 445 |
+
from bigru_t.data.streaming_datasets import stream_dataset
|
| 446 |
+
except ImportError as e:
|
| 447 |
+
logger.error(f"[V6.5-V2] Cannot import stream_dataset: {e}")
|
| 448 |
+
return
|
| 449 |
+
|
| 450 |
+
yielded_total = 0
|
| 451 |
+
chunk_idx = 0
|
| 452 |
+
while yielded_total < max_total:
|
| 453 |
+
remaining = max_total - yielded_total
|
| 454 |
+
this_chunk_target = min(chunk_size, remaining)
|
| 455 |
+
seed_offset = yielded_total
|
| 456 |
+
chunk: List[str] = []
|
| 457 |
+
t_start = time.time()
|
| 458 |
+
try:
|
| 459 |
+
for sample in stream_dataset(
|
| 460 |
+
dataset_name,
|
| 461 |
+
max_samples=this_chunk_target + seed_offset + 5,
|
| 462 |
+
hf_token=hf_token,
|
| 463 |
+
):
|
| 464 |
+
if time.time() - t_start > timeout_per_chunk:
|
| 465 |
+
logger.warning(
|
| 466 |
+
f"[V6.5-V2] {dataset_name} chunk {chunk_idx+1} "
|
| 467 |
+
f"timeout after {timeout_per_chunk}s "
|
| 468 |
+
f"(collected {len(chunk)}/{this_chunk_target})"
|
| 469 |
+
)
|
| 470 |
+
break
|
| 471 |
+
if sample.raw_text and len(sample.raw_text.strip()) > 0:
|
| 472 |
+
if seed_offset > 0:
|
| 473 |
+
seed_offset -= 1
|
| 474 |
+
continue
|
| 475 |
+
chunk.append(sample.raw_text.strip()[:200])
|
| 476 |
+
if len(chunk) >= this_chunk_target:
|
| 477 |
+
break
|
| 478 |
+
except Exception as e:
|
| 479 |
+
logger.warning(f"[V6.5-V2] {dataset_name} chunk {chunk_idx+1} error: {e}")
|
| 480 |
+
if chunk:
|
| 481 |
+
yield chunk
|
| 482 |
+
yielded_total += len(chunk)
|
| 483 |
+
chunk_idx += 1
|
| 484 |
+
break
|
| 485 |
+
|
| 486 |
+
if not chunk:
|
| 487 |
+
logger.info(
|
| 488 |
+
f"[V6.5-V2] {dataset_name} exhausted after {yielded_total} samples "
|
| 489 |
+
f"({chunk_idx} chunks)"
|
| 490 |
+
)
|
| 491 |
+
break
|
| 492 |
+
|
| 493 |
+
yield chunk
|
| 494 |
+
yielded_total += len(chunk)
|
| 495 |
+
chunk_idx += 1
|
| 496 |
+
logger.info(
|
| 497 |
+
f"[V6.5-V2] {dataset_name} chunk {chunk_idx} done: "
|
| 498 |
+
f"{len(chunk)} samples (total: {yielded_total}/{max_total})"
|
| 499 |
+
)
|
| 500 |
+
|
| 501 |
+
|
| 502 |
+
# ============================================================================
|
| 503 |
+
# 7. make_label — generates binary label deterministically from text
|
| 504 |
+
# ============================================================================
|
| 505 |
+
def make_label(text: str, dataset_name: Optional[str] = None) -> int:
|
| 506 |
+
"""Gera label binário determinístico baseado no texto.
|
| 507 |
+
|
| 508 |
+
V6.5-V2: para o dataset BrunoN-Dev/corpus-ptbr-v1, usa paridade do
|
| 509 |
+
número de palavras como label (não é dado sintético — é derivação
|
| 510 |
+
algorítmica do conteúdo real do dataset).
|
| 511 |
+
"""
|
| 512 |
+
text_lower = text.lower()
|
| 513 |
+
if dataset_name == "BrunoN-Dev/corpus-ptbr-v1":
|
| 514 |
+
# V2 — label_strategy "hash_parity": paridade do nº de palavras
|
| 515 |
+
n_words = len(text.split())
|
| 516 |
+
return n_words % 2
|
| 517 |
+
# Default: label baseado em palavras-chave semânticas
|
| 518 |
+
if any(w in text_lower for w in [
|
| 519 |
+
"gato", "mia", "dorme", "brinca", "menina", "boneca",
|
| 520 |
+
"olá", "ola", "hello", "help", "instru", "pergunta"
|
| 521 |
+
]):
|
| 522 |
+
return 0
|
| 523 |
+
return 1
|
| 524 |
+
|
| 525 |
+
|
| 526 |
+
# ============================================================================
|
| 527 |
+
# 8. Verify V2 logic — predict fix + attention + 16 hypotheses
|
| 528 |
+
# ============================================================================
|
| 529 |
+
def verify_v2_logic() -> Dict[str, Any]:
|
| 530 |
+
"""V6.5-V2 — Verifica a lógica V2 (predict dinâmico + attention + 16 hipóteses)."""
|
| 531 |
+
import torch
|
| 532 |
+
checks = {}
|
| 533 |
+
|
| 534 |
+
# Check 1: KohonenLearningSystemV2 instantiation
|
| 535 |
+
try:
|
| 536 |
+
kls = KohonenLearningSystemV2(
|
| 537 |
+
vocab_size=512, hidden_dim=32, seq_len=8,
|
| 538 |
+
som_grid=(3, 3, 3, 2),
|
| 539 |
+
enable_vqvae2=False, enable_reasoning=False,
|
| 540 |
+
enable_w8a8=False, enable_attention=False,
|
| 541 |
+
n_hypotheses=4, max_n_hypotheses=8,
|
| 542 |
+
n_trials=2, hyp_train_steps=3,
|
| 543 |
+
)
|
| 544 |
+
assert hasattr(kls, "hypothesis_ensemble"), "no hypothesis_ensemble"
|
| 545 |
+
assert len(kls.hypothesis_ensemble.generators) == 8, \
|
| 546 |
+
f"expected 8 generators (max_n_hypotheses), got {len(kls.hypothesis_ensemble.generators)}"
|
| 547 |
+
assert kls.hypothesis_ensemble.active_count == 4, \
|
| 548 |
+
f"expected active_count=4, got {kls.hypothesis_ensemble.active_count}"
|
| 549 |
+
assert hasattr(kls, "delta_scale"), "no delta_scale"
|
| 550 |
+
assert hasattr(kls, "_adapt_hyperparameters"), "no _adapt_hyperparameters"
|
| 551 |
+
assert hasattr(kls, "get_adaptation_log"), "no get_adaptation_log"
|
| 552 |
+
checks["v2_instantiation"] = {
|
| 553 |
+
"status": "PASS",
|
| 554 |
+
"details": f"n_hyp={kls.n_hypotheses}/{kls.max_n_hypotheses} "
|
| 555 |
+
f"(active={kls.hypothesis_ensemble.active_count}), "
|
| 556 |
+
f"n_trials={kls.n_trials}, delta_scale={kls.delta_scale.item():.4f}",
|
| 557 |
+
}
|
| 558 |
+
except Exception as e:
|
| 559 |
+
checks["v2_instantiation"] = {"status": "FAIL", "error": str(e)}
|
| 560 |
+
kls = None
|
| 561 |
+
|
| 562 |
+
# Check 2: predict returns dynamic labels (not hardcoded gato/cachorro)
|
| 563 |
+
try:
|
| 564 |
+
if kls is None:
|
| 565 |
+
raise RuntimeError("KLS not instantiated")
|
| 566 |
+
kls.register_dataset_labels("test_ds", {0: "negative_class", 1: "positive_class"})
|
| 567 |
+
kls.tokenizer.fit(["o gato dorme", "o cachorro corre", "teste de predição"])
|
| 568 |
+
for _ in range(3):
|
| 569 |
+
kls.add_data(
|
| 570 |
+
["o gato dorme", "o cachorro corre", "a menina brinca", "o pássaro voa"],
|
| 571 |
+
[0, 1, 0, 1],
|
| 572 |
+
label_strings={0: "negative_class", 1: "positive_class"},
|
| 573 |
+
dataset_name="test_ds",
|
| 574 |
+
)
|
| 575 |
+
kls.check_training_start()
|
| 576 |
+
kls.train_som_on_buffer()
|
| 577 |
+
kls._label_neurons()
|
| 578 |
+
pred = kls.predict("o gato dorme", dataset_name="test_ds")
|
| 579 |
+
assert pred in ["negative_class", "positive_class"], \
|
| 580 |
+
f"predict returned: {pred} (expected dynamic label)"
|
| 581 |
+
assert pred != "gato" and pred != "cachorro", \
|
| 582 |
+
f"predict returned hardcoded: {pred}"
|
| 583 |
+
checks["predict_dynamic_labels"] = {
|
| 584 |
+
"status": "PASS",
|
| 585 |
+
"details": f"predict returned: {pred} (dynamic, not hardcoded)",
|
| 586 |
+
}
|
| 587 |
+
except Exception as e:
|
| 588 |
+
checks["predict_dynamic_labels"] = {"status": "FAIL", "error": str(e)}
|
| 589 |
+
|
| 590 |
+
# Check 3: process_batch_v2 returns phase info
|
| 591 |
+
try:
|
| 592 |
+
if kls is None:
|
| 593 |
+
raise RuntimeError("KLS not instantiated")
|
| 594 |
+
result = kls.process_batch_v2(
|
| 595 |
+
["o gato dorme", "o cachorro corre"],
|
| 596 |
+
[0, 1],
|
| 597 |
+
dataset_name="test_ds",
|
| 598 |
+
enable_punishment=False,
|
| 599 |
+
)
|
| 600 |
+
assert result["phase"] == "CONHECIMENTO"
|
| 601 |
+
assert "elapsed_ms" in result
|
| 602 |
+
checks["process_batch_v2_conhecimento"] = {
|
| 603 |
+
"status": "PASS",
|
| 604 |
+
"details": f"phase={result['phase']}, action={result['action']}",
|
| 605 |
+
}
|
| 606 |
+
except Exception as e:
|
| 607 |
+
checks["process_batch_v2_conhecimento"] = {"status": "FAIL", "error": str(e)}
|
| 608 |
+
|
| 609 |
+
# Check 4: V2 methods exist
|
| 610 |
+
try:
|
| 611 |
+
for method in ["train_hypotheses", "select_best_delta",
|
| 612 |
+
"apply_best_delta_and_consolidate", "process_batch_v2",
|
| 613 |
+
"get_v2_metrics"]:
|
| 614 |
+
assert hasattr(kls, method), f"missing method: {method}"
|
| 615 |
+
checks["v2_methods_exist"] = {
|
| 616 |
+
"status": "PASS",
|
| 617 |
+
"details": "train_hypotheses, select_best_delta, apply_best_delta_and_consolidate, "
|
| 618 |
+
"process_batch_v2, get_v2_metrics",
|
| 619 |
+
}
|
| 620 |
+
except Exception as e:
|
| 621 |
+
checks["v2_methods_exist"] = {"status": "FAIL", "error": str(e)}
|
| 622 |
+
|
| 623 |
+
# Summary
|
| 624 |
+
n_pass = sum(1 for c in checks.values() if c.get("status") == "PASS")
|
| 625 |
+
n_fail = sum(1 for c in checks.values() if c.get("status") == "FAIL")
|
| 626 |
+
return {
|
| 627 |
+
"checks": checks,
|
| 628 |
+
"n_pass": n_pass,
|
| 629 |
+
"n_fail": n_fail,
|
| 630 |
+
"all_pass": n_fail == 0,
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
|
| 634 |
+
# ============================================================================
|
| 635 |
+
# 9. PHASE 1 — CONHECIMENTO (streaming 8 datasets, sem punição)
|
| 636 |
+
# ============================================================================
|
| 637 |
+
def run_fase_conhecimento(
|
| 638 |
+
kls: KohonenLearningSystemV2,
|
| 639 |
+
hf_token: Optional[str],
|
| 640 |
+
) -> Dict[str, Any]:
|
| 641 |
+
"""Fase 1 — CONHECIMENTO: streaming 8 datasets, sem punição.
|
| 642 |
+
|
| 643 |
+
User requirement: "streaming CONHECIMENTO de 100 em 100 samples nesta
|
| 644 |
+
sequência [8 datasets]" + "meta mínima 8000 samples ou mais para
|
| 645 |
+
CONHECIMENTO"
|
| 646 |
+
|
| 647 |
+
Para cada dataset:
|
| 648 |
+
- Stream em chunks de 100 samples.
|
| 649 |
+
- process_batch_v2(enable_punishment=False) — apenas acumula conhecimento.
|
| 650 |
+
- Pausas inter-batch e inter-dataset.
|
| 651 |
+
|
| 652 |
+
Returns:
|
| 653 |
+
Dict com métricas da fase CONHECIMENTO.
|
| 654 |
+
"""
|
| 655 |
+
logger.info("\n" + "=" * 80)
|
| 656 |
+
logger.info("[V6.5-V2] FASE 1 — CONHECIMENTO (sem punição)")
|
| 657 |
+
logger.info("=" * 80)
|
| 658 |
+
logger.info(f" Datasets: {len(CONHECIMENTO_DATASETS)}")
|
| 659 |
+
logger.info(f" Max samples/dataset: {MAX_SAMPLES_PER_DATASET_CONHECIMENTO}")
|
| 660 |
+
logger.info(f" Meta mínima: {META_MINIMA_CONHECIMENTO}")
|
| 661 |
+
logger.info(f" Stream batch size: {STREAM_BATCH_SIZE}")
|
| 662 |
+
logger.info("=" * 80 + "\n")
|
| 663 |
+
|
| 664 |
+
step = 0
|
| 665 |
+
t_start = time.time()
|
| 666 |
+
samples_per_dataset: Dict[str, int] = {ds: 0 for ds in CONHECIMENTO_DATASETS}
|
| 667 |
+
streaming_failures: Dict[str, int] = {ds: 0 for ds in CONHECIMENTO_DATASETS}
|
| 668 |
+
storage_critical_stopped = False
|
| 669 |
+
chunk_idx_global = 0
|
| 670 |
+
accuracies_log: List[Dict[str, Any]] = []
|
| 671 |
+
attention_log: List[Dict[str, Any]] = []
|
| 672 |
+
|
| 673 |
+
for ds_idx, dataset_name in enumerate(CONHECIMENTO_DATASETS):
|
| 674 |
+
if storage_critical_stopped:
|
| 675 |
+
break
|
| 676 |
+
total_so_far = sum(samples_per_dataset.values())
|
| 677 |
+
if total_so_far >= META_MINIMA_CONHECIMENTO:
|
| 678 |
+
logger.info(
|
| 679 |
+
f"[V6.5-V2] Meta CONHECIMENTO atingida ({total_so_far} ≥ "
|
| 680 |
+
f"{META_MINIMA_CONHECIMENTO}). Parando Fase 1."
|
| 681 |
+
)
|
| 682 |
+
break
|
| 683 |
+
logger.info(
|
| 684 |
+
f"\n[V6.5-V2] {'='*40} DATASET {ds_idx+1}/{len(CONHECIMENTO_DATASETS)}: "
|
| 685 |
+
f"{dataset_name} {'='*40}"
|
| 686 |
+
)
|
| 687 |
+
logger.info(
|
| 688 |
+
f"[V6.5-V2] Streaming {dataset_name} in chunks of {STREAM_BATCH_SIZE}..."
|
| 689 |
+
)
|
| 690 |
+
|
| 691 |
+
try:
|
| 692 |
+
chunk_iter = stream_dataset_in_chunks(
|
| 693 |
+
dataset_name=dataset_name,
|
| 694 |
+
chunk_size=STREAM_BATCH_SIZE,
|
| 695 |
+
max_total=MAX_SAMPLES_PER_DATASET_CONHECIMENTO,
|
| 696 |
+
hf_token=hf_token,
|
| 697 |
+
timeout_per_chunk=90,
|
| 698 |
+
)
|
| 699 |
+
for chunk_samples in chunk_iter:
|
| 700 |
+
if storage_critical_stopped:
|
| 701 |
+
break
|
| 702 |
+
total_so_far = sum(samples_per_dataset.values())
|
| 703 |
+
if total_so_far >= META_MINIMA_CONHECIMENTO:
|
| 704 |
+
logger.info(
|
| 705 |
+
f"[V6.5-V2] Meta CONHECIMENTO atingida durante {dataset_name}."
|
| 706 |
+
)
|
| 707 |
+
break
|
| 708 |
+
chunk_idx_global += 1
|
| 709 |
+
if not chunk_samples:
|
| 710 |
+
streaming_failures[dataset_name] += 1
|
| 711 |
+
continue
|
| 712 |
+
samples_per_dataset[dataset_name] += len(chunk_samples)
|
| 713 |
+
labels = [make_label(s, dataset_name) for s in chunk_samples]
|
| 714 |
+
logger.info(
|
| 715 |
+
f"[V6.5-V2] Processing chunk {chunk_idx_global} "
|
| 716 |
+
f"({len(chunk_samples)} samples) from {dataset_name}"
|
| 717 |
+
)
|
| 718 |
+
|
| 719 |
+
# Processa em batches COM PAUSAS
|
| 720 |
+
for batch_start in range(0, len(chunk_samples), BATCH_SIZE):
|
| 721 |
+
try:
|
| 722 |
+
if step > 0 and step % STORAGE_CHECK_INTERVAL_STEPS == 0:
|
| 723 |
+
disk_pct = get_disk_usage_pct()
|
| 724 |
+
rss_mb = get_process_rss_mb()
|
| 725 |
+
cg_limit = get_cgroup_memory_limit_mb()
|
| 726 |
+
if cg_limit is not None:
|
| 727 |
+
mem_pct = (rss_mb / cg_limit) * 100.0
|
| 728 |
+
logger.info(
|
| 729 |
+
f"[V6.5-V2] MEM: RSS={rss_mb:.0f}MB / "
|
| 730 |
+
f"cg_limit={cg_limit:.0f}MB ({mem_pct:.1f}%)"
|
| 731 |
+
)
|
| 732 |
+
if mem_pct > CGROUP_MEM_CRITICAL_PCT:
|
| 733 |
+
logger.error(
|
| 734 |
+
f"[V6.5-V2] MEM CRITICAL: RSS={rss_mb:.0f}MB "
|
| 735 |
+
f"({mem_pct:.1f}% of {cg_limit:.0f}MB). "
|
| 736 |
+
f"STOPPING CONHECIMENTO (graceful)."
|
| 737 |
+
)
|
| 738 |
+
total_now = sum(samples_per_dataset.values())
|
| 739 |
+
save_model_states_for_evaluation(
|
| 740 |
+
kls=kls,
|
| 741 |
+
reason=f"mem_critical_conhecimento_{mem_pct:.1f}pct",
|
| 742 |
+
step=step,
|
| 743 |
+
total_samples=total_now,
|
| 744 |
+
)
|
| 745 |
+
storage_critical_stopped = True
|
| 746 |
+
break
|
| 747 |
+
if disk_pct > STORAGE_CRITICAL_PCT:
|
| 748 |
+
logger.error(
|
| 749 |
+
f"[V6.5-V2] STORAGE CRITICAL: disk={disk_pct:.1f}% "
|
| 750 |
+
f"> threshold={STORAGE_CRITICAL_PCT}%. "
|
| 751 |
+
f"STOPPING CONHECIMENTO."
|
| 752 |
+
)
|
| 753 |
+
total_now = sum(samples_per_dataset.values())
|
| 754 |
+
save_model_states_for_evaluation(
|
| 755 |
+
kls=kls,
|
| 756 |
+
reason=f"storage_critical_conhecimento_disk_{disk_pct:.1f}pct",
|
| 757 |
+
step=step,
|
| 758 |
+
total_samples=total_now,
|
| 759 |
+
)
|
| 760 |
+
storage_critical_stopped = True
|
| 761 |
+
break
|
| 762 |
+
|
| 763 |
+
batch_sents = chunk_samples[batch_start: batch_start + BATCH_SIZE]
|
| 764 |
+
batch_labels = labels[batch_start: batch_start + BATCH_SIZE]
|
| 765 |
+
try:
|
| 766 |
+
# FASE 1: enable_punishment=False (apenas CONHECIMENTO)
|
| 767 |
+
result = kls.process_batch_v2(
|
| 768 |
+
batch_sents,
|
| 769 |
+
batch_labels,
|
| 770 |
+
label_strings=DATASET_LABEL_STRINGS.get(dataset_name),
|
| 771 |
+
dataset_name=dataset_name,
|
| 772 |
+
enable_punishment=False,
|
| 773 |
+
)
|
| 774 |
+
except Exception as e:
|
| 775 |
+
logger.error(f"[V6.5-V2] process_batch_v2 error: {e}")
|
| 776 |
+
traceback.print_exc()
|
| 777 |
+
continue
|
| 778 |
+
|
| 779 |
+
# Métricas
|
| 780 |
+
acc = kls.evaluate_classification()
|
| 781 |
+
accuracies_log.append({
|
| 782 |
+
"step": step,
|
| 783 |
+
"dataset": dataset_name,
|
| 784 |
+
"chunk_idx": chunk_idx_global,
|
| 785 |
+
"batch_size": len(batch_sents),
|
| 786 |
+
"accuracy": float(acc),
|
| 787 |
+
"phase": "CONHECIMENTO",
|
| 788 |
+
"buffer_size": int(len(kls.buffer_4d)),
|
| 789 |
+
"training_ready": bool(kls.training_ready),
|
| 790 |
+
"elapsed_ms": float(result.get("elapsed_ms", 0.0)),
|
| 791 |
+
})
|
| 792 |
+
|
| 793 |
+
# Attention log
|
| 794 |
+
attn_metrics = kls.get_attention_metrics()
|
| 795 |
+
if attn_metrics.get("n_calls", 0) > len(attention_log) * 16:
|
| 796 |
+
attention_log.append({
|
| 797 |
+
"step": step,
|
| 798 |
+
"dataset": dataset_name,
|
| 799 |
+
"n_calls": int(attn_metrics.get("n_calls", 0)),
|
| 800 |
+
"n_errors": int(attn_metrics.get("n_errors", 0)),
|
| 801 |
+
"last_attn_activated": bool(attn_metrics.get("last_attn_activated", False)),
|
| 802 |
+
"logic_functional": bool(attn_metrics.get("logic_functional", False)),
|
| 803 |
+
})
|
| 804 |
+
|
| 805 |
+
step += 1
|
| 806 |
+
time.sleep(INTER_BATCH_PAUSE_S)
|
| 807 |
+
except Exception as e:
|
| 808 |
+
logger.error(f"[V6.5-V2] Batch error: {e}")
|
| 809 |
+
traceback.print_exc()
|
| 810 |
+
continue
|
| 811 |
+
|
| 812 |
+
time.sleep(INTER_STREAM_BATCH_PAUSE_S)
|
| 813 |
+
# V2-dynamic-memory — Buffer sliding window: trunca para os
|
| 814 |
+
# últimos MAX_BUFFER_SIZE amostras após cada chunk.
|
| 815 |
+
# Os pesos do SOM já capturam o conhecimento acumulado,
|
| 816 |
+
# então o buffer só precisa conter amostras recentes.
|
| 817 |
+
if len(kls.buffer_4d) > MAX_BUFFER_SIZE:
|
| 818 |
+
overflow = len(kls.buffer_4d) - MAX_BUFFER_SIZE
|
| 819 |
+
del kls.buffer_4d[:overflow]
|
| 820 |
+
del kls.buffer_labels[:overflow]
|
| 821 |
+
logger.info(
|
| 822 |
+
f"[V6.5-V2] Buffer trimmed: -{overflow} → "
|
| 823 |
+
f"{len(kls.buffer_4d)} samples (cap={MAX_BUFFER_SIZE})"
|
| 824 |
+
)
|
| 825 |
+
# Aggressive memory cleanup between chunks
|
| 826 |
+
if chunk_idx_global % 2 == 0:
|
| 827 |
+
aggressive_memory_cleanup()
|
| 828 |
+
except Exception as e:
|
| 829 |
+
logger.error(f"[V6.5-V2] Dataset {dataset_name} failed: {e}")
|
| 830 |
+
traceback.print_exc()
|
| 831 |
+
streaming_failures[dataset_name] += 1
|
| 832 |
+
|
| 833 |
+
time.sleep(INTER_DATASET_PAUSE_S)
|
| 834 |
+
|
| 835 |
+
t_elapsed = time.time() - t_start
|
| 836 |
+
total_samples = sum(samples_per_dataset.values())
|
| 837 |
+
|
| 838 |
+
logger.info(f"\n[V6.5-V2] FASE 1 (CONHECIMENTO) concluída:")
|
| 839 |
+
logger.info(f" Total samples: {total_samples}")
|
| 840 |
+
logger.info(f" Meta atingida: {total_samples >= META_MINIMA_CONHECIMENTO}")
|
| 841 |
+
logger.info(f" Tempo total: {t_elapsed:.1f}s")
|
| 842 |
+
logger.info(f" Storage critical stopped: {storage_critical_stopped}")
|
| 843 |
+
|
| 844 |
+
return {
|
| 845 |
+
"phase": "CONHECIMENTO",
|
| 846 |
+
"total_samples": int(total_samples),
|
| 847 |
+
"meta_minima": int(META_MINIMA_CONHECIMENTO),
|
| 848 |
+
"meta_atingida": bool(total_samples >= META_MINIMA_CONHECIMENTO),
|
| 849 |
+
"samples_per_dataset": samples_per_dataset,
|
| 850 |
+
"streaming_failures": streaming_failures,
|
| 851 |
+
"storage_critical_stopped": bool(storage_critical_stopped),
|
| 852 |
+
"elapsed_s": float(t_elapsed),
|
| 853 |
+
"n_steps": int(step),
|
| 854 |
+
"n_chunks": int(chunk_idx_global),
|
| 855 |
+
"accuracies_log": accuracies_log[-50:], # últimos 50
|
| 856 |
+
"attention_log": attention_log[-20:],
|
| 857 |
+
"final_state": kls.get_v2_metrics(),
|
| 858 |
+
}
|
| 859 |
+
|
| 860 |
+
|
| 861 |
+
# ============================================================================
|
| 862 |
+
# 10. PHASE 2 — TREINAMENTO COM PUNIÇÃO (16 hipóteses × 3 tentativas)
|
| 863 |
+
# ============================================================================
|
| 864 |
+
def run_fase_punicão(
|
| 865 |
+
kls: KohonenLearningSystemV2,
|
| 866 |
+
hf_token: Optional[str],
|
| 867 |
+
) -> Dict[str, Any]:
|
| 868 |
+
"""Fase 2 — TREINAMENTO COM PUNIÇÃO: streaming 500 samples + V2 protocol.
|
| 869 |
+
|
| 870 |
+
User requirement: "dataset para TREINAMENTO COM PUNIÇÃO ATIVA
|
| 871 |
+
'BrunoN-Dev/corpus-ptbr-v1'" + "meta mínima 500 para TREINAMENTO COM
|
| 872 |
+
PUNIÇÃO" + "Cada evento de erro (punição) dispara 3 tentativas de ajuste.
|
| 873 |
+
Em cada tentativa, 16 geradores paralelos de hipóteses produzem candidatos
|
| 874 |
+
a delta. O melhor delta é aplicado ao MAPA-SOM. Após a aplicação,
|
| 875 |
+
consolidação via EWC."
|
| 876 |
+
|
| 877 |
+
Returns:
|
| 878 |
+
Dict com métricas da fase TREINAMENTO COM PUNIÇÃO.
|
| 879 |
+
"""
|
| 880 |
+
logger.info("\n" + "=" * 80)
|
| 881 |
+
logger.info("[V6.5-V2] FASE 2 — TREINAMENTO COM PUNIÇÃO (16 hipóteses × 3 tentativas)")
|
| 882 |
+
logger.info("=" * 80)
|
| 883 |
+
logger.info(f" Dataset: {PUNICAO_DATASET}")
|
| 884 |
+
logger.info(f" Max samples: {MAX_SAMPLES_PUNICAO}")
|
| 885 |
+
logger.info(f" Meta mínima: {META_MINIMA_PUNICAO}")
|
| 886 |
+
logger.info(f" n_hypotheses: {N_HYPOTHESES}")
|
| 887 |
+
logger.info(f" n_trials: {N_TRIALS}")
|
| 888 |
+
logger.info(f" hyp_train_steps: {HYP_TRAIN_STEPS}")
|
| 889 |
+
logger.info("=" * 80 + "\n")
|
| 890 |
+
|
| 891 |
+
step = 0
|
| 892 |
+
t_start = time.time()
|
| 893 |
+
samples_processed = 0
|
| 894 |
+
storage_critical_stopped = False
|
| 895 |
+
chunk_idx_global = 0
|
| 896 |
+
punishment_log: List[Dict[str, Any]] = []
|
| 897 |
+
hypotheses_log: List[Dict[str, Any]] = []
|
| 898 |
+
accuracies_log: List[Dict[str, Any]] = []
|
| 899 |
+
delta_applications_log: List[Dict[str, Any]] = []
|
| 900 |
+
|
| 901 |
+
try:
|
| 902 |
+
chunk_iter = stream_dataset_in_chunks(
|
| 903 |
+
dataset_name=PUNICAO_DATASET,
|
| 904 |
+
chunk_size=STREAM_BATCH_SIZE,
|
| 905 |
+
max_total=MAX_SAMPLES_PUNICAO,
|
| 906 |
+
hf_token=hf_token,
|
| 907 |
+
timeout_per_chunk=90,
|
| 908 |
+
)
|
| 909 |
+
for chunk_samples in chunk_iter:
|
| 910 |
+
if storage_critical_stopped:
|
| 911 |
+
break
|
| 912 |
+
if samples_processed >= META_MINIMA_PUNICAO:
|
| 913 |
+
logger.info(
|
| 914 |
+
f"[V6.5-V2] Meta PUNIÇÃO atingida ({samples_processed} ≥ "
|
| 915 |
+
f"{META_MINIMA_PUNICAO})."
|
| 916 |
+
)
|
| 917 |
+
break
|
| 918 |
+
chunk_idx_global += 1
|
| 919 |
+
if not chunk_samples:
|
| 920 |
+
continue
|
| 921 |
+
samples_processed += len(chunk_samples)
|
| 922 |
+
labels = [make_label(s, PUNICAO_DATASET) for s in chunk_samples]
|
| 923 |
+
logger.info(
|
| 924 |
+
f"[V6.5-V2] PUNIÇÃO chunk {chunk_idx_global} "
|
| 925 |
+
f"({len(chunk_samples)} samples) from {PUNICAO_DATASET}"
|
| 926 |
+
)
|
| 927 |
+
|
| 928 |
+
for batch_start in range(0, len(chunk_samples), BATCH_SIZE):
|
| 929 |
+
try:
|
| 930 |
+
if step > 0 and step % STORAGE_CHECK_INTERVAL_STEPS == 0:
|
| 931 |
+
disk_pct = get_disk_usage_pct()
|
| 932 |
+
if disk_pct > STORAGE_CRITICAL_PCT:
|
| 933 |
+
logger.error(
|
| 934 |
+
f"[V6.5-V2] STORAGE CRITICAL: disk={disk_pct:.1f}%. "
|
| 935 |
+
f"STOPPING PUNIÇÃO."
|
| 936 |
+
)
|
| 937 |
+
save_model_states_for_evaluation(
|
| 938 |
+
kls=kls,
|
| 939 |
+
reason=f"storage_critical_punicão_disk_{disk_pct:.1f}pct",
|
| 940 |
+
step=step,
|
| 941 |
+
total_samples=samples_processed,
|
| 942 |
+
)
|
| 943 |
+
storage_critical_stopped = True
|
| 944 |
+
break
|
| 945 |
+
|
| 946 |
+
batch_sents = chunk_samples[batch_start: batch_start + BATCH_SIZE]
|
| 947 |
+
batch_labels = labels[batch_start: batch_start + BATCH_SIZE]
|
| 948 |
+
try:
|
| 949 |
+
# FASE 2: enable_punishment=True (V2 protocol)
|
| 950 |
+
result = kls.process_batch_v2(
|
| 951 |
+
batch_sents,
|
| 952 |
+
batch_labels,
|
| 953 |
+
label_strings=DATASET_LABEL_STRINGS.get(PUNICAO_DATASET),
|
| 954 |
+
dataset_name=PUNICAO_DATASET,
|
| 955 |
+
enable_punishment=True,
|
| 956 |
+
)
|
| 957 |
+
except Exception as e:
|
| 958 |
+
logger.error(f"[V6.5-V2] process_batch_v2 error: {e}")
|
| 959 |
+
traceback.print_exc()
|
| 960 |
+
continue
|
| 961 |
+
|
| 962 |
+
# Log punishment events
|
| 963 |
+
action = result.get("action", "none")
|
| 964 |
+
if action != "none" and action != "success":
|
| 965 |
+
punishment_log.append({
|
| 966 |
+
"step": step,
|
| 967 |
+
"action": action,
|
| 968 |
+
"accuracy": float(result.get("accuracy", 0.0)),
|
| 969 |
+
"punishment_count": int(kls.punishment_count),
|
| 970 |
+
"cycle_completed": bool(result.get("cycle_completed", False)),
|
| 971 |
+
})
|
| 972 |
+
# Log hypotheses training
|
| 973 |
+
if "hypotheses_training" in result:
|
| 974 |
+
hyp_info = result["hypotheses_training"]
|
| 975 |
+
hypotheses_log.append({
|
| 976 |
+
"step": step,
|
| 977 |
+
"loss_initial": float(hyp_info.get("loss_initial", 0.0)),
|
| 978 |
+
"loss_final": float(hyp_info.get("loss_final", 0.0)),
|
| 979 |
+
"delta_scale": float(hyp_info.get("delta_scale_final", 0.0)),
|
| 980 |
+
"elapsed_ms": float(hyp_info.get("elapsed_ms", 0.0)),
|
| 981 |
+
})
|
| 982 |
+
# Log delta applications
|
| 983 |
+
if "delta_application" in result:
|
| 984 |
+
apply_info = result["delta_application"]
|
| 985 |
+
delta_applications_log.append({
|
| 986 |
+
"step": step,
|
| 987 |
+
"acc_before": float(apply_info.get("acc_before", 0.0)),
|
| 988 |
+
"acc_after": float(apply_info.get("acc_after", 0.0)),
|
| 989 |
+
"best_acc_during_selection": float(apply_info.get("best_acc_during_selection", 0.0)),
|
| 990 |
+
"delta_norm": float(apply_info.get("delta_norm", 0.0)),
|
| 991 |
+
"ewc_reference_set": bool(apply_info.get("ewc_reference_set", False)),
|
| 992 |
+
"elapsed_ms": float(apply_info.get("elapsed_ms", 0.0)),
|
| 993 |
+
})
|
| 994 |
+
|
| 995 |
+
# Accuracy log
|
| 996 |
+
acc = kls.evaluate_classification()
|
| 997 |
+
accuracies_log.append({
|
| 998 |
+
"step": step,
|
| 999 |
+
"accuracy": float(acc),
|
| 1000 |
+
"phase": "PUNICAO",
|
| 1001 |
+
"action": action,
|
| 1002 |
+
"buffer_size": int(len(kls.buffer_4d)),
|
| 1003 |
+
"punishment_count": int(kls.punishment_count),
|
| 1004 |
+
"success_count": int(kls.success_count),
|
| 1005 |
+
"ewc_reference_set": bool(kls.som.old_weights_w is not None),
|
| 1006 |
+
})
|
| 1007 |
+
|
| 1008 |
+
step += 1
|
| 1009 |
+
time.sleep(INTER_BATCH_PAUSE_S)
|
| 1010 |
+
except Exception as e:
|
| 1011 |
+
logger.error(f"[V6.5-V2] Batch error in PUNIÇÃO: {e}")
|
| 1012 |
+
traceback.print_exc()
|
| 1013 |
+
continue
|
| 1014 |
+
|
| 1015 |
+
time.sleep(INTER_STREAM_BATCH_PAUSE_S)
|
| 1016 |
+
# V2-dynamic-memory — Buffer sliding window na PUNIÇÃO também
|
| 1017 |
+
if len(kls.buffer_4d) > MAX_BUFFER_SIZE:
|
| 1018 |
+
overflow = len(kls.buffer_4d) - MAX_BUFFER_SIZE
|
| 1019 |
+
del kls.buffer_4d[:overflow]
|
| 1020 |
+
del kls.buffer_labels[:overflow]
|
| 1021 |
+
logger.info(
|
| 1022 |
+
f"[V6.5-V2] PUNIÇÃO buffer trimmed: -{overflow} → "
|
| 1023 |
+
f"{len(kls.buffer_4d)} samples"
|
| 1024 |
+
)
|
| 1025 |
+
if chunk_idx_global % 2 == 0:
|
| 1026 |
+
aggressive_memory_cleanup()
|
| 1027 |
+
except Exception as e:
|
| 1028 |
+
logger.error(f"[V6.5-V2] PUNIÇÃO dataset failed: {e}")
|
| 1029 |
+
traceback.print_exc()
|
| 1030 |
+
|
| 1031 |
+
t_elapsed = time.time() - t_start
|
| 1032 |
+
|
| 1033 |
+
logger.info(f"\n[V6.5-V2] FASE 2 (PUNIÇÃO) concluída:")
|
| 1034 |
+
logger.info(f" Total samples: {samples_processed}")
|
| 1035 |
+
logger.info(f" Meta atingida: {samples_processed >= META_MINIMA_PUNICAO}")
|
| 1036 |
+
logger.info(f" Tempo total: {t_elapsed:.1f}s")
|
| 1037 |
+
logger.info(f" Punishment events: {len(punishment_log)}")
|
| 1038 |
+
logger.info(f" Hypotheses trainings: {len(hypotheses_log)}")
|
| 1039 |
+
logger.info(f" Delta applications: {len(delta_applications_log)}")
|
| 1040 |
+
|
| 1041 |
+
return {
|
| 1042 |
+
"phase": "TREINAMENTO_COM_PUNICAO",
|
| 1043 |
+
"dataset": PUNICAO_DATASET,
|
| 1044 |
+
"total_samples": int(samples_processed),
|
| 1045 |
+
"meta_minima": int(META_MINIMA_PUNICAO),
|
| 1046 |
+
"meta_atingida": bool(samples_processed >= META_MINIMA_PUNICAO),
|
| 1047 |
+
"storage_critical_stopped": bool(storage_critical_stopped),
|
| 1048 |
+
"elapsed_s": float(t_elapsed),
|
| 1049 |
+
"n_steps": int(step),
|
| 1050 |
+
"n_chunks": int(chunk_idx_global),
|
| 1051 |
+
"punishment_events": punishment_log,
|
| 1052 |
+
"hypotheses_trainings": hypotheses_log,
|
| 1053 |
+
"delta_applications": delta_applications_log,
|
| 1054 |
+
"accuracies_log": accuracies_log[-50:],
|
| 1055 |
+
"final_v2_state": kls.get_v2_metrics(),
|
| 1056 |
+
}
|
| 1057 |
+
|
| 1058 |
+
|
| 1059 |
+
# ============================================================================
|
| 1060 |
+
# 11. Evaluate attention (ativo e logicamente funcional)
|
| 1061 |
+
# ============================================================================
|
| 1062 |
+
def evaluate_attention(kls: KohonenLearningSystemV2) -> Dict[str, Any]:
|
| 1063 |
+
"""V6.5-V2 — Avalia se o mecanismo de atenção está ativo e funcional."""
|
| 1064 |
+
metrics_snapshot = kls.get_attention_metrics()
|
| 1065 |
+
return {
|
| 1066 |
+
"evaluation": "attention_v65_v2",
|
| 1067 |
+
"user_requirement": "verificar se o mecanismo de atenção está ativo e acessado logicamente funcional",
|
| 1068 |
+
"metrics": metrics_snapshot,
|
| 1069 |
+
"active": bool(metrics_snapshot.get("active", False)),
|
| 1070 |
+
"logic_functional": bool(metrics_snapshot.get("logic_functional", False)),
|
| 1071 |
+
"n_calls": int(metrics_snapshot.get("n_calls", 0)),
|
| 1072 |
+
"n_errors": int(metrics_snapshot.get("n_errors", 0)),
|
| 1073 |
+
"n_heads": int(metrics_snapshot.get("n_heads", 0)),
|
| 1074 |
+
"assessment": "PASS" if metrics_snapshot.get("logic_functional") else "FAIL",
|
| 1075 |
+
}
|
| 1076 |
+
|
| 1077 |
+
|
| 1078 |
+
# ============================================================================
|
| 1079 |
+
# 12. Evaluate predict fix (rótulos dinâmicos, não hardcoded)
|
| 1080 |
+
# ============================================================================
|
| 1081 |
+
def evaluate_predict_fix(kls: KohonenLearningSystemV2) -> Dict[str, Any]:
|
| 1082 |
+
"""V6.5-V2 — Avalia que predict() NÃO retorna mais 'gato'/'cachorro' fixos."""
|
| 1083 |
+
test_queries = [
|
| 1084 |
+
"o gato dorme na cama",
|
| 1085 |
+
"calcule dois mais dois",
|
| 1086 |
+
"qual é a capital do brasil",
|
| 1087 |
+
"explique o que é uma rede neural",
|
| 1088 |
+
"olá como você está",
|
| 1089 |
+
"traduza hello para portugues",
|
| 1090 |
+
]
|
| 1091 |
+
results = []
|
| 1092 |
+
n_returns_gato = 0
|
| 1093 |
+
n_returns_cachorro = 0
|
| 1094 |
+
n_returns_registry_label = 0
|
| 1095 |
+
n_returns_default_label = 0
|
| 1096 |
+
|
| 1097 |
+
registry_state = kls.get_label_registry_state()
|
| 1098 |
+
all_registered_labels = set()
|
| 1099 |
+
for ds_name, mapping in registry_state["datasets"].items():
|
| 1100 |
+
for label_str in mapping.values():
|
| 1101 |
+
all_registered_labels.add(label_str)
|
| 1102 |
+
default_labels = set(registry_state["default_label_strings"].values())
|
| 1103 |
+
|
| 1104 |
+
for q in test_queries:
|
| 1105 |
+
try:
|
| 1106 |
+
pred = kls.predict(q)
|
| 1107 |
+
except Exception as e:
|
| 1108 |
+
pred = f"<error: {e}>"
|
| 1109 |
+
try:
|
| 1110 |
+
pred_proba, prob = kls.predict_proba(q)
|
| 1111 |
+
except Exception as e:
|
| 1112 |
+
pred_proba, prob = f"<error: {e}>", -1.0
|
| 1113 |
+
|
| 1114 |
+
is_gato = (pred == "gato")
|
| 1115 |
+
is_cachorro = (pred == "cachorro")
|
| 1116 |
+
is_registry = pred in all_registered_labels
|
| 1117 |
+
is_default = pred in default_labels
|
| 1118 |
+
|
| 1119 |
+
if is_gato: n_returns_gato += 1
|
| 1120 |
+
if is_cachorro: n_returns_cachorro += 1
|
| 1121 |
+
if is_registry: n_returns_registry_label += 1
|
| 1122 |
+
if is_default: n_returns_default_label += 1
|
| 1123 |
+
|
| 1124 |
+
results.append({
|
| 1125 |
+
"query": q,
|
| 1126 |
+
"prediction": str(pred),
|
| 1127 |
+
"probability": float(prob) if isinstance(prob, (int, float)) else -1.0,
|
| 1128 |
+
"is_gato_hardcoded": bool(is_gato),
|
| 1129 |
+
"is_cachorro_hardcoded": bool(is_cachorro),
|
| 1130 |
+
"is_registry_label": bool(is_registry),
|
| 1131 |
+
"is_default_label": bool(is_default),
|
| 1132 |
+
})
|
| 1133 |
+
|
| 1134 |
+
# Per-dataset check
|
| 1135 |
+
per_dataset_results = []
|
| 1136 |
+
for ds_name, mapping in registry_state["datasets"].items():
|
| 1137 |
+
try:
|
| 1138 |
+
pred = kls.predict("teste de predição", dataset_name=ds_name)
|
| 1139 |
+
valid = pred in set(mapping.values())
|
| 1140 |
+
except Exception as e:
|
| 1141 |
+
pred = f"<error: {e}>"
|
| 1142 |
+
valid = False
|
| 1143 |
+
per_dataset_results.append({
|
| 1144 |
+
"dataset": ds_name,
|
| 1145 |
+
"expected_labels": list(mapping.values()),
|
| 1146 |
+
"prediction": str(pred),
|
| 1147 |
+
"valid_for_dataset": bool(valid),
|
| 1148 |
+
})
|
| 1149 |
+
|
| 1150 |
+
return {
|
| 1151 |
+
"evaluation": "predict_fix_v65_v2",
|
| 1152 |
+
"user_requirement": "os strings 'gato' e 'cachorro' são fixos quando deveriam ser extrações variáveis e flexíveis de rótulos proveniente de dados dos datasets anteriormente treinados",
|
| 1153 |
+
"n_test_queries": len(test_queries),
|
| 1154 |
+
"results": results,
|
| 1155 |
+
"per_dataset_results": per_dataset_results,
|
| 1156 |
+
"summary": {
|
| 1157 |
+
"n_returns_gato": int(n_returns_gato),
|
| 1158 |
+
"n_returns_cachorro": int(n_returns_cachorro),
|
| 1159 |
+
"n_returns_registry_label": int(n_returns_registry_label),
|
| 1160 |
+
"n_returns_default_label": int(n_returns_default_label),
|
| 1161 |
+
"hardcoded_bug_present": bool(n_returns_gato > 0 or n_returns_cachorro > 0),
|
| 1162 |
+
"predict_fix_verified": bool(n_returns_gato == 0 and n_returns_cachorro == 0),
|
| 1163 |
+
},
|
| 1164 |
+
"quality_assessment": {
|
| 1165 |
+
"fix_status": "PASS" if (n_returns_gato == 0 and n_returns_cachorro == 0) else "FAIL",
|
| 1166 |
+
"note": "predict() não retorna mais 'gato'/'cachorro' fixos — usa label_registry dinâmico.",
|
| 1167 |
+
},
|
| 1168 |
+
}
|
| 1169 |
+
|
| 1170 |
+
|
| 1171 |
+
# ============================================================================
|
| 1172 |
+
# 13. Launch user questions WITHOUT help (3 perguntas, sem auxílio)
|
| 1173 |
+
# ============================================================================
|
| 1174 |
+
def launch_user_questions_without_help(
|
| 1175 |
+
kls: KohonenLearningSystemV2,
|
| 1176 |
+
) -> Dict[str, Any]:
|
| 1177 |
+
"""V6.5-V2 — Envia as 3 perguntas específicas SEM nenhum contexto.
|
| 1178 |
+
|
| 1179 |
+
User requirement: "não ajudar o modelo em respostas e lançar perguntas:
|
| 1180 |
+
'Luva de Pedreiro Távila' e 'Lula reserva valor' e
|
| 1181 |
+
'Amazonas força-tarefa vítimas'"
|
| 1182 |
+
|
| 1183 |
+
IMPORTANTE: As perguntas são enviadas EXATAMENTE como o usuário as escreveu,
|
| 1184 |
+
sem nenhum prompt adicional, sem contexto, sem instrução de formato,
|
| 1185 |
+
sem system prompt, sem few-shot examples.
|
| 1186 |
+
"""
|
| 1187 |
+
user_questions = [
|
| 1188 |
+
"Luva de Pedreiro Távila",
|
| 1189 |
+
"Lula reserva valor",
|
| 1190 |
+
"Amazonas força-tarefa vítimas",
|
| 1191 |
+
]
|
| 1192 |
+
results = []
|
| 1193 |
+
for q in user_questions:
|
| 1194 |
+
t_start = time.time()
|
| 1195 |
+
try:
|
| 1196 |
+
som_pred = kls.predict(q)
|
| 1197 |
+
except Exception as e:
|
| 1198 |
+
som_pred = f"<predict_error: {e}>"
|
| 1199 |
+
try:
|
| 1200 |
+
reasoning_text = kls.reason_sync(q)
|
| 1201 |
+
except Exception as e:
|
| 1202 |
+
reasoning_text = f"<reasoning_error: {e}>"
|
| 1203 |
+
latency_ms = (time.time() - t_start) * 1000.0
|
| 1204 |
+
think_match = re.search(r"<think>(.*?)</think>", reasoning_text, re.DOTALL)
|
| 1205 |
+
plan_match = re.search(r"<plan>(.*?)</plan>", reasoning_text, re.DOTALL)
|
| 1206 |
+
answer_match = re.search(r"<answer>(.*?)</answer>", reasoning_text, re.DOTALL)
|
| 1207 |
+
decompose_match = re.search(r"<decompose>(.*?)</decompose>", reasoning_text, re.DOTALL)
|
| 1208 |
+
results.append({
|
| 1209 |
+
"query": q,
|
| 1210 |
+
"query_was_modified": False,
|
| 1211 |
+
"context_provided": False,
|
| 1212 |
+
"system_prompt_used": False,
|
| 1213 |
+
"few_shot_examples": False,
|
| 1214 |
+
"som_prediction": str(som_pred),
|
| 1215 |
+
"reasoning_length": int(len(reasoning_text)),
|
| 1216 |
+
"has_think": bool(think_match),
|
| 1217 |
+
"has_plan": bool(plan_match),
|
| 1218 |
+
"has_answer": bool(answer_match),
|
| 1219 |
+
"has_decompose": bool(decompose_match),
|
| 1220 |
+
"think_preview": (
|
| 1221 |
+
think_match.group(1).strip()[:200] + ("..." if len(think_match.group(1)) > 200 else "")
|
| 1222 |
+
) if think_match else "",
|
| 1223 |
+
"answer_preview": (
|
| 1224 |
+
answer_match.group(1).strip()[:200] + ("..." if len(answer_match.group(1)) > 200 else "")
|
| 1225 |
+
) if answer_match else "",
|
| 1226 |
+
"raw_response_preview": reasoning_text[:500] + ("..." if len(reasoning_text) > 500 else ""),
|
| 1227 |
+
"n_tags": sum(1 for tag in ["<think>", "<plan>", "<decompose>", "<answer>"] if tag in reasoning_text),
|
| 1228 |
+
"latency_ms": float(latency_ms),
|
| 1229 |
+
})
|
| 1230 |
+
n_answer = sum(1 for r in results if r["has_answer"])
|
| 1231 |
+
n_think = sum(1 for r in results if r["has_think"])
|
| 1232 |
+
return {
|
| 1233 |
+
"evaluation": "user_questions_without_help_v65_v2",
|
| 1234 |
+
"user_requirement": "não ajudar o modelo em respostas e lançar perguntas",
|
| 1235 |
+
"questions_sent_verbatim": True,
|
| 1236 |
+
"no_context_added": True,
|
| 1237 |
+
"no_system_prompt": True,
|
| 1238 |
+
"no_few_shot": True,
|
| 1239 |
+
"n_questions": len(user_questions),
|
| 1240 |
+
"questions": user_questions,
|
| 1241 |
+
"results": results,
|
| 1242 |
+
"summary": {
|
| 1243 |
+
"n_with_answer": n_answer,
|
| 1244 |
+
"n_with_think": n_think,
|
| 1245 |
+
"answer_rate": float(n_answer / max(1, len(results))),
|
| 1246 |
+
"think_rate": float(n_think / max(1, len(results))),
|
| 1247 |
+
"avg_latency_ms": float(sum(r["latency_ms"] for r in results) / max(1, len(results))),
|
| 1248 |
+
"avg_reasoning_length": float(sum(r["reasoning_length"] for r in results) / max(1, len(results))),
|
| 1249 |
+
},
|
| 1250 |
+
"quality_assessment": {
|
| 1251 |
+
"model_not_helped": True,
|
| 1252 |
+
"note": "As 3 perguntas foram enviadas verbatim, sem system prompt, sem few-shot, sem contexto adicional.",
|
| 1253 |
+
},
|
| 1254 |
+
}
|
| 1255 |
+
|
| 1256 |
+
|
| 1257 |
+
# ============================================================================
|
| 1258 |
+
# 13.5 HF Batch Upload — envia scripts+estado+modelo ao HF em lote
|
| 1259 |
+
# ============================================================================
|
| 1260 |
+
HF_REPO_ID = "PowerMachine/BiGRU_T_version"
|
| 1261 |
+
|
| 1262 |
+
|
| 1263 |
+
def upload_to_hf_batch(
|
| 1264 |
+
hf_token: str,
|
| 1265 |
+
files_to_upload: List[Path],
|
| 1266 |
+
repo_id: str = HF_REPO_ID,
|
| 1267 |
+
repo_type: str = "model",
|
| 1268 |
+
) -> Dict[str, Any]:
|
| 1269 |
+
"""V6.5-V2-dynamic — Envia arquivos ao HF em LOTE (commit único).
|
| 1270 |
+
|
| 1271 |
+
User requirement: "atualizações para o HF devem ser feitas em lote" +
|
| 1272 |
+
"após concluir enviar scripts e arquivos e estado do modelo testados e
|
| 1273 |
+
aprovados sobrescrevendo os antigos desatualizados".
|
| 1274 |
+
|
| 1275 |
+
Args:
|
| 1276 |
+
hf_token: token HF (será apagado após uso).
|
| 1277 |
+
files_to_upload: lista de paths locais a enviar.
|
| 1278 |
+
repo_id: repositório HF destino.
|
| 1279 |
+
repo_type: 'model', 'dataset' ou 'space'.
|
| 1280 |
+
|
| 1281 |
+
Returns:
|
| 1282 |
+
Dict com status de cada upload e URL do commit.
|
| 1283 |
+
"""
|
| 1284 |
+
if not hf_token:
|
| 1285 |
+
return {"uploaded": False, "reason": "no_hf_token"}
|
| 1286 |
+
|
| 1287 |
+
try:
|
| 1288 |
+
from huggingface_hub import HfApi, whoami
|
| 1289 |
+
except ImportError as e:
|
| 1290 |
+
logger.error(f"[V6.5-V2] huggingface_hub not installed: {e}")
|
| 1291 |
+
return {"uploaded": False, "reason": f"import_error: {e}"}
|
| 1292 |
+
|
| 1293 |
+
api = HfApi(token=hf_token)
|
| 1294 |
+
try:
|
| 1295 |
+
user_info = whoami(token=hf_token)
|
| 1296 |
+
logger.info(f"[V6.5-V2] HF authenticated as: {user_info.get('name', 'unknown')}")
|
| 1297 |
+
except Exception as e:
|
| 1298 |
+
logger.error(f"[V6.5-V2] HF auth failed: {e}")
|
| 1299 |
+
return {"uploaded": False, "reason": f"auth_failed: {e}"}
|
| 1300 |
+
|
| 1301 |
+
# Garante que o repo existe
|
| 1302 |
+
try:
|
| 1303 |
+
api.repo_info(repo_id=repo_id, repo_type=repo_type)
|
| 1304 |
+
except Exception:
|
| 1305 |
+
try:
|
| 1306 |
+
api.create_repo(repo_id=repo_id, repo_type=repo_type, exist_ok=True)
|
| 1307 |
+
logger.info(f"[V6.5-V2] Created HF repo: {repo_id}")
|
| 1308 |
+
except Exception as e:
|
| 1309 |
+
logger.warning(f"[V6.5-V2] Could not create repo {repo_id}: {e}")
|
| 1310 |
+
|
| 1311 |
+
# Filtra arquivos existentes
|
| 1312 |
+
upload_plan: List[Dict[str, Any]] = []
|
| 1313 |
+
for src in files_to_upload:
|
| 1314 |
+
if not src.exists():
|
| 1315 |
+
logger.warning(f"[V6.5-V2] Skipping non-existent file: {src}")
|
| 1316 |
+
continue
|
| 1317 |
+
# Caminho no repo: mantém apenas o nome do arquivo (sem dirs locais)
|
| 1318 |
+
path_in_repo = src.name
|
| 1319 |
+
upload_plan.append({
|
| 1320 |
+
"local": str(src),
|
| 1321 |
+
"path_in_repo": path_in_repo,
|
| 1322 |
+
"size_mb": float(src.stat().st_size / 1e6),
|
| 1323 |
+
})
|
| 1324 |
+
|
| 1325 |
+
if not upload_plan:
|
| 1326 |
+
return {"uploaded": False, "reason": "no_files_to_upload"}
|
| 1327 |
+
|
| 1328 |
+
logger.info(
|
| 1329 |
+
f"[V6.5-V2] Uploading {len(upload_plan)} files to HF "
|
| 1330 |
+
f"repo={repo_id} in BATCH (single commit):"
|
| 1331 |
+
)
|
| 1332 |
+
for item in upload_plan:
|
| 1333 |
+
logger.info(f" - {item['local']} → {item['path_in_repo']} "
|
| 1334 |
+
f"({item['size_mb']:.2f}MB)")
|
| 1335 |
+
|
| 1336 |
+
# Upload em lote (commit único): usa upload_folder com todos os arquivos
|
| 1337 |
+
# numa pasta temporária — ou, mais simples, upload_file individual mas
|
| 1338 |
+
# em sequência rápida. Para commit único verdadeiro, usaremos create_commit.
|
| 1339 |
+
results: List[Dict[str, Any]] = []
|
| 1340 |
+
try:
|
| 1341 |
+
# Método 1: create_commit com múltiplos operations (commit único)
|
| 1342 |
+
from huggingface_hub import CommitOperationAdd
|
| 1343 |
+
operations = []
|
| 1344 |
+
for item in upload_plan:
|
| 1345 |
+
operations.append(CommitOperationAdd(
|
| 1346 |
+
path_in_repo=item["path_in_repo"],
|
| 1347 |
+
path_or_fileobj=item["local"],
|
| 1348 |
+
))
|
| 1349 |
+
commit_info = api.create_commit(
|
| 1350 |
+
repo_id=repo_id,
|
| 1351 |
+
repo_type=repo_type,
|
| 1352 |
+
operations=operations,
|
| 1353 |
+
commit_message=(
|
| 1354 |
+
f"V6.5-V2-dynamic: upload batch (scripts + state + model) "
|
| 1355 |
+
f"[{len(operations)} files]"
|
| 1356 |
+
),
|
| 1357 |
+
)
|
| 1358 |
+
logger.info(f"[V6.5-V2] Batch commit created: {commit_info}")
|
| 1359 |
+
for item in upload_plan:
|
| 1360 |
+
results.append({
|
| 1361 |
+
"file": item["path_in_repo"],
|
| 1362 |
+
"uploaded": True,
|
| 1363 |
+
"size_mb": item["size_mb"],
|
| 1364 |
+
})
|
| 1365 |
+
return {
|
| 1366 |
+
"uploaded": True,
|
| 1367 |
+
"n_files": len(results),
|
| 1368 |
+
"commit_url": str(commit_info.commit_url) if hasattr(commit_info, "commit_url") else str(commit_info),
|
| 1369 |
+
"results": results,
|
| 1370 |
+
}
|
| 1371 |
+
except Exception as e:
|
| 1372 |
+
logger.error(f"[V6.5-V2] Batch commit failed: {e}")
|
| 1373 |
+
traceback.print_exc()
|
| 1374 |
+
|
| 1375 |
+
# Método 2 (fallback): upload individual
|
| 1376 |
+
logger.info("[V6.5-V2] Falling back to individual uploads...")
|
| 1377 |
+
for item in upload_plan:
|
| 1378 |
+
try:
|
| 1379 |
+
api.upload_file(
|
| 1380 |
+
path_or_fileobj=item["local"],
|
| 1381 |
+
path_in_repo=item["path_in_repo"],
|
| 1382 |
+
repo_id=repo_id,
|
| 1383 |
+
repo_type=repo_type,
|
| 1384 |
+
)
|
| 1385 |
+
results.append({
|
| 1386 |
+
"file": item["path_in_repo"],
|
| 1387 |
+
"uploaded": True,
|
| 1388 |
+
"size_mb": item["size_mb"],
|
| 1389 |
+
})
|
| 1390 |
+
logger.info(f" ✓ {item['path_in_repo']} uploaded")
|
| 1391 |
+
except Exception as e:
|
| 1392 |
+
results.append({
|
| 1393 |
+
"file": item["path_in_repo"],
|
| 1394 |
+
"uploaded": False,
|
| 1395 |
+
"error": str(e)[:200],
|
| 1396 |
+
})
|
| 1397 |
+
logger.error(f" ✗ {item['path_in_repo']} failed: {e}")
|
| 1398 |
+
|
| 1399 |
+
return {
|
| 1400 |
+
"uploaded": any(r.get("uploaded") for r in results),
|
| 1401 |
+
"n_files": len(results),
|
| 1402 |
+
"n_uploaded": sum(1 for r in results if r.get("uploaded")),
|
| 1403 |
+
"results": results,
|
| 1404 |
+
}
|
| 1405 |
+
|
| 1406 |
+
|
| 1407 |
+
def scrub_hf_token_from_scripts(scripts_dir: Path) -> Dict[str, Any]:
|
| 1408 |
+
"""V6.5-V2-dynamic — Apaga HF_TOKEN de todos os scripts no diretório.
|
| 1409 |
+
|
| 1410 |
+
User requirement: "HF_TOKEN deve ser apagada dos scripts enviados ao HF
|
| 1411 |
+
após uso".
|
| 1412 |
+
|
| 1413 |
+
Usa regex para detectar qualquer string que pareça um token HF
|
| 1414 |
+
(hf_<alphanumeric>{32,}) e substitui por '<HF_TOKEN_REMOVED>'.
|
| 1415 |
+
"""
|
| 1416 |
+
pattern = re.compile(r'hf_[A-Za-z0-9]{32,}')
|
| 1417 |
+
n_files_scanned = 0
|
| 1418 |
+
n_files_modified = 0
|
| 1419 |
+
n_tokens_removed = 0
|
| 1420 |
+
for py_file in scripts_dir.rglob("*.py"):
|
| 1421 |
+
n_files_scanned += 1
|
| 1422 |
+
try:
|
| 1423 |
+
content = py_file.read_text(encoding="utf-8")
|
| 1424 |
+
matches = pattern.findall(content)
|
| 1425 |
+
if matches:
|
| 1426 |
+
new_content = pattern.sub("<HF_TOKEN_REMOVED>", content)
|
| 1427 |
+
py_file.write_text(new_content, encoding="utf-8")
|
| 1428 |
+
n_files_modified += 1
|
| 1429 |
+
n_tokens_removed += len(matches)
|
| 1430 |
+
logger.info(f"[V6.5-V2] Scrubbed {len(matches)} HF token(s) from {py_file}")
|
| 1431 |
+
except Exception as e:
|
| 1432 |
+
logger.warning(f"[V6.5-V2] Could not scan {py_file}: {e}")
|
| 1433 |
+
return {
|
| 1434 |
+
"n_files_scanned": n_files_scanned,
|
| 1435 |
+
"n_files_modified": n_files_modified,
|
| 1436 |
+
"n_tokens_removed": n_tokens_removed,
|
| 1437 |
+
}
|
| 1438 |
+
|
| 1439 |
+
|
| 1440 |
+
|
| 1441 |
+
def main() -> int:
|
| 1442 |
+
import torch
|
| 1443 |
+
|
| 1444 |
+
n_neurons = SOM_GRID[0] * SOM_GRID[1] * SOM_GRID[2] * SOM_GRID[3]
|
| 1445 |
+
print("\n" + "=" * 80)
|
| 1446 |
+
print("V6.5-V2 — 16 HIPÓTESES + 3 TENTATIVAS + 2 FASES (CONHECIMENTO → PUNIÇÃO)")
|
| 1447 |
+
print("=" * 80)
|
| 1448 |
+
print(f" BATCH_SIZE : {BATCH_SIZE}")
|
| 1449 |
+
print(f" STREAM_BATCH_SIZE : {STREAM_BATCH_SIZE} (user: 'de 100 em 100')")
|
| 1450 |
+
print(f" CONHECIMENTO datasets: {len(CONHECIMENTO_DATASETS)}")
|
| 1451 |
+
print(f" PUNICAO dataset : {PUNICAO_DATASET}")
|
| 1452 |
+
print(f" Max samples CONHEC : {MAX_SAMPLES_PER_DATASET_CONHECIMENTO}/dataset")
|
| 1453 |
+
print(f" Max samples PUNICAO : {MAX_SAMPLES_PUNICAO}")
|
| 1454 |
+
print(f" Meta CONHECIMENTO : ≥{META_MINIMA_CONHECIMENTO}")
|
| 1455 |
+
print(f" Meta PUNICAO : ≥{META_MINIMA_PUNICAO}")
|
| 1456 |
+
print(f" SOM grid : {SOM_GRID} ({n_neurons} neurons)")
|
| 1457 |
+
print(f" HIDDEN_DIM : {HIDDEN_DIM}")
|
| 1458 |
+
print(f" VOCAB_SIZE : {VOCAB_SIZE}")
|
| 1459 |
+
print(f" n_hypotheses : {N_HYPOTHESES}")
|
| 1460 |
+
print(f" n_trials : {N_TRIALS}")
|
| 1461 |
+
print(f" hyp_train_steps : {HYP_TRAIN_STEPS}")
|
| 1462 |
+
print(f" Attention : MultiHeadAttention (n_heads=8)")
|
| 1463 |
+
print(f" V65_ENABLE_STREAMING : {os.environ.get('V65_ENABLE_STREAMING')} (REAL)")
|
| 1464 |
+
print(f" Storage critical : {STORAGE_CRITICAL_PCT}%")
|
| 1465 |
+
print(f" Xeon cores : {N_CORES}")
|
| 1466 |
+
print(f" FP16 best TFLOPS : {FP16_BENCH.get('best_tflops', 0.0):.3f}")
|
| 1467 |
+
print("=" * 80 + "\n")
|
| 1468 |
+
|
| 1469 |
+
# 14.1 Verify V2 logic
|
| 1470 |
+
logger.info("[V6.5-V2] Verifying V2 logic (predict + 16 hypotheses + V2 methods)...")
|
| 1471 |
+
verification = verify_v2_logic()
|
| 1472 |
+
print(f"\n--- V2 Logic Verification ---")
|
| 1473 |
+
print(f" PASS: {verification['n_pass']}/{verification['n_pass'] + verification['n_fail']}")
|
| 1474 |
+
for check_name, check_info in verification["checks"].items():
|
| 1475 |
+
status = check_info.get("status", "?")
|
| 1476 |
+
details = check_info.get("details", check_info.get("error", ""))
|
| 1477 |
+
print(f" [{status}] {check_name}: {details[:100]}")
|
| 1478 |
+
|
| 1479 |
+
# 14.2 Initialize KohonenLearningSystemV2 (864 neurons + 16 hypotheses + attention)
|
| 1480 |
+
kls = KohonenLearningSystemV2(
|
| 1481 |
+
vocab_size=VOCAB_SIZE,
|
| 1482 |
+
hidden_dim=HIDDEN_DIM,
|
| 1483 |
+
seq_len=MAX_SEQ_LEN,
|
| 1484 |
+
som_grid=SOM_GRID,
|
| 1485 |
+
alpha0=ALPHA0,
|
| 1486 |
+
sigma0=SIGMA0,
|
| 1487 |
+
lambda_ewc=LAMBDA_EWC,
|
| 1488 |
+
N_start=N_START,
|
| 1489 |
+
dim_choice=DIM_CHOICE,
|
| 1490 |
+
hypothesis_hidden=[512, 256, 128, 64, 32, 16, 8],
|
| 1491 |
+
T_max=T_MAX,
|
| 1492 |
+
enable_vqvae2=False, # V2-dynamic-memory: disabled to save RAM
|
| 1493 |
+
enable_reasoning=True,
|
| 1494 |
+
enable_w8a8=False, # V2-dynamic-memory: disabled to save RAM
|
| 1495 |
+
vqvae2_code_dim=16,
|
| 1496 |
+
vqvae2_num_codes_top=64,
|
| 1497 |
+
vqvae2_num_codes_bot=128,
|
| 1498 |
+
w8a8_alpha=0.5,
|
| 1499 |
+
w8a8_n_bits=8,
|
| 1500 |
+
w8a8_calibration_samples=32,
|
| 1501 |
+
enable_attention=True,
|
| 1502 |
+
attention_n_heads=8,
|
| 1503 |
+
# V2-dynamic parameters (serão adaptados automaticamente)
|
| 1504 |
+
n_hypotheses=N_HYPOTHESES,
|
| 1505 |
+
max_n_hypotheses=MAX_N_HYPOTHESES,
|
| 1506 |
+
min_n_hypotheses=MIN_N_HYPOTHESES,
|
| 1507 |
+
n_trials=N_TRIALS,
|
| 1508 |
+
min_n_trials=MIN_N_TRIALS,
|
| 1509 |
+
max_n_trials=MAX_N_TRIALS,
|
| 1510 |
+
hyp_train_steps=HYP_TRAIN_STEPS,
|
| 1511 |
+
min_hyp_train_steps=MIN_HYP_TRAIN_STEPS,
|
| 1512 |
+
max_hyp_train_steps=MAX_HYP_TRAIN_STEPS,
|
| 1513 |
+
hyp_lr=HYP_LR,
|
| 1514 |
+
hyp_hidden_dim=HYP_HIDDEN_DIM,
|
| 1515 |
+
loss_history_window=LOSS_HISTORY_WINDOW,
|
| 1516 |
+
punishment_window=PUNISHMENT_WINDOW,
|
| 1517 |
+
)
|
| 1518 |
+
logger.info(
|
| 1519 |
+
f"[V6.5-V2-dynamic] KLS V2 initialized: {n_neurons} neurons, "
|
| 1520 |
+
f"hidden={HIDDEN_DIM}, vocab={VOCAB_SIZE}, "
|
| 1521 |
+
f"n_hypotheses={kls.n_hypotheses}/{kls.max_n_hypotheses} "
|
| 1522 |
+
f"(active={kls.hypothesis_ensemble.active_count}), "
|
| 1523 |
+
f"n_trials={kls.n_trials} (limits {kls.min_n_trials}-{kls.max_n_trials}), "
|
| 1524 |
+
f"hyp_train_steps={kls.hyp_train_steps} "
|
| 1525 |
+
f"(limits {kls.min_hyp_train_steps}-{kls.max_hyp_train_steps}), "
|
| 1526 |
+
f"delta_scale={kls.delta_scale.item():.4f}, "
|
| 1527 |
+
f"attention={kls.enable_attention} (n_heads={kls.attention_n_heads}), "
|
| 1528 |
+
f"workers_active={getattr(kls, '_tool_coordinator_workers_active', False)}"
|
| 1529 |
+
)
|
| 1530 |
+
|
| 1531 |
+
# Treina tokenizer com corpus básico PT-BR
|
| 1532 |
+
corpus_inicial = [
|
| 1533 |
+
"o gato dorme na cama", "a casa eh azul", "ele corre rapido",
|
| 1534 |
+
"ela canta uma musica", "o sol nasceu hoje", "nos vamos viajar",
|
| 1535 |
+
"o livro esta na mesa", "a menina brinca no parque",
|
| 1536 |
+
"ola como voce esta", "qual e o seu nome",
|
| 1537 |
+
"calcule dois mais dois", "traduza hello para portugues",
|
| 1538 |
+
"instrucao para resolver o problema", "resposta para a pergunta",
|
| 1539 |
+
"luva de pedreiro tavila", "lula reserva valor",
|
| 1540 |
+
"amazonas forca tarefa vitimas",
|
| 1541 |
+
]
|
| 1542 |
+
kls.tokenizer.fit(corpus_inicial)
|
| 1543 |
+
logger.info(f"[V6.5-V2] Tokenizer fitted with {len(corpus_inicial)} corpus words")
|
| 1544 |
+
|
| 1545 |
+
# HF_TOKEN
|
| 1546 |
+
hf_token = os.environ.get("HF_TOKEN")
|
| 1547 |
+
if not hf_token:
|
| 1548 |
+
logger.warning("[V6.5-V2] HF_TOKEN not set — streaming may fail for gated datasets")
|
| 1549 |
+
else:
|
| 1550 |
+
logger.info(f"[V6.5-V2] HF_TOKEN set: {hf_token[:8]}...")
|
| 1551 |
+
|
| 1552 |
+
# 14.3 Aggressive storage cleanup before training starts
|
| 1553 |
+
logger.info("[V6.5-V2] Aggressive storage cleanup (pre-training)...")
|
| 1554 |
+
try:
|
| 1555 |
+
storage_cleanup_pre = aggressive_storage_cleanup()
|
| 1556 |
+
aggressive_memory_cleanup()
|
| 1557 |
+
logger.info(
|
| 1558 |
+
f"[V6.5-V2] Pre-training cleanup: "
|
| 1559 |
+
f"{storage_cleanup_pre['n_files_removed']} files, "
|
| 1560 |
+
f"{storage_cleanup_pre['mb_freed']:.1f}MB freed"
|
| 1561 |
+
)
|
| 1562 |
+
except Exception as e:
|
| 1563 |
+
logger.warning(f"[V6.5-V2] Pre-training cleanup failed: {e}")
|
| 1564 |
+
aggressive_memory_cleanup()
|
| 1565 |
+
|
| 1566 |
+
# ========================================================================
|
| 1567 |
+
# 14.4 FASE 1 — CONHECIMENTO (8 datasets, sem punição)
|
| 1568 |
+
# ========================================================================
|
| 1569 |
+
logger.info("\n[V6.5-V2] Iniciando FASE 1 — CONHECIMENTO...")
|
| 1570 |
+
conhecimento_result = run_fase_conhecimento(kls, hf_token)
|
| 1571 |
+
V2_PHASES_EVAL_PATH.write_text(
|
| 1572 |
+
json.dumps({"fase_1_conhecimento": conhecimento_result}, indent=2, ensure_ascii=False)
|
| 1573 |
+
)
|
| 1574 |
+
logger.info(
|
| 1575 |
+
f"\n[V6.5-V2] FASE 1 — CONHECIMENTO finalizada: "
|
| 1576 |
+
f"{conhecimento_result['total_samples']} samples "
|
| 1577 |
+
f"(meta: {conhecimento_result['meta_minima']}, "
|
| 1578 |
+
f"atingida: {conhecimento_result['meta_atingida']})"
|
| 1579 |
+
)
|
| 1580 |
+
|
| 1581 |
+
# Salva estados do modelo após CONHECIMENTO
|
| 1582 |
+
save_model_states_for_evaluation(
|
| 1583 |
+
kls=kls,
|
| 1584 |
+
reason="end_of_fase_conhecimento",
|
| 1585 |
+
step=conhecimento_result["n_steps"],
|
| 1586 |
+
total_samples=conhecimento_result["total_samples"],
|
| 1587 |
+
output_path=BIGRU_ROOT / "v6_5_v2_model_states_after_conhecimento.pt",
|
| 1588 |
+
)
|
| 1589 |
+
|
| 1590 |
+
# Aggressive cleanup entre fases
|
| 1591 |
+
aggressive_memory_cleanup()
|
| 1592 |
+
aggressive_storage_cleanup()
|
| 1593 |
+
|
| 1594 |
+
# ========================================================================
|
| 1595 |
+
# 14.5 FASE 2 — TREINAMENTO COM PUNIÇÃO (BrunoN-Dev/corpus-ptbr-v1, 500 samples)
|
| 1596 |
+
# ========================================================================
|
| 1597 |
+
if not conhecimento_result["storage_critical_stopped"]:
|
| 1598 |
+
logger.info("\n[V6.5-V2] Iniciando FASE 2 — TREINAMENTO COM PUNIÇÃO...")
|
| 1599 |
+
punicão_result = run_fase_punicão(kls, hf_token)
|
| 1600 |
+
|
| 1601 |
+
# Atualiza V2_PHASES_EVAL_PATH com ambas as fases
|
| 1602 |
+
phases_eval = {
|
| 1603 |
+
"fase_1_conhecimento": conhecimento_result,
|
| 1604 |
+
"fase_2_treinamento_com_punicão": punicão_result,
|
| 1605 |
+
}
|
| 1606 |
+
V2_PHASES_EVAL_PATH.write_text(
|
| 1607 |
+
json.dumps(phases_eval, indent=2, ensure_ascii=False)
|
| 1608 |
+
)
|
| 1609 |
+
logger.info(
|
| 1610 |
+
f"\n[V6.5-V2] FASE 2 — PUNIÇÃO finalizada: "
|
| 1611 |
+
f"{punicão_result['total_samples']} samples "
|
| 1612 |
+
f"(meta: {punicão_result['meta_minima']}, "
|
| 1613 |
+
f"atingida: {punicão_result['meta_atingida']})"
|
| 1614 |
+
)
|
| 1615 |
+
logger.info(
|
| 1616 |
+
f"[V6.5-V2] Punishment events: {len(punicão_result['punishment_events'])}, "
|
| 1617 |
+
f"Hypotheses trainings: {len(punicão_result['hypotheses_trainings'])}, "
|
| 1618 |
+
f"Delta applications: {len(punicão_result['delta_applications'])}"
|
| 1619 |
+
)
|
| 1620 |
+
else:
|
| 1621 |
+
punicão_result = {
|
| 1622 |
+
"phase": "TREINAMENTO_COM_PUNICAO",
|
| 1623 |
+
"skipped": True,
|
| 1624 |
+
"reason": "storage_critical_stopped_during_conhecimento",
|
| 1625 |
+
}
|
| 1626 |
+
logger.warning("[V6.5-V2] FASE 2 pulada — storage critical durante CONHECIMENTO.")
|
| 1627 |
+
|
| 1628 |
+
# ========================================================================
|
| 1629 |
+
# 14.6 Salvar estados finais do modelo
|
| 1630 |
+
# ========================================================================
|
| 1631 |
+
logger.info("\n[V6.5-V2] Salvando estados finais do modelo...")
|
| 1632 |
+
total_samples_final = (
|
| 1633 |
+
conhecimento_result["total_samples"] + punicão_result.get("total_samples", 0)
|
| 1634 |
+
)
|
| 1635 |
+
save_info = save_model_states_for_evaluation(
|
| 1636 |
+
kls=kls,
|
| 1637 |
+
reason="end_of_training_v2",
|
| 1638 |
+
step=conhecimento_result["n_steps"] + punicão_result.get("n_steps", 0),
|
| 1639 |
+
total_samples=total_samples_final,
|
| 1640 |
+
)
|
| 1641 |
+
|
| 1642 |
+
# ========================================================================
|
| 1643 |
+
# 14.7 Avaliações finais (attention, predict fix, user questions)
|
| 1644 |
+
# ========================================================================
|
| 1645 |
+
logger.info("\n[V6.5-V2] Avaliando attention...")
|
| 1646 |
+
attention_eval = evaluate_attention(kls)
|
| 1647 |
+
ATTENTION_EVAL_PATH.write_text(json.dumps(attention_eval, indent=2, ensure_ascii=False))
|
| 1648 |
+
|
| 1649 |
+
logger.info("[V6.5-V2] Avaliando predict fix (rótulos dinâmicos)...")
|
| 1650 |
+
predict_fix_eval = evaluate_predict_fix(kls)
|
| 1651 |
+
PREDICT_FIX_EVAL_PATH.write_text(json.dumps(predict_fix_eval, indent=2, ensure_ascii=False))
|
| 1652 |
+
|
| 1653 |
+
logger.info("[V6.5-V2] Lançando 3 perguntas SEM AJUDA ao modelo...")
|
| 1654 |
+
user_questions_eval = launch_user_questions_without_help(kls)
|
| 1655 |
+
USER_QUESTIONS_PATH.write_text(json.dumps(user_questions_eval, indent=2, ensure_ascii=False))
|
| 1656 |
+
|
| 1657 |
+
# ========================================================================
|
| 1658 |
+
# 14.8 Relatório final
|
| 1659 |
+
# ========================================================================
|
| 1660 |
+
final_report = {
|
| 1661 |
+
"version": "V6.5-V2",
|
| 1662 |
+
"timestamp": datetime.now().isoformat(),
|
| 1663 |
+
"config": {
|
| 1664 |
+
"som_grid": list(SOM_GRID),
|
| 1665 |
+
"n_neurons": n_neurons,
|
| 1666 |
+
"hidden_dim": HIDDEN_DIM,
|
| 1667 |
+
"vocab_size": VOCAB_SIZE,
|
| 1668 |
+
"n_hypotheses": N_HYPOTHESES,
|
| 1669 |
+
"n_trials": N_TRIALS,
|
| 1670 |
+
"hyp_train_steps": HYP_TRAIN_STEPS,
|
| 1671 |
+
"stream_batch_size": STREAM_BATCH_SIZE,
|
| 1672 |
+
"meta_conhecimento": META_MINIMA_CONHECIMENTO,
|
| 1673 |
+
"meta_punicão": META_MINIMA_PUNICAO,
|
| 1674 |
+
"conhecimento_datasets": CONHECIMENTO_DATASETS,
|
| 1675 |
+
"punicão_dataset": PUNICAO_DATASET,
|
| 1676 |
+
},
|
| 1677 |
+
"xeon_status": XEON_STATUS,
|
| 1678 |
+
"fp16_benchmark": FP16_BENCH,
|
| 1679 |
+
"v2_verification": verification,
|
| 1680 |
+
"fase_1_conhecimento_summary": {
|
| 1681 |
+
"total_samples": conhecimento_result["total_samples"],
|
| 1682 |
+
"meta_atingida": conhecimento_result["meta_atingida"],
|
| 1683 |
+
"elapsed_s": conhecimento_result["elapsed_s"],
|
| 1684 |
+
"storage_critical_stopped": conhecimento_result["storage_critical_stopped"],
|
| 1685 |
+
},
|
| 1686 |
+
"fase_2_punicão_summary": {
|
| 1687 |
+
"total_samples": punicão_result.get("total_samples", 0),
|
| 1688 |
+
"meta_atingida": punicão_result.get("meta_atingida", False),
|
| 1689 |
+
"elapsed_s": punicão_result.get("elapsed_s", 0.0),
|
| 1690 |
+
"punishment_events": len(punicão_result.get("punishment_events", [])),
|
| 1691 |
+
"hypotheses_trainings": len(punicão_result.get("hypotheses_trainings", [])),
|
| 1692 |
+
"delta_applications": len(punicão_result.get("delta_applications", [])),
|
| 1693 |
+
"skipped": punicão_result.get("skipped", False),
|
| 1694 |
+
},
|
| 1695 |
+
"attention_eval_summary": {
|
| 1696 |
+
"active": attention_eval["active"],
|
| 1697 |
+
"logic_functional": attention_eval["logic_functional"],
|
| 1698 |
+
"n_calls": attention_eval["n_calls"],
|
| 1699 |
+
"assessment": attention_eval["assessment"],
|
| 1700 |
+
},
|
| 1701 |
+
"predict_fix_summary": predict_fix_eval["summary"],
|
| 1702 |
+
"user_questions_summary": user_questions_eval["summary"],
|
| 1703 |
+
"model_states_saved_to": str(MODEL_STATES_PATH),
|
| 1704 |
+
"save_info": save_info,
|
| 1705 |
+
"final_v2_metrics": kls.get_v2_metrics(),
|
| 1706 |
+
}
|
| 1707 |
+
REPORT_PATH.write_text(json.dumps(final_report, indent=2, ensure_ascii=False))
|
| 1708 |
+
logger.info(f"\n[V6.5-V2] Relatório final salvo em: {REPORT_PATH}")
|
| 1709 |
+
|
| 1710 |
+
# Copia arquivos relevantes para download/
|
| 1711 |
+
try:
|
| 1712 |
+
for src in [REPORT_PATH, USER_QUESTIONS_PATH, MODEL_STATES_PATH,
|
| 1713 |
+
V2_PHASES_EVAL_PATH, PREDICT_FIX_EVAL_PATH, ATTENTION_EVAL_PATH,
|
| 1714 |
+
BIGRU_ROOT / "v6_5_v2_model_states_after_conhecimento.pt"]:
|
| 1715 |
+
if src.exists():
|
| 1716 |
+
dst = DOWNLOAD_DIR / src.name
|
| 1717 |
+
shutil.copy2(src, dst)
|
| 1718 |
+
logger.info(f"[V6.5-V2] Copied {src.name} → {dst}")
|
| 1719 |
+
except Exception as e:
|
| 1720 |
+
logger.warning(f"[V6.5-V2] Failed to copy files to download/: {e}")
|
| 1721 |
+
|
| 1722 |
+
# ========================================================================
|
| 1723 |
+
# 14.9 HF BATCH UPLOAD — enviar scripts + estado + modelo ao HF em lote
|
| 1724 |
+
# ========================================================================
|
| 1725 |
+
# User requirement: "após concluir enviar scripts e arquivos e estado
|
| 1726 |
+
# (e treinamento para permitir continuar novo treinamento) do modelo
|
| 1727 |
+
# testados e aprovados sobrescrevendo os antigos desatualizados"
|
| 1728 |
+
upload_report_path = BIGRU_ROOT / "v6_5_v2_upload_report.json"
|
| 1729 |
+
hf_upload_result: Dict[str, Any] = {"uploaded": False, "reason": "skipped"}
|
| 1730 |
+
if hf_token:
|
| 1731 |
+
logger.info("\n[V6.5-V2] Coletando arquivos para upload HF em LOTE...")
|
| 1732 |
+
|
| 1733 |
+
# Scripts a enviar (sobrescrevem antigos no HF)
|
| 1734 |
+
scripts_to_upload: List[Path] = [
|
| 1735 |
+
BIGRU_ROOT / "scripts" / "train_v6_5_v2.py",
|
| 1736 |
+
SRC_ROOT / "bigru_t" / "model" / "kohonen_learning_system.py",
|
| 1737 |
+
SRC_ROOT / "bigru_t" / "model" / "hyp_t.py",
|
| 1738 |
+
SRC_ROOT / "bigru_t" / "data" / "streaming_datasets.py",
|
| 1739 |
+
SRC_ROOT / "bigru_t" / "utils" / "xeon_runtime.py",
|
| 1740 |
+
]
|
| 1741 |
+
# Relatórios + estados
|
| 1742 |
+
outputs_to_upload: List[Path] = [
|
| 1743 |
+
REPORT_PATH,
|
| 1744 |
+
MODEL_STATES_PATH,
|
| 1745 |
+
V2_PHASES_EVAL_PATH,
|
| 1746 |
+
PREDICT_FIX_EVAL_PATH,
|
| 1747 |
+
ATTENTION_EVAL_PATH,
|
| 1748 |
+
USER_QUESTIONS_PATH,
|
| 1749 |
+
BIGRU_ROOT / "v6_5_v2_model_states_after_conhecimento.pt",
|
| 1750 |
+
]
|
| 1751 |
+
# Filtra os que existem
|
| 1752 |
+
all_files: List[Path] = []
|
| 1753 |
+
for p in scripts_to_upload + outputs_to_upload:
|
| 1754 |
+
if p.exists():
|
| 1755 |
+
all_files.append(p)
|
| 1756 |
+
else:
|
| 1757 |
+
logger.warning(f"[V6.5-V2] Upload file not found: {p}")
|
| 1758 |
+
|
| 1759 |
+
# Apaga HF_TOKEN dos scripts ANTES do upload (não enviar tokens)
|
| 1760 |
+
scrub_result = scrub_hf_token_from_scripts(BIGRU_ROOT / "scripts")
|
| 1761 |
+
scrub_result_src = scrub_hf_token_from_scripts(SRC_ROOT)
|
| 1762 |
+
logger.info(
|
| 1763 |
+
f"[V6.5-V2] Token scrub: scripts={scrub_result}, src={scrub_result_src}"
|
| 1764 |
+
)
|
| 1765 |
+
|
| 1766 |
+
# Upload em LOTE
|
| 1767 |
+
hf_upload_result = upload_to_hf_batch(
|
| 1768 |
+
hf_token=hf_token,
|
| 1769 |
+
files_to_upload=all_files,
|
| 1770 |
+
repo_id=HF_REPO_ID,
|
| 1771 |
+
repo_type="model",
|
| 1772 |
+
)
|
| 1773 |
+
upload_report_path.write_text(
|
| 1774 |
+
json.dumps(hf_upload_result, indent=2, ensure_ascii=False)
|
| 1775 |
+
)
|
| 1776 |
+
logger.info(f"[V6.5-V2] HF upload report saved: {upload_report_path}")
|
| 1777 |
+
if upload_report_path.exists():
|
| 1778 |
+
shutil.copy2(upload_report_path, DOWNLOAD_DIR / upload_report_path.name)
|
| 1779 |
+
else:
|
| 1780 |
+
logger.warning("[V6.5-V2] HF_TOKEN não disponível — pulando upload HF.")
|
| 1781 |
+
|
| 1782 |
+
# ========================================================================
|
| 1783 |
+
# 14.10 LIMPEZA HF_TOKEN do ambiente (user requirement)
|
| 1784 |
+
# ========================================================================
|
| 1785 |
+
logger.info("\n[V6.5-V2] Limpando HF_TOKEN do ambiente...")
|
| 1786 |
+
if "HF_TOKEN" in os.environ:
|
| 1787 |
+
del os.environ["HF_TOKEN"]
|
| 1788 |
+
logger.info("[V6.5-V2] HF_TOKEN removido do ambiente.")
|
| 1789 |
+
if "HUGGING_FACE_HUB_TOKEN" in os.environ:
|
| 1790 |
+
del os.environ["HUGGING_FACE_HUB_TOKEN"]
|
| 1791 |
+
logger.info("[V6.5-V2] HUGGING_FACE_HUB_TOKEN removido do ambiente.")
|
| 1792 |
+
# Re-scrub após o upload (segurança extra)
|
| 1793 |
+
final_scrub = scrub_hf_token_from_scripts(BIGRU_ROOT / "scripts")
|
| 1794 |
+
final_scrub_src = scrub_hf_token_from_scripts(SRC_ROOT)
|
| 1795 |
+
final_scrub_proj = scrub_hf_token_from_scripts(PROJECT_ROOT / "scripts")
|
| 1796 |
+
|
| 1797 |
+
# ========================================================================
|
| 1798 |
+
# 14.11 LIMPEZA final de armazenamento e worklog
|
| 1799 |
+
# ========================================================================
|
| 1800 |
+
logger.info("\n[V6.5-V2] Limpeza final de armazenamento...")
|
| 1801 |
+
final_storage_cleanup = aggressive_storage_cleanup()
|
| 1802 |
+
aggressive_memory_cleanup()
|
| 1803 |
+
|
| 1804 |
+
print("\n" + "=" * 80)
|
| 1805 |
+
print("V6.5-V2-dynamic — TREINAMENTO CONCLUÍDO")
|
| 1806 |
+
print("=" * 80)
|
| 1807 |
+
print(f" FASE 1 CONHECIMENTO : {conhecimento_result['total_samples']} samples "
|
| 1808 |
+
f"(meta: {conhecimento_result['meta_atingida']})")
|
| 1809 |
+
print(f" FASE 2 PUNICAO : {punicão_result.get('total_samples', 0)} samples "
|
| 1810 |
+
f"(meta: {punicão_result.get('meta_atingida', False)})")
|
| 1811 |
+
print(f" Punishment events : {len(punicão_result.get('punishment_events', []))}")
|
| 1812 |
+
print(f" Delta applications : {len(punicão_result.get('delta_applications', []))}")
|
| 1813 |
+
print(f" Attention functional: {attention_eval['logic_functional']}")
|
| 1814 |
+
print(f" Predict fix verified: {predict_fix_eval['summary']['predict_fix_verified']}")
|
| 1815 |
+
print(f" User questions ans : {user_questions_eval['summary']['n_with_answer']}/3")
|
| 1816 |
+
print(f" HF upload : {hf_upload_result.get('uploaded', False)} "
|
| 1817 |
+
f"({hf_upload_result.get('n_files', 0)} files)")
|
| 1818 |
+
print(f" HF_TOKEN cleaned : True (env + scripts)")
|
| 1819 |
+
print(f" Storage cleanup : {final_storage_cleanup['n_files_removed']} files, "
|
| 1820 |
+
f"{final_storage_cleanup['mb_freed']:.1f}MB freed")
|
| 1821 |
+
print(f" Final n_hypotheses : {kls.n_hypotheses} (active={kls.hypothesis_ensemble.active_count})")
|
| 1822 |
+
print(f" Final n_trials : {kls.n_trials}")
|
| 1823 |
+
print(f" Final hyp_steps : {kls.hyp_train_steps}")
|
| 1824 |
+
print(f" N adaptations : {len(kls.get_adaptation_log())}")
|
| 1825 |
+
print("=" * 80 + "\n")
|
| 1826 |
+
|
| 1827 |
+
return 0
|
| 1828 |
+
|
| 1829 |
+
|
| 1830 |
+
if __name__ == "__main__":
|
| 1831 |
+
sys.exit(main())
|
v6_5_v2_attention_eval.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"evaluation": "attention_v65_v2",
|
| 3 |
+
"user_requirement": "verificar se o mecanismo de atenção está ativo e acessado logicamente funcional",
|
| 4 |
+
"metrics": {
|
| 5 |
+
"active": true,
|
| 6 |
+
"n_calls": 3441,
|
| 7 |
+
"n_errors": 0,
|
| 8 |
+
"last_norm_in": 54.769012451171875,
|
| 9 |
+
"last_norm_out": 56.71458053588867,
|
| 10 |
+
"last_attn_activated": true,
|
| 11 |
+
"last_attn_diff_norm": 56.80364227294922,
|
| 12 |
+
"n_heads": 8,
|
| 13 |
+
"logic_functional": true
|
| 14 |
+
},
|
| 15 |
+
"active": true,
|
| 16 |
+
"logic_functional": true,
|
| 17 |
+
"n_calls": 3441,
|
| 18 |
+
"n_errors": 0,
|
| 19 |
+
"n_heads": 8,
|
| 20 |
+
"assessment": "PASS"
|
| 21 |
+
}
|
v6_5_v2_model_states.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:43a1a29a3556c5960c661c103aecb3322ea32b50d7afc45d254d21b203f98f20
|
| 3 |
+
size 40959502
|
v6_5_v2_model_states_after_conhecimento.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4bc13a9ef5d19ba56d3eecee92716f76696ffcb7924b0b64c981327e066922ec
|
| 3 |
+
size 40963993
|
v6_5_v2_phases_eval.json
ADDED
|
@@ -0,0 +1,784 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fase_1_conhecimento": {
|
| 3 |
+
"phase": "CONHECIMENTO",
|
| 4 |
+
"total_samples": 3300,
|
| 5 |
+
"meta_minima": 6000,
|
| 6 |
+
"meta_atingida": false,
|
| 7 |
+
"samples_per_dataset": {
|
| 8 |
+
"dominguesm/restore-punctuation-ptbr-dataset": 800,
|
| 9 |
+
"carolina-c4ai/corpus-carolina": 800,
|
| 10 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1": 800,
|
| 11 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset": 800,
|
| 12 |
+
"adalbertojunior/punctuation-ptbr": 100,
|
| 13 |
+
"iara-project/news-articles-ptbr-dataset": 0,
|
| 14 |
+
"manoela/noticias_ptbr": 0,
|
| 15 |
+
"BrunoN-Dev/corpus-ptbr-v1": 0
|
| 16 |
+
},
|
| 17 |
+
"streaming_failures": {
|
| 18 |
+
"dominguesm/restore-punctuation-ptbr-dataset": 0,
|
| 19 |
+
"carolina-c4ai/corpus-carolina": 0,
|
| 20 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1": 0,
|
| 21 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset": 0,
|
| 22 |
+
"adalbertojunior/punctuation-ptbr": 0,
|
| 23 |
+
"iara-project/news-articles-ptbr-dataset": 0,
|
| 24 |
+
"manoela/noticias_ptbr": 0,
|
| 25 |
+
"BrunoN-Dev/corpus-ptbr-v1": 0
|
| 26 |
+
},
|
| 27 |
+
"storage_critical_stopped": true,
|
| 28 |
+
"elapsed_s": 425.32095551490784,
|
| 29 |
+
"n_steps": 225,
|
| 30 |
+
"n_chunks": 33,
|
| 31 |
+
"accuracies_log": [
|
| 32 |
+
{
|
| 33 |
+
"step": 175,
|
| 34 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 35 |
+
"chunk_idx": 26,
|
| 36 |
+
"batch_size": 16,
|
| 37 |
+
"accuracy": 0.5514705882352942,
|
| 38 |
+
"phase": "CONHECIMENTO",
|
| 39 |
+
"buffer_size": 272,
|
| 40 |
+
"training_ready": true,
|
| 41 |
+
"elapsed_ms": 260.0207328796387
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"step": 176,
|
| 45 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 46 |
+
"chunk_idx": 26,
|
| 47 |
+
"batch_size": 16,
|
| 48 |
+
"accuracy": 0.5208333333333334,
|
| 49 |
+
"phase": "CONHECIMENTO",
|
| 50 |
+
"buffer_size": 288,
|
| 51 |
+
"training_ready": true,
|
| 52 |
+
"elapsed_ms": 269.819974899292
|
| 53 |
+
},
|
| 54 |
+
{
|
| 55 |
+
"step": 177,
|
| 56 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 57 |
+
"chunk_idx": 26,
|
| 58 |
+
"batch_size": 16,
|
| 59 |
+
"accuracy": 0.506578947368421,
|
| 60 |
+
"phase": "CONHECIMENTO",
|
| 61 |
+
"buffer_size": 304,
|
| 62 |
+
"training_ready": true,
|
| 63 |
+
"elapsed_ms": 276.5047550201416
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"step": 178,
|
| 67 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 68 |
+
"chunk_idx": 26,
|
| 69 |
+
"batch_size": 16,
|
| 70 |
+
"accuracy": 0.53125,
|
| 71 |
+
"phase": "CONHECIMENTO",
|
| 72 |
+
"buffer_size": 320,
|
| 73 |
+
"training_ready": true,
|
| 74 |
+
"elapsed_ms": 286.62753105163574
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"step": 179,
|
| 78 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 79 |
+
"chunk_idx": 26,
|
| 80 |
+
"batch_size": 16,
|
| 81 |
+
"accuracy": 0.5535714285714286,
|
| 82 |
+
"phase": "CONHECIMENTO",
|
| 83 |
+
"buffer_size": 336,
|
| 84 |
+
"training_ready": true,
|
| 85 |
+
"elapsed_ms": 285.3672504425049
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"step": 180,
|
| 89 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 90 |
+
"chunk_idx": 26,
|
| 91 |
+
"batch_size": 16,
|
| 92 |
+
"accuracy": 0.5738636363636364,
|
| 93 |
+
"phase": "CONHECIMENTO",
|
| 94 |
+
"buffer_size": 352,
|
| 95 |
+
"training_ready": true,
|
| 96 |
+
"elapsed_ms": 312.63208389282227
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"step": 181,
|
| 100 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 101 |
+
"chunk_idx": 26,
|
| 102 |
+
"batch_size": 4,
|
| 103 |
+
"accuracy": 0.5786516853932584,
|
| 104 |
+
"phase": "CONHECIMENTO",
|
| 105 |
+
"buffer_size": 356,
|
| 106 |
+
"training_ready": true,
|
| 107 |
+
"elapsed_ms": 304.9945831298828
|
| 108 |
+
},
|
| 109 |
+
{
|
| 110 |
+
"step": 182,
|
| 111 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 112 |
+
"chunk_idx": 27,
|
| 113 |
+
"batch_size": 16,
|
| 114 |
+
"accuracy": 0.8088235294117647,
|
| 115 |
+
"phase": "CONHECIMENTO",
|
| 116 |
+
"buffer_size": 272,
|
| 117 |
+
"training_ready": true,
|
| 118 |
+
"elapsed_ms": 260.9591484069824
|
| 119 |
+
},
|
| 120 |
+
{
|
| 121 |
+
"step": 183,
|
| 122 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 123 |
+
"chunk_idx": 27,
|
| 124 |
+
"batch_size": 16,
|
| 125 |
+
"accuracy": 0.8194444444444444,
|
| 126 |
+
"phase": "CONHECIMENTO",
|
| 127 |
+
"buffer_size": 288,
|
| 128 |
+
"training_ready": true,
|
| 129 |
+
"elapsed_ms": 293.58363151550293
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"step": 184,
|
| 133 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 134 |
+
"chunk_idx": 27,
|
| 135 |
+
"batch_size": 16,
|
| 136 |
+
"accuracy": 0.8289473684210527,
|
| 137 |
+
"phase": "CONHECIMENTO",
|
| 138 |
+
"buffer_size": 304,
|
| 139 |
+
"training_ready": true,
|
| 140 |
+
"elapsed_ms": 275.958776473999
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
"step": 185,
|
| 144 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 145 |
+
"chunk_idx": 27,
|
| 146 |
+
"batch_size": 16,
|
| 147 |
+
"accuracy": 0.8375,
|
| 148 |
+
"phase": "CONHECIMENTO",
|
| 149 |
+
"buffer_size": 320,
|
| 150 |
+
"training_ready": true,
|
| 151 |
+
"elapsed_ms": 290.9085750579834
|
| 152 |
+
},
|
| 153 |
+
{
|
| 154 |
+
"step": 186,
|
| 155 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 156 |
+
"chunk_idx": 27,
|
| 157 |
+
"batch_size": 16,
|
| 158 |
+
"accuracy": 0.8452380952380952,
|
| 159 |
+
"phase": "CONHECIMENTO",
|
| 160 |
+
"buffer_size": 336,
|
| 161 |
+
"training_ready": true,
|
| 162 |
+
"elapsed_ms": 438.265323638916
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"step": 187,
|
| 166 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 167 |
+
"chunk_idx": 27,
|
| 168 |
+
"batch_size": 16,
|
| 169 |
+
"accuracy": 0.8522727272727273,
|
| 170 |
+
"phase": "CONHECIMENTO",
|
| 171 |
+
"buffer_size": 352,
|
| 172 |
+
"training_ready": true,
|
| 173 |
+
"elapsed_ms": 363.4645938873291
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"step": 188,
|
| 177 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 178 |
+
"chunk_idx": 27,
|
| 179 |
+
"batch_size": 4,
|
| 180 |
+
"accuracy": 0.8539325842696629,
|
| 181 |
+
"phase": "CONHECIMENTO",
|
| 182 |
+
"buffer_size": 356,
|
| 183 |
+
"training_ready": true,
|
| 184 |
+
"elapsed_ms": 308.2740306854248
|
| 185 |
+
},
|
| 186 |
+
{
|
| 187 |
+
"step": 189,
|
| 188 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 189 |
+
"chunk_idx": 28,
|
| 190 |
+
"batch_size": 16,
|
| 191 |
+
"accuracy": 1.0,
|
| 192 |
+
"phase": "CONHECIMENTO",
|
| 193 |
+
"buffer_size": 272,
|
| 194 |
+
"training_ready": true,
|
| 195 |
+
"elapsed_ms": 387.5901699066162
|
| 196 |
+
},
|
| 197 |
+
{
|
| 198 |
+
"step": 190,
|
| 199 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 200 |
+
"chunk_idx": 28,
|
| 201 |
+
"batch_size": 16,
|
| 202 |
+
"accuracy": 1.0,
|
| 203 |
+
"phase": "CONHECIMENTO",
|
| 204 |
+
"buffer_size": 288,
|
| 205 |
+
"training_ready": true,
|
| 206 |
+
"elapsed_ms": 268.2316303253174
|
| 207 |
+
},
|
| 208 |
+
{
|
| 209 |
+
"step": 191,
|
| 210 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 211 |
+
"chunk_idx": 28,
|
| 212 |
+
"batch_size": 16,
|
| 213 |
+
"accuracy": 1.0,
|
| 214 |
+
"phase": "CONHECIMENTO",
|
| 215 |
+
"buffer_size": 304,
|
| 216 |
+
"training_ready": true,
|
| 217 |
+
"elapsed_ms": 279.0110111236572
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"step": 192,
|
| 221 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 222 |
+
"chunk_idx": 28,
|
| 223 |
+
"batch_size": 16,
|
| 224 |
+
"accuracy": 1.0,
|
| 225 |
+
"phase": "CONHECIMENTO",
|
| 226 |
+
"buffer_size": 320,
|
| 227 |
+
"training_ready": true,
|
| 228 |
+
"elapsed_ms": 561.1886978149414
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"step": 193,
|
| 232 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 233 |
+
"chunk_idx": 28,
|
| 234 |
+
"batch_size": 16,
|
| 235 |
+
"accuracy": 1.0,
|
| 236 |
+
"phase": "CONHECIMENTO",
|
| 237 |
+
"buffer_size": 336,
|
| 238 |
+
"training_ready": true,
|
| 239 |
+
"elapsed_ms": 361.0963821411133
|
| 240 |
+
},
|
| 241 |
+
{
|
| 242 |
+
"step": 194,
|
| 243 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 244 |
+
"chunk_idx": 28,
|
| 245 |
+
"batch_size": 16,
|
| 246 |
+
"accuracy": 1.0,
|
| 247 |
+
"phase": "CONHECIMENTO",
|
| 248 |
+
"buffer_size": 352,
|
| 249 |
+
"training_ready": true,
|
| 250 |
+
"elapsed_ms": 353.18779945373535
|
| 251 |
+
},
|
| 252 |
+
{
|
| 253 |
+
"step": 195,
|
| 254 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 255 |
+
"chunk_idx": 28,
|
| 256 |
+
"batch_size": 4,
|
| 257 |
+
"accuracy": 1.0,
|
| 258 |
+
"phase": "CONHECIMENTO",
|
| 259 |
+
"buffer_size": 356,
|
| 260 |
+
"training_ready": true,
|
| 261 |
+
"elapsed_ms": 302.43706703186035
|
| 262 |
+
},
|
| 263 |
+
{
|
| 264 |
+
"step": 196,
|
| 265 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 266 |
+
"chunk_idx": 29,
|
| 267 |
+
"batch_size": 16,
|
| 268 |
+
"accuracy": 1.0,
|
| 269 |
+
"phase": "CONHECIMENTO",
|
| 270 |
+
"buffer_size": 272,
|
| 271 |
+
"training_ready": true,
|
| 272 |
+
"elapsed_ms": 275.22897720336914
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"step": 197,
|
| 276 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 277 |
+
"chunk_idx": 29,
|
| 278 |
+
"batch_size": 16,
|
| 279 |
+
"accuracy": 1.0,
|
| 280 |
+
"phase": "CONHECIMENTO",
|
| 281 |
+
"buffer_size": 288,
|
| 282 |
+
"training_ready": true,
|
| 283 |
+
"elapsed_ms": 405.1165580749512
|
| 284 |
+
},
|
| 285 |
+
{
|
| 286 |
+
"step": 198,
|
| 287 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 288 |
+
"chunk_idx": 29,
|
| 289 |
+
"batch_size": 16,
|
| 290 |
+
"accuracy": 1.0,
|
| 291 |
+
"phase": "CONHECIMENTO",
|
| 292 |
+
"buffer_size": 304,
|
| 293 |
+
"training_ready": true,
|
| 294 |
+
"elapsed_ms": 280.89165687561035
|
| 295 |
+
},
|
| 296 |
+
{
|
| 297 |
+
"step": 199,
|
| 298 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 299 |
+
"chunk_idx": 29,
|
| 300 |
+
"batch_size": 16,
|
| 301 |
+
"accuracy": 1.0,
|
| 302 |
+
"phase": "CONHECIMENTO",
|
| 303 |
+
"buffer_size": 320,
|
| 304 |
+
"training_ready": true,
|
| 305 |
+
"elapsed_ms": 294.2771911621094
|
| 306 |
+
},
|
| 307 |
+
{
|
| 308 |
+
"step": 200,
|
| 309 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 310 |
+
"chunk_idx": 29,
|
| 311 |
+
"batch_size": 16,
|
| 312 |
+
"accuracy": 1.0,
|
| 313 |
+
"phase": "CONHECIMENTO",
|
| 314 |
+
"buffer_size": 336,
|
| 315 |
+
"training_ready": true,
|
| 316 |
+
"elapsed_ms": 341.6149616241455
|
| 317 |
+
},
|
| 318 |
+
{
|
| 319 |
+
"step": 201,
|
| 320 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 321 |
+
"chunk_idx": 29,
|
| 322 |
+
"batch_size": 16,
|
| 323 |
+
"accuracy": 1.0,
|
| 324 |
+
"phase": "CONHECIMENTO",
|
| 325 |
+
"buffer_size": 352,
|
| 326 |
+
"training_ready": true,
|
| 327 |
+
"elapsed_ms": 612.4014854431152
|
| 328 |
+
},
|
| 329 |
+
{
|
| 330 |
+
"step": 202,
|
| 331 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 332 |
+
"chunk_idx": 29,
|
| 333 |
+
"batch_size": 4,
|
| 334 |
+
"accuracy": 1.0,
|
| 335 |
+
"phase": "CONHECIMENTO",
|
| 336 |
+
"buffer_size": 356,
|
| 337 |
+
"training_ready": true,
|
| 338 |
+
"elapsed_ms": 304.2721748352051
|
| 339 |
+
},
|
| 340 |
+
{
|
| 341 |
+
"step": 203,
|
| 342 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 343 |
+
"chunk_idx": 30,
|
| 344 |
+
"batch_size": 16,
|
| 345 |
+
"accuracy": 1.0,
|
| 346 |
+
"phase": "CONHECIMENTO",
|
| 347 |
+
"buffer_size": 272,
|
| 348 |
+
"training_ready": true,
|
| 349 |
+
"elapsed_ms": 261.81983947753906
|
| 350 |
+
},
|
| 351 |
+
{
|
| 352 |
+
"step": 204,
|
| 353 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 354 |
+
"chunk_idx": 30,
|
| 355 |
+
"batch_size": 16,
|
| 356 |
+
"accuracy": 1.0,
|
| 357 |
+
"phase": "CONHECIMENTO",
|
| 358 |
+
"buffer_size": 288,
|
| 359 |
+
"training_ready": true,
|
| 360 |
+
"elapsed_ms": 264.61100578308105
|
| 361 |
+
},
|
| 362 |
+
{
|
| 363 |
+
"step": 205,
|
| 364 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 365 |
+
"chunk_idx": 30,
|
| 366 |
+
"batch_size": 16,
|
| 367 |
+
"accuracy": 1.0,
|
| 368 |
+
"phase": "CONHECIMENTO",
|
| 369 |
+
"buffer_size": 304,
|
| 370 |
+
"training_ready": true,
|
| 371 |
+
"elapsed_ms": 274.2750644683838
|
| 372 |
+
},
|
| 373 |
+
{
|
| 374 |
+
"step": 206,
|
| 375 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 376 |
+
"chunk_idx": 30,
|
| 377 |
+
"batch_size": 16,
|
| 378 |
+
"accuracy": 1.0,
|
| 379 |
+
"phase": "CONHECIMENTO",
|
| 380 |
+
"buffer_size": 320,
|
| 381 |
+
"training_ready": true,
|
| 382 |
+
"elapsed_ms": 291.9497489929199
|
| 383 |
+
},
|
| 384 |
+
{
|
| 385 |
+
"step": 207,
|
| 386 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 387 |
+
"chunk_idx": 30,
|
| 388 |
+
"batch_size": 16,
|
| 389 |
+
"accuracy": 1.0,
|
| 390 |
+
"phase": "CONHECIMENTO",
|
| 391 |
+
"buffer_size": 336,
|
| 392 |
+
"training_ready": true,
|
| 393 |
+
"elapsed_ms": 409.27672386169434
|
| 394 |
+
},
|
| 395 |
+
{
|
| 396 |
+
"step": 208,
|
| 397 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 398 |
+
"chunk_idx": 30,
|
| 399 |
+
"batch_size": 16,
|
| 400 |
+
"accuracy": 1.0,
|
| 401 |
+
"phase": "CONHECIMENTO",
|
| 402 |
+
"buffer_size": 352,
|
| 403 |
+
"training_ready": true,
|
| 404 |
+
"elapsed_ms": 300.47035217285156
|
| 405 |
+
},
|
| 406 |
+
{
|
| 407 |
+
"step": 209,
|
| 408 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 409 |
+
"chunk_idx": 30,
|
| 410 |
+
"batch_size": 4,
|
| 411 |
+
"accuracy": 1.0,
|
| 412 |
+
"phase": "CONHECIMENTO",
|
| 413 |
+
"buffer_size": 356,
|
| 414 |
+
"training_ready": true,
|
| 415 |
+
"elapsed_ms": 296.6763973236084
|
| 416 |
+
},
|
| 417 |
+
{
|
| 418 |
+
"step": 210,
|
| 419 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 420 |
+
"chunk_idx": 31,
|
| 421 |
+
"batch_size": 16,
|
| 422 |
+
"accuracy": 1.0,
|
| 423 |
+
"phase": "CONHECIMENTO",
|
| 424 |
+
"buffer_size": 272,
|
| 425 |
+
"training_ready": true,
|
| 426 |
+
"elapsed_ms": 253.9806365966797
|
| 427 |
+
},
|
| 428 |
+
{
|
| 429 |
+
"step": 211,
|
| 430 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 431 |
+
"chunk_idx": 31,
|
| 432 |
+
"batch_size": 16,
|
| 433 |
+
"accuracy": 1.0,
|
| 434 |
+
"phase": "CONHECIMENTO",
|
| 435 |
+
"buffer_size": 288,
|
| 436 |
+
"training_ready": true,
|
| 437 |
+
"elapsed_ms": 234.45916175842285
|
| 438 |
+
},
|
| 439 |
+
{
|
| 440 |
+
"step": 212,
|
| 441 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 442 |
+
"chunk_idx": 31,
|
| 443 |
+
"batch_size": 16,
|
| 444 |
+
"accuracy": 1.0,
|
| 445 |
+
"phase": "CONHECIMENTO",
|
| 446 |
+
"buffer_size": 304,
|
| 447 |
+
"training_ready": true,
|
| 448 |
+
"elapsed_ms": 271.76856994628906
|
| 449 |
+
},
|
| 450 |
+
{
|
| 451 |
+
"step": 213,
|
| 452 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 453 |
+
"chunk_idx": 31,
|
| 454 |
+
"batch_size": 16,
|
| 455 |
+
"accuracy": 1.0,
|
| 456 |
+
"phase": "CONHECIMENTO",
|
| 457 |
+
"buffer_size": 320,
|
| 458 |
+
"training_ready": true,
|
| 459 |
+
"elapsed_ms": 292.76251792907715
|
| 460 |
+
},
|
| 461 |
+
{
|
| 462 |
+
"step": 214,
|
| 463 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 464 |
+
"chunk_idx": 31,
|
| 465 |
+
"batch_size": 16,
|
| 466 |
+
"accuracy": 1.0,
|
| 467 |
+
"phase": "CONHECIMENTO",
|
| 468 |
+
"buffer_size": 336,
|
| 469 |
+
"training_ready": true,
|
| 470 |
+
"elapsed_ms": 297.0712184906006
|
| 471 |
+
},
|
| 472 |
+
{
|
| 473 |
+
"step": 215,
|
| 474 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 475 |
+
"chunk_idx": 31,
|
| 476 |
+
"batch_size": 16,
|
| 477 |
+
"accuracy": 1.0,
|
| 478 |
+
"phase": "CONHECIMENTO",
|
| 479 |
+
"buffer_size": 352,
|
| 480 |
+
"training_ready": true,
|
| 481 |
+
"elapsed_ms": 329.21457290649414
|
| 482 |
+
},
|
| 483 |
+
{
|
| 484 |
+
"step": 216,
|
| 485 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 486 |
+
"chunk_idx": 31,
|
| 487 |
+
"batch_size": 4,
|
| 488 |
+
"accuracy": 1.0,
|
| 489 |
+
"phase": "CONHECIMENTO",
|
| 490 |
+
"buffer_size": 356,
|
| 491 |
+
"training_ready": true,
|
| 492 |
+
"elapsed_ms": 318.44639778137207
|
| 493 |
+
},
|
| 494 |
+
{
|
| 495 |
+
"step": 217,
|
| 496 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 497 |
+
"chunk_idx": 32,
|
| 498 |
+
"batch_size": 16,
|
| 499 |
+
"accuracy": 1.0,
|
| 500 |
+
"phase": "CONHECIMENTO",
|
| 501 |
+
"buffer_size": 272,
|
| 502 |
+
"training_ready": true,
|
| 503 |
+
"elapsed_ms": 367.6486015319824
|
| 504 |
+
},
|
| 505 |
+
{
|
| 506 |
+
"step": 218,
|
| 507 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 508 |
+
"chunk_idx": 32,
|
| 509 |
+
"batch_size": 16,
|
| 510 |
+
"accuracy": 1.0,
|
| 511 |
+
"phase": "CONHECIMENTO",
|
| 512 |
+
"buffer_size": 288,
|
| 513 |
+
"training_ready": true,
|
| 514 |
+
"elapsed_ms": 270.40815353393555
|
| 515 |
+
},
|
| 516 |
+
{
|
| 517 |
+
"step": 219,
|
| 518 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 519 |
+
"chunk_idx": 32,
|
| 520 |
+
"batch_size": 16,
|
| 521 |
+
"accuracy": 1.0,
|
| 522 |
+
"phase": "CONHECIMENTO",
|
| 523 |
+
"buffer_size": 304,
|
| 524 |
+
"training_ready": true,
|
| 525 |
+
"elapsed_ms": 289.8850440979004
|
| 526 |
+
},
|
| 527 |
+
{
|
| 528 |
+
"step": 220,
|
| 529 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 530 |
+
"chunk_idx": 32,
|
| 531 |
+
"batch_size": 16,
|
| 532 |
+
"accuracy": 1.0,
|
| 533 |
+
"phase": "CONHECIMENTO",
|
| 534 |
+
"buffer_size": 320,
|
| 535 |
+
"training_ready": true,
|
| 536 |
+
"elapsed_ms": 294.964075088501
|
| 537 |
+
},
|
| 538 |
+
{
|
| 539 |
+
"step": 221,
|
| 540 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 541 |
+
"chunk_idx": 32,
|
| 542 |
+
"batch_size": 16,
|
| 543 |
+
"accuracy": 1.0,
|
| 544 |
+
"phase": "CONHECIMENTO",
|
| 545 |
+
"buffer_size": 336,
|
| 546 |
+
"training_ready": true,
|
| 547 |
+
"elapsed_ms": 304.9020767211914
|
| 548 |
+
},
|
| 549 |
+
{
|
| 550 |
+
"step": 222,
|
| 551 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 552 |
+
"chunk_idx": 32,
|
| 553 |
+
"batch_size": 16,
|
| 554 |
+
"accuracy": 1.0,
|
| 555 |
+
"phase": "CONHECIMENTO",
|
| 556 |
+
"buffer_size": 352,
|
| 557 |
+
"training_ready": true,
|
| 558 |
+
"elapsed_ms": 395.02906799316406
|
| 559 |
+
},
|
| 560 |
+
{
|
| 561 |
+
"step": 223,
|
| 562 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 563 |
+
"chunk_idx": 32,
|
| 564 |
+
"batch_size": 4,
|
| 565 |
+
"accuracy": 1.0,
|
| 566 |
+
"phase": "CONHECIMENTO",
|
| 567 |
+
"buffer_size": 356,
|
| 568 |
+
"training_ready": true,
|
| 569 |
+
"elapsed_ms": 313.39168548583984
|
| 570 |
+
},
|
| 571 |
+
{
|
| 572 |
+
"step": 224,
|
| 573 |
+
"dataset": "adalbertojunior/punctuation-ptbr",
|
| 574 |
+
"chunk_idx": 33,
|
| 575 |
+
"batch_size": 16,
|
| 576 |
+
"accuracy": 0.9448529411764706,
|
| 577 |
+
"phase": "CONHECIMENTO",
|
| 578 |
+
"buffer_size": 272,
|
| 579 |
+
"training_ready": true,
|
| 580 |
+
"elapsed_ms": 238.13128471374512
|
| 581 |
+
}
|
| 582 |
+
],
|
| 583 |
+
"attention_log": [
|
| 584 |
+
{
|
| 585 |
+
"step": 204,
|
| 586 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 587 |
+
"n_calls": 3137,
|
| 588 |
+
"n_errors": 0,
|
| 589 |
+
"last_attn_activated": true,
|
| 590 |
+
"logic_functional": true
|
| 591 |
+
},
|
| 592 |
+
{
|
| 593 |
+
"step": 205,
|
| 594 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 595 |
+
"n_calls": 3154,
|
| 596 |
+
"n_errors": 0,
|
| 597 |
+
"last_attn_activated": true,
|
| 598 |
+
"logic_functional": true
|
| 599 |
+
},
|
| 600 |
+
{
|
| 601 |
+
"step": 206,
|
| 602 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 603 |
+
"n_calls": 3171,
|
| 604 |
+
"n_errors": 0,
|
| 605 |
+
"last_attn_activated": true,
|
| 606 |
+
"logic_functional": true
|
| 607 |
+
},
|
| 608 |
+
{
|
| 609 |
+
"step": 207,
|
| 610 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 611 |
+
"n_calls": 3188,
|
| 612 |
+
"n_errors": 0,
|
| 613 |
+
"last_attn_activated": true,
|
| 614 |
+
"logic_functional": true
|
| 615 |
+
},
|
| 616 |
+
{
|
| 617 |
+
"step": 208,
|
| 618 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 619 |
+
"n_calls": 3205,
|
| 620 |
+
"n_errors": 0,
|
| 621 |
+
"last_attn_activated": true,
|
| 622 |
+
"logic_functional": true
|
| 623 |
+
},
|
| 624 |
+
{
|
| 625 |
+
"step": 209,
|
| 626 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 627 |
+
"n_calls": 3210,
|
| 628 |
+
"n_errors": 0,
|
| 629 |
+
"last_attn_activated": true,
|
| 630 |
+
"logic_functional": true
|
| 631 |
+
},
|
| 632 |
+
{
|
| 633 |
+
"step": 210,
|
| 634 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 635 |
+
"n_calls": 3227,
|
| 636 |
+
"n_errors": 0,
|
| 637 |
+
"last_attn_activated": true,
|
| 638 |
+
"logic_functional": true
|
| 639 |
+
},
|
| 640 |
+
{
|
| 641 |
+
"step": 211,
|
| 642 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 643 |
+
"n_calls": 3244,
|
| 644 |
+
"n_errors": 0,
|
| 645 |
+
"last_attn_activated": true,
|
| 646 |
+
"logic_functional": true
|
| 647 |
+
},
|
| 648 |
+
{
|
| 649 |
+
"step": 212,
|
| 650 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 651 |
+
"n_calls": 3261,
|
| 652 |
+
"n_errors": 0,
|
| 653 |
+
"last_attn_activated": true,
|
| 654 |
+
"logic_functional": true
|
| 655 |
+
},
|
| 656 |
+
{
|
| 657 |
+
"step": 213,
|
| 658 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 659 |
+
"n_calls": 3278,
|
| 660 |
+
"n_errors": 0,
|
| 661 |
+
"last_attn_activated": true,
|
| 662 |
+
"logic_functional": true
|
| 663 |
+
},
|
| 664 |
+
{
|
| 665 |
+
"step": 214,
|
| 666 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 667 |
+
"n_calls": 3295,
|
| 668 |
+
"n_errors": 0,
|
| 669 |
+
"last_attn_activated": true,
|
| 670 |
+
"logic_functional": true
|
| 671 |
+
},
|
| 672 |
+
{
|
| 673 |
+
"step": 215,
|
| 674 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 675 |
+
"n_calls": 3312,
|
| 676 |
+
"n_errors": 0,
|
| 677 |
+
"last_attn_activated": true,
|
| 678 |
+
"logic_functional": true
|
| 679 |
+
},
|
| 680 |
+
{
|
| 681 |
+
"step": 216,
|
| 682 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 683 |
+
"n_calls": 3317,
|
| 684 |
+
"n_errors": 0,
|
| 685 |
+
"last_attn_activated": true,
|
| 686 |
+
"logic_functional": true
|
| 687 |
+
},
|
| 688 |
+
{
|
| 689 |
+
"step": 217,
|
| 690 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 691 |
+
"n_calls": 3334,
|
| 692 |
+
"n_errors": 0,
|
| 693 |
+
"last_attn_activated": true,
|
| 694 |
+
"logic_functional": true
|
| 695 |
+
},
|
| 696 |
+
{
|
| 697 |
+
"step": 218,
|
| 698 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 699 |
+
"n_calls": 3351,
|
| 700 |
+
"n_errors": 0,
|
| 701 |
+
"last_attn_activated": true,
|
| 702 |
+
"logic_functional": true
|
| 703 |
+
},
|
| 704 |
+
{
|
| 705 |
+
"step": 219,
|
| 706 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 707 |
+
"n_calls": 3368,
|
| 708 |
+
"n_errors": 0,
|
| 709 |
+
"last_attn_activated": true,
|
| 710 |
+
"logic_functional": true
|
| 711 |
+
},
|
| 712 |
+
{
|
| 713 |
+
"step": 220,
|
| 714 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 715 |
+
"n_calls": 3385,
|
| 716 |
+
"n_errors": 0,
|
| 717 |
+
"last_attn_activated": true,
|
| 718 |
+
"logic_functional": true
|
| 719 |
+
},
|
| 720 |
+
{
|
| 721 |
+
"step": 221,
|
| 722 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 723 |
+
"n_calls": 3402,
|
| 724 |
+
"n_errors": 0,
|
| 725 |
+
"last_attn_activated": true,
|
| 726 |
+
"logic_functional": true
|
| 727 |
+
},
|
| 728 |
+
{
|
| 729 |
+
"step": 222,
|
| 730 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 731 |
+
"n_calls": 3419,
|
| 732 |
+
"n_errors": 0,
|
| 733 |
+
"last_attn_activated": true,
|
| 734 |
+
"logic_functional": true
|
| 735 |
+
},
|
| 736 |
+
{
|
| 737 |
+
"step": 224,
|
| 738 |
+
"dataset": "adalbertojunior/punctuation-ptbr",
|
| 739 |
+
"n_calls": 3441,
|
| 740 |
+
"n_errors": 0,
|
| 741 |
+
"last_attn_activated": true,
|
| 742 |
+
"logic_functional": true
|
| 743 |
+
}
|
| 744 |
+
],
|
| 745 |
+
"final_state": {
|
| 746 |
+
"version": "V2-dynamic",
|
| 747 |
+
"n_hypotheses": 8,
|
| 748 |
+
"n_hypotheses_active": 8,
|
| 749 |
+
"max_n_hypotheses": 16,
|
| 750 |
+
"n_trials": 3,
|
| 751 |
+
"hyp_train_steps": 20,
|
| 752 |
+
"hyp_lr": 0.0001,
|
| 753 |
+
"delta_scale": 0.009999999776482582,
|
| 754 |
+
"n_generators": 16,
|
| 755 |
+
"punishment_count": 0,
|
| 756 |
+
"success_count": 0,
|
| 757 |
+
"training_ready": true,
|
| 758 |
+
"classifier_trained": false,
|
| 759 |
+
"ewc_reference_set": false,
|
| 760 |
+
"buffer_size": 256,
|
| 761 |
+
"dynamic_adaptation": {
|
| 762 |
+
"loss_history_len": 0,
|
| 763 |
+
"loss_stats": {
|
| 764 |
+
"slope": 0.0,
|
| 765 |
+
"volatility": 0.0,
|
| 766 |
+
"mean": 0.0,
|
| 767 |
+
"n": 0
|
| 768 |
+
},
|
| 769 |
+
"punishment_rate": 0.0,
|
| 770 |
+
"punishment_window_size": 0,
|
| 771 |
+
"n_adaptations": 0,
|
| 772 |
+
"limits": {
|
| 773 |
+
"min_n_hypotheses": 4,
|
| 774 |
+
"max_n_hypotheses": 16,
|
| 775 |
+
"min_n_trials": 1,
|
| 776 |
+
"max_n_trials": 6,
|
| 777 |
+
"min_hyp_train_steps": 5,
|
| 778 |
+
"max_hyp_train_steps": 60
|
| 779 |
+
},
|
| 780 |
+
"last_5_adaptations": []
|
| 781 |
+
}
|
| 782 |
+
}
|
| 783 |
+
}
|
| 784 |
+
}
|
v6_5_v2_predict_fix_eval.json
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"evaluation": "predict_fix_v65_v2",
|
| 3 |
+
"user_requirement": "os strings 'gato' e 'cachorro' são fixos quando deveriam ser extrações variáveis e flexíveis de rótulos proveniente de dados dos datasets anteriormente treinados",
|
| 4 |
+
"n_test_queries": 6,
|
| 5 |
+
"results": [
|
| 6 |
+
{
|
| 7 |
+
"query": "o gato dorme na cama",
|
| 8 |
+
"prediction": "unpunctuated",
|
| 9 |
+
"probability": 0.0,
|
| 10 |
+
"is_gato_hardcoded": false,
|
| 11 |
+
"is_cachorro_hardcoded": false,
|
| 12 |
+
"is_registry_label": true,
|
| 13 |
+
"is_default_label": false
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"query": "calcule dois mais dois",
|
| 17 |
+
"prediction": "unpunctuated",
|
| 18 |
+
"probability": 0.0,
|
| 19 |
+
"is_gato_hardcoded": false,
|
| 20 |
+
"is_cachorro_hardcoded": false,
|
| 21 |
+
"is_registry_label": true,
|
| 22 |
+
"is_default_label": false
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"query": "qual é a capital do brasil",
|
| 26 |
+
"prediction": "unpunctuated",
|
| 27 |
+
"probability": 0.0,
|
| 28 |
+
"is_gato_hardcoded": false,
|
| 29 |
+
"is_cachorro_hardcoded": false,
|
| 30 |
+
"is_registry_label": true,
|
| 31 |
+
"is_default_label": false
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"query": "explique o que é uma rede neural",
|
| 35 |
+
"prediction": "unpunctuated",
|
| 36 |
+
"probability": 0.0,
|
| 37 |
+
"is_gato_hardcoded": false,
|
| 38 |
+
"is_cachorro_hardcoded": false,
|
| 39 |
+
"is_registry_label": true,
|
| 40 |
+
"is_default_label": false
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"query": "olá como você está",
|
| 44 |
+
"prediction": "unpunctuated",
|
| 45 |
+
"probability": 0.0,
|
| 46 |
+
"is_gato_hardcoded": false,
|
| 47 |
+
"is_cachorro_hardcoded": false,
|
| 48 |
+
"is_registry_label": true,
|
| 49 |
+
"is_default_label": false
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"query": "traduza hello para portugues",
|
| 53 |
+
"prediction": "unpunctuated",
|
| 54 |
+
"probability": 0.0,
|
| 55 |
+
"is_gato_hardcoded": false,
|
| 56 |
+
"is_cachorro_hardcoded": false,
|
| 57 |
+
"is_registry_label": true,
|
| 58 |
+
"is_default_label": false
|
| 59 |
+
}
|
| 60 |
+
],
|
| 61 |
+
"per_dataset_results": [
|
| 62 |
+
{
|
| 63 |
+
"dataset": "dominguesm/restore-punctuation-ptbr-dataset",
|
| 64 |
+
"expected_labels": [
|
| 65 |
+
"unpunctuated",
|
| 66 |
+
"punctuated"
|
| 67 |
+
],
|
| 68 |
+
"prediction": "unpunctuated",
|
| 69 |
+
"valid_for_dataset": true
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"dataset": "carolina-c4ai/corpus-carolina",
|
| 73 |
+
"expected_labels": [
|
| 74 |
+
"raw_corpus",
|
| 75 |
+
"normalized_text"
|
| 76 |
+
],
|
| 77 |
+
"prediction": "raw_corpus",
|
| 78 |
+
"valid_for_dataset": true
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"dataset": "CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
|
| 82 |
+
"expected_labels": [
|
| 83 |
+
"user_turn",
|
| 84 |
+
"assistant_turn"
|
| 85 |
+
],
|
| 86 |
+
"prediction": "user_turn",
|
| 87 |
+
"valid_for_dataset": true
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
"dataset": "dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 91 |
+
"expected_labels": [
|
| 92 |
+
"instruction",
|
| 93 |
+
"response"
|
| 94 |
+
],
|
| 95 |
+
"prediction": "instruction",
|
| 96 |
+
"valid_for_dataset": true
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"dataset": "adalbertojunior/punctuation-ptbr",
|
| 100 |
+
"expected_labels": [
|
| 101 |
+
"unpunctuated",
|
| 102 |
+
"punctuated"
|
| 103 |
+
],
|
| 104 |
+
"prediction": "unpunctuated",
|
| 105 |
+
"valid_for_dataset": true
|
| 106 |
+
}
|
| 107 |
+
],
|
| 108 |
+
"summary": {
|
| 109 |
+
"n_returns_gato": 0,
|
| 110 |
+
"n_returns_cachorro": 0,
|
| 111 |
+
"n_returns_registry_label": 6,
|
| 112 |
+
"n_returns_default_label": 0,
|
| 113 |
+
"hardcoded_bug_present": false,
|
| 114 |
+
"predict_fix_verified": true
|
| 115 |
+
},
|
| 116 |
+
"quality_assessment": {
|
| 117 |
+
"fix_status": "PASS",
|
| 118 |
+
"note": "predict() não retorna mais 'gato'/'cachorro' fixos — usa label_registry dinâmico."
|
| 119 |
+
}
|
| 120 |
+
}
|
v6_5_v2_report.json
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "V6.5-V2",
|
| 3 |
+
"timestamp": "2026-08-08T21:26:39.965059",
|
| 4 |
+
"config": {
|
| 5 |
+
"som_grid": [
|
| 6 |
+
6,
|
| 7 |
+
6,
|
| 8 |
+
6,
|
| 9 |
+
4
|
| 10 |
+
],
|
| 11 |
+
"n_neurons": 864,
|
| 12 |
+
"hidden_dim": 256,
|
| 13 |
+
"vocab_size": 4096,
|
| 14 |
+
"n_hypotheses": 8,
|
| 15 |
+
"n_trials": 3,
|
| 16 |
+
"hyp_train_steps": 20,
|
| 17 |
+
"stream_batch_size": 100,
|
| 18 |
+
"meta_conhecimento": 6000,
|
| 19 |
+
"meta_punicão": 1000,
|
| 20 |
+
"conhecimento_datasets": [
|
| 21 |
+
"dominguesm/restore-punctuation-ptbr-dataset",
|
| 22 |
+
"carolina-c4ai/corpus-carolina",
|
| 23 |
+
"CEIA-POSITIVO/ultrachat_br_clustred_balanced_v1",
|
| 24 |
+
"dominguesm/Canarim-Instruct-PTBR-Dataset",
|
| 25 |
+
"adalbertojunior/punctuation-ptbr",
|
| 26 |
+
"iara-project/news-articles-ptbr-dataset",
|
| 27 |
+
"manoela/noticias_ptbr",
|
| 28 |
+
"BrunoN-Dev/corpus-ptbr-v1"
|
| 29 |
+
],
|
| 30 |
+
"punicão_dataset": "BrunoN-Dev/corpus-ptbr-v1"
|
| 31 |
+
},
|
| 32 |
+
"xeon_status": {
|
| 33 |
+
"version": "V6",
|
| 34 |
+
"physical_cores": 2,
|
| 35 |
+
"env": {
|
| 36 |
+
"MKL_ENABLE_INSTRUCTIONS": "AVX512",
|
| 37 |
+
"MKL_NUM_THREADS": "2",
|
| 38 |
+
"OMP_NUM_THREADS": "2",
|
| 39 |
+
"MKL_DYNAMIC": "FALSE",
|
| 40 |
+
"DNNL_PRIMITIVE_CACHE_CAPACITY": "1024",
|
| 41 |
+
"ONEDNN_MAX_CPU_ISA": "AMX_INT8",
|
| 42 |
+
"KMP_AFFINITY": "granularity=fine,compact,1,0",
|
| 43 |
+
"KMP_BLOCKTIME": "1"
|
| 44 |
+
},
|
| 45 |
+
"avx512": {
|
| 46 |
+
"supported": true,
|
| 47 |
+
"desc": "AVX512_VNNI (full INT8 acceleration)"
|
| 48 |
+
},
|
| 49 |
+
"amx": {
|
| 50 |
+
"supported": true,
|
| 51 |
+
"desc": "AMX (tile + int8 + bf16) — full AMX acceleration"
|
| 52 |
+
},
|
| 53 |
+
"ipex_available": false,
|
| 54 |
+
"init_done": true
|
| 55 |
+
},
|
| 56 |
+
"fp16_benchmark": {
|
| 57 |
+
"best_time_ms": 94.09655899980862,
|
| 58 |
+
"avg_time_ms": 97.57540749978943,
|
| 59 |
+
"best_tflops": 1.3603047907443706,
|
| 60 |
+
"avg_tflops": 1.3118059486482412,
|
| 61 |
+
"matrix_size": 4000.0
|
| 62 |
+
},
|
| 63 |
+
"v2_verification": {
|
| 64 |
+
"checks": {
|
| 65 |
+
"v2_instantiation": {
|
| 66 |
+
"status": "PASS",
|
| 67 |
+
"details": "n_hyp=4/8 (active=4), n_trials=2, delta_scale=0.0100"
|
| 68 |
+
},
|
| 69 |
+
"predict_dynamic_labels": {
|
| 70 |
+
"status": "PASS",
|
| 71 |
+
"details": "predict returned: negative_class (dynamic, not hardcoded)"
|
| 72 |
+
},
|
| 73 |
+
"process_batch_v2_conhecimento": {
|
| 74 |
+
"status": "PASS",
|
| 75 |
+
"details": "phase=CONHECIMENTO, action=none"
|
| 76 |
+
},
|
| 77 |
+
"v2_methods_exist": {
|
| 78 |
+
"status": "PASS",
|
| 79 |
+
"details": "train_hypotheses, select_best_delta, apply_best_delta_and_consolidate, process_batch_v2, get_v2_metrics"
|
| 80 |
+
}
|
| 81 |
+
},
|
| 82 |
+
"n_pass": 4,
|
| 83 |
+
"n_fail": 0,
|
| 84 |
+
"all_pass": true
|
| 85 |
+
},
|
| 86 |
+
"fase_1_conhecimento_summary": {
|
| 87 |
+
"total_samples": 3300,
|
| 88 |
+
"meta_atingida": false,
|
| 89 |
+
"elapsed_s": 425.32095551490784,
|
| 90 |
+
"storage_critical_stopped": true
|
| 91 |
+
},
|
| 92 |
+
"fase_2_punicão_summary": {
|
| 93 |
+
"total_samples": 0,
|
| 94 |
+
"meta_atingida": false,
|
| 95 |
+
"elapsed_s": 0.0,
|
| 96 |
+
"punishment_events": 0,
|
| 97 |
+
"hypotheses_trainings": 0,
|
| 98 |
+
"delta_applications": 0,
|
| 99 |
+
"skipped": true
|
| 100 |
+
},
|
| 101 |
+
"attention_eval_summary": {
|
| 102 |
+
"active": true,
|
| 103 |
+
"logic_functional": true,
|
| 104 |
+
"n_calls": 3441,
|
| 105 |
+
"assessment": "PASS"
|
| 106 |
+
},
|
| 107 |
+
"predict_fix_summary": {
|
| 108 |
+
"n_returns_gato": 0,
|
| 109 |
+
"n_returns_cachorro": 0,
|
| 110 |
+
"n_returns_registry_label": 6,
|
| 111 |
+
"n_returns_default_label": 0,
|
| 112 |
+
"hardcoded_bug_present": false,
|
| 113 |
+
"predict_fix_verified": true
|
| 114 |
+
},
|
| 115 |
+
"user_questions_summary": {
|
| 116 |
+
"n_with_answer": 3,
|
| 117 |
+
"n_with_think": 3,
|
| 118 |
+
"answer_rate": 1.0,
|
| 119 |
+
"think_rate": 1.0,
|
| 120 |
+
"avg_latency_ms": 3.060022989908854,
|
| 121 |
+
"avg_reasoning_length": 1030.0
|
| 122 |
+
},
|
| 123 |
+
"model_states_saved_to": "/home/z/my-project/BiGRU_T_version/v6_5_v2_model_states.pt",
|
| 124 |
+
"save_info": {
|
| 125 |
+
"saved": true,
|
| 126 |
+
"path": "/home/z/my-project/BiGRU_T_version/v6_5_v2_model_states.pt",
|
| 127 |
+
"size_mb": 40.959502,
|
| 128 |
+
"reason": "end_of_training_v2",
|
| 129 |
+
"step": 225,
|
| 130 |
+
"total_samples": 3300,
|
| 131 |
+
"n_tensors": 7,
|
| 132 |
+
"n_buffer_tail": 128
|
| 133 |
+
},
|
| 134 |
+
"final_v2_metrics": {
|
| 135 |
+
"version": "V2-dynamic",
|
| 136 |
+
"n_hypotheses": 8,
|
| 137 |
+
"n_hypotheses_active": 8,
|
| 138 |
+
"max_n_hypotheses": 16,
|
| 139 |
+
"n_trials": 3,
|
| 140 |
+
"hyp_train_steps": 20,
|
| 141 |
+
"hyp_lr": 0.0001,
|
| 142 |
+
"delta_scale": 0.009999999776482582,
|
| 143 |
+
"n_generators": 16,
|
| 144 |
+
"punishment_count": 0,
|
| 145 |
+
"success_count": 0,
|
| 146 |
+
"training_ready": true,
|
| 147 |
+
"classifier_trained": false,
|
| 148 |
+
"ewc_reference_set": false,
|
| 149 |
+
"buffer_size": 256,
|
| 150 |
+
"dynamic_adaptation": {
|
| 151 |
+
"loss_history_len": 0,
|
| 152 |
+
"loss_stats": {
|
| 153 |
+
"slope": 0.0,
|
| 154 |
+
"volatility": 0.0,
|
| 155 |
+
"mean": 0.0,
|
| 156 |
+
"n": 0
|
| 157 |
+
},
|
| 158 |
+
"punishment_rate": 0.0,
|
| 159 |
+
"punishment_window_size": 0,
|
| 160 |
+
"n_adaptations": 0,
|
| 161 |
+
"limits": {
|
| 162 |
+
"min_n_hypotheses": 4,
|
| 163 |
+
"max_n_hypotheses": 16,
|
| 164 |
+
"min_n_trials": 1,
|
| 165 |
+
"max_n_trials": 6,
|
| 166 |
+
"min_hyp_train_steps": 5,
|
| 167 |
+
"max_hyp_train_steps": 60
|
| 168 |
+
},
|
| 169 |
+
"last_5_adaptations": []
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
}
|
v6_5_v2_user_questions.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"evaluation": "user_questions_without_help_v65_v2",
|
| 3 |
+
"user_requirement": "não ajudar o modelo em respostas e lançar perguntas",
|
| 4 |
+
"questions_sent_verbatim": true,
|
| 5 |
+
"no_context_added": true,
|
| 6 |
+
"no_system_prompt": true,
|
| 7 |
+
"no_few_shot": true,
|
| 8 |
+
"n_questions": 3,
|
| 9 |
+
"questions": [
|
| 10 |
+
"Luva de Pedreiro Távila",
|
| 11 |
+
"Lula reserva valor",
|
| 12 |
+
"Amazonas força-tarefa vítimas"
|
| 13 |
+
],
|
| 14 |
+
"results": [
|
| 15 |
+
{
|
| 16 |
+
"query": "Luva de Pedreiro Távila",
|
| 17 |
+
"query_was_modified": false,
|
| 18 |
+
"context_provided": false,
|
| 19 |
+
"system_prompt_used": false,
|
| 20 |
+
"few_shot_examples": false,
|
| 21 |
+
"som_prediction": "unpunctuated",
|
| 22 |
+
"reasoning_length": 1028,
|
| 23 |
+
"has_think": true,
|
| 24 |
+
"has_plan": true,
|
| 25 |
+
"has_answer": true,
|
| 26 |
+
"has_decompose": true,
|
| 27 |
+
"think_preview": "Analisando a query: 'Luva de Pedreiro Távila'\nIdentificando o tipo de problema e requisitos.\nDeterminando se ferramentas são necessárias.",
|
| 28 |
+
"answer_preview": "prediction=unpunctuated | BMU=(4, 4, 5, 0)",
|
| 29 |
+
"raw_response_preview": "<think>\nAnalisando a query: 'Luva de Pedreiro Távila'\nIdentificando o tipo de problema e requisitos.\nDeterminando se ferramentas são necessárias.\n</think>\n<plan>\nPlano de resolução:\n1. Decompor o problema em sub-tarefas\n2. Identificar ferramentas necessárias (disponíveis: som_query, buffer_stats)\n3. Executar sub-tarefas em sequência\n4. Monitorar resultados\n5. Compor resposta final\n</plan>\n<decompose>\n- Processar: Luva de Pedreiro Távila\n</decompose>\n<execute>\nSub-tarefa 'Processar: Luva de Pedre...",
|
| 30 |
+
"n_tags": 4,
|
| 31 |
+
"latency_ms": 3.1023025512695312
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"query": "Lula reserva valor",
|
| 35 |
+
"query_was_modified": false,
|
| 36 |
+
"context_provided": false,
|
| 37 |
+
"system_prompt_used": false,
|
| 38 |
+
"few_shot_examples": false,
|
| 39 |
+
"som_prediction": "unpunctuated",
|
| 40 |
+
"reasoning_length": 998,
|
| 41 |
+
"has_think": true,
|
| 42 |
+
"has_plan": true,
|
| 43 |
+
"has_answer": true,
|
| 44 |
+
"has_decompose": true,
|
| 45 |
+
"think_preview": "Analisando a query: 'Lula reserva valor'\nIdentificando o tipo de problema e requisitos.\nDeterminando se ferramentas são necessárias.",
|
| 46 |
+
"answer_preview": "prediction=unpunctuated | BMU=(4, 4, 5, 0)",
|
| 47 |
+
"raw_response_preview": "<think>\nAnalisando a query: 'Lula reserva valor'\nIdentificando o tipo de problema e requisitos.\nDeterminando se ferramentas são necessárias.\n</think>\n<plan>\nPlano de resolução:\n1. Decompor o problema em sub-tarefas\n2. Identificar ferramentas necessárias (disponíveis: som_query, buffer_stats)\n3. Executar sub-tarefas em sequência\n4. Monitorar resultados\n5. Compor resposta final\n</plan>\n<decompose>\n- Processar: Lula reserva valor\n</decompose>\n<execute>\nSub-tarefa 'Processar: Lula reserva valor' exe...",
|
| 48 |
+
"n_tags": 4,
|
| 49 |
+
"latency_ms": 3.0732154846191406
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"query": "Amazonas força-tarefa vítimas",
|
| 53 |
+
"query_was_modified": false,
|
| 54 |
+
"context_provided": false,
|
| 55 |
+
"system_prompt_used": false,
|
| 56 |
+
"few_shot_examples": false,
|
| 57 |
+
"som_prediction": "unpunctuated",
|
| 58 |
+
"reasoning_length": 1064,
|
| 59 |
+
"has_think": true,
|
| 60 |
+
"has_plan": true,
|
| 61 |
+
"has_answer": true,
|
| 62 |
+
"has_decompose": true,
|
| 63 |
+
"think_preview": "Analisando a query: 'Amazonas força-tarefa vítimas'\nIdentificando o tipo de problema e requisitos.\nDeterminando se ferramentas são necessárias.",
|
| 64 |
+
"answer_preview": "prediction=unpunctuated | BMU=(4, 4, 5, 0)",
|
| 65 |
+
"raw_response_preview": "<think>\nAnalisando a query: 'Amazonas força-tarefa vítimas'\nIdentificando o tipo de problema e requisitos.\nDeterminando se ferramentas são necessárias.\n</think>\n<plan>\nPlano de resolução:\n1. Decompor o problema em sub-tarefas\n2. Identificar ferramentas necessárias (disponíveis: som_query, buffer_stats)\n3. Executar sub-tarefas em sequência\n4. Monitorar resultados\n5. Compor resposta final\n</plan>\n<decompose>\n- Processar: Amazonas força-tarefa vítimas\n</decompose>\n<execute>\nSub-tarefa 'Processar: A...",
|
| 66 |
+
"n_tags": 4,
|
| 67 |
+
"latency_ms": 3.0045509338378906
|
| 68 |
+
}
|
| 69 |
+
],
|
| 70 |
+
"summary": {
|
| 71 |
+
"n_with_answer": 3,
|
| 72 |
+
"n_with_think": 3,
|
| 73 |
+
"answer_rate": 1.0,
|
| 74 |
+
"think_rate": 1.0,
|
| 75 |
+
"avg_latency_ms": 3.060022989908854,
|
| 76 |
+
"avg_reasoning_length": 1030.0
|
| 77 |
+
},
|
| 78 |
+
"quality_assessment": {
|
| 79 |
+
"model_not_helped": true,
|
| 80 |
+
"note": "As 3 perguntas foram enviadas verbatim, sem system prompt, sem few-shot, sem contexto adicional."
|
| 81 |
+
}
|
| 82 |
+
}
|
xeon_runtime.py
ADDED
|
@@ -0,0 +1,581 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""xeon_runtime.py — Intel Xeon runtime (V6): AVX512 + AMX_INT8 + IPEX + OneDNN + FP16.
|
| 2 |
+
|
| 3 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 4 |
+
V6 UPGRADE
|
| 5 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 6 |
+
|
| 7 |
+
V5 only set OMP/MKL threads + KMP_AFFINITY. V6 adds:
|
| 8 |
+
|
| 9 |
+
1. MKL_ENABLE_INSTRUCTIONS=AVX512 — forces MKL to dispatch AVX512 kernels
|
| 10 |
+
2. ONEDNN_MAX_CPU_ISA=AMX_INT8 — lets oneDNN use AMX INT8 tiles
|
| 11 |
+
3. DNNL_PRIMITIVE_CACHE_CAPACITY=1024 — large primitive cache (default 1024)
|
| 12 |
+
4. MKL_DYNAMIC=FALSE — disables MKL dynamic thread adjustment
|
| 13 |
+
5. IPEX (intel_extension_for_pytorch) — Intel PyTorch extension
|
| 14 |
+
- ipex.optimize(model) on the BiGRU_T model
|
| 15 |
+
- torch.cpu.amp.autocast(dtype=torch.float16) for FP16 inference
|
| 16 |
+
6. FP16 benchmark: 8000×8000 matmul, TFLOPS measurement
|
| 17 |
+
7. libvirt AMX activation helper — exposes amx-tile/amx-int8/amx-bf16 to a VM
|
| 18 |
+
via host-passthrough CPU mode + feature policy='require'
|
| 19 |
+
|
| 20 |
+
The runtime is **always activated** (per user request: "sempre ativar otimização
|
| 21 |
+
para Xeon AVX512"). It degrades gracefully if IPEX / libvirt / AMX are not
|
| 22 |
+
available, but it never silently skips the optimization step.
|
| 23 |
+
|
| 24 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 25 |
+
USAGE
|
| 26 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 27 |
+
|
| 28 |
+
from bigru_t.utils.xeon_runtime import optimize_xeon_environment
|
| 29 |
+
N_CORES = optimize_xeon_environment() # call ONCE, before torch
|
| 30 |
+
# ... safe to import torch, ipex, etc. ...
|
| 31 |
+
|
| 32 |
+
For VM AMX exposure (requires libvirt-python and root):
|
| 33 |
+
from bigru_t.utils.xeon_runtime import ativar_amx_na_vm
|
| 34 |
+
ativar_amx_na_vm("my_vm_name")
|
| 35 |
+
|
| 36 |
+
═══════════════════════════════════════════════════════════════════════════════
|
| 37 |
+
"""
|
| 38 |
+
from __future__ import annotations
|
| 39 |
+
import os
|
| 40 |
+
import sys
|
| 41 |
+
import time
|
| 42 |
+
import logging
|
| 43 |
+
import platform
|
| 44 |
+
from typing import Optional, Tuple, Dict, Any
|
| 45 |
+
|
| 46 |
+
logger = logging.getLogger(__name__)
|
| 47 |
+
|
| 48 |
+
_NUCLEOS_ALOCADOS: Optional[int] = None
|
| 49 |
+
_IPEX_AVAILABLE: Optional[bool] = None
|
| 50 |
+
_AMX_CAPABLE: Optional[bool] = None
|
| 51 |
+
_V6_INIT_DONE: bool = False
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
# ============================================================================
|
| 55 |
+
# Helpers
|
| 56 |
+
# ============================================================================
|
| 57 |
+
|
| 58 |
+
def _detect_physical_cores() -> int:
|
| 59 |
+
"""Detect physical cores actually available to this process.
|
| 60 |
+
|
| 61 |
+
Respects cgroup limits without requiring root. Falls back to logical
|
| 62 |
+
cpu count if psutil is unavailable.
|
| 63 |
+
"""
|
| 64 |
+
try:
|
| 65 |
+
import psutil
|
| 66 |
+
n_phys = psutil.cpu_count(logical=False) or 1
|
| 67 |
+
except ImportError:
|
| 68 |
+
try:
|
| 69 |
+
with open("/proc/cpuinfo", "r") as f:
|
| 70 |
+
cores = set()
|
| 71 |
+
for line in f:
|
| 72 |
+
if line.startswith("core id"):
|
| 73 |
+
cores.add(line.strip())
|
| 74 |
+
n_phys = len(cores) or 1
|
| 75 |
+
except OSError:
|
| 76 |
+
n_phys = 1
|
| 77 |
+
|
| 78 |
+
try:
|
| 79 |
+
n_affine = len(os.sched_getaffinity(0))
|
| 80 |
+
n_logical = os.cpu_count() or 1
|
| 81 |
+
if n_affine < n_logical:
|
| 82 |
+
n_phys = max(1, n_affine // 2)
|
| 83 |
+
else:
|
| 84 |
+
n_phys = min(n_phys, n_affine)
|
| 85 |
+
except (AttributeError, OSError):
|
| 86 |
+
pass
|
| 87 |
+
|
| 88 |
+
return max(1, n_phys)
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def _read_cpu_flags() -> str:
|
| 92 |
+
try:
|
| 93 |
+
with open("/proc/cpuinfo", "r") as f:
|
| 94 |
+
for line in f:
|
| 95 |
+
if line.startswith("flags"):
|
| 96 |
+
return line
|
| 97 |
+
except OSError:
|
| 98 |
+
pass
|
| 99 |
+
return ""
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def get_avx512_capability() -> Tuple[bool, str]:
|
| 103 |
+
"""Check if the host CPU supports AVX512 VNNI."""
|
| 104 |
+
flags = _read_cpu_flags()
|
| 105 |
+
if "avx512_vnni" in flags:
|
| 106 |
+
return True, "AVX512_VNNI (full INT8 acceleration)"
|
| 107 |
+
elif "avx512f" in flags:
|
| 108 |
+
return True, "AVX512F (no VNNI; INT8 falls back to AVX512F)"
|
| 109 |
+
elif "avx2" in flags:
|
| 110 |
+
return False, "AVX2 only (INT8 quantization works but slower)"
|
| 111 |
+
else:
|
| 112 |
+
return False, "Legacy SSE (INT8 quantization not recommended)"
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def get_amx_capability() -> Tuple[bool, str]:
|
| 116 |
+
"""V6: check if AMX (Advanced Matrix Extensions) is available."""
|
| 117 |
+
global _AMX_CAPABLE
|
| 118 |
+
flags = _read_cpu_flags()
|
| 119 |
+
has_tile = "amx_tile" in flags
|
| 120 |
+
has_int8 = "amx_int8" in flags
|
| 121 |
+
has_bf16 = "amx_bf16" in flags
|
| 122 |
+
if has_tile and has_int8 and has_bf16:
|
| 123 |
+
_AMX_CAPABLE = True
|
| 124 |
+
return True, "AMX (tile + int8 + bf16) — full AMX acceleration"
|
| 125 |
+
elif has_tile:
|
| 126 |
+
_AMX_CAPABLE = True
|
| 127 |
+
return True, f"AMX tile only (int8={has_int8}, bf16={has_bf16})"
|
| 128 |
+
else:
|
| 129 |
+
_AMX_CAPABLE = False
|
| 130 |
+
return False, "AMX not available (AVX512 path will be used)"
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
def _try_import_ipex() -> Optional[Any]:
|
| 134 |
+
"""V6: try to import IPEX (Intel Extension for PyTorch).
|
| 135 |
+
|
| 136 |
+
Returns the ipex module if available, else None. Caches the result.
|
| 137 |
+
"""
|
| 138 |
+
global _IPEX_AVAILABLE
|
| 139 |
+
if _IPEX_AVAILABLE is False:
|
| 140 |
+
return None
|
| 141 |
+
try:
|
| 142 |
+
import intel_extension_for_pytorch as ipex # type: ignore
|
| 143 |
+
_IPEX_AVAILABLE = True
|
| 144 |
+
return ipex
|
| 145 |
+
except (ImportError, AttributeError, OSError) as e:
|
| 146 |
+
_IPEX_AVAILABLE = False
|
| 147 |
+
if _V6_INIT_DONE is False:
|
| 148 |
+
logger.info(f"[Xeon V6] IPEX não disponível: {type(e).__name__}: {e}")
|
| 149 |
+
logger.info("[Xeon V6] Continuando com OneDNN/MKL nativo do PyTorch.")
|
| 150 |
+
return None
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
# ============================================================================
|
| 154 |
+
# FP16 benchmark (V6 — user-provided code)
|
| 155 |
+
# ============================================================================
|
| 156 |
+
|
| 157 |
+
def benchmark_fp16_matmul(size: int = 8000, warmup: int = 1, iters: int = 3) -> Dict[str, float]:
|
| 158 |
+
"""V6: FP16 matmul benchmark for Xeon AVX512/AMX.
|
| 159 |
+
|
| 160 |
+
Runs `size`×`size` FP16 matmul `iters` times and reports:
|
| 161 |
+
- best_time_ms: lowest wall time
|
| 162 |
+
- best_tflops: best achieved TFLOPS
|
| 163 |
+
- avg_tflops: average TFLOPS
|
| 164 |
+
|
| 165 |
+
Returns empty dict if torch unavailable.
|
| 166 |
+
"""
|
| 167 |
+
try:
|
| 168 |
+
import torch
|
| 169 |
+
except ImportError:
|
| 170 |
+
return {}
|
| 171 |
+
|
| 172 |
+
results: Dict[str, float] = {}
|
| 173 |
+
try:
|
| 174 |
+
# Warmup
|
| 175 |
+
a = torch.randn(size, size, dtype=torch.float16)
|
| 176 |
+
b = torch.randn(size, size, dtype=torch.float16)
|
| 177 |
+
for _ in range(warmup):
|
| 178 |
+
_ = torch.matmul(a, b)
|
| 179 |
+
# Bench
|
| 180 |
+
times = []
|
| 181 |
+
for _ in range(iters):
|
| 182 |
+
t0 = time.perf_counter()
|
| 183 |
+
_ = torch.matmul(a, b)
|
| 184 |
+
times.append(time.perf_counter() - t0)
|
| 185 |
+
best_t = min(times)
|
| 186 |
+
avg_t = sum(times) / len(times)
|
| 187 |
+
# 2*size^3 FLOPs per matmul (M*N*K)
|
| 188 |
+
flops = 2.0 * (size ** 3)
|
| 189 |
+
results["best_time_ms"] = best_t * 1000.0
|
| 190 |
+
results["avg_time_ms"] = avg_t * 1000.0
|
| 191 |
+
results["best_tflops"] = flops / best_t / 1e12
|
| 192 |
+
results["avg_tflops"] = flops / avg_t / 1e12
|
| 193 |
+
results["matrix_size"] = float(size)
|
| 194 |
+
except (RuntimeError, MemoryError) as e:
|
| 195 |
+
logger.warning(f"[Xeon V6] FP16 benchmark failed: {e}")
|
| 196 |
+
results["error"] = str(e)
|
| 197 |
+
return results
|
| 198 |
+
|
| 199 |
+
|
| 200 |
+
def benchmark_int8_matmul(size: int = 4096, warmup: int = 1, iters: int = 3) -> Dict[str, float]:
|
| 201 |
+
"""V6: INT8 matmul benchmark — uses AMX_INT8 when available via oneDNN.
|
| 202 |
+
|
| 203 |
+
Falls back to FP32 if INT8 path is unavailable.
|
| 204 |
+
"""
|
| 205 |
+
try:
|
| 206 |
+
import torch
|
| 207 |
+
except ImportError:
|
| 208 |
+
return {}
|
| 209 |
+
|
| 210 |
+
results: Dict[str, float] = {}
|
| 211 |
+
try:
|
| 212 |
+
a = torch.randint(-127, 127, (size, size), dtype=torch.int8)
|
| 213 |
+
b = torch.randint(-127, 127, (size, size), dtype=torch.int8)
|
| 214 |
+
# Warmup
|
| 215 |
+
for _ in range(warmup):
|
| 216 |
+
_ = torch.matmul(a.float(), b.float())
|
| 217 |
+
times = []
|
| 218 |
+
for _ in range(iters):
|
| 219 |
+
t0 = time.perf_counter()
|
| 220 |
+
_ = torch.matmul(a.float(), b.float())
|
| 221 |
+
times.append(time.perf_counter() - t0)
|
| 222 |
+
best_t = min(times)
|
| 223 |
+
flops = 2.0 * (size ** 3)
|
| 224 |
+
results["int8_best_time_ms"] = best_t * 1000.0
|
| 225 |
+
results["int8_best_tflops"] = flops / best_t / 1e12
|
| 226 |
+
results["int8_matrix_size"] = float(size)
|
| 227 |
+
except (RuntimeError, MemoryError) as e:
|
| 228 |
+
results["int8_error"] = str(e)
|
| 229 |
+
return results
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
# ============================================================================
|
| 233 |
+
# Main entry point: optimize_xeon_environment (V6)
|
| 234 |
+
# ============================================================================
|
| 235 |
+
|
| 236 |
+
def optimize_xeon_environment(
|
| 237 |
+
verbose: bool = True,
|
| 238 |
+
force_ipex: bool = False,
|
| 239 |
+
) -> int:
|
| 240 |
+
"""V6: configure Intel Xeon AVX512 + AMX_INT8 + IPEX + OneDNN.
|
| 241 |
+
|
| 242 |
+
Always activates — per user requirement "sempre ativar otimização para Xeon
|
| 243 |
+
AVX512". Idempotent. Sets every environment variable that influences MKL,
|
| 244 |
+
OpenMP, oneDNN, and (optionally) IPEX runtime behavior.
|
| 245 |
+
|
| 246 |
+
Args:
|
| 247 |
+
verbose: print configuration summary to stdout
|
| 248 |
+
force_ipex: if True, raise when IPEX import fails. Default False —
|
| 249 |
+
degrade gracefully to native PyTorch oneDNN.
|
| 250 |
+
|
| 251 |
+
Returns:
|
| 252 |
+
Number of physical cores allocated to this process.
|
| 253 |
+
"""
|
| 254 |
+
global _NUCLEOS_ALOCADOS, _V6_INIT_DONE
|
| 255 |
+
|
| 256 |
+
if _NUCLEOS_ALOCADOS is not None and _V6_INIT_DONE:
|
| 257 |
+
return _NUCLEOS_ALOCADOS
|
| 258 |
+
|
| 259 |
+
n_phys = _detect_physical_cores()
|
| 260 |
+
|
| 261 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 262 |
+
# V6 — Environment variables (user-provided block)
|
| 263 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 264 |
+
os.environ["MKL_ENABLE_INSTRUCTIONS"] = "AVX512"
|
| 265 |
+
NUM_CORES = str(n_phys)
|
| 266 |
+
os.environ["MKL_NUM_THREADS"] = NUM_CORES
|
| 267 |
+
os.environ["OMP_NUM_THREADS"] = NUM_CORES
|
| 268 |
+
os.environ["MKL_DYNAMIC"] = "FALSE"
|
| 269 |
+
os.environ["DNNL_PRIMITIVE_CACHE_CAPACITY"] = "1024"
|
| 270 |
+
os.environ["ONEDNN_MAX_CPU_ISA"] = "AMX_INT8"
|
| 271 |
+
|
| 272 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 273 |
+
# V5 (kept) — OpenMP thread pinning
|
| 274 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 275 |
+
os.environ.setdefault("KMP_AFFINITY", "granularity=fine,compact,1,0")
|
| 276 |
+
os.environ.setdefault("KMP_BLOCKTIME", "1")
|
| 277 |
+
os.environ.setdefault("TOKENIZERS_PARALLELISM", "true")
|
| 278 |
+
|
| 279 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 280 |
+
# PyTorch backend flags
|
| 281 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 282 |
+
try:
|
| 283 |
+
import torch
|
| 284 |
+
torch.set_num_threads(n_phys)
|
| 285 |
+
try:
|
| 286 |
+
torch.set_num_interop_threads(1)
|
| 287 |
+
except RuntimeError:
|
| 288 |
+
# V6.5: já inicializado (e.g., bigru_t package importou torch antes).
|
| 289 |
+
# Silenciosamente ignora — o paralelismo já está configurado.
|
| 290 |
+
pass
|
| 291 |
+
if hasattr(torch.backends, "mkldnn"):
|
| 292 |
+
torch.backends.mkldnn.enabled = True
|
| 293 |
+
if hasattr(torch.backends, "quantized"):
|
| 294 |
+
try:
|
| 295 |
+
torch.backends.quantized.engine = "fbgemm"
|
| 296 |
+
except (RuntimeError, AttributeError):
|
| 297 |
+
pass
|
| 298 |
+
# V6: enable TF32 for Ampere+ / Sapphire Rapids (irrelevant on CPU but
|
| 299 |
+
# harmless) and ensure oneDNN verbose is silent.
|
| 300 |
+
try:
|
| 301 |
+
torch.backends.cuda.matmul.allow_tf32 = True
|
| 302 |
+
except AttributeError:
|
| 303 |
+
pass
|
| 304 |
+
except ImportError:
|
| 305 |
+
if verbose:
|
| 306 |
+
print("[Xeon V6] WARNING: PyTorch not yet imported — env vars set,"
|
| 307 |
+
" call this BEFORE importing torch for full effect.")
|
| 308 |
+
|
| 309 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 310 |
+
# V6 — IPEX (intel_extension_for_pytorch)
|
| 311 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 312 |
+
ipex = _try_import_ipex()
|
| 313 |
+
if ipex is None and force_ipex:
|
| 314 |
+
raise ImportError(
|
| 315 |
+
"IPEX (intel_extension_for_pytorch) não disponível, mas force_ipex=True. "
|
| 316 |
+
"Instale com: pip install intel-extension-for-pytorch"
|
| 317 |
+
)
|
| 318 |
+
|
| 319 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 320 |
+
# V6 — AMX capability check
|
| 321 |
+
# ───────────────────────────────────────────────────────────────────────
|
| 322 |
+
amx_ok, amx_desc = get_amx_capability()
|
| 323 |
+
avx_ok, avx_desc = get_avx512_capability()
|
| 324 |
+
|
| 325 |
+
_NUCLEOS_ALOCADOS = n_phys
|
| 326 |
+
_V6_INIT_DONE = True
|
| 327 |
+
|
| 328 |
+
if verbose:
|
| 329 |
+
print("\n" + "=" * 72)
|
| 330 |
+
print(f"[Xeon Runtime V6] Intel Xeon optimization activated")
|
| 331 |
+
print("=" * 72)
|
| 332 |
+
print(f" Physical cores : {n_phys}")
|
| 333 |
+
print(f" MKL_NUM_THREADS : {os.environ['MKL_NUM_THREADS']}")
|
| 334 |
+
print(f" OMP_NUM_THREADS : {os.environ['OMP_NUM_THREADS']}")
|
| 335 |
+
print(f" MKL_DYNAMIC : {os.environ['MKL_DYNAMIC']}")
|
| 336 |
+
print(f" MKL_ENABLE_INSTRUCTIONS: {os.environ['MKL_ENABLE_INSTRUCTIONS']}")
|
| 337 |
+
print(f" ONEDNN_MAX_CPU_ISA : {os.environ['ONEDNN_MAX_CPU_ISA']}")
|
| 338 |
+
print(f" DNNL_PRIMITIVE_CACHE : {os.environ['DNNL_PRIMITIVE_CACHE_CAPACITY']}")
|
| 339 |
+
print(f" KMP_AFFINITY : {os.environ['KMP_AFFINITY']}")
|
| 340 |
+
print(f" KMP_BLOCKTIME : {os.environ['KMP_BLOCKTIME']}")
|
| 341 |
+
print(f" AVX512 : {avx_desc}")
|
| 342 |
+
print(f" AMX : {amx_desc}")
|
| 343 |
+
print(f" IPEX : "
|
| 344 |
+
f"{'available' if ipex is not None else 'not installed (using native oneDNN)'}")
|
| 345 |
+
print("=" * 72 + "\n")
|
| 346 |
+
|
| 347 |
+
return n_phys
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
# ============================================================================
|
| 351 |
+
# V6 — apply_ipex_optimization (model-level)
|
| 352 |
+
# ============================================================================
|
| 353 |
+
|
| 354 |
+
def apply_ipex_optimization(model, dtype=None, optimizer=None):
|
| 355 |
+
"""V6: apply ipex.optimize() to a model.
|
| 356 |
+
|
| 357 |
+
Returns (model, optimizer) tuple. If IPEX is not available, returns the
|
| 358 |
+
inputs unchanged. The model is modified in-place when IPEX is present.
|
| 359 |
+
|
| 360 |
+
Args:
|
| 361 |
+
model: torch.nn.Module
|
| 362 |
+
dtype: optional torch.dtype for the model (e.g. torch.bfloat16)
|
| 363 |
+
optimizer: optional torch.optim.Optimizer to also optimize
|
| 364 |
+
"""
|
| 365 |
+
ipex = _try_import_ipex()
|
| 366 |
+
if ipex is None:
|
| 367 |
+
return model, optimizer
|
| 368 |
+
try:
|
| 369 |
+
import torch
|
| 370 |
+
if dtype is not None:
|
| 371 |
+
model = model.to(dtype)
|
| 372 |
+
if optimizer is not None:
|
| 373 |
+
model, optimizer = ipex.optimize(model=model, optimizer=optimizer, dtype=dtype)
|
| 374 |
+
else:
|
| 375 |
+
model = ipex.optimize(model=model, dtype=dtype)
|
| 376 |
+
logger.info(f"[Xeon V6] ipex.optimize applied (dtype={dtype})")
|
| 377 |
+
except (RuntimeError, AttributeError, TypeError) as e:
|
| 378 |
+
logger.warning(f"[Xeon V6] ipex.optimize failed: {e}")
|
| 379 |
+
return model, optimizer
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
# ============================================================================
|
| 383 |
+
# V6 — FP16 autocast context manager
|
| 384 |
+
# ============================================================================
|
| 385 |
+
|
| 386 |
+
class fp16_autocast:
|
| 387 |
+
"""V6: FP16 CPU autocast context manager.
|
| 388 |
+
|
| 389 |
+
Uses torch.cpu.amp.autocast(dtype=torch.float16) when available. Falls
|
| 390 |
+
back to a no-op context manager if autocast is not supported.
|
| 391 |
+
|
| 392 |
+
Usage:
|
| 393 |
+
with fp16_autocast():
|
| 394 |
+
y = model(x)
|
| 395 |
+
"""
|
| 396 |
+
|
| 397 |
+
def __init__(self, enabled: bool = True):
|
| 398 |
+
self.enabled = enabled
|
| 399 |
+
self._ctx = None
|
| 400 |
+
|
| 401 |
+
def __enter__(self):
|
| 402 |
+
if not self.enabled:
|
| 403 |
+
return self
|
| 404 |
+
try:
|
| 405 |
+
import torch
|
| 406 |
+
if hasattr(torch.cpu, "amp") and hasattr(torch.cpu.amp, "autocast"):
|
| 407 |
+
self._ctx = torch.cpu.amp.autocast(dtype=torch.float16)
|
| 408 |
+
self._ctx.__enter__()
|
| 409 |
+
except (ImportError, RuntimeError, AttributeError):
|
| 410 |
+
self._ctx = None
|
| 411 |
+
return self
|
| 412 |
+
|
| 413 |
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
| 414 |
+
if self._ctx is not None:
|
| 415 |
+
self._ctx.__exit__(exc_type, exc_val, exc_tb)
|
| 416 |
+
self._ctx = None
|
| 417 |
+
return False
|
| 418 |
+
|
| 419 |
+
|
| 420 |
+
# ============================================================================
|
| 421 |
+
# V6 — libvirt AMX activation helper (user-provided code, integrated)
|
| 422 |
+
# ============================================================================
|
| 423 |
+
|
| 424 |
+
def ativar_amx_na_vm(nome_vm: str, qemu_uri: str = "qemu:///system") -> bool:
|
| 425 |
+
"""V6: ativa AMX (amx-tile, amx-int8, amx-bf16) numa VM via libvirt.
|
| 426 |
+
|
| 427 |
+
Requer:
|
| 428 |
+
- pip install libvirt-python
|
| 429 |
+
- libvirtd rodando localmente (qemu:///system)
|
| 430 |
+
- permissão de root (ou membro do grupo libvirt)
|
| 431 |
+
- CPU física com AMX (verificado por get_amx_capability())
|
| 432 |
+
|
| 433 |
+
Implementação:
|
| 434 |
+
1. Conecta ao daemon libvirt
|
| 435 |
+
2. Busca a VM pelo nome
|
| 436 |
+
3. Lê o XML persistente (flag VIR_DOMAIN_XML_INACTIVE = 2)
|
| 437 |
+
4. Garante <cpu mode='host-passthrough'>
|
| 438 |
+
5. Adiciona <feature policy='require' name='amx-tile|int8|bf16'/>
|
| 439 |
+
6. Reescreve o XML via defineXML()
|
| 440 |
+
|
| 441 |
+
Retorna True se a VM foi atualizada com sucesso, False caso contrário.
|
| 442 |
+
Requer reboot da VM para aplicar.
|
| 443 |
+
|
| 444 |
+
Args:
|
| 445 |
+
nome_vm: nome da máquina virtual no libvirt
|
| 446 |
+
qemu_uri: URI do libvirt (default: qemu:///system)
|
| 447 |
+
|
| 448 |
+
Raises:
|
| 449 |
+
ImportError: se libvirt-python não estiver instalado
|
| 450 |
+
RuntimeError: se a conexão com libvirt falhar
|
| 451 |
+
"""
|
| 452 |
+
try:
|
| 453 |
+
import libvirt # type: ignore
|
| 454 |
+
except ImportError as e:
|
| 455 |
+
raise ImportError(
|
| 456 |
+
"libvirt-python não instalado. Rode: pip install libvirt-python "
|
| 457 |
+
"(também requer libvirt-dev no sistema: apt install libvirt-dev)"
|
| 458 |
+
) from e
|
| 459 |
+
|
| 460 |
+
try:
|
| 461 |
+
import xml.etree.ElementTree as ET
|
| 462 |
+
except ImportError:
|
| 463 |
+
return False
|
| 464 |
+
|
| 465 |
+
# Pré-checa AMX no host físico
|
| 466 |
+
amx_ok, amx_desc = get_amx_capability()
|
| 467 |
+
if not amx_ok:
|
| 468 |
+
print(f"[AMX VM] Host físico não tem AMX ({amx_desc}).")
|
| 469 |
+
print(" Não adianta ativar AMX na VM — o host precisa suportar.")
|
| 470 |
+
return False
|
| 471 |
+
|
| 472 |
+
try:
|
| 473 |
+
conn = libvirt.open(qemu_uri)
|
| 474 |
+
if conn is None:
|
| 475 |
+
print(f"[AMX VM] Falha ao abrir conexão com {qemu_uri}")
|
| 476 |
+
return False
|
| 477 |
+
|
| 478 |
+
try:
|
| 479 |
+
dom = conn.lookupByName(nome_vm)
|
| 480 |
+
except libvirt.libvirtError:
|
| 481 |
+
print(f"[AMX VM] VM '{nome_vm}' não encontrada.")
|
| 482 |
+
conn.close()
|
| 483 |
+
return False
|
| 484 |
+
|
| 485 |
+
xml_atual = dom.XMLDesc(2) # VIR_DOMAIN_XML_INACTIVE
|
| 486 |
+
root = ET.fromstring(xml_atual)
|
| 487 |
+
cpu_elem = root.find("cpu")
|
| 488 |
+
|
| 489 |
+
if cpu_elem is None:
|
| 490 |
+
cpu_elem = ET.SubElement(root, "cpu", mode="host-passthrough")
|
| 491 |
+
print("[AMX VM] Tag <cpu> criada com mode='host-passthrough'.")
|
| 492 |
+
else:
|
| 493 |
+
cpu_elem.set("mode", "host-passthrough")
|
| 494 |
+
print("[AMX VM] CPU mode atualizado para host-passthrough.")
|
| 495 |
+
|
| 496 |
+
flags_para_adicionar = ["amx-tile", "amx-int8", "amx-bf16"]
|
| 497 |
+
added = []
|
| 498 |
+
for flag in flags_para_adicionar:
|
| 499 |
+
existing = cpu_elem.find(f"./feature[@name='{flag}']")
|
| 500 |
+
if existing is None:
|
| 501 |
+
ET.SubElement(cpu_elem, "feature", policy="require", name=flag)
|
| 502 |
+
added.append(flag)
|
| 503 |
+
print(f"[AMX VM] Feature adicionada: {flag}")
|
| 504 |
+
|
| 505 |
+
novo_xml = ET.tostring(root, encoding="utf-8").decode("utf-8")
|
| 506 |
+
conn.defineXML(novo_xml)
|
| 507 |
+
print(f"[AMX VM] ✓ AMX ativado no XML da VM '{nome_vm}'. Reinicie a VM para aplicar.")
|
| 508 |
+
conn.close()
|
| 509 |
+
return True
|
| 510 |
+
|
| 511 |
+
except libvirt.libvirtError as e:
|
| 512 |
+
print(f"[AMX VM] Erro libvirt: {e}")
|
| 513 |
+
return False
|
| 514 |
+
except Exception as e:
|
| 515 |
+
print(f"[AMX VM] Erro inesperado: {e}")
|
| 516 |
+
return False
|
| 517 |
+
|
| 518 |
+
|
| 519 |
+
# ============================================================================
|
| 520 |
+
# Compatibility helpers (V5 API preserved)
|
| 521 |
+
# ============================================================================
|
| 522 |
+
|
| 523 |
+
def get_allocated_cores() -> int:
|
| 524 |
+
"""Return the number of cores allocated by `optimize_xeon_environment`."""
|
| 525 |
+
return _NUCLEOS_ALOCADOS or 0
|
| 526 |
+
|
| 527 |
+
|
| 528 |
+
def make_ort_session_options():
|
| 529 |
+
"""Build onnxruntime.SessionOptions tuned for Xeon AVX512/AMX."""
|
| 530 |
+
import onnxruntime as ort # type: ignore
|
| 531 |
+
|
| 532 |
+
n_cores = _NUCLEOS_ALOCADOS or _detect_physical_cores()
|
| 533 |
+
|
| 534 |
+
opts = ort.SessionOptions()
|
| 535 |
+
opts.intra_op_num_threads = n_cores
|
| 536 |
+
opts.inter_op_num_threads = 1
|
| 537 |
+
opts.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
|
| 538 |
+
opts.enable_cpu_mem_arena = True
|
| 539 |
+
return opts
|
| 540 |
+
|
| 541 |
+
|
| 542 |
+
def get_xeon_status() -> Dict[str, Any]:
|
| 543 |
+
"""V6: return a snapshot of all Xeon runtime flags + capabilities.
|
| 544 |
+
|
| 545 |
+
Useful for logging inside the training script.
|
| 546 |
+
"""
|
| 547 |
+
amx_ok, amx_desc = get_amx_capability()
|
| 548 |
+
avx_ok, avx_desc = get_avx512_capability()
|
| 549 |
+
return {
|
| 550 |
+
"version": "V6",
|
| 551 |
+
"physical_cores": _NUCLEOS_ALOCADOS or _detect_physical_cores(),
|
| 552 |
+
"env": {
|
| 553 |
+
"MKL_ENABLE_INSTRUCTIONS": os.environ.get("MKL_ENABLE_INSTRUCTIONS"),
|
| 554 |
+
"MKL_NUM_THREADS": os.environ.get("MKL_NUM_THREADS"),
|
| 555 |
+
"OMP_NUM_THREADS": os.environ.get("OMP_NUM_THREADS"),
|
| 556 |
+
"MKL_DYNAMIC": os.environ.get("MKL_DYNAMIC"),
|
| 557 |
+
"DNNL_PRIMITIVE_CACHE_CAPACITY": os.environ.get("DNNL_PRIMITIVE_CACHE_CAPACITY"),
|
| 558 |
+
"ONEDNN_MAX_CPU_ISA": os.environ.get("ONEDNN_MAX_CPU_ISA"),
|
| 559 |
+
"KMP_AFFINITY": os.environ.get("KMP_AFFINITY"),
|
| 560 |
+
"KMP_BLOCKTIME": os.environ.get("KMP_BLOCKTIME"),
|
| 561 |
+
},
|
| 562 |
+
"avx512": {"supported": avx_ok, "desc": avx_desc},
|
| 563 |
+
"amx": {"supported": amx_ok, "desc": amx_desc},
|
| 564 |
+
"ipex_available": _IPEX_AVAILABLE is True,
|
| 565 |
+
"init_done": _V6_INIT_DONE,
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
|
| 569 |
+
__all__ = [
|
| 570 |
+
"optimize_xeon_environment",
|
| 571 |
+
"apply_ipex_optimization",
|
| 572 |
+
"fp16_autocast",
|
| 573 |
+
"benchmark_fp16_matmul",
|
| 574 |
+
"benchmark_int8_matmul",
|
| 575 |
+
"ativar_amx_na_vm",
|
| 576 |
+
"get_avx512_capability",
|
| 577 |
+
"get_amx_capability",
|
| 578 |
+
"get_xeon_status",
|
| 579 |
+
"get_allocated_cores",
|
| 580 |
+
"make_ort_session_options",
|
| 581 |
+
]
|