Horizon-Labs's picture
Multilingual prompt task & complexity classifier base v1.0
aa93893 verified
Raw History Blame Contribute Delete
3.7 kB
"""Baseline: nvidia/prompt-task-and-complexity-classifier (inference code from its model card) on a prompt set.
python prompt/run_nvidia.py IN.parquet OUT.parquet (adds nv_task, nv_creativity, nv_reasoning, nv_contextual_knowledge, nv_domain_knowledge,
nv_constraints, nv_complexity)"""
import sys
import numpy as np, pandas as pd, torch, torch.nn as nn
from huggingface_hub import PyTorchModelHubMixin
from transformers import AutoConfig, AutoModel, AutoTokenizer
class MeanPooling(nn.Module):
def forward(self, h, m):
m = m.unsqueeze(-1).expand(h.size()).float(); return (h * m).sum(1) / m.sum(1).clamp(min=1e-9)
class MulticlassHead(nn.Module):
def __init__(self, i, n):
super().__init__(); self.fc = nn.Linear(i, n)
def forward(self, x):
return self.fc(x)
class CustomModel(nn.Module, PyTorchModelHubMixin):
def __init__(self, target_sizes, task_type_map, weights_map, divisor_map):
super().__init__()
self.backbone = AutoModel.from_pretrained("microsoft/DeBERTa-v3-base"); self.target_sizes = target_sizes.values()
self.task_type_map, self.weights_map, self.divisor_map = task_type_map, weights_map, divisor_map
self.heads = [MulticlassHead(self.backbone.config.hidden_size, sz) for sz in self.target_sizes]
for i, h in enumerate(self.heads):
self.add_module(f"head_{i}", h)
self.pool = MeanPooling()
def forward(self, ids, att):
h = self.backbone(input_ids=ids, attention_mask=att).last_hidden_state; p = self.pool(h, att)
return [hd(p) for hd in self.heads]
import json, types
from huggingface_hub import hf_hub_download
cfg = types.SimpleNamespace(**json.load(open(hf_hub_download("nvidia/prompt-task-and-complexity-classifier", "config.json")))) # no model_type -> AutoConfig fails on transformers 5
tok = AutoTokenizer.from_pretrained("nvidia/prompt-task-and-complexity-classifier")
m = CustomModel(target_sizes=cfg.target_sizes, task_type_map=cfg.task_type_map, weights_map=cfg.weights_map, divisor_map=cfg.divisor_map
).from_pretrained("nvidia/prompt-task-and-complexity-classifier").cuda().eval()
names = list(cfg.target_sizes.keys()); print(names, cfg.task_type_map, flush=True)
df = pd.read_parquet(sys.argv[1]); out = {k: [] for k in ["nv_task", "creativity_scope", "reasoning", "contextual_knowledge", "number_of_few_shots",
"domain_knowledge", "constraint_ct"]}
score = lambda lo, t: (torch.softmax(lo, 1).cpu().numpy() * np.array(cfg.weights_map[t])).sum(1) / cfg.divisor_map[t]
with torch.no_grad():
for s in range(0, len(df), 64):
e = tok(["Prompt: " + t for t in df.text.iloc[s:s + 64]], return_tensors="pt", max_length=512, padding=True, truncation=True)
lo = m(e["input_ids"].cuda(), e["attention_mask"].cuda())
out["nv_task"] += [cfg.task_type_map[str(i)] for i in lo[0].argmax(1).tolist()]
for k, t in enumerate(names[1:], 1):
if t in out:
out[t] += list(score(lo[k].float(), t))
df["nv_task"] = out["nv_task"]
for a, b in [("creativity_scope", "nv_creativity"), ("reasoning", "nv_reasoning"), ("contextual_knowledge", "nv_contextual_knowledge"),
("domain_knowledge", "nv_domain_knowledge"), ("constraint_ct", "nv_constraints"), ("number_of_few_shots", "nv_few_shots")]:
df[b] = out[a]
df["nv_complexity"] = (0.35 * df.nv_creativity + 0.25 * df.nv_reasoning + 0.15 * df.nv_constraints + 0.15 * df.nv_domain_knowledge
+ 0.05 * df.nv_contextual_knowledge + 0.05 * df.nv_few_shots)
df.to_parquet(sys.argv[2]); print(df.nv_task.value_counts().to_dict(), flush=True)