cwinkler commited on
Commit
3cbd6c7
·
verified ·
1 Parent(s): d50ca3b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -101
app.py CHANGED
@@ -1,101 +1,103 @@
1
- # app.py — Hugging Face Space (Gradio) using a prebuilt Chroma index
2
- # Embeddings: nomic-ai/nomic-embed-text-v1.5 (HF), trust_remote_code=True, normalize_embeddings=True
3
-
4
- import os
5
- import gradio as gr
6
-
7
- # Silence Chroma telemetry noise
8
- os.environ["CHROMA_TELEMETRY_DISABLED"] = "1"
9
-
10
- from chromadb.config import Settings
11
- from langchain_chroma import Chroma
12
- from langchain_community.embeddings import HuggingFaceEmbeddings
13
-
14
- # -------- Config (can be overridden via Space "Variables") --------
15
- PERSIST_DIR = os.getenv("PERSIST_DIR", "./chroma_langchain") # path to your committed Chroma index
16
- EMB_MODEL = os.getenv("EMB_MODEL", "nomic-ai/nomic-embed-text-v1.5")
17
- TOPK_DEF = int(os.getenv("TOPK", "5"))
18
-
19
- # Embedding function for query text — must match the model used to build the index
20
- EMBEDDINGS = HuggingFaceEmbeddings(
21
- model_name=EMB_MODEL,
22
- model_kwargs={"trust_remote_code": True},
23
- encode_kwargs={"normalize_embeddings": True},
24
- )
25
-
26
- def load_vector_store():
27
- """
28
- Load the persisted Chroma collection with the embedding function for query-time encoding.
29
- Returns (vs, error_message_or_None)
30
- """
31
- try:
32
- vs = Chroma(
33
- persist_directory=PERSIST_DIR,
34
- embedding_function=EMBEDDINGS,
35
- client_settings=Settings(anonymized_telemetry=False),
36
- )
37
- # sanity check (forces collection open)
38
- _ = vs._collection.count()
39
- return vs, None
40
- except Exception as e:
41
- # Helpful diagnostics: list available collections
42
- try:
43
- import chromadb
44
- client = chromadb.PersistentClient(
45
- path=PERSIST_DIR, settings=Settings(anonymized_telemetry=False)
46
- )
47
- existing = [c.name for c in client.list_collections()]
48
- except Exception:
49
- existing = []
50
- msg = (
51
- f"Failed to load Chroma store at '{PERSIST_DIR}'. "
52
- f"Existing collections: {existing or '—'}. "
53
- "Check that the index folder is present in the Space and the collection name matches."
54
- )
55
- return None, f"{msg}\n\nDetails: {e}"
56
-
57
- VS, LOAD_ERR = load_vector_store()
58
-
59
- def search(query: str, k: int = TOPK_DEF):
60
- if LOAD_ERR:
61
- return f"⚠️ {LOAD_ERR}"
62
- q = (query or "").strip()
63
- if not q:
64
- return "Please enter a query."
65
- try:
66
- results = VS.similarity_search_with_score(q, k=int(k))
67
- except Exception as e:
68
- return f"Search failed: {e}"
69
- if not results:
70
- return "No results."
71
-
72
- lines = [f"### Top {len(results)} results"]
73
- for i, (doc, score) in enumerate(results, 1):
74
- meta = doc.metadata or {}
75
- src = meta.get("source") or meta.get("file_path") or "(no source)"
76
- snippet = (doc.page_content[:800] + "…") if len(doc.page_content) > 800 else doc.page_content
77
- lines.append(f"**[{i}]** \nSimilarity: `{score:.4f}`\n\n> {snippet}")
78
- lines.append("\n> **Disclaimer:** Models can produce incorrect or misleading statements. Verify with sources.")
79
- return "\n\n".join(lines)
80
-
81
- with gr.Blocks(title="Semantische Suchmaschine für BGH Leitsatzentscheidungen v0.1") as demo:
82
- gr.Markdown(
83
- """
84
- ## Semantische Suchmaschine für BGH Leitsatzentscheidungen v0.1
85
- Datensatz: **21.603 Leitsatzentscheidungen des BGH (ab dem Jahr 2000) extrahiert aus https://zenodo.org/records/15153244**
86
-
87
- **Wie es funktioniert:** Ermöglicht die semantische Suche im Datensatz und gibt die Entscheidungen geordnet nach Ähnlichkeitswerten zurück.
88
-
89
- **Versuche bespielsweise:**
90
- - `Kann KI Erfinder sein?` → erwartetes Aktenzeichen **X ZB 5/22**
91
-
92
- *Disclaimer:* Models may produce incorrect or misleading statements. Verify with sources.
93
- """
94
- )
95
- with gr.Row():
96
- q = gr.Textbox(label="Query", placeholder="Kann KI Erfinder sein?")
97
- k = gr.Slider(1, 20, value=TOPK_DEF, step=1, label="Top-K")
98
- out = gr.Markdown()
99
- gr.Button("Search").click(fn=search, inputs=[q, k], outputs=[out])
100
-
101
- demo.launch()
 
 
 
1
+ # app.py — Hugging Face Space (Gradio) using a prebuilt Chroma index
2
+ # Embeddings: nomic-ai/nomic-embed-text-v1.5 (HF), trust_remote_code=True, normalize_embeddings=True
3
+
4
+ import os
5
+ import gradio as gr
6
+
7
+ # Silence Chroma telemetry noise
8
+ os.environ["CHROMA_TELEMETRY_DISABLED"] = "1"
9
+
10
+ from chromadb.config import Settings
11
+ from langchain_chroma import Chroma
12
+ from langchain_community.embeddings import HuggingFaceEmbeddings
13
+
14
+ # -------- Config (can be overridden via Space "Variables") --------
15
+ PERSIST_DIR = os.getenv("PERSIST_DIR", "./chroma_langchain") # path to your committed Chroma index
16
+ EMB_MODEL = os.getenv("EMB_MODEL", "nomic-ai/nomic-embed-text-v1.5")
17
+ TOPK_DEF = int(os.getenv("TOPK", "5"))
18
+
19
+ # Embedding function for query text — must match the model used to build the index
20
+ EMBEDDINGS = HuggingFaceEmbeddings(
21
+ model_name=EMB_MODEL,
22
+ model_kwargs={"trust_remote_code": True},
23
+ encode_kwargs={"normalize_embeddings": True},
24
+ )
25
+
26
+ def load_vector_store():
27
+ """
28
+ Load the persisted Chroma collection with the embedding function for query-time encoding.
29
+ Returns (vs, error_message_or_None)
30
+ """
31
+ try:
32
+ vs = Chroma(
33
+ persist_directory=PERSIST_DIR,
34
+ embedding_function=EMBEDDINGS,
35
+ client_settings=Settings(anonymized_telemetry=False),
36
+ )
37
+ # sanity check (forces collection open)
38
+ _ = vs._collection.count()
39
+ return vs, None
40
+ except Exception as e:
41
+ # Helpful diagnostics: list available collections
42
+ try:
43
+ import chromadb
44
+ client = chromadb.PersistentClient(
45
+ path=PERSIST_DIR, settings=Settings(anonymized_telemetry=False)
46
+ )
47
+ existing = [c.name for c in client.list_collections()]
48
+ except Exception:
49
+ existing = []
50
+ msg = (
51
+ f"Failed to load Chroma store at '{PERSIST_DIR}'. "
52
+ f"Existing collections: {existing or '—'}. "
53
+ "Check that the index folder is present in the Space and the collection name matches."
54
+ )
55
+ return None, f"{msg}\n\nDetails: {e}"
56
+
57
+ VS, LOAD_ERR = load_vector_store()
58
+
59
+ def search(query: str, k: int = TOPK_DEF):
60
+ if LOAD_ERR:
61
+ return f"⚠️ {LOAD_ERR}"
62
+ q = (query or "").strip()
63
+ if not q:
64
+ return "Please enter a query."
65
+ try:
66
+ results = VS.similarity_search_with_score(q, k=int(k))
67
+ except Exception as e:
68
+ return f"Search failed: {e}"
69
+ if not results:
70
+ return "No results."
71
+
72
+ lines = [f"### Top {len(results)} results"]
73
+ for i, (doc, score) in enumerate(results, 1):
74
+ meta = doc.metadata or {}
75
+ src = meta.get("source") or meta.get("file_path") or "(no source)"
76
+ snippet = (doc.page_content[:800] + "…") if len(doc.page_content) > 800 else doc.page_content
77
+ lines.append(f"**[{i}]** \nSimilarity: `{score:.4f}`\n\n> {snippet}")
78
+ lines.append("\n> **Disclaimer:** Models can produce incorrect or misleading statements. Verify with sources.")
79
+ return "\n\n".join(lines)
80
+
81
+ with gr.Blocks(title="Semantische Suchmaschine für BGH Leitsatzentscheidungen v0.1") as demo:
82
+ gr.Markdown(
83
+ """
84
+ ## Semantische Suchmaschine für BGH Leitsatzentscheidungen v0.1
85
+ **Datensatz: 21.603 Leitsatzentscheidungen des BGH (ab dem Jahr 2000) extrahiert aus https://zenodo.org/records/15153244**
86
+
87
+ **Modell:** nomic-ai/nomic-embed-text-v1.5
88
+
89
+ **Wie es funktioniert:** Ermöglicht die semantische Suche im Datensatz und gibt die Entscheidungen geordnet nach Ähnlichkeitswerten zurück.
90
+
91
+ **Versuche bespielsweise:**
92
+ - `Kann KI Erfinder sein?` erwartetes Aktenzeichen **X ZB 5/22**
93
+
94
+ *Disclaimer:* Models may produce incorrect or misleading statements. Verify with sources.
95
+ """
96
+ )
97
+ with gr.Row():
98
+ q = gr.Textbox(label="Query", placeholder="Kann KI Erfinder sein?")
99
+ k = gr.Slider(1, 20, value=TOPK_DEF, step=1, label="Top-K")
100
+ out = gr.Markdown()
101
+ gr.Button("Search").click(fn=search, inputs=[q, k], outputs=[out])
102
+
103
+ demo.launch()