NLP · Transformers · Multilingual

BERT Multilingual Sentiment Analysis Pipeline

End-to-end fine-tuning of bert-base-multilingual-cased on a 500k-document multilingual corpus for real-time sentiment classification. Served via an async FastAPI inference server with sub-80ms latency at P95.

BERT Hugging Face FastAPI Docker MLflow Multilingual PyTorch
92.1%
Macro F1-Score
91.8%
Accuracy
74ms
P95 Latency
6
Languages

Project Overview

This pipeline fine-tunes bert-base-multilingual-cased (110M parameters) on a 500k-document multilingual dataset spanning six languages for three-class sentiment classification (negative, neutral, positive). The model achieves a 92.1% Macro F1-score — outperforming monolingual baselines such as RoBERTa-base.

The inference server supports both single predictions and async batch processing, with MLflow tracking all experiments. Class imbalance is handled through weighted random sampling rather than post-hoc reweighting.

Supported Languages

🇬🇧 English 🇰🇪 Swahili 🇩🇪 German 🇫🇷 French 🇪🇸 Spanish 🇧🇷 Portuguese

Architecture

1

Data Pipeline

Tokenization with bert-base-multilingual-cased tokenizer. Max sequence length 128. Weighted random sampling for class balance.

2

Fine-tuning

Hugging Face Trainer API. 4 epochs, AdamW with linear warmup (10%) + linear decay. Gradient accumulation ×2.

3

Evaluation

Macro F1-Score, Accuracy, AUC-ROC, and per-class metrics across all 6 supported languages.

4

Async Inference

FastAPI server with async batching. Single prediction + batch endpoints. Sub-80ms P95 latency on single GPU.

5

Experiment Tracking

MLflow for all training runs — metrics, hyperparameters, model artifacts, and comparison across baselines.

6

Deployment

Dockerized for reproducibility. Mount model outputs volume to persist fine-tuned checkpoints.

Benchmark Comparison

ModelMacro F1
TF-IDF + Logistic Regression (baseline)78.3%
DistilBERT-multilingual88.9%
RoBERTa-base (English only)91.4%
BERT-multilingual (this project)92.1%

Training Details

Model

  • Base: bert-base-multilingual-cased
  • Parameters: 110M
  • Classes: 3 (neg / neutral / pos)

Optimisation

  • Optimiser: AdamW
  • Warmup: linear 10%
  • Decay: linear
  • Grad accumulation: ×2 → eff. batch 64

Data

  • 500k documents
  • Max length: 128 tokens
  • Imbalance: weighted sampling

Requirements

  • Python 3.9+
  • Transformers 4.x+
  • PyTorch 2.0+

Quickstart

1. Install

bash
pip install -r requirements.txt

2. Prepare data

CSV with columns: text, label (0=negative, 1=neutral, 2=positive), language

3. Fine-tune

bash
python src/train.py \
  --train_file data/train.csv \
  --val_file data/val.csv \
  --output_dir outputs/ \
  --epochs 4 \
  --batch_size 32

4. Evaluate

bash
python src/evaluate.py \
  --model_dir outputs/ \
  --test_file data/test.csv

5. Run API

bash
uvicorn src.api:app --host 0.0.0.0 --port 8000

Docker

bash
docker build -t bert-sentiment .
docker run -p 8000:8000 -v $(pwd)/outputs:/app/outputs bert-sentiment

API Usage

python
import requests

# Single prediction
r = requests.post("http://localhost:8000/predict", json={
    "text": "This product exceeded all my expectations!",
    "language": "en"
})
print(r.json())
# {"label": "positive", "confidence": 0.9821, "scores": {"negative": 0.007, "neutral": 0.011, "positive": 0.982}}

# Batch prediction
r = requests.post("http://localhost:8000/predict/batch", json={
    "texts": ["Great!", "Terrible experience.", "It was okay."]
})

Project Structure

bert-sentiment-pipeline/
  ├── src/
    ├── dataset.py  # Tokenisation + data collation pipeline
    ├── train.py  # Fine-tuning with Hugging Face Trainer API
    ├── evaluate.py  # F1, AUC-ROC, per-class metrics
    ├── inference.py  # Inference wrapper with async batching
    └── api.py  # FastAPI REST API
  ├── data/sample/
    └── sample_reviews.csv
  ├── Dockerfile
  ├── requirements.txt
  └── README.md