Spaces:
Running on Zero
Running on Zero
Download scripts/train_qna.py from zeguru/tiny-transformers: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/spaces/zeguru/tiny-transformers/resolve/main/scripts/train_qna.py
- Command line
-
hf download hf://spaces/zeguru/tiny-transformers/scripts/train_qna.py
-
curl -L -o train_qna.py https://huggingface.co/spaces/zeguru/tiny-transformers/resolve/main/scripts/train_qna.py
3.89 kB
| from pathlib import Path | |
| import torch | |
| import json | |
| from src.infra.dataset.util import split_tokens, get_batch | |
| from src.infra.tokenizer import CharacterTokenizer | |
| from src.infra.dataset.answering import QuestionAnsweringDataset | |
| from torch.utils.data import random_split | |
| from src.task.config import ModelConfig,TrainingConfig | |
| from src.task.model import TinyAnsweringModel | |
| from src.task.training.question_answering import train | |
| from src.task.training.util import TrainingLogger, count_parameters, separator | |
| logger = TrainingLogger( | |
| "logs/question_answering.log" | |
| ) | |
| checkpoint = "tiny_answering.pt" | |
| # Configs | |
| separator("Configuration") | |
| torch.manual_seed(42) | |
| # Configs | |
| model_config = ModelConfig() | |
| training_config = TrainingConfig() | |
| # Overrides | |
| model_config.context_length=512 | |
| training_config.num_steps = 300 | |
| training_config.eval_interval = 10 | |
| logger.log(model_config) | |
| logger.log(training_config) | |
| # Load the corpus | |
| separator("Corpus") | |
| torch.manual_seed(42) | |
| SQUAD_PATH = Path("data/squad/dev-v1.1.json") | |
| QA_TOKENIZER_PATH = Path("checkpoints/qa_tokenizer.json") | |
| print(f"Squad file: {SQUAD_PATH}") | |
| print(f"Tokenizer file: {QA_TOKENIZER_PATH}") | |
| if not SQUAD_PATH.exists(): | |
| raise FileNotFoundError(f"Squad file not found: {SQUAD_PATH}") | |
| if not QA_TOKENIZER_PATH.exists(): | |
| raise FileNotFoundError(f"Tokenizer file not found: {QA_TOKENIZER_PATH}") | |
| tokenizer = CharacterTokenizer.load(QA_TOKENIZER_PATH) | |
| vocab_size = tokenizer.vocab_size | |
| with SQUAD_PATH.open("r", encoding="utf-8") as file: | |
| squad = json.load(file) | |
| # Tokens | |
| records = [] | |
| article = next( | |
| article | |
| for article in squad["data"] | |
| if article["title"] == "Kenya" | |
| ) | |
| # for index, article in enumerate(squad["data"]): #when we need all the data | |
| for paragraph in article["paragraphs"] : | |
| context = paragraph["context"] | |
| for qa in paragraph["qas"]: | |
| for answer in qa["answers"]: | |
| records.append( | |
| { | |
| "question": qa["question"], | |
| "context": context, | |
| "answer": answer["text"], | |
| "answer_start": answer["answer_start"], | |
| } | |
| ) | |
| print(f"Number of records: {len(records)}") | |
| print("\n=== Sample record ===") | |
| question = records[0]["question"] | |
| context = records[0]["context"] | |
| answer_text = records[0]["answer"] | |
| answer_start = records[0]["answer_start"] | |
| answer_end = answer_start + len(answer_text) | |
| print("Context:", context) | |
| print("Question:", question) | |
| print("Answer:", answer_text) | |
| print("Answer Start:", answer_start) | |
| print("Answer End:", answer_end) | |
| separator("Dataset") | |
| dataset = QuestionAnsweringDataset( | |
| records=records, | |
| tokenizer=tokenizer, | |
| max_length=model_config.context_length, #to manage truncation and padding | |
| ) | |
| n = len(dataset) | |
| train_size = int(0.90 * n) | |
| val_size = int(0.05 * n) | |
| test_size = n - train_size - val_size | |
| train_dataset, val_dataset, test_dataset = random_split( | |
| dataset, | |
| [train_size, val_size, test_size], | |
| generator=torch.Generator().manual_seed(42), | |
| ) | |
| logger.log(f"Train examples: {len(train_dataset):,}") | |
| logger.log(f"Val examples: {len(val_dataset):,}") | |
| logger.log(f"Test examples: {len(test_dataset):,}") | |
| # Models | |
| separator("Model") | |
| model = TinyAnsweringModel( | |
| config=model_config, | |
| vocab_size=tokenizer.vocab_size, | |
| ) | |
| logger.log(model) | |
| # Train........ | |
| separator("Training") | |
| model = train( | |
| model=model, | |
| train_dataset=train_dataset, | |
| val_dataset=val_dataset, | |
| training_config=training_config, | |
| ) | |
| logger.log(f"Parameters: {count_parameters(model):,}") | |
| separator("Saving") | |
| checkpoint_dir = Path("checkpoints") | |
| checkpoint_dir.mkdir(parents=True, exist_ok=True) | |
| checkpoint_path = ( | |
| checkpoint_dir / checkpoint | |
| ) | |
| torch.save( | |
| model.state_dict(), | |
| checkpoint_path, | |
| ) | |
| print(f"Checkpoint saved to: {checkpoint_path}") |