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%}")