Downloads · 30 days
25
23% of all-time downloads
bendavidsteel/Qwen3.5-4B-stance-detection
Qwen3.5-4B-stance-detection is a text classification model from bendavidsteel. Use it when you need a label for a piece of text. It is set up for transformers. The card lists the license as apache-2.0.
Qwen/Qwen3.5-4B fine-tuned for three-way stance detection: given a document and a target, predict whether the author is favor, against, or neutral toward that target.
Downloads · 30 days
25
23% of all-time downloads
All-time downloads
109
Public
Parameters
4.2B
8.4 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors8.4 GB · 100%
From the Hugging Face model README
Qwen/Qwen3.5-4B fine-tuned for three-way
stance detection: given a document and a target, predict whether the author is
favor, against, or neutral toward that target.
Trained with LoRA on a sequence-classification head (the adapter is merged into these weights), as part of the StanceMining pipeline. It is the Qwen3.5 successor to bendavidsteel/Qwen3-4B-stance-detection.
| Base model | Qwen/Qwen3.5-4B |
| Architecture | Qwen3_5ForSequenceClassification (hybrid linear/full attention, 32 layers) |
| Parameters | 4.21 B |
| Precision | bfloat16 |
| Classification head | score.weight, shape [3, 2560] |
| Max position embeddings | 262144 (trained and evaluated at 2048) |
| Labels | 0: neutral, 1: favor, 2: against |
The classification head pools the final non-padding token, so inputs must be formatted with the chat template and a generation prompt — the same way the model was trained.
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
repo = "bendavidsteel/Qwen3.5-4B-stance-detection"
tokenizer = AutoTokenizer.from_pretrained(repo)
model = AutoModelForSequenceClassification.from_pretrained(repo, dtype=torch.bfloat16, device_map="auto")
model.eval()
PROMPT = (
"For the following text, determine whether the author's stance is in favor of, "
"against, or neutral toward the target: '{target}'. Consider the language used, "
"any explicit statements of position, and contextual clues that suggest the "
"author's stance. Answer only with 'in favor', 'against', or 'neutral'. \n\n"
"Text: '{text}'"
)
def classify(text, target):
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": PROMPT.format(target=target, text=text)},
]
inputs = tokenizer.apply_chat_template(
messages,
add_generation_prompt=True,
enable_thinking=False,
truncation=True,
max_length=2048,
return_tensors="pt",
return_dict=True,
).to(model.device)
with torch.no_grad():
logits = model(**inputs).logits[0]
probs = logits.softmax(-1)
return model.config.id2label[int(probs.argmax())], probs.tolist()
print(classify("Cycling infrastructure has made my commute so much safer.", "bike lanes"))
The prompt is part of the model's interface — the fine-tune only ever saw inputs in
these two forms. Both are also stored in metadata.json in this repo.
Standalone document:
For the following text, determine whether the author's stance is in favor of, against, or neutral toward the target: '{target}'. Consider the language used, any explicit statements of position, and contextual clues that suggest the author's stance. Answer only with 'in favor', 'against', or 'neutral'.
Text: '{text}'
Document in a reply chain (used for conversational datasets such as MT-CSD and CTSDT):
For the following text, determine whether the author's stance is in favor of, against, or neutral toward the target: '{target}'. Consider the language used, any explicit statements of position, the chain of parent texts that the author is replying to, and contextual clues that suggest the author's attitude. Answer only with 'in favor', 'against', or 'neutral'.
Parent Document Chain (from oldest to most recent):
{parent_chain}
Text: '{text}'
Fine-tuned on the combined training splits of eight stance datasets:
| Dataset | Domain | Language |
|---|---|---|
| VAST | Varied, zero-shot topics | en |
| EZ-STANCE | Varied, zero/few-shot targets | en |
| P-Stance | US political figures | en |
| SemEval-2016 Task 6 | Mixed political/social targets | en |
| MT-CSD | Multi-turn conversational threads | en |
| CTSDT | COVID-19 vaccination, conversation threads | en |
| Catalonia | Catalonia independence | es, ca |
| French-Election | Le Pen, Macron, Italian referendum | fr, it |
LoRA adapters on a randomly initialised sequence-classification head, merged into
the base weights after training. Hyperparameters from the
wandb run autumn-moon-345:
| LoRA rank / alpha / dropout | 4 / 8 / 0.2 |
| Learning rate | 1e-4 |
| Per-device batch size | 8 |
| Gradient accumulation steps | 16 (effective batch 128) |
| Max sequence length | 2048 (padded) |
| Precision | bfloat16, no quantization |
| Attention | flash_attention_2 |
| System message | You are a helpful assistant. |
Training ran as three consecutive jobs — an initial run plus two resumptions after crashes — totalling roughly 69 GPU-hours. Final held-out validation loss was 0.575.
Held-out test split of the combined corpus (16,972 examples).
Overall
| Metric | Value |
|---|---|
| Accuracy | 0.7403 |
| Macro F1 | 0.7399 |
| Macro precision | 0.7386 |
| Macro recall | 0.7436 |
Per class (derived from the confusion matrix in metadata.json)
| Class | Precision | Recall | F1 | Support |
|---|---|---|---|---|
| neutral | 0.7049 | 0.7791 | 0.7401 | 4762 |
| favor | 0.7196 | 0.7329 | 0.7262 | 5612 |
| against | 0.7913 | 0.7187 | 0.7532 | 6598 |
Per dataset
| Dataset | Accuracy | Macro F1 | Precision | Recall |
|---|---|---|---|---|
| VAST | 0.7828 | 0.7787 | 0.7782 | 0.7797 |
| EZ-STANCE | 0.6605 | 0.6654 | 0.6770 | 0.6602 |
| P-Stance | 0.8507 | 0.8502 | 0.8510 | 0.8498 |
| SemEval | 0.7086 | 0.6932 | 0.7017 | 0.7230 |
| MT-CSD | 0.6706 | 0.6289 | 0.6620 | 0.6131 |
| CTSDT | 0.8029 | 0.7520 | 0.7936 | 0.7243 |
| Catalonia | 0.7506 | 0.7533 | 0.7540 | 0.7533 |
| French-Election | 0.7716 | 0.7043 | 0.6837 | 0.8159 |
Confusion matrix (rows are true labels, columns predicted)
| neutral | favor | against | |
|---|---|---|---|
| neutral | 3710 | 577 | 475 |
| favor | 723 | 4113 | 776 |
| against | 830 | 1026 | 4742 |
Same training and test splits, same prompts.
| Model | Accuracy | Macro F1 |
|---|---|---|
| Qwen3-1.7B-stance-detection | 0.7182 | 0.7183 |
| Qwen3-4B-stance-detection | 0.7353 | 0.7350 |
| Qwen3.5-4B-stance-detection (this model) | 0.7403 | 0.7399 |
neutral absorbs both "no stance" and "discusses the target without taking a
side", which differ across the source datasets.Apache 2.0, following the base model.