Horizon-Labs's picture
Multilingual hate speech detector base v1.0
c1e5dc4 verified
Raw History Blame Contribute Delete
1.96 kB
"""Shared sentiment helpers (no sklearn: also used in the vLLM venv)."""
import glob, os
import numpy as np, pandas as pd
C3 = ["negative", "neutral", "positive"]
def load_evals(d):
return {os.path.basename(p)[:-8]: pd.read_parquet(p) for p in sorted(glob.glob(f"{d}/*.parquet"))}
def macro_f1(y, p, labels):
f = []
for c in labels:
tp = np.sum((p == c) & (y == c)); fp = np.sum((p == c) & (y != c)); fn = np.sum((p != c) & (y == c))
f.append(0.0 if tp == 0 else 2 * tp / (2 * tp + fp + fn))
return float(np.mean(f))
def score(df, probs):
"""probs: (n, 3) over C3. Binary sets (no neutral gold label): argmax over negative/positive only."""
probs = np.asarray(probs, dtype=float); y = df.label.values
if int(df.binary.iloc[0]) == 1:
p = np.where(probs[:, 2] >= probs[:, 0], "positive", "negative"); labs = ["negative", "positive"]
else:
p = np.array(C3)[probs.argmax(1)]; labs = C3
conf = {g: {q: int(((y == g) & (p == q)).sum()) for q in labs} for g in labs} # gold -> predicted counts
return dict(n=len(df), acc=float((p == y).mean()), macro_f1=macro_f1(y, p, labs), conf=conf)
def summarize(r):
out = {}
for fam in ["tweets", "amazon", "mteb"]:
v = [x["macro_f1"] for k, x in r.items() if k.startswith(fam + "_")]
if v:
out[f"_{fam}_mean_f1"] = float(np.mean(v))
return out
def hard_exit(code=0):
"""os._exit after killing our child processes: a vLLM engine core left alive keeps the job's log pipe open and the job
never ends (2026-09-30: an eval job ran on for 30 min after writing its results)."""
import signal, sys
sys.stdout.flush(); me = str(os.getpid())
for p in os.listdir("/proc"):
try:
if p.isdigit() and open(f"/proc/{p}/stat").read().rsplit(")", 1)[1].split()[1] == me:
os.kill(int(p), signal.SIGKILL)
except Exception:
pass
os._exit(code)