From 5a11aab766511990861bd6d034600093f17c9f77 Mon Sep 17 00:00:00 2001 From: AstraBert Date: Fri, 5 Apr 2024 03:43:16 +0200 Subject: [PATCH] v0.1.0 updates --- .gitignore | 3 + README.md | 34 ++++++-- data/example_chat.png | Bin 0 -> 100365 bytes docker/Dockerfile | 44 ++++++++++ docker/chat.py | 78 ++++++++++++++++++ docker/requirements.txt | 10 +++ docker/utils.py | 172 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 333 insertions(+), 8 deletions(-) create mode 100644 data/example_chat.png create mode 100644 docker/Dockerfile create mode 100644 docker/chat.py create mode 100644 docker/requirements.txt create mode 100644 docker/utils.py diff --git a/.gitignore b/.gitignore index e69de29..9888957 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,3 @@ +flagged/ +scripts/__pycache__ +docker/build_command.sh \ No newline at end of file diff --git a/README.md b/README.md index 6d3f1b1..34bb47f 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,21 @@ _Go and give it a try [here](https://hf.co/chat/assistant/660d9a4f590a7924eed02a32)!_ 🤖
-
GitHub top language GitHub commit activity Static Badge - Static Badge + Static Badge +
+ Example chat +

Example chat with everything-rag, mediated by google/flan-t5-base

+
### Table of Contents 1. [Introduction](#introduction) +2. [Inspiration](#inspiration) 2. [Getting Started](#getting-started) 3. [Using the Chatbot](#using-the-chatbot) 4. [Troubleshooting](#troubleshooting) @@ -38,22 +42,35 @@ While everything-rag offers many benefits, there are a couple of limitations to In summary, everything-rag is a simple, customizable, and local chatbot assistant that offers a wide range of features and capabilities. By leveraging the power of RAG, everything-rag offers a unique and flexible chatbot experience that can be tailored to your specific needs and preferences. Whether you're looking for a simple chatbot to answer basic questions or a more advanced conversational AI to engage with your users, everything-rag has got you covered.😊 +## Inspiration + +This project is a humble and modest carbon-copy of its main and true inspirations, i.e. [Jan.ai](https://jan.ai/), [Cheshire Cat AI](https://cheshirecat.ai/), [privateGPT](https://privategpt.io/) and many other projects that focus on making LLMs (and AI in general) open-source and easily accessible to everyone. + ## Getting Started You can do two things: - Play with generation on [Kaggle](https://www.kaggle.com/code/astrabertelli/gemma-for-datasciences) - Clone this repository, head over to [the python script](./scripts/gemma_for_datasciences.py) and modify everything to your needs! +- Docker installation(⚠️**NOT YET FULLY IMPLEMENTED**): you will be able, **in the near future**, to install everything-rag through docker image and running it thanks do Docker by following these really simple commands: -😇🤪Coming soon... Installation through Docker image! +```bash +docker pull ghcr.io/AstraBert/everything-rag:latest +docker run everything-rag:latest -e "model=microsoft/phi-2" -e "task=text-generation" +``` +- As you can see, you just need to specify the LLM model and its task. Keep in mind that, for what concerns v0.1.0, everything-rag supports only text-generation and text2text-generation (this is not even mandatory: if not specified, the image employes directly google/flan-t5-base, a model for text2text-generation). For these two tasks, you can use virtually *any* model from HuggingFace Hub: the sole recommendation is to watch out for your disk space, RAM and CPU power, LLMs can be quite resource-consuming! ## Using the Chatbot ### GUI -The chatbot has a simple GUI built using tkinter. The GUI displays the chat history and allows the user to input queries. The user can send a message by pressing the "Send" button. +The chatbot has a brand-new GradIO-based interface that runs on local server. You can interact by uploading directly your pdf files and/or sending messages, all (for now), by running: + +```bash +python3 scripts/chat.py -m provider/modelname -t task +``` -### Code breakdown +### Code breakdown - notebook Everything is explained in [the dedicated notebook](./scripts/gemma-for-datasciences.ipynb), but here's a brief breakdown of the code: @@ -66,7 +83,6 @@ Everything is explained in [the dedicated notebook](./scripts/gemma-for-datascie Et voilà, your chatbot is up and running!🦿 - ## Troubleshooting ### Common Issues Q&A @@ -77,8 +93,10 @@ Et voilà, your chatbot is up and running!🦿 > A: This is quite common with resource-limited environments that deal with too large or too small models: large models require **at least** 32 GB RAM and >8 core CPU, whereas small model can easily be allucinating and producing responses that are endless repetitions of the same thing! Check *penalty_score* parameter to avoid this. **try rephrasing the query and be as specific as possible** * Q: My model is allucinatin and/or repeating the same sentence over and over again😵‍💫 > A: This is quite common with small or old models: check *penalty_score* and *temperature* parameter to avoid this. -* The chatbot is giving incorrect/non-meaningful answers🤥 +* Q: The chatbot is giving incorrect/non-meaningful answers🤥 >A: Check that the PDF document is relevant and up-to-date. Also, **try rephrasing the query and be as specific as possible** +* Q: An error occurred while generating the answer💔 + >A: This frequently occures when your (small) LLM has a limited maximum hidden size (generally 512 or 1024) and the context that the retrieval-augmented chain produces goes beyond that maximum. You could, potentially, modify the configuration of the model, but this would mean dramatically increase its resource consumption, and your small laptop is not prepared to take it, trust me!!! A solution, if you have enough RAM and CPU power, is to switch to larger LLMs: they do not have problems in this sense. ## Contributing @@ -92,10 +110,10 @@ Contributions are welcome! If you would like to improve the chatbot's functional * [Langchain-community](https://github.com/langchain-community/langchain-community) * [Tkinter](https://docs.python.org/3/library/tkinter.html) * [PDF document about data science](https://www.kaggle.com/datasets/astrabertelli/what-is-datascience-docs) +* [GradIO](https://www.gradio.app/) ## License - This project is licensed under the Apache 2.0 License. If you use this work for your projects, please consider citing the author [Astra Bertelli](http://astrabert.vercel.app). diff --git a/data/example_chat.png b/data/example_chat.png new file mode 100644 index 0000000000000000000000000000000000000000..7391af1eb2346c2bae982eb97c48eddd30ce97a3 GIT binary patch literal 100365 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%0D%YfMY5Ywi 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 z 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 Csm(+H literal 0 HcmV?d00001 diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..3f7bbfa --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,44 @@ +# Use an official Python runtime as a parent image +FROM python:3.10-slim-buster + +# Set the working directory in the container to /app +WORKDIR /app + +# Add the current directory contents into the container at /app +ADD . /app + +# Update and install system dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + libpq-dev \ + libffi-dev \ + libssl-dev \ + musl-dev \ + libxml2-dev \ + libxslt1-dev \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +RUN python3 -m pip cache purge +RUN python3 -m pip install --no-cache-dir -r requirements.txt + +# Set version +ARG version="v0.1.0" + +# Echo version +RUN echo "Started everything-rag ${version}" + +# Set default model and task +ENV model="google/flan-t5-base" + +ENV task="text2text-generation" + +# Run script to install and build the model for the first time +RUN python3 utils.py -m ${model} -t ${task} + +# Expose the port that the application will run on +EXPOSE 7860 + +# Set the entrypoint with a default command and allow the user to override it +ENTRYPOINT ["python3", "chat.py", "-m", "${model}", "-t", "${task}"] \ No newline at end of file diff --git a/docker/chat.py b/docker/chat.py new file mode 100644 index 0000000..bb1e601 --- /dev/null +++ b/docker/chat.py @@ -0,0 +1,78 @@ +import gradio as gr +import os +import time +from utils import * + +vectordb = "" + +def generate_welcome_message(): + return (None, "Hello! Welcome to the chatbot. You can enter a message or upload a file.") + +def print_like_dislike(x: gr.LikeData): + print(x.index, x.value, x.liked) + +def add_message(history, message): + if len(message["files"]) > 0: + history.append((message["files"], None)) + if message["text"] is not None and message["text"] != "": + history.append((message["text"], None)) + return history, gr.MultimodalTextbox(value=None, interactive=False) + + +def bot(history): + global vectordb + global tsk + if type(history[-1][0]) != tuple: + if vectordb == "": + pipe = pipeline(tsk, tokenizer=tokenizer, model=model) + response = pipe(history[-1][0])[0] + response = response["generated_text"] + history[-1][1] = "" + for character in response: + history[-1][1] += character + time.sleep(0.05) + yield history + else: + try: + response = just_chatting(model=model, tokenizer=tokenizer, query=history[-1][0], vectordb=vectordb, chat_history=[convert_none_to_str(his) for his in history])["answer"] + history[-1][1] = "" + for character in response: + history[-1][1] += character + time.sleep(0.05) + yield history + except Exception as e: + response = f"Sorry, the error '{e}' occured while generating the response; check [troubleshooting documentation](https://astrabert.github.io/everything-rag/#troubleshooting) for more" + if type(history[-1][0]) == tuple: + filelist = [] + for i in history[-1][0]: + filelist.append(i) + finalpdf = merge_pdfs(filelist) + vectordb = create_a_persistent_db(finalpdf, os.path.dirname(finalpdf)+"_localDB", os.path.dirname(finalpdf)+"_embcache") + response = "VectorDB was successfully created, now you can ask me anything about the document you uploaded!😊" + history[-1][1] = "" + for character in response: + history[-1][1] += character + time.sleep(0.05) + yield history + +with gr.Blocks() as demo: + chatbot = gr.Chatbot( + [[None, "Hi, I'm **everything-rag**🤖.\nI'm here to assist you and let you chat with _your_ pdfs!\nCheck [my website](https://astrabert.github.io/everything-rag/) for troubleshooting and documentation reference\nHave fun!😊"]], + label="everything-rag", + elem_id="chatbot", + bubble_full_width=False, + ) + + chat_input = gr.MultimodalTextbox(interactive=True, file_types=["pdf"], placeholder="Enter message or upload file...", show_label=False) + + chat_msg = chat_input.submit(add_message, [chatbot, chat_input], [chatbot, chat_input]) + bot_msg = chat_msg.then(bot, chatbot, chatbot, api_name="bot_response") + bot_msg.then(lambda: gr.MultimodalTextbox(interactive=True), None, [chat_input]) + + chatbot.like(print_like_dislike, None, None) + gr.ClearButton(chatbot) +demo.queue() +if __name__ == "__main__": + demo.launch() + + \ No newline at end of file diff --git a/docker/requirements.txt b/docker/requirements.txt new file mode 100644 index 0000000..b818043 --- /dev/null +++ b/docker/requirements.txt @@ -0,0 +1,10 @@ +langchain-community==0.0.13 +langchain==0.1.1 +pypdf==3.17.4 +sentence_transformers==2.2.2 +chromadb==0.4.22 +gradio +torch +transformers +trl +peft \ No newline at end of file diff --git a/docker/utils.py b/docker/utils.py new file mode 100644 index 0000000..576d494 --- /dev/null +++ b/docker/utils.py @@ -0,0 +1,172 @@ +from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForCausalLM, pipeline +import time +from langchain_community.llms import HuggingFacePipeline +from langchain.storage import LocalFileStore +from langchain.embeddings import CacheBackedEmbeddings +from langchain_community.vectorstores import Chroma +from langchain.text_splitter import CharacterTextSplitter +from langchain_community.document_loaders import PyPDFLoader +from langchain_community.embeddings import HuggingFaceEmbeddings +from langchain.chains import ConversationalRetrievalChain +import os +from pypdf import PdfMerger +from argparse import ArgumentParser + +argparse = ArgumentParser() +argparse.add_argument( + "-m", + "--model", + help="HuggingFace Model identifier, such as 'google/flan-t5-base'", + required=True, +) + +argparse.add_argument( + "-t", + "--task", + help="Task for the model: for now supported task are ['text-generation', 'text2text-generation']", + required=True, +) + +args = argparse.parse_args() + + +mod = args.model +tsk = args.task + +mod = mod.replace("\"", "").replace("'", "") +tsk = tsk.replace("\"", "").replace("'", "") + +TASK_TO_MODEL = {"text-generation": AutoModelForCausalLM, "text2text-generation": AutoModelForSeq2SeqLM} + +if tsk not in TASK_TO_MODEL: + raise Exception("Unsopported task! Supported task are ['text-generation', 'text2text-generation']") + +def merge_pdfs(pdfs: list): + merger = PdfMerger() + for pdf in pdfs: + merger.append(pdf) + merger.write(f"{pdfs[-1].split('.')[0]}_results.pdf") + merger.close() + return f"{pdfs[-1].split('.')[0]}_results.pdf" + +def create_a_persistent_db(pdfpath, dbpath, cachepath) -> None: + """ + Creates a persistent database from a PDF file. + + Args: + pdfpath (str): The path to the PDF file. + dbpath (str): The path to the storage folder for the persistent LocalDB. + cachepath (str): The path to the storage folder for the embeddings cache. + """ + print("Started the operation...") + a = time.time() + loader = PyPDFLoader(pdfpath) + documents = loader.load() + + ### Split the documents into smaller chunks for processing + text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) + texts = text_splitter.split_documents(documents) + + ### Use HuggingFace embeddings for transforming text into numerical vectors + ### This operation can take a while the first time but, once you created your local database with + ### cached embeddings, it should be a matter of seconds to load them! + embeddings = HuggingFaceEmbeddings() + store = LocalFileStore( + os.path.join( + cachepath, os.path.basename(pdfpath).split(".")[0] + "_cache" + ) + ) + cached_embeddings = CacheBackedEmbeddings.from_bytes_store( + underlying_embeddings=embeddings, + document_embedding_cache=store, + namespace=os.path.basename(pdfpath).split(".")[0], + ) + + b = time.time() + print( + f"Embeddings successfully created and stored at {os.path.join(cachepath, os.path.basename(pdfpath).split('.')[0]+'_cache')} under namespace: {os.path.basename(pdfpath).split('.')[0]}" + ) + print(f"To load and embed, it took: {b - a}") + + persist_directory = os.path.join( + dbpath, os.path.basename(pdfpath).split(".")[0] + "_localDB" + ) + vectordb = Chroma.from_documents( + documents=texts, + embedding=cached_embeddings, + persist_directory=persist_directory, + ) + c = time.time() + print( + f"Persistent database successfully created and stored at {os.path.join(dbpath, os.path.basename(pdfpath).split('.')[0] + '_localDB')}" + ) + print(f"To create a persistent database, it took: {c - b}") + return vectordb + +def convert_none_to_str(l: list): + newlist = [] + for i in range(len(l)): + if l[i] is None or type(l[i])==tuple: + newlist.append("") + else: + newlist.append(l[i]) + return tuple(newlist) + +def just_chatting( + task, + model, + tokenizer, + query, + vectordb, + chat_history=[] +): + """ + Implements a chat system using Hugging Face models and a persistent database. + + Args: + task (str): Task for the pipeline; for now supported task are ['text-generation', 'text2text-generation'] + model (AutoModelForCausalLM): Hugging Face model, already loaded and prepared. + tokenizer (AutoTokenizer): Hugging Face tokenizer, already loaded and prepared. + model_task (str): Task for the Hugging Face model. + persistent_db_dir (str): Directory for the persistent database. + embeddings_cache (str): Path to cache Hugging Face embeddings. + pdfpath (str): Path to the PDF file. + query (str): Question by the user + vectordb (ChromaDB): vectorstorer variable for retrieval. + chat_history (list): A list with previous questions and answers, serves as context; by default it is empty (it may make the model allucinate) + """ + ### Create a text-generation pipeline and connect it to a ConversationalRetrievalChain + pipe = pipeline(task, + model=model, + tokenizer=tokenizer, + max_new_tokens = 2048, + repetition_penalty = float(10), + ) + + local_llm = HuggingFacePipeline(pipeline=pipe) + llm_chain = ConversationalRetrievalChain.from_llm( + llm=local_llm, + chain_type="stuff", + retriever=vectordb.as_retriever(search_kwargs={"k": 1}), + return_source_documents=False, + ) + rst = llm_chain({"question": query, "chat_history": chat_history}) + return rst + + +try: + tokenizer = AutoTokenizer.from_pretrained( + mod, + ) + + tokenizer.pad_token = tokenizer.eos_token + + model = TASK_TO_MODEL[tsk].from_pretrained( + mod, + ) +except Exception as e: + import sys + print(f"The error {e} occured while handling model and tokenizer loading: please ensure that the model you provided was correct and suitable for the specified task. Be also sure that the HF repository for the loaded model contains all the necessary files.", file=sys.stderr) + sys.exit(1) + +