Multilingual Emotions (small, 141M): the 28 GoEmotions labels in many languages
0
3 commits
1 linked in READMEs
updated Oct 2, 2026
A multi-label emotion classifier with the 28 labels of Google's GoEmotions (admiration, amusement, anger, ... , surprise, neutral). It works on text in English and 35 other languages. It is a drop-in multilingual alternative to English-only GoEmotions models such as SamLowe/roberta-base-go_emotions: the labels are the same and it uses the same sigmoid multi-label output. Built on mmBERT-small, Apache-2.0. ONNX files for CPU and the browser (transformers.js) are included. A larger, more accurate version is available as multilingual-emotions-base. Try it in the browser.
neutral.thresholds.json has one threshold per label, tuned on the GoEmotions validation set. Use it instead of 0.5,
especially for rare labels (grief, pride, relief, nervousness). See Usage.ekman_mapping.json, code below).onnx/model_quantized.onnx (int8 embeddings, 268 MB) agrees with fp32 on 98.7% of 448 test texts (all 28 labels thresholded at 0.5).import json
from huggingface_hub import hf_hub_download
from transformers import pipeline
clf = pipeline("text-classification", model="Horizon-Labs/multilingual-emotions-small", top_k=None)
thr = json.load(open(hf_hub_download("Horizon-Labs/multilingual-emotions-small", "thresholds.json")))
out = clf(["Thank you so much, this made my day!", "Tengo miedo de que no lleguemos a tiempo."])
print([[x["label"] for x in o if x["score"] >= thr[x["label"]]] for o in out])
# e.g. [['excitement', 'gratitude', 'joy'], ['fear']]
# 6 Ekman emotions: max score over each group
ekman = json.load(open(hf_hub_download("Horizon-Labs/multilingual-emotions-small", "ekman_mapping.json")))
scores = {x["label"]: x["score"] for x in out[1]}
print({e: max(scores[l] for l in ls) for e, ls in ekman.items()})
transformers.js:
import { pipeline } from "@huggingface/transformers";
const clf = await pipeline("text-classification", "Horizon-Labs/multilingual-emotions-small", { dtype: "q8" });
console.log(await clf("Je suis tellement fier de toi !", { top_k: 5 }));
The benchmarks were used only for evaluation, and training texts that also occur in them were removed.
| model | licence | GoEmotions test, macro-F1 @0.5 | GoEmotions test, macro-F1 (tuned thresholds) | BRIGHTER, 6 emotions | BRIGHTER, 4 emotions | labels |
|---|---|---|---|---|---|---|
| this model (141M) | Apache-2.0 | 0.447 | 0.494 | 0.406 | 0.432 | 28 GoEmotions labels, multilingual |
| multilingual-emotions-base (308M) | Apache-2.0 | 0.473 | 0.516 | 0.420 | 0.449 | |
| SamLowe/roberta-base-go_emotions (125M) | MIT | 0.450 | 0.519 | 0.282 | 0.291 | 28 GoEmotions labels, English |
| AnasAlokla/multilingual_go_emotions | MIT | 0.455 | 0.538 | 0.337 | 0.355 | 28 GoEmotions labels, multilingual |
| j-hartmann/emotion-english-distilroberta-base (82M) | none given | β | β | 0.297 | 0.315 | 7 labels, English |
| MilaNLProc/xlm-emo-t (278M) | none given | β | β | β | 0.456 | 4 labels (anger, fear, joy, sadness), multilingual tweets |
| tabularisai/multilingual-emotion-classification (135M) | CC-BY-NC-4.0 | β | β | 0.404 | 0.428 | 11 labels, multilingual |
Per BRIGHTER language (macro-F1):
| language | this model (6 emotions) | this model (4) | xlm-emo-t (4) | tabularisai (6, NC) |
|---|---|---|---|---|
| Afrikaans | 0.405 | 0.442 | 0.350 | 0.339 |
| Algerian Arabic | 0.434 | 0.429 | 0.479 | 0.442 |
| Moroccan Arabic | 0.348 | 0.382 | 0.457 | 0.314 |
| Chinese | 0.432 | 0.493 | 0.564 | 0.439 |
| German | 0.418 | 0.452 | 0.510 | 0.434 |
| English | 0.543 | 0.565 | 0.618 | 0.522 |
| Spanish | 0.653 | 0.672 | 0.772 | 0.636 |
| Hausa | 0.335 | 0.321 | 0.342 | 0.354 |
| Hindi | 0.612 | 0.606 | 0.731 | 0.757 |
| Igbo | 0.250 | 0.284 | 0.294 | 0.272 |
| Indonesian | 0.506 | 0.535 | 0.587 | 0.495 |
| Javanese | 0.448 | 0.480 | 0.425 | 0.433 |
| Kinyarwanda | 0.228 | 0.274 | 0.261 | 0.194 |
| Marathi | 0.579 | 0.569 | 0.624 | 0.670 |
| Nigerian Pidgin | 0.420 | 0.361 | 0.425 | 0.451 |
| Portuguese (Brazil) | 0.408 | 0.511 | 0.564 | 0.406 |
| Portuguese (Mozambique) | 0.271 | 0.351 | 0.384 | 0.287 |
| Romanian | 0.587 | 0.664 | 0.683 | 0.570 |
| Russian | 0.640 | 0.647 | 0.755 | 0.706 |
| Sundanese | 0.396 | 0.446 | 0.458 | 0.389 |
| Swahili | 0.251 | 0.228 | 0.278 | 0.244 |
| Swedish | 0.445 | 0.490 | 0.475 | 0.367 |
| Tatar | 0.548 | 0.551 | 0.352 | 0.359 |
| Ukrainian | 0.436 | 0.478 | 0.517 | 0.462 |
| Makhuwa | 0.163 | 0.188 | 0.174 | 0.151 |
| isiXhosa | 0.298 | 0.304 | 0.294 | 0.300 |
| Yoruba | 0.155 | 0.201 | 0.196 | 0.154 |
| isiZulu | 0.162 | 0.181 | 0.189 | 0.164 |
Weakest GoEmotions labels (test F1, tuned thresholds): grief 0.20, relief 0.21, disappointment 0.29, realization 0.31, annoyance 0.36, excitement 0.36. Several of these are rare, and GoEmotions annotators often disagree on such labels.
code/ in this repository.Multilingual Emotions (small, 141M): the 28 GoEmotions labels in many languages
0
3 commits
1 linked in READMEs
updated Oct 2, 2026
A multi-label emotion classifier with the 28 labels of Google's GoEmotions (admiration, amusement, anger, ... , surprise, neutral). It works on text in English and 35 other languages. It is a drop-in multilingual alternative to English-only GoEmotions models such as SamLowe/roberta-base-go_emotions: the labels are the same and it uses the same sigmoid multi-label output. Built on mmBERT-small, Apache-2.0. ONNX files for CPU and the browser (transformers.js) are included. A larger, more accurate version is available as multilingual-emotions-base. Try it in the browser.
neutral.thresholds.json has one threshold per label, tuned on the GoEmotions validation set. Use it instead of 0.5,
especially for rare labels (grief, pride, relief, nervousness). See Usage.ekman_mapping.json, code below).onnx/model_quantized.onnx (int8 embeddings, 268 MB) agrees with fp32 on 98.7% of 448 test texts (all 28 labels thresholded at 0.5).import json
from huggingface_hub import hf_hub_download
from transformers import pipeline
clf = pipeline("text-classification", model="Horizon-Labs/multilingual-emotions-small", top_k=None)
thr = json.load(open(hf_hub_download("Horizon-Labs/multilingual-emotions-small", "thresholds.json")))
out = clf(["Thank you so much, this made my day!", "Tengo miedo de que no lleguemos a tiempo."])
print([[x["label"] for x in o if x["score"] >= thr[x["label"]]] for o in out])
# e.g. [['excitement', 'gratitude', 'joy'], ['fear']]
# 6 Ekman emotions: max score over each group
ekman = json.load(open(hf_hub_download("Horizon-Labs/multilingual-emotions-small", "ekman_mapping.json")))
scores = {x["label"]: x["score"] for x in out[1]}
print({e: max(scores[l] for l in ls) for e, ls in ekman.items()})
transformers.js:
import { pipeline } from "@huggingface/transformers";
const clf = await pipeline("text-classification", "Horizon-Labs/multilingual-emotions-small", { dtype: "q8" });
console.log(await clf("Je suis tellement fier de toi !", { top_k: 5 }));
The benchmarks were used only for evaluation, and training texts that also occur in them were removed.
| model | licence | GoEmotions test, macro-F1 @0.5 | GoEmotions test, macro-F1 (tuned thresholds) | BRIGHTER, 6 emotions | BRIGHTER, 4 emotions | labels |
|---|---|---|---|---|---|---|
| this model (141M) | Apache-2.0 | 0.447 | 0.494 | 0.406 | 0.432 | 28 GoEmotions labels, multilingual |
| multilingual-emotions-base (308M) | Apache-2.0 | 0.473 | 0.516 | 0.420 | 0.449 | |
| SamLowe/roberta-base-go_emotions (125M) | MIT | 0.450 | 0.519 | 0.282 | 0.291 | 28 GoEmotions labels, English |
| AnasAlokla/multilingual_go_emotions | MIT | 0.455 | 0.538 | 0.337 | 0.355 | 28 GoEmotions labels, multilingual |
| j-hartmann/emotion-english-distilroberta-base (82M) | none given | β | β | 0.297 | 0.315 | 7 labels, English |
| MilaNLProc/xlm-emo-t (278M) | none given | β | β | β | 0.456 | 4 labels (anger, fear, joy, sadness), multilingual tweets |
| tabularisai/multilingual-emotion-classification (135M) | CC-BY-NC-4.0 | β | β | 0.404 | 0.428 | 11 labels, multilingual |
Per BRIGHTER language (macro-F1):
| language | this model (6 emotions) | this model (4) | xlm-emo-t (4) | tabularisai (6, NC) |
|---|---|---|---|---|
| Afrikaans | 0.405 | 0.442 | 0.350 | 0.339 |
| Algerian Arabic | 0.434 | 0.429 | 0.479 | 0.442 |
| Moroccan Arabic | 0.348 | 0.382 | 0.457 | 0.314 |
| Chinese | 0.432 | 0.493 | 0.564 | 0.439 |
| German | 0.418 | 0.452 | 0.510 | 0.434 |
| English | 0.543 | 0.565 | 0.618 | 0.522 |
| Spanish | 0.653 | 0.672 | 0.772 | 0.636 |
| Hausa | 0.335 | 0.321 | 0.342 | 0.354 |
| Hindi | 0.612 | 0.606 | 0.731 | 0.757 |
| Igbo | 0.250 | 0.284 | 0.294 | 0.272 |
| Indonesian | 0.506 | 0.535 | 0.587 | 0.495 |
| Javanese | 0.448 | 0.480 | 0.425 | 0.433 |
| Kinyarwanda | 0.228 | 0.274 | 0.261 | 0.194 |
| Marathi | 0.579 | 0.569 | 0.624 | 0.670 |
| Nigerian Pidgin | 0.420 | 0.361 | 0.425 | 0.451 |
| Portuguese (Brazil) | 0.408 | 0.511 | 0.564 | 0.406 |
| Portuguese (Mozambique) | 0.271 | 0.351 | 0.384 | 0.287 |
| Romanian | 0.587 | 0.664 | 0.683 | 0.570 |
| Russian | 0.640 | 0.647 | 0.755 | 0.706 |
| Sundanese | 0.396 | 0.446 | 0.458 | 0.389 |
| Swahili | 0.251 | 0.228 | 0.278 | 0.244 |
| Swedish | 0.445 | 0.490 | 0.475 | 0.367 |
| Tatar | 0.548 | 0.551 | 0.352 | 0.359 |
| Ukrainian | 0.436 | 0.478 | 0.517 | 0.462 |
| Makhuwa | 0.163 | 0.188 | 0.174 | 0.151 |
| isiXhosa | 0.298 | 0.304 | 0.294 | 0.300 |
| Yoruba | 0.155 | 0.201 | 0.196 | 0.154 |
| isiZulu | 0.162 | 0.181 | 0.189 | 0.164 |
Weakest GoEmotions labels (test F1, tuned thresholds): grief 0.20, relief 0.21, disappointment 0.29, realization 0.31, annoyance 0.36, excitement 0.36. Several of these are rare, and GoEmotions annotators often disagree on such labels.
code/ in this repository.