PowerMachine commited on
Commit
eb3bffd
·
verified ·
1 Parent(s): 1dd3249

V6.5-V2-dynamic: upload batch (scripts + state + model) [80 files]

Browse files
scripts/train_v6_5_v2.py CHANGED
@@ -1201,6 +1201,33 @@ def run_fase_conhecimento(
1201
  auto_adjust_log: List[Dict[str, Any]] = []
1202
  stop_training_reason: Optional[str] = None
1203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1204
  # V6.5-V2-metrics — reseta histórico de métricas SOM no início de CONHECIMENTO
1205
  kls.reset_som_metric_history()
1206
  logger.info("[V6.5-V2-metrics] Histórico de métricas SOM resetado para FASE 1.")
@@ -1468,6 +1495,54 @@ def run_fase_conhecimento(
1468
  f"{len(kls.buffer_4d)} samples (cap={MAX_BUFFER_SIZE})"
1469
  )
1470
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1471
  # V6.5-V2-metrics — Computa métricas SOM após cada chunk
1472
  # (QE, TE, Kaski-Lagus, Variância Explicada, Dead Neurons,
1473
  # Colapso Topológico, Estagnação QE, Cruzamento Vizinhança).
@@ -1709,6 +1784,11 @@ def run_fase_conhecimento(
1709
  "auto_adjust_log": auto_adjust_log[-50:],
1710
  "auto_adjust_state": auto_adjuster.state.to_dict(),
1711
  "stop_training_reason": stop_training_reason,
 
 
 
 
 
1712
  }
1713
 
1714
 
 
1201
  auto_adjust_log: List[Dict[str, Any]] = []
1202
  stop_training_reason: Optional[str] = None
1203
 
1204
+ # V7-tokenizer-growth — Corpus collector para crescimento do vocabulário
1205
+ # User requirement: "verificar impacto de seq_len em vocab real=293
1206
+ # (alvo 16384)". A análise V7 revelou que o vocab real era apenas 293
1207
+ # porque o tokenizer era treinado com apenas 17 frases hardcoded.
1208
+ #
1209
+ # Prova 13 (vocab growth): O BBPE precisa de corpus ≥ 200 textos para
1210
+ # ter merges suficientes para alcançar vocab_size=16384. Com 17 frases,
1211
+ # o nº de pares únicos é ~50, limitando o vocab a ~300. Com 2000+
1212
+ # frases (coletadas durante FASE1), o nº de pares cresce para 5000+,
1213
+ # permitindo vocab alcançar 5000-10000 (próximo do alvo 16384).
1214
+ #
1215
+ # Estratégia: acumular textos dos chunks durante FASE1, e refitar o
1216
+ # tokenizer a cada 1000 amostras (10 chunks). O embedding matrix é
1217
+ # fixo (16384 rows), então qualquer crescimento de vocab é acomodado.
1218
+ # O SOM adapta-se automaticamente às novas projeções 4D do embedding.
1219
+ tokenizer_corpus_buffer: List[str] = []
1220
+ TOKENIZER_REFIT_INTERVAL_SAMPLES = 1000 # refit a cada 1000 amostras
1221
+ TOKENIZER_CORPUS_CAP = 2000 # cap para evitar OOM (memória: ~2MB)
1222
+ last_tokenizer_refit_sample_count = 0
1223
+ tokenizer_growth_log: List[Dict[str, Any]] = []
1224
+ initial_vocab_size = int(getattr(kls.tokenizer, "vocab_size", 0))
1225
+ logger.info(
1226
+ f"[V7-tokenizer-growth] Initial vocab_size={initial_vocab_size} "
1227
+ f"(target={VOCAB_SIZE}). Will refit every "
1228
+ f"{TOKENIZER_REFIT_INTERVAL_SAMPLES} samples during FASE1."
1229
+ )
1230
+
1231
  # V6.5-V2-metrics — reseta histórico de métricas SOM no início de CONHECIMENTO
1232
  kls.reset_som_metric_history()
1233
  logger.info("[V6.5-V2-metrics] Histórico de métricas SOM resetado para FASE 1.")
 
1495
  f"{len(kls.buffer_4d)} samples (cap={MAX_BUFFER_SIZE})"
1496
  )
1497
 
1498
+ # V7-tokenizer-growth — Acumula corpus para refit do tokenizer
1499
+ # User requirement: "verificar impacto de seq_len em vocab
1500
+ # real=293 (alvo 16384)". Coleta amostras reais do streaming
1501
+ # para treinar o BBPE com corpus maior.
1502
+ try:
1503
+ # Adiciona amostras do chunk ao buffer (cap para evitar OOM)
1504
+ tokenizer_corpus_buffer.extend(chunk_samples[:200])
1505
+ if len(tokenizer_corpus_buffer) > TOKENIZER_CORPUS_CAP:
1506
+ # Mantém apenas as TOKENIZER_CORPUS_CAP mais recentes
1507
+ overflow_corpus = len(tokenizer_corpus_buffer) - TOKENIZER_CORPUS_CAP
1508
+ del tokenizer_corpus_buffer[:overflow_corpus]
1509
+
1510
+ total_so_far_now = sum(samples_per_dataset.values())
1511
+ samples_since_refit = total_so_far_now - last_tokenizer_refit_sample_count
1512
+ if (samples_since_refit >= TOKENIZER_REFIT_INTERVAL_SAMPLES
1513
+ and len(tokenizer_corpus_buffer) >= 200):
1514
+ # Refit tokenizer com corpus acumulado
1515
+ vocab_before = int(getattr(kls.tokenizer, "vocab_size", 0))
1516
+ try:
1517
+ kls.tokenizer.fit(list(tokenizer_corpus_buffer))
1518
+ vocab_after = int(getattr(kls.tokenizer, "vocab_size", 0))
1519
+ growth = vocab_after - vocab_before
1520
+ tokenizer_growth_log.append({
1521
+ "step": step,
1522
+ "chunk_idx": chunk_idx_global,
1523
+ "total_samples": total_so_far_now,
1524
+ "corpus_size": len(tokenizer_corpus_buffer),
1525
+ "vocab_before": vocab_before,
1526
+ "vocab_after": vocab_after,
1527
+ "vocab_growth": growth,
1528
+ })
1529
+ logger.info(
1530
+ f"[V7-tokenizer-growth] Refit @ sample "
1531
+ f"{total_so_far_now}: vocab {vocab_before} → "
1532
+ f"{vocab_after} (+{growth}, corpus="
1533
+ f"{len(tokenizer_corpus_buffer)})"
1534
+ )
1535
+ last_tokenizer_refit_sample_count = total_so_far_now
1536
+ except Exception as tok_fit_err:
1537
+ logger.warning(
1538
+ f"[V7-tokenizer-growth] Refit failed (non-fatal): "
1539
+ f"{tok_fit_err}"
1540
+ )
1541
+ except Exception as tok_col_err:
1542
+ logger.warning(
1543
+ f"[V7-tokenizer-growth] Corpus collection failed: {tok_col_err}"
1544
+ )
1545
+
1546
  # V6.5-V2-metrics — Computa métricas SOM após cada chunk
1547
  # (QE, TE, Kaski-Lagus, Variância Explicada, Dead Neurons,
1548
  # Colapso Topológico, Estagnação QE, Cruzamento Vizinhança).
 
1784
  "auto_adjust_log": auto_adjust_log[-50:],
1785
  "auto_adjust_state": auto_adjuster.state.to_dict(),
1786
  "stop_training_reason": stop_training_reason,
1787
+ # V7-tokenizer-growth — diagnóstico de crescimento do vocabulário
1788
+ "tokenizer_growth_log": tokenizer_growth_log,
1789
+ "tokenizer_final_vocab_size": int(getattr(kls.tokenizer, "vocab_size", 0)),
1790
+ "tokenizer_initial_vocab_size": int(initial_vocab_size),
1791
+ "tokenizer_target_vocab_size": int(VOCAB_SIZE),
1792
  }
1793
 
1794
 
src/bigru_t/model/som_auto_adjust.py CHANGED
@@ -32,6 +32,8 @@ Stop-learning detection (user: "parar caso não esteja"):
32
  - QE estagnado em nível crítico (severity="severe") por ≥ 5 chunks consecutivos
33
  - Dead neuron rate > 0.8 após revival + conscience boost
34
  - All metrics NaN por 2 batches consecutivos
 
 
35
 
36
  ============================================================================
37
  MATH (Kohonen canonical + adaptive extensions)
@@ -42,8 +44,18 @@ MATH (Kohonen canonical + adaptive extensions)
42
  α₀_eff ← α₀_eff · (1 + 0.3 · norm_qe) (resposta ao QE)
43
  σ₀_eff ← σ₀_eff · (1 + 0.4 · te) (resposta ao TE)
44
  α₀_eff ← α₀_eff · (1 - 0.2 · crossing_severity) (estabiliza crossing)
 
 
45
  - Decay bound: α₀_eff ∈ [α₀, 2·α₀], σ₀_eff ∈ [σ₀, 2·σ₀]
46
  (nunca abaixo do canônico, no máximo 2× para evitar divergência)
 
 
 
 
 
 
 
 
47
  """
48
  from __future__ import annotations
49
 
@@ -75,6 +87,11 @@ class SOMAutoAdjustState:
75
  consecutive_qe_stagnant_severe: int = 0
76
  consecutive_dead_rate_critical: int = 0
77
  consecutive_nan_batches: int = 0
 
 
 
 
 
78
  # Histórico de ações tomadas (últimas 50)
79
  actions_log: List[Dict[str, Any]] = field(default_factory=list)
80
  # Flag de parada (uma vez True, treino não deve continuar)
@@ -89,6 +106,7 @@ class SOMAutoAdjustState:
89
  self.consecutive_qe_stagnant_severe = 0
90
  self.consecutive_dead_rate_critical = 0
91
  self.consecutive_nan_batches = 0
 
92
 
93
  def to_dict(self) -> Dict[str, Any]:
94
  return {
@@ -98,6 +116,7 @@ class SOMAutoAdjustState:
98
  "consecutive_qe_stagnant_severe": int(self.consecutive_qe_stagnant_severe),
99
  "consecutive_dead_rate_critical": int(self.consecutive_dead_rate_critical),
100
  "consecutive_nan_batches": int(self.consecutive_nan_batches),
 
101
  "stop_training": bool(self.stop_training),
102
  "stop_reason": self.stop_reason,
103
  "n_actions_total": int(self.n_actions_total),
@@ -131,6 +150,14 @@ class SOMAutoAdjuster:
131
  COLLAPSE_POINT_LIMIT = 3 # 3 collapses consecutivos = parar
132
  DEAD_CRITICAL_LIMIT = 5 # 5 batches críticos = parar
133
  NAN_BATCH_LIMIT = 2 # 2 batches NaN = parar
 
 
 
 
 
 
 
 
134
 
135
  def __init__(self, state: Optional[SOMAutoAdjustState] = None):
136
  self.state = state or SOMAutoAdjustState()
@@ -355,6 +382,7 @@ class SOMAutoAdjuster:
355
 
356
  # ==============================================================
357
  # 2.4 Neighborhood Crossing → -α₀ (estabiliza), +σ₀
 
358
  # ==============================================================
359
  if crossing_detected:
360
  # Desacelera aprendizado para estabilizar
@@ -367,6 +395,38 @@ class SOMAutoAdjuster:
367
  f"({crossing_severity})"
368
  )
369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  # ==============================================================
371
  # Aplica boosts efetivos ao SOM (se alterados)
372
  # ==============================================================
 
32
  - QE estagnado em nível crítico (severity="severe") por ≥ 5 chunks consecutivos
33
  - Dead neuron rate > 0.8 após revival + conscience boost
34
  - All metrics NaN por 2 batches consecutivos
35
+ - V7: Neighborhood crossing severity="severe" por ≥ 4 chunks consecutivos
36
+ (instabilidade sináptica crônica — Prova 12)
37
 
38
  ============================================================================
39
  MATH (Kohonen canonical + adaptive extensions)
 
44
  α₀_eff ← α₀_eff · (1 + 0.3 · norm_qe) (resposta ao QE)
45
  σ₀_eff ← σ₀_eff · (1 + 0.4 · te) (resposta ao TE)
46
  α₀_eff ← α₀_eff · (1 - 0.2 · crossing_severity) (estabiliza crossing)
47
+ - V7 — Crossing severo extra boost:
48
+ σ₀_eff ← σ₀_eff + 0.25 (re-organização topológica forçada)
49
  - Decay bound: α₀_eff ∈ [α₀, 2·α₀], σ₀_eff ∈ [σ₀, 2·σ₀]
50
  (nunca abaixo do canônico, no máximo 2× para evitar divergência)
51
+
52
+ Prova 12 (neighborhood_crossing_severe stop):
53
+ Se std(TE_final) > 2·growth_threshold·std(TE_initial) ou TE cresce
54
+ monotonicamente no final, severity="severe". Após 4 chunks consecutivos
55
+ severe, o treino para — a rede entrou em regime de instabilidade
56
+ sináptica crônica onde correções (-α +σ) não recuperam a topologia.
57
+ Continuar o treino só degrada mais a topologia, desperdiçando compute.
58
+ Stop-learning preserva o estado atual e permite diagnóstico.
59
  """
60
  from __future__ import annotations
61
 
 
87
  consecutive_qe_stagnant_severe: int = 0
88
  consecutive_dead_rate_critical: int = 0
89
  consecutive_nan_batches: int = 0
90
+ # V7 — Neighborhood crossing severo consecutivo (instabilidade crônica)
91
+ # User requirement: "neighborhood_crossing_severe" deve ser detectado e
92
+ # tratado. Após N batches consecutivos com severity="severe", o treino
93
+ # para (a rede sofreu instabilidade sináptica crônica).
94
+ consecutive_crossing_severe: int = 0
95
  # Histórico de ações tomadas (últimas 50)
96
  actions_log: List[Dict[str, Any]] = field(default_factory=list)
97
  # Flag de parada (uma vez True, treino não deve continuar)
 
106
  self.consecutive_qe_stagnant_severe = 0
107
  self.consecutive_dead_rate_critical = 0
108
  self.consecutive_nan_batches = 0
109
+ self.consecutive_crossing_severe = 0
110
 
111
  def to_dict(self) -> Dict[str, Any]:
112
  return {
 
116
  "consecutive_qe_stagnant_severe": int(self.consecutive_qe_stagnant_severe),
117
  "consecutive_dead_rate_critical": int(self.consecutive_dead_rate_critical),
118
  "consecutive_nan_batches": int(self.consecutive_nan_batches),
119
+ "consecutive_crossing_severe": int(self.consecutive_crossing_severe),
120
  "stop_training": bool(self.stop_training),
121
  "stop_reason": self.stop_reason,
122
  "n_actions_total": int(self.n_actions_total),
 
150
  COLLAPSE_POINT_LIMIT = 3 # 3 collapses consecutivos = parar
151
  DEAD_CRITICAL_LIMIT = 5 # 5 batches críticos = parar
152
  NAN_BATCH_LIMIT = 2 # 2 batches NaN = parar
153
+ # V7 — Neighborhood crossing severo (user requirement)
154
+ # 4 batches consecutivos com crossing_severity="severe" = parar treino.
155
+ # Justificativa matemática (Prova 12): se a oscilação crônica do TE
156
+ # persiste por 4+ batches apesar das correções (-α +σ), isto indica
157
+ # que a vizinhança topológica não consegue fixar — a rede entrou em
158
+ # regime de instabilidade sináptica crônica, e continuar o treino
159
+ # só degrada a topologia. Stop-learning evita desperdiçar compute.
160
+ CROSSING_SEVERE_LIMIT = 4
161
 
162
  def __init__(self, state: Optional[SOMAutoAdjustState] = None):
163
  self.state = state or SOMAutoAdjustState()
 
382
 
383
  # ==============================================================
384
  # 2.4 Neighborhood Crossing → -α₀ (estabiliza), +σ₀
385
+ # V7 — Crossing severo consecutivo → stop-learning (Prova 12)
386
  # ==============================================================
387
  if crossing_detected:
388
  # Desacelera aprendizado para estabilizar
 
395
  f"({crossing_severity})"
396
  )
397
 
398
+ # V7 — Contador de crossing severo consecutivo
399
+ if crossing_severity == "severe":
400
+ self.state.consecutive_crossing_severe += 1
401
+ actions.append(
402
+ f"crossing_severe_consecutive="
403
+ f"{self.state.consecutive_crossing_severe} "
404
+ f"(limit={self.CROSSING_SEVERE_LIMIT})"
405
+ )
406
+ # Intervenção extra em crossing severo: boost agressivo de σ
407
+ # para forçar re-organização topológica.
408
+ self.state.sigma0_boost = min(2.0, self.state.sigma0_boost + 0.25)
409
+ actions.append(
410
+ "crossing_severe_extra_boost: σ+0.25 (re-organização forçada)"
411
+ )
412
+ if self.state.consecutive_crossing_severe >= self.CROSSING_SEVERE_LIMIT:
413
+ self.state.stop_training = True
414
+ self.state.stop_reason = (
415
+ f"neighborhood_crossing_severe_consecutive="
416
+ f"{self.state.consecutive_crossing_severe}"
417
+ )
418
+ logger.error(
419
+ f"[som_auto_adjust] STOP: {self.state.stop_reason} "
420
+ f"(instabilidade sináptica crônica por "
421
+ f"{self.state.consecutive_crossing_severe} batches)"
422
+ )
423
+ else:
424
+ # Crossing mild: reseta contador de severo (mild é recuperável)
425
+ self.state.consecutive_crossing_severe = 0
426
+ else:
427
+ # Sem crossing: reseta contador
428
+ self.state.consecutive_crossing_severe = 0
429
+
430
  # ==============================================================
431
  # Aplica boosts efetivos ao SOM (se alterados)
432
  # ==============================================================
src/bigru_t/training/ewc.py CHANGED
@@ -1,6 +1,37 @@
1
- """ewc.py — V6: Elastic Weight Consolidation with Kohonen 4D per-neuron support.
 
2
 
3
  ═══════════════════════════════════════════════════════════════════════════════
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  V6 — EWC + KOHONEN 4D PER-NEURON WEIGHTS
5
  ═══════════════════════════════════════════════════════════════════════════════
6
 
@@ -80,7 +111,7 @@ class EWCConfigV6:
80
  fisher_n_samples: int = 32
81
  fisher_batch_size: int = 4
82
  online_ewc: bool = True
83
- online_decay: float = 0.99
84
  fisher_smoothing_alpha: float = 0.1
85
  adaptive_lambda: bool = True
86
  fisher_clip_eps: float = 1e-8
@@ -92,6 +123,14 @@ class EWCConfigV6:
92
  skip_som_filled_neurons: bool = True # default True (user requirement)
93
  # Skip_mask é lido do OrqCell.neuron_filled_mask em compute_fisher()
94
  # e aplicado em compute_penalty() para zerar a penalidade dos filled.
 
 
 
 
 
 
 
 
95
 
96
 
97
  class EWCV6:
@@ -124,6 +163,16 @@ class EWCV6:
124
  self._last_task_grad_norm: float = 0.0
125
  self._last_ewc_grad_norm: float = 0.0
126
  self._adaptive_lambda: float = self.cfg.lambda_ewc
 
 
 
 
 
 
 
 
 
 
127
  # Detectar OrqCells no modelo
128
  self.orq_cells: Dict[str, nn.Module] = self._find_orq_cells()
129
 
@@ -241,8 +290,8 @@ class EWCV6:
241
  for orq_name in neuron_fisher_accum:
242
  neuron_fisher_accum[orq_name] /= max(1, n_used // bs)
243
 
244
- # Smooth + clip Fisher
245
- self.fisher = self._smooth_and_clip(fisher_accum)
246
  # V6.1 — Aplicar skip mask também no Fisher CLÁSSICO para
247
  # orq_cell.neuron_cache (evita dupla penalização: o classic Fisher
248
  # e o Kohonen per-neuron Fisher apontam para o MESMO parâmetro).
@@ -253,13 +302,34 @@ class EWCV6:
253
  if not hasattr(orq_cell, "neuron_filled_mask"):
254
  continue
255
  param_name = f"{orq_name}.neuron_cache"
256
- if param_name not in self.fisher:
257
  continue
258
  filled = orq_cell.neuron_filled_mask.bool()
259
  keep_mask = (~filled).float() # 1 onde EWC atua, 0 onde skip
260
  # Zera o Fisher das posições filled no classic Fisher
261
- self.fisher[param_name] = self.fisher[param_name] * keep_mask.unsqueeze(-1)
262
- self.neuron_fisher = {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  self.fisher_neuron_mask = {} # V6.1
264
  for orq_name, f_tensor in neuron_fisher_accum.items():
265
  # V6.1 — Aplicar skip mask: neurônios filled no SOM NÃO recebem Fisher
@@ -280,21 +350,70 @@ class EWCV6:
280
  self.fisher_neuron_mask[orq_name] = torch.ones(
281
  f_tensor.size(0), dtype=torch.bool
282
  )
283
- self.neuron_fisher[orq_name] = self._smooth_and_clip_tensor(f_tensor)
284
-
285
- # Salvar pesos ótimos atuais (anchors)
286
- self.optimal_weights = {
 
 
 
 
 
 
 
 
 
 
 
 
287
  name: p.detach().clone()
288
  for name, p in self.model.named_parameters()
289
  if name in self.fisher
290
  }
 
 
 
 
 
 
 
 
 
 
 
 
291
  for orq_name, orq_cell in self.orq_cells.items():
292
  if orq_name in self.neuron_fisher:
293
- self.neuron_optimal[orq_name] = orq_cell.neuron_cache.detach().clone()
294
- # Salvar topologia do grid (fixa)
 
 
 
 
 
 
 
 
295
  if hasattr(orq_cell, "grid_dist"):
296
  self.neuron_grid_dist[orq_name] = orq_cell.grid_dist.detach().clone()
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  self.n_tasks += 1
299
  self.model.zero_grad()
300
  gc.collect(0)
@@ -501,6 +620,12 @@ class EWCV6:
501
  "skip_som_filled_neurons": self.cfg.skip_som_filled_neurons,
502
  "n_active_ewc_neurons": n_active, # EWC atua nestes
503
  "n_masked_som_neurons": n_masked, # SOM já cobre estes (não duplica)
 
 
 
 
 
 
504
  }
505
 
506
 
 
1
+ """ewc.py — V6/V7: Elastic Weight Consolidation with Kohonen 4D per-neuron support
2
+ + Fisher accumulation (online EWC with EMA decay).
3
 
4
  ═══════════════════════════════════════════════════════════════════════════════
5
+ V7 — FISHER ACCUMULATION (ONLINE EWC)
6
+ ═══════════════════════════════════════════════════════════════════════════════
7
+
8
+ V6 mantinha `online_ewc: bool = True` e `online_decay: float = 0.99` na
9
+ configuração, mas NUNCA os utilizava — a cada chamada de `compute_fisher()`,
10
+ a Fisher anterior era SOBRESCRITA pela nova (perda total do conhecimento
11
+ de tarefas anteriores). Isto explica o sintoma observado na análise V7:
12
+
13
+ Fisher_w_mean = 0.0 (EWC sem acumulação Fisher — possível bug)
14
+
15
+ A correção V7 implementa a acumulação online clássica (Schwarz et al. 2018):
16
+
17
+ F_new = decay · F_old + (1 - decay) · F_computed
18
+
19
+ onde:
20
+ - F_old : Fisher acumulada de tarefas anteriores (persistente)
21
+ - F_computed: Fisher computada nesta tarefa (a partir de gradients²)
22
+ - decay : fator EMA (default 0.99 — preserva 99% do passado)
23
+ - F_new : Fisher acumulada após esta tarefa
24
+
25
+ Analogamente, os pesos ótimos (anchors) seguem EMA:
26
+ W*_new = decay · W*_old + (1 - decay) · W_current
27
+
28
+ Isto garante que:
29
+ 1. Tarefas antigas continuem a ser "ancoradas" mesmo após muitas tarefas
30
+ novas (evita catastrophic forgetting multi-tarefa).
31
+ 2. A Fisher seja suave (sem saltos bruscos) — estável sob gradient noise.
32
+ 3. A penalty V6 (clássica + Kohonen per-neuron + topológica) é aplicada
33
+ sobre a Fisher ACUMULADA, não sobre a Fisher da última tarefa.
34
+
35
  V6 — EWC + KOHONEN 4D PER-NEURON WEIGHTS
36
  ═══════════════════════════════════════════════════════════════════════════════
37
 
 
111
  fisher_n_samples: int = 32
112
  fisher_batch_size: int = 4
113
  online_ewc: bool = True
114
+ online_decay: float = 0.99 # V7 — agora EFETIVAMENTE usado (era decorativo)
115
  fisher_smoothing_alpha: float = 0.1
116
  adaptive_lambda: bool = True
117
  fisher_clip_eps: float = 1e-8
 
123
  skip_som_filled_neurons: bool = True # default True (user requirement)
124
  # Skip_mask é lido do OrqCell.neuron_filled_mask em compute_fisher()
125
  # e aplicado em compute_penalty() para zerar a penalidade dos filled.
126
+ # ───────────────────────────────────────────────────────────────────────
127
+ # V7 — Fisher accumulation diagnostics (apenas leitura, não-configurável)
128
+ # ───────────────────────────────────────────────────────────────────────
129
+ # fisher_accumulation_active: se True, compute_fisher() faz EMA entre
130
+ # F_old e F_computed (V7 — ativação do online_ewc).
131
+ # fisher_ema_initialized: True após a 1ª compute_fisher (não há F_old
132
+ # na 1ª chamada — apenas inicializa).
133
+ fisher_accumulation_active: bool = True # V7 — ativa por padrão
134
 
135
 
136
  class EWCV6:
 
163
  self._last_task_grad_norm: float = 0.0
164
  self._last_ewc_grad_norm: float = 0.0
165
  self._adaptive_lambda: float = self.cfg.lambda_ewc
166
+ # ───────────────────────────────────────────────────────────────────
167
+ # V7 — Fisher accumulation state (online EWC with EMA)
168
+ # ───────────────────────────────────────────────────────────────────
169
+ # _fisher_ema_initialized: False até a 1ª compute_fisher() concluir.
170
+ # Antes disso, compute_fisher() apenas inicializa F = F_computed.
171
+ # Após isso, F = decay·F_old + (1-decay)·F_computed.
172
+ self._fisher_ema_initialized: bool = False
173
+ # Diagnóstico: média da Fisher acumulada (para auditoria)
174
+ self._fisher_w_mean: float = 0.0 # média da Fisher clássica (scalar)
175
+ self._fisher_n_mean: float = 0.0 # média da Fisher per-neuron (scalar)
176
  # Detectar OrqCells no modelo
177
  self.orq_cells: Dict[str, nn.Module] = self._find_orq_cells()
178
 
 
290
  for orq_name in neuron_fisher_accum:
291
  neuron_fisher_accum[orq_name] /= max(1, n_used // bs)
292
 
293
+ # Smooth + clip Fisher (compute F_computed — smoothed/clipped)
294
+ fisher_computed = self._smooth_and_clip(fisher_accum)
295
  # V6.1 — Aplicar skip mask também no Fisher CLÁSSICO para
296
  # orq_cell.neuron_cache (evita dupla penalização: o classic Fisher
297
  # e o Kohonen per-neuron Fisher apontam para o MESMO parâmetro).
 
302
  if not hasattr(orq_cell, "neuron_filled_mask"):
303
  continue
304
  param_name = f"{orq_name}.neuron_cache"
305
+ if param_name not in fisher_computed:
306
  continue
307
  filled = orq_cell.neuron_filled_mask.bool()
308
  keep_mask = (~filled).float() # 1 onde EWC atua, 0 onde skip
309
  # Zera o Fisher das posições filled no classic Fisher
310
+ fisher_computed[param_name] = fisher_computed[param_name] * keep_mask.unsqueeze(-1)
311
+
312
+ # V7 ── Fisher accumulation (online EWC with EMA) ─────────────────
313
+ # F_new = decay · F_old + (1 - decay) · F_computed
314
+ # Se for a 1ª chamada (não inicializado), apenas copia F_computed.
315
+ # Aplicado APÓS smoothing/clip/skip_mask para herdar as propriedades
316
+ # de estabilidade numérica (log-clip evita explosão de Fisher EMA).
317
+ if self.cfg.online_ewc and self.cfg.fisher_accumulation_active \
318
+ and self._fisher_ema_initialized and len(self.fisher) > 0:
319
+ decay = float(self.cfg.online_decay)
320
+ for name, f_new_computed in fisher_computed.items():
321
+ f_old = self.fisher.get(name)
322
+ if f_old is not None and f_old.shape == f_new_computed.shape:
323
+ fisher_computed[name] = (
324
+ decay * f_old + (1.0 - decay) * f_new_computed
325
+ )
326
+ # else: novo parâmetro — apenas usa F_computed (cold start)
327
+ # Aplica Fisher final (acumulada ou cold-start)
328
+ self.fisher = fisher_computed
329
+
330
+ # ── Per-neuron Fisher accumulation (V7) ──────────────────────────
331
+ # Mesma lógica EMA para neuron_fisher (orq_cell).
332
+ neuron_fisher_computed: Dict[str, torch.Tensor] = {}
333
  self.fisher_neuron_mask = {} # V6.1
334
  for orq_name, f_tensor in neuron_fisher_accum.items():
335
  # V6.1 — Aplicar skip mask: neurônios filled no SOM NÃO recebem Fisher
 
350
  self.fisher_neuron_mask[orq_name] = torch.ones(
351
  f_tensor.size(0), dtype=torch.bool
352
  )
353
+ f_smoothed = self._smooth_and_clip_tensor(f_tensor)
354
+ # V7 — EMA accumulation sobre neuron_fisher
355
+ if self.cfg.online_ewc and self.cfg.fisher_accumulation_active \
356
+ and self._fisher_ema_initialized \
357
+ and orq_name in self.neuron_fisher:
358
+ f_old = self.neuron_fisher[orq_name]
359
+ if f_old.shape == f_smoothed.shape:
360
+ decay = float(self.cfg.online_decay)
361
+ f_smoothed = decay * f_old + (1.0 - decay) * f_smoothed
362
+ neuron_fisher_computed[orq_name] = f_smoothed
363
+ self.neuron_fisher = neuron_fisher_computed
364
+
365
+ # Salvar pesos ótimos atuais (anchors) — V7 EMA accumulation
366
+ # W*_new = decay · W*_old + (1 - decay) · W_current
367
+ # Se 1ª chamada, apenas W*_new = W_current (cold start).
368
+ new_optimal_weights = {
369
  name: p.detach().clone()
370
  for name, p in self.model.named_parameters()
371
  if name in self.fisher
372
  }
373
+ if (self.cfg.online_ewc and self.cfg.fisher_accumulation_active
374
+ and self._fisher_ema_initialized and len(self.optimal_weights) > 0):
375
+ decay = float(self.cfg.online_decay)
376
+ for name, w_new in new_optimal_weights.items():
377
+ w_old = self.optimal_weights.get(name)
378
+ if w_old is not None and w_old.shape == w_new.shape:
379
+ new_optimal_weights[name] = (
380
+ decay * w_old + (1.0 - decay) * w_new
381
+ )
382
+ self.optimal_weights = new_optimal_weights
383
+
384
+ # V7 — EMA accumulation para neuron_optimal (orq_cell anchors)
385
  for orq_name, orq_cell in self.orq_cells.items():
386
  if orq_name in self.neuron_fisher:
387
+ new_w_n = orq_cell.neuron_cache.detach().clone()
388
+ if (self.cfg.online_ewc and self.cfg.fisher_accumulation_active
389
+ and self._fisher_ema_initialized
390
+ and orq_name in self.neuron_optimal):
391
+ w_old = self.neuron_optimal[orq_name]
392
+ if w_old.shape == new_w_n.shape:
393
+ decay = float(self.cfg.online_decay)
394
+ new_w_n = decay * w_old + (1.0 - decay) * new_w_n
395
+ self.neuron_optimal[orq_name] = new_w_n
396
+ # Salvar topologia do grid (fixa — NÃO sofre EMA, é constante)
397
  if hasattr(orq_cell, "grid_dist"):
398
  self.neuron_grid_dist[orq_name] = orq_cell.grid_dist.detach().clone()
399
 
400
+ # V7 — Diagnóstico: média das Fishers acumuladas
401
+ if self.fisher:
402
+ try:
403
+ all_means = [float(f.mean().item()) for f in self.fisher.values()]
404
+ self._fisher_w_mean = sum(all_means) / len(all_means) if all_means else 0.0
405
+ except (RuntimeError, ValueError):
406
+ self._fisher_w_mean = 0.0
407
+ if self.neuron_fisher:
408
+ try:
409
+ all_n_means = [float(f.mean().item()) for f in self.neuron_fisher.values()]
410
+ self._fisher_n_mean = sum(all_n_means) / len(all_n_means) if all_n_means else 0.0
411
+ except (RuntimeError, ValueError):
412
+ self._fisher_n_mean = 0.0
413
+
414
+ # V7 — Marca que a Fisher foi inicializada (próxima compute_fisher fará EMA)
415
+ self._fisher_ema_initialized = True
416
+
417
  self.n_tasks += 1
418
  self.model.zero_grad()
419
  gc.collect(0)
 
620
  "skip_som_filled_neurons": self.cfg.skip_som_filled_neurons,
621
  "n_active_ewc_neurons": n_active, # EWC atua nestes
622
  "n_masked_som_neurons": n_masked, # SOM já cobre estes (não duplica)
623
+ # V7 — Fisher accumulation diagnostics
624
+ "online_ewc_active": bool(self.cfg.online_ewc and self.cfg.fisher_accumulation_active),
625
+ "online_decay": float(self.cfg.online_decay),
626
+ "fisher_ema_initialized": bool(self._fisher_ema_initialized),
627
+ "fisher_w_mean": float(self._fisher_w_mean), # diagnostic
628
+ "fisher_n_mean": float(self._fisher_n_mean), # diagnostic
629
  }
630
 
631
 
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": 10000,
7
+ "n_errors": 0,
8
+ "last_norm_in": 111.79922485351562,
9
+ "last_norm_out": 114.68800354003906,
10
+ "last_attn_activated": true,
11
+ "last_attn_diff_norm": 113.93474578857422,
12
+ "n_heads": 8,
13
+ "logic_functional": true
14
+ },
15
+ "active": true,
16
+ "logic_functional": true,
17
+ "n_calls": 10000,
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:7748a306b4aac259a9d877b2672fe5e7d277872b75854a4084b58996b6712cfa
3
+ size 118971444
v6_5_v2_phases_eval.json ADDED
The diff for this file is too large to render. See raw diff
 
v6_5_v2_predict_fix_eval.json ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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": "short_text",
9
+ "probability": 0.4827089011669159,
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": "short_text",
18
+ "probability": 0.35426780581474304,
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": "long_text",
27
+ "probability": 0.5526613593101501,
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": "short_text",
36
+ "probability": 0.3866918683052063,
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": "short_text",
45
+ "probability": 0.4471302032470703,
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": "short_text",
54
+ "probability": 0.35634148120880127,
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": "punctuated",
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": "normalized_text",
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": "assistant_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": "response",
96
+ "valid_for_dataset": true
97
+ },
98
+ {
99
+ "dataset": "adalbertojunior/punctuation-ptbr",
100
+ "expected_labels": [
101
+ "unpunctuated",
102
+ "punctuated"
103
+ ],
104
+ "prediction": "punctuated",
105
+ "valid_for_dataset": true
106
+ },
107
+ {
108
+ "dataset": "iara-project/news-articles-ptbr-dataset",
109
+ "expected_labels": [
110
+ "headline",
111
+ "body"
112
+ ],
113
+ "prediction": "body",
114
+ "valid_for_dataset": true
115
+ },
116
+ {
117
+ "dataset": "manoela/noticias_ptbr",
118
+ "expected_labels": [
119
+ "headline",
120
+ "body"
121
+ ],
122
+ "prediction": "body",
123
+ "valid_for_dataset": true
124
+ },
125
+ {
126
+ "dataset": "BrunoN-Dev/corpus-ptbr-v1",
127
+ "expected_labels": [
128
+ "short_text",
129
+ "long_text"
130
+ ],
131
+ "prediction": "long_text",
132
+ "valid_for_dataset": true
133
+ }
134
+ ],
135
+ "summary": {
136
+ "n_returns_gato": 0,
137
+ "n_returns_cachorro": 0,
138
+ "n_returns_registry_label": 6,
139
+ "n_returns_default_label": 0,
140
+ "hardcoded_bug_present": false,
141
+ "predict_fix_verified": true
142
+ },
143
+ "quality_assessment": {
144
+ "fix_status": "PASS",
145
+ "note": "predict() não retorna mais 'gato'/'cachorro' fixos — usa label_registry dinâmico."
146
+ }
147
+ }
v6_5_v2_report.json ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "V6.5-V2",
3
+ "timestamp": "2026-08-09T21:42:58.763756",
4
+ "config": {
5
+ "som_grid": [
6
+ 4,
7
+ 4,
8
+ 4,
9
+ 4
10
+ ],
11
+ "n_neurons": 256,
12
+ "hidden_dim": 1024,
13
+ "vocab_size": 16384,
14
+ "n_hypotheses": 16,
15
+ "n_trials": 3,
16
+ "hyp_train_steps": 30,
17
+ "stream_batch_size": 100,
18
+ "meta_conhecimento": 8000,
19
+ "meta_punicão": 2000,
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": 95.63248199992813,
58
+ "avg_time_ms": 96.47887749997608,
59
+ "best_tflops": 1.3384573664008448,
60
+ "avg_tflops": 1.3267152698789613,
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": 8000,
88
+ "meta_atingida": true,
89
+ "elapsed_s": 576.7120866775513,
90
+ "storage_critical_stopped": false
91
+ },
92
+ "fase_2_punicão_summary": {
93
+ "total_samples": 2000,
94
+ "meta_atingida": true,
95
+ "elapsed_s": 281.3677294254303,
96
+ "punishment_events": 24,
97
+ "hypotheses_trainings": 12,
98
+ "delta_applications": 12,
99
+ "skipped": false
100
+ },
101
+ "attention_eval_summary": {
102
+ "active": true,
103
+ "logic_functional": true,
104
+ "n_calls": 10000,
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": 0,
118
+ "answer_rate": 1.0,
119
+ "think_rate": 0.0,
120
+ "avg_latency_ms": 13.19591204325358,
121
+ "avg_reasoning_length": 68.66666666666667
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": 118.971444,
128
+ "size_gb": 0.11080079153180122,
129
+ "size_status": "OK",
130
+ "size_within_1gb_limit": true,
131
+ "reason": "end_of_training_v2",
132
+ "step": 700,
133
+ "total_samples": 10000,
134
+ "n_tensors": 7,
135
+ "n_buffer_tail": 64
136
+ },
137
+ "final_v2_metrics": {
138
+ "version": "V2-dynamic",
139
+ "n_hypotheses": 16,
140
+ "n_hypotheses_active": 16,
141
+ "max_n_hypotheses": 32,
142
+ "n_trials": 6,
143
+ "hyp_train_steps": 80,
144
+ "hyp_lr": 0.0001,
145
+ "delta_scale": 0.0010000000474974513,
146
+ "n_generators": 32,
147
+ "punishment_count": 0,
148
+ "success_count": 0,
149
+ "training_ready": false,
150
+ "classifier_trained": true,
151
+ "ewc_reference_set": true,
152
+ "buffer_size": 256,
153
+ "total_hyp_steps_executed": 710,
154
+ "n_train_hyp_calls": 12,
155
+ "dynamic_adaptation": {
156
+ "loss_history_len": 8,
157
+ "loss_stats": {
158
+ "slope": 0.0008405418623061408,
159
+ "volatility": 0.007682365915095164,
160
+ "mean": 0.6946855634450912,
161
+ "std": 0.005336828694319248,
162
+ "n": 8
163
+ },
164
+ "punishment_rate": 1.0,
165
+ "punishment_window_size": 12,
166
+ "n_adaptations": 20,
167
+ "limits": {
168
+ "min_n_hypotheses": 4,
169
+ "max_n_hypotheses": 32,
170
+ "min_n_trials": 1,
171
+ "max_n_trials": 6,
172
+ "min_hyp_train_steps": 10,
173
+ "max_hyp_train_steps": 80
174
+ },
175
+ "last_5_adaptations": [
176
+ {
177
+ "trigger": "punishment",
178
+ "step": 19,
179
+ "before": {
180
+ "n_hypotheses": 26,
181
+ "n_trials": 6,
182
+ "hyp_train_steps": 80
183
+ },
184
+ "after": {
185
+ "n_hypotheses": 24,
186
+ "n_trials": 6,
187
+ "hyp_train_steps": 80
188
+ },
189
+ "adapted": true,
190
+ "rules_fired": [
191
+ "n_hyp-2 (vol=0.016 → 24)"
192
+ ],
193
+ "loss_stats": {
194
+ "slope": -0.0026504212901705786,
195
+ "volatility": 0.015901827414676772,
196
+ "mean": 0.6972703039646149,
197
+ "std": 0.01108787203502452,
198
+ "n": 8
199
+ },
200
+ "punishment_rate": 1.0
201
+ },
202
+ {
203
+ "trigger": "auto",
204
+ "step": 20,
205
+ "before": {
206
+ "n_hypotheses": 24,
207
+ "n_trials": 6,
208
+ "hyp_train_steps": 80
209
+ },
210
+ "after": {
211
+ "n_hypotheses": 22,
212
+ "n_trials": 6,
213
+ "hyp_train_steps": 80
214
+ },
215
+ "adapted": true,
216
+ "rules_fired": [
217
+ "n_hyp-2 (vol=0.007 → 22)"
218
+ ],
219
+ "loss_stats": {
220
+ "slope": 0.0013643034866877965,
221
+ "volatility": 0.007450016062041352,
222
+ "mean": 0.6949898302555084,
223
+ "std": 0.0051776853983589305,
224
+ "n": 8
225
+ },
226
+ "punishment_rate": 1.0
227
+ },
228
+ {
229
+ "trigger": "punishment",
230
+ "step": 21,
231
+ "before": {
232
+ "n_hypotheses": 22,
233
+ "n_trials": 6,
234
+ "hyp_train_steps": 80
235
+ },
236
+ "after": {
237
+ "n_hypotheses": 20,
238
+ "n_trials": 6,
239
+ "hyp_train_steps": 80
240
+ },
241
+ "adapted": true,
242
+ "rules_fired": [
243
+ "n_hyp-2 (vol=0.007 → 20)"
244
+ ],
245
+ "loss_stats": {
246
+ "slope": 0.0013643034866877965,
247
+ "volatility": 0.007450016062041352,
248
+ "mean": 0.6949898302555084,
249
+ "std": 0.0051776853983589305,
250
+ "n": 8
251
+ },
252
+ "punishment_rate": 1.0
253
+ },
254
+ {
255
+ "trigger": "auto",
256
+ "step": 22,
257
+ "before": {
258
+ "n_hypotheses": 20,
259
+ "n_trials": 6,
260
+ "hyp_train_steps": 80
261
+ },
262
+ "after": {
263
+ "n_hypotheses": 18,
264
+ "n_trials": 6,
265
+ "hyp_train_steps": 80
266
+ },
267
+ "adapted": true,
268
+ "rules_fired": [
269
+ "n_hyp-2 (vol=0.008 → 18)"
270
+ ],
271
+ "loss_stats": {
272
+ "slope": 0.0008405418623061408,
273
+ "volatility": 0.007682365915095164,
274
+ "mean": 0.6946855634450912,
275
+ "std": 0.005336828694319248,
276
+ "n": 8
277
+ },
278
+ "punishment_rate": 1.0
279
+ },
280
+ {
281
+ "trigger": "punishment",
282
+ "step": 23,
283
+ "before": {
284
+ "n_hypotheses": 18,
285
+ "n_trials": 6,
286
+ "hyp_train_steps": 80
287
+ },
288
+ "after": {
289
+ "n_hypotheses": 16,
290
+ "n_trials": 6,
291
+ "hyp_train_steps": 80
292
+ },
293
+ "adapted": true,
294
+ "rules_fired": [
295
+ "n_hyp-2 (vol=0.008 → 16)"
296
+ ],
297
+ "loss_stats": {
298
+ "slope": 0.0008405418623061408,
299
+ "volatility": 0.007682365915095164,
300
+ "mean": 0.6946855634450912,
301
+ "std": 0.005336828694319248,
302
+ "n": 8
303
+ },
304
+ "punishment_rate": 1.0
305
+ }
306
+ ]
307
+ }
308
+ }
309
+ }
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": "long_text",
22
+ "reasoning_length": 68,
23
+ "has_think": false,
24
+ "has_plan": false,
25
+ "has_answer": true,
26
+ "has_decompose": false,
27
+ "think_preview": "",
28
+ "answer_preview": "ReasoningEngine disabled. SOM prediction: long_text",
29
+ "raw_response_preview": "<answer>ReasoningEngine disabled. SOM prediction: long_text</answer>",
30
+ "n_tags": 1,
31
+ "latency_ms": 28.188228607177734
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": "short_text",
40
+ "reasoning_length": 69,
41
+ "has_think": false,
42
+ "has_plan": false,
43
+ "has_answer": true,
44
+ "has_decompose": false,
45
+ "think_preview": "",
46
+ "answer_preview": "ReasoningEngine disabled. SOM prediction: short_text",
47
+ "raw_response_preview": "<answer>ReasoningEngine disabled. SOM prediction: short_text</answer>",
48
+ "n_tags": 1,
49
+ "latency_ms": 5.802154541015625
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": "short_text",
58
+ "reasoning_length": 69,
59
+ "has_think": false,
60
+ "has_plan": false,
61
+ "has_answer": true,
62
+ "has_decompose": false,
63
+ "think_preview": "",
64
+ "answer_preview": "ReasoningEngine disabled. SOM prediction: short_text",
65
+ "raw_response_preview": "<answer>ReasoningEngine disabled. SOM prediction: short_text</answer>",
66
+ "n_tags": 1,
67
+ "latency_ms": 5.597352981567383
68
+ }
69
+ ],
70
+ "summary": {
71
+ "n_with_answer": 3,
72
+ "n_with_think": 0,
73
+ "answer_rate": 1.0,
74
+ "think_rate": 0.0,
75
+ "avg_latency_ms": 13.19591204325358,
76
+ "avg_reasoning_length": 68.66666666666667
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
+ }