{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":50947,"databundleVersionId":5741538,"sourceType":"competition"},{"sourceId":64148,"databundleVersionId":7669720,"sourceType":"competition"},{"sourceId":8104317,"sourceType":"datasetVersion","datasetId":9},{"sourceId":136669987,"sourceType":"kernelVersion"},{"sourceId":11372,"sourceType":"modelInstanceVersion","modelInstanceId":5388}],"dockerImageVersionId":30683,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Installation Commands\n","metadata":{}},{"cell_type":"markdown","source":"## Prerequisites: The following packages are a prerequisite:\n- **dspy-ai: It is a framework for algorithimically optimizing LM prompts and weights, when LMs are used one or more times within a pipeline**\n- **weaviate-client: It is a vector search engine that allows us to perform similarity searches on large datasets using vector embeddings**\n- **LLama Index:  It is a simple, flexible data framework for connecting custom data sources to LLMs**\n- **llama-index-embeddings-huggingface: This package provides integration b/w LLama index and Hugging Face's transformers library**\n- **llama-index-vector-stores-weaviate: Provides integration b/w LLama index and weaviate.**","metadata":{}},{"cell_type":"markdown","source":"- **Set the environment variable for the keras backend to jax, it determines the library used for numerical computations**\n- **Set the enviroment variable for the XLA or Accelerated Linear Algebra GPU allocation, setting it to 1.0 allocates the entire GPU memory for the XLA python client** *suitable for running large models*","metadata":{}},{"cell_type":"code","source":"!pip install -q -U keras-nlp\n!pip install -q -U keras>3\n!pip install -q -U llama_index\n!pip install llama-index-embeddings-huggingface\n!pip install weaviate-client\n!pip install llama-index-vector-stores-weaviate\n!pip install torch sentence-transformers","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:30:42.890224Z","iopub.execute_input":"2024-04-14T07:30:42.890955Z","iopub.status.idle":"2024-04-14T07:32:33.305759Z","shell.execute_reply.started":"2024-04-14T07:30:42.890921Z","shell.execute_reply":"2024-04-14T07:32:33.304467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras\nimport keras_nlp\nimport os\n\nos.environ[\"KERAS_BACKEND\"] = \"jax\"\nos.environ[\"XLA_PYTHON_CLIENT_MEM_FRACTION\"] = \"1.00\"\n\ngemma_lm = keras_nlp.models.GemmaCausalLM.from_preset(\"gemma_instruct_2b_en\")","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:37:04.383135Z","iopub.execute_input":"2024-04-14T07:37:04.384000Z","iopub.status.idle":"2024-04-14T07:37:15.653769Z","shell.execute_reply.started":"2024-04-14T07:37:04.383967Z","shell.execute_reply":"2024-04-14T07:37:15.651428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Defining a custom model as shown in the LLamaIndex docs","metadata":{}},{"cell_type":"code","source":"from typing import Any\n\nfrom llama_index.core.callbacks import CallbackManager\nfrom llama_index.core.llms import (\n    CustomLLM,\n    CompletionResponse,\n    CompletionResponseGen,\n    LLMMetadata,\n)\nfrom llama_index.core.llms.callbacks import llm_completion_callback","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:37:34.638359Z","iopub.execute_input":"2024-04-14T07:37:34.639081Z","iopub.status.idle":"2024-04-14T07:37:34.644129Z","shell.execute_reply.started":"2024-04-14T07:37:34.639047Z","shell.execute_reply":"2024-04-14T07:37:34.643053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Gemma(CustomLLM):\n    num_output: int = 512  # Default number of output tokens\n    model_name: str = \"Gemma\"  # Name of the model\n    model: Any = None  # Placeholder for the model object\n\n    def __init__(self, model, num_output):\n        super(Gemma, self).__init__()\n        self.model = model  # Initialize the model object\n        self.num_output = num_output  # Set the number of output tokens\n\n    @property\n    def metadata(self) -> LLMMetadata:\n        \"\"\"Get LLM metadata.\"\"\"\n        return LLMMetadata(\n            num_output=self.num_output,  # Set the number of output tokens in the metadata\n            model_name=self.model_name,  # Set the model name in the metadata\n        )\n\n    @llm_completion_callback()  # Decorator for completion callback\n    def complete(self, prompt: str, **kwargs: Any) -> CompletionResponse:\n        \"\"\"Generate completions for the given prompt.\"\"\"\n        return CompletionResponse(text=self.model.generate(prompt, max_length=self.num_output))\n\n    @llm_completion_callback()  # Decorator for streaming completion callback\n    def stream_complete(self, prompt: str, **kwargs: Any) -> CompletionResponseGen:\n        \"\"\"Generate completions for the given prompt in a streaming fashion.\"\"\"\n        response = \"\"  # Initialize response string\n        for token in self.model.generate(prompt, max_length=self.num_output):\n            response += token  # Append token to the response\n            yield CompletionResponse(text=response, delta=token)  # Yield completion response with current response and delta token\n","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:37:36.722430Z","iopub.execute_input":"2024-04-14T07:37:36.723116Z","iopub.status.idle":"2024-04-14T07:37:36.734782Z","shell.execute_reply.started":"2024-04-14T07:37:36.723080Z","shell.execute_reply":"2024-04-14T07:37:36.733987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Define Embedding Model \n### Embedding Model is used to generate vector embeddings for the document chunks as well as the query\n### LLM: used to generate an answer based on the user query and the relevant context","metadata":{}},{"cell_type":"code","source":"from llama_index.core.settings import Settings\nfrom llama_index.embeddings.huggingface import HuggingFaceEmbedding","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:37:38.174515Z","iopub.execute_input":"2024-04-14T07:37:38.175170Z","iopub.status.idle":"2024-04-14T07:37:38.179502Z","shell.execute_reply.started":"2024-04-14T07:37:38.175141Z","shell.execute_reply":"2024-04-14T07:37:38.178563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Settings.llm = Gemma(gemma_lm, 512)\nSettings.embed_model = HuggingFaceEmbedding(model_name = \"BAAI/bge-small-en-v1.5\") #can be replaced by any other model available on huggingface","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:37:40.010468Z","iopub.execute_input":"2024-04-14T07:37:40.011302Z","iopub.status.idle":"2024-04-14T07:37:40.958465Z","shell.execute_reply.started":"2024-04-14T07:37:40.011264Z","shell.execute_reply":"2024-04-14T07:37:40.957679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Loading  Data: We use the Kaggle Competition dataset","metadata":{}},{"cell_type":"code","source":"import pandas as pd \ndf = pd.read_csv(\"/kaggle/input/2023-kaggle-ai-report/kaggle_writeups_20230510.csv\")\n\ndf = df.sample(frac = 0.1, random_state = 42)\n\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:37:46.530489Z","iopub.execute_input":"2024-04-14T07:37:46.531361Z","iopub.status.idle":"2024-04-14T07:37:46.732753Z","shell.execute_reply.started":"2024-04-14T07:37:46.531325Z","shell.execute_reply":"2024-04-14T07:37:46.731808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from llama_index.core import Document  # Import the Document class from the llama_index.core module\n\n# Create a list of Document objects by iterating over rows in a DataFrame\ndocuments = [\n    Document(\n        text=row['Writeup'],  # Set the text attribute of the Document to the value in the 'Writeup' column\n        metadata={\"competition_title\": row['Title of Competition']},  # Set metadata for the Document\n    ) \n    for _, row in df.iterrows()  # Iterate over rows in the DataFrame df\n]\n\n# Print the text of the first document in the list\nprint((documents[0].text))\n\n# Display the first document\ndocuments[0]\n","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:37:49.578283Z","iopub.execute_input":"2024-04-14T07:37:49.578670Z","iopub.status.idle":"2024-04-14T07:37:49.626783Z","shell.execute_reply.started":"2024-04-14T07:37:49.578610Z","shell.execute_reply":"2024-04-14T07:37:49.625882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from llama_index.core.node_parser import SentenceSplitter\n\nparser = SentenceSplitter(chunk_size = 128, chunk_overlap = 20)\nnodes = parser.get_nodes_from_documents(documents)","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:40:52.587872Z","iopub.execute_input":"2024-04-14T07:40:52.588551Z","iopub.status.idle":"2024-04-14T07:40:55.378441Z","shell.execute_reply.started":"2024-04-14T07:40:52.588516Z","shell.execute_reply":"2024-04-14T07:40:55.377637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Store the nodes in a vector database using Weaviate","metadata":{"execution":{"iopub.status.busy":"2024-04-14T05:37:19.631731Z","iopub.execute_input":"2024-04-14T05:37:19.632452Z","iopub.status.idle":"2024-04-14T05:37:22.535916Z","shell.execute_reply.started":"2024-04-14T05:37:19.632418Z","shell.execute_reply":"2024-04-14T05:37:22.535021Z"}}},{"cell_type":"code","source":"import weaviate\nfrom weaviate.embedded import EmbeddedOptions\n\n# Connect to Weaviate client in embedded mode\nclient = weaviate.Client(embedded_options=EmbeddedOptions())","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:40:58.587083Z","iopub.execute_input":"2024-04-14T07:40:58.587437Z","iopub.status.idle":"2024-04-14T07:40:58.656191Z","shell.execute_reply.started":"2024-04-14T07:40:58.587409Z","shell.execute_reply":"2024-04-14T07:40:58.655333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from llama_index.core import VectorStoreIndex, StorageContext\nfrom llama_index.vector_stores.weaviate import WeaviateVectorStore","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:41:01.940009Z","iopub.execute_input":"2024-04-14T07:41:01.940411Z","iopub.status.idle":"2024-04-14T07:41:01.945090Z","shell.execute_reply.started":"2024-04-14T07:41:01.940382Z","shell.execute_reply":"2024-04-14T07:41:01.944162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the name of the index\nindex_name = \"SolutionsWriteups\"\n\n# Create a WeaviateVectorStore object with the specified index name and Weaviate client\nvector_store = WeaviateVectorStore(\n    weaviate_client=client,  # Weaviate client object\n    index_name=index_name  # Name of the index\n)\n\n# Create a StorageContext object from defaults, using the WeaviateVectorStore as the vector store\nstorage_context = StorageContext.from_defaults(\n    vector_store=vector_store  # WeaviateVectorStore object\n)\n\n# Check if the schema for the index already exists in the Weaviate instance\nif client.schema.exists(index_name):\n    # If the schema exists, delete the class corresponding to the index\n    client.schema.delete_class(index_name)\n\n# Create a VectorStoreIndex object with the specified nodes and storage context\nindex = VectorStoreIndex(\n    nodes,  # List of nodes (vectors) to be indexed\n    storage_context=storage_context,  # StorageContext object\n)\n","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:41:03.260468Z","iopub.execute_input":"2024-04-14T07:41:03.261383Z","iopub.status.idle":"2024-04-14T07:41:43.161672Z","shell.execute_reply.started":"2024-04-14T07:41:03.261349Z","shell.execute_reply":"2024-04-14T07:41:43.160877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Demonstrating retreival ","metadata":{"execution":{"iopub.status.busy":"2024-04-12T19:26:57.420865Z","iopub.execute_input":"2024-04-12T19:26:57.421202Z","iopub.status.idle":"2024-04-12T19:26:57.492998Z","shell.execute_reply.started":"2024-04-12T19:26:57.421176Z","shell.execute_reply":"2024-04-12T19:26:57.491975Z"}}},{"cell_type":"code","source":"import json\n\nresponse = (\n    client.query\n    .get(index_name, [\"text\"])\n    .with_where({\n        \"path\": [\"competition_title\"],\n        \"operator\": \"Equal\",\n        \"valueText\": \"Google - Isolated Sign Language Recognition\"\n    })\n    .with_limit(2)\n    .do()\n)\n\nprint(json.dumps(response, indent=4))","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:41:50.250570Z","iopub.execute_input":"2024-04-14T07:41:50.251451Z","iopub.status.idle":"2024-04-14T07:41:50.261059Z","shell.execute_reply.started":"2024-04-14T07:41:50.251416Z","shell.execute_reply":"2024-04-14T07:41:50.260189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Creating a naive query pipeline","metadata":{}},{"cell_type":"code","source":"rag_pipeline = index.as_query_engine()","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:41:56.636490Z","iopub.execute_input":"2024-04-14T07:41:56.636857Z","iopub.status.idle":"2024-04-14T07:41:56.700370Z","shell.execute_reply.started":"2024-04-14T07:41:56.636827Z","shell.execute_reply":"2024-04-14T07:41:56.699645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"example_query = \"What is a good backbone for the Kaggle competition with the title 'Feedback Prize - English Language Learning'?\"\n\n","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:43:38.311563Z","iopub.execute_input":"2024-04-14T07:43:38.311964Z","iopub.status.idle":"2024-04-14T07:43:38.316367Z","shell.execute_reply.started":"2024-04-14T07:43:38.311934Z","shell.execute_reply":"2024-04-14T07:43:38.315470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"response = rag_pipeline.query(example_query)\n\nprint(response.response)","metadata":{"execution":{"iopub.status.busy":"2024-04-14T07:43:40.241701Z","iopub.execute_input":"2024-04-14T07:43:40.242510Z","iopub.status.idle":"2024-04-14T07:43:41.534714Z","shell.execute_reply.started":"2024-04-14T07:43:40.242478Z","shell.execute_reply":"2024-04-14T07:43:41.533684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}