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>

Files changed (4) hide show
  1. Dockerfile +4 -2
  2. label_to_topic.json +1 -0
  3. requirements.txt +3 -2
  4. src/streamlit_app.py +62 -37
Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM python:3.13.5-slim
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 -r requirements.txt
 
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
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
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()