{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "view-in-github", "colab_type": "text" }, "source": [ "\"Open" ] }, { "cell_type": "markdown", "metadata": { "id": "5BGJ3fxhOk2V" }, "source": [ "# Install Packages and Setup Variables\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "QPJzr-I9XQ7l", "collapsed": true, "outputId": "a68229ea-1d76-475b-9eb2-05dca0ef431e", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/67.3 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.3/67.3 kB\u001b[0m \u001b[31m2.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25h Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n", " Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n", " Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.4/50.4 kB\u001b[0m \u001b[31m3.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m337.0/337.0 kB\u001b[0m \u001b[31m21.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.1/1.1 MB\u001b[0m \u001b[31m35.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m584.3/584.3 kB\u001b[0m \u001b[31m25.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m40.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m15.5/15.5 MB\u001b[0m \u001b[31m47.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m273.8/273.8 kB\u001b[0m \u001b[31m11.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.0/94.0 kB\u001b[0m \u001b[31m5.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m150.7/150.7 kB\u001b[0m \u001b[31m9.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m679.1/679.1 kB\u001b[0m \u001b[31m22.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.7/1.7 MB\u001b[0m \u001b[31m37.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m26.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.6/67.6 kB\u001b[0m \u001b[31m4.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.2/13.2 MB\u001b[0m \u001b[31m30.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.0/64.0 kB\u001b[0m \u001b[31m4.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.5/52.5 kB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.7/149.7 kB\u001b[0m \u001b[31m10.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m110.5/110.5 kB\u001b[0m \u001b[31m7.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m141.9/141.9 kB\u001b[0m \u001b[31m9.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.5/4.5 MB\u001b[0m \u001b[31m55.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.2/54.2 kB\u001b[0m \u001b[31m3.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m62.8/62.8 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m3.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m341.4/341.4 kB\u001b[0m \u001b[31m18.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m187.4/187.4 kB\u001b[0m \u001b[31m12.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m295.8/295.8 kB\u001b[0m \u001b[31m17.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m71.4/71.4 kB\u001b[0m \u001b[31m4.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.4/3.4 MB\u001b[0m \u001b[31m34.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m425.7/425.7 kB\u001b[0m \u001b[31m20.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m157.3/157.3 kB\u001b[0m \u001b[31m9.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.0/46.0 kB\u001b[0m \u001b[31m2.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m5.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.3/49.3 kB\u001b[0m \u001b[31m2.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25h Building wheel for pypika (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n" ] } ], "source": [ "!pip install -q llama-index==0.10.57 openai==1.37.0 tiktoken==0.7.0 chromadb==0.5.5 llama-index-vector-stores-chroma==0.1.10 llama-index-llms-gemini==0.1.11" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "riuXwpSPcvWC" }, "outputs": [], "source": [ "import os\n", "\n", "# Set the following API Keys in the Python environment. Will be used later.\n", "os.environ[\"OPENAI_API_KEY\"] = \"\"\n", "os.environ[\"GOOGLE_API_KEY\"] = \"\"" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "km-KQOrgr3VB" }, "outputs": [], "source": [ "# Allows running asyncio in environments with an existing event loop, like Jupyter notebooks.\n", "\n", "import nest_asyncio\n", "\n", "nest_asyncio.apply()" ] }, { "cell_type": "markdown", "metadata": { "id": "0BwVuJXlzHVL" }, "source": [ "# Create a VectoreStore\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "SQP87lHczHKc" }, "outputs": [], "source": [ "import chromadb\n", "\n", "# create client and a new collection\n", "# chromadb.EphemeralClient saves data in-memory.\n", "chroma_client = chromadb.PersistentClient(path=\"./mini-llama-articles\")\n", "chroma_collection = chroma_client.create_collection(\"mini-llama-articles\")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "zAaGcYMJzHAN" }, "outputs": [], "source": [ "from llama_index.vector_stores.chroma import ChromaVectorStore\n", "\n", "# Define a storage context object using the created vector database.\n", "vector_store = ChromaVectorStore(chroma_collection=chroma_collection)" ] }, { "cell_type": "markdown", "metadata": { "id": "I9JbAzFcjkpn" }, "source": [ "# Load the Dataset (CSV)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "_Tif8-JoRH68" }, "source": [ "## Download\n" ] }, { "cell_type": "markdown", "metadata": { "id": "4fQaa1LN1mXL" }, "source": [ "The dataset includes several articles from the TowardsAI blog, which provide an in-depth explanation of the LLaMA2 model.\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "id": "fQtpDvUzKNzI", "outputId": "811bbd6b-8f04-45a9-d3c9-b19128daf306", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", "100 169k 100 169k 0 0 273k 0 --:--:-- --:--:-- --:--:-- 274k\n" ] } ], "source": [ "!curl -o ./mini-dataset.csv https://raw.githubusercontent.com/AlaFalaki/tutorial_notebooks/main/data/mini-llama-articles.csv" ] }, { "cell_type": "markdown", "metadata": { "id": "zk-4alIxROo8" }, "source": [ "## Load the Articles\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "id": "_WER5lt0N7c5", "outputId": "7cf8a364-fe04-4957-aacd-42f6fb0386d5", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "14" ] }, "metadata": {}, "execution_count": 7 } ], "source": [ "import csv\n", "\n", "rows = []\n", "\n", "# Load the file as a JSON\n", "with open(\"./mini-dataset.csv\", mode=\"r\", encoding=\"utf-8\") as file:\n", " csv_reader = csv.reader(file)\n", "\n", " for idx, row in enumerate(csv_reader):\n", " if idx == 0:\n", " continue\n", " # Skip header row\n", " rows.append(row)\n", "\n", "# The number of characters in the dataset.\n", "len(rows)" ] }, { "cell_type": "markdown", "metadata": { "id": "wxEStggPdxYs" }, "source": [ "# Convert to Document obj\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "lFvW_886dxKX" }, "outputs": [], "source": [ "from llama_index.core import Document\n", "from llama_index.core.schema import TextNode\n", "\n", "# Convert the chunks to Document objects so the LlamaIndex framework can process them.\n", "documents = [\n", " Document(\n", " text=row[1],\n", " metadata={\"title\": row[0], \"url\": row[2], \"source_name\": row[3]},\n", " )\n", " for row in rows\n", "]\n", "# By default, the node/chunks ids are set to random uuids. To ensure same id's per run, we manually set them.\n", "for idx, doc in enumerate(documents):\n", " doc.id_ = f\"doc_{idx}\"" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "collapsed": true, "id": "Njoc3XEVkKkf", "outputId": "83f885cd-371f-4497-cb8c-65105e876585" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "Document(id_='doc_0', embedding=None, metadata={'title': \"Beyond GPT-4: What's New?\", 'url': 'https://pub.towardsai.net/beyond-gpt-4-whats-new-cbd61a448eb9#dda8', 'source_name': 'towards_ai'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text='LLM Variants and Meta\\'s Open Source Before shedding light on four major trends, I\\'d share the latest Meta\\'s Llama 2 and Code Llama. Meta\\'s Llama 2 represents a sophisticated evolution in LLMs. This suite spans models pretrained and fine-tuned across a parameter spectrum of 7 billion to 70 billion. A specialized derivative, Llama 2-Chat, has been engineered explicitly for dialogue-centric applications. Benchmarking revealed Llama 2\\'s superior performance over most extant open-source chat models. Human-centric evaluations, focusing on safety and utility metrics, positioned Llama 2-Chat as a potential contender against proprietary, closed-source counterparts. The development trajectory of Llama 2 emphasized rigorous fine-tuning methodologies. Meta\\'s transparent delineation of these processes aims to catalyze community-driven advancements in LLMs, underscoring a commitment to collaborative and responsible AI development. Code Llama is built on top of Llama 2 and is available in three models: Code Llama, the foundational code model;Codel Llama - Python specialized for Python;and Code Llama - Instruct, which is fine-tuned for understanding natural language instructions. Based on its benchmark testing, Code Llama outperformed state-of-the-art publicly available LLMs (except GPT-4) on code tasks. Llama 2, Llama 2-Chat, and Code Llama are key steps in LLM development but still have a way to go compared to GPT-4. Meta\\'s open access and commitment to improving these models promise transparent and faster LLM progress in the future. Please refer to the LLM and Llama variants below: From LLMs to Multimodal LLMs, like OpenAI\\'s ChatGPT (GPT-3.5), primarily focus on understanding and generating human language. They\\'ve been instrumental in tasks like text generation, translation, and even creative writing. However, their scope is limited to text. Enter multimodal models like GPT-4. These are a new breed of AI models that can understand and generate not just text, but also images, sounds, and potentially other types of data. The term \"multimodal\" refers to their ability to process multiple modes or types of data simultaneously. This is a game-changer. Imagine an AI that can not only read a description of a dress but also visualize it or even design it! Multimodal AI models are moving us towards more holistic AI systems. These systems can potentially understand our world in a more comprehensive manner, bridging the gap between different forms of data and providing richer, more integrated solutions. As we stand on the cusp of this new era, it\\'s exciting to envision the myriad of applications and innovations that Multimodal models will bring to the table. The future of AI looks more integrated and versatile than ever before. From Connections to Vector DB The AI landscape is witnessing a fascinating transition: from Language Model (LLM) connections or integrations, e.g., LangChain and LlamaIndex, to the rise of Vector Databases (Vector DB) such as Weaviate, Milvus, Pinecone, Chroma, and Vespa.ai. But what\\'s driving this shift, and why does it matter? LLM connections, like the LlamaIndex, primarily focus on linking and understanding vast amounts of external data. They\\'ve been pivotal in creating semantic connections, enabling more intuitive search experiences, and enhancing data accessibility. However, as the volume and variety of data grow, the need for more advanced storage and retrieval mechanisms becomes evident. This is where Vector DBs come into play. Unlike traditional databases that store data in rows and columns, Vector DBs store data in high-dimensional space, allowing for more efficient and accurate similarity searches. Tools like Weaviate and Milvus are designed to handle massive datasets, making them ideal for tasks like image recognition, recommendation systems, and more. The rise of Vector DBs represents a broader trend in AI: the quest for more efficient, scalable, and versatile data handling solutions. As we navigate this evolution, it\\'s clear that the combination of LLMs and Vector DBs will redefine how we store, access, and understand data in the AI-driven future. From Agents to OS The AI realm is abuzz with innovations, and one of the most intriguing shifts we\\'re witnessing is the transition from LLM agents to using LLMs as Operating Systems (OS). Let\\'s delve into this evolution and its implications. LLM agents, like AutoGPT, AgentGPT, BabyAGI, and HuggingGPT, have been groundbreaking in automating tasks based on user requests. These agents leverage the power of Language Models (LLMs) to understand and execute commands, making them invaluable in tasks ranging from content generation to data analysis. Their adaptability and intelligence have made them a staple in many AI toolkits. However, the vision for AI doesn\\'t stop there. The concept of LLM as an OS is emerging as the next big thing. Imagine an operating system where the core is a language model, orchestrating everything around it. Such a system would not just execute tasks but would understand context, anticipate needs, and offer solutions in real time. It\\'s like turning the LLM into the brain of the digital ecosystem, making devices and applications more intuitive and responsive than ever. The move towards LLM as OS signifies a paradigm shift in how we perceive and utilize AI. It\\'s not just about automation anymore; it\\'s about creating a seamless, intelligent interface between humans and technology. As we stand on the brink of this transformation, the potential for LLM-driven OS to revolutionize our digital interactions is immense. From Fine-tuning to Plugins The world of LLMs is undergoing a transformative shift, moving from intricate fine-tuning processes to the more dynamic realm of plugins. Let\\'s unpack this evolution. Historically, fine-tuning has been the cornerstone of LLM optimization. There are two primary ways to fine-tune LLMs: feeding data into the LLM in real-time and directly fine-tuning on the LLM. From a technical standpoint, this involves three methods: Transfer Learning: Adapting a pre-trained model to new tasks.Sequential Fine-tuning: Refining models in stages for specific tasks.Task-specific Fine-tuning: Tailoring models for a particular function. Moreover, LLM techniques like In-context learning, Few-shot learning, and Zero-shot learning have further enhanced the model\\'s adaptability, allowing them to understand and generate content with minimal data. However, the future of LLMs is leaning towards plugins. With the introduction of tools like GPT-4 Plugins, the focus is on extending LLMs seamlessly. Instead of running LLMs as a service, they\\'re envisioned as platforms. This means integrating LLMs with various tools, enhancing their capabilities, and offering a more modular and scalable approach to AI applications. The journey from fine-tuning to plugins represents a move from static optimization to dynamic adaptability, ensuring that LLMs remain at the forefront of AI innovation. In a Nutshell The AI domain is witnessing rapid shifts, with LLMs playing a central role. Initially, the move was from LLMs to Multimodal models, expanding from text to include images and sounds. Simultaneously, the trend shifted from LLM connections, which linked external data, to Vector Databases for efficient high-dimensional storage. Another evolution saw LLM agents, which automated tasks, transitioning towards LLMs as Operating Systems. This change aims for more intuitive, context-aware devices and applications. Furthermore, the traditional fine-tuning processes of LLMs are now being replaced by dynamic plugins, turning LLMs into platforms integrated with various tools. Leading this LLM revolution are OpenAI\\'s GPT-4 and Meta\\'s LLaMA2. Their pioneering efforts are setting the stage for an AI future that\\'s more integrated, responsive, and attuned to human interactions. More Readings Harnessing the Power of LLMs in Practice: A Survey on ChatGPT and Beyond: https://arxiv.org/abs/2304.13712Sparks of Artificial General Intelligence: Early experiments with GPT-4: https://arxiv.org/abs/2303.12712GPT4All-J: https://huggingface.co/nomic-ai/gpt4all-jIntroducing Code Llama, a state-of-the-art large language model for coding: https://ai.meta.com/blog/code-llama-large-language-model-coding/Llama 2: Open Foundation and Fine-Tuned Chat Models: https://ai.meta.com/research/publications/llama-2-open-foundation-and-fine-tuned-chat-models/', mimetype='text/plain', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n')" ] }, "metadata": {}, "execution_count": 9 } ], "source": [ "documents[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "S17g2RYOjmf2" }, "source": [ "# Transforming\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "STACTMUR1z9N" }, "outputs": [], "source": [ "from llama_index.core.node_parser import TokenTextSplitter\n", "from llama_index.core.schema import BaseNode\n", "import hashlib\n", "\n", "\n", "def deterministic_id_func(i: int, doc: BaseNode) -> str:\n", " \"\"\"Deterministic ID function for the text splitter.\n", " This will be used to generate a unique repeatable identifier for each node.\"\"\"\n", " unique_identifier = doc.id_ + str(i)\n", " hasher = hashlib.sha256()\n", " hasher.update(unique_identifier.encode(\"utf-8\"))\n", " return hasher.hexdigest()\n", "\n", "\n", "text_splitter = TokenTextSplitter(\n", " separator=\" \", chunk_size=512, chunk_overlap=128, id_func=deterministic_id_func\n", ")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "id": "CtdsIUQ81_hT", "outputId": "b97984d9-9639-42d8-fb51-de036e38e274", "colab": { "base_uri": "https://localhost:8080/", "height": 81, "referenced_widgets": [ "6a5b3fec3572436f97ed97b570f15984", "9d28cdd8504e429d85b9849c4f679085", "b4bbbd97b95e4e79b1923aabd512e4c7", "3b66c8f4087b4df5a9eb84b7dc82e440", "9639bc37437145c1af00c627da831e2e", "960a9f07924c4722b42332c9a3b233a8", "9dd071e120884e88b44101bd4b252342", "911b081e2a144929a67a0ef8e425706e", "4bddc051ddc744dcb6efdd74e841bf00", "4ea27a5184b2446aba68157bd1cb0d2d", "9e87cc59ae8c4fa1b3b710b83a371590", "847dfcd1770b4352bc839db928f0834a", "d013604d2eb4432b850f451d86fc5e90", "8893726a2ae0488fa04b1c12ef38fd01", "74be1acb609041ecbecb662c1613575c", "8e728820e82542e1a4aa440e043e23c2", "b1661862e73d4b898daa82a61128a7fa", "d282aabfe99642a699d1aab1122a2806", "39cbcd4e42ae4af782caf71e3529c459", "4f121d46026d4435ba35448c8da3be50", "bebe97dd44e94312ad185632f15caddc", "45d27d06f7da4f80a31a0347d77f075d" ] } }, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "Parsing nodes: 0%| | 0/14 [00:00: RelatedNodeInfo(node_id='doc_0', node_type=, metadata={'title': \"Beyond GPT-4: What's New?\", 'url': 'https://pub.towardsai.net/beyond-gpt-4-whats-new-cbd61a448eb9#dda8', 'source_name': 'towards_ai'}, hash='3b095b0e25cdf965d950cdbd7feb8024030e7645998c1a33dc4427affca624ab'), : RelatedNodeInfo(node_id='e470fa0d001e50b3ec3088022462a94ea7c87dd80106411b7d120f90b379e977', node_type=, metadata={}, hash='71418de3d50e604c2581574f1abf2248e5cc3ab7c74a3182c37cb1152d0cfd21')}, text='LLM Variants and Meta\\'s Open Source Before shedding light on four major trends, I\\'d share the latest Meta\\'s Llama 2 and Code Llama. Meta\\'s Llama 2 represents a sophisticated evolution in LLMs. This suite spans models pretrained and fine-tuned across a parameter spectrum of 7 billion to 70 billion. A specialized derivative, Llama 2-Chat, has been engineered explicitly for dialogue-centric applications. Benchmarking revealed Llama 2\\'s superior performance over most extant open-source chat models. Human-centric evaluations, focusing on safety and utility metrics, positioned Llama 2-Chat as a potential contender against proprietary, closed-source counterparts. The development trajectory of Llama 2 emphasized rigorous fine-tuning methodologies. Meta\\'s transparent delineation of these processes aims to catalyze community-driven advancements in LLMs, underscoring a commitment to collaborative and responsible AI development. Code Llama is built on top of Llama 2 and is available in three models: Code Llama, the foundational code model;Codel Llama - Python specialized for Python;and Code Llama - Instruct, which is fine-tuned for understanding natural language instructions. Based on its benchmark testing, Code Llama outperformed state-of-the-art publicly available LLMs (except GPT-4) on code tasks. Llama 2, Llama 2-Chat, and Code Llama are key steps in LLM development but still have a way to go compared to GPT-4. Meta\\'s open access and commitment to improving these models promise transparent and faster LLM progress in the future. Please refer to the LLM and Llama variants below: From LLMs to Multimodal LLMs, like OpenAI\\'s ChatGPT (GPT-3.5), primarily focus on understanding and generating human language. They\\'ve been instrumental in tasks like text generation, translation, and even creative writing. However, their scope is limited to text. Enter multimodal models like GPT-4. These are a new breed of AI models that can understand and generate not just text, but also images, sounds, and potentially other types of data. The term \"multimodal\" refers to their ability to process multiple modes or', mimetype='text/plain', start_char_idx=0, end_char_idx=2117, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n')" ] }, "metadata": {}, "execution_count": 12 } ], "source": [ "nodes[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "EV0ll57p46Dc" }, "source": [ "# Load Indexes\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "id": "HbT3-kRO4Qpt" }, "outputs": [], "source": [ "# Create your index\n", "from llama_index.core import VectorStoreIndex\n", "\n", "index = VectorStoreIndex.from_vector_store(vector_store)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "id": "sb61DWU84bHP" }, "outputs": [], "source": [ "from llama_index.llms.gemini import Gemini\n", "\n", "# Define a query engine that is responsible for retrieving related pieces of text,\n", "# and using a LLM to formulate the final answer.\n", "\n", "llm = Gemini(model=\"models/gemini-1.5-flash\", temperature=0.3, max_tokens=512)\n", "query_engine = index.as_query_engine(llm=llm, similarity_top_k=5)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "id": "G32W2LMMCmnv" }, "outputs": [], "source": [ "res = query_engine.query(\"How many parameters LLaMA 2 model has?\")" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 35 }, "id": "obc20cU5Cxf2", "outputId": "c9ca8f2d-91e5-4333-b799-1ef1584eb85e" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "'The Llama2 model has 7 billion parameters. \\n'" ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" } }, "metadata": {}, "execution_count": 16 } ], "source": [ "res.response" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "oIAO-saJCzYe", "outputId": "13661c3b-8192-47c6-c4d5-cffd2993de79" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Node ID\t de49ab9024a434ca1cd1efba258fbaa9a3e2d9a1bca3ab4a0349220cc1e2754f\n", "Title\t Building a Q&A Bot over Private Documents with OpenAI and LangChain\n", "Text\t Private data to be used The example provided can be used with any dataset. I am using a data set that has Analyst recommendations from various stocks. For the purpose of demonstration, I have gathered publicly available analyst recommendations to showcase its capabilities. You can replace this with your own information to try this. Below is a partial extract of the information commonly found in these documents. If you wish to try it yourself, you can download analyst recommendations for your preferred stocks from online sources or access them through subscription platforms like Barron's. Although the example provided focuses on analyst recommendations, the underlying structure can be utilized to query various other types of documents in any industry as well. I have assembled such data for a few stocks for demonstration purposes. This includes Google, Microsoft, Meta, and Tesla. To facilitate easy access and updating of analysts' recommendations, all the recommendations can be organized into a designated folder. Each stock corresponds to a separate file within this folder. For example, if there are recommendations for 20 stocks, there will be 20 individual files. This organization enables convenient updating of information for each stock as new recommendations arrive, streamlining the process of managing and maintaining the most up-to-date data for each stock. Questions this Q&A bot application can answer The data we have for this application is stock market analyst recommendations for many stocks. Let's say you are looking for insight about Microsoft stock. You can ask any of the following questions as an example: What is the median target price for Microsoft (MSFT)?What is the highest price estimate for Microsoft (MSFT)?What is the lowest price estimate for Microsoft (MSFT)?How much percentage increase is expected in the stock price of Microsoft (MSFT)?How many analysts provided price forecasts for Microsoft (MSFT)?What is the current consensus among investment analysts regarding Microsoft (MSFT)?Has the consensus rating for Microsoft (MSFT) changed recently?When was the consensus rating last updated for Microsoft (MSFT)?Is the current recommendation for Microsoft (MSFT) to buy, sell, or hold the stock?Are there any recent analyst reports available for Microsoft (MSFT)? These questions cover various aspects of the stock analysis, including price forecasts, analyst recommendations, and recent changes in ratings. The\n", "Score\t 0.14514275574970692\n", "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n", "Node ID\t ef0097732e6eed361247a1081f21a3688bdcfff0d8ec6db66c2bfd6381359bf0\n", "Title\t Exploring Large Language Models -Part 3\n", "Text\t is, does not result in proper output to questions. The answers are not affected by the training data. Take 2: Instruct Fine-tuning with QLoRa Instruction Tuning concept is a higher-level training concept introduced by this paper FineTuned Language Models Are Zero shot Learners (FLAN) We leverage the intuition that NLP tasks can be described via natural language instructions, such as \"Is the sentiment of this movie review positive or negative?\" or \"Translate 'how are you' into Chinese.\" We take a pre-trained language model of 137B parameters and perform instruction tuning ... Since we use QLoRa we are effectively closely following this paper - QLORA: Efficient Finetuning of Quantized LLMs concerning the training data set, the format that the authors used to train their Gauanco model This is the format for the Llama2 model and will be different for others. One of the hardest problems of training is finding or creating a good quality data set to train. In our case, converting the available training data set to the instruction data set. Since our use case is Closed Book QA, we need to convert this to a QA format. Using older NLP methods like NER (Named Entity Recognition) and then using that to create a QA dataset was not effective. This is where the Self-instruct concept could be used However previous to Llama2, the best-performing model was the GPT 3/4 model via ChatGPT or its API and using these models to do the same was expensive. The 7 billion model of Llama2 has sufficient NLU (Natural Language Understanding) to create output based on a particular format. Running this in 4-bit mode via Quantisation makes it feasible compute-wise to run this on a large data set and convert it to a QA dataset. This was the prompt used. The context was a sliding window from the text dataset. Some minimal parsing and finetuning were done on the output of the model, and we could generate a QA dataset of the format below. This was fed to the QLoRA-based fine-tuning (Colab Notebook). We can see that the output from a fine-tuned 4-bit quantized llama2 7 B model is pretty good. Colab Notebook Trying to\n", "Score\t 0.14320868766475625\n", "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n", "Node ID\t 7c0ff552ae4caad1b5fa1914f8c5ea0c907705192580cc127e76b245221805c1\n", "Title\t Foundation Models: Scaling Large Language Models\n", "Text\t AI, providing a versatile and adaptable approach to solving complex problems across multiple domains. From language and vision to robotics and reasoning, these models are unlocking new possibilities and driving innovation across various industries. As we continue to explore the full potential of foundation models and their role in the evolution towards AGI, it is crucial to foster responsible and ethical AI development, ensuring these models are used to benefit humanity and address the most pressing challenges of our time. With foundation models as a solid basis, we can accelerate AI research and development, unlocking new frontiers and shaping the future of intelligent systems. LLMs Papers GPT-4 Technical Report: https://arxiv.org/abs/2303.08774GPT-3: Language Models are Few-Shot Learners: https://arxiv.org/abs/2005.14165Toolformer: Language Models Can Teach Themselves to Use Tools: https://arxiv.org/abs/2302.04761LLaMA: Open and Efficient Foundation Language Models: https://arxiv.org/abs/2302.13971Google USM: Scaling Automatic Speech Recognition Beyond 100 Languages: https://arxiv.org/abs/2303.01037Using DeepSpeed and Megatron to Train Megatron-Turing NLG 530B, A Large-Scale Generative Language Model: https://arxiv.org/abs/2201.11990 Foundation Models Resources Reflections on Foundation Models: https://hai.stanford.edu/news/reflections-foundation-modelsOn the Opportunities and Risks of Foundation Models: https://arxiv.org/abs/2108.07258\n", "Score\t 0.1430069728266482\n", "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n", "Node ID\t b5eeda2ed7d31c3d4f55c6dd4d95f8c3bc0c4a14e3ef371f92770f124632dbef\n", "Title\t Exploring Large Language Models -Part 3\n", "Text\t a particular format. Running this in 4-bit mode via Quantisation makes it feasible compute-wise to run this on a large data set and convert it to a QA dataset. This was the prompt used. The context was a sliding window from the text dataset. Some minimal parsing and finetuning were done on the output of the model, and we could generate a QA dataset of the format below. This was fed to the QLoRA-based fine-tuning (Colab Notebook). We can see that the output from a fine-tuned 4-bit quantized llama2 7 B model is pretty good. Colab Notebook Trying to reduce hallucination via fine-tuning In the generated dataset, I added a specific tag `Source:8989REF`. The idea was that via attention, this token will be somehow associated with the text that we were training on. And then to use this hash somehow to tweak the prompt to control hallucination. Something like \"[INST] <>\\nYou are a helpful Question Answering Assistant. Please only answer from this reference Source:8989REF\" However, that turned out to be a very naive attempt. Also, note that the generated QA missed transforming training data related to Professor Thiersch's method to a proper QA dataset. These and other improvements need to be experimented with, as well as to train with some completely new data that the model has not seen to test more effectively. Update: Training with new data was done by writing an imaginary story with ChatGPT help and then creating an instruction tuning data set (colab notebook). The model was then trained and tested (colab notebook) with this generated instruct dataset. The results confirm that the model learns via Instruct tuning, not only the fed questions but other details and relations of the domain. Problems with hallucinations remain (Bordor, Lila characters who are not in the story). The LLama2 13B 4-bit fine-tuned model has better output than the 7B model. A lot more needs to be explored in Fine-tuning. One observation is that slight changes in prompts give different answers. Since the output is not deterministic (that is, with even the same prompt, it varies over time), it is all the more difficult to fine-tune prompts to\n", "Score\t 0.14165182982721075\n", "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n", "Node ID\t 15268fd9c2a45644a0c49ca1b4897b4fabfe3005fccee48af0acc7eea7dd0e9c\n", "Title\t Building a Q&A Bot over Private Documents with OpenAI and LangChain\n", "Text\t much percentage increase is expected in the stock price of Microsoft (MSFT)?How many analysts provided price forecasts for Microsoft (MSFT)?What is the current consensus among investment analysts regarding Microsoft (MSFT)?Has the consensus rating for Microsoft (MSFT) changed recently?When was the consensus rating last updated for Microsoft (MSFT)?Is the current recommendation for Microsoft (MSFT) to buy, sell, or hold the stock?Are there any recent analyst reports available for Microsoft (MSFT)? These questions cover various aspects of the stock analysis, including price forecasts, analyst recommendations, and recent changes in ratings. The chat system can provide specific answers based on the information available in the financial documents. Please note that you can not only ask questions about an individual stock but can also ask comparative questions across stocks. For example, which stock has the most price increase? Here the system will compare the price increase across all the stocks and provide an answer. Quick summary of how the web application works This web-based application allows users to input their questions in a text box and receive answers based on insights gathered from multiple documents. For instance, users can inquire, \"What is the highest price estimate for Microsoft?\" and the application will query the relevant documents to provide an accurate response. Moreover, users can also compare stocks by asking questions such as, \"Which stock, Meta or Microsoft, has a higher percentage increase in the stock price?\" The application will analyze the data across the documents, enabling users to make informed investment decisions based on the comparative insights provided. Application Overview The application is built with LangChain and ChatGPT. Though it uses ChatGPT, we can also wire this to other LLMs as well. LangChain is an innovative framework designed to empower you in building sophisticated applications driven by large language models (LLMs). By offering a standardized interface, LangChain facilitates the seamless integration of various components, including LLMs, data sources, and actions. This streamlined approach accelerates the development of robust applications, enhanced by features such as chaining, data awareness, and agentic capabilities. To complement LangChain, the web application is built utilizing Streamlit, a Python library for creating interactive web applications and data dashboards. Streamlit's\n", "Score\t 0.14137764389568408\n", "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n" ] } ], "source": [ "for src in res.source_nodes:\n", " print(\"Node ID\\t\", src.node_id)\n", " print(\"Title\\t\", src.metadata[\"title\"])\n", " print(\"Text\\t\", src.text)\n", " print(\"Score\\t\", src.score)\n", " print(\"-_\" * 20)" ] }, { "cell_type": "markdown", "metadata": { "id": "d4xxZHbdN0lK" }, "source": [ "# Evaluate the retrieval process and quality of answers\n", "\n", "We can evaluate our RAG system with a dataset of questions and associated chunks. Given a question, we can see if the RAG system retrieves the correct chunks of text that can answer the question.\n", "\n", "You can generate a synthetic dataset with an LLM such as `gemini-1.5-flash` or create an authentic and manually curated dataset.\n", "\n", "Note that a **well curated dataset will always be a better option**, especially for a specific domain or use case.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "SuYIj1tD1Hwv" }, "source": [ "In our example, we will generate a synthetic dataset using `gemini-1.5-flash` to make it simple.\n", "\n", "This is the default prompt that the `generate_question_context_pairs` function will uses:\n", "\n", "```python\n", "DEFAULT_QA_GENERATE_PROMPT_TMPL = \"\"\"\\\n", "Context information is below.\n", "\n", "---------------------\n", "{context_str}\n", "---------------------\n", "\n", "Given the context information and no prior knowledge,\n", "generate only questions based on the below query.\n", "\n", "You are a Teacher/Professor. Your task is to setup \\\n", "{num_questions_per_chunk} questions for an upcoming \\\n", "quiz/examination. The questions should be diverse in nature \\\n", "across the document. Restrict the questions to the \\\n", "context information provided.\"\n", "\"\"\"\n", "```\n" ] }, { "cell_type": "code", "source": [ "# Free Tier-Gemini API key\n", "from llama_index.core.llms.utils import LLM\n", "from llama_index.core.schema import MetadataMode, TextNode\n", "from tqdm import tqdm\n", "import json\n", "import re\n", "import uuid\n", "import warnings\n", "import time\n", "from typing import Dict, List, Tuple\n", "from llama_index.core.evaluation import EmbeddingQAFinetuneDataset\n", "\n", "DEFAULT_QA_GENERATE_PROMPT_TMPL = \"\"\"\\\n", "Context information is below.\n", "\n", "---------------------\n", "{context_str}\n", "---------------------\n", "\n", "Given the context information and not prior knowledge.\n", "generate only questions based on the below query.\n", "\n", "You are a Teacher/ Professor. Your task is to setup \\\n", "{num_questions_per_chunk} questions for an upcoming \\\n", "quiz/examination. The questions should be diverse in nature \\\n", "across the document. Restrict the questions to the \\\n", "context information provided.\"\n", "\"\"\"\n", "\n", "def generate_question_context_pairs(\n", " nodes: List[TextNode],\n", " llm: LLM,\n", " qa_generate_prompt_tmpl: str = DEFAULT_QA_GENERATE_PROMPT_TMPL,\n", " num_questions_per_chunk: int = 2,\n", " request_delay: float = 2.0\n", ") -> EmbeddingQAFinetuneDataset:\n", " \"\"\"Generate examples given a set of nodes with delays between requests.\"\"\"\n", " node_dict = {\n", " node.node_id: node.get_content(metadata_mode=MetadataMode.NONE)\n", " for node in nodes\n", " }\n", "\n", " queries = {}\n", " relevant_docs = {}\n", "\n", " for node_id, text in tqdm(node_dict.items()):\n", " query = qa_generate_prompt_tmpl.format(\n", " context_str=text, num_questions_per_chunk=num_questions_per_chunk\n", " )\n", " response = llm.complete(query)\n", "\n", " result = str(response).strip().split(\"\\n\")\n", " questions = [\n", " re.sub(r\"^\\d+[\\).\\s]\", \"\", question).strip() for question in result\n", " ]\n", " questions = [question for question in questions if len(question) > 0][\n", " :num_questions_per_chunk\n", " ]\n", "\n", " num_questions_generated = len(questions)\n", " if num_questions_generated < num_questions_per_chunk:\n", " warnings.warn(\n", " f\"Fewer questions generated ({num_questions_generated}) \"\n", " f\"than requested ({num_questions_per_chunk}).\"\n", " )\n", "\n", " for question in questions:\n", " question_id = str(uuid.uuid4())\n", " queries[question_id] = question\n", " relevant_docs[question_id] = [node_id]\n", "\n", " time.sleep(request_delay)\n", "\n", " return EmbeddingQAFinetuneDataset(\n", " queries=queries, corpus=node_dict, relevant_docs=relevant_docs\n", " )\n", "\n", "#from llama_index.core.evaluation import generate_question_context_pairs\n", "from llama_index.llms.gemini import Gemini\n", "\n", "llm = Gemini(model=\"models/gemini-1.5-flash\", temperature=1, max_tokens=512)\n", "\n", "rag_eval_dataset = generate_question_context_pairs(\n", " nodes[:25],\n", " llm=llm,\n", " num_questions_per_chunk=1,\n", " request_delay=4\n", ")\n", "\n", "# Save the dataset as a json file for later use\n", "rag_eval_dataset.save_json(\"./rag_eval_dataset.json\")\n" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 34 }, "id": "_kCbMX67TqG-", "outputId": "84034294-ba9b-4d5a-baeb-b2c250180045" }, "execution_count": 18, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "100%|██████████| 25/25 [02:41<00:00, 6.46s/it]\n" ] } ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "id": "jhHLA3he1Hww", "collapsed": true }, "outputs": [], "source": [ "# #Paid-Gemini API Key\n", "\n", "# from llama_index.core.evaluation import generate_question_context_pairs\n", "# from llama_index.llms.gemini import Gemini\n", "\n", "# llm = Gemini(model=\"models/gemini-1.5-flash\", temperature=1, max_tokens=512)\n", "# rag_eval_dataset = generate_question_context_pairs(nodes, llm=llm, num_questions_per_chunk=1)\n", "\n", "# # We can save the dataset as a json file for later use.\n", "# rag_eval_dataset.save_json(\"./rag_eval_dataset.json\")" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "id": "mNDd5i921Hww" }, "outputs": [], "source": [ "# We can also load the dataset from a previously saved json file.\n", "from llama_index.core.evaluation import EmbeddingQAFinetuneDataset\n", "\n", "rag_eval_dataset = EmbeddingQAFinetuneDataset.from_json(\"./rag_eval_dataset.json\")" ] }, { "cell_type": "markdown", "metadata": { "id": "qOx3vDWA1Hww" }, "source": [ "### Evaluation for Hit Rate and Mean Reciprocal Rank (MRR)\n", "\n", "We will make use of `RetrieverEvaluator` available in Llama-index. We will measure the Hit Rate and Mean Reciprocal Rank (MRR).\n", "\n", "**Hit Rate:**\n", "\n", "Think of the Hit Rate like playing a game of guessing. You're given a question and you need to guess the correct answer from a list of options. The Hit Rate measures how often you guess the correct answer by only looking at your top few guesses. If you often find the right answer in your first few guesses, you have a high Hit Rate. So, in the context of a retrieval system, it's about how frequently the system finds the correct document within its top 'k' picks (where 'k' is a number you decide, like top 5 or top 10).\n", "\n", "**Mean Reciprocal Rank (MRR):**\n", "\n", "MRR is a bit like measuring how quickly you can find a treasure in a list of boxes. Imagine you have a row of boxes and only one of them has a treasure. The MRR calculates how close to the start of the row the treasure box is, on average. If the treasure is always in the first box you open, you're doing great and have an MRR of 1. If it's in the second box, the score is 1/2, since you took two tries to find it. If it's in the third box, your score is 1/3, and so on. MRR averages these scores across all your searches. So, for a retrieval system, MRR looks at where the correct document ranks in the system's guesses. If it's usually near the top, the MRR will be high, indicating good performance.\n", "In summary, Hit Rate tells you how often the system gets it right in its top guesses, and MRR tells you how close to the top the right answer usually is. Both metrics are useful for evaluating the effectiveness of a retrieval system, like how well a search engine or a recommendation system works.\n" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "id": "eARSzx8I1Hww" }, "outputs": [], "source": [ "import pandas as pd\n", "\n", "\n", "def display_results_retriever(name, eval_results):\n", " \"\"\"Display results from evaluate.\"\"\"\n", "\n", " metric_dicts = []\n", " for eval_result in eval_results:\n", " metric_dict = eval_result.metric_vals_dict\n", " metric_dicts.append(metric_dict)\n", "\n", " full_df = pd.DataFrame(metric_dicts)\n", "\n", " hit_rate = full_df[\"hit_rate\"].mean()\n", " mrr = full_df[\"mrr\"].mean()\n", "\n", " metric_df = pd.DataFrame(\n", " {\"Retriever Name\": [name], \"Hit Rate\": [hit_rate], \"MRR\": [mrr]}\n", " )\n", "\n", " return metric_df" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "id": "hD5YflG51Hww", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "53a0b810-b589-4735-faab-5f1d0f4ebcf9" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ " Retriever Name Hit Rate MRR\n", "0 Retriever top_4 0.12 0.043333\n", " Retriever Name Hit Rate MRR\n", "0 Retriever top_6 0.16 0.05\n", " Retriever Name Hit Rate MRR\n", "0 Retriever top_8 0.2 0.055714\n", " Retriever Name Hit Rate MRR\n", "0 Retriever top_10 0.24 0.060159\n" ] } ], "source": [ "from llama_index.core.evaluation import RetrieverEvaluator\n", "\n", "# We can evaluate the retievers with different top_k values.\n", "for i in [2, 4, 6, 8, 10]:\n", " retriever = index.as_retriever(similarity_top_k=i)\n", " retriever_evaluator = RetrieverEvaluator.from_metric_names(\n", " [\"mrr\", \"hit_rate\"], retriever=retriever\n", " )\n", " eval_results = await retriever_evaluator.aevaluate_dataset(\n", " rag_eval_dataset, workers=32\n", " )\n", " print(display_results_retriever(f\"Retriever top_{i}\", eval_results))\n", "\n", "time.sleep(60)" ] }, { "cell_type": "markdown", "metadata": { "id": "9y6uofcJ1Hwx" }, "source": [ "### Evaluation using Relevance and Faithfulness metrics.\n", "\n", "Here, we evaluate the answer generated by the LLM. Is the answer using the correct context? Is the answer faithful to the context? Is the answer relevant to the question?\n", "\n", "An LLM will answer these questions, more specifically `gpt-4o`.\n", "\n", "**`FaithfulnessEvaluator`**\n", "Evaluates if the answer is faithful to the retrieved contexts (in other words, whether there's an hallucination).\n", "\n", "**`RelevancyEvaluator`**\n", "Evaluates whether the retrieved context and answer are relevant to the user question.\n", "\n", "Now, let's see how the top_k value affects these two metrics.\n" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "id": "ckjE4fcD1Hwx", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "ef15f35f-5010-441f-e023-caa5e68489ea" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "top_2 faithfulness_score: 0.25\n", "top_2 relevancy_score: 0.6\n", "===============\n", "top_4 faithfulness_score: 0.1\n", "top_4 relevancy_score: 0.95\n", "===============\n", "top_6 faithfulness_score: 0.2\n", "top_6 relevancy_score: 0.9\n", "===============\n", "top_8 faithfulness_score: 0.1\n", "top_8 relevancy_score: 0.6\n", "===============\n", "top_10 faithfulness_score: 0.05\n", "top_10 relevancy_score: 0.55\n", "===============\n" ] } ], "source": [ "from llama_index.core.evaluation import RelevancyEvaluator, FaithfulnessEvaluator, BatchEvalRunner\n", "from llama_index.llms.openai import OpenAI\n", "\n", "# Create your index\n", "from llama_index.core import VectorStoreIndex\n", "index = VectorStoreIndex.from_vector_store(vector_store)\n", "\n", "# Define an LLM as a judge\n", "llm_gpt4o = OpenAI(temperature=0, model=\"gpt-4o\")\n", "llm_gpt4o_mini = OpenAI(temperature=0, model=\"gpt-4o-mini\")\n", "\n", "# Initiate the faithfulnes and relevancy evaluator objects\n", "faithfulness_evaluator = FaithfulnessEvaluator(llm=llm_gpt4o)\n", "relevancy_evaluator = RelevancyEvaluator(llm=llm_gpt4o)\n", "\n", "# Extract the questions from the dataset\n", "queries = list(rag_eval_dataset.queries.values())\n", "# Limit to first 10 question to save time (!!remove this line in production!!)\n", "batch_eval_queries = queries[:20]\n", "\n", "# The batch evaluator runs the evaluation in batches\n", "runner = BatchEvalRunner(\n", " {\"faithfulness\": faithfulness_evaluator, \"relevancy\": relevancy_evaluator},\n", " workers=32,\n", ")\n", "\n", "\n", "# Define a for-loop to try different `similarity_top_k` values\n", "for i in [2, 4, 6, 8, 10]:\n", " # Set query engine with different number of returned chunks\n", " query_engine = index.as_query_engine(similarity_top_k=i, llm = llm_gpt4o_mini)\n", "\n", " # Run the evaluation\n", " eval_results = await runner.aevaluate_queries(query_engine, queries=batch_eval_queries)\n", "\n", " # Printing the results\n", " faithfulness_score = sum(\n", " result.passing for result in eval_results[\"faithfulness\"]\n", " ) / len(eval_results[\"faithfulness\"])\n", " print(f\"top_{i} faithfulness_score: {faithfulness_score}\")\n", "\n", " relevancy_score = sum(result.passing for result in eval_results[\"relevancy\"]) / len(\n", " eval_results[\"relevancy\"]\n", " )\n", " print(f\"top_{i} relevancy_score: {relevancy_score}\")\n", " print(\"=\"*15)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "YmlmP2Px4THB" }, "source": [ "### Correctness\n" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "id": "aUulxzuh1Hwx" }, "outputs": [], "source": [ "from llama_index.core.evaluation import CorrectnessEvaluator\n", "\n", "query = (\n", " \"Can you explain the theory of relativity proposed by Albert Einstein in\" \" detail?\"\n", ")\n", "\n", "reference = \"\"\"\n", "Certainly! Albert Einstein's theory of relativity consists of two main components: special relativity and general relativity. Special relativity, published in 1905, introduced the concept that the laws of physics are the same for all non-accelerating observers and that the speed of light in a vacuum is a constant, regardless of the motion of the source or observer. It also gave rise to the famous equation E=mc², which relates energy (E) and mass (m).\n", "\n", "General relativity, published in 1915, extended these ideas to include the effects of gravity. According to general relativity, gravity is not a force between masses, as described by Newton's theory of gravity, but rather the result of the warping of space and time by mass and energy. Massive objects, such as planets and stars, cause a curvature in spacetime, and smaller objects follow curved paths in response to this curvature. This concept is often illustrated using the analogy of a heavy ball placed on a rubber sheet, causing it to create a depression that other objects (representing smaller masses) naturally move towards.\n", "\n", "In essence, general relativity provided a new understanding of gravity, explaining phenomena like the bending of light by gravity (gravitational lensing) and the precession of the orbit of Mercury. It has been confirmed through numerous experiments and observations and has become a fundamental theory in modern physics.\n", "\"\"\"\n", "\n", "response = \"\"\"\n", "Certainly! Albert Einstein's theory of relativity consists of two main components: special relativity and general relativity. Special relativity, published in 1905, introduced the concept that the laws of physics are the same for all non-accelerating observers and that the speed of light in a vacuum is a constant, regardless of the motion of the source or observer. It also gave rise to the famous equation E=mc², which relates energy (E) and mass (m).\n", "\n", "However, general relativity, published in 1915, extended these ideas to include the effects of magnetism. According to general relativity, gravity is not a force between masses but rather the result of the warping of space and time by magnetic fields generated by massive objects. Massive objects, such as planets and stars, create magnetic fields that cause a curvature in spacetime, and smaller objects follow curved paths in response to this magnetic curvature. This concept is often illustrated using the analogy of a heavy ball placed on a rubber sheet with magnets underneath, causing it to create a depression that other objects (representing smaller masses) naturally move towards due to magnetic attraction.\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "id": "CYIjkAP74bly" }, "outputs": [], "source": [ "evaluator = CorrectnessEvaluator(llm=llm_gpt4o)\n", "\n", "result = evaluator.evaluate(query=query,response=response,reference=reference,)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "id": "-3b-bgvA4dAz", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "84fdccf9-6fd0-402e-b10a-3158a9eb7613" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2.0" ] }, "metadata": {}, "execution_count": 26 } ], "source": [ "result.score" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "id": "KNEhRQAo4dT0", "colab": { "base_uri": "https://localhost:8080/", "height": 70 }, "outputId": "c39199f3-ecba-434e-b1f6-2907168dc2c8" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "'The generated answer is mostly relevant but contains significant inaccuracies. It incorrectly states that general relativity involves the effects of magnetism and magnetic fields, which is not true. General relativity deals with the warping of space and time by mass and energy, not magnetic fields. This fundamental error reduces the correctness of the answer.'" ], "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" } }, "metadata": {}, "execution_count": 27 } ], "source": [ "result.feedback" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "id": "ZOlwVWZb49H4" }, "outputs": [], "source": [] } ], "metadata": { "colab": { "provenance": [], "include_colab_link": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.4" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "6a5b3fec3572436f97ed97b570f15984": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_9d28cdd8504e429d85b9849c4f679085", "IPY_MODEL_b4bbbd97b95e4e79b1923aabd512e4c7", "IPY_MODEL_3b66c8f4087b4df5a9eb84b7dc82e440" ], "layout": "IPY_MODEL_9639bc37437145c1af00c627da831e2e" } }, "9d28cdd8504e429d85b9849c4f679085": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_960a9f07924c4722b42332c9a3b233a8", "placeholder": "​", "style": "IPY_MODEL_9dd071e120884e88b44101bd4b252342", "value": "Parsing nodes: 100%" } }, "b4bbbd97b95e4e79b1923aabd512e4c7": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_911b081e2a144929a67a0ef8e425706e", "max": 14, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_4bddc051ddc744dcb6efdd74e841bf00", "value": 14 } }, "3b66c8f4087b4df5a9eb84b7dc82e440": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_4ea27a5184b2446aba68157bd1cb0d2d", "placeholder": "​", "style": "IPY_MODEL_9e87cc59ae8c4fa1b3b710b83a371590", "value": " 14/14 [00:01<00:00,  9.81it/s]" } }, "9639bc37437145c1af00c627da831e2e": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "960a9f07924c4722b42332c9a3b233a8": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9dd071e120884e88b44101bd4b252342": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "model_module_version": "1.5.0", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "911b081e2a144929a67a0ef8e425706e": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4bddc051ddc744dcb6efdd74e841bf00": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "model_module_version": "1.5.0", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "4ea27a5184b2446aba68157bd1cb0d2d": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9e87cc59ae8c4fa1b3b710b83a371590": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "model_module_version": "1.5.0", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "847dfcd1770b4352bc839db928f0834a": { "model_module": "@jupyter-widgets/controls", "model_name": "HBoxModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_d013604d2eb4432b850f451d86fc5e90", "IPY_MODEL_8893726a2ae0488fa04b1c12ef38fd01", "IPY_MODEL_74be1acb609041ecbecb662c1613575c" ], "layout": "IPY_MODEL_8e728820e82542e1a4aa440e043e23c2" } }, "d013604d2eb4432b850f451d86fc5e90": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_b1661862e73d4b898daa82a61128a7fa", "placeholder": "​", "style": "IPY_MODEL_d282aabfe99642a699d1aab1122a2806", "value": "Generating embeddings: 100%" } }, "8893726a2ae0488fa04b1c12ef38fd01": { "model_module": "@jupyter-widgets/controls", "model_name": "FloatProgressModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_39cbcd4e42ae4af782caf71e3529c459", "max": 108, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_4f121d46026d4435ba35448c8da3be50", "value": 108 } }, "74be1acb609041ecbecb662c1613575c": { "model_module": "@jupyter-widgets/controls", "model_name": "HTMLModel", "model_module_version": "1.5.0", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_bebe97dd44e94312ad185632f15caddc", "placeholder": "​", "style": "IPY_MODEL_45d27d06f7da4f80a31a0347d77f075d", "value": " 108/108 [00:02<00:00, 39.87it/s]" } }, "8e728820e82542e1a4aa440e043e23c2": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b1661862e73d4b898daa82a61128a7fa": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d282aabfe99642a699d1aab1122a2806": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "model_module_version": "1.5.0", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "39cbcd4e42ae4af782caf71e3529c459": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "4f121d46026d4435ba35448c8da3be50": { "model_module": "@jupyter-widgets/controls", "model_name": "ProgressStyleModel", "model_module_version": "1.5.0", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "bebe97dd44e94312ad185632f15caddc": { "model_module": "@jupyter-widgets/base", "model_name": "LayoutModel", "model_module_version": "1.2.0", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "45d27d06f7da4f80a31a0347d77f075d": { "model_module": "@jupyter-widgets/controls", "model_name": "DescriptionStyleModel", "model_module_version": "1.5.0", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } } } } }, "nbformat": 4, "nbformat_minor": 0 }