Download sbert_training/train.py from jstAnotherCapi/sbert_training_raw_folder_HPC: direct link, hf CLI and curl.
- Browser
- Download file 5.76 kB
-
https://huggingface.co/jstAnotherCapi/sbert_training_raw_folder_HPC/resolve/main/sbert_training/train.py
- Command line
-
hf download hf://jstAnotherCapi/sbert_training_raw_folder_HPC/sbert_training/train.py
-
curl -L -o train.py https://huggingface.co/jstAnotherCapi/sbert_training_raw_folder_HPC/resolve/main/sbert_training/train.py
5.76 kB
| import os | |
| from sklearn.model_selection import train_test_split | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import logging | |
| import sys | |
| import traceback | |
| from datetime import datetime | |
| from datasets import load_dataset | |
| from sentence_transformers import SentenceTransformer, losses | |
| from sentence_transformers.evaluation import EmbeddingSimilarityEvaluator,TripletEvaluator,SequentialEvaluator | |
| from sentence_transformers.similarity_functions import SimilarityFunction | |
| from sentence_transformers.trainer import SentenceTransformerTrainer | |
| from sentence_transformers.training_args import SentenceTransformerTrainingArguments | |
| import torch | |
| from sentence_transformers.training_args import BatchSamplers | |
| import pandas as pd | |
| from arabert.preprocess import ArabertPreprocessor | |
| from pathlib import Path | |
| # Configure logging to write to logs.txt | |
| logging.basicConfig( | |
| format="%(asctime)s - %(message)s", | |
| datefmt="%Y-%m-%d %H:%M:%S", | |
| level=logging.INFO, | |
| handlers=[ | |
| logging.FileHandler("logs.txt") | |
| ] | |
| ) | |
| class Tee: | |
| def __init__(self, *files): | |
| self.files = files | |
| def write(self, obj): | |
| for f in self.files: | |
| f.write(obj) | |
| f.flush() | |
| def flush(self): | |
| for f in self.files: | |
| f.flush() | |
| def isatty(self): | |
| return False | |
| log_file = open("logs.txt", "a") | |
| sys.stdout = Tee(sys.stdout, log_file) | |
| train_batch_size = 64 | |
| model_name = "bert-base-arabertv02" | |
| model_nickname = "arabert" | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M") | |
| output_dir = f"output/{model_nickname}_{timestamp}" | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| model = SentenceTransformer(model_name, device=device) | |
| print(f"Model is running on: {device}") | |
| logging.info("Reading the training and eval dataset") | |
| train_dataset = load_dataset("csv", data_files="train.csv") | |
| eval_dataset = load_dataset("csv", data_files="val.csv") | |
| test_dataset = load_dataset("csv", data_files="test.csv") | |
| logging.info(train_dataset) | |
| logging.info(eval_dataset) | |
| logging.info(test_dataset) | |
| # Add this line before the 'evaluators = []' loop | |
| eval_subset = eval_dataset["train"].shuffle(seed=42).select(range(250000)) | |
| # Training loss | |
| matryoshka_dims = [768, 512, 256, 128, 64] | |
| inner_train_loss = losses.MultipleNegativesRankingLoss(model=model) | |
| train_loss = losses.MatryoshkaLoss(model, inner_train_loss, matryoshka_dims=matryoshka_dims) | |
| # Evaluators for validation | |
| evaluators = [] | |
| for dim in matryoshka_dims: | |
| evaluators.append( | |
| TripletEvaluator( | |
| anchors=eval_subset["anchor"], | |
| positives=eval_subset["positive"], | |
| negatives=eval_subset["negative"], | |
| name=f"dev-{dim}", | |
| truncate_dim=dim, | |
| ) | |
| ) | |
| dev_evaluator = SequentialEvaluator(evaluators, main_score_function=lambda scores: scores[0]) | |
| dev_evaluator(model) | |
| args = SentenceTransformerTrainingArguments( | |
| # --- Output & Identity --- | |
| output_dir=output_dir, # Where the model and checkpoints are saved | |
| seed=42, # Ensures results are reproducible (shuffling/init) | |
| # --- Epochs & Batching (L40S Optimized) --- | |
| num_train_epochs=2, # Increased to 2 for better convergence | |
| per_device_train_batch_size=train_batch_size, # High batch size to saturate the L40S 48GB VRAM | |
| per_device_eval_batch_size=train_batch_size, # Matching eval batch size for speed | |
| gradient_accumulation_steps=2, # Effective batch size = 128 (64 * 2) | |
| # --- Optimization & Precision --- | |
| bf16=True, # Set to True for L40S; faster and more stable than FP16 | |
| fp16=False, # Disabled in favor of BF16 | |
| learning_rate=2e-5, # Standard "safe" learning rate for Transformers | |
| lr_scheduler_type="linear", # Gently reduces learning rate to 0 over training | |
| warmup_ratio=0.1, # Ramps up LR for the first 10% of steps to prevent spikes | |
| weight_decay=0.01, # Regularization to prevent overfitting | |
| # --- Data Handling --- | |
| batch_sampler=BatchSamplers.NO_DUPLICATES, # Essential for MNR/Matryoshka loss to avoid bad negatives | |
| dataloader_num_workers=8, # Use 8 CPU cores to keep the GPU fed with data | |
| # --- Evaluation & Saving (Safety) --- | |
| eval_strategy="steps", # Evaluate every X steps | |
| eval_steps=6000, # Increased from 10; L40S processes data very fast | |
| save_strategy="steps", # Save checkpoints every X steps | |
| save_steps=6000, # Usually matches eval_steps | |
| save_total_limit=2, # Keep only the top 3 checkpoints to save disk space | |
| # --- Tracking & Debugging --- | |
| report_to="tensorboard", # Send live metrics to TensorBoard | |
| logging_steps=200, # Print/Log stats every 200 steps (prevents messy logs) | |
| logging_dir="arabvert02-matryoshka/runs", # Specific folder for TensorBoard event files | |
| ) | |
| trainer = SentenceTransformerTrainer( | |
| model=model, | |
| args=args, | |
| train_dataset=train_dataset, | |
| eval_dataset=eval_dataset, | |
| loss=train_loss, | |
| evaluator=dev_evaluator, | |
| ) | |
| trainer.train() | |
| # Save final model | |
| final_output_dir = f"{output_dir}/final" | |
| model.save(final_output_dir) | |
| print("model saved successfully") | |
| # Test evaluation | |
| evaluators = [] | |
| for dim in matryoshka_dims: | |
| evaluators.append( | |
| TripletEvaluator( | |
| anchors=test_dataset["train"]["anchor"], | |
| positives=test_dataset["train"]["positive"], | |
| negatives=test_dataset["train"]["negative"], | |
| name=f"test-{dim}", | |
| truncate_dim=dim, | |
| ) | |
| ) | |
| test_evaluator = SequentialEvaluator(evaluators) | |
| test_evaluator(model) | |