Downloads · 30 days
0
d-schafer/illiberal-speech-ei-relevance
illiberal-speech-ei-relevance is a text classification model from d-schafer. Use it when you need a label for a piece of text. It is set up for peft. The card lists the license as mit.
A DeBERTa-v3-base + LoRA binary classifier that flags whether a political-speech paragraph is topically relevant to the exclusive–inclusive (EI) dimension of political discourse: cultural identity, group boundaries, m…
Downloads · 30 days
0
Access
Public
Updated Jul 14, 2026
Repo size
745 MB
Likes
1
Public
Click a slice to open those files.
.pth739 MB · 99%
From the Hugging Face model README
A DeBERTa-v3-base + LoRA binary classifier that flags whether a political-speech paragraph is topically relevant to the exclusive–inclusive (EI) dimension of political discourse: cultural identity, group boundaries, minority rights, pluralism, and tolerance.
This is the first stage of the two-stage Illiberal Speech Indicators (ISI) pipeline. Paragraphs flagged as relevant are then scored 0–10 by the companion regression model, illiberal-speech-ei-scorer.
The models were developed for:
Maerz, Seraphine F., Dean G. Schafer, and Carsten Q. Schneider. Listening to Leaders: Illiberal Speech as a Symptom of Democratic Decline. (2026)
where the ISI pipeline scores 28,227 speeches by 453 political leaders in 123 countries (1989–2024), yielding over half a million semantically coherent paragraphs.
| Model | Dimension | Task |
|---|---|---|
| illiberal-speech-ei-relevance | Exclusive–Inclusive | Relevance filter (this model) |
| illiberal-speech-ei-scorer | Exclusive–Inclusive | 0–10 scorer |
| illiberal-speech-cd-relevance | Concentration–Dispersion | Relevance filter |
| illiberal-speech-cd-scorer | Concentration–Dispersion | 0–10 scorer |
microsoft/deberta-v3-base encoder with LoRA adapters (r=16, α=32, dropout=0.1, target modules: query_proj, key_proj, value_proj), mean pooling over the last hidden state, and a linear 2-class classification head. Max sequence length 512.On the held-out test split (n = 955): F1 (positive class) = 0.897, F1 macro = 0.929, AUC = 0.986.
On an independent hand-coded holdout (n = 299 paragraphs labelled by the authors), at the recommended decision threshold of 0.20: recall = 0.878, precision = 0.800, F1 (positive) = 0.837, AUC = 0.857. The threshold was chosen by grid search on this holdout to favor recall: false positives are tolerable because the downstream scorer sees them anyway, while false negatives are lost from the index entirely.
The .pth file contains the full model state dict (LoRA weights and the classification head). The lora_adapters/ folder holds the PEFT adapters for the encoder only — it does not include the classification head, so use the .pth for working predictions:
import torch
import torch.nn as nn
from huggingface_hub import hf_hub_download
from transformers import DebertaV2Tokenizer, DebertaV2Model
from peft import LoraConfig, get_peft_model
REPO = "d-schafer/illiberal-speech-ei-relevance"
THRESHOLD = 0.20 # recommended decision threshold
class DebertaForClassification(nn.Module):
def __init__(self):
super().__init__()
self.deberta = DebertaV2Model.from_pretrained("microsoft/deberta-v3-base")
hidden_size = self.deberta.config.hidden_size
lora_config = LoraConfig(
r=16, lora_alpha=32, lora_dropout=0.1,
target_modules=["query_proj", "key_proj", "value_proj"],
bias="none", task_type="FEATURE_EXTRACTION",
)
self.deberta = get_peft_model(self.deberta, lora_config)
self.classifier = nn.Linear(hidden_size, 2)
self.dropout = nn.Dropout(0.1)
def forward(self, input_ids, attention_mask):
h = self.deberta(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state
m = attention_mask.unsqueeze(-1).expand(h.size()).float()
pooled = (h * m).sum(1) / m.sum(1).clamp(min=1e-9)
return self.classifier(self.dropout(pooled))
model_path = hf_hub_download(REPO, "illiberal-speech-ei-relevance.pth")
model = DebertaForClassification()
model.load_state_dict(torch.load(model_path, map_location="cpu", weights_only=True))
model.eval()
tokenizer = DebertaV2Tokenizer.from_pretrained(REPO, subfolder="tokenizer")
texts = ["We must defend our nation against those who would replace our culture."]
enc = tokenizer(texts, padding=True, truncation=True, max_length=512, return_tensors="pt")
with torch.no_grad():
probs = torch.softmax(model(enc["input_ids"], enc["attention_mask"]), dim=1)[:, 1]
relevant = probs >= THRESHOLD
print(probs.tolist(), relevant.tolist())
Requires torch, transformers, peft, and sentencepiece.
| File | Description |
|---|---|
illiberal-speech-ei-relevance.pth | Full state dict (encoder + LoRA + classification head) — use this |
lora_adapters/ | PEFT adapter weights for the encoder (no classification head) |
tokenizer/ | DeBERTa-v3 tokenizer files (offline-reproducible copy) |
Designed for paragraph-length segments (~200 words) of political leaders' speeches in English; non-English speeches in the underlying corpus were translated to English before processing. Performance is not validated for other text domains (social media, news, parliamentary debate), other languages, or sentence-/document-length inputs. The recommended threshold (0.20) favors recall by design; raise it if your application needs higher precision.
If you use this model, please cite the paper:
@unpublished{maerz2026listening,
title = {Listening to Leaders: Illiberal Speech as a Symptom of Democratic Decline},
author = {Maerz, Seraphine F. and Schafer, Dean G. and Schneider, Carsten Q.},
year = {2026},
note = {Working paper}
}
An interactive dashboard for exploring the data is available at https://validation.shinyapps.io/speeches/.