tomas.helmfridsson commited on
Commit
babd2a7
Β·
1 Parent(s): 30881d9
Files changed (1) hide show
  1. app.py +58 -75
app.py CHANGED
@@ -11,18 +11,13 @@ from langchain_huggingface.llms import HuggingFacePipeline
11
  from langchain.chains import RetrievalQA
12
  from langchain.text_splitter import RecursiveCharacterTextSplitter
13
 
14
- # ── 1) Setup logging ───────────────────────────────────────────
15
- logging.basicConfig(
16
- format="%(asctime)s %(levelname)s %(message)s",
17
- level=logging.INFO
18
- )
19
- # GΓΆr Transformers mer detaljerade i loggarna
20
- hf_logging.set_verbosity_debug()
21
-
22
- # ── 2) Ladda & chunka PDF:er ────────────────────────────────────
23
  all_docs, files = [], []
24
  splitter = RecursiveCharacterTextSplitter(chunk_size=250, chunk_overlap=30)
25
-
26
  for fn in os.listdir("document"):
27
  if fn.lower().endswith(".pdf"):
28
  path = os.path.join("document", fn)
@@ -31,114 +26,102 @@ for fn in os.listdir("document"):
31
  chunks = splitter.split_documents(pages)
32
  all_docs.extend(chunks)
33
  files.append(fn)
 
34
 
35
- logging.info(f"βœ… Laddade och chunkade {len(files)} PDF:er β†’ totalt {len(all_docs)} chunkar")
36
-
37
- # ── 3) Skapa embedding + FAISS───────────────────────────────────
38
  emb = HuggingFaceEmbeddings(model_name="KBLab/sentence-bert-swedish-cased")
39
  vs = FAISS.from_documents(all_docs, emb)
40
  logging.info("βœ… FAISS-vektorstore skapat")
41
 
42
- # ── 4) Initiera CPU-pipeline fΓΆr Falcon-1B───────────────────────
43
- pipe = pipeline(
44
- "text-generation",
45
- model="tiiuae/falcon-rw-1b",
46
- device=-1,
47
- max_new_tokens=64
48
- )
49
- llm = HuggingFacePipeline(
50
- pipeline=pipe,
51
- model_kwargs={"temperature": 0.3}
52
- )
53
- logging.info("βœ… LLM-pipeline initierad (CPU, max_new_tokens=64)")
54
-
55
- # ── 5) Bygg RetrievalQA med bara 1 chunk───────────────────────
56
- retriever = vs.as_retriever(search_kwargs={"k": 1})
57
- qa = RetrievalQA.from_chain_type(
58
- llm=llm,
59
- retriever=retriever,
60
- chain_type="stuff"
61
- )
62
- logging.info("βœ… RetrievalQA-kedja skapad (k=1)")
63
-
64
- # ── 6) Ping-funktion fΓΆr sanity-check────────────────────────────
65
  def ping():
66
  logging.info("πŸ“ Ping mottagen")
67
  return "pong"
68
 
69
- # ── 7) Chat-funktion som returnerar list-of-tuples────────────────
 
 
 
 
 
 
 
 
 
 
 
70
  def chat_fn(message, temperature, history):
71
- start_time = time.time()
72
  history = history or []
73
  logging.info(f"β†’ chat_fn start – message={message!r}, temp={temperature}")
74
 
75
- # Tom frΓ₯ga?
76
  if not message.strip():
77
- history.append(("assistant", "⚠️ Du mΓ₯ste skriva en frΓ₯ga."))
78
- logging.info("← chat_fn exit – tom frΓ₯ga")
79
  return history, history
80
 
81
- # LΓ€gg till anvΓ€ndarens frΓ₯ga
82
  history.append(("user", message))
83
-
84
- # FΓΆr lΓ₯ng frΓ₯ga?
85
  if len(message) > 1000:
86
- warn = f"⚠️ FrΓ₯gan Γ€r fΓΆr lΓ₯ng ({len(message)} tecken)."
87
- history.append(("assistant", warn))
88
- logging.info("← chat_fn exit – fΓΆr lΓ₯ng frΓ₯ga")
89
  return history, history
90
 
91
- # Justera temperatur
92
  llm.model_kwargs["temperature"] = temperature
93
 
94
- # Retrieval
95
  t0 = time.time()
96
  docs = retriever.get_relevant_documents(message)
97
- logging.info(f" πŸ” Retrieval tog {time.time() - t0:.2f}s, hittade {len(docs)} docs")
98
 
99
- # Inference
100
  t1 = time.time()
101
  try:
102
- result = qa.invoke({"query": message})["result"]
103
- logging.info(f" πŸ€– QA.invoke tog {time.time() - t1:.2f}s")
104
  except Exception as e:
105
  logging.exception("❌ Fel i QA.invoke")
106
- result = f"Fel vid QA: {e}"
107
-
108
- # LΓ€gg till svaret
109
- history.append(("assistant", result))
110
 
111
- logging.info(f"← chat_fn klar pΓ₯ {time.time() - start_time:.2f}s med {len(history)} meddelanden")
 
112
  return history, history
113
 
114
- # ── 8) Bygg Gradio-UI & lansera publicerat────────────────────────
115
  with gr.Blocks() as demo:
116
  gr.Markdown("# 🌟 Dokumentassistent (Svenska)")
117
- gr.Markdown("**βœ… Laddade PDF-filer:**\n\n" + "\n".join(f"- {f}" for f in files))
118
 
119
  with gr.Row():
120
- # Ping-test
121
  ping_btn = gr.Button("πŸ“ Ping")
122
  ping_out = gr.Textbox(label="Ping-svar")
123
 
124
- # RAG-chat
125
- txt = gr.Textbox(lines=2, label="Din frΓ₯ga:", placeholder="Ex: Vad anges fΓΆr krav?")
126
- temp = gr.Slider(0.0, 1.0, value=0.3, step=0.05, label="Temperatur")
127
- send = gr.Button("πŸ“¨ Skicka")
 
 
 
 
128
 
129
- chatbot = gr.Chatbot() # default == tuple-format
 
130
  chat_state = gr.State([])
131
 
132
- # Koppla Ping
133
  ping_btn.click(fn=ping, inputs=[], outputs=[ping_out])
134
-
135
- # Koppla chat
136
- send.click(
137
- fn=chat_fn,
138
- inputs=[txt, temp, chat_state],
139
- outputs=[chatbot, chat_state]
140
- )
141
 
142
  if __name__ == "__main__":
143
  demo.launch(share=True)
144
-
 
11
  from langchain.chains import RetrievalQA
12
  from langchain.text_splitter import RecursiveCharacterTextSplitter
13
 
14
+ # ── 1) Logging ─────────────────────────────────────────────────
15
+ logging.basicConfig(format="%(asctime)s %(levelname)s %(message)s", level=logging.INFO)
16
+ hf_logging.set_verbosity_debug() # SΓ€tt HF-transformers till debug
17
+
18
+ # ── 2) Ladda & chunk-pdf:er ────────────────────────────────────
 
 
 
 
19
  all_docs, files = [], []
20
  splitter = RecursiveCharacterTextSplitter(chunk_size=250, chunk_overlap=30)
 
21
  for fn in os.listdir("document"):
22
  if fn.lower().endswith(".pdf"):
23
  path = os.path.join("document", fn)
 
26
  chunks = splitter.split_documents(pages)
27
  all_docs.extend(chunks)
28
  files.append(fn)
29
+ logging.info(f"βœ… {len(files)} PDF:er laddade β†’ {len(all_docs)} chunkar totalt")
30
 
31
+ # ── 3) Bygg FAISS med svenska embeddings ────────────────────────
 
 
32
  emb = HuggingFaceEmbeddings(model_name="KBLab/sentence-bert-swedish-cased")
33
  vs = FAISS.from_documents(all_docs, emb)
34
  logging.info("βœ… FAISS-vektorstore skapat")
35
 
36
+ # ── 4) Initiera Falcon-1B CPU-pipeline ─────────────────────────
37
+ pipe = pipeline("text-generation", model="tiiuae/falcon-rw-1b", device=-1, max_new_tokens=64)
38
+ llm = HuggingFacePipeline(pipeline=pipe, model_kwargs={"temperature":0.3})
39
+ logging.info("βœ… LLM-pipeline initierad")
40
+
41
+ # ── 5) RetrievalQA (k=1) ───────────────────────────────────────
42
+ retriever = vs.as_retriever(search_kwargs={"k":1})
43
+ qa = RetrievalQA.from_chain_type(llm=llm, retriever=retriever, chain_type="stuff")
44
+ logging.info("βœ… RetrievalQA-kedja skapad")
45
+
46
+ # ── 6) Ping-funktion ───────────────────────────────────────────
 
 
 
 
 
 
 
 
 
 
 
 
47
  def ping():
48
  logging.info("πŸ“ Ping mottagen")
49
  return "pong"
50
 
51
+ # ── 7) Test-retrieval fΓΆr att se chunk-innehΓ₯ll ────────────────
52
+ def test_retrieval(query):
53
+ logging.info(f"πŸ”Ž Retrieval-test fΓΆr frΓ₯ga: {query!r}")
54
+ docs = retriever.get_relevant_documents(query)
55
+ if not docs:
56
+ return "🚫 Inga dokument trÀffades"
57
+ # Visa fΓΆrsta 200 tecken i fΓΆrsta chunk
58
+ snippet = docs[0].page_content[:200].replace("\n"," ")
59
+ logging.info(f" Hittade chunk: {snippet!r}")
60
+ return snippet
61
+
62
+ # ── 8) Chat-funktion ───────────────────────────────────────────
63
  def chat_fn(message, temperature, history):
64
+ start = time.time()
65
  history = history or []
66
  logging.info(f"β†’ chat_fn start – message={message!r}, temp={temperature}")
67
 
 
68
  if not message.strip():
69
+ history.append(("assistant","⚠️ Du mΓ₯ste skriva en frΓ₯ga."))
 
70
  return history, history
71
 
 
72
  history.append(("user", message))
73
+ # FΓΆr lΓ₯ng frΓ₯ga
 
74
  if len(message) > 1000:
75
+ history.append(("assistant", f"⚠️ FrΓ₯gan Γ€r fΓΆr lΓ₯ng ({len(message)} tecken)."))
 
 
76
  return history, history
77
 
 
78
  llm.model_kwargs["temperature"] = temperature
79
 
80
+ # Retrieval-timing
81
  t0 = time.time()
82
  docs = retriever.get_relevant_documents(message)
83
+ logging.info(f" πŸ” Retrieval tog {time.time()-t0:.2f}s, docs={len(docs)}")
84
 
85
+ # QA-inference
86
  t1 = time.time()
87
  try:
88
+ svar = qa.invoke({"query": message})["result"]
89
+ logging.info(f" πŸ€– QA.invoke tog {time.time()-t1:.2f}s")
90
  except Exception as e:
91
  logging.exception("❌ Fel i QA.invoke")
92
+ svar = f"Fel vid QA: {e}"
 
 
 
93
 
94
+ history.append(("assistant", svar))
95
+ logging.info(f"← chat_fn klar pΓ₯ {time.time()-start:.2f}s")
96
  return history, history
97
 
98
+ # ── 9) Bygg Gradio-UI & lansera publicerat ─────────────────────
99
  with gr.Blocks() as demo:
100
  gr.Markdown("# 🌟 Dokumentassistent (Svenska)")
101
+ gr.Markdown("**βœ… Laddade PDF-filer:** \n" + "\n".join(f"- {f}" for f in files))
102
 
103
  with gr.Row():
104
+ # Ping
105
  ping_btn = gr.Button("πŸ“ Ping")
106
  ping_out = gr.Textbox(label="Ping-svar")
107
 
108
+ # Test retrieval
109
+ test_btn = gr.Button("πŸ”Ž Testa Retrieval")
110
+ test_out = gr.Textbox(label="FΓΆrsta chunk-snippet")
111
+
112
+ # Chat
113
+ txt = gr.Textbox(lines=2, label="Din frΓ₯ga:")
114
+ temp = gr.Slider(0.0,1.0,value=0.3,step=0.05,label="Temperatur")
115
+ send = gr.Button("πŸ“¨ Skicka")
116
 
117
+ # Komponenter fΓΆr chat
118
+ chatbot = gr.Chatbot() # tuple-format
119
  chat_state = gr.State([])
120
 
121
+ # Kopplingar
122
  ping_btn.click(fn=ping, inputs=[], outputs=[ping_out])
123
+ test_btn.click(fn=test_retrieval, inputs=[txt], outputs=[test_out])
124
+ send.click(fn=chat_fn, inputs=[txt, temp, chat_state], outputs=[chatbot, chat_state])
 
 
 
 
 
125
 
126
  if __name__ == "__main__":
127
  demo.launch(share=True)