PowerMachine commited on
Commit
9ecd0c8
·
verified ·
1 Parent(s): 1af55e5

Delete cnn_bigru/tests/test_50_samples.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. cnn_bigru/tests/test_50_samples.py +0 -513
cnn_bigru/tests/test_50_samples.py DELETED
@@ -1,513 +0,0 @@
1
- """test_50_samples.py — Teste de 50 amostras para erros lógicos ou falhas.
2
-
3
- Executa o pipeline completo:
4
- 1. Inicializa xeon_runtime + memory_optimizer
5
- 2. Treina BBPE tokenizer em corpus sintético
6
- 3. Cria dataset streaming multimodal (50 amostras)
7
- 4. Instancia modelo multimodal + generator + verifier + anti-hallucination
8
- 5. Executa treinamento cooperativo com:
9
- - Synergy search (N tentativas)
10
- - Hypothesis controller (ativa em punições)
11
- - Auto-learner (ajuste dinâmico de LR + spectral norm)
12
- 6. Executa inferência com sampling
13
- 7. Avalia perplexidade
14
- 8. Reporta erros lógicos/falhas encontradas
15
-
16
- Usage:
17
- python -m cnn_bigru.tests.test_50_samples
18
- """
19
- from __future__ import annotations
20
-
21
- import logging
22
- import os
23
- import sys
24
- import time
25
- import traceback
26
- from pathlib import Path
27
- from typing import Dict, List
28
-
29
- # Setup paths (must come before torch import for xeon_runtime)
30
- PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
31
- sys.path.insert(0, str(PROJECT_ROOT))
32
-
33
- # Ativa Xeon runtime ANTES de importar torch
34
- from cnn_bigru.utils.xeon_runtime import optimize_xeon_environment
35
- N_CORES = optimize_xeon_environment()
36
-
37
- import numpy as np
38
- import torch
39
- from torch.utils.data import DataLoader
40
-
41
- from cnn_bigru.tokenizer.bbpe_tokenizer import BBPETokenizer
42
- from cnn_bigru.data.streaming_dataset import (
43
- MultimodalStreamingDataset,
44
- collate_multimodal,
45
- )
46
- from cnn_bigru.models.multimodal_model import MultimodalCNNBiGRU
47
- from cnn_bigru.models.generator_verifier import (
48
- GeneratorCNNBiGRU,
49
- VerifierCNNBiGRU,
50
- AntiHallucinationLayer,
51
- )
52
- from cnn_bigru.losses.losses import LossConfig, MultiLoss
53
- from cnn_bigru.training.trainer import TrainerConfig, CooperativeTrainer
54
- from cnn_bigru.training.auto_learner import (
55
- AutoLearnConfig,
56
- orthogonal_init_model,
57
- )
58
- from cnn_bigru.training.hypothesis_controller import (
59
- HypothesisConfig,
60
- HypothesisController,
61
- )
62
- from cnn_bigru.inference.inference import (
63
- generate_with_sampling,
64
- evaluate_perplexity,
65
- )
66
- from cnn_bigru.utils.memory_optimizer import MemoryOptimizer
67
-
68
- logging.basicConfig(
69
- level=logging.INFO,
70
- format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
71
- datefmt="%H:%M:%S",
72
- )
73
- logger = logging.getLogger("test_50")
74
-
75
-
76
- # ============================================================================
77
- # Corpus para treino do tokenizer
78
- # ============================================================================
79
-
80
- CORPUS_TEXTS = [
81
- "o modelo cooperativo cnn-bigru combina fluxos paralelos",
82
- "a atencao cruzada troca informacoes entre redes a e b",
83
- "gru bidirecional captura dependencias temporais em ambas direcoes",
84
- "a porta de atenuacao controla o fluxo de informacao entre celulas",
85
- "a camada anti-alucinacao usa logica fuzzy de lukasiewicz",
86
- "o verificador classifica passos com sigmoid binaria",
87
- "penalidades linear e exponencial reduzem o erro grave",
88
- "ajuste dinamico de lr estabiliza o treinamento cooperativo",
89
- "normalizacao espectral limita a norma dos pesos",
90
- "inicializacao ortogonal estabiliza matrizes recorrentes",
91
- "o gerador decodificador usa atencao bahdanau sobre o encoder",
92
- "a fusao multimodal combina texto imagem e audio",
93
- "hipoteses sao ativadas quando o verificador pune o passo",
94
- "synergy search tenta n configuracoes e escolhe a melhor",
95
- "a perplexidade mede a confusao do modelo na previsao",
96
- "top-k e top-p filtram a distribuicao de probabilidade",
97
- "temperature ajusta a entropia das previsoes do modelo",
98
- "presence penalty pune tokens ja aparecidos na geracao",
99
- "frequency penalty pune proporcionalmente a frequencia do token",
100
- "streaming dataset carrega amostras sem materializacao completa",
101
- "byte bpe tokeniza qualquer string utf-8 sem unk",
102
- "o otimizador adamw combina momentum e weight decay",
103
- "gradient clipping previne explosao de gradiente",
104
- "amp reduz vram com precisao mista bfloat16",
105
- "memory optimizer limpa cache entre batches",
106
- ] * 4 # ~100 amostras para treino BBPE
107
-
108
-
109
- def step_01_init_runtime() -> Dict:
110
- """Inicializa runtime e reporta configurações."""
111
- logger.info("=" * 70)
112
- logger.info("PASSO 1: Inicialização do runtime Xeon + memory optimizer")
113
- logger.info("=" * 70)
114
- from cnn_bigru.utils.xeon_runtime import get_runtime_info
115
- info = get_runtime_info()
116
- for k, v in info.items():
117
- logger.info(" %s: %s", k, v)
118
- mem = MemoryOptimizer(enable_amp=False)
119
- mem.configure()
120
- mem_info = mem.get_memory_mb()
121
- logger.info(" Memória: %s", mem_info)
122
- return {"runtime": info, "memory": mem_info}
123
-
124
-
125
- def step_02_train_tokenizer() -> BBPETokenizer:
126
- """Treina BBPE tokenizer em corpus sintético."""
127
- logger.info("=" * 70)
128
- logger.info("PASSO 2: Treino do BBPE tokenizer")
129
- logger.info("=" * 70)
130
- t0 = time.time()
131
- tok = BBPETokenizer.train_from_texts(
132
- CORPUS_TEXTS,
133
- vocab_size=2000,
134
- min_frequency=1,
135
- )
136
- elapsed = time.time() - t0
137
- logger.info(" Vocab size: %d", tok.vocab_size)
138
- logger.info(" BOS/PAD/EOS IDs: %d/%d/%d", tok.bos_id, tok.pad_id, tok.eos_id)
139
- logger.info(" Tempo: %.2fs", elapsed)
140
-
141
- # Validação roundtrip
142
- test_strs = CORPUS_TEXTS[:5]
143
- roundtrip = tok.validate_roundtrip(test_strs)
144
- logger.info(" Roundtrip accuracy: %.2f%%", roundtrip * 100)
145
-
146
- if roundtrip < 0.8:
147
- logger.warning(" Roundtrip baixo — possível problema no tokenizer")
148
- return tok, roundtrip
149
-
150
-
151
- def step_03_create_dataset(tokenizer: BBPETokenizer, n_samples: int = 50) -> DataLoader:
152
- """Cria dataset streaming multimodal com N amostras."""
153
- logger.info("=" * 70)
154
- logger.info("PASSO 3: Criação do dataset streaming multimodal (%d amostras)", n_samples)
155
- logger.info("=" * 70)
156
-
157
- # Para teste determinístico, usamos fallback sintético
158
- dataset = MultimodalStreamingDataset(
159
- n_samples=n_samples,
160
- hf_datasets=[], # skip HF forçando sintético
161
- use_synthetic_fallback=True,
162
- seed=42,
163
- image_size=(28, 28, 1),
164
- audio_shape=(32, 40),
165
- )
166
-
167
- # Coleta todas as amostras em uma lista (para DataLoader iterável)
168
- samples = list(dataset)
169
- logger.info(" Amostras coletadas: %d", len(samples))
170
- assert len(samples) == n_samples, f"Esperado {n_samples}, obtido {len(samples)}"
171
-
172
- # Cria DataLoader com collate_fn
173
- from torch.utils.data import DataLoader
174
- loader = DataLoader(
175
- samples,
176
- batch_size=8,
177
- shuffle=False,
178
- collate_fn=lambda b: collate_multimodal(b, tokenizer, max_len=32),
179
- )
180
- logger.info(" DataLoader criado: batch_size=8, max_len=32")
181
- return loader
182
-
183
-
184
- def step_04_init_model(tokenizer: BBPETokenizer, device: str = "cpu") -> Dict:
185
- """Instancia todos os componentes do modelo."""
186
- logger.info("=" * 70)
187
- logger.info("PASSO 4: Instanciação dos modelos")
188
- logger.info("=" * 70)
189
- V = tokenizer.vocab_size
190
-
191
- # Modelo multimodal principal
192
- model = MultimodalCNNBiGRU(
193
- vocab_size=V,
194
- num_classes=3,
195
- embedding_dim=32,
196
- cnn_filters=32,
197
- gru_hidden=32,
198
- n_heads=4,
199
- dropout=0.1,
200
- pad_idx=tokenizer.pad_id,
201
- img_channels=1,
202
- img_hidden=16,
203
- img_out_dim=32,
204
- audio_freq=40,
205
- audio_hidden=16,
206
- audio_out_dim=32,
207
- fusion_dim=64,
208
- use_spectral_norm=False,
209
- )
210
-
211
- # Aplica inicialização ortogonal
212
- n_init = orthogonal_init_model(model)
213
- logger.info(" Modelo multimodal: %d params, %d camadas ortogonalizadas",
214
- sum(p.numel() for p in model.parameters()), n_init)
215
-
216
- # Generator (encoder + decoder)
217
- generator = GeneratorCNNBiGRU(
218
- vocab_size=V,
219
- embedding_dim=32,
220
- cnn_filters=32,
221
- gru_hidden=32,
222
- n_heads=4,
223
- dropout=0.1,
224
- pad_idx=tokenizer.pad_id,
225
- max_proof_len=16,
226
- )
227
- orthogonal_init_model(generator)
228
-
229
- # Verifier
230
- verifier = VerifierCNNBiGRU(
231
- vocab_size=V,
232
- embedding_dim=32,
233
- cnn_filters=32,
234
- gru_hidden=32,
235
- n_heads=4,
236
- dropout=0.1,
237
- pad_idx=tokenizer.pad_id,
238
- )
239
- orthogonal_init_model(verifier)
240
-
241
- # Anti-hallucination
242
- anti_hall = AntiHallucinationLayer(vocab_size=V, embed_dim=16)
243
-
244
- logger.info(" Generator params: %d", sum(p.numel() for p in generator.parameters()))
245
- logger.info(" Verifier params: %d", sum(p.numel() for p in verifier.parameters()))
246
- logger.info(" Anti-hall params: %d", sum(p.numel() for p in anti_hall.parameters()))
247
-
248
- return {
249
- "model": model,
250
- "generator": generator,
251
- "verifier": verifier,
252
- "anti_hall": anti_hall,
253
- }
254
-
255
-
256
- def step_05_train(
257
- models: Dict,
258
- tokenizer: BBPETokenizer,
259
- dataloader: DataLoader,
260
- device: str = "cpu",
261
- ) -> Dict:
262
- """Executa treinamento cooperativo."""
263
- logger.info("=" * 70)
264
- logger.info("PASSO 5: Treinamento cooperativo (synergy + hipóteses + auto-learn)")
265
- logger.info("=" * 70)
266
-
267
- cfg = TrainerConfig(
268
- num_epochs=2,
269
- max_batches_per_epoch=6,
270
- batch_size=8,
271
- n_synergy_attempts=3,
272
- use_synergy_search=True,
273
- use_hypotheses=True,
274
- n_hypotheses=4,
275
- loss_config=LossConfig(
276
- alpha=1.0, beta=0.5, gamma_loss=0.3, delta=0.01,
277
- lambda_penal=0.1, mu_exp_penal=0.05,
278
- gamma_exp=1.0, threshold_err=0.5,
279
- l2_reg=1e-5, use_curvature=True, curvature_eps=1e-3,
280
- ),
281
- auto_config=AutoLearnConfig(
282
- kappa_curv=0.01, grad_clip=1.0, spectral_radius=1.0,
283
- lr_min=1e-6, lr_max=1e-2,
284
- initial_lr_G=1e-3, initial_lr_V=1e-3,
285
- use_spectral_norm=True, apply_after_step=True,
286
- ),
287
- device=device,
288
- log_every=1,
289
- )
290
-
291
- trainer = CooperativeTrainer(
292
- model=models["model"],
293
- tokenizer=tokenizer,
294
- config=cfg,
295
- generator=models["generator"],
296
- verifier=models["verifier"],
297
- anti_hallucination=models["anti_hall"],
298
- )
299
-
300
- try:
301
- result = trainer.train(dataloader)
302
- logger.info(" Treinamento OK | final_loss=%.4f | final_ppl=%.2f | elapsed=%.1fs",
303
- result["final_loss"], result["final_ppl"], result["elapsed_s"])
304
- return result
305
- except Exception as e:
306
- logger.error(" Treinamento FALHOU: %s", e)
307
- logger.error(traceback.format_exc())
308
- raise
309
-
310
-
311
- def step_06_inference(
312
- model: MultimodalCNNBiGRU,
313
- tokenizer: BBPETokenizer,
314
- device: str = "cpu",
315
- ) -> Dict:
316
- """Executa inferência com sampling."""
317
- logger.info("=" * 70)
318
- logger.info("PASSO 6: Inferência com Temperatura + Top-K + Top-P + Penalidades")
319
- logger.info("=" * 70)
320
-
321
- prompts = [
322
- ("o modelo coopera entre", "fluxos paralelos"),
323
- ("atencao cruzada troca", "informacoes entre redes"),
324
- ("gru bidirecional captura", "dependencias temporais"),
325
- ]
326
-
327
- results = []
328
- for prompt_a, prompt_b in prompts:
329
- try:
330
- result = generate_with_sampling(
331
- model=model,
332
- tokenizer=tokenizer,
333
- prompt_a=prompt_a,
334
- prompt_b=prompt_b,
335
- max_new_tokens=16,
336
- temperature=0.7,
337
- top_k=20,
338
- top_p=0.9,
339
- presence_penalty=0.3,
340
- frequency_penalty=0.3,
341
- device=device,
342
- )
343
- logger.info(" Prompt A: %s", prompt_a)
344
- logger.info(" Prompt B: %s", prompt_b)
345
- logger.info(" Gerado: %s", result["text"][:100])
346
- logger.info(" Metrics: %s", result["metrics"])
347
- results.append({"prompt_a": prompt_a, "prompt_b": prompt_b, **result})
348
- except Exception as e:
349
- logger.error(" Inferência falhou para (%s, %s): %s", prompt_a, prompt_b, e)
350
- results.append({"prompt_a": prompt_a, "prompt_b": prompt_b, "error": str(e)})
351
-
352
- return {"results": results}
353
-
354
-
355
- def step_07_eval_ppl(
356
- model: MultimodalCNNBiGRU,
357
- tokenizer: BBPETokenizer,
358
- dataloader: DataLoader,
359
- device: str = "cpu",
360
- ) -> Dict:
361
- """Avalia perplexidade."""
362
- logger.info("=" * 70)
363
- logger.info("PASSO 7: Avaliação de Perplexidade (PPL)")
364
- logger.info("=" * 70)
365
- try:
366
- result = evaluate_perplexity(
367
- model=model,
368
- dataloader=dataloader,
369
- tokenizer=tokenizer,
370
- device=device,
371
- max_batches=5,
372
- )
373
- logger.info(" Loss: %.4f | PPL: %.2f | batches: %d",
374
- result["loss"], result["ppl"], result["n_batches"])
375
- return result
376
- except Exception as e:
377
- logger.error(" PPL falhou: %s", e)
378
- logger.error(traceback.format_exc())
379
- return {"error": str(e)}
380
-
381
-
382
- def step_08_report_errors(errors: List[str], warnings: List[str]) -> None:
383
- """Reporta erros lógicos ou falhas encontradas."""
384
- logger.info("=" * 70)
385
- logger.info("PASSO 8: Relatório de erros lógicos ou falhas")
386
- logger.info("=" * 70)
387
-
388
- if not errors:
389
- logger.info(" ✓ NENHUM ERRO CRÍTICO encontrado")
390
- else:
391
- logger.error(" ✗ %d ERRO(S) CRÍTICO(S) encontrado(s):", len(errors))
392
- for e in errors:
393
- logger.error(" - %s", e)
394
-
395
- if not warnings:
396
- logger.info(" ✓ Nenhum warning relevante")
397
- else:
398
- logger.warning(" ⚠ %d warning(s):", len(warnings))
399
- for w in warnings:
400
- logger.warning(" - %s", w)
401
-
402
- logger.info("=" * 70)
403
-
404
-
405
- def main():
406
- """Executa o teste completo de 50 amostras."""
407
- logger.info("INICIANDO TESTE DE 50 AMOSTRAS — CNN-BiGRU MULTIMODAL COOPERATIVO")
408
- logger.info("Project root: %s", PROJECT_ROOT)
409
- logger.info("Device: %s", "cpu")
410
- logger.info("Cores: %d", N_CORES)
411
-
412
- errors: List[str] = []
413
- warnings: List[str] = []
414
-
415
- try:
416
- # Step 1
417
- step_01_init_runtime()
418
-
419
- # Step 2
420
- tokenizer, roundtrip = step_02_train_tokenizer()
421
- if roundtrip < 0.8:
422
- warnings.append(f"BBPE roundtrip accuracy = {roundtrip:.2%} (esperado >= 80%)")
423
-
424
- # Step 3
425
- dataloader = step_03_create_dataset(tokenizer, n_samples=50)
426
-
427
- # Step 4
428
- models = step_04_init_model(tokenizer, device="cpu")
429
-
430
- # Verificação: forward pass simples antes do treino
431
- try:
432
- batch = next(iter(dataloader))
433
- with torch.no_grad():
434
- out = models["model"](
435
- batch["input_ids_a"], batch["input_ids_b"],
436
- images=batch["images"], audios=batch["audios"],
437
- mode="classify",
438
- )
439
- logger.info(" Forward pass OK | logits shape: %s", out["logits"].shape)
440
- assert out["logits"].shape == (batch["input_ids_a"].size(0), 3), \
441
- f"Shape inesperado: {out['logits'].shape}"
442
- except Exception as e:
443
- errors.append(f"Forward pass inicial falhou: {e}")
444
- logger.error(traceback.format_exc())
445
-
446
- # Step 5
447
- if not errors:
448
- try:
449
- train_result = step_05_train(models, tokenizer, dataloader, device="cpu")
450
- except Exception as e:
451
- errors.append(f"Treinamento falhou: {e}")
452
- train_result = None
453
- else:
454
- train_result = None
455
-
456
- # Step 6
457
- if not errors:
458
- try:
459
- step_06_inference(models["model"], tokenizer, device="cpu")
460
- except Exception as e:
461
- errors.append(f"Inferência falhou: {e}")
462
- logger.error(traceback.format_exc())
463
-
464
- # Step 7
465
- if not errors:
466
- try:
467
- step_07_eval_ppl(models["model"], tokenizer, dataloader, device="cpu")
468
- except Exception as e:
469
- warnings.append(f"PPL falhou (não crítico): {e}")
470
-
471
- # Step 8
472
- step_08_report_errors(errors, warnings)
473
-
474
- # Resumo final
475
- logger.info("=" * 70)
476
- logger.info("RESUMO FINAL DO TESTE DE 50 AMOSTRAS")
477
- logger.info("=" * 70)
478
- logger.info(" Amostras processadas: 50")
479
- logger.info(" Erros críticos: %d", len(errors))
480
- logger.info(" Warnings: %d", len(warnings))
481
- if train_result:
482
- logger.info(" Loss final: %.4f", train_result["final_loss"])
483
- logger.info(" PPL final: %.2f", train_result["final_ppl"])
484
- logger.info(" Tempo: %.1fs", train_result["elapsed_s"])
485
- logger.info(" Synergy attempts: %d", len(train_result.get("synergy_history", [])))
486
- logger.info(" Hypothesis activations: %d",
487
- sum(h.get("hypothesis_activations", 0) for h in train_result.get("history", [])))
488
-
489
- if errors:
490
- logger.error(" STATUS: FALHA — %d erro(s)", len(errors))
491
- return 1
492
- else:
493
- logger.info(" STATUS: SUCESSO")
494
- return 0
495
-
496
- except Exception as e:
497
- logger.error("ERRO FATAL: %s", e)
498
- logger.error(traceback.format_exc())
499
- return 2
500
-
501
-
502
- if __name__ == "__main__":
503
- try:
504
- rc = main()
505
- except SystemExit:
506
- raise
507
- except Exception as e:
508
- logger.error("Unhandled exception: %s", e)
509
- rc = 2
510
- # Evita o "Fatal Python error: PyGILState_Release" no shutdown causado
511
- # por threads do tokenizers/datasets que ainda estão ativas.
512
- import os
513
- os._exit(rc)