Download scripts/train_from_v13_9_2.py from PowerMachine/gru-ring-v13-9-2: direct link, hf CLI and curl.
- Browser
- Download file 24.7 kB
-
https://huggingface.co/PowerMachine/gru-ring-v13-9-2/resolve/main/scripts/train_from_v13_9_2.py
- Command line
-
hf download hf://PowerMachine/gru-ring-v13-9-2/scripts/train_from_v13_9_2.py
-
curl -L -o train_from_v13_9_2.py https://huggingface.co/PowerMachine/gru-ring-v13-9-2/resolve/main/scripts/train_from_v13_9_2.py
24.7 kB
| #!/usr/bin/env python3 | |
| """train_from_v13_9_2.py β Continua treinamento do GRU-RING v13.9.2 | |
| em um ou mais datasets HF (default: Carolina), partindo dos pesos v13.9.2 | |
| jΓ‘ treinados. | |
| V13.9.2-finetune-v2: generalizado para aceitar --datasets (lista separada | |
| por vΓrgula). Default mantΓ©m "carolina-c4ai/corpus-carolina" para | |
| retrocompatibilidade. Nenhuma mudanΓ§a na arquitetura do modelo β apenas | |
| na escolha do dataset de fine-tuning. | |
| ESTRATΓGIAS DE BAIXA MEMΓRIA (3.5GB RAM disponΓvel): | |
| - streaming=True: dataset lido amostra por amostra (via lxml.iterparse direto, | |
| bypass do script Python carolina.py que nΓ£o Γ© suportado em datasets 5.0+) | |
| - per_device_train_batch_size=1: 1 amostra por vez | |
| - gradient_accumulation_steps=16: acumula 16 gradientes antes de atualizar | |
| pesos (simula batch_size=16 sem explodir RAM) | |
| - max_length=64: o max_seq_len nativo do modelo v13.9.2 (nΓ£o 128 β preserva | |
| a arquitetura e economiza 2Γ memΓ³ria de atenΓ§Γ£o) | |
| - gradient_checkpointing=True: jΓ‘ habilitado no modelo (config.gradient_checkpointing) | |
| BUG-HUNT (verificado neste script): | |
| 1. NoneType backward: backward() sΓ³ Γ© chamado quando outputs contΓ©m "loss" | |
| (labels passadas). Sempre passamos labels. | |
| 2. state_dict mismatch: usamos create_gru_ring_v139() com config idΓͺntica Γ | |
| do treino original (d_model=128, n_layers=4, etc) β load_state_dict Γ© safe. | |
| 3. Tokenizer encoding: collate_samples_to_tensors jΓ‘ trata .ids / .input_ids / | |
| list. Reaproveitado do mΓ³dulo streaming_datasets_v13_9. | |
| 4. Buffer trust_state persistente: preservado no state_dict (register_buffer). | |
| 5. padding_idx=1: pad_token_id=1 no config. Garantido por _normalize_sample | |
| que ignora textos com <10 chars (sem padding-only batches). | |
| Uso (default β Carolina): | |
| export HF_TOKEN="hf_xxx" | |
| python3 train_from_v13_9_2.py \ | |
| --max-samples 200 \ | |
| --max-steps 200 \ | |
| --grad-accum 16 \ | |
| --lr 2e-5 \ | |
| --output-dir /home/z/my-project/download/gru_ring_v13_9/carolina_finetune | |
| Uso (fine-tune v2 β 3 novos datasets PT-BR): | |
| export HF_TOKEN="hf_xxx" | |
| python3 train_from_v13_9_2.py \ | |
| --datasets orion-research/translations-en_US-pt_BR,cnmoro/Instruct-PTBR-10M,strak2005/corpus-ptbr-v1 \ | |
| --max-samples 200 \ | |
| --max-steps 200 \ | |
| --grad-accum 16 \ | |
| --lr 2e-5 \ | |
| --output-dir /home/z/my-project/download/gru_ring_v13_9/finetune_v2 | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import gc | |
| import json | |
| import logging | |
| import math | |
| import os | |
| import sys | |
| import time | |
| import traceback | |
| from pathlib import Path | |
| from typing import Dict, List, Optional | |
| # Limitar threads para evitar OOM em ambiente com 3.5GB RAM | |
| import torch | |
| torch.set_num_threads(2) | |
| os.environ.setdefault("OMP_NUM_THREADS", "2") | |
| os.environ.setdefault("MKL_NUM_THREADS", "2") | |
| os.environ.setdefault("TOKENIZERS_PARALLELISM", "false") | |
| from torch.optim import AdamW | |
| sys.path.insert(0, "/home/z/my-project/xavante_work") | |
| from flexnet.gru_ring_v13_9 import create_gru_ring_v139, GRURingV139, GRURingV139Config | |
| from flexnet.streaming_datasets_v13_9 import ( | |
| stream_dataset, | |
| collate_samples_to_tensors, | |
| ProcessedSample, | |
| ) | |
| from flexnet.w8a8_qoperator import W8A8QOperatorQuantizer | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s [%(levelname)s] %(message)s", | |
| datefmt="%H:%M:%S", | |
| handlers=[logging.StreamHandler()], | |
| ) | |
| logger = logging.getLogger(__name__) | |
| # Caminhos padrΓ£o (v13.9.2 treinado) | |
| # BUG FIX V13.9.2-finetune-v2: paths apontavam para /tmp/my-project/ (legado). | |
| # Corrigido para /home/z/my-project/ que Γ© onde os artefatos realmente estΓ£o. | |
| DEFAULT_MODEL_PATH = "/home/z/my-project/download/gru_ring_v13_9/rename_uploads/model_final/pytorch_model.bin" | |
| DEFAULT_TOKENIZER_PATH = "/home/z/my-project/download/gru_ring_v13_9/rename_uploads/model_final/tokenizer/tokenizer.json" | |
| DEFAULT_OUTPUT_DIR = "/home/z/my-project/download/gru_ring_v13_9/finetune_v2" | |
| # Default dataset (retrocompatibilidade). Para mudar, use --datasets. | |
| DEFAULT_DATASETS = "carolina-c4ai/corpus-carolina" | |
| def get_warmup_cosine_scheduler(optimizer, num_warmup, num_total, min_ratio=0.1): | |
| """Warmup + cosine schedule.""" | |
| def lr_lambda(step): | |
| if step < num_warmup: | |
| return float(step) / max(1, num_warmup) | |
| progress = float(step - num_warmup) / max(1, num_total - num_warmup) | |
| cosine = 0.5 * (1.0 + math.cos(math.pi * progress)) | |
| return max(min_ratio, cosine) | |
| from torch.optim.lr_scheduler import LambdaLR | |
| return LambdaLR(optimizer, lr_lambda) | |
| def load_tokenizer(path: str): | |
| """Carrega tokenizer BBPE 16K.""" | |
| try: | |
| from tokenizers import Tokenizer | |
| return Tokenizer.from_file(path) | |
| except Exception as e: | |
| logger.error(f"Failed to load tokenizer from {path}: {e}") | |
| return None | |
| def load_pretrained_model(model_path: str) -> GRURingV139: | |
| """Carrega modelo v13.9.2 a partir dos pesos treinados.""" | |
| model, config = create_gru_ring_v139() | |
| counts = model.count_parameters() | |
| logger.info(f"Model created: {counts['total']:,} params ({counts['total_M']:.2f}M)") | |
| if not Path(model_path).exists(): | |
| raise FileNotFoundError(f"Model not found: {model_path}") | |
| logger.info(f"Loading pretrained weights: {model_path}") | |
| state = torch.load(model_path, map_location="cpu", weights_only=False) | |
| if isinstance(state, dict) and "model_state_dict" in state: | |
| state = state["model_state_dict"] | |
| missing, unexpected = model.load_state_dict(state, strict=False) | |
| if missing: | |
| logger.warning(f"Missing keys ({len(missing)}): {missing[:5]}...") | |
| if unexpected: | |
| logger.warning(f"Unexpected keys ({len(unexpected)}): {unexpected[:5]}...") | |
| logger.info("Weights loaded successfully") | |
| return model, config | |
| def train_carolina( | |
| model_path: str = DEFAULT_MODEL_PATH, | |
| tokenizer_path: str = DEFAULT_TOKENIZER_PATH, | |
| output_dir: str = DEFAULT_OUTPUT_DIR, | |
| max_samples: int = 200, | |
| max_steps: int = 200, | |
| grad_accum: int = 16, | |
| lr: float = 2e-5, | |
| weight_decay: float = 0.01, | |
| max_seq_len: int = 64, | |
| log_every: int = 10, | |
| save_every: int = 100, | |
| seed: int = 42, | |
| datasets: Optional[str] = None, | |
| ) -> Dict: | |
| """Treina o modelo em um ou mais datasets HF (default: Carolina). | |
| V13.9.2-finetune-v2: aceita `datasets` como string separada por vΓrgulas. | |
| Se None ou vazio, usa DEFAULT_DATASETS (Carolina) para retrocompatibilidade. | |
| Quando mΓΊltiplos datasets sΓ£o passados, cada um contribui com atΓ© | |
| `max_samples` amostras (total = max_samples Γ nΒΊ de datasets). | |
| Args: | |
| model_path: caminho para pytorch_model.bin v13.9.2 | |
| tokenizer_path: caminho para tokenizer.json | |
| output_dir: diretΓ³rio de saΓda para checkpoints | |
| max_samples: nΒΊ mΓ‘x de amostras POR dataset (buffer) | |
| max_steps: nΒΊ mΓ‘x de optimizer steps (cada step = grad_accum micro-batches) | |
| grad_accum: gradient_accumulation_steps (batch_size efetivo = 1 Γ grad_accum) | |
| lr: learning rate (baixo: 2e-5 β nΓ£o destruir o aprendizado do .bin) | |
| weight_decay: weight decay (AdamW) | |
| max_seq_len: tamanho da sequΓͺncia (64 = nativo do v13.9.2) | |
| log_every: log a cada N micro-batches | |
| save_every: salvar checkpoint a cada N optimizer steps | |
| seed: random seed | |
| datasets: string separada por vΓrgulas com nomes de datasets HF | |
| (default: "carolina-c4ai/corpus-carolina") | |
| Returns: | |
| dict com mΓ©tricas finais | |
| """ | |
| torch.manual_seed(seed) | |
| Path(output_dir).mkdir(parents=True, exist_ok=True) | |
| # ββ Resolve lista de datasets βββββββββββββββββββββββββββββββββββββββ | |
| if not datasets: | |
| datasets = DEFAULT_DATASETS | |
| datasets_list = [d.strip() for d in datasets.split(",") if d.strip()] | |
| if not datasets_list: | |
| datasets_list = [DEFAULT_DATASETS] | |
| logger.info(f"Datasets para fine-tune ({len(datasets_list)}):") | |
| for i, d in enumerate(datasets_list, 1): | |
| logger.info(f" [{i}] {d}") | |
| logger.info(f"max_samples POR dataset = {max_samples} " | |
| f"(total esperado = {max_samples * len(datasets_list)})") | |
| # ββ Log do config ββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| logger.info("=" * 60) | |
| logger.info("GRU-RING v13.9.2 β Fine-tuning") | |
| logger.info("=" * 60) | |
| logger.info(f" model_path: {model_path}") | |
| logger.info(f" tokenizer_path: {tokenizer_path}") | |
| logger.info(f" output_dir: {output_dir}") | |
| logger.info(f" max_samples: {max_samples} (por dataset)") | |
| logger.info(f" max_steps: {max_steps}") | |
| logger.info(f" grad_accum: {grad_accum} (efetivo batch = {1 * grad_accum})") | |
| logger.info(f" lr: {lr}") | |
| logger.info(f" max_seq_len: {max_seq_len}") | |
| logger.info(f" gradient_ckpt: True (jΓ‘ no config do modelo)") | |
| logger.info("=" * 60) | |
| # ββ HF token βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # BUG FIX V13.9.2-finetune-v4: `os.environ.get("HF_TOKEN")` retorna "" | |
| # (string vazia) quando a variΓ‘vel estΓ‘ setada como vazia no shell. | |
| # Essa string vazia Γ© passada para huggingface_hub que constrΓ³i o header | |
| # HTTP `Authorization: Bearer ` β "Illegal header value". Fix: normalizar | |
| # para None (ausΓͺncia de token). Datasets pΓΊblicos nΓ£o precisam de token. | |
| hf_token = os.environ.get("HF_TOKEN") or None | |
| if not hf_token: | |
| logger.warning("HF_TOKEN nΓ£o setado β datasets pΓΊblicos, sem auth") | |
| # ββ Modelo + tokenizer βββββββββββββββββββββββββββββββββββββββββββββββ | |
| model, config = load_pretrained_model(model_path) | |
| device = torch.device("cpu") | |
| model = model.to(device) | |
| model.train() | |
| tokenizer = load_tokenizer(tokenizer_path) | |
| if tokenizer is None: | |
| return {"error": "no tokenizer"} | |
| # ββ Optimizer ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # LR baixo (2e-5) para preservar conhecimento dos 8 datasets anteriores. | |
| optimizer = AdamW( | |
| model.parameters(), | |
| lr=lr, | |
| betas=(0.9, 0.95), | |
| weight_decay=weight_decay, | |
| eps=1e-8, | |
| ) | |
| # Scheduler: warmup (10% dos steps) + cosine | |
| warmup_steps = max(1, max_steps // 10) | |
| scheduler = get_warmup_cosine_scheduler( | |
| optimizer, num_warmup=warmup_steps, num_total=max_steps | |
| ) | |
| logger.info(f"Scheduler: warmup={warmup_steps}, total={max_steps}") | |
| # ββ Carrega datasets em buffer (streaming) βββββββββββββββββββββββββββ | |
| # V13.9.2-finetune-v2: itera sobre a lista de datasets. Cada um contribui | |
| # com atΓ© max_samples amostras. Timeout por dataset = 180s (Carolina Γ© | |
| # mais rΓ‘pido pois usa lxml.iterparse direto; outros podem demorar para | |
| # materializar a primeira amostra de parquet grande). | |
| samples_buffer: List[ProcessedSample] = [] | |
| per_dataset_counts: Dict[str, int] = {} | |
| stream_start_total = time.time() | |
| for ds_name in datasets_list: | |
| logger.info(f"Streaming atΓ© {max_samples} amostras de {ds_name}...") | |
| ds_start = time.time() | |
| ds_count = 0 | |
| try: | |
| for sample in stream_dataset( | |
| ds_name, | |
| max_samples=max_samples, | |
| hf_token=hf_token, | |
| ): | |
| samples_buffer.append(sample) | |
| ds_count += 1 | |
| if ds_count >= max_samples: | |
| break | |
| if time.time() - ds_start > 600: | |
| logger.warning(f" timeout em {ds_name} apΓ³s {ds_count} amostras") | |
| break | |
| except Exception as e: | |
| logger.error(f"Erro carregando {ds_name}: {e}") | |
| traceback.print_exc() | |
| # NΓ£o aborta β continua com prΓ³ximos datasets | |
| continue | |
| per_dataset_counts[ds_name] = ds_count | |
| logger.info(f" {ds_name}: {ds_count} amostras em {time.time()-ds_start:.1f}s") | |
| n_loaded = len(samples_buffer) | |
| logger.info(f"Total carregado: {n_loaded} amostras de {len(datasets_list)} " | |
| f"datasets em {time.time()-stream_start_total:.1f}s") | |
| if n_loaded == 0: | |
| return {"error": "no samples loaded"} | |
| # ββ Loop de treino βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Cada micro-batch = 1 amostra (per_device_train_batch_size=1). | |
| # Acumulamos grad_accum micro-batches antes de optimizer.step(). | |
| global_step = 0 | |
| micro_batch_idx = 0 | |
| sample_idx = 0 # Γndice circular no buffer | |
| best_loss = float("inf") | |
| last_loss = float("nan") | |
| losses_history: List[float] = [] | |
| t_start = time.time() | |
| logger.info(f"Iniciando treino β {max_steps} optimizer steps " | |
| f"({max_steps * grad_accum} micro-batches)") | |
| optimizer.zero_grad() | |
| while global_step < max_steps: | |
| # Pega prΓ³xima amostra do buffer (loop circular) | |
| sample = samples_buffer[sample_idx % n_loaded] | |
| sample_idx += 1 | |
| # Tokeniza (batch_size=1) | |
| try: | |
| input_ids, attention_mask, labels = collate_samples_to_tensors( | |
| [sample], tokenizer, | |
| max_seq_len=max_seq_len, | |
| pad_token_id=config.pad_token_id, | |
| ) | |
| except Exception as e: | |
| logger.warning(f"Tokenize erro micro-batch {micro_batch_idx}: {e}") | |
| continue | |
| # Forward + backward (com grad accum) | |
| try: | |
| outputs = model(input_ids, attention_mask=attention_mask, labels=labels) | |
| loss = outputs["loss"] / grad_accum # normaliza por grad_accum | |
| loss.backward() | |
| current_loss = outputs["loss"].item() | |
| model.update_loss_tracking(current_loss) | |
| last_overall_confidence = outputs["overall_confidence"].mean().item() | |
| losses_history.append(current_loss) | |
| last_loss = current_loss | |
| if current_loss < best_loss: | |
| best_loss = current_loss | |
| except RuntimeError as e: | |
| err = str(e).lower() | |
| if "out of memory" in err: | |
| logger.warning(f"OOM micro-batch {micro_batch_idx}, limpando cache") | |
| gc.collect() | |
| optimizer.zero_grad() | |
| continue | |
| else: | |
| logger.error(f"Runtime erro micro-batch {micro_batch_idx}: {e}") | |
| traceback.print_exc() | |
| break | |
| micro_batch_idx += 1 | |
| # Step no optimizer a cada grad_accum micro-batches | |
| if micro_batch_idx % grad_accum == 0: | |
| torch.nn.utils.clip_grad_norm_(model.parameters(), 5.0) | |
| optimizer.step() | |
| scheduler.step() | |
| optimizer.zero_grad() | |
| global_step += 1 | |
| # Log | |
| if global_step % log_every == 0 or global_step == 1: | |
| elapsed = time.time() - t_start | |
| avg_loss = sum(losses_history[-grad_accum:]) / max(1, min(grad_accum, len(losses_history))) | |
| ppl = math.exp(min(20, avg_loss)) if avg_loss < 20 else float("inf") | |
| logger.info( | |
| f" step {global_step}/{max_steps} | micro {micro_batch_idx} | " | |
| f"loss={avg_loss:.4f} ppl={ppl:.2f} " | |
| f"lr={scheduler.get_last_lr()[0]:.2e} " | |
| f"conf={last_overall_confidence:.3f} " | |
| f"punish={model.is_punishment_active()} " | |
| f"elapsed={elapsed:.0f}s" | |
| ) | |
| # Save checkpoint | |
| if global_step % save_every == 0: | |
| ckpt_path = Path(output_dir) / f"checkpoint_step{global_step}.pt" | |
| torch.save({ | |
| "model_state_dict": model.state_dict(), | |
| "optimizer_state_dict": optimizer.state_dict(), | |
| "scheduler_state_dict": scheduler.state_dict(), | |
| "global_step": global_step, | |
| "best_loss": best_loss, | |
| "last_loss": last_loss, | |
| "samples_loaded": n_loaded, | |
| }, ckpt_path) | |
| logger.info(f" Checkpoint salvo: {ckpt_path}") | |
| gc.collect() | |
| # ββ Save final model βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| elapsed_total = time.time() - t_start | |
| final_loss = last_loss | |
| final_avg_loss = sum(losses_history[-grad_accum:]) / max(1, min(grad_accum, len(losses_history))) | |
| final_ppl = math.exp(min(20, final_avg_loss)) if final_avg_loss < 20 else float("inf") | |
| logger.info("=" * 60) | |
| logger.info("TREINO CONCLUΓDO") | |
| logger.info(f" optimizer steps: {global_step}") | |
| logger.info(f" micro-batches: {micro_batch_idx}") | |
| logger.info(f" tempo total: {elapsed_total:.1f}s ({elapsed_total/60:.1f}min)") | |
| logger.info(f" best loss: {best_loss:.4f}") | |
| logger.info(f" final avg loss: {final_avg_loss:.4f}") | |
| logger.info(f" final perplexity:{final_ppl:.2f}") | |
| logger.info("=" * 60) | |
| # Salva modelo final (state_dict puro, formato HF-compatible) | |
| model_dir = Path(output_dir) / "model_final" | |
| model_dir.mkdir(parents=True, exist_ok=True) | |
| final_state_path = model_dir / "pytorch_model.bin" | |
| torch.save(model.state_dict(), final_state_path) | |
| logger.info(f"Modelo final salvo: {final_state_path}") | |
| # Salva config (mantΓ©m todos os hiperparΓ’metros do v13.9.2) | |
| config_dict = { | |
| "model_type": "gru_ring_v13_9_2", | |
| "vocab_size": config.vocab_size, | |
| "d_model": config.d_model, | |
| "n_layers": config.n_layers, | |
| "n_heads": config.n_heads, | |
| "n_kv_heads": config.n_kv_heads, | |
| "max_seq_len": config.max_seq_len, | |
| "batch_size": config.batch_size, | |
| "pad_token_id": config.pad_token_id, | |
| "d_ff1": config.d_ff1, | |
| "d_ff2": config.d_ff2, | |
| "d_ff3": config.d_ff3, | |
| "num_hypotheses": config.num_hypotheses, | |
| "num_trust_scorers": config.num_trust_scorers, | |
| "hypothesis_rank": config.hypothesis_rank, | |
| "dropout": config.dropout, | |
| "trust_lr": config.trust_lr, | |
| "punishment_patience": config.punishment_patience, | |
| "warmup_skip_steps": config.warmup_skip_steps, | |
| "total_params": model.count_parameters()["total"], | |
| "total_params_M": model.count_parameters()["total_M"], | |
| "training": { | |
| "version_base": "v13.9.2", | |
| "datasets": datasets_list, | |
| "per_dataset_counts": per_dataset_counts, | |
| "max_samples_per_dataset": max_samples, | |
| "max_steps": max_steps, | |
| "grad_accum": grad_accum, | |
| "per_device_batch_size": 1, | |
| "effective_batch_size": grad_accum, | |
| "lr": lr, | |
| "weight_decay": weight_decay, | |
| "max_seq_len": max_seq_len, | |
| "gradient_checkpointing": True, | |
| "global_step": global_step, | |
| "micro_batches": micro_batch_idx, | |
| "best_loss": best_loss, | |
| "final_loss": final_loss, | |
| "final_avg_loss": final_avg_loss, | |
| "final_perplexity": final_ppl, | |
| "elapsed_s": elapsed_total, | |
| }, | |
| } | |
| with open(model_dir / "config.json", "w") as f: | |
| json.dump(config_dict, f, indent=2, ensure_ascii=False) | |
| # Copia tokenizer para o model_dir | |
| import shutil | |
| tok_dest = model_dir / "tokenizer" | |
| tok_dest.mkdir(exist_ok=True) | |
| shutil.copy(tokenizer_path, tok_dest / "tokenizer.json") | |
| # Salva relatΓ³rio de treino | |
| report = { | |
| "version": "v13.9.2", | |
| "base_model": "v13.9.2 (9/9 datasets)", | |
| "datasets": datasets_list, | |
| "training_params": { | |
| "max_samples_per_dataset": max_samples, | |
| "max_steps": max_steps, | |
| "grad_accum": grad_accum, | |
| "per_device_batch_size": 1, | |
| "effective_batch_size": grad_accum, | |
| "lr": lr, | |
| "max_seq_len": max_seq_len, | |
| "gradient_checkpointing": True, | |
| }, | |
| "results": { | |
| "global_step": global_step, | |
| "micro_batches": micro_batch_idx, | |
| "best_loss": best_loss, | |
| "final_loss": final_loss, | |
| "final_avg_loss": final_avg_loss, | |
| "final_perplexity": final_ppl, | |
| "elapsed_s": elapsed_total, | |
| "samples_loaded": n_loaded, | |
| "per_dataset_counts": per_dataset_counts, | |
| }, | |
| } | |
| report_path = Path(output_dir) / "training_report.json" | |
| with open(report_path, "w") as f: | |
| json.dump(report, f, indent=2, ensure_ascii=False, default=str) | |
| logger.info(f"RelatΓ³rio salvo: {report_path}") | |
| # ββ W8A8 Quantization (opcional β sΓ³ se solicitado) ββββββββββββββββββ | |
| # NΓ£o vamos quantizar por padrΓ£o β o modelo fp32 jΓ‘ estΓ‘ treinado. | |
| # A quantizaΓ§Γ£o pode ser feita depois com W8A8QOperatorQuantizer. | |
| # ββ Cleanup ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| del model, optimizer, scheduler | |
| gc.collect() | |
| return report["results"] | |
| def main(): | |
| parser = argparse.ArgumentParser( | |
| description="Treina GRU-RING v13.9.2 no dataset Carolina" | |
| ) | |
| parser.add_argument("--model-path", default=DEFAULT_MODEL_PATH, | |
| help=f"Caminho do pytorch_model.bin (default: {DEFAULT_MODEL_PATH})") | |
| parser.add_argument("--tokenizer-path", default=DEFAULT_TOKENIZER_PATH, | |
| help=f"Caminho do tokenizer (default: {DEFAULT_TOKENIZER_PATH})") | |
| parser.add_argument("--output-dir", default=DEFAULT_OUTPUT_DIR, | |
| help=f"DiretΓ³rio de saΓda (default: {DEFAULT_OUTPUT_DIR})") | |
| parser.add_argument("--datasets", type=str, default=None, | |
| help=f"Lista separada por vΓrgulas. Default: {DEFAULT_DATASETS}") | |
| parser.add_argument("--max-samples", type=int, default=200, | |
| help="NΒΊ mΓ‘x de amostras POR dataset (default: 200)") | |
| parser.add_argument("--max-steps", type=int, default=200, | |
| help="NΒΊ mΓ‘x de optimizer steps (default: 200)") | |
| parser.add_argument("--grad-accum", type=int, default=16, | |
| help="gradient_accumulation_steps (default: 16)") | |
| parser.add_argument("--lr", type=float, default=2e-5, | |
| help="learning rate (default: 2e-5 β baixo p/ fine-tune)") | |
| parser.add_argument("--weight-decay", type=float, default=0.01) | |
| parser.add_argument("--max-seq-len", type=int, default=64, | |
| help="tamanho sequΓͺncia (default: 64 β nativo do v13.9.2)") | |
| parser.add_argument("--log-every", type=int, default=10) | |
| parser.add_argument("--save-every", type=int, default=100) | |
| parser.add_argument("--seed", type=int, default=42) | |
| parser.add_argument("--smoke-test", action="store_true", | |
| help="Smoke test: 10 samples, 5 steps, 4 grad_accum") | |
| args = parser.parse_args() | |
| if args.smoke_test: | |
| logger.info("SMOKE TEST MODE β 10 samples, 5 steps, 4 grad_accum") | |
| args.max_samples = 10 | |
| args.max_steps = 5 | |
| args.grad_accum = 4 | |
| args.log_every = 1 | |
| args.save_every = 5 | |
| result = train_carolina( | |
| model_path=args.model_path, | |
| tokenizer_path=args.tokenizer_path, | |
| output_dir=args.output_dir, | |
| max_samples=args.max_samples, | |
| max_steps=args.max_steps, | |
| grad_accum=args.grad_accum, | |
| lr=args.lr, | |
| weight_decay=args.weight_decay, | |
| max_seq_len=args.max_seq_len, | |
| log_every=args.log_every, | |
| save_every=args.save_every, | |
| seed=args.seed, | |
| datasets=args.datasets, | |
| ) | |
| print(f"\n=== Resultado Final ===") | |
| print(json.dumps(result, indent=2, default=str)) | |
| if __name__ == "__main__": | |
| main() | |