Kulebyaka-kokosik Claude Sonnet 4.6 commited on
Commit ·
db7fe13
1
Parent(s): 979fdfb
Fix Docker build: correct Python version, add missing json file, use CPU torch
Browse files- Change python:3.13.5-slim (nonexistent) to python:3.10-slim
- Copy label_to_topic.json into image (was missing, causing runtime error)
- Install CPU-only torch to avoid ~2GB CUDA download and speed up build
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dockerfile +4 -2
- label_to_topic.json +1 -0
- requirements.txt +3 -2
- src/streamlit_app.py +62 -37
Dockerfile
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
FROM python:3.
|
| 2 |
|
| 3 |
WORKDIR /app
|
| 4 |
|
|
@@ -10,8 +10,10 @@ RUN apt-get update && apt-get install -y \
|
|
| 10 |
|
| 11 |
COPY requirements.txt ./
|
| 12 |
COPY src/ ./src/
|
|
|
|
| 13 |
|
| 14 |
-
RUN pip3 install -
|
|
|
|
| 15 |
|
| 16 |
EXPOSE 8501
|
| 17 |
|
|
|
|
| 1 |
+
FROM python:3.10-slim
|
| 2 |
|
| 3 |
WORKDIR /app
|
| 4 |
|
|
|
|
| 10 |
|
| 11 |
COPY requirements.txt ./
|
| 12 |
COPY src/ ./src/
|
| 13 |
+
COPY label_to_topic.json ./
|
| 14 |
|
| 15 |
+
RUN pip3 install torch --index-url https://download.pytorch.org/whl/cpu && \
|
| 16 |
+
pip3 install -r requirements.txt
|
| 17 |
|
| 18 |
EXPOSE 8501
|
| 19 |
|
label_to_topic.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"0": "Artificial Intelligence", "1": "Computation and Language", "2": "Computer Vision and Pattern Recognition", "3": "Neural and Evolutionary Computing", "4": "Machine Learning", "5": "Machine Learning", "6": "Physics and Society", "7": "Applications", "8": "Robotics", "9": "Software Engineering", "10": "Multiagent Systems", "11": "Optimization and Control", "12": "Information Retrieval", "13": "Disordered Systems and Neural Networks", "14": "Methodology", "15": "Distributed, Parallel, and Cluster Computing", "16": "Computation", "17": "Neurons and Cognition", "18": "Computer Science and Game Theory", "19": "Multimedia", "20": "Cryptography and Security", "21": "Human-Computer Interaction", "22": "Sound", "23": "Graphics", "24": "Numerical Analysis", "25": "Computers and Society", "26": "Data Analysis, Statistics and Probability", "27": "Statistics Theory", "28": "Statistics Theory", "29": "Information Theory", "30": "Information Theory", "31": "Quantum Physics", "32": "Social and Information Networks", "33": "Databases", "34": "Logic in Computer Science", "35": "Adaptation and Self-Organizing Systems", "36": "Systems and Control", "37": "Computational Complexity", "38": "Quantitative Methods", "39": "Networking and Internet Architecture", "40": "Data Structures and Algorithms", "41": "Numerical Analysis", "42": "Discrete Mathematics", "43": "Probability", "44": "Computational Engineering, Finance, and Science", "45": "Programming Languages", "46": "Digital Libraries"}
|
requirements.txt
CHANGED
|
@@ -1,3 +1,4 @@
|
|
| 1 |
-
altair
|
| 2 |
pandas
|
| 3 |
-
streamlit
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
pandas
|
| 2 |
+
streamlit
|
| 3 |
+
transformers
|
| 4 |
+
torch
|
src/streamlit_app.py
CHANGED
|
@@ -1,40 +1,65 @@
|
|
| 1 |
-
import altair as alt
|
| 2 |
import numpy as np
|
| 3 |
-
import pandas as pd
|
| 4 |
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import numpy as np
|
|
|
|
| 2 |
import streamlit as st
|
| 3 |
+
from typing import Dict, List
|
| 4 |
+
import torch
|
| 5 |
+
import json
|
| 6 |
+
from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
| 7 |
|
| 8 |
+
@st.cache_resource
|
| 9 |
+
def load_model():
|
| 10 |
+
model = AutoModelForSequenceClassification.from_pretrained("Kulebyaka-kokosik/articles-classifier-model")
|
| 11 |
+
tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-cased")
|
| 12 |
+
model.eval()
|
| 13 |
+
return model, tokenizer
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@st.cache_resource
|
| 17 |
+
def load_label_to_topic():
|
| 18 |
+
with open("label_to_topic.json") as file:
|
| 19 |
+
label_to_topic = json.load(file)
|
| 20 |
+
return label_to_topic
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def inference(
|
| 24 |
+
model: AutoModelForSequenceClassification,
|
| 25 |
+
tokenizer: AutoTokenizer,
|
| 26 |
+
title: str,
|
| 27 |
+
summary: str
|
| 28 |
+
) -> torch.Tensor:
|
| 29 |
+
tokenized = tokenizer(title, summary, padding='max_length', truncation=True, return_tensors="pt")
|
| 30 |
+
|
| 31 |
+
with torch.no_grad():
|
| 32 |
+
logits = model(**tokenized).logits
|
| 33 |
+
return logits
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def predict_topics(
|
| 37 |
+
model: AutoModelForSequenceClassification,
|
| 38 |
+
tokenizer: AutoTokenizer,
|
| 39 |
+
title: str,
|
| 40 |
+
summary: str,
|
| 41 |
+
label_to_topic: Dict[str, str],
|
| 42 |
+
top_k: int = 5,
|
| 43 |
+
) -> List[str]:
|
| 44 |
+
logits = inference(model, tokenizer, title, summary)
|
| 45 |
+
|
| 46 |
+
probs = torch.sigmoid(logits).squeeze(0)
|
| 47 |
+
labels = np.argsort(-probs)[:top_k].tolist()
|
| 48 |
+
topics = [label_to_topic[str(label)] for label in labels]
|
| 49 |
+
return topics
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def main():
|
| 54 |
+
model, tokenizer = load_model()
|
| 55 |
+
label_to_topic = load_label_to_topic()
|
| 56 |
+
|
| 57 |
+
st.title("Articles classifier")
|
| 58 |
+
|
| 59 |
+
title = st.text_input("Title")
|
| 60 |
+
abstract = st.text_area("Abstract")
|
| 61 |
+
|
| 62 |
+
topics = predict_topics(model, tokenizer, title, abstract, label_to_topic=label_to_topic)
|
| 63 |
+
st.write(topics)
|
| 64 |
+
|
| 65 |
+
main()
|