Vibe Check β€” a 7-emotion Transformer trained from scratch 🎭

πŸ”— Try the live app - chat with Buddy & Wit and run a Vibe Check, nothing to install: https://civilaakash.github.io/buddymini/

Vibe Check is a compact (~8.3M parameter) Transformer text classifier that reads the emotional tone of a sentence or a short conversation across 7 classes: sadness Β· joy Β· love Β· anger Β· fear Β· surprise Β· neutral.

It was built entirely from scratch as a hands-on learning project β€” my own word tokenizer, my own model architecture, trained from random initialization (no pretrained weights, no fine-tuning of a large model) on public data only.

Not a fine-tune

Unlike most models on the Hub, this is not a fine-tune of a large pretrained model. Every weight was learned from zero on public data. The tokenizer, architecture, training config, and inference code are all included in this repo.

Architecture

  • Word-level tokenizer (regex [a-z']+), vocab 20,002
  • Token embedding + learned positional embedding (max length 64)
  • 4 Transformer encoder layers Β· embedding dim 256 Β· 8 heads Β· FF 1024 Β· GELU
  • Padding-masked mean pooling β†’ linear classification head
  • 8,297,735 parameters Β· runs on CPU in milliseconds

Performance (measured, honest)

  • ~88% accuracy on the dair-ai/emotion validation split (2,000 held-out tweets, 7-way argmax).
  • It is strong when emotion is stated in words:
    Input Prediction
    "I'm terrified of the interview tomorrow" fear (97%)
    "I love spending time with my family" love (96%)
    "This is amazing news" joy (94%)

⚠️ Known limitation β€” implied emotion reads as neutral

This is a tiny model, and it keys off explicit emotional language. When a feeling is only implied by a factual statement (no emotion words), it tends to fall back to neutral:

Input Prediction What a human would say
"My dog passed away" neutral (46%) sadness
"I got promoted today!" neutral (75%) joy

So it works best as a conversation-tone reader (see analyze_day below), where it aggregates emotion across many messages and skips the neutral filler β€” not as a single-sentence oracle. Treat it as an educational / entertainment model, not a clinical or production sentiment system.

Usage β€” PyTorch

# clone/download this repo, then from inside it:
from emotion import predict_emotion, analyze_day

predict_emotion("i feel so happy right now")
# {'label': 'joy', 'confidence': 97.6, 'distribution': {...}, 'words': [...]}

# reads the overall mood across a whole conversation (list of messages):
analyze_day([
    "work made me feel sad and invisible today",
    "but then my friend called and i felt loved",
])
# {'dominant': 'love', 'valence': 'mixed', 'distribution': {...}, ...}

Usage β€” ONNX (no PyTorch needed)

import json, re, numpy as np, onnxruntime as ort
vocab = json.load(open("emotion_vocab.json"))
labels = ["sadness","joy","love","anger","fear","surprise","neutral"]
sess = ort.InferenceSession("vibe-int8.onnx")
name = sess.get_inputs()[0].name
ids = [vocab.get(w, 1) for w in re.findall(r"[a-z']+", "i love this so much".lower())][:64]
logits = sess.run(None, {name: np.array([ids], dtype=np.int64)})[0][0]
print(labels[int(logits.argmax())])   # -> love

Training data

  • dair-ai/emotion β€” English tweets, 6 emotions.
  • GoEmotions (Google) β€” Reddit comments; low-signal labels (e.g. curiosity/confusion) mapped to neutral.
  • Classes balanced (capped per class) to remove the "everything is joy" bias.

All training data is public β€” no company data and no personal data of any kind.

License & intent

Model weights and code released under Apache-2.0, for educational and entertainment use. Built by @AakashakaAkku while learning how transformers and LLMs actually work β€” by building one end to end. Feedback and questions welcome. πŸ™Œ

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Datasets used to train AakashakaAkku/vibe-check-emotion