| |
| import os |
| import re |
| import shutil |
| import csv |
| import sys |
| import json |
| from pathlib import Path |
|
|
| import torch |
| import torch.distributed as dist |
| from dotenv import load_dotenv |
|
|
| import hydra |
| from omegaconf import OmegaConf |
|
|
| |
| from lmr.config import initialize_config |
| from lmr.tokenizer import Tokenizer |
| from lmr.models import get_model |
| from lmr.data import get_dataset_splits |
| from lmr.checkpointing import Checkpointing |
| from lmr.utils.seed import set_seed |
| from lmr.training import Bert_Trainer, Trainer |
| from lmr.generation import Generator |
| from lmr.benchmark import Benchmark |
| from lmr.ddp import unwrap_model |
|
|
| |
| |
| from lmr.training.bert_finetune_trainer import BertFineTuneTrainer |
|
|
| |
| from transformers import AutoTokenizer, AutoConfig, AutoModelForSequenceClassification, BertForNextSentencePrediction |
|
|
| DATASET_DIR = Path("datasets") |
| CHECKPOINT_DIR = Path("/work/jf381/checkpoints") |
| BENCHMARK_DIR = Path("output") |
|
|
| |
| |
| |
| def create_tokenizer_and_model_for_finetune(model_name_or_path: str, task: str, num_labels: int = None): |
| """ |
| Returns (tokenizer, model). |
| - task == "sentence_pair" -> AutoModelForSequenceClassification (num_labels required or inferred) |
| - task == "next_sentence_prediction" -> BertForNextSentencePrediction |
| """ |
| tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=True) |
|
|
| if task == "sentence_pair": |
| |
| nlab = num_labels if num_labels is not None else 2 |
| model = AutoModelForSequenceClassification.from_pretrained(model_name_or_path, num_labels=nlab) |
| elif task == "next_sentence_prediction": |
| |
| model = BertForNextSentencePrediction.from_pretrained(model_name_or_path) |
| else: |
| raise ValueError(f"Unsupported finetune task: {task}") |
|
|
| return tokenizer, model |
|
|
| |
| |
| |
|
|
| @hydra.main(config_path="config", config_name="config", version_base="1.3") |
| def main(config): |
| |
| load_dotenv() |
| set_seed(config) |
| initialize_config(config) |
|
|
| mode = config.mode |
| maybe_print = print |
|
|
| |
| if mode == "train": |
| |
| if torch.cuda.is_available() and torch.cuda.device_count() > 1: |
| if not dist.is_initialized(): |
| dist.init_process_group(backend="nccl") |
| torch.cuda.set_device(dist.get_rank() % torch.cuda.device_count()) |
|
|
| tokenizer, model = setup_model_and_tokenizer(config) |
| tokenized_dataset_dir = DATASET_DIR / config.tokenizer_base |
| splits = get_dataset_splits(config.dataset, 1024, tokenized_dataset_dir) |
| checkpointing = Checkpointing(model, CHECKPOINT_DIR / config.checkpoint_name) |
|
|
| if "bert" in str(config.model).lower(): |
| from lmr.training import Bert_Trainer |
| trainer = Bert_Trainer(config.training, model, tokenizer, splits, checkpointing, None) |
| else: |
| trainer = Trainer(config.training, model, tokenizer, splits, checkpointing) |
| trainer.train() |
|
|
| elif mode == "generate": |
| generate(config) |
|
|
| elif mode == "generate_all": |
| generate_all(config) |
|
|
| elif mode == "benchmark": |
| tokenizer, model = setup_model_and_tokenizer(config) |
| checkpointing = Checkpointing(model, CHECKPOINT_DIR / config.checkpoint_name) |
| benchmarking = Benchmark(config.benchmark, model, tokenizer, checkpointing, BENCHMARK_DIR / config.checkpoint_name) |
| benchmarking.run_benchmarks() |
|
|
| |
| |
| |
| elif mode == "bert_finetune": |
| |
| |
| |
| |
| |
| maybe_print("=== BERT FINETUNE MODE ===") |
| maybe_print(f"Config: task={config.finetune.task}, dataset={config.finetune.dataset}, model={config.finetune.model_name_or_path}") |
|
|
| |
| tokenizer, model = create_tokenizer_and_model_for_finetune( |
| model_name_or_path=config.finetune.model_name_or_path, |
| task=config.finetune.task, |
| num_labels=getattr(config.finetune, "num_labels", None) |
| ) |
|
|
| |
| use_ddp = getattr(config.finetune, "use_ddp", False) |
| if use_ddp and torch.cuda.is_available(): |
| |
| local_rank = int(os.environ.get("LOCAL_RANK", os.environ.get("RANK", 0))) |
| world_size = int(os.environ.get("WORLD_SIZE", 1)) |
| device = torch.device(f"cuda:{local_rank}") |
| maybe_print(f"[finetune] DDP mode: local_rank={local_rank} world_size={world_size} device={device}") |
| cfg_namespace = argparse.Namespace(**config.finetune) |
| |
| finetune_trainer = BertFineTuneTrainer(model=model, tokenizer=tokenizer, cfg=cfg_namespace, device=device) |
| |
| finetune_trainer.train() |
| else: |
| |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
| maybe_print(f"[finetune] Single-device mode: device={device}") |
| cfg_namespace = argparse.Namespace(**config.finetune) |
| finetune_trainer = BertFineTuneTrainer(model=model, tokenizer=tokenizer, cfg=cfg_namespace, device=device) |
| finetune_trainer.train() |
|
|
| else: |
| print(f"❌ Unknown mode: {mode}") |
|
|
| if __name__ == "__main__": |
| main() |
|
|