Spaces:
Runtime error
Runtime error
| """OPTIONAL fine-tuning scaffold. The demo does NOT depend on this. | |
| Fine-tunes the primary checkpoint on a small local CSV (columns: text,label | |
| where label is 0=not-hate, 1=hate). Useful if you want to adapt the classifier | |
| to your own examples. Produces a model directory you could point PRIMARY_MODEL at. | |
| Usage: | |
| python backend/scripts/finetune.py --data my_data.csv --out backend/models/finetuned --epochs 2 | |
| Requires: transformers[torch], datasets, accelerate. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import sys | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(ROOT)) | |
| from config import PRIMARY_MODEL # noqa: E402 | |
| def main() -> None: | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--data", required=True, help="CSV with columns: text,label") | |
| ap.add_argument("--out", default=str(ROOT / "models" / "finetuned")) | |
| ap.add_argument("--epochs", type=float, default=2.0) | |
| ap.add_argument("--lr", type=float, default=2e-5) | |
| ap.add_argument("--batch", type=int, default=8) | |
| args = ap.parse_args() | |
| try: | |
| import numpy as np | |
| from datasets import load_dataset | |
| from transformers import ( | |
| AutoModelForSequenceClassification, | |
| AutoTokenizer, | |
| DataCollatorWithPadding, | |
| Trainer, | |
| TrainingArguments, | |
| ) | |
| except ImportError as exc: # noqa: BLE001 | |
| raise SystemExit( | |
| f"Missing dependency: {exc}. Install with: pip install datasets accelerate" | |
| ) | |
| tok = AutoTokenizer.from_pretrained(PRIMARY_MODEL) | |
| model = AutoModelForSequenceClassification.from_pretrained(PRIMARY_MODEL, num_labels=2) | |
| ds = load_dataset("csv", data_files=args.data)["train"].train_test_split(test_size=0.2) | |
| ds = ds.map(lambda b: tok(b["text"], truncation=True, max_length=256), batched=True) | |
| def metrics(p): | |
| preds = np.argmax(p.predictions, axis=-1) | |
| return {"accuracy": float((preds == p.label_ids).mean())} | |
| targs = TrainingArguments( | |
| output_dir=args.out, | |
| num_train_epochs=args.epochs, | |
| learning_rate=args.lr, | |
| per_device_train_batch_size=args.batch, | |
| per_device_eval_batch_size=args.batch, | |
| eval_strategy="epoch", | |
| save_strategy="epoch", | |
| logging_steps=10, | |
| ) | |
| trainer = Trainer( | |
| model=model, | |
| args=targs, | |
| train_dataset=ds["train"], | |
| eval_dataset=ds["test"], | |
| tokenizer=tok, | |
| data_collator=DataCollatorWithPadding(tok), | |
| compute_metrics=metrics, | |
| ) | |
| trainer.train() | |
| trainer.save_model(args.out) | |
| tok.save_pretrained(args.out) | |
| print(f"\nSaved fine-tuned model to {args.out}") | |
| print("To use it, set PRIMARY_MODEL in backend/config.py to that path.") | |
| if __name__ == "__main__": | |
| main() | |