File size: 6,121 Bytes
9f0e60b f6f5b3d 9f0e60b f6f5b3d 1480198 f6f5b3d 9f0e60b f6f5b3d 9f0e60b f6f5b3d 9f0e60b f6f5b3d 1480198 9f0e60b f6f5b3d 1480198 9f0e60b f6f5b3d 1480198 9f0e60b 1480198 f6f5b3d 1480198 9f0e60b f6f5b3d 1480198 f6f5b3d 9f0e60b f6f5b3d 1480198 f6f5b3d 9f0e60b f6f5b3d 1480198 9f0e60b f6f5b3d 9f0e60b 1480198 9f0e60b f6f5b3d 1480198 f6f5b3d 9f0e60b f6f5b3d 9f0e60b f6f5b3d 9f0e60b f6f5b3d 9f0e60b f6f5b3d 1480198 f6f5b3d 1480198 9f0e60b 1480198 9f0e60b f6f5b3d 1480198 f6f5b3d 1480198 9f0e60b f6f5b3d 1480198 f6f5b3d 1480198 f6f5b3d 1480198 f6f5b3d 9f0e60b 1480198 9f0e60b 1480198 9f0e60b f6f5b3d 1480198 9f0e60b f6f5b3d 9f0e60b f6f5b3d 1480198 f6f5b3d 1480198 f6f5b3d | 1 2 3 4 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | import streamlit as st
import torch
import joblib
from transformers import AutoTokenizer, AutoModelForSequenceClassification
# -----------------------------------------------------------
# ๐ Streamlit Page Configuration
# -----------------------------------------------------------
st.set_page_config(
page_title="StackOverflow Tag Predictor",
page_icon="๐ฏ",
layout="centered",
)
# -----------------------------------------------------------
# ๐ Custom CSS for a Rich UI
# -----------------------------------------------------------
st.markdown("""
<style>
body {
background-color: #F5F7FB;
}
.header {
text-align: center;
margin-top: -20px;
margin-bottom: 10px;
}
.header-title {
font-size: 48px;
font-weight: 900;
background: linear-gradient(90deg, #4A4AFC, #6A6AFF);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.header-subtitle {
font-size: 18px;
color: #555;
margin-top: -10px;
margin-bottom: 25px;
}
.card {
background: white;
padding: 30px;
border-radius: 18px;
box-shadow: 0px 6px 20px rgba(0,0,0,0.08);
margin-bottom: 20px;
}
.result-tag {
background: linear-gradient(90deg, #4A4AFC, #6A6AFF);
padding: 14px 24px;
border-radius: 14px;
color: white;
display: inline-block;
font-size: 22px;
font-weight: 700;
animation: fadeIn 0.4s ease-out;
}
@keyframes fadeIn {
from {opacity: 0; transform: translateY(10px);}
to {opacity: 1; transform: translateY(0);}
}
.footer {
text-align: center;
margin-top: 40px;
color: #777;
font-size: 14px;
}
</style>
""", unsafe_allow_html=True)
# -----------------------------------------------------------
# ๐ฆ Load Model & Tokenizer
# -----------------------------------------------------------
@st.cache_resource
def load_model():
model = AutoModelForSequenceClassification.from_pretrained(".")
tokenizer = AutoTokenizer.from_pretrained(".")
return model, tokenizer
model, tokenizer = load_model()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# -----------------------------------------------------------
# ๐ค Load Label Encoder
# -----------------------------------------------------------
label_encoder = joblib.load("label_encoder.joblib")
id2label = {i: label for i, label in enumerate(label_encoder.classes_)}
# -----------------------------------------------------------
# ๐ฎ Prediction Function
# -----------------------------------------------------------
def predict_tag(text):
encoding = tokenizer(
text,
truncation=True,
padding=True,
max_length=128,
return_tensors="pt"
)
encoding = {k: v.to(device) for k, v in encoding.items()}
with torch.no_grad():
outputs = model(**encoding)
pred_id = torch.argmax(outputs.logits, dim=-1).item()
tag = id2label[pred_id]
confidence = torch.softmax(outputs.logits, dim=-1).max().item()
return tag, confidence
# -----------------------------------------------------------
# ๐ฏ Header
# -----------------------------------------------------------
st.markdown("""
<div class="header">
<div class="header-title">๐ฏ StackOverflow Tag Predictor</div>
<div class="header-subtitle">Powered by DistilBERT โข Predict the most likely tag from a question title</div>
</div>
""", unsafe_allow_html=True)
# -----------------------------------------------------------
# ๐๏ธ Sidebar โ About the Model
# -----------------------------------------------------------
st.sidebar.title("โน๏ธ About This App")
st.sidebar.write("""
This app uses a fine-tuned **DistilBERT** model trained on the
top 50 StackOverflow tags.
You can:
- Type your own question title
- Pick from example titles
- See model confidence
""")
st.sidebar.write("### ๐ง Model Info")
st.sidebar.write(f"**Labels:** {len(id2label)} classes")
st.sidebar.write("**Framework:** PyTorch + HuggingFace Transformers")
# -----------------------------------------------------------
# ๐งช Example Questions Dropdown
# -----------------------------------------------------------
examples = [
"How to fix NullPointerException in Java?",
"What is the best way to center a div in CSS?",
"How do I connect to a MySQL database in Python?",
"Why is my React component not rendering?",
"How to optimize a SQL query that is too slow?",
"How to declare an array in C++?"
]
example_choice = st.selectbox(
"โจ Or choose an example question:",
["(None)"] + examples
)
# -----------------------------------------------------------
# ๐ Main Input Card
# -----------------------------------------------------------
st.markdown("<div class='card'>", unsafe_allow_html=True)
if example_choice != "(None)":
user_input = example_choice
else:
user_input = st.text_area(
"๐ฌ Enter a StackOverflow question title:",
height=120,
placeholder="Example: \"How to fix NullPointerException in Java?\""
)
predict_btn = st.button("๐ Predict Tag", use_container_width=True)
# -----------------------------------------------------------
# ๐ Prediction Output
# -----------------------------------------------------------
if predict_btn:
if user_input.strip() == "":
st.warning("โ ๏ธ Please enter a question title.")
else:
with st.spinner("Analyzing with AIโฆ ๐งโจ"):
tag, confidence = predict_tag(user_input)
st.success("Prediction ready! ๐")
st.markdown(f"<div class='result-tag'>{tag}</div>", unsafe_allow_html=True)
st.markdown(
f"### ๐ฅ Confidence Score: **{confidence*100:.2f}%**"
)
st.markdown("</div>", unsafe_allow_html=True)
# -----------------------------------------------------------
# ๐ Footer
# -----------------------------------------------------------
st.markdown("""
<div class='footer'>
Made with โค๏ธ using DistilBERT + Streamlit + HuggingFace Spaces<br>
Try different example titles or write your own!
</div>
""", unsafe_allow_html=True)
|