to-be commited on
Commit
b7f4192
·
verified ·
1 Parent(s): 19ab65f

Upload 4 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ Codex_over_het_welzijn_op_het_werk.pdf filter=lfs diff=lfs merge=lfs -text
37
+ codex-e5-base.db filter=lfs diff=lfs merge=lfs -text
Codex_over_het_welzijn_op_het_werk.pdf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:27575cae547a176ebf94bc59658bed2338cf8fdd5386eb39f257a3918a2254b6
3
+ size 5611790
app.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from pathlib import Path
3
+ from tempfile import mkdtemp
4
+
5
+ import gradio as gr
6
+ from docling_haystack.converter import ExportType
7
+ from dotenv import load_dotenv
8
+
9
+ from docling_haystack.converter import DoclingConverter
10
+ from haystack import Pipeline
11
+ from haystack.components.embedders import (
12
+ SentenceTransformersDocumentEmbedder,
13
+ SentenceTransformersTextEmbedder,
14
+ )
15
+ from haystack.components.preprocessors import DocumentSplitter
16
+ from haystack.components.writers import DocumentWriter
17
+ from milvus_haystack import MilvusDocumentStore, MilvusEmbeddingRetriever
18
+ from docling.chunking import DocChunk, HybridChunker
19
+ from haystack.components.builders import AnswerBuilder
20
+ from haystack.components.builders.prompt_builder import PromptBuilder
21
+ from haystack.components.generators import HuggingFaceAPIGenerator
22
+ from haystack.utils import Secret
23
+
24
+ def _get_env_from_colab_or_os(key):
25
+ try:
26
+ from google.colab import userdata
27
+
28
+ try:
29
+ return userdata.get(key)
30
+ except userdata.SecretNotFoundError:
31
+ pass
32
+ except ImportError:
33
+ pass
34
+ return os.getenv(key)
35
+
36
+ load_dotenv()
37
+ HF_TOKEN = _get_env_from_colab_or_os("HF_TOKEN")
38
+ PATHS = ["Codex_over_het_welzijn_op_het_werk.pdf"] # Docling Technical Report
39
+ EMBED_MODEL_ID = "intfloat/multilingual-e5-base" # sentence-transformers/all-MiniLM-L6-v2"
40
+ EXPORT_TYPE = ExportType.DOC_CHUNKS
41
+ TOP_K = 3
42
+ MILVUS_URI = str("codex-e5-base.db")
43
+
44
+ document_store = MilvusDocumentStore(
45
+ connection_args={"uri": MILVUS_URI},
46
+ drop_old=False,
47
+ text_field="txt", # set for preventing conflict with same-name metadata field
48
+ )
49
+
50
+ prompt_template = """
51
+ Beantwoord de vraag met behulp van volgende documenten.
52
+ Documenten:
53
+ {% for doc in documents %}
54
+ {{ doc.content }}
55
+ {% endfor %}
56
+ Vraag: {{query}}
57
+ Antwoord:
58
+ """
59
+
60
+ def create_rag_pipeline(model_id):
61
+ rag_pipe = Pipeline()
62
+ rag_pipe.add_component(
63
+ "embedder",
64
+ SentenceTransformersTextEmbedder(model=EMBED_MODEL_ID),
65
+ )
66
+ rag_pipe.add_component(
67
+ "retriever",
68
+ MilvusEmbeddingRetriever(document_store=document_store, top_k=TOP_K),
69
+ )
70
+ rag_pipe.add_component("prompt_builder", PromptBuilder(template=prompt_template))
71
+ rag_pipe.add_component(
72
+ "llm",
73
+ HuggingFaceAPIGenerator(
74
+ api_type="serverless_inference_api",
75
+ api_params={"model": model_id},
76
+ token=Secret.from_token(HF_TOKEN) if HF_TOKEN else None,
77
+ ),
78
+ )
79
+ rag_pipe.add_component("answer_builder", AnswerBuilder())
80
+ rag_pipe.connect("embedder.embedding", "retriever")
81
+ rag_pipe.connect("retriever", "prompt_builder.documents")
82
+ rag_pipe.connect("prompt_builder", "llm")
83
+ rag_pipe.connect("llm.replies", "answer_builder.replies")
84
+ rag_pipe.connect("llm.meta", "answer_builder.meta")
85
+ rag_pipe.connect("retriever", "answer_builder.documents")
86
+ return rag_pipe
87
+
88
+ def answer_question(question, selected_model_id):
89
+ rag_pipe = create_rag_pipeline(selected_model_id)
90
+ rag_res = rag_pipe.run(
91
+ {
92
+ "embedder": {"text": question},
93
+ "prompt_builder": {"query": question},
94
+ "answer_builder": {"query": question},
95
+ }
96
+ )
97
+
98
+ answer = rag_res['answer_builder']['answers'][0].data.strip()
99
+ sources = rag_res["answer_builder"]["answers"][0].documents
100
+
101
+ sources_info = []
102
+ for source in sources:
103
+ if EXPORT_TYPE == ExportType.DOC_CHUNKS:
104
+ doc_chunk = DocChunk.model_validate(source.meta["dl_meta"])
105
+ sources_info.append(f"*** text: {doc_chunk.text}")
106
+ if doc_chunk.meta.origin:
107
+ sources_info.append(f" file: {doc_chunk.meta.origin.filename}")
108
+ if doc_chunk.meta.headings:
109
+ sources_info.append(f" section: {' / '.join(doc_chunk.meta.headings)}")
110
+ bbox = doc_chunk.meta.doc_items[0].prov[0].bbox
111
+ sources_info.append(
112
+ f" page: {doc_chunk.meta.doc_items[0].prov[0].page_no}, "
113
+ f" bounding box: [{int(bbox.l)}, {int(bbox.t)}, {int(bbox.r)}, {int(bbox.b)}]"
114
+ )
115
+ elif EXPORT_TYPE == ExportType.MARKDOWN:
116
+ sources_info.append(repr(source.content))
117
+ else:
118
+ raise ValueError(f"Unexpected export type: {EXPORT_TYPE}")
119
+
120
+ return answer, str("\n".join(sources_info))
121
+
122
+ def main():
123
+ with gr.Blocks() as demo:
124
+ gr.Markdown('''<sub><sup>(english explanation below)</sup></sub>
125
+
126
+ **RAG met codex welzijn op het werk**
127
+
128
+ Deze app biedt een slimme manier om specifieke vragen te stellen over de **[Codex over het welzijn op het werk](https://huggingface.co/spaces/to-be/chat_met_codex_over_het_welzijn_op_het_werk/resolve/main/Codex_over_het_welzijn_op_het_werk.pdf)**, een Belgische wetgeving die de veiligheid, gezondheid en het welzijn van werknemers regelt. De codex bestaat uit 10 boeken die diverse aspecten van arbeidsomstandigheden behandelen, zoals preventie van psychosociale risico's, gezondheidstoezicht en eerste hulp. Dit kan een hulp zijn voor preventieadviseurs en werkpleksveiligheidsdeskundigen.
129
+
130
+ ''')
131
+
132
+ with gr.Row():
133
+ question_input = gr.Textbox(label="Vraag", value="Mag een werkgever zelf een asbestinventaris maken voor zijn bedrijf?")
134
+ with gr.Row():
135
+ sample_questions = gr.Dropdown(
136
+ label="Voorbeeldvragen",
137
+ choices=[
138
+ "Mag een werkgever zelf een asbestinventaris maken voor zijn bedrijf?",
139
+ "Rangschik volgende beschermingsmaatregelen volgens prioriteit:\n3. A. Organisatorische maatregelen: opleidingen, procedures, werkvergunningen, …\n2. B. Risico’s verminderen met collectieve beschermingsmiddelen zoals relingen\n1. C. Substitutie van het gevaar: bv. een gevaarlijk chemisch product vervangen door een minder gevaarlijke stof\n4. D. Persoonlijke beschermingsmiddelen: denk aan een veiligheidsharnas",
140
+ "Wat is geen taak van de Interne Dienst voor Preventie en Bescherming op het Werk (IDPBW)? Kies 1 van volgende opties:\nA: Risico's onderzoeken en advies geven over de risico-evaluatie\nB: Advies geven over arbeidshygiëne\nC: Werk-privébalans voor werknemers bewaken\nD: Policies rond telewerken goedkeuren\nE: Werkinstructies opstellen"
141
+ ],
142
+ value="Mag een werkgever zelf een asbestinventaris maken voor zijn bedrijf?"
143
+ )
144
+ with gr.Row(equal_height=True):
145
+ model_dropdown = gr.Dropdown(
146
+ label="Selecteer generatie model",
147
+ choices=[
148
+ "01-ai/Yi-1.5-34B-Chat",
149
+ "mistralai/Mixtral-8x7B-Instruct-v0.1",
150
+ "mistralai/Mistral-Nemo-Instruct-2407",
151
+ "Qwen/Qwen2.5-72B-Instruct",
152
+ "microsoft/Phi-3.5-mini-instruct"
153
+ ],
154
+ value="microsoft/Phi-3.5-mini-instruct"
155
+ )
156
+ send_button = gr.Button("Send")
157
+ with gr.Row():
158
+ answer_output = gr.Textbox(label="Antwoord")
159
+ sources_output = gr.Textbox(label="Bronnen")
160
+
161
+ gr.Markdown("<sub><sup>LLM kan fouten maken. Dubbelcheck belangrijke informatie</sup></sub>")
162
+ gr.Markdown('''
163
+
164
+
165
+ **Hoe werkt de app?**
166
+
167
+ De app maakt gebruik van **Retrieval-Augmented Generation (RAG)** om specifieke vragen te beantwoorden op basis van de inhoud van de codex. De gebruiker kan een vraag stellen via een eenvoudige interface en krijgt een antwoord met **relevante bronnen** uit de codex.
168
+
169
+
170
+ **Technologieën die zijn gebruikt:**
171
+
172
+ - **Docling**: Voor het converteren en indexeren van de documenten.
173
+ - **Haystack**: Voor het bouwen van de RAG-pipeline.
174
+ - **Hugging Face Inference API**: Voor het genereren van antwoorden via AI.
175
+ - **Gradio**: Voor het bouwen van de gebruikersinterface.
176
+
177
+ **Verbeteringen:**
178
+
179
+ - Het embedding-model is gewijzigd van `sentence-transformers/all-MiniLM-L6-v2` naar `intfloat/multilingual-e5-base` vanwege betere prestaties in multilinguïsme, vooral voor het Nederlands.
180
+ - Je hebt keuze tussen verschillende LLM's, met persoonlijke voorkeur voor **Phi-3.5-mini-instruct.**
181
+
182
+ This demo provides a smart way to ask specific questions about the **Codex on Well-Being at Work**, a Belgian legislation that regulates the safety, health, and well-being of employees. The codex consists of 10 books that cover various aspects of working conditions, such as prevention of psychosocial risks, health monitoring, and first aid. This can be a help for prevention advisors and workplace safety professionals.
183
+
184
+ **How does the app work?**
185
+
186
+ The app uses **Retrieval-Augmented Generation (RAG)** to answer specific questions based on the content of the codex. The user can ask a question through a simple interface and receives an answer with **relevant sources** from the codex.
187
+
188
+ **Technologies used:**
189
+
190
+ - **Docling**: For converting and indexing the documents.
191
+ - **Haystack**: For building the RAG pipeline.
192
+ - **Hugging Face Inference API**: For generating answers via AI.
193
+ - **Gradio**: For building the user interface.
194
+
195
+ **Improvements:**
196
+
197
+ - The embedding model was changed from `sentence-transformers/all-MiniLM-L6-v2` to `intfloat/multilingual-e5-base` for better performance in multilingualism, especially for Dutch.
198
+ - You have the option to choose between different LLMs, with a personal preference for **Phi-3.5-mini-instruct**.
199
+
200
+
201
+ Comments / questions can be directed to [[email protected]](mailto:[email protected]?subject=to-be/chat_met_codex_over_het_welzijn_op_het_werk)
202
+
203
+ ''')
204
+ gr.HTML('''<a href="https://visitorbadge.io/status?path=chat_met_codex_over_het_welzijn_op_het_werk"><img src="https://api.visitorbadge.io/api/combined?path=chat_met_codex_over_het_welzijn_op_het_werk&countColor=%23263759" /></a>''')
205
+ sample_questions.change(lambda x: x, inputs=sample_questions, outputs=question_input)
206
+ send_button.click(answer_question, inputs=[question_input, model_dropdown], outputs=[answer_output, sources_output])
207
+ question_input.submit(answer_question, inputs=[question_input, model_dropdown], outputs=[answer_output, sources_output])
208
+
209
+ demo.launch()
210
+
211
+ if __name__ == "__main__":
212
+ main()
codex-e5-base.db ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7c2c13a57847ac1aa6831cea140f348944d56c4127130fe04f10d30e1f9f1943
3
+ size 13680640
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ docling-haystack
2
+ haystack-ai
3
+ docling
4
+ pymilvus
5
+ milvus-haystack
6
+ sentence-transformers