| --- |
| language: |
| - en |
| license: mit |
| tags: |
| - text-classification |
| - deception-detection |
| - fake-news |
| - spam-detection |
| - modernbert |
| - pytorch |
| - multi-task-learning |
| - cross-domain |
| base_model: answerdotai/ModernBERT-base |
| datasets: |
| - difraud/difraud |
| metrics: |
| - f1 |
| - roc_auc |
| pipeline_tag: text-classification |
| --- |
| |
| # Verite!: Cross-Domain Deception Detection |
|
|
| **Verite!** is a cross-domain deception detection classifier built on [ModernBERT-base](https://huggingface.co/answerdotai/ModernBERT-base). It detects deceptive content (fake news, phishing, spam, job scams, political misinformation, product review fraud, and Twitter rumours) with a single unified model. |
|
|
| > Code and training script: [github.com/Daxlia/Verite](https://github.com/Daxlia/Verite) |
|
|
| Evaluated on the [DIFrauD](https://huggingface.co/datasets/difraud/difraud) benchmark — 7 domains, ~103K samples. |
|
|
| --- |
|
|
| ## Results |
|
|
|  |
|
|
| Evaluated on the DIFrauD test set (macro-F1 and AUC-ROC, higher is better). |
|
|
| | System | Macro-F1 | AUC-ROC | |
| | ------ | -------- | ------- | |
| | Majority class | 0.3792 | 0.5000 | |
| | TF-IDF + LR | 0.8094 | 0.9079 | |
| | **Verite! (ours)** | **0.8512** | **0.9487** | |
| | SOTA (DIFrauD leaderboard) | 0.904 | — | |
|
|
| > Single seed (seed=42) on 2×NVIDIA T4. Multi-seed ensemble (3 seeds) expected to improve further. |
|
|
| ### Per-Domain Breakdown |
|
|
|  |
|
|
| | Domain | Macro-F1 | AUC-ROC | Accuracy | |
| | ------ | -------- | ------- | -------- | |
| | Fake News | 0.9855 | 0.9990 | 0.9858 | |
| | Job Scams | 0.7584 | 0.9354 | 0.9636 | |
| | Phishing | 0.9708 | 0.9964 | 0.9719 | |
| | Political Statements | 0.4562 | 0.6418 | 0.6504 | |
| | Product Reviews | 0.6424 | 0.7653 | 0.6582 | |
| | SMS Spam | 0.9834 | 0.9998 | 0.9894 | |
| | Twitter Rumours | 0.7856 | 0.8800 | 0.7945 | |
|
|
| ### Ablation Study |
|
|
|  |
|
|
| | Variant | Macro-F1 | AUC-ROC | |
| | ------- | -------- | ------- | |
| | Verite! (full) | 0.8512 | 0.9487 | |
| | w/o Linguistic Features | 0.8544 | 0.9475 | |
| | TTA | 0.8515 | 0.9456 | |
|
|
| --- |
|
|
| ## Model Description |
|
|
| Verite! extends ModernBERT-base with four feature streams fused before classification: |
|
|
| | Component | Output | Role | |
| | --------- | ------ | ---- | |
| | **AttentionPooling + semantic_proj** | 512-d | Weighted token aggregation → projected semantic embedding | |
| | **ling_proj** | 512-d | 8 hand-crafted linguistic features (caps ratio, punctuation, TTR, hedge words, negation…) projected to hidden dim | |
| | **LocalConsistencyModule** | 256-d | Splits sequence into 4 segments; cross-attention detects internal contradictions | |
| | **SpectralFeatures** | 10-d | Top-8 FFT magnitudes + spectral centroid + entropy over the token sequence | |
|
|
| All four streams are concatenated (512+512+256+10 = **1290-d**), projected through `LayerNorm → Linear(512) → GELU`, then through 5× multi-sample dropout into a **HypersphericalHead** (prototype classifier on the unit hypersphere, scale=20). |
|
|
| **Architecture diagram:** |
|
|
| ```text |
| Input Text ──────────────────────── Linguistic Features (8-d) |
| │ │ |
| ▼ ▼ |
| ModernBERT-base (149M params, fp32) ling_proj → feat_emb (512-d) |
| │ │ |
| ├── AttentionPooling ──► semantic_proj ──► sem_emb (512-d) ──┐ |
| ├── LocalConsistencyModule (4 segs) ──► cons_emb (256-d) ─────┤ |
| └── SpectralFeatures (top-8 FFT + centroid + entropy) ► spec (10-d) |
| │ |
| Concatenate [sem_emb | feat_emb | cons_emb | spec] (1290-d) |
| │ |
| LayerNorm → Linear(512) → GELU |
| │ |
| Multi-sample Dropout (5×) → HypersphericalHead |
| │ |
| Logits (2 classes) |
| ``` |
|
|
| --- |
|
|
| ## Training |
|
|
| Trained on 2×NVIDIA T4 (16 GB each) via Kaggle (~13 h, < 14 h total session). The encoder always runs in fp32 to avoid SDPA overflow on sm75 hardware; head layers use fp16 via PyTorch AMP. |
|
|
| **Training objectives:** |
|
|
| - Focal loss (γ=2.0) with class-balanced weights and label smoothing (ε=0.05) |
| - Supervised Contrastive loss (λ=0.1, τ=0.07) on semantic embeddings |
| - Domain MTL cross-entropy (λ=0.1) across 7 domain heads |
|
|
| **Regularization stack:** |
|
|
| - AdamW + LLRD (decay=0.9): encoder LR=1e-5, head LR=1e-4 |
| - Cosine schedule with 8% linear warmup |
| - Gradient accumulation (×4), gradient clipping (0.7) |
| - EMA (decay=0.995) — used for final checkpoint selection |
| - Adversarial Weight Perturbation (AWP, ε=0.001) from epoch 4 onward |
|
|
| **Hyperparameters:** |
|
|
| | Parameter | Value | |
| | --------- | ----- | |
| | Base encoder | `answerdotai/ModernBERT-base` | |
| | Max sequence length | 256 | |
| | Effective batch size | 64 (8 × 2 GPUs × 4 accum steps) | |
| | Epochs | 5 | |
| | Encoder LR | 1e-5 | |
| | Head LR | 1e-4 | |
| | LLRD decay | 0.9 | |
| | Warmup | 8% | |
| | Weight decay | 0.02 | |
| | Focal γ | 2.0 | |
| | SupCon λ | 0.1 | |
| | Domain MTL λ | 0.1 | |
| | AWP start | Epoch 4 | |
| | EMA decay | 0.995 | |
| | Total runtime | ~13 h on 2×T4 (< 14 h) | |
|
|
| --- |
|
|
| ## Usage |
|
|
| > **Important:** This model uses a custom architecture defined in `VeriteTrainer.py`. You must have that file in your Python path before loading. |
|
|
| ### Installation |
|
|
| ```bash |
| pip install torch>=2.1.0 transformers>=4.47.0 safetensors sentencepiece |
| ``` |
|
|
| ### Inference |
|
|
| ```python |
| import torch |
| from torch.utils.data import DataLoader |
| from transformers import AutoTokenizer |
| from safetensors.torch import load_file |
| |
| from VeriteTrainer import DeceptionReasoningModel, Config, DeceptionDataset, collate_fn |
| |
| cfg = Config() |
| tokenizer = AutoTokenizer.from_pretrained("Daxlia/verite") |
| |
| model = DeceptionReasoningModel(cfg) |
| model.load_state_dict(load_file("model.safetensors")) |
| model.eval() |
| |
| texts = ["Congratulations! You've been selected to receive a $1,000 gift card. Click here to claim."] |
| |
| dataset = DeceptionDataset(texts, [0] * len(texts), tokenizer, cfg) |
| loader = DataLoader(dataset, batch_size=8, shuffle=False, collate_fn=collate_fn) |
| |
| with torch.no_grad(): |
| for batch in loader: |
| out = model(input_ids=batch["input_ids"], |
| attention_mask=batch["attention_mask"], |
| ling_feats=batch["ling_feats"]) |
| prob = torch.softmax(out["logits"], dim=-1)[:, 1] |
| for t, p in zip(texts, prob.tolist()): |
| label = "DECEPTIVE" if p > 0.5 else "GENUINE" |
| print(f"[{label}] P(deceptive) = {p:.4f} | {t}") |
| ``` |
|
|
| ### Output format |
|
|
| | Key | Shape | Description | |
| | --- | ----- | ----------- | |
| | `logits` | `(B, 2)` | Raw class logits (genuine=0, deceptive=1) | |
| | `sem_emb` | `(B, 512)` | Semantic embedding (useful for downstream tasks) | |
| | `domain_logits` | `(B, 7)` | Domain classification logits | |
|
|
| --- |
|
|
| ## Domains |
|
|
| The model was trained jointly on all 7 DIFrauD domains: |
|
|
| | Domain | Description | |
| | ------ | ----------- | |
| | `fake_news` | News articles with fabricated or misleading content | |
| | `job_scams` | Fraudulent job postings | |
| | `phishing` | Phishing emails and URLs | |
| | `political_statements` | Fact-checked political claims | |
| | `product_reviews` | Fake/incentivised product reviews | |
| | `sms` | SMS spam messages | |
| | `twitter_rumours` | Unverified claims spread on Twitter/X | |
|
|
| --- |
|
|
| ## Limitations |
|
|
| - Max input length is 256 tokens; longer texts are truncated. |
| - Inference requires `VeriteTrainer.py` — no `AutoModel`-compatible registration yet. |
| - Performance is weakest on Political Statements (F1=0.456) and Product Reviews (F1=0.642) — domains with subtle, opinion-heavy deception signals. |
| - Results reported for a single training seed; variance across seeds has not been fully characterized. |
|
|
| --- |
|
|
| ## Citation |
|
|
| ```bibtex |
| @misc{verite2026, |
| author = {Daxlia}, |
| title = {Verite!: Cross-Domain Deception Detection with ModernBERT}, |
| year = {2026}, |
| doi = {10.5281/zenodo.20256648}, |
| url = {https://doi.org/10.5281/zenodo.20256648} |
| } |
| ``` |
|
|
| --- |
|
|
| ## AI Disclosure |
|
|
| This project was developed with assistance from AI tools: |
|
|
| - **ChatGPT (OpenAI)** — Bug identification, algorithmic suggestions, and research ideation |
| - **Claude (Anthropic)** — Code implementation, debugging, and writing of documentation files |
|
|
| All AI-generated content was reviewed, validated, and adapted by the author. |
|
|
| --- |
|
|
| ## License |
|
|
| This model is released under the [MIT License](https://opensource.org/licenses/MIT). |
|
|
| The base encoder [ModernBERT-base](https://huggingface.co/answerdotai/ModernBERT-base) is licensed under Apache 2.0. |
| The [DIFrauD dataset](https://huggingface.co/datasets/difraud/difraud) is subject to its own license; refer to the dataset repository. |
|
|