tahamajs's picture
download
raw
6.15 kB
# train.py - Training and evaluation functions
import torch
import torch.nn as nn
import torch.optim as optim
from transformers import AutoTokenizer
def train_model(model, optimizer, train_loader, epochs=5, device='cuda'):
model.to(device)
model.train()
criterion = nn.CrossEntropyLoss()
for epoch in range(epochs):
total_loss = 0
for imgs, labels in train_loader:
imgs, labels = imgs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(imgs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {total_loss/len(train_loader):.4f}")
def evaluate_model(model, test_loader, device='cuda'):
model.to(device)
model.eval()
correct = 0
total = 0
with torch.no_grad():
for imgs, labels in test_loader:
imgs, labels = imgs.to(device), labels.to(device)
outputs = model(imgs)
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f"Accuracy: {accuracy:.2f}%")
return accuracy
# LLaDA training functions
def prepare_batch(examples, tokenizer):
"""Prepare a batch of examples for training"""
input_ids_list = []
prompt_lengths = []
for example in examples:
prompt, answer = format_example(example, tokenizer)
full_text = prompt + answer
# Tokenize
tokens = tokenizer(full_text, return_tensors='pt', padding=False)
input_ids = tokens['input_ids'].squeeze()
# Find prompt length
prompt_tokens = tokenizer(prompt, return_tensors='pt', padding=False)['input_ids'].squeeze()
prompt_len = len(prompt_tokens)
input_ids_list.append(input_ids)
prompt_lengths.append(prompt_len)
# Pad to max length
max_len = max(len(ids) for ids in input_ids_list)
padded_ids = []
attention_masks = []
for ids in input_ids_list:
pad_len = max_len - len(ids)
padded = torch.cat([ids, torch.full((pad_len,), tokenizer.pad_token_id)])
mask = torch.cat([torch.ones(len(ids)), torch.zeros(pad_len)])
padded_ids.append(padded)
attention_masks.append(mask)
batch_input_ids = torch.stack(padded_ids)
batch_attention_mask = torch.stack(attention_masks)
batch_prompt_lengths = torch.tensor(prompt_lengths)
return batch_input_ids, batch_attention_mask, batch_prompt_lengths
def noisy_batch(input_ids, attention_mask, prompt_lengths, tokenizer, schedule='linear'):
batch_size, seq_len = input_ids.shape
device = input_ids.device
t = torch.rand(batch_size, device=device)
if schedule == 'linear':
p_mask = t.view(-1,1)
else:
p_mask = t.view(-1,1)
p_mask_exp = p_mask.expand(-1, seq_len)
rand_matrix = torch.rand(input_ids.shape, device=device)
mask_indices = rand_matrix < p_mask_exp
for i in range(batch_size):
mask_indices[i, :prompt_lengths[i]] = False
mask_indices = mask_indices & (attention_mask.bool())
special_ids = set(
x for x in [getattr(tokenizer, 'eos_token_id', None), getattr(tokenizer, 'pad_token_id', None)] if x is not None
)
if len(special_ids) > 0:
for sid in special_ids:
mask_indices = mask_indices & (input_ids != sid)
masked_input_ids = input_ids.clone()
labels = torch.full_like(input_ids, -100)
masked_input_ids[mask_indices] = tokenizer.mask_token_id
labels[mask_indices] = input_ids[mask_indices]
# Ensure at least one masked token per sample if possible
for i in range(batch_size):
if mask_indices[i].sum() == 0:
start = int(prompt_lengths[i].item())
if start < seq_len:
idx = torch.randint(start, seq_len, (1,), device=device).item()
mask_indices[i, idx] = True
masked_input_ids[i, idx] = tokenizer.mask_token_id
labels[i, idx] = input_ids[i, idx]
return masked_input_ids, labels, mask_indices, p_mask.view(-1,1)
def train_step(batch, model, optimizer, tokenizer, device='cuda'):
input_ids, att_mask, prompt_lens = prepare_batch(batch, tokenizer)
input_ids, att_mask, prompt_lens = input_ids.to(device), att_mask.to(device), prompt_lens.to(device)
masked_ids, labels, mask_indices, p_mask = noisy_batch(input_ids, att_mask, prompt_lens, tokenizer)
outputs = model(input_ids=masked_ids, attention_mask=att_mask)
logits = outputs.logits
loss_fct = nn.CrossEntropyLoss(reduction='none')
loss = loss_fct(logits.view(-1, logits.size(-1)), labels.view(-1))
batch_size = input_ids.shape[0]
loss = loss.view(batch_size, -1)
num_masked = mask_indices.sum(dim=1).float()
safe_num = num_masked.clone()
safe_num[safe_num == 0] = 1.0
loss_per_seq = loss.sum(dim=1)
loss_per_mask = loss_per_seq / safe_num
weights = 1.0 / (p_mask.squeeze() + 1e-6)
weighted_loss = loss_per_mask * weights * (num_masked > 0).float()
final_loss = weighted_loss.mean()
final_loss.backward()
optimizer.step()
optimizer.zero_grad()
return final_loss.item()
def evaluate_pipeline(test_dataset, model, tokenizer, device='cuda', num_samples=10):
from data import format_example, exact_match_score
from utils import post_process_sql
total = 0
correct = 0
for example in test_dataset.select(range(num_samples)): # Small subset for demo
prompt, gold_sql = format_example(example, tokenizer)
# Generate
from generate import generate_block_diffusion
raw_output = generate_block_diffusion(model, tokenizer, prompt)
pred_sql = post_process_sql(raw_output)
# Metric
if exact_match_score(pred_sql, gold_sql):
correct += 1
total += 1
print(f"Accuracy: {correct/total * 100:.2f}%")

Xet Storage Details

Size:
6.15 kB
·
Xet hash:
49366da610f855cbc23d9ff8c97d2c0ffb699157680df7b5c19d7b63214c20b2

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.