Mitchins's picture
Initial V5 title-author book genre classifier
e40a651 verified
Raw
History Blame Contribute Delete
2.39 kB
import argparse
import json
import torch
import os
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from genre_policy import GenreDecisionPolicy
def main():
parser = argparse.ArgumentParser(description="Infer genre from Title and Author")
parser.add_argument("--title", required=True, type=str)
parser.add_argument("--author", default="Unknown", type=str)
parser.add_argument("--model-dir", default=".", type=str)
args = parser.parse_args()
# Load Model and Tokenizer
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
tokenizer = AutoTokenizer.from_pretrained(args.model_dir)
model = AutoModelForSequenceClassification.from_pretrained(args.model_dir)
model.to(device)
model.eval()
# Load Policy
policy_path = os.path.join(args.model_dir, "decision_policy.json")
policy = GenreDecisionPolicy(policy_path)
# Input format MUST NOT contain breadcrumbs or categories
input_text = f"Title: {args.title}\nAuthor: {args.author}"
inputs = tokenizer(input_text, return_tensors="pt", truncation=True, max_length=128)
inputs = {k: v.to(device) for k, v in inputs.items()}
with torch.no_grad():
outputs = model(**inputs)
probs = torch.nn.functional.softmax(outputs.logits, dim=-1)[0].cpu().numpy()
# Get labels
id2label = model.config.id2label
top_indices = probs.argsort()[::-1]
top_k = [[id2label[i], float(probs[i])] for i in top_indices]
top1_label, top1_confidence = top_k[0]
top2_label, top2_confidence = top_k[1]
margin = top1_confidence - top2_confidence
decision_out = policy.decide(top_k)
result = {
"title": args.title,
"author": args.author,
"input_text": input_text,
"top1_label": top1_label,
"top1_confidence": round(top1_confidence, 4),
"top2_label": top2_label,
"top2_confidence": round(top2_confidence, 4),
"margin": round(margin, 4),
"top_k": [[l, round(p, 4)] for l, p in top_k],
"decision": decision_out["decision"],
"final_label": decision_out["final_label"],
"ambiguity_bucket": decision_out["ambiguity_bucket"],
"reason": decision_out["reason"],
"model_version": "book_genre_v5_title_author"
}
print(json.dumps(result, indent=2))
if __name__ == "__main__":
main()