Implementation for Track A (classification) and Track B (embedding) of SemEval 2026 Task 4.
SemEval2026-Task4-ttda704/
│
├── configs/ # All hyperparameters (YAML)
│ ├── track_a_mpnet.yaml # Track A config (margin, lr, layer freezing)
│ ├── track_b_multiview.yaml # Track B config (fusion weights, alignment lambda)
│ └── prompt_templates.yaml # LLM system prompt for o3-mini (no hardcoding)
│
├── data/ # Data directory (NOT pushed — use .gitignore)
│ ├── raw/ # Original SemEval data
│ ├── processed/ # Post-pseudonymization (Track A)
│ └── llm_extracted/ # Theme, Plot, Outcome JSON from LLM (Track B)
│
├── src/ # Core source modules
│ ├── __init__.py
│ ├── data_processing/
│ │ ├── llm_extractor.py # OpenAI Batch API caller for multi-view extraction
│ │ └── dataset.py # PyTorch Dataset + JSONL loaders
│ ├── models/
│ │ ├── backbone.py # EmbedModel wrapper (MPNet/MiniLM + mean pooling)
│ │ └── multiview_net.py # Multi-view projection heads + fusion layer
│ ├── training/
│ │ ├── trainer_track_a.py # Single-view training loop
│ │ ├── trainer_track_b.py # Multi-view training loop (alternating losses)
│ │ └── losses.py # AdaptiveTripletLoss, MultiViewContrastiveLoss, AlignmentLoss
│ └── utils/
│ ├── common.py # Zip extraction, Kaggle download helpers
│ ├── metrics.py # Accuracy via cosine similarity
│ └── seed.py # Fix random seed for reproducibility
│
├── scripts/ # Entry points
│ ├── run_preprocess.sh # Run LLM extraction pipeline
│ ├── train_track_a.py # Train Track A (reads from configs/)
│ ├── train_track_b.py # Train Track B (reads from configs/)
│ └── generate_submission.py # Generate track_b.npy + submission.zip
│
├── docs/ # Documentation
├── notebooks/ # EDA and error analysis notebooks
│
├── .gitignore
├── requirements.txt
└── README.md
git clone <repository-url>
cd SemEval2026-Task4-ttda704
pip install -r requirements.txt
Download datasets via KaggleHub:
pip install kagglehub
python -c "from src.utils.common import download_and_prepare; download_and_prepare('dinhthienan33/semeval-2026-task-4-track-b')"
Or place data manually in data/raw/.
python scripts/train_track_a.py --config configs/track_a_mpnet.yaml
python scripts/train_track_b.py
python scripts/generate_submission.py \
--model-dir checkpoints/track_a \
--dev-track-b data/raw/dev_track_b.jsonl \
--dev-track-a data/raw/dev_track_a.jsonl
sentence-transformers/all-MiniLM-L6-v2 (384-dim)sentence-transformers/all-mpnet-base-v2 (768-dim)All hyperparameters are in configs/*.yaml. Key settings:
| Parameter | Track A | Track B |
|---|---|---|
| Backbone | all-MiniLM-L6-v2 | all-mpnet-base-v2 |
| Learning rate | 2e-5 | 2e-5 |
| Batch size | 8 | 32 |
| Epochs | 20 | 15 |
| Loss margin | 0.3 | temperature=0.07 |
Set these before running LLM extraction or W&B logging:
export OPENAI_API_KEY="your-key-here"
export WANDB_API_KEY="your-key-here"
2 commits
Python
85.9%
Jupyter Notebook
13.7%
Implementation for Track A (classification) and Track B (embedding) of SemEval 2026 Task 4.
SemEval2026-Task4-ttda704/
│
├── configs/ # All hyperparameters (YAML)
│ ├── track_a_mpnet.yaml # Track A config (margin, lr, layer freezing)
│ ├── track_b_multiview.yaml # Track B config (fusion weights, alignment lambda)
│ └── prompt_templates.yaml # LLM system prompt for o3-mini (no hardcoding)
│
├── data/ # Data directory (NOT pushed — use .gitignore)
│ ├── raw/ # Original SemEval data
│ ├── processed/ # Post-pseudonymization (Track A)
│ └── llm_extracted/ # Theme, Plot, Outcome JSON from LLM (Track B)
│
├── src/ # Core source modules
│ ├── __init__.py
│ ├── data_processing/
│ │ ├── llm_extractor.py # OpenAI Batch API caller for multi-view extraction
│ │ └── dataset.py # PyTorch Dataset + JSONL loaders
│ ├── models/
│ │ ├── backbone.py # EmbedModel wrapper (MPNet/MiniLM + mean pooling)
│ │ └── multiview_net.py # Multi-view projection heads + fusion layer
│ ├── training/
│ │ ├── trainer_track_a.py # Single-view training loop
│ │ ├── trainer_track_b.py # Multi-view training loop (alternating losses)
│ │ └── losses.py # AdaptiveTripletLoss, MultiViewContrastiveLoss, AlignmentLoss
│ └── utils/
│ ├── common.py # Zip extraction, Kaggle download helpers
│ ├── metrics.py # Accuracy via cosine similarity
│ └── seed.py # Fix random seed for reproducibility
│
├── scripts/ # Entry points
│ ├── run_preprocess.sh # Run LLM extraction pipeline
│ ├── train_track_a.py # Train Track A (reads from configs/)
│ ├── train_track_b.py # Train Track B (reads from configs/)
│ └── generate_submission.py # Generate track_b.npy + submission.zip
│
├── docs/ # Documentation
├── notebooks/ # EDA and error analysis notebooks
│
├── .gitignore
├── requirements.txt
└── README.md
git clone <repository-url>
cd SemEval2026-Task4-ttda704
pip install -r requirements.txt
Download datasets via KaggleHub:
pip install kagglehub
python -c "from src.utils.common import download_and_prepare; download_and_prepare('dinhthienan33/semeval-2026-task-4-track-b')"
Or place data manually in data/raw/.
python scripts/train_track_a.py --config configs/track_a_mpnet.yaml
python scripts/train_track_b.py
python scripts/generate_submission.py \
--model-dir checkpoints/track_a \
--dev-track-b data/raw/dev_track_b.jsonl \
--dev-track-a data/raw/dev_track_a.jsonl
sentence-transformers/all-MiniLM-L6-v2 (384-dim)sentence-transformers/all-mpnet-base-v2 (768-dim)All hyperparameters are in configs/*.yaml. Key settings:
| Parameter | Track A | Track B |
|---|---|---|
| Backbone | all-MiniLM-L6-v2 | all-mpnet-base-v2 |
| Learning rate | 2e-5 | 2e-5 |
| Batch size | 8 | 32 |
| Epochs | 20 | 15 |
| Loss margin | 0.3 | temperature=0.07 |
Set these before running LLM extraction or W&B logging:
export OPENAI_API_KEY="your-key-here"
export WANDB_API_KEY="your-key-here"
2 commits
Python
85.9%
Jupyter Notebook
13.7%