-
Notifications
You must be signed in to change notification settings - Fork 1
wip: Integration #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
wip: Integration #23
Changes from all commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
ff3fe68
feat: cache huggingface models
rti 38a3bf9
fix: sentence_transformers version
rti 3fb6fd0
chore: remove custom model based on modelfile
rti a4c7294
fix(frontend): do not filter by score for now TBD
rti d38c5f0
chore: remove debug/test code
rti dc4501a
fix: required sentence_transformers version was actually > 2.2.0
rti 42cdcc5
docs: add notes about embedding models to readme
rti 13bc12e
chore: add debug output to api.py
rti 4933a9a
fix: question in prompt
rti b23833b
chore: top_k 3 results for now
rti da1017b
wip: embeddings cache
rti 41ff046
feat: document splitter
rti 4e69697
Update .dockerignore
exowanderer 10103c6
Merge branch 'main' into integration
rti 0ee6ed5
docs: note on how to dev locally
rti 7a2c955
docs: add research_log.md
rti 0a5e2be
feat: set top_k via api
rti 332e3dc
feat: support en and de on the api to switch prompts
rti 6225fcc
feat: cache embedding model during docker build
rti 4877807
wip: smaller chunk size, 5 sentences for now
rti da9859d
chore: remove comment
rti 291aaaf
feat: enable embeddings cache (for developmnet)
rti 936d83e
feat: add document cleaner
rti 1b88437
Merge branch 'main' into integration
rti 3e0b8f4
docs: long docker run options
rti edf5eb2
fix: access mode
rti 63baf2b
fix: redraw loading animation on subsequent searches
rti 56a7b8c
wip: workaround for runpod.io http port forwarding
rti 8e05473
feat: switch to openchat 7b model
rti 8276e35
Merge branch 'openchat' into integration
rti 22b04d0
added logging via logger with Handler to api.py; PEP8 formatted api.py
exowanderer 10f6b21
debugging use of homepage instead of hard coded endpoint values
exowanderer bfbd245
returning to previous to restart without errors
exowanderer 7b6ba0a
renewed app.mount; bug fixed PEP8 changes in api.py; reformatted rag.…
exowanderer 0428f87
returned to stablelm2 model for testing purposes. PEP8 upgrades in ap…
exowanderer 8104dde
added OLLAMA_MODEL_NAME and OLLAMA_URL as environment variables; call…
exowanderer fbc4591
created logger.py to serve get_logger to all modules
exowanderer caecfd1
created a rag_pipeline in the rag.py based on the usage in api.py; re…
exowanderer 5c0b4d0
UPdated with PEP8 formatting in vector_store_interface.py
exowanderer 8833af7
chore(Dockerfile): install python deps early
rti 9ee8a32
fix(sentence-transformers): use cuda if available
rti b2357e3
fix(frontend): run from webserver root
rti b518abf
feat: store embedding cache in volume
rti 69800b0
feat(start.sh): pull llm using ollama (if not built into container)
rti 7803649
feat(ollama): use chat api to leverage prompt templates
rti ff1fcab
docs: fix run cmd
rti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1 @@ | ||
| from .api import * | ||
| # from .haystack2beta_tutorial_InMemoryEmbeddingRetriever import * |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,71 +1,59 @@ | ||
| from fastapi.responses import RedirectResponse | ||
| from fastapi.responses import FileResponse | ||
| from fastapi.staticfiles import StaticFiles | ||
| from fastapi import FastAPI | ||
|
|
||
| # from .rag import rag_pipeline | ||
| from .rag import embedder, retriever, prompt_builder, llm, answer_builder | ||
| from .rag import rag_pipeline | ||
|
|
||
| from haystack import Document | ||
| from .logger import get_logger | ||
|
|
||
| # Create logger instance from base logger config in `logger.py` | ||
| logger = get_logger(__name__) | ||
|
|
||
| FRONTEND_STATIC_DIR = './frontend/dist' | ||
|
|
||
| app = FastAPI() | ||
|
|
||
| app.mount( | ||
| "/frontend/dist", | ||
| StaticFiles(directory="frontend/dist", html=True), | ||
| name="frontend" | ||
| "/assets", | ||
| StaticFiles(directory=f"{FRONTEND_STATIC_DIR}/assets"), | ||
| name="frontend-assets" | ||
| ) | ||
|
|
||
|
|
||
| @app.get("/") | ||
| async def root(): | ||
| return RedirectResponse(url="/frontend/dist", status_code=302) | ||
| return FileResponse(f"{FRONTEND_STATIC_DIR}/index.html") | ||
|
|
||
| @app.get("/favicon.ico") | ||
| async def favicon(): | ||
| return FileResponse(f"{FRONTEND_STATIC_DIR}/favicon.ico") | ||
|
|
||
| @app.get("/api") | ||
| async def api(q): | ||
|
|
||
| embedder, retriever, prompt_builder, llm, answer_builder | ||
|
|
||
| # query = "How many languages are there?" | ||
| query = Document(content=q) | ||
|
|
||
| result = embedder.run([query]) | ||
|
|
||
| results = retriever.run( | ||
| query_embedding=list(result['documents'][0].embedding), | ||
| filters=None, | ||
| top_k=None, | ||
| scale_score=None, | ||
| return_embedding=None | ||
| async def api(query, top_k=3, lang='en'): | ||
| if not lang in ['en', 'de']: | ||
| raise Exception("language must be 'en' or 'de'") | ||
|
|
||
| logger.debug(f'{query=}') # Assuming we change the input name | ||
| logger.debug(f'{top_k=}') | ||
| logger.debug(f'{lang=}') | ||
|
|
||
| answer = rag_pipeline( | ||
| query=query, | ||
| top_k=top_k, | ||
| lang=lang | ||
| ) | ||
| # .run( | ||
| # result['documents'][0].embedding | ||
| # ) | ||
|
|
||
| prompt = prompt_builder.run(documents=results['documents'])['prompt'] | ||
|
|
||
| response = llm.run(prompt=prompt, generation_kwargs=None) | ||
| # reply = response['replies'][0] | ||
|
|
||
| # rag_pipeline.connect("llm.replies", "answer_builder.replies") | ||
| # rag_pipeline.connect("llm.metadata", "answer_builder.meta") | ||
| # rag_pipeline.connect("retriever", "answer_builder.documents") | ||
|
|
||
| results = answer_builder.run( | ||
| query=q, | ||
| replies=response['replies'], | ||
| meta=response['meta'], | ||
| documents=results['documents'], | ||
| pattern=None, | ||
| reference_pattern=None | ||
| ) | ||
| sources = [ | ||
| { | ||
| "src": d_.meta['src'], | ||
| "content": d_.content, | ||
| "score": d_.score | ||
| } for d_ in answer.documents | ||
| ] | ||
|
|
||
| answer = results['answers'][0] | ||
| logger.debug(f'{answer=}') | ||
|
|
||
| return { | ||
| "answer": answer.data, | ||
| "sources": [{ | ||
| "src": d.meta['src'], | ||
| "content": d.content, | ||
| "score": d.score | ||
| } for d in answer.documents] | ||
| "answer": answer.data.content, | ||
| "sources": sources | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,23 @@ | ||
| import os | ||
| from haystack_integrations.components.generators.ollama import OllamaGenerator | ||
| from haystack_integrations.components.generators.ollama import OllamaChatGenerator | ||
|
|
||
| # TODO: discolm prompt https://huggingface.co/DiscoResearch/DiscoLM_German_7b_v1 | ||
| print(f"Setting up ollama with {os.getenv('MODEL')}") | ||
| llm = OllamaGenerator( | ||
| model=os.getenv("MODEL"), | ||
| url="http://localhost:11434/api/generate" | ||
| from .logger import get_logger | ||
|
|
||
| # Create logger instance from base logger config in `logger.py` | ||
| logger = get_logger(__name__) | ||
|
|
||
| OLLAMA_MODEL_NAME = os.environ.get("OLLAMA_MODEL_NAME") | ||
| OLLAMA_URL = os.environ.get("OLLAMA_URL") | ||
| OLLAMA_CHAT_URL = f"{OLLAMA_URL}/api/chat" | ||
|
|
||
| logger.info(f'Using {OLLAMA_MODEL_NAME=}') | ||
| logger.info(f'Endpoint: {OLLAMA_URL=}') | ||
| logger.info(f'Generate: {OLLAMA_CHAT_URL=}') | ||
|
|
||
| logger.info(f"Setting up ollama with {OLLAMA_MODEL_NAME}") | ||
|
|
||
| llm = OllamaChatGenerator( | ||
| model=OLLAMA_MODEL_NAME, | ||
| url=OLLAMA_CHAT_URL, | ||
| timeout=120 | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import logging | ||
| import sys | ||
|
|
||
|
|
||
| def get_logger(name): | ||
| # Create a logger | ||
| # Source: https://docs.python.org/3/howto/logging.html | ||
| logging.basicConfig( | ||
| filename='gbnc_api.log', | ||
| encoding='utf-8', | ||
| level=logging.DEBUG | ||
| ) | ||
|
|
||
| logger = logging.getLogger(name) | ||
| logger.setLevel(logging.DEBUG) # Set the logging level | ||
|
|
||
| # Source: stackoverflow.com/questions/14058453/ | ||
| # making-python-loggers-output-all-messages- | ||
| # to-stdout-in-addition-to-log-file | ||
|
|
||
| # Create console handler and set level to debug | ||
| handler = logging.StreamHandler(sys.stdout) | ||
| handler.setLevel(logging.DEBUG) | ||
| formatter = logging.Formatter( | ||
| '%(asctime)s - %(name)s - %(levelname)s - %(message)s' | ||
| ) | ||
| handler.setFormatter(formatter) | ||
| logger.addHandler(handler) | ||
|
|
||
| return logger |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,28 @@ | ||
| from haystack.components.builders.prompt_builder import PromptBuilder | ||
|
|
||
| # prompt_template = """ | ||
| # Given these documents, answer the question. Answer in a full sentence. Give the response only, no explanation. Don't mention the documents. | ||
| # Documents: | ||
| # {% for doc in documents %} | ||
| # If {{ doc.content }} answers the Question: {{question}} | ||
| # Then return {{ doc.meta["src"] }} | ||
| # {% endfor %} | ||
| # """ | ||
|
|
||
| prompt_template = """ | ||
| <|system|> | ||
| You are a helpful assistant. You answer questions based on the given documents. | ||
| Answer based on the documents only. If the information is not in the documents, | ||
| say that you cannot find the information. | ||
| <|endoftext|> | ||
| <|user|> | ||
| prompt_template_en = """ | ||
| Documents: | ||
| {% for doc in documents %} | ||
| {{ doc.content }} | ||
| {% for doc_ in documents %} | ||
| {{ doc_.content }} | ||
| {% endfor %} | ||
| With this documents, answer the following question: {{question}} | ||
| <|endoftext|> | ||
| <|assistant|> | ||
| """ | ||
|
|
||
| # prompt_template = """ | ||
| # Given these documents, answer the question. Answer in a full sentence. Give the response only, no explanation. Don't mention the documents. | ||
| # Documents: | ||
| # If {{ doc.content }} answers the Question: {{question}} | ||
| # Then only return {{ doc.meta["src"] }} and nothing at all. | ||
| # {% endfor %} | ||
| # """ | ||
| prompt_template_de = """ | ||
| Dokumente: | ||
| {% for doc_ in documents %} | ||
| {{ doc_.content }} | ||
| {% endfor %} | ||
| Mit diesen Dokumenten, beantworte die folgende Frage: {{question}} | ||
| """ | ||
|
|
||
| system_prompts = { | ||
| 'en': 'You are a helpful assistant. You answer questions based on the given documents. Answer based on the documents only. If the information is not in the documents, say that you cannot find the information.', | ||
| 'de': 'Du bist ein hilfreicher Assistent. Du beantwortest Fragen basierend auf den vorliegenden Dokumenten. Beantworte basierend auf den Dokumenten nur. Wenn die Information nicht in den Dokumenten ist, sage, dass du sie nicht finden kannst.', | ||
| } | ||
|
|
||
| user_prompt_builders = { | ||
| 'en': PromptBuilder(template=prompt_template_en), | ||
| 'de': PromptBuilder(template=prompt_template_de), | ||
| } | ||
|
|
||
| prompt_builder = PromptBuilder(template=prompt_template) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.