locgi / train_simple.py
Mauricio-100's picture
Upload train_simple.py with huggingface_hub
34001e4 verified
Raw
History Blame Contribute Delete
3.14 kB
import torch
import torch.nn as nn
import json
from safetensors.torch import save_file
class GopuBrain(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, vocab_size)
def forward(self, x, hidden=None):
x = self.embedding(x)
out, hidden = self.lstm(x, hidden)
return self.fc(out), hidden
# Charger le corpus
with open("corpus.txt", "r", encoding="utf-8") as f:
texte = f.read()
print(f"📚 Corpus: {len(texte)} caractères")
# Vocabulaire
vocab = sorted(list(set(texte)))
char_to_int = {c: i for i, c in enumerate(vocab)}
int_to_char = {i: c for i, c in enumerate(vocab)}
with open("vocab.json", "w") as f:
json.dump(char_to_int, f)
print(f"📝 Vocabulaire: {len(vocab)} caractères")
# Modèle plus petit pour aller plus vite
model = GopuBrain(len(vocab), 64, 128) # Réduit: 64 au lieu de 128, 128 au lieu de 256
optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # Learning rate plus élevé
criterion = nn.CrossEntropyLoss()
# Entraînement optimisé
def train_step(seq_len=80):
# Position aléatoire
start = torch.randint(0, max(1, len(texte) - seq_len - 1), (1,)).item()
x = torch.tensor([char_to_int[c] for c in texte[start:start+seq_len]], dtype=torch.long).unsqueeze(0)
y = torch.tensor([char_to_int[c] for c in texte[start+1:start+seq_len+1]], dtype=torch.long).unsqueeze(0)
model.train()
optimizer.zero_grad()
out, _ = model(x)
loss = criterion(out.reshape(-1, len(vocab)), y.reshape(-1))
loss.backward()
optimizer.step()
return loss.item()
print("\n🚀 Entraînement rapide...")
print("=" * 40)
best_loss = float('inf')
# Seulement 50 époques, mais avec plus d'échantillons par époque
for epoch in range(50):
# Faire plusieurs steps par époque pour apprendre plus vite
total_loss = 0
for _ in range(20): # 20 échantillons par époque
loss = train_step()
total_loss += loss
avg_loss = total_loss / 20
if avg_loss < best_loss:
best_loss = avg_loss
save_file(model.state_dict(), "gopu_poids.safetensors")
if epoch % 10 == 0 or epoch == 49:
print(f"Époque {epoch:3d}/50 | Loss: {avg_loss:.4f} | Best: {best_loss:.4f}")
print("=" * 40)
print("✅ Terminé en {:.1f} secondes !".format(epoch * 2)) # Estimation
print(f"📊 Meilleure loss: {best_loss:.4f}")
print(f"💾 Modèle sauvegardé")
# Test rapide
def test(prompt, n=20):
model.eval()
result = prompt
for _ in range(n):
data = [char_to_int.get(c, 0) for c in result[-50:]]
x = torch.tensor(data, dtype=torch.long).unsqueeze(0)
out, _ = model(x)
char = int_to_char[torch.argmax(out[0, -1]).item()]
result += char
return result
print("\n🧪 Tests:")
print(f" bonjour -> {test('bonjour')}")
print(f" le football -> {test('le football')}")
print(f" python est -> {test('python est')}")