This repository contains multiple training and inference pipelines for binary sarcasm/sentiment classification on BESSTIE-style data (text, label, variety, source, task).
It includes:
- Encoder baselines (
roberta-large, multilingualdistilbert) - Decoder baseline (
Mistral-Small-Instruct) with QLoRA - RoBERTa extensions with custom heads (CNN, attention pooling)
- VAAT (Variety-Aware Adapter Tuning) extension
- Evaluation, plotting, error analysis, and multi-prompt inference scripts
- Detect sarcasm (
task=Sarcasm) and sentiment (task=Sentiment) - Compare robustness across English varieties (
en-AU,en-IN,en-UK) and sources (Google,Reddit) - Support several model families and decoder/head variants under a unified config-first CLI
.
|- src/
| |- baseline_roberta_large/ # RoBERTa-large encoder baseline
| |- baseline_distilbert/ # DistilBERT multilingual baseline
| |- baseline_mistral/ # Mistral decoder baseline (QLoRA)
| |- dataset_translated/ # RoBERTa + custom heads (cnn/attn_pool)
| |- dataset_translated_vaat/ # RoBERTa + custom heads + VAAT
| |- dataset/ # main train/valid CSVs
| |- eval_macro_f1.py # generic metrics script
| `- multi_prompt_inference.py # classifier-level multi-template inference
|- plots/ # generated charts and summaries
|- output_models/ # example saved checkpoints
|- requirements.txt
`- requirements-colab.txt
Expected CSV columns:
text,label,variety,source,taskLabel semantics:
task=Sarcasm:1 = sarcastic,0 = not sarcastictask=Sentiment:1 = positive,0 = negative
Current dataset stats in src/dataset:
- Train rows:
17,760 - Valid rows:
2,428 - Train tasks:
Sentiment=8,866,Sarcasm=8,894 - Valid tasks:
Sentiment=1,212,Sarcasm=1,216 - Varieties:
en-AU,en-IN,en-UK - Sources:
Google,Reddit
- Python
3.10+recommended python3available on PATH- For GPU runs: CUDA-capable PyTorch install
- For Mistral QLoRA: CUDA +
bitsandbytes+peft(CPU-only is not practical for this path)
cd /path/to/sarcasm-detection-nlp
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -r requirements.txtOptional API serving dependency:
pip install uvicornFor Colab:
pip install -r requirements-colab.txtAll major model folders use a config-first entrypoint (main.py):
- Load and validate
config.yaml(--configcan be passed before or after subcommand) - Merge CLI overrides over config values
- Load BESSTIE data (from CSV paths in config, optionally HF dataset loader in some scripts)
- Filter by
task(SarcasmorSentiment) - Tokenize and build dataloaders
- Train across one or more learning rates
- Select best run (typically by macro-F1 on validation)
- Save final checkpoint
- Run prediction from
predictsubcommand orinference.py
Common training features across folders:
- Mixed precision flags (
fp16,bf16,tf32) deviceselection (auto|cuda|cpu)batch_size,max_length, dataloader workers- Class weighting for imbalanced labels (encoder pipelines)
Folder-specific additions:
baseline_distilbert,baseline_mistral: periodic checkpoints + resumedataset_translated: custom heads (hf_default,cnn,attn_pool) + early stoppingdataset_translated_vaat: VAAT head (decoder_type=vaat) + early stopping + variety conditioning
Train and predict with RoBERTa-large baseline:
cd src/baseline_roberta_large
# Important: set train.valid_file to ./dataset/valid-nottranslated.csv in config.yaml
python3 main.py train --config config.yaml
python3 main.py predict --config config.yaml \
--input_file ./dataset/valid-nottranslated.csv \
--output_file ./valid_predictions.csvcd src/baseline_roberta_large
python3 main.py train --config config.yaml
python3 main.py predict --config config.yaml --input_file ./dataset/valid-nottranslated.csvOutputs: ./model_output/ (best model/tokenizer), predictions CSV.
cd src/baseline_distilbert
python3 main.py train --config config.yaml
python3 main.py predict --config config.yaml --input_file ../dataset/valid.csvAdds: checkpointing every N epochs and resume support.
cd src/baseline_mistral
python3 main.py train --config config.yaml
python3 main.py predict --config config.yaml --input_file ../dataset/valid.csvNotes:
- Requires CUDA for normal QLoRA workflow (
use_qlora: true) - Uses prompt-based label generation ("0"/"1") for classification
cd src/dataset_translated
python3 main.py train --config config.yaml
python3 main.py predict --config config.yaml --input_file ./dataset/valid-new.csvHead options in config:
decoder_type: hf_defaultdecoder_type: cnndecoder_type: attn_pool
Custom-head checkpoints include:
- encoder/tokenizer files
decoder_config.jsondecoder_head.pt
cd src/dataset_translated_vaat
python3 main.py train --config config.yamlKey config fields:
decoder_type: vaatvaat_adapter_dimvaat_freeze_encoder
Important caveat:
src/dataset_translated_vaat/inference.pycurrently loadsAutoModelForSequenceClassificationdirectly, so it does not properly load saved custom VAAT head checkpoints.
For VAAT evaluation/inference, usemodel_io.py-based scripts (for exampleevaluation.py) or update inference to useload_model_and_tokenizer.
From repo root:
python3 src/eval_macro_f1.py \
--input_file path/to/predictions.csv \
--label_col label \
--pred_col prediction \
--task Sarcasm \
--task_col task \
--group_col varietypython3 src/multi_prompt_inference.py \
--checkpoint_dir output_models/1 \
--input_file src/dataset/valid.csv \
--output_file src/multi_prompt_predictions.csv \
--aggregation weighted_mean \
--task_filter SarcasmFor translated or VAAT folders:
cd src/dataset_translated
mkdir -p results
python3 evaluation.py --models_root ./model_output --validation_csv ./dataset/valid-new.csv
python3 plots.py --results_dir ./results --output_prefix tdata_ --plots_dir ../../plotsHistorical outputs tracked in repo are under uppercase Results/; new script outputs default to lowercase results/.
Each model folder contains app.py. Example:
cd src/dataset_translated
export BESSTIE_CHECKPOINT_DIR=./model_output
export BESSTIE_DEVICE=auto
uvicorn app:app --host 0.0.0.0 --port 8000Request:
curl -X POST "http://localhost:8000/predict" \
-H "Content-Type: application/json" \
-d '{"texts":["Great, another Monday morning."]}'-
Wrong working directory Run each pipeline from its own folder (
cd src/<pipeline>), because config paths are relative. -
pythonnot found Usepython3explicitly. -
RoBERTa baseline config uses train file as valid file In
src/baseline_roberta_large/config.yaml, set:train.train_file: ./dataset/train-nottranslated.csvtrain.valid_file: ./dataset/valid-nottranslated.csv
-
Missing
results/dir for evaluation scripts Create it first:mkdir -p results -
Mistral QLoRA on CPU Not recommended; use CUDA and keep
use_qlora: truefor intended workflow. -
VAAT inference mismatch Custom VAAT checkpoints require
model_io.pyloading path (see caveat in section 7E).
- Seeds are configurable (
train.seed) - Best model selection is based on validation metrics (usually macro-F1)
- Several training scripts support checkpoint resume
run_config.jsonis saved in some pipelines to record effective settings
- Research PDF:
original article/2025.findings-acl.441.pdf - Example outputs and plots:
plots/src/dataset_translated/Results/src/dataset_translated_vaat/Results/errors_Robertalarge_VAAT.csvsrc/multi_prompt_predictions.csv