Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
from huggingface_hub import HfApi
|
| 3 |
+
|
| 4 |
+
api = HfApi()
|
| 5 |
+
|
| 6 |
+
# Minimalnie: twardo wpisane, stabilne propozycje (CPU-friendly) + ewentualnie dynamiczne "bonusy"
|
| 7 |
+
RECOMMENDATIONS = {
|
| 8 |
+
"instruction": [
|
| 9 |
+
("google/flan-t5-small", "Lekki text2text, dobry na CPU do poleceń i krótkich odpowiedzi."),
|
| 10 |
+
("google/flan-t5-base", "Lepsza jakość kosztem szybkości; nadal sensowne na CPU."),
|
| 11 |
+
("google-t5/t5-small", "Prosty fallback text2text, gdy chcesz klasykę i szybkość.")
|
| 12 |
+
],
|
| 13 |
+
"qa": [
|
| 14 |
+
("distilbert/distilbert-base-cased-distilled-squad", "Szybki QA extractive na CPU; klasyczny wybór."),
|
| 15 |
+
("distilbert/distilbert-base-uncased-distilled-squad", "Popularny model SQuAD; dobry default."),
|
| 16 |
+
("deepset/bert-base-cased-squad2", "SQuAD2; potrafi częściej zwrócić 'brak odpowiedzi'.")
|
| 17 |
+
],
|
| 18 |
+
"embeddings": [
|
| 19 |
+
("sentence-transformers/all-MiniLM-L6-v2", "Bardzo popularny do similarity search; szybki."),
|
| 20 |
+
("intfloat/e5-small-v2", "Silny embedding do wyszukiwania; dobry kompromis."),
|
| 21 |
+
("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", "Multilingual (lepszy przy PL/mix).")
|
| 22 |
+
],
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
def hub_bonus_models(pipeline_tag: str, limit: int = 5):
|
| 26 |
+
"""
|
| 27 |
+
Opcjonalnie: dociągaj popularne modele z Hub.
|
| 28 |
+
Uwaga: to zapytania sieciowe; jeśli wolisz offline, usuń ten fragment.
|
| 29 |
+
"""
|
| 30 |
+
try:
|
| 31 |
+
# huggingface_hub pozwala listować modele z filtrami (HfApi.list_models). :contentReference[oaicite:1]{index=1}
|
| 32 |
+
models = api.list_models(filter=pipeline_tag, sort="downloads", direction=-1, limit=limit)
|
| 33 |
+
out = []
|
| 34 |
+
for m in models:
|
| 35 |
+
if m.modelId:
|
| 36 |
+
out.append(m.modelId)
|
| 37 |
+
return out
|
| 38 |
+
except Exception:
|
| 39 |
+
return []
|
| 40 |
+
|
| 41 |
+
def recommend(task, has_docs, language, cpu_only, priority):
|
| 42 |
+
# Prosta logika decyzyjna
|
| 43 |
+
if task == "Semantyczne podobieństwo / duplikaty / wyszukiwanie":
|
| 44 |
+
model_type = "embeddings"
|
| 45 |
+
why = (
|
| 46 |
+
"Chcesz porównywać znaczenie wpisów i wykrywać duplikaty. "
|
| 47 |
+
"Do tego używa się embeddingów (wektorów) i miary podobieństwa (np. cosinus). "
|
| 48 |
+
"To nie jest generowanie tekstu."
|
| 49 |
+
)
|
| 50 |
+
pipeline_tag = "sentence-similarity"
|
| 51 |
+
elif task == "Odpowiedzi na pytania z dokumentu (tekst wejściowy)":
|
| 52 |
+
model_type = "qa"
|
| 53 |
+
why = (
|
| 54 |
+
"Masz kontekst (dokument/tekst) i pytanie. QA extractive znajduje odpowiedź w kontekście "
|
| 55 |
+
"i zwykle halucynuje rzadziej niż modele generatywne."
|
| 56 |
+
)
|
| 57 |
+
pipeline_tag = "question-answering"
|
| 58 |
+
else:
|
| 59 |
+
model_type = "instruction"
|
| 60 |
+
why = (
|
| 61 |
+
"Chcesz odpowiedzi 'z polecenia' (chat/wyjaśnianie/streszczanie). "
|
| 62 |
+
"Modele instrukcyjne są dostrajane do wykonywania instrukcji."
|
| 63 |
+
)
|
| 64 |
+
pipeline_tag = "text-generation"
|
| 65 |
+
|
| 66 |
+
# Zbuduj wynik: min. 3
|
| 67 |
+
recs = RECOMMENDATIONS[model_type].copy()
|
| 68 |
+
|
| 69 |
+
# Bonus: dociągnij popularne modele z Hub (nie obowiązkowe)
|
| 70 |
+
bonus = hub_bonus_models(pipeline_tag, limit=5)
|
| 71 |
+
# Usuń te, które już mamy
|
| 72 |
+
existing = {mid for mid, _ in recs}
|
| 73 |
+
bonus = [m for m in bonus if m not in existing]
|
| 74 |
+
# Dodaj 0–2 bonusy, ale nie kosztem czytelności
|
| 75 |
+
for m in bonus[:2]:
|
| 76 |
+
recs.append((m, "Popularny model z Hub (dobrany po tagu i pobraniach)."))
|
| 77 |
+
|
| 78 |
+
# Sformatuj odpowiedź
|
| 79 |
+
lines = []
|
| 80 |
+
lines.append(f"Rekomendowany typ modelu: {model_type}")
|
| 81 |
+
lines.append("")
|
| 82 |
+
lines.append("Uzasadnienie:")
|
| 83 |
+
lines.append(f"- {why}")
|
| 84 |
+
lines.append("")
|
| 85 |
+
lines.append("Minimum 3 pasujące modele:")
|
| 86 |
+
for mid, note in recs[:5]:
|
| 87 |
+
lines.append(f"- {mid} — {note}")
|
| 88 |
+
|
| 89 |
+
# Dodatkowe wskazówki „jak użyć” dla embeddings
|
| 90 |
+
if model_type == "embeddings":
|
| 91 |
+
lines.append("")
|
| 92 |
+
lines.append("Jak użyć do duplikatów (zarys):")
|
| 93 |
+
lines.append("- Policz embedding dla każdego wpisu.")
|
| 94 |
+
lines.append("- Porównuj podobieństwo cosinusowe.")
|
| 95 |
+
lines.append("- Ustal próg (np. 0.85–0.95) i grupuj podobne wpisy.")
|
| 96 |
+
lines.append("- W każdej grupie zostaw 1 rekord, resztę oznacz jako duplikaty.")
|
| 97 |
+
|
| 98 |
+
if language in ["PL", "Mieszany"]:
|
| 99 |
+
lines.append("")
|
| 100 |
+
lines.append("Uwaga językowa:")
|
| 101 |
+
lines.append("- Przy PL lub mieszanych językach preferuj model multilingual z listy.")
|
| 102 |
+
return "\n".join(lines)
|
| 103 |
+
|
| 104 |
+
with gr.Blocks(title="Model Fit Finder (CPU)") as demo:
|
| 105 |
+
gr.Markdown("# Model Fit Finder\nDobiera typ modelu i podaje konkretne propozycje (CPU).")
|
| 106 |
+
|
| 107 |
+
task = gr.Dropdown(
|
| 108 |
+
choices=[
|
| 109 |
+
"Chat / polecenia / generowanie",
|
| 110 |
+
"Odpowiedzi na pytania z dokumentu (tekst wejściowy)",
|
| 111 |
+
"Semantyczne podobieństwo / duplikaty / wyszukiwanie",
|
| 112 |
+
],
|
| 113 |
+
value="Semantyczne podobieństwo / duplikaty / wyszukiwanie",
|
| 114 |
+
label="Co chcesz zrobić?"
|
| 115 |
+
)
|
| 116 |
+
has_docs = gr.Radio(choices=["Tak", "Nie"], value="Tak", label="Czy masz własne dokumenty/teksty do analizy?")
|
| 117 |
+
language = gr.Radio(choices=["EN", "PL", "Mieszany"], value="Mieszany", label="Język danych")
|
| 118 |
+
cpu_only = gr.Checkbox(value=True, label="CPU only")
|
| 119 |
+
priority = gr.Radio(choices=["Szybkość", "Jakość"], value="Szybkość", label="Priorytet")
|
| 120 |
+
|
| 121 |
+
btn = gr.Button("Zarekomenduj")
|
| 122 |
+
out = gr.Textbox(lines=18, label="Wynik")
|
| 123 |
+
|
| 124 |
+
btn.click(
|
| 125 |
+
fn=recommend,
|
| 126 |
+
inputs=[task, has_docs, language, cpu_only, priority],
|
| 127 |
+
outputs=[out],
|
| 128 |
+
)
|
| 129 |
+
|
| 130 |
+
demo.launch()
|