dodanie
This commit is contained in:
parent
cb94d35f24
commit
21c797bd96
1
Pathl.AI
1
Pathl.AI
@ -1 +0,0 @@
|
||||
Subproject commit 577b442bafdd8a1f21cfb42816627fb7e0daedf2
|
||||
198
clay_manager.py
Normal file
198
clay_manager.py
Normal file
@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🛠️ Clay Checkpoint Manager - CLI do zarządzania checkpointami
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from config import cfg
|
||||
|
||||
|
||||
def list_checkpoints():
|
||||
"""Wyświetla dostępne checkpointy"""
|
||||
checkpoints = list(Path(cfg.checkpoints_dir).glob("clay_checkpoint_*.pt"))
|
||||
|
||||
if not checkpoints:
|
||||
print("❌ Brak checkpointów")
|
||||
return
|
||||
|
||||
print(f"\n📁 CLAY CHECKPOINTS ({len(checkpoints)}):")
|
||||
print("=" * 80)
|
||||
|
||||
for cp in sorted(checkpoints, key=lambda x: x.stat().st_mtime, reverse=True):
|
||||
# Wczytaj info z JSON
|
||||
json_file = cp.with_suffix('.json')
|
||||
if json_file.exists():
|
||||
with open(json_file, 'r') as f:
|
||||
info = json.load(f)['checkpoint_info']
|
||||
|
||||
size_mb = info['file_size'] / (1024 * 1024)
|
||||
print(f"📄 {cp.name}")
|
||||
print(f" • Epoka: {info['epoch']} | Krok: {info['step']:,}")
|
||||
print(f" • Loss: {info['loss']:.4f} | Rozmiar: {size_mb:.1f}MB")
|
||||
print(f" • Data: {info['timestamp']}")
|
||||
print("-" * 40)
|
||||
else:
|
||||
size_mb = cp.stat().st_size / (1024 * 1024)
|
||||
print(f"📄 {cp.name} ({size_mb:.1f}MB)")
|
||||
|
||||
|
||||
def show_training_stats():
|
||||
"""Pokazuje statystyki treningu"""
|
||||
stats_file = Path(cfg.checkpoints_dir) / "training_stats.json"
|
||||
|
||||
if stats_file.exists():
|
||||
with open(stats_file, 'r') as f:
|
||||
stats = json.load(f)
|
||||
|
||||
print("\n📊 STATYSTYKI TRENINGU:")
|
||||
print("=" * 60)
|
||||
|
||||
total_time = stats.get('total_time', 0)
|
||||
hours = total_time / 3600
|
||||
minutes = (total_time % 3600) / 60
|
||||
|
||||
print(f" • Całkowity czas: {hours:.0f}h {minutes:.0f}m")
|
||||
print(f" • Ostatni loss: {stats.get('final_loss', 0):.4f}")
|
||||
print(f" • Najlepszy loss: {stats.get('best_loss', 0):.4f}")
|
||||
print(f" • Średni loss: {stats.get('avg_loss', 0):.4f}")
|
||||
print(f" • Sprawdzone kroki: {stats.get('total_steps', 0):,}")
|
||||
print(f" • Zakończono: {stats.get('completion_time', 'N/A')}")
|
||||
else:
|
||||
print("❌ Brak statystyk treningu")
|
||||
|
||||
|
||||
def cleanup_checkpoints(keep=5):
|
||||
"""Czyści stare checkpointy"""
|
||||
checkpoints = list(Path(cfg.checkpoints_dir).glob("clay_checkpoint_*.pt"))
|
||||
|
||||
if len(checkpoints) <= keep:
|
||||
print(f"✅ Wszystkie checkpointy zachowane (mniej niż {keep})")
|
||||
return
|
||||
|
||||
checkpoints.sort(key=lambda x: x.stat().st_mtime)
|
||||
to_delete = checkpoints[:-keep]
|
||||
|
||||
print(f"\n🗑️ Usuwanie {len(to_delete)} starych checkpointów:")
|
||||
total_freed = 0
|
||||
|
||||
for cp in to_delete:
|
||||
size_mb = cp.stat().st_size / (1024 * 1024)
|
||||
total_freed += size_mb
|
||||
print(f" • {cp.name} ({size_mb:.1f}MB)")
|
||||
cp.unlink()
|
||||
|
||||
# Usuń też JSON
|
||||
json_file = cp.with_suffix('.json')
|
||||
if json_file.exists():
|
||||
json_file.unlink()
|
||||
|
||||
print(f"\n✅ Zachowano {keep} najnowszych checkpointów")
|
||||
print(f"💰 Zwolniono {total_freed:.1f}MB")
|
||||
|
||||
|
||||
def export_checkpoint(checkpoint_name, export_dir="exports"):
|
||||
"""Eksportuje checkpoint do osobnego folderu"""
|
||||
cp_path = Path(cfg.checkpoints_dir) / checkpoint_name
|
||||
|
||||
if not cp_path.exists():
|
||||
print(f"❌ Checkpoint {checkpoint_name} nie istnieje")
|
||||
return
|
||||
|
||||
# Stwórz folder eksportu
|
||||
export_path = Path(export_dir)
|
||||
export_path.mkdir(exist_ok=True)
|
||||
|
||||
# Skopiuj checkpoint i JSON
|
||||
dest_path = export_path / checkpoint_name
|
||||
shutil.copy2(cp_path, dest_path)
|
||||
|
||||
json_file = cp_path.with_suffix('.json')
|
||||
if json_file.exists():
|
||||
shutil.copy2(json_file, export_path / json_file.name)
|
||||
|
||||
print(f"✅ Checkpoint wyeksportowany do: {dest_path}")
|
||||
|
||||
|
||||
def show_checkpoint_info(checkpoint_name):
|
||||
"""Pokazuje szczegółowe info o checkpoincie"""
|
||||
cp_path = Path(cfg.checkpoints_dir) / checkpoint_name
|
||||
|
||||
if not cp_path.exists():
|
||||
print(f"❌ Checkpoint {checkpoint_name} nie istnieje")
|
||||
return
|
||||
|
||||
json_file = cp_path.with_suffix('.json')
|
||||
|
||||
if json_file.exists():
|
||||
with open(json_file, 'r') as f:
|
||||
info = json.load(f)
|
||||
|
||||
print(f"\n📋 INFO O CHECKPOINCIE: {checkpoint_name}")
|
||||
print("=" * 60)
|
||||
|
||||
cp_info = info['checkpoint_info']
|
||||
stats = info['training_stats']
|
||||
|
||||
print("📁 PODSTAWOWE INFORMACJE:")
|
||||
print(f" • Epoka: {cp_info['epoch']}")
|
||||
print(f" • Krok: {cp_info['step']:,}")
|
||||
print(f" • Loss: {cp_info['loss']:.4f}")
|
||||
print(f" • Rozmiar: {cp_info['file_size'] / (1024 * 1024):.1f}MB")
|
||||
print(f" • Data: {cp_info['timestamp']}")
|
||||
|
||||
print("\n📊 STATYSTYKI TRENINGU:")
|
||||
print(f" • Całkowity czas: {stats['total_time']:.0f}s")
|
||||
print(f" • Średni loss: {stats['avg_loss']:.4f}")
|
||||
print(f" • Current LR: {stats['current_lr']:.6f}")
|
||||
print(f" • Kroki: {stats['steps_done']:,}")
|
||||
else:
|
||||
print("❌ Brak informacji JSON dla tego checkpointu")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Clay Checkpoint Manager")
|
||||
parser.add_argument("--list", action="store_true", help="Lista checkpointów")
|
||||
parser.add_argument("--stats", action="store_true", help="Pokaż statystyki")
|
||||
parser.add_argument("--cleanup", type=int, nargs='?', const=5, help="Wyczyść stare checkpointy (domyślnie: 5)")
|
||||
parser.add_argument("--export", type=str, help="Eksportuj checkpoint")
|
||||
parser.add_argument("--info", type=str, help="Info o konkretnym checkpoincie")
|
||||
parser.add_argument("--export-all", action="store_true", help="Eksportuj wszystkie checkpointy")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.list:
|
||||
list_checkpoints()
|
||||
elif args.stats:
|
||||
show_training_stats()
|
||||
elif args.cleanup is not None:
|
||||
cleanup_checkpoints(args.cleanup)
|
||||
elif args.export:
|
||||
export_checkpoint(args.export)
|
||||
elif args.info:
|
||||
show_checkpoint_info(args.info)
|
||||
elif args.export_all:
|
||||
checkpoints = list(Path(cfg.checkpoints_dir).glob("clay_checkpoint_*.pt"))
|
||||
for cp in checkpoints:
|
||||
export_checkpoint(cp.name)
|
||||
else:
|
||||
print("\n🛠️ Clay Checkpoint Manager")
|
||||
print("=" * 40)
|
||||
print("Użyj:")
|
||||
print(" --list # Lista checkpointów")
|
||||
print(" --stats # Statystyki treningu")
|
||||
print(" --cleanup [N] # Zostaw N najnowszych (domyślnie 5)")
|
||||
print(" --export NAME # Eksportuj checkpoint")
|
||||
print(" --info NAME # Info o checkpoincie")
|
||||
print(" --export-all # Eksportuj wszystkie")
|
||||
print("\nPrzykłady:")
|
||||
print(" python clay_manager.py --list")
|
||||
print(" python clay_manager.py --cleanup 3")
|
||||
print(" python clay_manager.py --info clay_checkpoint_ep2_step5000_20240126_143022.pt")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
214
config.py
Normal file
214
config.py
Normal file
@ -0,0 +1,214 @@
|
||||
"""
|
||||
🎯 CONFIG - Wspólna konfiguracja dla MiniGPT-60M
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
import numpy as np
|
||||
import torch
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Any, Optional
|
||||
import logging
|
||||
import json
|
||||
|
||||
# ==================== LOGGING ====================
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('training.log', encoding='utf-8'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# ==================== KONFIGURACJA SYSTEMU ====================
|
||||
class SystemConfig:
|
||||
"""Konfiguracja systemu i urządzeń"""
|
||||
|
||||
def __init__(self):
|
||||
self.device = self._get_device()
|
||||
self.set_seeds(42)
|
||||
self._print_info()
|
||||
|
||||
def _get_device(self) -> str:
|
||||
"""Automatycznie wybiera najlepsze urządzenie"""
|
||||
if torch.cuda.is_available():
|
||||
return "cuda"
|
||||
elif torch.backends.mps.is_available():
|
||||
return "mps"
|
||||
else:
|
||||
return "cpu"
|
||||
|
||||
def set_seeds(self, seed: int = 42):
|
||||
"""Ustawia seed dla reprodukowalności"""
|
||||
random.seed(seed)
|
||||
np.random.seed(seed)
|
||||
torch.manual_seed(seed)
|
||||
if torch.cuda.is_available():
|
||||
torch.cuda.manual_seed_all(seed)
|
||||
torch.backends.cudnn.deterministic = True
|
||||
torch.backends.cudnn.benchmark = False
|
||||
|
||||
def _print_info(self):
|
||||
"""Wyświetla informacje o systemie"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("🎯 SYSTEM MINIGPT-60M")
|
||||
logger.info("=" * 60)
|
||||
logger.info(f"Python: {sys.version.split()[0]}")
|
||||
logger.info(f"PyTorch: {torch.__version__}")
|
||||
logger.info(f"Device: {self.device.upper()}")
|
||||
|
||||
if self.device == "cuda":
|
||||
gpu_count = torch.cuda.device_count()
|
||||
logger.info(f"CUDA dostępne: {torch.cuda.is_available()}")
|
||||
logger.info(f"Liczba GPU: {gpu_count}")
|
||||
for i in range(gpu_count):
|
||||
mem = torch.cuda.get_device_properties(i).total_memory / 1e9
|
||||
logger.info(f"GPU {i}: {torch.cuda.get_device_name(i)} ({mem:.1f} GB)")
|
||||
|
||||
logger.info("=" * 60)
|
||||
|
||||
# ==================== KONFIGURACJA MODELU ====================
|
||||
class ModelConfig:
|
||||
"""Konfiguracja modelu 60M parametrów"""
|
||||
|
||||
def __init__(self):
|
||||
# Słownik
|
||||
self.vocab_chars = list("aąbcćdeęfghijklłmnńoóprsśtuwyzźżAĄBCĆDEĘFGHIJKLŁMNŃOÓPRSŚTUWYZŹŻ")
|
||||
self.vocab_chars += list("0123456789")
|
||||
self.vocab_chars += list(" .,?!:;()[]{}+-*/=<>_\"'`~@#$%^&|\\/\n\t")
|
||||
self.vocab_chars += [" ", "\n\n", "\t\t", "->", "::", "=>"]
|
||||
|
||||
self.vocab = self.vocab_chars
|
||||
self.vocab_size = len(self.vocab)
|
||||
|
||||
# Architektura dla ~60M parametrów
|
||||
self.embed_dim = 768
|
||||
self.n_layers = 12
|
||||
self.n_heads = 12
|
||||
self.max_len = 512
|
||||
self.ff_dim = self.embed_dim * 4
|
||||
self.dropout = 0.1
|
||||
self.activation = "gelu"
|
||||
self.norm_eps = 1e-5
|
||||
|
||||
# Trening
|
||||
self.epochs = 3
|
||||
self.batch_size = 16 if torch.cuda.is_available() else 4
|
||||
self.grad_accum_steps = 4
|
||||
self.learning_rate = 3e-4
|
||||
self.weight_decay = 0.1
|
||||
self.adam_beta1 = 0.9
|
||||
self.adam_beta2 = 0.95
|
||||
self.adam_eps = 1e-8
|
||||
self.clip_grad = 1.0
|
||||
self.warmup_steps = 2000
|
||||
|
||||
# Mixed Precision
|
||||
self.use_amp = torch.cuda.is_available()
|
||||
|
||||
# Parallel
|
||||
self.num_workers = 4 if torch.cuda.is_available() else 0
|
||||
self.pin_memory = True
|
||||
|
||||
# Generowanie
|
||||
self.generation_temperature = 0.8
|
||||
self.top_k = 50
|
||||
self.top_p = 0.95
|
||||
self.repetition_penalty = 1.1
|
||||
|
||||
# Ścieżki
|
||||
self.model_dir = "models"
|
||||
self.data_dir = "data"
|
||||
self.prepared_dir = "prepared_data"
|
||||
self.log_dir = "logs"
|
||||
self.tensorboard_dir = "runs"
|
||||
self.cache_dir = ".cache"
|
||||
self.checkpoints_dir = "checkpoints"
|
||||
self.resume_file = "resume_state.json" # Plik stanu do wznowienia
|
||||
|
||||
# Tworzenie katalogów
|
||||
self._create_dirs()
|
||||
|
||||
def _create_dirs(self):
|
||||
"""Tworzy wymagane katalogi"""
|
||||
dirs = [self.model_dir, self.data_dir, self.prepared_dir,
|
||||
self.log_dir, self.tensorboard_dir, self.cache_dir,
|
||||
"backups", "results", self.checkpoints_dir]
|
||||
|
||||
for d in dirs:
|
||||
Path(d).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def print_config(self):
|
||||
"""Wyświetla konfigurację"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("⚙️ KONFIGURACJA MODELU")
|
||||
logger.info("=" * 60)
|
||||
logger.info(f"• Vocab size: {self.vocab_size}")
|
||||
logger.info(f"• Embed dim: {self.embed_dim}")
|
||||
logger.info(f"• Warstwy: {self.n_layers}")
|
||||
logger.info(f"• Głowy: {self.n_heads}")
|
||||
logger.info(f"• Kontekst: {self.max_len}")
|
||||
logger.info(f"• Batch size: {self.batch_size}")
|
||||
logger.info(f"• Learning rate: {self.learning_rate}")
|
||||
logger.info(f"• Mixed precision: {self.use_amp}")
|
||||
logger.info("=" * 60)
|
||||
|
||||
def save_resume_state(self, state: Dict[str, Any]):
|
||||
"""Zapisuje stan do wznowienia"""
|
||||
state_path = Path(self.checkpoints_dir) / self.resume_file
|
||||
with open(state_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(state, f, indent=2, ensure_ascii=False)
|
||||
logger.info(f"💾 Stan zapisany do {state_path}")
|
||||
|
||||
def load_resume_state(self) -> Optional[Dict[str, Any]]:
|
||||
"""Wczytuje stan do wznowienia"""
|
||||
state_path = Path(self.checkpoints_dir) / self.resume_file
|
||||
if state_path.exists():
|
||||
with open(state_path, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
return None
|
||||
|
||||
def get_latest_checkpoint(self) -> Optional[Path]:
|
||||
"""Znajduje najnowszy checkpoint"""
|
||||
checkpoints = list(Path(self.checkpoints_dir).glob("checkpoint_*.pt"))
|
||||
if checkpoints:
|
||||
# Sortuj po czasie modyfikacji
|
||||
checkpoints.sort(key=lambda x: x.stat().st_mtime, reverse=True)
|
||||
return checkpoints[0]
|
||||
return None
|
||||
|
||||
def get_latest_model(self) -> Optional[Path]:
|
||||
"""Znajduje najnowszy model"""
|
||||
models = list(Path(self.model_dir).glob("model_*.pt"))
|
||||
if models:
|
||||
# Szukaj model_final.pt, potem model_epoch_X.pt
|
||||
final_model = Path(self.model_dir) / "model_final.pt"
|
||||
if final_model.exists():
|
||||
return final_model
|
||||
|
||||
# Sortuj po numerze epoki
|
||||
def get_epoch_num(path: Path) -> int:
|
||||
try:
|
||||
# model_epoch_10.pt -> 10
|
||||
name = path.stem
|
||||
return int(name.split('_')[-1])
|
||||
except:
|
||||
return 0
|
||||
|
||||
models.sort(key=get_epoch_num, reverse=True)
|
||||
return models[0]
|
||||
return None
|
||||
def get_device(prefer_gpu=True):
|
||||
"""Inteligentnie wybiera urządzenie"""
|
||||
if prefer_gpu and torch.cuda.is_available():
|
||||
return 'cuda'
|
||||
elif torch.backends.mps.is_available(): # Apple Silicon
|
||||
return 'mps'
|
||||
else:
|
||||
return 'cpu'
|
||||
# Inicjalizacja konfiguracji
|
||||
sys_config = SystemConfig()
|
||||
cfg = ModelConfig()
|
||||
41
daj_no_Plik.py
Normal file
41
daj_no_Plik.py
Normal file
@ -0,0 +1,41 @@
|
||||
# daj_no_Plik.py (wersja lokalna)
|
||||
import os
|
||||
import zipfile
|
||||
import requests
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def download_from_url(url, save_path):
|
||||
"""Pobiera plik z URL"""
|
||||
print(f"Pobieranie z {url}...")
|
||||
response = requests.get(url, stream=True)
|
||||
|
||||
with open(save_path, 'wb') as f:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
print(f"Zapisano do {save_path}")
|
||||
|
||||
|
||||
def main():
|
||||
# Jeśli masz plik .zip na dysku
|
||||
zip_path = "/ścieżka/do/Pathl_AI.zip"
|
||||
|
||||
if os.path.exists(zip_path):
|
||||
print("Rozpakowywanie...")
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall("Pathl.AI")
|
||||
print("✅ Gotowe!")
|
||||
else:
|
||||
print("❌ Plik nie istnieje")
|
||||
print("\n📥 Pobierz plik z Google Colab:")
|
||||
print("1. W Colab uruchom:")
|
||||
print(" from google.colab import files")
|
||||
print(" files.download('/content/Pathl_AI.zip')")
|
||||
print("2. Pobierz plik na komputer")
|
||||
print("3. Uruchom ten skrypt ponownie")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("plik")
|
||||
main()
|
||||
108
final_fix.py
Normal file
108
final_fix.py
Normal file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Ostateczna poprawka metody generate()"""
|
||||
|
||||
import re
|
||||
|
||||
with open('ai.py', 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Nowa, uniwersalna metoda generate
|
||||
new_generate_method = '''
|
||||
def generate(self, input_ids=None, max_length=100, temperature=1.0, **kwargs):
|
||||
"""Uniwersalna metoda generate obsługująca różne interfejsy"""
|
||||
# Ignoruj nieobsługiwane argumenty (device, max_len, etc.)
|
||||
max_len = kwargs.get('max_len', max_length)
|
||||
|
||||
if isinstance(input_ids, str):
|
||||
return self.generate_text(input_ids, max_len=max_len, temperature=temperature)
|
||||
elif input_ids is not None:
|
||||
# Jeśli to tensor, przekonwertuj na tekst
|
||||
if hasattr(input_ids, 'tolist'):
|
||||
if len(input_ids.shape) > 1:
|
||||
text = self.tokenizer.decode(input_ids[0].tolist())
|
||||
else:
|
||||
text = self.tokenizer.decode(input_ids.tolist())
|
||||
else:
|
||||
text = self.tokenizer.decode(input_ids)
|
||||
return self.generate_text(text, max_len=max_len, temperature=temperature)
|
||||
else:
|
||||
return "" # Pusty string dla None input
|
||||
'''
|
||||
|
||||
# Znajdź i zamień metodę generate
|
||||
if 'def generate(' in content:
|
||||
# Użyj regex do znalezienia całej metody
|
||||
pattern = r'def generate\(.*?\).*?(?=\n def \w+\(|\nclass \w+|\Z)'
|
||||
|
||||
# Sprawdź czy regex działa
|
||||
match = re.search(pattern, content, re.DOTALL)
|
||||
if match:
|
||||
content = re.sub(pattern, new_generate_method, content, flags=re.DOTALL)
|
||||
print("✅ Zaktualizowano metodę generate()")
|
||||
else:
|
||||
# Alternatywny sposób: znajdź między def generate a następną def
|
||||
lines = content.split('\n')
|
||||
new_lines = []
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
new_lines.append(line)
|
||||
|
||||
if line.strip().startswith('def generate('):
|
||||
# Pomijaj stare linie metody aż do następnej metody
|
||||
i += 1
|
||||
while i < len(lines) and not lines[i].strip().startswith('def ') and not lines[i].strip().startswith('class '):
|
||||
i += 1
|
||||
# Dodaj nową metodę
|
||||
new_lines.append(new_generate_method)
|
||||
if i < len(lines):
|
||||
new_lines.append(lines[i])
|
||||
i += 1
|
||||
continue
|
||||
|
||||
i += 1
|
||||
|
||||
content = '\n'.join(new_lines)
|
||||
print("✅ Zastąpiono metodę generate() (alternatywna metoda)")
|
||||
else:
|
||||
print("❌ Metoda generate() nie znaleziona, dodaję...")
|
||||
# Dodaj przed ostatnią metodą w klasie
|
||||
if 'class MiniGPT60M' in content:
|
||||
# Wstaw przed ostatnim 'def' w klasie
|
||||
lines = content.split('\n')
|
||||
new_lines = []
|
||||
in_class = False
|
||||
methods_found = []
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
new_lines.append(line)
|
||||
|
||||
if 'class MiniGPT60M' in line:
|
||||
in_class = True
|
||||
|
||||
if in_class and line.strip().startswith('def '):
|
||||
methods_found.append(i)
|
||||
|
||||
if methods_found:
|
||||
# Dodaj przed ostatnią metodą
|
||||
last_method_idx = methods_found[-1]
|
||||
new_lines.insert(last_method_idx, '\n' + new_generate_method)
|
||||
content = '\n'.join(new_lines)
|
||||
print("✅ Dodano metodę generate()")
|
||||
else:
|
||||
# Dodaj na końcu klasy
|
||||
if 'class MiniGPT60M' in content:
|
||||
# Znajdź koniec klasy
|
||||
class_pattern = r'(class MiniGPT60M.*?)(?=\nclass|\Z)'
|
||||
match = re.search(class_pattern, content, re.DOTALL)
|
||||
if match:
|
||||
class_content = match.group(1)
|
||||
updated_class = class_content.rstrip() + '\n\n' + new_generate_method
|
||||
content = content.replace(class_content, updated_class)
|
||||
print("✅ Dodano metodę generate() na końcu klasy")
|
||||
|
||||
# Zapisz zmiany
|
||||
with open('ai.py', 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
print("✅ Plik ai.py zaktualizowany!")
|
||||
314
main.py
Normal file
314
main.py
Normal file
@ -0,0 +1,314 @@
|
||||
"""
|
||||
🎯 MAIN - Główny skrypt MiniGPT-60M z checkpointami
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import signal
|
||||
from pathlib import Path
|
||||
|
||||
# Dodaj ścieżkę do importów
|
||||
sys.path.append('.')
|
||||
|
||||
from config import logger, cfg, sys_config
|
||||
import prepare_data
|
||||
import ai
|
||||
|
||||
# ==================== OBSŁUGA SYGNAŁÓW ====================
|
||||
def signal_handler(sig, frame):
|
||||
"""Obsługa przerwania (Ctrl+C)"""
|
||||
logger.info("\n\n⚠️ Trening przerwany przez użytkownika!")
|
||||
logger.info("💾 Zapisuję stan do wznowienia...")
|
||||
|
||||
# Tutaj można dodać zapis stanu przed wyjściem
|
||||
# W aktualnej implementacji stan jest zapisywany automatycznie
|
||||
|
||||
logger.info("✅ Możesz wznowić trening używając: python main.py --cont")
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
# ==================== FUNKCJE GŁÓWNE ====================
|
||||
def prepare_all_data():
|
||||
"""Przygotowuje wszystkie dane"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("📊 PRZYGOTOWYWANIE WSZYSTKICH DANYCH")
|
||||
logger.info("=" * 60)
|
||||
|
||||
preparer = prepare_data.DataPreparer()
|
||||
preparer.prepare_all_data()
|
||||
|
||||
def train_model(resume: bool = False):
|
||||
"""Trenuje model"""
|
||||
logger.info("=" * 60)
|
||||
if resume:
|
||||
logger.info("🔄 WZNIOWANIE TRENINGU MODELU")
|
||||
else:
|
||||
logger.info("🚀 TRENING MODELU MINIGPT-60M")
|
||||
logger.info("=" * 60)
|
||||
|
||||
# Sprawdź czy dane są przygotowane
|
||||
data_file = Path(cfg.prepared_dir) / "all_data.txt"
|
||||
|
||||
if not data_file.exists():
|
||||
logger.warning("⚠️ Brak przygotowanych danych. Przygotowuję...")
|
||||
prepare_all_data()
|
||||
|
||||
# Uruchom trening
|
||||
if resume:
|
||||
ai.continue_training()
|
||||
else:
|
||||
ai.train_model(resume=False)
|
||||
|
||||
def continue_training():
|
||||
"""Kontynuuje trening od ostatniego checkpointu"""
|
||||
train_model(resume=True)
|
||||
|
||||
def train_more_epochs(additional_epochs: int = 3):
|
||||
"""Dodaje więcej epok treningu"""
|
||||
logger.info("=" * 60)
|
||||
logger.info(f"📈 DODATKOWY TRENING: {additional_epochs} epok")
|
||||
logger.info("=" * 60)
|
||||
|
||||
# Sprawdź czy dane są przygotowane
|
||||
data_file = Path(cfg.prepared_dir) / "all_data.txt"
|
||||
|
||||
if not data_file.exists():
|
||||
logger.error("❌ Brak przygotowanych danych!")
|
||||
logger.info("💡 Uruchom: python main.py --prepare")
|
||||
return
|
||||
|
||||
# Uruchom dodatkowy trening
|
||||
ai.train_more_epochs(additional_epochs)
|
||||
|
||||
def generate_text(prompt: str):
|
||||
"""Generuje tekst"""
|
||||
logger.info(f"🎨 GENEROWANIE TEKSTU: '{prompt}'")
|
||||
ai.generate_text(prompt)
|
||||
|
||||
def start_chat():
|
||||
"""Uruchamia czat"""
|
||||
ai.start_chat()
|
||||
|
||||
def evaluate_model():
|
||||
"""Ocenia model"""
|
||||
logger.info("🎯 OCENA MODELU")
|
||||
|
||||
# Sprawdź czy model istnieje
|
||||
model_path = cfg.get_latest_model()
|
||||
|
||||
if not model_path:
|
||||
logger.error("❌ Brak wytrenowanego modelu!")
|
||||
logger.info("💡 Uruchom: python main.py --train")
|
||||
return
|
||||
|
||||
logger.info(f"✅ Model wczytany: {model_path.name}")
|
||||
|
||||
# Tutaj można dodać ewaluację
|
||||
logger.info("📊 Dodaj ewaluację w ai.py")
|
||||
|
||||
def show_checkpoints():
|
||||
"""Pokazuje dostępne checkpointy"""
|
||||
logger.info("📁 DOSTĘPNE CHECKPOINTY:")
|
||||
|
||||
checkpoints = list(Path(cfg.checkpoints_dir).glob("checkpoint_*.pt"))
|
||||
models = list(Path(cfg.model_dir).glob("model_*.pt"))
|
||||
|
||||
if checkpoints:
|
||||
logger.info("\n🔽 CHECKPOINTY (do wznowienia):")
|
||||
for cp in sorted(checkpoints, key=lambda x: x.stat().st_mtime, reverse=True)[:5]:
|
||||
size_mb = cp.stat().st_size / (1024 * 1024)
|
||||
logger.info(f" • {cp.name} ({size_mb:.1f} MB)")
|
||||
else:
|
||||
logger.info(" ❌ Brak checkpointów")
|
||||
|
||||
if models:
|
||||
logger.info("\n🤖 MODELE:")
|
||||
for model in sorted(models, key=lambda x: x.stat().st_mtime, reverse=True)[:5]:
|
||||
size_mb = model.stat().st_size / (1024 * 1024)
|
||||
logger.info(f" • {model.name} ({size_mb:.1f} MB)")
|
||||
|
||||
# Sprawdź stan resume
|
||||
resume_state = cfg.load_resume_state()
|
||||
if resume_state:
|
||||
logger.info(f"\n🔄 OSTATNI STAN TRENINGU:")
|
||||
logger.info(f" • Epoka: {resume_state.get('epoch', 'N/A')}")
|
||||
logger.info(f" • Krok: {resume_state.get('step', 'N/A')}")
|
||||
logger.info(f" • Loss: {resume_state.get('train_loss', 'N/A')}")
|
||||
|
||||
def clean_checkpoints(keep_last: int = 3):
|
||||
"""Czyści stare checkpointy"""
|
||||
logger.info(f"🧹 CZYSZCZENIE STARYCH CHECKPOINTÓW (zachowuję {keep_last} najnowszych)")
|
||||
|
||||
checkpoints = list(Path(cfg.checkpoints_dir).glob("checkpoint_*.pt"))
|
||||
|
||||
if len(checkpoints) <= keep_last:
|
||||
logger.info("✅ Nie ma czego czyścić")
|
||||
return
|
||||
|
||||
# Sortuj od najstarszego do najnowszego
|
||||
checkpoints.sort(key=lambda x: x.stat().st_mtime)
|
||||
|
||||
# Usuń wszystkie poza keep_last najnowszych
|
||||
to_delete = checkpoints[:-keep_last]
|
||||
|
||||
for cp in to_delete:
|
||||
try:
|
||||
cp.unlink()
|
||||
logger.info(f" 🗑️ Usunięto: {cp.name}")
|
||||
except Exception as e:
|
||||
logger.error(f" ❌ Błąd usuwania {cp.name}: {e}")
|
||||
|
||||
logger.info(f"✅ Pozostawiono {keep_last} najnowszych checkpointów")
|
||||
|
||||
def show_config():
|
||||
"""Pokazuje konfigurację"""
|
||||
cfg.print_config()
|
||||
|
||||
def run_tests():
|
||||
"""Uruchamia testy"""
|
||||
logger.info("🧪 TESTY JEDNOSTKOWE")
|
||||
|
||||
# Test tokenizera
|
||||
from ai import tokenizer
|
||||
text = "Test tokenizacji"
|
||||
ids = tokenizer.encode(text)
|
||||
decoded = tokenizer.decode(ids)
|
||||
|
||||
logger.info(f"✅ Tokenizer: '{text}' -> '{decoded}'")
|
||||
|
||||
# Test modelu
|
||||
import torch
|
||||
model = ai.MiniGPT60M()
|
||||
x = torch.randint(0, cfg.vocab_size, (2, 32))
|
||||
logits = model(x)
|
||||
|
||||
logger.info(f"✅ Model: logits shape {logits.shape}")
|
||||
logger.info("✅ Wszystkie testy przeszły pomyślnie!")
|
||||
|
||||
# ==================== GŁÓWNA FUNKCJA ====================
|
||||
def main():
|
||||
"""Główna funkcja programu"""
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="🎯 MiniGPT-60M: Zaawansowany model językowy ~60M parametrów",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Przykłady użycia:
|
||||
python main.py --prepare # Przygotuj dane ze wszystkich folderów data_*
|
||||
python main.py --train # Trenuj model od początku
|
||||
python main.py --cont # Wznów trening od ostatniego checkpointu
|
||||
python main.py --more [N] # Dodaj N epok treningu (domyślnie 3)
|
||||
python main.py --generate "AI" # Generuj tekst
|
||||
python main.py --chat # Rozmawiaj z modelem
|
||||
python main.py --checkpoints # Pokaż dostępne checkpointy
|
||||
python main.py --clean-cp # Wyczyść stare checkpointy
|
||||
python main.py --test # Uruchom testy
|
||||
python main.py --config # Pokaż konfigurację
|
||||
python main.py --evaluate # Oceń model
|
||||
python main.py --all # Przygotuj dane i trenuj od początku
|
||||
|
||||
Kontynuacja treningu:
|
||||
Rozpocznij trening: python main.py --train
|
||||
Przerwij (Ctrl+C): Zapisz stan automatycznie
|
||||
Wznów: python main.py --cont
|
||||
Dodaj epoki: python main.py --more 5
|
||||
"""
|
||||
)
|
||||
|
||||
parser.add_argument("--prepare", action="store_true", help="Przygotuj dane")
|
||||
parser.add_argument("--train", action="store_true", help="Trening od początku")
|
||||
parser.add_argument("--cont", action="store_true", help="Kontynuuj trening od checkpointu")
|
||||
parser.add_argument("--more", type=int, nargs='?', const=3, help="Dodaj epoki treningu (domyślnie 3)")
|
||||
parser.add_argument("--generate", type=str, help="Generuj tekst z promptu")
|
||||
parser.add_argument("--chat", action="store_true", help="Tryb rozmowy")
|
||||
parser.add_argument("--checkpoints", action="store_true", help="Pokaż dostępne checkpointy")
|
||||
parser.add_argument("--clean-cp", action="store_true", help="Wyczyść stare checkpointy")
|
||||
parser.add_argument("--test", action="store_true", help="Testy jednostkowe")
|
||||
parser.add_argument("--config", action="store_true", help="Pokaż konfigurację")
|
||||
parser.add_argument("--evaluate", action="store_true", help="Oceń model")
|
||||
parser.add_argument("--all", action="store_true", help="Przygotuj dane i trenuj")
|
||||
parser.add_argument("--epochs", type=int, default=cfg.epochs, help="Liczba epok")
|
||||
parser.add_argument("--model", type=str, help="Ścieżka do konkretnego modelu")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Pokaż nagłówek
|
||||
logger.info("=" * 60)
|
||||
logger.info("🎯 MINIGPT-60M - Z CHECKPOINTAMI")
|
||||
logger.info("=" * 60)
|
||||
|
||||
# Update liczby epok jeśli podano
|
||||
if args.epochs != cfg.epochs:
|
||||
cfg.epochs = args.epochs
|
||||
logger.info(f"⚙️ Ustawiono {cfg.epochs} epok")
|
||||
|
||||
# Uruchom odpowiednią funkcję
|
||||
if args.prepare:
|
||||
prepare_all_data()
|
||||
|
||||
elif args.train:
|
||||
train_model(resume=False)
|
||||
|
||||
elif args.cont:
|
||||
continue_training()
|
||||
|
||||
elif args.more is not None:
|
||||
train_more_epochs(additional_epochs=args.more)
|
||||
|
||||
elif args.generate:
|
||||
generate_text(args.generate)
|
||||
|
||||
elif args.chat:
|
||||
start_chat()
|
||||
|
||||
elif args.checkpoints:
|
||||
show_checkpoints()
|
||||
|
||||
elif args.clean_cp:
|
||||
clean_checkpoints()
|
||||
|
||||
elif args.test:
|
||||
run_tests()
|
||||
|
||||
elif args.config:
|
||||
show_config()
|
||||
|
||||
elif args.evaluate:
|
||||
evaluate_model()
|
||||
|
||||
elif args.all:
|
||||
prepare_all_data()
|
||||
train_model(resume=False)
|
||||
|
||||
else:
|
||||
# Jeśli żadna flaga, pokaż help
|
||||
logger.info("\n❓ Nie podano flagi. Dostępne opcje:\n")
|
||||
parser.print_help()
|
||||
|
||||
# Pokaż dodatkowe informacje
|
||||
logger.info("\n💡 PRZYKŁADY UŻYCIA:")
|
||||
logger.info(" python main.py --train # Trenuj od początku")
|
||||
logger.info(" [Ctrl+C] # Przerwij trening")
|
||||
logger.info(" python main.py --cont # Wznów trening")
|
||||
logger.info(" python main.py --more 5 # Dodaj 5 epok")
|
||||
logger.info(" python main.py --generate 'AI' # Generuj tekst")
|
||||
|
||||
# Sprawdź czy są checkpointy
|
||||
if cfg.get_latest_checkpoint():
|
||||
logger.info("\n🔄 Dostępne checkpointy do wznowienia!")
|
||||
|
||||
logger.info("=" * 60)
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
logger.info("\n\n👋 Program przerwany przez użytkownika")
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
logger.error(f"\n❌ Krytyczny błąd: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
315
prepare_data.py
Normal file
315
prepare_data.py
Normal file
@ -0,0 +1,315 @@
|
||||
"""
|
||||
📊 PREPARE_DATA - Przygotowanie danych z wielu folderów
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import random
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Any, Generator
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
from config import logger, cfg
|
||||
|
||||
|
||||
# ==================== KLASY DO PRZYGOTOWANIA DANYCH ====================
|
||||
class DataPreparer:
|
||||
"""Główna klasa do przygotowania danych"""
|
||||
|
||||
def __init__(self):
|
||||
self.output_file = Path(cfg.prepared_dir) / "all_data.txt"
|
||||
self.metadata_file = Path(cfg.prepared_dir) / "metadata.json"
|
||||
self.stats = {
|
||||
"total_files": 0,
|
||||
"total_samples": 0,
|
||||
"total_chars": 0,
|
||||
"sources": {},
|
||||
"errors": []
|
||||
}
|
||||
|
||||
def find_data_folders(self) -> List[Path]:
|
||||
"""Znajduje wszystkie foldery zaczynające się od 'data_'"""
|
||||
current_dir = Path(".")
|
||||
data_folders = []
|
||||
|
||||
for item in current_dir.iterdir():
|
||||
if item.is_dir() and item.name.startswith("data_"):
|
||||
data_folders.append(item)
|
||||
logger.info(f"📁 Znaleziono folder: {item.name}")
|
||||
|
||||
# Dodaj też standardowy folder 'data' jeśli istnieje
|
||||
if Path("data").exists():
|
||||
data_folders.append(Path("data"))
|
||||
|
||||
return data_folders
|
||||
|
||||
def process_file(self, file_path: Path) -> List[str]:
|
||||
"""Przetwarza pojedynczy plik i zwraca próbki"""
|
||||
samples = []
|
||||
|
||||
try:
|
||||
if file_path.suffix == '.txt':
|
||||
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
content = f.read()
|
||||
|
||||
# Różne strategie dla różnych typów plików
|
||||
if "news" in file_path.name.lower() or "article" in file_path.name.lower():
|
||||
# Dla newsów - podziel na akapity
|
||||
paragraphs = re.split(r'\n\s*\n', content)
|
||||
for para in paragraphs:
|
||||
para = para.strip()
|
||||
if 100 < len(para) < 5000:
|
||||
samples.append(para)
|
||||
|
||||
elif "code" in file_path.name.lower() or "python" in file_path.name.lower():
|
||||
# Dla kodu - zachowaj całe funkcje
|
||||
lines = content.split('\n')
|
||||
current_chunk = []
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line:
|
||||
current_chunk.append(line)
|
||||
|
||||
# Jeśli znaleziono koniec funkcji lub duży blok
|
||||
if line.startswith('def ') and len(current_chunk) > 3:
|
||||
samples.append('\n'.join(current_chunk))
|
||||
current_chunk = []
|
||||
|
||||
# Dodaj pozostały chunk
|
||||
if current_chunk and len('\n'.join(current_chunk)) > 50:
|
||||
samples.append('\n'.join(current_chunk))
|
||||
|
||||
else:
|
||||
# Domyślnie - podziel na linie/akapity
|
||||
lines = content.split('\n')
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if 20 < len(line) < 1000:
|
||||
samples.append(line)
|
||||
|
||||
elif file_path.suffix == '.json':
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
if isinstance(data, list):
|
||||
for item in data:
|
||||
if isinstance(item, str):
|
||||
samples.append(item)
|
||||
elif isinstance(item, dict):
|
||||
# Konwertuj słownik na tekst
|
||||
text = ' '.join([f"{k}: {v}" for k, v in item.items()])
|
||||
if len(text) > 20:
|
||||
samples.append(text)
|
||||
|
||||
elif file_path.suffix == '.csv':
|
||||
import csv
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
text = ' '.join(row.values())
|
||||
if len(text) > 20:
|
||||
samples.append(text)
|
||||
|
||||
except Exception as e:
|
||||
self.stats["errors"].append(f"{file_path}: {str(e)}")
|
||||
|
||||
return samples
|
||||
|
||||
def process_folder(self, folder_path: Path) -> Dict[str, Any]:
|
||||
"""Przetwarza cały folder"""
|
||||
folder_stats = {
|
||||
"name": folder_path.name,
|
||||
"files_processed": 0,
|
||||
"samples_found": 0,
|
||||
"samples": []
|
||||
}
|
||||
|
||||
# Znajdź wszystkie pliki tekstowe
|
||||
file_patterns = ['*.txt', '*.json', '*.csv']
|
||||
files = []
|
||||
|
||||
for pattern in file_patterns:
|
||||
files.extend(list(folder_path.rglob(pattern)))
|
||||
|
||||
logger.info(f" 📂 {folder_path.name}: {len(files)} plików")
|
||||
|
||||
# Przetwarzaj pliki równolegle
|
||||
with ThreadPoolExecutor(max_workers=4) as executor:
|
||||
futures = {executor.submit(self.process_file, file): file for file in files}
|
||||
|
||||
for future in as_completed(futures):
|
||||
file = futures[future]
|
||||
try:
|
||||
samples = future.result()
|
||||
if samples:
|
||||
folder_stats["samples"].extend(samples)
|
||||
folder_stats["samples_found"] += len(samples)
|
||||
folder_stats["files_processed"] += 1
|
||||
except Exception as e:
|
||||
self.stats["errors"].append(f"{file}: {str(e)}")
|
||||
|
||||
return folder_stats
|
||||
|
||||
def prepare_all_data(self) -> None:
|
||||
"""Główna funkcja przygotowania danych"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("📊 PRZYGOTOWYWANIE DANYCH Z WSZYSTKICH FOLDERÓW")
|
||||
logger.info("=" * 60)
|
||||
|
||||
# Znajdź foldery
|
||||
data_folders = self.find_data_folders()
|
||||
|
||||
if not data_folders:
|
||||
logger.error("❌ Nie znaleziono folderów zaczynających się od 'data_'")
|
||||
return
|
||||
|
||||
all_samples = []
|
||||
|
||||
# Przetwórz każdy folder
|
||||
for folder in data_folders:
|
||||
logger.info(f"\n🔍 Przetwarzam folder: {folder.name}")
|
||||
|
||||
folder_stats = self.process_folder(folder)
|
||||
|
||||
if folder_stats["samples"]:
|
||||
all_samples.extend(folder_stats["samples"])
|
||||
self.stats["sources"][folder.name] = folder_stats["samples_found"]
|
||||
|
||||
logger.info(f" ✅ Znaleziono: {folder_stats['samples_found']} próbek")
|
||||
logger.info(f" 📝 Przykłady:")
|
||||
for sample in random.sample(folder_stats["samples"], min(3, len(folder_stats["samples"]))):
|
||||
logger.info(f" • {sample[:80]}...")
|
||||
else:
|
||||
logger.warning(f" ⚠️ Brak danych w folderze {folder.name}")
|
||||
|
||||
# Przetasuj i ogranicz
|
||||
if all_samples:
|
||||
random.shuffle(all_samples)
|
||||
|
||||
# Ogranicz do 1 miliona próbek (dla pamięci)
|
||||
if len(all_samples) > 1000000:
|
||||
all_samples = all_samples[:1000000]
|
||||
logger.warning(f"⚠️ Ograniczono do 1,000,000 próbek")
|
||||
|
||||
# Zapisz do jednego pliku
|
||||
self._save_to_file(all_samples)
|
||||
|
||||
# Zapisz metadane
|
||||
self._save_metadata()
|
||||
|
||||
# Podsumowanie
|
||||
self._print_summary()
|
||||
else:
|
||||
logger.error("❌ Nie znaleziono żadnych danych!")
|
||||
|
||||
def _save_to_file(self, samples: List[str]) -> None:
|
||||
"""Zapisuje wszystkie dane do jednego pliku"""
|
||||
logger.info(f"\n💾 Zapisuję {len(samples):,} próbek do {self.output_file}")
|
||||
|
||||
with open(self.output_file, 'w', encoding='utf-8') as f:
|
||||
for i, sample in enumerate(samples, 1):
|
||||
f.write(sample + "\n\n")
|
||||
|
||||
# Progress bar co 10k próbek
|
||||
if i % 10000 == 0:
|
||||
logger.info(f" Zapisano {i:,}/{len(samples):,} próbek")
|
||||
|
||||
logger.info(f"✅ Zapisano wszystkie dane do {self.output_file}")
|
||||
|
||||
def _save_metadata(self) -> None:
|
||||
"""Zapisuje metadane"""
|
||||
metadata = {
|
||||
"total_samples": self.stats["total_samples"],
|
||||
"total_chars": self.stats["total_chars"],
|
||||
"sources": self.stats["sources"],
|
||||
"created": os.path.getmtime(str(self.output_file)),
|
||||
"file_size": os.path.getsize(self.output_file),
|
||||
"errors": self.stats["errors"][:10] # Tylko 10 pierwszych błędów
|
||||
}
|
||||
|
||||
with open(self.metadata_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(metadata, f, indent=2, ensure_ascii=False)
|
||||
|
||||
logger.info(f"📊 Metadane zapisane do {self.metadata_file}")
|
||||
|
||||
def _print_summary(self) -> None:
|
||||
"""Wyświetla podsumowanie"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("📈 PODSUMOWANIE PRZYGOTOWANIA DANYCH")
|
||||
logger.info("=" * 60)
|
||||
|
||||
total_samples = self.stats["total_samples"]
|
||||
total_chars_mb = self.stats["total_chars"] / (1024 * 1024)
|
||||
|
||||
logger.info(f"📊 STATYSTYKI:")
|
||||
logger.info(f" • Całkowite próbki: {total_samples:,}")
|
||||
logger.info(f" • Rozmiar danych: {total_chars_mb:.1f} MB")
|
||||
logger.info(f" • Źródła danych: {len(self.stats['sources'])}")
|
||||
|
||||
logger.info(f"\n📁 ŹRÓDŁA:")
|
||||
for source, count in self.stats["sources"].items():
|
||||
logger.info(f" • {source}: {count:,} próbek")
|
||||
|
||||
if self.stats["errors"]:
|
||||
logger.warning(f"\n⚠️ BŁĘDY ({len(self.stats['errors'])}):")
|
||||
for error in self.stats["errors"][:5]:
|
||||
logger.warning(f" • {error}")
|
||||
|
||||
logger.info(f"\n💾 WYJŚCIE:")
|
||||
logger.info(f" • Dane: {self.output_file}")
|
||||
logger.info(f" • Metadane: {self.metadata_file}")
|
||||
|
||||
logger.info("\n🎮 UŻYCIE:")
|
||||
logger.info(" python main.py --train # Trening na przygotowanych danych")
|
||||
logger.info(" python main.py --prepare # Ponowne przygotowanie danych")
|
||||
logger.info("=" * 60)
|
||||
|
||||
|
||||
# ==================== FUNKCJE POMOCNICZE ====================
|
||||
def clean_text(text: str) -> str:
|
||||
"""Czyści tekst"""
|
||||
# Usuń nadmiarowe białe znaki
|
||||
text = re.sub(r'\s+', ' ', text)
|
||||
|
||||
# Usuń specjalne znaki (opcjonalnie)
|
||||
# text = re.sub(r'[^\w\s.,!?;:()\-\'"ąćęłńóśźżĄĆĘŁŃÓŚŹŻ]', '', text)
|
||||
|
||||
return text.strip()
|
||||
|
||||
|
||||
def split_into_chunks(text: str, max_chunk_size: int = 1000) -> List[str]:
|
||||
"""Dzieli długi tekst na kawałki"""
|
||||
words = text.split()
|
||||
chunks = []
|
||||
current_chunk = []
|
||||
current_size = 0
|
||||
|
||||
for word in words:
|
||||
word_size = len(word) + 1 # +1 dla spacji
|
||||
|
||||
if current_size + word_size > max_chunk_size and current_chunk:
|
||||
chunks.append(' '.join(current_chunk))
|
||||
current_chunk = [word]
|
||||
current_size = word_size
|
||||
else:
|
||||
current_chunk.append(word)
|
||||
current_size += word_size
|
||||
|
||||
if current_chunk:
|
||||
chunks.append(' '.join(current_chunk))
|
||||
|
||||
return chunks
|
||||
|
||||
|
||||
# ==================== GŁÓWNA FUNKCJA ====================
|
||||
def main():
|
||||
"""Główna funkcja przygotowania danych"""
|
||||
preparer = DataPreparer()
|
||||
preparer.prepare_all_data()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
108
test_questions.json
Normal file
108
test_questions.json
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"questions": [
|
||||
{"id": 1, "category": "polski", "question": "Jak się nazywasz?"},
|
||||
{"id": 2, "category": "polski", "question": "Skąd jesteś?"},
|
||||
{"id": 3, "category": "polski", "question": "Ile masz lat?"},
|
||||
{"id": 4, "category": "polski", "question": "Co lubisz robić?"},
|
||||
{"id": 5, "category": "polski", "question": "Jaki jest twój ulubiony film?"},
|
||||
{"id": 6, "category": "polski", "question": "Dlaczego uczysz się programowania?"},
|
||||
{"id": 7, "category": "polski", "question": "Jakie są twoje hobby?"},
|
||||
{"id": 8, "category": "polski", "question": "Jaka jest dziś pogoda?"},
|
||||
{"id": 9, "category": "polski", "question": "Co będzie jutro?"},
|
||||
{"id": 10, "category": "polski", "question": "Jakie jest twoje marzenie?"},
|
||||
{"id": 11, "category": "polski", "question": "Jaka jest twoja ulubiona książka?"},
|
||||
{"id": 12, "category": "polski", "question": "Kto jest twoim ulubionym autorem?"},
|
||||
{"id": 13, "category": "polski", "question": "Co lubisz jeść?"},
|
||||
{"id": 14, "category": "polski", "question": "Jak spędzasz weekend?"},
|
||||
{"id": 15, "category": "polski", "question": "Jakie filmy lubisz oglądać?"},
|
||||
{"id": 16, "category": "polski", "question": "Jaki jest twój ulubiony sport?"},
|
||||
{"id": 17, "category": "polski", "question": "Co robisz po szkole?"},
|
||||
{"id": 18, "category": "polski", "question": "Jakie jest twoje ulubione miejsce?"},
|
||||
{"id": 19, "category": "polski", "question": "Co lubisz w swojej szkole?"},
|
||||
{"id": 20, "category": "polski", "question": "Jakie są twoje plany na przyszłość?"},
|
||||
|
||||
{"id": 21, "category": "python", "question": "Co to jest zmienna w Pythonie?"},
|
||||
{"id": 22, "category": "python", "question": "Jak działa instrukcja if?"},
|
||||
{"id": 23, "category": "python", "question": "Do czego służy lista w Pythonie?"},
|
||||
{"id": 24, "category": "python", "question": "Jak działa słownik w Pythonie?"},
|
||||
{"id": 25, "category": "python", "question": "Co to jest moduł w Pythonie?"},
|
||||
{"id": 26, "category": "python", "question": "Jak działa pętla while?"},
|
||||
{"id": 27, "category": "python", "question": "Jak otworzyć plik w Pythonie?"},
|
||||
{"id": 28, "category": "python", "question": "Jak działa funkcja print()?"},
|
||||
{"id": 29, "category": "python", "question": "Co to jest wyjątek?"},
|
||||
{"id": 30, "category": "python", "question": "Jak działa f-string?"},
|
||||
{"id": 31, "category": "python", "question": "Jak definiuje się funkcję w Pythonie?"},
|
||||
{"id": 32, "category": "python", "question": "Co to jest tuple?"},
|
||||
{"id": 33, "category": "python", "question": "Co to jest set?"},
|
||||
{"id": 34, "category": "python", "question": "Jak działa pętla for?"},
|
||||
{"id": 35, "category": "python", "question": "Jak działa operator in?"},
|
||||
{"id": 36, "category": "python", "question": "Co robi pass w Pythonie?"},
|
||||
{"id": 37, "category": "python", "question": "Jak działa funkcja input()?"},
|
||||
{"id": 38, "category": "python", "question": "Co to jest list comprehension?"},
|
||||
{"id": 39, "category": "python", "question": "Jak działa instrukcja break?"},
|
||||
{"id": 40, "category": "python", "question": "Jak działa instrukcja continue?"},
|
||||
|
||||
{"id": 41, "category": "matematyka", "question": "Co to jest liczba pierwsza?"},
|
||||
{"id": 42, "category": "matematyka", "question": "Jak obliczyć procent?"},
|
||||
{"id": 43, "category": "matematyka", "question": "Co to jest promień koła?"},
|
||||
{"id": 44, "category": "matematyka", "question": "Jak obliczyć pole prostokąta?"},
|
||||
{"id": 45, "category": "matematyka", "question": "Co to jest równanie?"},
|
||||
{"id": 46, "category": "matematyka", "question": "Jak działa pierwiastek kwadratowy?"},
|
||||
{"id": 47, "category": "matematyka", "question": "Co to jest funkcja?"},
|
||||
{"id": 48, "category": "matematyka", "question": "Jak obliczyć średnią?"},
|
||||
{"id": 49, "category": "matematyka", "question": "Co to jest wektor?"},
|
||||
{"id": 50, "category": "matematyka", "question": "Jak działa logarytm?"},
|
||||
{"id": 51, "category": "matematyka", "question": "Co to jest macierz?"},
|
||||
{"id": 52, "category": "matematyka", "question": "Jak obliczyć deltę w równaniu kwadratowym?"},
|
||||
{"id": 53, "category": "matematyka", "question": "Co to jest granica funkcji?"},
|
||||
{"id": 54, "category": "matematyka", "question": "Jak działa pochodna?"},
|
||||
{"id": 55, "category": "matematyka", "question": "Co to jest całka?"},
|
||||
{"id": 56, "category": "matematyka", "question": "Jak obliczyć pole trójkąta?"},
|
||||
{"id": 57, "category": "matematyka", "question": "Co to jest ciąg arytmetyczny?"},
|
||||
{"id": 58, "category": "matematyka", "question": "Co to jest ciąg geometryczny?"},
|
||||
{"id": 59, "category": "matematyka", "question": "Jak działa funkcja odwrotna?"},
|
||||
{"id": 60, "category": "matematyka", "question": "Co to jest wartość bezwzględna?"},
|
||||
|
||||
{"id": 61, "category": "historia", "question": "Kiedy była II wojna światowa?"},
|
||||
{"id": 62, "category": "historia", "question": "Kto był królem Polski?"},
|
||||
{"id": 63, "category": "historia", "question": "Co to była komunizm?"},
|
||||
{"id": 64, "category": "historia", "question": "Gdzie działał Napoleon?"},
|
||||
{"id": 65, "category": "historia", "question": "Kto wynalazł prasę drukarską?"},
|
||||
{"id": 66, "category": "historia", "question": "Czym był średniowiecze?"},
|
||||
{"id": 67, "category": "historia", "question": "Co spowodowało rewolucję przemysłową?"},
|
||||
{"id": 68, "category": "historia", "question": "Kto był Juliusz Cezar?"},
|
||||
{"id": 69, "category": "historia", "question": "Co to był renesans?"},
|
||||
{"id": 70, "category": "historia", "question": "Kiedy Polska odzyskała niepodległość?"},
|
||||
{"id": 71, "category": "historia", "question": "Kto był pierwszym prezydentem USA?"},
|
||||
{"id": 72, "category": "historia", "question": "Co to była zimna wojna?"},
|
||||
{"id": 73, "category": "historia", "question": "Kto był Hitlerem?"},
|
||||
{"id": 74, "category": "historia", "question": "Co to była rewolucja francuska?"},
|
||||
{"id": 75, "category": "historia", "question": "Kiedy powstało państwo polskie?"},
|
||||
{"id": 76, "category": "historia", "question": "Kto był Karolem Wielkim?"},
|
||||
{"id": 77, "category": "historia", "question": "Co to była starożytna Grecja?"},
|
||||
{"id": 78, "category": "historia", "question": "Co to była starożytna Roma?"},
|
||||
{"id": 79, "category": "historia", "question": "Kto był Kazimierz Wielki?"},
|
||||
{"id": 80, "category": "historia", "question": "Kiedy był upadek Cesarstwa Rzymskiego?"},
|
||||
|
||||
{"id": 81, "category": "nauka", "question": "Co to jest atom?"},
|
||||
{"id": 82, "category": "nauka", "question": "Jak działa grawitacja?"},
|
||||
{"id": 83, "category": "nauka", "question": "Co to jest DNA?"},
|
||||
{"id": 84, "category": "nauka", "question": "Jak powstaje tęcza?"},
|
||||
{"id": 85, "category": "nauka", "question": "Co to jest energia?"},
|
||||
{"id": 86, "category": "nauka", "question": "Jak działa magnetyzm?"},
|
||||
{"id": 87, "category": "nauka", "question": "Co to jest światło?"},
|
||||
{"id": 88, "category": "nauka", "question": "Jak działa silnik?"},
|
||||
{"id": 89, "category": "nauka", "question": "Co to jest fotosynteza?"},
|
||||
{"id": 90, "category": "nauka", "question": "Jak działa komputer?"},
|
||||
{"id": 91, "category": "nauka", "question": "Co to jest elektron?"},
|
||||
{"id": 92, "category": "nauka", "question": "Jak działa siła odśrodkowa?"},
|
||||
{"id": 93, "category": "nauka", "question": "Co to jest ciśnienie atmosferyczne?"},
|
||||
{"id": 94, "category": "nauka", "question": "Co to jest fotosfera?"},
|
||||
{"id": 95, "category": "nauka", "question": "Jak powstaje wiatr?"},
|
||||
{"id": 96, "category": "nauka", "question": "Co to jest ciśnienie krwi?"},
|
||||
{"id": 97, "category": "nauka", "question": "Co to jest komórka?"},
|
||||
{"id": 98, "category": "nauka", "question": "Co to jest grawitacja Newtona?"},
|
||||
{"id": 99, "category": "nauka", "question": "Jak działa fotosynteza w roślinach?"},
|
||||
{"id": 100, "category": "nauka", "question": "Co to jest mikroorganizm?"}
|
||||
]
|
||||
}
|
||||
190
training.log
Normal file
190
training.log
Normal file
@ -0,0 +1,190 @@
|
||||
2026-01-26 11:36:51,804 - INFO - ============================================================
|
||||
2026-01-26 11:36:51,804 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:36:51,804 - INFO - ============================================================
|
||||
2026-01-26 11:36:51,804 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:36:51,804 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:36:51,804 - INFO - Device: CPU
|
||||
2026-01-26 11:36:51,804 - INFO - ============================================================
|
||||
2026-01-26 11:36:51,963 - INFO - ============================================================
|
||||
2026-01-26 11:36:51,963 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:36:51,963 - INFO - ============================================================
|
||||
2026-01-26 11:36:51,963 - INFO -
|
||||
❓ Nie podano flagi. Dostępne opcje:
|
||||
|
||||
2026-01-26 11:36:51,964 - INFO -
|
||||
💡 PRZYKŁADY UŻYCIA:
|
||||
2026-01-26 11:36:51,965 - INFO - python main.py --train # Trenuj od początku
|
||||
2026-01-26 11:36:51,965 - INFO - [Ctrl+C] # Przerwij trening
|
||||
2026-01-26 11:36:51,965 - INFO - python main.py --cont # Wznów trening
|
||||
2026-01-26 11:36:51,965 - INFO - python main.py --more 5 # Dodaj 5 epok
|
||||
2026-01-26 11:36:51,965 - INFO - python main.py --generate 'AI' # Generuj tekst
|
||||
2026-01-26 11:36:51,965 - INFO - ============================================================
|
||||
2026-01-26 11:37:01,141 - INFO - ============================================================
|
||||
2026-01-26 11:37:01,141 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:37:01,141 - INFO - ============================================================
|
||||
2026-01-26 11:37:01,141 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:37:01,141 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:37:01,141 - INFO - Device: CPU
|
||||
2026-01-26 11:37:01,141 - INFO - ============================================================
|
||||
2026-01-26 11:37:01,225 - INFO - ============================================================
|
||||
2026-01-26 11:37:01,225 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:37:01,225 - INFO - ============================================================
|
||||
2026-01-26 11:37:02,243 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:37:02,244 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:37:02,244 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:37:08,343 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:37:08,343 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:37:08,343 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:37:55,253 - INFO - ============================================================
|
||||
2026-01-26 11:37:55,254 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:37:55,254 - INFO - ============================================================
|
||||
2026-01-26 11:37:55,254 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:37:55,255 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:37:55,255 - INFO - Device: CPU
|
||||
2026-01-26 11:37:55,255 - INFO - ============================================================
|
||||
2026-01-26 11:37:55,453 - INFO - ============================================================
|
||||
2026-01-26 11:37:55,453 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:37:55,453 - INFO - ============================================================
|
||||
2026-01-26 11:37:56,683 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:37:56,684 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:37:56,685 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:38:10,327 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:38:10,327 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:38:10,327 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:38:31,310 - INFO - ============================================================
|
||||
2026-01-26 11:38:31,310 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:38:31,310 - INFO - ============================================================
|
||||
2026-01-26 11:38:31,310 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:38:31,310 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:38:31,310 - INFO - Device: CPU
|
||||
2026-01-26 11:38:31,310 - INFO - ============================================================
|
||||
2026-01-26 11:38:31,473 - INFO - ============================================================
|
||||
2026-01-26 11:38:31,473 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:38:31,473 - INFO - ============================================================
|
||||
2026-01-26 11:38:32,504 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:38:32,504 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:38:32,505 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:38:36,336 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:38:36,336 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:38:36,336 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:39:32,575 - INFO - ============================================================
|
||||
2026-01-26 11:39:32,576 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:39:32,576 - INFO - ============================================================
|
||||
2026-01-26 11:39:32,576 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:39:32,576 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:39:32,576 - INFO - Device: CPU
|
||||
2026-01-26 11:39:32,576 - INFO - ============================================================
|
||||
2026-01-26 11:39:32,740 - INFO - ============================================================
|
||||
2026-01-26 11:39:32,740 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:39:32,740 - INFO - ============================================================
|
||||
2026-01-26 11:39:33,882 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:39:33,882 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:39:33,883 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:39:36,591 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:39:36,591 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:39:36,591 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:40:11,736 - INFO - ============================================================
|
||||
2026-01-26 11:40:11,737 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:40:11,737 - INFO - ============================================================
|
||||
2026-01-26 11:40:11,737 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:40:11,737 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:40:11,737 - INFO - Device: CPU
|
||||
2026-01-26 11:40:11,737 - INFO - ============================================================
|
||||
2026-01-26 11:40:11,872 - INFO - ============================================================
|
||||
2026-01-26 11:40:11,872 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:40:11,873 - INFO - ============================================================
|
||||
2026-01-26 11:40:13,485 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:40:13,486 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:40:13,488 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:40:15,460 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:40:15,460 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:40:15,460 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:41:14,387 - INFO - ============================================================
|
||||
2026-01-26 11:41:14,388 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:41:14,388 - INFO - ============================================================
|
||||
2026-01-26 11:41:14,388 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:41:14,388 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:41:14,388 - INFO - Device: CPU
|
||||
2026-01-26 11:41:14,388 - INFO - ============================================================
|
||||
2026-01-26 11:41:14,475 - INFO - ============================================================
|
||||
2026-01-26 11:41:14,475 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:41:14,475 - INFO - ============================================================
|
||||
2026-01-26 11:41:15,430 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:41:15,431 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:41:15,431 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:41:18,877 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:41:18,877 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:41:18,877 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:43:21,037 - INFO - ============================================================
|
||||
2026-01-26 11:43:21,038 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:43:21,038 - INFO - ============================================================
|
||||
2026-01-26 11:43:21,038 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:43:21,038 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:43:21,038 - INFO - Device: CPU
|
||||
2026-01-26 11:43:21,038 - INFO - ============================================================
|
||||
2026-01-26 11:43:21,124 - INFO - ============================================================
|
||||
2026-01-26 11:43:21,124 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:43:21,124 - INFO - ============================================================
|
||||
2026-01-26 11:43:22,084 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:43:22,084 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:43:22,085 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:43:24,269 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:43:24,269 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:43:24,270 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:44:46,990 - INFO - ============================================================
|
||||
2026-01-26 11:44:46,990 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:44:46,990 - INFO - ============================================================
|
||||
2026-01-26 11:44:46,990 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:44:46,990 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:44:46,990 - INFO - Device: CPU
|
||||
2026-01-26 11:44:46,990 - INFO - ============================================================
|
||||
2026-01-26 11:44:57,235 - INFO - ============================================================
|
||||
2026-01-26 11:44:57,235 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:44:57,235 - INFO - ============================================================
|
||||
2026-01-26 11:44:57,235 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:44:57,235 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:44:57,235 - INFO - Device: CPU
|
||||
2026-01-26 11:44:57,235 - INFO - ============================================================
|
||||
2026-01-26 11:44:57,321 - INFO - ============================================================
|
||||
2026-01-26 11:44:57,321 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:44:57,321 - INFO - ============================================================
|
||||
2026-01-26 11:44:58,280 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:44:58,281 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:44:58,281 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:45:05,073 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:45:05,073 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:45:05,073 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
2026-01-26 11:51:39,327 - INFO - ============================================================
|
||||
2026-01-26 11:51:39,327 - INFO - 🎯 SYSTEM MINIGPT-60M
|
||||
2026-01-26 11:51:39,327 - INFO - ============================================================
|
||||
2026-01-26 11:51:39,327 - INFO - Python: 3.13.5
|
||||
2026-01-26 11:51:39,327 - INFO - PyTorch: 2.9.1+cpu
|
||||
2026-01-26 11:51:39,328 - INFO - Device: CPU
|
||||
2026-01-26 11:51:39,328 - INFO - ============================================================
|
||||
2026-01-26 11:51:39,414 - INFO - ============================================================
|
||||
2026-01-26 11:51:39,414 - INFO - 🎯 MINIGPT-60M - Z CHECKPOINTAMI
|
||||
2026-01-26 11:51:39,414 - INFO - ============================================================
|
||||
2026-01-26 11:51:39,414 - WARNING - ⚠️ Brak wytrenowanego modelu, używam niewytrenowanego
|
||||
2026-01-26 11:51:40,380 - INFO - 🤖 Model: 85,501,440 parametrów (85.5M)
|
||||
2026-01-26 11:51:40,389 - INFO - 🤖 ChatBot initialized on cpu
|
||||
2026-01-26 11:52:15,241 - INFO -
|
||||
|
||||
⚠️ Trening przerwany przez użytkownika!
|
||||
2026-01-26 11:52:15,242 - INFO - 💾 Zapisuję stan do wznowienia...
|
||||
2026-01-26 11:52:15,242 - INFO - ✅ Możesz wznowić trening używając: python main.py --cont
|
||||
Loading…
Reference in New Issue
Block a user