Text Classification
Transformers
Safetensors
Arabic
Stance Detection
Text Classification
arabic-nlp
stanceeval-2026
few-shot-learning
retrieval-augmented
Mawqif-v2
ensemble
LoRA
AraBERT
MARBERT
Instructions to use zaher-m/stanceeval2026 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use zaher-m/stanceeval2026 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="zaher-m/stanceeval2026")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("zaher-m/stanceeval2026", device_map="auto") - Notebooks
- Google Colab
- Kaggle
| """Run one or more models over a CSV and dump a submission file. Multiple | |
| model dirs just get their softmax probabilities averaged. Checks the | |
| submission format before writing it out. | |
| python -m src.predict --models outputs/t1_arabert \\ | |
| --csv data/track1/dev.csv --gold data/track1/dev.csv \\ | |
| --out submissions/t1_dev.txt | |
| """ | |
| import argparse | |
| import json | |
| import os | |
| import numpy as np | |
| import torch | |
| import torch.nn.functional as F | |
| from torch.utils.data import DataLoader | |
| from transformers import AutoModelForSequenceClassification, AutoTokenizer | |
| from src.data import ID2LABEL, LABEL2ID, StanceDataset, load_split | |
| from src.scorer import load_gold, score, validate_submission | |
| def model_settings(model_dir, defaults): | |
| """Read the preprocessing a model was trained with, if recorded.""" | |
| cfg_path = os.path.join(model_dir, "best.json") | |
| if os.path.isfile(cfg_path): | |
| with open(cfg_path, encoding="utf-8") as f: | |
| cfg = json.load(f).get("config", {}) | |
| return { | |
| "prep_mode": cfg.get("prep_mode", defaults["prep_mode"]), | |
| "use_description": cfg.get( | |
| "use_description", defaults["use_description"] | |
| ), | |
| "max_len": cfg.get("max_len", defaults["max_len"]), | |
| } | |
| return dict(defaults) | |
| def model_probs(model_dir, csv_path, device, defaults, batch_size=64): | |
| s = model_settings(model_dir, defaults) | |
| df = load_split(csv_path, s["prep_mode"], has_labels=False) | |
| tok = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True) | |
| model = AutoModelForSequenceClassification.from_pretrained( | |
| model_dir, trust_remote_code=True | |
| ).to(device).eval() | |
| ds = StanceDataset( | |
| df, tok, s["max_len"], s["use_description"], has_labels=False | |
| ) | |
| loader = DataLoader(ds, batch_size=batch_size, shuffle=False) | |
| probs = [] | |
| for batch in loader: | |
| batch = {k: v.to(device) for k, v in batch.items()} | |
| logits = model(**batch).logits.float() | |
| probs.append(F.softmax(logits, dim=-1).cpu().numpy()) | |
| return np.concatenate(probs, axis=0) | |
| def parse_args(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--models", nargs="+", required=True) | |
| ap.add_argument("--csv", required=True) | |
| ap.add_argument("--out", required=True) | |
| ap.add_argument("--gold", default=None) | |
| ap.add_argument("--max_len", type=int, default=128) | |
| ap.add_argument("--use_description", action="store_true") | |
| ap.add_argument("--prep_mode", default="preserve") | |
| ap.add_argument("--none_bias", type=float, default=0.0) | |
| ap.add_argument("--llm_probs", default=None, | |
| help="npy of LLM class probabilities aligned to --csv") | |
| ap.add_argument("--enc_weight", type=float, default=1.0, | |
| help="weight on encoder probs; LLM gets 1 - enc_weight") | |
| return ap.parse_args() | |
| def main(): | |
| args = parse_args() | |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| defaults = { | |
| "prep_mode": args.prep_mode, | |
| "use_description": args.use_description, | |
| "max_len": args.max_len, | |
| } | |
| n_rows = len(load_split(args.csv, "preserve", has_labels=False)) | |
| probs = np.mean( | |
| [model_probs(m, args.csv, device, defaults) for m in args.models], | |
| axis=0, | |
| ) | |
| if args.llm_probs: | |
| llm = np.load(args.llm_probs) | |
| if len(llm) != n_rows: | |
| raise SystemExit( | |
| f"llm_probs rows {len(llm)} != csv rows {n_rows}" | |
| ) | |
| probs = args.enc_weight * probs + (1 - args.enc_weight) * llm | |
| probs[:, LABEL2ID["None"]] += args.none_bias | |
| preds = [ID2LABEL[i] for i in probs.argmax(axis=1)] | |
| ok, msg = validate_submission(preds, n_rows) | |
| print(f"[validate] {msg}") | |
| if not ok: | |
| raise SystemExit(1) | |
| os.makedirs(os.path.dirname(os.path.abspath(args.out)), exist_ok=True) | |
| with open(args.out, "w", encoding="utf-8") as f: | |
| f.write("\n".join(preds) + "\n") | |
| print(f"[write] {len(preds)} predictions -> {args.out}") | |
| if args.gold: | |
| print("[score]") | |
| score(load_gold(args.gold), preds) | |
| if __name__ == "__main__": | |
| main() | |