arxiv-topic-classifier / src /streamlit_app.py
mslovenberg's picture
Upload 7 files
e8e0226 verified
Raw
History Blame Contribute Delete
2.57 kB
from pathlib import Path
import streamlit as st
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
MODEL_DIR = Path(__file__).resolve().parent / "model"
DEMO_LABELS = [
"cs.CL",
"math.NT",
"astro-ph.GA",
"q-bio.NC",
"physics.optics",
"econ.EM",
]
def make_text(title: str, abstract: str) -> str:
title = title.strip()
abstract = abstract.strip()
if abstract:
return f"Title: {title}\nAbstract: {abstract}"
return f"Title: {title}"
def top_95(labels, probabilities):
order = torch.argsort(probabilities, descending=True)
result = []
total = 0.0
for idx in order:
probability = float(probabilities[idx])
result.append((labels[int(idx)], probability))
total += probability
if total >= 0.95:
break
return result
@st.cache_resource(show_spinner=False)
def load_model():
tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR, use_fast=False)
model = AutoModelForSequenceClassification.from_pretrained(MODEL_DIR)
model.eval()
labels = [model.config.id2label[i] for i in range(model.config.num_labels)]
return tokenizer, model, labels
def predict(text: str):
tokenizer, model, labels = load_model()
encoded = tokenizer(
text,
truncation=True,
max_length=384,
padding=True,
return_tensors="pt",
)
with torch.inference_mode():
logits = model(**encoded).logits[0]
probabilities = torch.softmax(logits, dim=-1)
return top_95(labels, probabilities)
st.set_page_config(page_title="ArXiv Topic Classifier", page_icon=":books:", layout="centered")
st.title("ArXiv Topic Classifier")
st.caption("Классификатор тематики научной статьи по названию и abstract.")
title = st.text_input("Название статьи", placeholder="Attention Is All You Need")
abstract = st.text_area(
"Abstract",
height=180,
placeholder="Вставьте abstract. Если его нет, модель использует только название.",
)
if st.button("Классифицировать", type="primary", use_container_width=True):
if not title.strip() and not abstract.strip():
st.warning("Введите название, abstract или оба поля.")
else:
st.subheader("Топ-95% тематик")
for label, probability in predict(make_text(title, abstract)):
st.progress(probability, text=f"{label}: {probability:.1%}")