ghostai1 commited on
Commit
6310b52
Β·
verified Β·
1 Parent(s): f24b473

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -43
app.py CHANGED
@@ -1,52 +1,65 @@
1
- import gradio as gr
 
 
 
2
  import pandas as pd
 
3
  from sentence_transformers import SentenceTransformer, util
4
 
5
- # ---------- Load data & model (all CPU-friendly) ----------
6
- faq_df = pd.read_csv("faqs.csv")
 
 
 
 
7
  questions = faq_df["question"].tolist()
8
  answers = faq_df["answer"].tolist()
9
 
10
- model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
11
- question_embeddings = model.encode(questions, convert_to_tensor=True, normalize_embeddings=True)
12
-
13
- # ---------- Search function ----------
14
- def semantic_search(user_query, top_k=3):
15
- query_embedding = model.encode(user_query, convert_to_tensor=True, normalize_embeddings=True)
16
- scores = util.cos_sim(query_embedding, question_embeddings)[0]
17
- top_k_idx = scores.topk(k=top_k).indices.cpu().numpy()
18
-
19
- results = []
20
- for idx in top_k_idx:
21
- results.append(
22
- {
23
- "FAQ Question": questions[idx],
24
- "FAQ Answer" : answers[idx],
25
- "Similarity" : f"{scores[idx]:.3f}"
26
- }
27
- )
28
- return results
29
-
30
- # ---------- Gradio UI ----------
31
- with gr.Blocks(title="MiniLM Semantic FAQ Search") as demo:
32
- gr.Markdown(
33
- """
34
- # πŸ” Semantic FAQ Search
35
- Enter a salon-related question. The model finds the closest FAQs and displays their answers.
36
- """)
37
-
 
 
 
 
 
 
 
 
38
  with gr.Row():
39
- query_box = gr.Textbox(
40
- label="Ask a question",
41
- placeholder="e.g. Which spray protects hair from heat?"
42
- )
43
- topk_slider = gr.Slider(
44
- 1, 5, value=3, step=1, label="Number of results"
45
- )
46
- search_btn = gr.Button("Search")
47
- out = gr.Dataframe(headers=["FAQ Question", "FAQ Answer", "Similarity"], visible=True, wrap=True)
48
-
49
- search_btn.click(semantic_search, [query_box, topk_slider], out)
50
 
51
  if __name__ == "__main__":
52
- demo.launch(server_name="0.0.0.0", show_error=True)
 
1
+ # app.py ─ HF Space β€’ MiniLM semantic FAQ search (CPU-only)
2
+
3
+ import re
4
+ from pathlib import Path
5
  import pandas as pd
6
+ import gradio as gr
7
  from sentence_transformers import SentenceTransformer, util
8
 
9
+ # ─────────── config ───────────
10
+ CSV_PATH = Path("faqs.csv")
11
+ MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2"
12
+
13
+ # ─────────── load data/model ───────────
14
+ faq_df = pd.read_csv(CSV_PATH)
15
  questions = faq_df["question"].tolist()
16
  answers = faq_df["answer"].tolist()
17
 
18
+ model = SentenceTransformer(MODEL_NAME)
19
+ question_embs = model.encode(
20
+ questions, convert_to_tensor=True, normalize_embeddings=True
21
+ )
22
+
23
+ # ─────────── tiny emoji tagger ───────────
24
+ EMOJI_RULES = {
25
+ r"\b(shampoo|conditioner|mask)\b" : "🧴",
26
+ r"\b(hair\s?spray|spray)\b" : "πŸ’¨",
27
+ r"\b(vegan|botanical|organic)\b" : "🌱",
28
+ r"\b(heat|thermal)\b" : "πŸ”₯",
29
+ r"\b(balayage|color|colour|dye)\b" : "πŸ’‡β€β™€οΈ",
30
+ r"\b(scissors|cut|trim)\b" : "βœ‚οΈ",
31
+ }
32
+ def tag_emoji(text: str) -> str:
33
+ for pat, emo in EMOJI_RULES.items():
34
+ if re.search(pat, text, flags=re.I):
35
+ return emo
36
+ return "❓"
37
+
38
+ # ─────────── search fn ───────────
39
+ def search_faq(query: str, top_k: int):
40
+ if not query.strip():
41
+ return pd.DataFrame(columns=["Emoji", "Question", "Answer", "Score"])
42
+ q_emb = model.encode(query, convert_to_tensor=True, normalize_embeddings=True)
43
+ scores = util.cos_sim(q_emb, question_embs)[0]
44
+ idx_list = scores.topk(k=top_k).indices.cpu().tolist()
45
+ rows = [
46
+ [tag_emoji(answers[i]), questions[i], answers[i], round(float(scores[i]), 3)]
47
+ for i in idx_list
48
+ ]
49
+ return pd.DataFrame(rows, columns=["Emoji", "Question", "Answer", "Score"])
50
+
51
+ # ─────────── gradio ui ───────────
52
+ with gr.Blocks(theme=gr.themes.Soft(), title="Semantic FAQ Search") as demo:
53
+ gr.Markdown("# πŸ” Semantic FAQ Search")
54
  with gr.Row():
55
+ inp = gr.Textbox(label="Ask a question", lines=2,
56
+ placeholder="e.g. Which spray protects hair from heat?")
57
+ k = gr.Slider(1, 5, value=3, step=1, label="Number of results")
58
+ btn = gr.Button("Search", variant="primary")
59
+ table = gr.Dataframe(headers=["Emoji", "Question", "Answer", "Score"],
60
+ datatype=["str", "str", "str", "number"],
61
+ wrap=True, interactive=False)
62
+ btn.click(search_faq, [inp, k], table)
 
 
 
63
 
64
  if __name__ == "__main__":
65
+ demo.launch(server_name="0.0.0.0")