MLOps Assignment 2: Text Classification Pipeline

Genre Categorization for Goodreads Reviews via Fine-Tuned DistilBERT

This project details an end-to-end MLOps workflow designed to classify Goodreads book reviews into seven distinct genres using a fine-tuned distilbert-base-cased architecture. The implementation showcases standard MLOps practices, including GPU-accelerated training via Kaggle, experiment logging with Weights & Biases, and model hosting on the Hugging Face Hub.


Project Framework


Project Objective

The core task is multi-class text classification: analyzing unstructured text from Goodreads reviews to determine the corresponding book genre. The model categorizes inputs into one of seven target genres:

  • Poetry
  • Comics & Graphic
  • Fantasy & Paranormal
  • History & Biography
  • Mystery, Thriller & Crime
  • Romance
  • Young Adult

Note: The primary aim of this assignment is to establish a robust, tracked, and easily deployable machine learning engineering pipeline rather than optimizing raw predictive accuracy.


Dataset

  • Origin: Data is sourced from the UCSD Goodreads Book Graph, utilizing individual genre files in .json.gz format.
  • Sampling Strategy: Subsets of reviews were extracted across all genres to accommodate training constraints on free tier hardware.
  • Data Partitioning: A stratified 80/20 split was applied to separate training and evaluation sets while maintaining balanced class representations.
  • Features: The review_text column serves as the input sequence, capped at a maximum length of 512 tokens during tokenization.

Pipeline Architecture

Raw Goodreads Reviews (7 genres, UCSD Book Graph) β”‚ β–Ό Data Loading & Sampling β”‚ β–Ό DistilBERT Tokenization (distilbert-base-cased, max_length=512) β”‚ β–Ό Fine-Tuning on Kaggle GPU (T4) (HuggingFace Trainer API, 3 epochs) β”‚ β”œβ”€β”€β–Ί Experiment Tracking (Weights & Biases) β”‚ - Loss, Accuracy, F1 per epoch β”‚ - Hyperparameters logged β”‚ - Eval report as W&B Artifact β–Ό Evaluation on Test Set (Accuracy, F1, Classification Report) β”‚ β–Ό Model Deployment β†’ Hugging Face Hub (publicly accessible for inference)


Model Architecture

Component Detail
Base model distilbert-base-cased
Task head DistilBertForSequenceClassification
Number of labels 7
Max token length 512
Framework HuggingFace Transformers + PyTorch

Why DistilBERT? DistilBERT is a distilled (compressed) version of BERT that retains ~97% of BERT's language understanding while being 40% smaller and 60% faster. For an MLOps assignment focused on workflow rather than state-of-the-art accuracy, DistilBERT offers the ideal balance between performance and training speed on free Kaggle GPU resources. Its well-documented HuggingFace integration also makes it straightforward to load, fine-tune, and deploy within a single pipeline.


Training Configuration

Hyperparameter Value
Epochs 3
Train batch size 16
Eval batch size 32
Learning rate 3e-5
Warmup steps 100
Weight decay 0.01
Logging steps 50
Evaluation strategy Every epoch
Optimizer AdamW (HuggingFace default)
Training platform Kaggle Notebook (GPU T4)

MLOps Components

1. Experiment Tracking β€” Weights & Biases

  • All runs logged automatically via report_to="wandb" in TrainingArguments
  • Tracks: training loss, eval loss, accuracy, F1 score per epoch
  • Hyperparameters captured in W&B config for full reproducibility
  • Final evaluation report saved as a versioned W&B Artifact

2. Training Platform β€” Kaggle Notebooks

  • Hardware: GPU T4 (free tier, 30 hrs/week)
  • Internet enabled for HuggingFace model downloads and Hub push
  • API credentials stored securely via Kaggle Secrets (WANDB_API_KEY_2, HF_TOKEN_2)
  • Zero hardcoded credentials in any code

3. Model Deployment β€” Hugging Face Hub

  • Fine-tuned model and tokenizer pushed to HuggingFace Hub
  • Publicly accessible β€” anyone can load and run inference with one line:
from transformers import pipeline
classifier = pipeline("text-classification", model="Rodosi/mlops-distilbert-workflow")
result = classifier("This fantasy novel had incredible world-building and magic systems.")
print(result)

Results

MetricScoreAccuracy | 0.6013 | Weighted F1 | 0.5979 | Eval Loss | 2.2483 |


What the W&B Charts Showed

  • Training loss decreased steadily across all 3 epochs β€” model was learning
  • Validation loss tracked training loss closely β€” no significant overfitting
  • Accuracy and F1 improved each epoch, confirming the fine-tuning was effective

Project Structure

mlops-assignment2/
β”œβ”€β”€ mlops-assignment2.ipynb      # Kaggle notebook β€” full training pipeline
β”œβ”€β”€ train_pipeline.py           # Python script exported from Kaggle notebook
β”œβ”€β”€ requirements.txt            # All Python dependencies
└── README.md                   # This file

Setup & Reproduction

1. Clone the repository

git clone https://github.com/rodosi-iitj-g25ait2088/mlops-distilbert-workflow.git
cd mlops-assignment2

2. Install dependencies

pip install -r requirements.txt

3. Set environment variables

export WANDB_API_KEY=<your_wandb_api_key>
export HF_TOKEN=<your_huggingface_token>

On Kaggle: use Add-ons β†’ Secrets to store these securely instead of environment variables.

4. Run on Kaggle (Recommended)

  • Import mlops-assignment2.ipynb into Kaggle
  • Enable GPU: Settings β†’ Accelerator β†’ GPU T4
  • Enable Internet: Settings β†’ Environment Preferences β†’ Internet ON
  • Add secrets: Add-ons β†’ Secrets β†’ add WANDB_API_KEY_2 and HF_TOKEN_2
  • Click Run All

5. Run locally (CPU only β€” slow)

python train_pipeline.py

For CPU runs, reduce sample size to 200 per genre and set device = 'cpu'


Links

Resource URL
Hugging Face Model Rodosi/mlops-distilbert-workflow
W&B Dashboard mlops-assignment2-rodosi
Kaggle Notebook mlops-assignment2
GitHub Repository mlops-assignment2
Downloads last month
1
Safetensors
Model size
65.8M params
Tensor type
F32
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support