Bangla Fake News Detector — XLM-RoBERTa
Fine-tuned xlm-roberta-base for binary fake news classification
in Bangla and English. Trained on BanFakeNews-2.0 with calibrated
confidence scores and optimized decision threshold.
⚠️ Critical Usage Warning — Read Before Using
Minimum Input Length: 500+ characters
This model requires full article text to work reliably.
Short texts (headlines, snippets, social media posts under 200 characters)
will almost always return "Credible" regardless of content — this is
expected behavior, not a bug.
| Input length | Reliability |
|---|
| < 200 chars | ❌ Unreliable — do not use |
| 200–500 chars | ⚠️ Low reliability |
| 500–1,000 chars | ✓ Acceptable |
| 1,000+ chars | ✓ Best results |
Why? The model was trained on full news articles (average 1,796 chars,
median 553 tokens). It learned patterns from article structure, writing
style, source signals, and content coherence — none of which are present
in short snippets.
Correct usage:
1# ✓ CORRECT — full article text
2text = """নির্বাচনের দিন যানবাহন চলাচল বন্ধ থাকার পরেও যেভাবে ভোট দিতে যাবেন।
3আসন্ন একাদশ জাতীয় সংসদ নির্বাচন ঘিরে সব ধরনের যান চলাচলে বিধিনিষেধ জারি করেছে
4সড়ক পরিবহন ও সেতু মন্ত্রণালয়...""" # 500+ chars
5
6# ✗ WRONG — headline only (will return Credible regardless)
7text = "সরকার ঘোষণা করেছে সমস্ত বিদ্যালয় বন্ধ হবে"
Model Description
| Property | Value |
|---|
| Base model | xlm-roberta-base |
| Task | Binary text classification (Fake / Credible) |
| Languages | Bangla (primary), English (secondary), Banglish |
| Parameters | 278M |
| Training GPU | Kaggle T4 (~2.7 hours) |
| Calibration | Temperature scaling (T=0.5308) |
| Decision threshold | 0.05 (on calibrated Fake probability) |
| W&B run | g9qn9beq |
Test Set Performance
Evaluated on a stratified temporal test set of 7,784 samples
(195 fake, 7,589 credible) — articles from 2024+,
never seen during training.
| Class | Precision | Recall | F1 | Support |
|---|
| Fake | 0.9066 | 0.8462 | 0.8753 | 195 |
| Credible | 0.9961 | 0.9978 | 0.9969 | 7,589 |
| Macro avg | 0.9513 | 0.9220 | 0.9361 | 7,784 |
Key metric: Macro F1 = 0.9361 — primary metric for imbalanced evaluation.
Accuracy (0.9940) is reported for reference only — it is misleading at 39:1 imbalance.
Training Details
Dataset
- Primary: BanFakeNews-2.0 — 60,000 Bangla news articles (2025)
- After deduplication: 51,889 unique articles
- Split: Stratified 70/15/15 (train/val/test)
- Class imbalance: 39:1 authentic-to-fake ratio
- Fake samples in train: 906 out of 36,322
Class Imbalance Handling
The severe 39:1 imbalance required a custom training strategy:
1# Class weights applied to CrossEntropyLoss
2CLASS_WEIGHTS = {
3 0: 20.0386, # Fake — upweighted 20x
4 1: 0.5126, # Credible — downweighted
5}
6
7# Custom Trainer subclass to apply weights
8class WeightedTrainer(Trainer):
9 def compute_loss(self, model, inputs, return_outputs=False, **kwargs):
10 labels = inputs.pop("labels")
11 outputs = model(**inputs)
12 weight = torch.tensor([20.0386, 0.5126], device=outputs.logits.device)
13 loss = F.cross_entropy(outputs.logits, labels, weight=weight)
14 return (loss, outputs) if return_outputs else loss
Hyperparameters
optimizer: AdamW
learning_rate: 2e-5
weight_decay: 0.01
warmup_ratio: 0.10
epochs: 5 (early stopping, patience=2)
batch_size: 16 (T4 GPU)
max_length: 512 tokens
fp16: True
metric: Macro F1 (for best model selection)
Confidence Calibration
Raw softmax outputs from fine-tuned transformers are overconfident.
Temperature scaling was applied on the validation set:
1# Optimal temperature found via NLL minimization on validation set
2T_optimal = 0.5308 # T < 1.0 = model was underconfident (due to class weights)
3
4# Calibrated probability
5calibrated_probs = softmax(logits / T_optimal)
6
7# Optimal threshold found via Precision-Recall curve
8# Target: maximize recall at precision >= 0.70
9threshold_fake = 0.05
Usage
Direct inference
1from transformers import AutoTokenizer, AutoModelForSequenceClassification
2from scipy.special import softmax
3import torch
4import json
5
6model_name = "maksays-003/bangla-fake-news-xlmr"
7tokenizer = AutoTokenizer.from_pretrained(model_name)
8model = AutoModelForSequenceClassification.from_pretrained(model_name)
9model.eval()
10
11# Calibration config is included in the model repo
12import requests
13config = requests.get(
14 "https://huggingface.co/maksays-003/bangla-fake-news-xlmr/resolve/main/calibration_config.json"
15).json()
16T = config["temperature"] # 0.5308
17threshold = config["threshold_fake"] # 0.05
18
19def predict(text: str) -> dict:
20 # ⚠️ Minimum 500 characters recommended
21 if len(text) < 200:
22 return {"warning": "Text too short for reliable prediction"}
23
24 inputs = tokenizer(
25 text,
26 return_tensors = "pt",
27 max_length = 512,
28 truncation = True,
29 padding = True,
30 )
31 with torch.no_grad():
32 logits = model(**inputs).logits[0].numpy()
33
34 # Apply temperature scaling
35 probs = softmax(logits / T)
36 fake_prob = float(probs[0])
37
38 return {
39 "label": "Fake" if fake_prob >= threshold else "Credible",
40 "fake_prob": round(fake_prob, 4),
41 "credible_prob": round(float(probs[1]), 4),
42 "threshold": threshold,
43 }
44
45# Example — use full article text
46text = """নির্বাচনের দিন যানবাহন চলাচল বন্ধ থাকার পরেও যেভাবে ভোট দিতে যাবেন।
47আসন্ন একাদশ জাতীয় সংসদ নির্বাচন ঘিরে সব ধরনের যান চলাচলে বিধিনিষেধ জারি করেছে
48সড়ক পরিবহন ও সেতু মন্ত্রণালয়। ২৯ ডিসেম্বর মধ্যরাত থেকে ৩০ ডিসেম্বর মধ্যরাত
49পর্যন্ত সড়কপথে সব ধরনের যান চলাচল বন্ধ থাকবে।"""
50
51result = predict(text)
52print(result)
53# {'label': 'Fake', 'fake_prob': 0.9998, 'credible_prob': 0.0002, 'threshold': 0.05}
Via Live API (easiest)
1curl -X POST https://redis-production-b1ef.up.railway.app/v1/predict \
2 -H "X-API-Key: YOUR_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{"text": "your full article text here (500+ chars recommended)"}'
Known Limitations
1. Short text unreliability ⚠️
The most important limitation. Articles under 500 characters will
produce unreliable results — almost always "Credible" regardless of
actual content. This is a fundamental constraint of the training data
distribution (average article: 1,796 chars).
2. Binary classification only
This version classifies as Fake or Credible only. The Unverified/Satire
class was not included due to insufficient labeled data. Satire articles
may be incorrectly labeled as either Fake or Credible.
3. Temporal drift
Trained on data up to 2024. Misinformation patterns, writing styles,
and portal credibility change over time. Model should be re-evaluated
and potentially retrained annually.
4. False negatives (~15%)
At threshold=0.05, approximately 15% of fake articles are missed
(classified as Credible). This is a known trade-off — lowering the
threshold increases recall but reduces precision.
5. Banglish handling
Code-switching between Bangla and English (Banglish) is handled by
XLM-R but with lower confidence than pure Bangla or pure English text.
6. Source bias
BanFakeNews-2.0 was collected from specific Bangladeshi news portals.
Political and topical biases in the training data may cause systematic
errors on certain news categories.
Ethical Considerations
This model labels news articles as "Fake" — a high-stakes classification
with real-world consequences:
- False positives can damage the reputation of legitimate journalists
- False negatives allow misinformation to spread unchallenged
- Do not use this as the sole basis for editorial or legal decisions
- Always show confidence scores alongside verdicts, never just labels
- Always provide a feedback mechanism for users to report errors
Required disclaimer when deploying:
"This is an AI-assisted tool for first-pass screening only.
It is not a substitute for professional fact-checking.
Results may be incorrect. Short texts (<500 chars) are unreliable."
License note
BanFakeNews-2.0 is licensed CC BY-NC-SA 4.0 (non-commercial).
This model inherits that restriction — do not use for commercial purposes
without building your own dataset.
Citation
1@software{bangla_fake_news_2026,
2 author = {Md. Masum Khan},
3 title = {Bangla Fake News Detector},
4 year = {2026},
5 url = {https://github.com/Masum-Khan003/bangla-fake-news-detector},
6 note = {Fine-tuned XLM-RoBERTa for Bangla fake news detection,
7 Macro-F1: 0.9361, trained on BanFakeNews-2.0}
8}
9
10@dataset{BanFakeNews2,
11 title = {BanFakeNews-2.0},
12 year = {2025},
13 note = {60,000 labeled Bangla news articles for fake news detection}
14}
Links