Elysium X 20 FR - structured emotion appraisal LoRA

base method weights code data engine

Read one message. Get a structured emotion appraisal as JSON.
A LoRA adapter on Qwen2.5-1.5B-Instruct, built to feed the Elysium X 20 emotion-state engine. Part of Project NHE. Usable on its own.


Status: v1, small and honest. One epoch on 12k examples, free Colab T4. It clearly beats the trivial baseline but is not a state-of-the-art emotion classifier. All numbers are from one run, one seed.

Technical paper: Elysium X 20 FR: A Small LoRA Adapter That Turns One Message into a Structured Emotion Appraisal, Trained on GoEmotions (Zenodo preprint, DOI 10.5281/zenodo.23161139, CC BY-NC-ND 4.0), Pratham Prateek Mohanty. Research showcase: itsppm76/research.

Demo

Terminal demo: message in, appraisal JSON out, then engine impulses

Real sample from the eval set. Impulses are computed with the label table in scripts/fr_appraiser.py.

Output format

Input: one user message. Output: compact JSON, no extra text.

{"emotions":[{"label":"gratitude","intensity":1.0},{"label":"admiration","intensity":0.67}],"valence":0.8,"arousal":0.2}
field meaning
label one of the 28 GoEmotions labels (27 emotions + neutral)
intensity fraction of human raters (3-5 per comment) who chose the label. An agreement signal, not measured intensity
valence, arousal -1..1, computed from the labels with a hand-written table (train/common.py). A convention, not psychometric ground truth. The model learned to reproduce it

Architecture

Message to Qwen2.5 plus LoRA to appraisal JSON to FRAppraiser to the Elysium X 20 engine

The adapter sits in front of the engine's Appraiser protocol. FRAppraiser turns the 28 GoEmotions labels into the engine's Plutchik 8 impulses with a hand-written table (GOEMO_TO_PLUTCHIK). Edit it to taste.

Evaluation

1,500 random examples from the GoEmotions test split (seed 42), greedy decoding. Gold = GoEmotions' agreement-filtered labels, multi-label.

micro-F1 0.570, 99.93 percent valid JSON, 61.9 percent top-1 in gold

metric value
parser-accepted JSON 99.93% (1499 / 1500)
micro-F1 (labels) 0.570
baseline: always predict neutral 0.304
macro-F1, all 28 labels 0.431
macro-F1, 24 labels with >=10 test examples 0.484
top-1 predicted label is in gold 61.9%
MAE valence / arousal vs derived target 0.21 / 0.15
MAE intensity (on correctly matched labels) 0.14

The valence, arousal and intensity rows measure agreement with derived targets, not accuracy against independent human ratings.

Strong and weak emotions

Per-label F1: strong on gratitude, amusement, love; weak on approval, realization, disapproval

All 28 labels (F1, support in the 1,500 sample)

Labels with support under 10 are noisy: grief (4) and pride (3) scored 0.

label support F1
gratitude 104 0.906
amusement 80 0.844
love 64 0.797
neutral 495 0.667
admiration 133 0.651
remorse 16 0.650
fear 19 0.612
curiosity 85 0.568
optimism 53 0.542
embarrassment 13 0.526
joy 44 0.491
sadness 45 0.489
anger 53 0.485
confusion 35 0.464
disgust 32 0.409
surprise 45 0.385
caring 30 0.361
desire 19 0.333
excitement 28 0.333
annoyance 82 0.284
disappointment 41 0.262
relief 6 0.250
disapproval 71 0.220
realization 39 0.205
nervousness 8 0.200
approval 105 0.124
grief 4 0.000
pride 3 0.000

Usage

# pip install transformers peft torch
# scripts/ and train/ (FRAppraiser) are not public; load the adapter with transformers + peft as shown below the engine snippet
from scripts.fr_appraiser import FRAppraiser
fr = FRAppraiser("open-nhe/Elysium-X-20-FR")
print(fr.raw("I got the job!! can't believe it"))

Plug into the engine (pip install from the Elysium X 20 repo first):

from elysium_x20 import EmotionEngine
engine = EmotionEngine(appraiser=FRAppraiser("open-nhe/Elysium-X-20-FR"))
state = engine.process_turn("thank you, that really helped")

The adapter and FRAppraiser.raw() were run on a GPU in Colab. The engine integration (scripts/fr_appraiser.py) was checked for label-name compatibility only, not run end to end with the model loaded.

Limits

  • Weak on context-dependent labels: approval, disapproval, annoyance, realization, disappointment. It over-predicts neutral on sarcasm and subtle tone.
  • English only; trained on Reddit comments, so register skews informal. Single message in, no conversation history and no prior emotion state.
  • No rationales and no response-modulation output. Only the JSON above was trained.
  • Only 12,000 of the 43,410 training examples and one epoch were used. More data and epochs would likely help; this is untested.
  • Not for clinical, safety or mental-health decisions. It labels the text, not the person's actual feelings.

Training

  • Base: Qwen/Qwen2.5-1.5B-Instruct, fp16, LoRA r=16, alpha=32, dropout 0.05 on all attention + MLP projections (18.5M trainable params).
  • Data: GoEmotions (Demszky et al., 2020), google-research-datasets/go_emotions, simplified split for labels and raw for per-rater counts. First 12,000 shuffled train examples.
  • 1 epoch, batch 16, lr 2e-4 cosine, loss on the JSON answer only. Final train loss about 0.10. 36 min on a free Colab T4.
  • Reproduce: notebooks/Elysium_X_20_FR_train.ipynb (self-contained) or train/train.py.

Paper and citation

Mohanty, P. P. (2026). Elysium X 20 FR: A Small LoRA Adapter That Turns One Message into a Structured Emotion Appraisal, Trained on GoEmotions. Zenodo. https://doi.org/10.5281/zenodo.23161139

License and credits

Proprietary - All Rights Reserved (the repository is public for reading and evaluation) for Pratham Prateek Mohanty's original contributions to the project (code, LoRA adapter weights, and documentation). Qwen2.5-1.5B-Instruct and the GoEmotions dataset remain under Apache-2.0, with their applicable upstream license terms and notices.

Built on Qwen2.5-1.5B-Instruct (Apache-2.0), copyright Alibaba Group; GoEmotions dataset (Apache-2.0), Google Research.

Author: Pratham Prateek Mohanty, Project NHE.

Downloads last month
9
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for open-nhe/Elysium-X-20-FR

Adapter
(1507)
this model

Dataset used to train open-nhe/Elysium-X-20-FR

Space using open-nhe/Elysium-X-20-FR 1