diff --git a/tutorials/27_First_RAG_Pipeline.ipynb b/tutorials/27_First_RAG_Pipeline.ipynb index d9467ff..1e5b0b6 100644 --- a/tutorials/27_First_RAG_Pipeline.ipynb +++ b/tutorials/27_First_RAG_Pipeline.ipynb @@ -1,1446 +1,1480 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "2OvkPji9O-qX" - }, - "source": [ - "# Tutorial: Creating Your First QA Pipeline with Retrieval-Augmentation\n", - "\n", - "- **Level**: Beginner\n", - "- **Time to complete**: 10 minutes\n", - "- **Components Used**: [`InMemoryDocumentStore`](https://docs.haystack.deepset.ai/docs/inmemorydocumentstore), [`SentenceTransformersDocumentEmbedder`](https://docs.haystack.deepset.ai/docs/sentencetransformersdocumentembedder), [`SentenceTransformersTextEmbedder`](https://docs.haystack.deepset.ai/docs/sentencetransformerstextembedder), [`InMemoryEmbeddingRetriever`](https://docs.haystack.deepset.ai/docs/inmemoryembeddingretriever), [`PromptBuilder`](https://docs.haystack.deepset.ai/docs/promptbuilder), [`OpenAIGenerator`](https://docs.haystack.deepset.ai/docs/openaigenerator)\n", - "- **Prerequisites**: You must have an [OpenAI API Key](https://platform.openai.com/api-keys).\n", - "- **Goal**: After completing this tutorial, you'll have learned the new prompt syntax and how to use PromptBuilder and OpenAIGenerator to build a generative question-answering pipeline with retrieval-augmentation.\n", - "\n", - "> This tutorial uses Haystack 2.0. To learn more, read the [Haystack 2.0 announcement](https://haystack.deepset.ai/blog/haystack-2-release) or visit the [Haystack 2.0 Documentation](https://docs.haystack.deepset.ai/docs/intro)." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "LFqHcXYPO-qZ" - }, - "source": [ - "## Overview\n", - "\n", - "This tutorial shows you how to create a generative question-answering pipeline using the retrieval-augmentation ([RAG](https://www.deepset.ai/blog/llms-retrieval-augmentation)) approach with Haystack 2.0. The process involves four main components: [SentenceTransformersTextEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformerstextembedder) for creating an embedding for the user query, [InMemoryBM25Retriever](https://docs.haystack.deepset.ai/docs/inmemorybm25retriever) for fetching relevant documents, [PromptBuilder](https://docs.haystack.deepset.ai/docs/promptbuilder) for creating a template prompt, and [OpenAIGenerator](https://docs.haystack.deepset.ai/docs/openaigenerator) for generating responses.\n", - "\n", - "For this tutorial, you'll use the Wikipedia pages of [Seven Wonders of the Ancient World](https://en.wikipedia.org/wiki/Wonders_of_the_World) as Documents, but you can replace them with any text you want.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "QXjVlbPiO-qZ" - }, - "source": [ - "## Preparing the Colab Environment\n", - "\n", - "- [Enable GPU Runtime in Colab](https://docs.haystack.deepset.ai/docs/enabling-gpu-acceleration)\n", - "- [Set logging level to INFO](https://docs.haystack.deepset.ai/docs/logging)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Kww5B_vXO-qZ" - }, - "source": [ - "## Installing Haystack\n", - "\n", - "Install Haystack 2.0 and other required packages with `pip`:" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "2OvkPji9O-qX" + }, + "source": [ + "# Tutorial: Creating Your First QA Pipeline with Retrieval-Augmentation\n", + "\n", + "- **Level**: Beginner\n", + "- **Time to complete**: 10 minutes\n", + "- **Components Used**: [`InMemoryDocumentStore`](https://docs.haystack.deepset.ai/docs/inmemorydocumentstore), [`SentenceTransformersDocumentEmbedder`](https://docs.haystack.deepset.ai/docs/sentencetransformersdocumentembedder), [`SentenceTransformersTextEmbedder`](https://docs.haystack.deepset.ai/docs/sentencetransformerstextembedder), [`InMemoryEmbeddingRetriever`](https://docs.haystack.deepset.ai/docs/inmemoryembeddingretriever), [`PromptBuilder`](https://docs.haystack.deepset.ai/docs/promptbuilder), [`OpenAIChatGenerator`](https://docs.haystack.deepset.ai/docs/openaichatgenerator)\n", + "- **Prerequisites**: You must have an [OpenAI API Key](https://platform.openai.com/api-keys).\n", + "- **Goal**: After completing this tutorial, you'll have learned the new prompt syntax and how to use PromptBuilder and OpenAIChatGenerator to build a generative question-answering pipeline with retrieval-augmentation.\n", + "\n", + "> This tutorial uses Haystack 2.0. To learn more, read the [Haystack 2.0 announcement](https://haystack.deepset.ai/blog/haystack-2-release) or visit the [Haystack 2.0 Documentation](https://docs.haystack.deepset.ai/docs/intro)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LFqHcXYPO-qZ" + }, + "source": [ + "## Overview\n", + "\n", + "This tutorial shows you how to create a generative question-answering pipeline using the retrieval-augmentation ([RAG](https://www.deepset.ai/blog/llms-retrieval-augmentation)) approach with Haystack 2.0. The process involves four main components: [SentenceTransformersTextEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformerstextembedder) for creating an embedding for the user query, [InMemoryBM25Retriever](https://docs.haystack.deepset.ai/docs/inmemorybm25retriever) for fetching relevant documents, [PromptBuilder](https://docs.haystack.deepset.ai/docs/promptbuilder) for creating a template prompt, and [OpenAIChatGenerator](https://docs.haystack.deepset.ai/docs/openaichatgenerator) for generating responses.\n", + "\n", + "For this tutorial, you'll use the Wikipedia pages of [Seven Wonders of the Ancient World](https://en.wikipedia.org/wiki/Wonders_of_the_World) as Documents, but you can replace them with any text you want.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QXjVlbPiO-qZ" + }, + "source": [ + "## Preparing the Colab Environment\n", + "\n", + "- [Enable GPU Runtime in Colab](https://docs.haystack.deepset.ai/docs/enabling-gpu-acceleration)\n", + "- [Set logging level to INFO](https://docs.haystack.deepset.ai/docs/logging)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kww5B_vXO-qZ" + }, + "source": [ + "## Installing Haystack\n", + "\n", + "Install Haystack 2.0 and other required packages with `pip`:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "UQbU8GUfO-qZ", + "outputId": "c33579e9-5557-43bd-a3c5-63b8373770c7" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "UQbU8GUfO-qZ", - "outputId": "c33579e9-5557-43bd-a3c5-63b8373770c7" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: haystack-ai in /usr/local/lib/python3.10/dist-packages (2.0.0b8)\n", - "Requirement already satisfied: boilerpy3 in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (1.0.7)\n", - "Requirement already satisfied: haystack-bm25 in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (1.0.2)\n", - "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (3.1.3)\n", - "Requirement already satisfied: lazy-imports in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (0.3.1)\n", - "Requirement already satisfied: more-itertools in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (10.1.0)\n", - "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (3.2.1)\n", - "Requirement already satisfied: openai>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (1.13.3)\n", - "Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (1.5.3)\n", - "Requirement already satisfied: posthog in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (3.5.0)\n", - "Requirement already satisfied: pyyaml in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (6.0.1)\n", - "Requirement already satisfied: tenacity in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (8.2.3)\n", - "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (4.66.2)\n", - "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (4.10.0)\n", - "Requirement already satisfied: anyio<5,>=3.5.0 in /usr/local/lib/python3.10/dist-packages (from openai>=1.1.0->haystack-ai) (3.7.1)\n", - "Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai>=1.1.0->haystack-ai) (1.7.0)\n", - "Requirement already satisfied: httpx<1,>=0.23.0 in /usr/local/lib/python3.10/dist-packages (from openai>=1.1.0->haystack-ai) (0.27.0)\n", - "Requirement already satisfied: pydantic<3,>=1.9.0 in /usr/local/lib/python3.10/dist-packages (from openai>=1.1.0->haystack-ai) (2.6.3)\n", - "Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from openai>=1.1.0->haystack-ai) (1.3.1)\n", - "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from haystack-bm25->haystack-ai) (1.25.2)\n", - "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->haystack-ai) (2.1.5)\n", - "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas->haystack-ai) (2.8.2)\n", - "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->haystack-ai) (2023.4)\n", - "Requirement already satisfied: requests<3.0,>=2.7 in /usr/local/lib/python3.10/dist-packages (from posthog->haystack-ai) (2.31.0)\n", - "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from posthog->haystack-ai) (1.16.0)\n", - "Requirement already satisfied: monotonic>=1.5 in /usr/local/lib/python3.10/dist-packages (from posthog->haystack-ai) (1.6)\n", - "Requirement already satisfied: backoff>=1.10.0 in /usr/local/lib/python3.10/dist-packages (from posthog->haystack-ai) (2.2.1)\n", - "Requirement already satisfied: idna>=2.8 in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3.5.0->openai>=1.1.0->haystack-ai) (3.6)\n", - "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3.5.0->openai>=1.1.0->haystack-ai) (1.2.0)\n", - "Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from httpx<1,>=0.23.0->openai>=1.1.0->haystack-ai) (2024.2.2)\n", - "Requirement already satisfied: httpcore==1.* in /usr/local/lib/python3.10/dist-packages (from httpx<1,>=0.23.0->openai>=1.1.0->haystack-ai) (1.0.4)\n", - "Requirement already satisfied: h11<0.15,>=0.13 in /usr/local/lib/python3.10/dist-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai>=1.1.0->haystack-ai) (0.14.0)\n", - "Requirement already satisfied: annotated-types>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1.9.0->openai>=1.1.0->haystack-ai) (0.6.0)\n", - "Requirement already satisfied: pydantic-core==2.16.3 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1.9.0->openai>=1.1.0->haystack-ai) (2.16.3)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3.0,>=2.7->posthog->haystack-ai) (3.3.2)\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3.0,>=2.7->posthog->haystack-ai) (2.0.7)\n", - "Requirement already satisfied: datasets>=2.6.1 in /usr/local/lib/python3.10/dist-packages (2.18.0)\n", - "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (3.13.1)\n", - "Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (1.25.2)\n", - "Requirement already satisfied: pyarrow>=12.0.0 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (14.0.2)\n", - "Requirement already satisfied: pyarrow-hotfix in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (0.6)\n", - "Requirement already satisfied: dill<0.3.9,>=0.3.0 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (0.3.8)\n", - "Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (1.5.3)\n", - "Requirement already satisfied: requests>=2.19.0 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (2.31.0)\n", - "Requirement already satisfied: tqdm>=4.62.1 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (4.66.2)\n", - "Requirement already satisfied: xxhash in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (3.4.1)\n", - "Requirement already satisfied: multiprocess in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (0.70.16)\n", - "Requirement already satisfied: fsspec[http]<=2024.2.0,>=2023.1.0 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (2023.6.0)\n", - "Requirement already satisfied: aiohttp in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (3.9.3)\n", - "Requirement already satisfied: huggingface-hub>=0.19.4 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (0.20.3)\n", - "Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (23.2)\n", - "Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from datasets>=2.6.1) (6.0.1)\n", - "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets>=2.6.1) (1.3.1)\n", - "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets>=2.6.1) (23.2.0)\n", - "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets>=2.6.1) (1.4.1)\n", - "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets>=2.6.1) (6.0.5)\n", - "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets>=2.6.1) (1.9.4)\n", - "Requirement already satisfied: async-timeout<5.0,>=4.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->datasets>=2.6.1) (4.0.3)\n", - "Requirement already satisfied: typing-extensions>=3.7.4.3 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.19.4->datasets>=2.6.1) (4.10.0)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.19.0->datasets>=2.6.1) (3.3.2)\n", - "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests>=2.19.0->datasets>=2.6.1) (3.6)\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.19.0->datasets>=2.6.1) (2.0.7)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests>=2.19.0->datasets>=2.6.1) (2024.2.2)\n", - "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas->datasets>=2.6.1) (2.8.2)\n", - "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->datasets>=2.6.1) (2023.4)\n", - "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.1->pandas->datasets>=2.6.1) (1.16.0)\n", - "Requirement already satisfied: sentence-transformers>=2.2.0 in /usr/local/lib/python3.10/dist-packages (2.5.1)\n", - "Requirement already satisfied: transformers<5.0.0,>=4.32.0 in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (4.38.2)\n", - "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (4.66.2)\n", - "Requirement already satisfied: torch>=1.11.0 in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (2.1.0+cu121)\n", - "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (1.25.2)\n", - "Requirement already satisfied: scikit-learn in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (1.2.2)\n", - "Requirement already satisfied: scipy in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (1.11.4)\n", - "Requirement already satisfied: huggingface-hub>=0.15.1 in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (0.20.3)\n", - "Requirement already satisfied: Pillow in /usr/local/lib/python3.10/dist-packages (from sentence-transformers>=2.2.0) (9.4.0)\n", - "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (3.13.1)\n", - "Requirement already satisfied: fsspec>=2023.5.0 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (2023.6.0)\n", - "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (2.31.0)\n", - "Requirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (6.0.1)\n", - "Requirement already satisfied: typing-extensions>=3.7.4.3 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (4.10.0)\n", - "Requirement already satisfied: packaging>=20.9 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (23.2)\n", - "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch>=1.11.0->sentence-transformers>=2.2.0) (1.12)\n", - "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch>=1.11.0->sentence-transformers>=2.2.0) (3.2.1)\n", - "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch>=1.11.0->sentence-transformers>=2.2.0) (3.1.3)\n", - "Requirement already satisfied: triton==2.1.0 in /usr/local/lib/python3.10/dist-packages (from torch>=1.11.0->sentence-transformers>=2.2.0) (2.1.0)\n", - "Requirement already satisfied: regex!=2019.12.17 in /usr/local/lib/python3.10/dist-packages (from transformers<5.0.0,>=4.32.0->sentence-transformers>=2.2.0) (2023.12.25)\n", - "Requirement already satisfied: tokenizers<0.19,>=0.14 in /usr/local/lib/python3.10/dist-packages (from transformers<5.0.0,>=4.32.0->sentence-transformers>=2.2.0) (0.15.2)\n", - "Requirement already satisfied: safetensors>=0.4.1 in /usr/local/lib/python3.10/dist-packages (from transformers<5.0.0,>=4.32.0->sentence-transformers>=2.2.0) (0.4.2)\n", - "Requirement already satisfied: joblib>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from scikit-learn->sentence-transformers>=2.2.0) (1.3.2)\n", - "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from scikit-learn->sentence-transformers>=2.2.0) (3.3.0)\n", - "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch>=1.11.0->sentence-transformers>=2.2.0) (2.1.5)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (3.3.2)\n", - "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (3.6)\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (2.0.7)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=2.2.0) (2024.2.2)\n", - "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.10/dist-packages (from sympy->torch>=1.11.0->sentence-transformers>=2.2.0) (1.3.0)\n" - ] - } - ], - "source": [ - "%%bash\n", - "\n", - "pip install haystack-ai\n", - "pip install \"datasets>=2.6.1\"\n", - "pip install \"sentence-transformers>=3.0.0\"" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Requirement already satisfied: haystack-ai==2.8.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (2.8.0)\n", + "Requirement already satisfied: haystack-experimental in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (0.3.0)\n", + "Requirement already satisfied: jinja2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (3.1.4)\n", + "Requirement already satisfied: lazy-imports in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (0.3.1)\n", + "Requirement already satisfied: more-itertools in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (10.2.0)\n", + "Requirement already satisfied: networkx in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (3.2.1)\n", + "Requirement already satisfied: numpy in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (1.26.4)\n", + "Requirement already satisfied: openai>=1.1.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (1.31.1)\n", + "Requirement already satisfied: pandas in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (2.2.2)\n", + "Requirement already satisfied: posthog in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (3.5.0)\n", + "Requirement already satisfied: python-dateutil in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (2.9.0.post0)\n", + "Requirement already satisfied: pyyaml in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (6.0.1)\n", + "Requirement already satisfied: requests in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (2.32.3)\n", + "Requirement already satisfied: tenacity!=8.4.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (8.3.0)\n", + "Requirement already satisfied: tqdm in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (4.66.4)\n", + "Requirement already satisfied: typing-extensions>=4.7 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai==2.8.0) (4.12.1)\n", + "Requirement already satisfied: anyio<5,>=3.5.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from openai>=1.1.0->haystack-ai==2.8.0) (4.4.0)\n", + "Requirement already satisfied: distro<2,>=1.7.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from openai>=1.1.0->haystack-ai==2.8.0) (1.9.0)\n", + "Requirement already satisfied: httpx<1,>=0.23.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from openai>=1.1.0->haystack-ai==2.8.0) (0.27.0)\n", + "Requirement already satisfied: pydantic<3,>=1.9.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from openai>=1.1.0->haystack-ai==2.8.0) (2.7.3)\n", + "Requirement already satisfied: sniffio in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from openai>=1.1.0->haystack-ai==2.8.0) (1.3.1)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from jinja2->haystack-ai==2.8.0) (2.1.5)\n", + "Requirement already satisfied: pytz>=2020.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from pandas->haystack-ai==2.8.0) (2024.1)\n", + "Requirement already satisfied: tzdata>=2022.7 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from pandas->haystack-ai==2.8.0) (2024.1)\n", + "Requirement already satisfied: six>=1.5 in /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/site-packages (from python-dateutil->haystack-ai==2.8.0) (1.15.0)\n", + "Requirement already satisfied: monotonic>=1.5 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from posthog->haystack-ai==2.8.0) (1.6)\n", + "Requirement already satisfied: backoff>=1.10.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from posthog->haystack-ai==2.8.0) (2.2.1)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->haystack-ai==2.8.0) (3.3.2)\n", + "Requirement already satisfied: idna<4,>=2.5 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->haystack-ai==2.8.0) (3.7)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->haystack-ai==2.8.0) (1.26.18)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->haystack-ai==2.8.0) (2024.6.2)\n", + "Requirement already satisfied: exceptiongroup>=1.0.2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from anyio<5,>=3.5.0->openai>=1.1.0->haystack-ai==2.8.0) (1.2.1)\n", + "Requirement already satisfied: httpcore==1.* in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from httpx<1,>=0.23.0->openai>=1.1.0->haystack-ai==2.8.0) (1.0.5)\n", + "Requirement already satisfied: h11<0.15,>=0.13 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai>=1.1.0->haystack-ai==2.8.0) (0.14.0)\n", + "Requirement already satisfied: annotated-types>=0.4.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from pydantic<3,>=1.9.0->openai>=1.1.0->haystack-ai==2.8.0) (0.7.0)\n", + "Requirement already satisfied: pydantic-core==2.18.4 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from pydantic<3,>=1.9.0->openai>=1.1.0->haystack-ai==2.8.0) (2.18.4)\n" + ] }, { - "cell_type": "markdown", - "metadata": { - "id": "Wl_jYERtO-qa" - }, - "source": [ - "### Enabling Telemetry\n", - "\n", - "Knowing you're using this tutorial helps us decide where to invest our efforts to build a better product but you can always opt out by commenting the following line. See [Telemetry](https://docs.haystack.deepset.ai/docs/enabling-telemetry) for more details." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49m/Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip\u001b[0m\n" + ] }, { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "id": "A76B4S49O-qa" - }, - "outputs": [], - "source": [ - "from haystack.telemetry import tutorial_running\n", - "\n", - "tutorial_running(27)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Requirement already satisfied: datasets>=2.6.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (3.1.0)\n", + "Requirement already satisfied: filelock in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (3.14.0)\n", + "Requirement already satisfied: numpy>=1.17 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (1.26.4)\n", + "Requirement already satisfied: pyarrow>=15.0.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (18.1.0)\n", + "Requirement already satisfied: dill<0.3.9,>=0.3.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (0.3.8)\n", + "Requirement already satisfied: pandas in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (2.2.2)\n", + "Requirement already satisfied: requests>=2.32.2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (2.32.3)\n", + "Requirement already satisfied: tqdm>=4.66.3 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (4.66.4)\n", + "Requirement already satisfied: xxhash in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (3.5.0)\n", + "Requirement already satisfied: multiprocess<0.70.17 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (0.70.16)\n", + "Requirement already satisfied: fsspec<=2024.9.0,>=2023.1.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from fsspec[http]<=2024.9.0,>=2023.1.0->datasets>=2.6.1) (2024.6.0)\n", + "Requirement already satisfied: aiohttp in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (3.11.10)\n", + "Requirement already satisfied: huggingface-hub>=0.23.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (0.23.3)\n", + "Requirement already satisfied: packaging in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (24.0)\n", + "Requirement already satisfied: pyyaml>=5.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from datasets>=2.6.1) (6.0.1)\n", + "Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (2.4.4)\n", + "Requirement already satisfied: aiosignal>=1.1.2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (1.3.1)\n", + "Requirement already satisfied: async-timeout<6.0,>=4.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (5.0.1)\n", + "Requirement already satisfied: attrs>=17.3.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (24.2.0)\n", + "Requirement already satisfied: frozenlist>=1.1.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (1.5.0)\n", + "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (6.1.0)\n", + "Requirement already satisfied: propcache>=0.2.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (0.2.1)\n", + "Requirement already satisfied: yarl<2.0,>=1.17.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from aiohttp->datasets>=2.6.1) (1.18.3)\n", + "Requirement already satisfied: typing-extensions>=3.7.4.3 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from huggingface-hub>=0.23.0->datasets>=2.6.1) (4.12.1)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests>=2.32.2->datasets>=2.6.1) (3.3.2)\n", + "Requirement already satisfied: idna<4,>=2.5 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests>=2.32.2->datasets>=2.6.1) (3.7)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests>=2.32.2->datasets>=2.6.1) (1.26.18)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests>=2.32.2->datasets>=2.6.1) (2024.6.2)\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from pandas->datasets>=2.6.1) (2.9.0.post0)\n", + "Requirement already satisfied: pytz>=2020.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from pandas->datasets>=2.6.1) (2024.1)\n", + "Requirement already satisfied: tzdata>=2022.7 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from pandas->datasets>=2.6.1) (2024.1)\n", + "Requirement already satisfied: six>=1.5 in /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/site-packages (from python-dateutil>=2.8.2->pandas->datasets>=2.6.1) (1.15.0)\n" + ] }, { - "cell_type": "markdown", - "metadata": { - "id": "_lvfew16O-qa" - }, - "source": [ - "## Fetching and Indexing Documents\n", - "\n", - "You'll start creating your question answering system by downloading the data and indexing the data with its embeddings to a DocumentStore. \n", - "\n", - "In this tutorial, you will take a simple approach to writing documents and their embeddings into the DocumentStore. For a full indexing pipeline with preprocessing, cleaning and splitting, check out our tutorial on [Preprocessing Different File Types](https://haystack.deepset.ai/tutorials/30_file_type_preprocessing_index_pipeline).\n", - "\n", - "\n", - "### Initializing the DocumentStore\n", - "\n", - "Initialize a DocumentStore to index your documents. A DocumentStore stores the Documents that the question answering system uses to find answers to your questions. In this tutorial, you'll be using the `InMemoryDocumentStore`." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49m/Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip\u001b[0m\n" + ] }, { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "id": "CbVN-s5LO-qa" - }, - "outputs": [], - "source": [ - "from haystack.document_stores.in_memory import InMemoryDocumentStore\n", - "\n", - "document_store = InMemoryDocumentStore()" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Requirement already satisfied: sentence-transformers>=3.0.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (3.0.0)\n", + "Requirement already satisfied: transformers<5.0.0,>=4.34.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (4.41.2)\n", + "Requirement already satisfied: tqdm in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (4.66.4)\n", + "Requirement already satisfied: torch>=1.11.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (2.3.1)\n", + "Requirement already satisfied: numpy in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (1.26.4)\n", + "Requirement already satisfied: scikit-learn in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (1.5.0)\n", + "Requirement already satisfied: scipy in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (1.13.1)\n", + "Requirement already satisfied: huggingface-hub>=0.15.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (0.23.3)\n", + "Requirement already satisfied: Pillow in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sentence-transformers>=3.0.0) (10.3.0)\n", + "Requirement already satisfied: filelock in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (3.14.0)\n", + "Requirement already satisfied: fsspec>=2023.5.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (2024.6.0)\n", + "Requirement already satisfied: packaging>=20.9 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (24.0)\n", + "Requirement already satisfied: pyyaml>=5.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (6.0.1)\n", + "Requirement already satisfied: requests in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (2.32.3)\n", + "Requirement already satisfied: typing-extensions>=3.7.4.3 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (4.12.1)\n", + "Requirement already satisfied: sympy in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from torch>=1.11.0->sentence-transformers>=3.0.0) (1.12.1)\n", + "Requirement already satisfied: networkx in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from torch>=1.11.0->sentence-transformers>=3.0.0) (3.2.1)\n", + "Requirement already satisfied: jinja2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from torch>=1.11.0->sentence-transformers>=3.0.0) (3.1.4)\n", + "Requirement already satisfied: regex!=2019.12.17 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from transformers<5.0.0,>=4.34.0->sentence-transformers>=3.0.0) (2024.5.15)\n", + "Requirement already satisfied: tokenizers<0.20,>=0.19 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from transformers<5.0.0,>=4.34.0->sentence-transformers>=3.0.0) (0.19.1)\n", + "Requirement already satisfied: safetensors>=0.4.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from transformers<5.0.0,>=4.34.0->sentence-transformers>=3.0.0) (0.4.3)\n", + "Requirement already satisfied: joblib>=1.2.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from scikit-learn->sentence-transformers>=3.0.0) (1.4.2)\n", + "Requirement already satisfied: threadpoolctl>=3.1.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from scikit-learn->sentence-transformers>=3.0.0) (3.5.0)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from jinja2->torch>=1.11.0->sentence-transformers>=3.0.0) (2.1.5)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (3.3.2)\n", + "Requirement already satisfied: idna<4,>=2.5 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (3.7)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (1.26.18)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from requests->huggingface-hub>=0.15.1->sentence-transformers>=3.0.0) (2024.6.2)\n", + "Requirement already satisfied: mpmath<1.4.0,>=1.1.0 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from sympy->torch>=1.11.0->sentence-transformers>=3.0.0) (1.3.0)\n" + ] }, { - "cell_type": "markdown", - "metadata": { - "id": "yL8nuJdWO-qa" - }, - "source": [ - "> `InMemoryDocumentStore` is the simplest DocumentStore to get started with. It requires no external dependencies and it's a good option for smaller projects and debugging. But it doesn't scale up so well to larger Document collections, so it's not a good choice for production systems. To learn more about the different types of external databases that Haystack supports, see [DocumentStore Integrations](https://haystack.deepset.ai/integrations?type=Document+Store)." - ] - }, + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49m/Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip\u001b[0m\n" + ] + } + ], + "source": [ + "%%bash\n", + "\n", + "pip install haystack-ai==2.8.0\n", + "pip install \"datasets>=2.6.1\"\n", + "pip install \"sentence-transformers>=3.0.0\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Wl_jYERtO-qa" + }, + "source": [ + "### Enabling Telemetry\n", + "\n", + "Knowing you're using this tutorial helps us decide where to invest our efforts to build a better product but you can always opt out by commenting the following line. See [Telemetry](https://docs.haystack.deepset.ai/docs/enabling-telemetry) for more details." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "A76B4S49O-qa" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "XvLVaFHTO-qb" - }, - "source": [ - "The DocumentStore is now ready. Now it's time to fill it with some Documents." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + } + ], + "source": [ + "from haystack.telemetry import tutorial_running\n", + "\n", + "tutorial_running(27)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_lvfew16O-qa" + }, + "source": [ + "## Fetching and Indexing Documents\n", + "\n", + "You'll start creating your question answering system by downloading the data and indexing the data with its embeddings to a DocumentStore. \n", + "\n", + "In this tutorial, you will take a simple approach to writing documents and their embeddings into the DocumentStore. For a full indexing pipeline with preprocessing, cleaning and splitting, check out our tutorial on [Preprocessing Different File Types](https://haystack.deepset.ai/tutorials/30_file_type_preprocessing_index_pipeline).\n", + "\n", + "\n", + "### Initializing the DocumentStore\n", + "\n", + "Initialize a DocumentStore to index your documents. A DocumentStore stores the Documents that the question answering system uses to find answers to your questions. In this tutorial, you'll be using the `InMemoryDocumentStore`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "CbVN-s5LO-qa" + }, + "outputs": [], + "source": [ + "from haystack.document_stores.in_memory import InMemoryDocumentStore\n", + "\n", + "document_store = InMemoryDocumentStore()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yL8nuJdWO-qa" + }, + "source": [ + "> `InMemoryDocumentStore` is the simplest DocumentStore to get started with. It requires no external dependencies and it's a good option for smaller projects and debugging. But it doesn't scale up so well to larger Document collections, so it's not a good choice for production systems. To learn more about the different types of external databases that Haystack supports, see [DocumentStore Integrations](https://haystack.deepset.ai/integrations?type=Document+Store)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XvLVaFHTO-qb" + }, + "source": [ + "The DocumentStore is now ready. Now it's time to fill it with some Documents." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HryYZP9ZO-qb" + }, + "source": [ + "### Fetch the Data\n", + "\n", + "You'll use the Wikipedia pages of [Seven Wonders of the Ancient World](https://en.wikipedia.org/wiki/Wonders_of_the_World) as Documents. We preprocessed the data and uploaded to a Hugging Face Space: [Seven Wonders](https://huggingface.co/datasets/bilgeyucel/seven-wonders). Thus, you don't need to perform any additional cleaning or splitting.\n", + "\n", + "Fetch the data and convert it into Haystack Documents:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, - { - "cell_type": "markdown", - "metadata": { - "id": "HryYZP9ZO-qb" - }, - "source": [ - "### Fetch the Data\n", - "\n", - "You'll use the Wikipedia pages of [Seven Wonders of the Ancient World](https://en.wikipedia.org/wiki/Wonders_of_the_World) as Documents. We preprocessed the data and uploaded to a Hugging Face Space: [Seven Wonders](https://huggingface.co/datasets/bilgeyucel/seven-wonders). Thus, you don't need to perform any additional cleaning or splitting.\n", - "\n", - "Fetch the data and convert it into Haystack Documents:" - ] + "id": "INdC3WvLO-qb", + "outputId": "1af43d0f-2999-4de4-d152-b3cca9fb49e6" + }, + "outputs": [], + "source": [ + "from datasets import load_dataset\n", + "from haystack import Document\n", + "\n", + "dataset = load_dataset(\"bilgeyucel/seven-wonders\", split=\"train\")\n", + "docs = [Document(content=doc[\"content\"], meta=doc[\"meta\"]) for doc in dataset]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "czMjWwnxPA-3" + }, + "source": [ + "### Initalize a Document Embedder\n", + "\n", + "To store your data in the DocumentStore with embeddings, initialize a [SentenceTransformersDocumentEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformersdocumentembedder) with the model name and call `warm_up()` to download the embedding model.\n", + "\n", + "> If you'd like, you can use a different [Embedder](https://docs.haystack.deepset.ai/docs/embedders) for your documents." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "EUmAH9sEn3R7", + "outputId": "ee54b59b-4d4a-45eb-c1a9-0b7b248f1dd4" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "INdC3WvLO-qb", - "outputId": "1af43d0f-2999-4de4-d152-b3cca9fb49e6" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:88: UserWarning: \n", - "The secret `HF_TOKEN` does not exist in your Colab secrets.\n", - "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n", - "You will be able to reuse this secret in all of your notebooks.\n", - "Please note that authentication is recommended but still optional to access public models or datasets.\n", - " warnings.warn(\n" - ] - } - ], - "source": [ - "from datasets import load_dataset\n", - "from haystack import Document\n", - "\n", - "dataset = load_dataset(\"bilgeyucel/seven-wonders\", split=\"train\")\n", - "docs = [Document(content=doc[\"content\"], meta=doc[\"meta\"]) for doc in dataset]" - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "from haystack.components.embedders import SentenceTransformersDocumentEmbedder\n", + "\n", + "doc_embedder = SentenceTransformersDocumentEmbedder(model=\"sentence-transformers/all-MiniLM-L6-v2\")\n", + "doc_embedder.warm_up()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9y4iJE_SrS4K" + }, + "source": [ + "### Write Documents to the DocumentStore\n", + "\n", + "Run the `doc_embedder` with the Documents. The embedder will create embeddings for each document and save these embeddings in Document object's `embedding` field. Then, you can write the Documents to the DocumentStore with `write_documents()` method." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 66, + "referenced_widgets": [ + "7d482188c12d4a7886f20a65d3402c59", + "2a3ec74419ae4a02ac0210db66133415", + "ddeff9a822404adbbc3cad97a939bc0c", + "36d341ab3a044709b5af2e8ab97559bc", + "88fc33e1ab78405e911b5eafa512c935", + "91e5d4b0ede848319ef0d3b558d57d19", + "d2428c21707d43f2b6f07bfafbace8bb", + "7fdb2c859e454e72888709a835f7591e", + "6b8334e071a3438397ba6435aac69f58", + "5f5cfa425cac4d37b2ea29e53b4ed900", + "3c59a82dac5c476b9a3e3132094e1702" + ] }, + "id": "ETpQKftLplqh", + "outputId": "b9c8658c-90c8-497c-e765-97487c0daf8e" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "czMjWwnxPA-3" - }, - "source": [ - "### Initalize a Document Embedder\n", - "\n", - "To store your data in the DocumentStore with embeddings, initialize a [SentenceTransformersDocumentEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformersdocumentembedder) with the model name and call `warm_up()` to download the embedding model.\n", - "\n", - "> If you'd like, you can use a different [Embedder](https://docs.haystack.deepset.ai/docs/embedders) for your documents." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "Batches: 100%|██████████| 5/5 [00:01<00:00, 3.09it/s]\n" + ] }, { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "EUmAH9sEn3R7", - "outputId": "ee54b59b-4d4a-45eb-c1a9-0b7b248f1dd4" - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.10/dist-packages/torch/_utils.py:831: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly. To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage()\n", - " return self.fget.__get__(instance, owner)()\n" - ] - } - ], - "source": [ - "from haystack.components.embedders import SentenceTransformersDocumentEmbedder\n", - "\n", - "doc_embedder = SentenceTransformersDocumentEmbedder(model=\"sentence-transformers/all-MiniLM-L6-v2\")\n", - "doc_embedder.warm_up()" + "data": { + "text/plain": [ + "151" ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "docs_with_embeddings = doc_embedder.run(docs)\n", + "document_store.write_documents(docs_with_embeddings[\"documents\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IdojTxg6uubn" + }, + "source": [ + "## Building the RAG Pipeline\n", + "\n", + "The next step is to build a [Pipeline](https://docs.haystack.deepset.ai/docs/pipelines) to generate answers for the user query following the RAG approach. To create the pipeline, you first need to initialize each component, add them to your pipeline, and connect them." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0uyV6-u-u56P" + }, + "source": [ + "### Initialize a Text Embedder\n", + "\n", + "Initialize a text embedder to create an embedding for the user query. The created embedding will later be used by the Retriever to retrieve relevant documents from the DocumentStore.\n", + "\n", + "> ⚠️ Notice that you used `sentence-transformers/all-MiniLM-L6-v2` model to create embeddings for your documents before. This is why you need to use the same model to embed the user queries." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "LyJY2yW628dl" + }, + "outputs": [], + "source": [ + "from haystack.components.embedders import SentenceTransformersTextEmbedder\n", + "\n", + "text_embedder = SentenceTransformersTextEmbedder(model=\"sentence-transformers/all-MiniLM-L6-v2\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0_cj-5m-O-qb" + }, + "source": [ + "### Initialize the Retriever\n", + "\n", + "Initialize a [InMemoryEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/inmemoryembeddingretriever) and make it use the InMemoryDocumentStore you initialized earlier in this tutorial. This Retriever will get the relevant documents to the query." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "-uo-6fjiO-qb" + }, + "outputs": [], + "source": [ + "from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever\n", + "\n", + "retriever = InMemoryEmbeddingRetriever(document_store)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6CEuQpB7O-qb" + }, + "source": [ + "### Define a Template Prompt\n", + "\n", + "Create a custom prompt for a generative question answering task using the RAG approach. The prompt should take in two parameters: `documents`, which are retrieved from a document store, and a `question` from the user. Use the Jinja2 looping syntax to combine the content of the retrieved documents in the prompt.\n", + "\n", + "Next, initialize a [PromptBuilder](https://docs.haystack.deepset.ai/docs/promptbuilder) instance with your prompt template. The PromptBuilder, when given the necessary values, will automatically fill in the variable values and generate a complete prompt. This approach allows for a more tailored and effective question-answering experience." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "ObahTh45FqOT" + }, + "outputs": [], + "source": [ + "from haystack.components.builders import ChatPromptBuilder\n", + "from haystack.dataclasses import ChatMessage\n", + "\n", + "template = [ChatMessage.from_user(\"\"\"\n", + "Given the following information, answer the question.\n", + "\n", + "Context:\n", + "{% for document in documents %}\n", + " {{ document.content }}\n", + "{% endfor %}\n", + "\n", + "Question: {{question}}\n", + "Answer:\n", + "\"\"\")]\n", + "\n", + "prompt_builder = ChatPromptBuilder(template=template)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HR14lbfcFtXj" + }, + "source": [ + "### Initialize a ChatGenerator\n", + "\n", + "\n", + "ChatGenerators are the components that interact with large language models (LLMs). Now, set `OPENAI_API_KEY` environment variable and initialize a [OpenAIChatGenerator](https://docs.haystack.deepset.ai/docs/OpenAIChatGenerator) that can communicate with OpenAI GPT models. As you initialize, provide a model name:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, - { - "cell_type": "markdown", - "metadata": { - "id": "9y4iJE_SrS4K" - }, - "source": [ - "### Write Documents to the DocumentStore\n", - "\n", - "Run the `doc_embedder` with the Documents. The embedder will create embeddings for each document and save these embeddings in Document object's `embedding` field. Then, you can write the Documents to the DocumentStore with `write_documents()` method." - ] + "id": "SavE_FAqfApo", + "outputId": "1afbf2e8-ae63-41ff-c37f-5123b2103356" + }, + "outputs": [], + "source": [ + "import os\n", + "from getpass import getpass\n", + "from haystack.components.generators.chat import OpenAIChatGenerator\n", + "\n", + "if \"OPENAI_API_KEY\" not in os.environ:\n", + " os.environ[\"OPENAI_API_KEY\"] = getpass(\"Enter OpenAI API key:\")\n", + "chat_generator = OpenAIChatGenerator(model=\"gpt-4o-mini\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nenbo2SvycHd" + }, + "source": [ + "> You can replace `OpenAIChatGenerator` in your pipeline with another `ChatGenerator`. Check out the full list of chat generators [here](https://docs.haystack.deepset.ai/docs/generators)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1bfHwOQwycHe" + }, + "source": [ + "### Build the Pipeline\n", + "\n", + "To build a pipeline, add all components to your pipeline and connect them. Create connections from `text_embedder`'s \"embedding\" output to \"query_embedding\" input of `retriever`, from `retriever` to `prompt_builder` and from `prompt_builder` to `llm`. Explicitly connect the output of `retriever` with \"documents\" input of the `prompt_builder` to make the connection obvious as `prompt_builder` has two inputs (\"documents\" and \"question\").\n", + "\n", + "For more information on pipelines and creating connections, refer to [Creating Pipelines](https://docs.haystack.deepset.ai/docs/creating-pipelines) documentation." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 }, + "id": "f6NFmpjEO-qb", + "outputId": "89fd1b48-5189-4401-9cf8-15f55c503676" + }, + "outputs": [], + "source": [ + "from haystack import Pipeline\n", + "\n", + "basic_rag_pipeline = Pipeline()\n", + "# Add components to your pipeline\n", + "basic_rag_pipeline.add_component(\"text_embedder\", text_embedder)\n", + "basic_rag_pipeline.add_component(\"retriever\", retriever)\n", + "basic_rag_pipeline.add_component(\"prompt_builder\", prompt_builder)\n", + "basic_rag_pipeline.add_component(\"llm\", chat_generator)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 66, - "referenced_widgets": [ - "7d482188c12d4a7886f20a65d3402c59", - "2a3ec74419ae4a02ac0210db66133415", - "ddeff9a822404adbbc3cad97a939bc0c", - "36d341ab3a044709b5af2e8ab97559bc", - "88fc33e1ab78405e911b5eafa512c935", - "91e5d4b0ede848319ef0d3b558d57d19", - "d2428c21707d43f2b6f07bfafbace8bb", - "7fdb2c859e454e72888709a835f7591e", - "6b8334e071a3438397ba6435aac69f58", - "5f5cfa425cac4d37b2ea29e53b4ed900", - "3c59a82dac5c476b9a3e3132094e1702" - ] - }, - "id": "ETpQKftLplqh", - "outputId": "b9c8658c-90c8-497c-e765-97487c0daf8e" - }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "7d482188c12d4a7886f20a65d3402c59", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Batches: 0%| | 0/5 [00:00\n", + "🚅 Components\n", + " - text_embedder: SentenceTransformersTextEmbedder\n", + " - retriever: InMemoryEmbeddingRetriever\n", + " - prompt_builder: ChatPromptBuilder\n", + " - llm: OpenAIChatGenerator\n", + "🛤️ Connections\n", + " - text_embedder.embedding -> retriever.query_embedding (List[float])\n", + " - retriever.documents -> prompt_builder.documents (List[Document])\n", + " - prompt_builder.prompt -> llm.messages (List[ChatMessage])" ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Now, connect the components to each other\n", + "basic_rag_pipeline.connect(\"text_embedder.embedding\", \"retriever.query_embedding\")\n", + "basic_rag_pipeline.connect(\"retriever\", \"prompt_builder\")\n", + "basic_rag_pipeline.connect(\"prompt_builder.prompt\", \"llm.messages\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6NqyLhx7O-qc" + }, + "source": [ + "That's it! Your RAG pipeline is ready to generate answers to questions!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DBAyF5tVO-qc" + }, + "source": [ + "## Asking a Question\n", + "\n", + "When asking a question, use the `run()` method of the pipeline. Make sure to provide the question to both the `text_embedder` and the `prompt_builder`. This ensures that the `{{question}}` variable in the template prompt gets replaced with your specific question." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 86, + "referenced_widgets": [ + "4e6e97b6d54f4f80bb7e8b25aba8e616", + "1a820c06a7a049d8b6c9ff300284d06e", + "58ff4e0603a74978a134f63533859be5", + "8bdb8bfae31d4f4cb6c3b0bf43120eed", + "39a68d9a5c274e2dafaa2d1f86eea768", + "d0cfe5dacdfc431a91b4c4741123e2d0", + "e7f1e1a14bb740d18827dd78bbe7b2e3", + "3fda06f905b445a488efdd2dd08c0939", + "2bc341a780f7498ba9cd475468841bb5", + "d7218475e23b420a8c03d00ca4ab8718", + "a694abaf765f4d1b82fa0138e59c6793" + ] }, + "id": "Vnt283M5O-qc", + "outputId": "d2843a73-3ad5-4daa-8d1e-a58de7aa2bb0" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "IdojTxg6uubn" - }, - "source": [ - "## Building the RAG Pipeline\n", - "\n", - "The next step is to build a [Pipeline](https://docs.haystack.deepset.ai/docs/pipelines) to generate answers for the user query following the RAG approach. To create the pipeline, you first need to initialize each component, add them to your pipeline, and connect them." - ] + "name": "stderr", + "output_type": "stream", + "text": [ + "Batches: 100%|██████████| 1/1 [00:00<00:00, 4.19it/s]\n" + ] }, { - "cell_type": "markdown", - "metadata": { - "id": "0uyV6-u-u56P" - }, - "source": [ - "### Initialize a Text Embedder\n", - "\n", - "Initialize a text embedder to create an embedding for the user query. The created embedding will later be used by the Retriever to retrieve relevant documents from the DocumentStore.\n", - "\n", - "> ⚠️ Notice that you used `sentence-transformers/all-MiniLM-L6-v2` model to create embeddings for your documents before. This is why you need to use the same model to embed the user queries." - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "ChatMessage(content='The Colossus of Rhodes was a statue of the Greek sun-god Helios, thought to be approximately 70 cubits, or about 33 meters (108 feet) tall. Although no definitive description of its appearance survives, ancient accounts suggest it featured a standard rendering of Helios from that era. It likely had curly hair with bronze or silver spikes representing flames radiating from his head, similar to depictions found on Rhodian coins.\\n\\nThe statue was constructed using iron tie bars and brass plates, forming a skin that covered a core filled with stone blocks. The details of the face and head followed common artistic conventions of the time, with the design possibly reflecting a pose of shielding the eyes with one hand, resembling the way a person looks toward the sun. While it was built to celebrate the victory of Rhodes over an attacking army, its exact posture and additional details remain subjects of speculation due to the lack of surviving descriptions.', role=, name=None, meta={'model': 'gpt-4o-mini-2024-07-18', 'index': 0, 'finish_reason': 'stop', 'usage': {'completion_tokens': 187, 'prompt_tokens': 2405, 'total_tokens': 2592, 'prompt_tokens_details': {'cached_tokens': 2176, 'audio_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0, 'audio_tokens': 0, 'accepted_prediction_tokens': 0, 'rejected_prediction_tokens': 0}}})\n" + ] + } + ], + "source": [ + "question = \"What does Rhodes Statue look like?\"\n", + "\n", + "response = basic_rag_pipeline.run({\"text_embedder\": {\"text\": question}, \"prompt_builder\": {\"question\": question}})\n", + "\n", + "print(response[\"llm\"][\"replies\"][0])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IWQN-aoGO-qc" + }, + "source": [ + "Here are some other example questions to test:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "id": "_OHUQ5xxO-qc" + }, + "outputs": [], + "source": [ + "examples = [\n", + " \"Where is Gardens of Babylon?\",\n", + " \"Why did people build Great Pyramid of Giza?\",\n", + " \"What does Rhodes Statue look like?\",\n", + " \"Why did people visit the Temple of Artemis?\",\n", + " \"What is the importance of Colossus of Rhodes?\",\n", + " \"What happened to the Tomb of Mausolus?\",\n", + " \"How did Colossus of Rhodes collapse?\",\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "XueCK3y4O-qc" + }, + "source": [ + "## What's next\n", + "\n", + "🎉 Congratulations! You've learned how to create a generative QA system for your documents with the RAG approach.\n", + "\n", + "If you liked this tutorial, you may also enjoy:\n", + "- [Filtering Documents with Metadata](https://haystack.deepset.ai/tutorials/31_metadata_filtering)\n", + "- [Preprocessing Different File Types](https://haystack.deepset.ai/tutorials/30_file_type_preprocessing_index_pipeline)\n", + "- [Creating a Hybrid Retrieval Pipeline](https://haystack.deepset.ai/tutorials/33_hybrid_retrieval)\n", + "\n", + "To stay up to date on the latest Haystack developments, you can [subscribe to our newsletter](https://landing.deepset.ai/haystack-community-updates) and [join Haystack discord community](https://discord.gg/haystack).\n", + "\n", + "Thanks for reading!" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "gpuType": "T4", + "provenance": [] + }, + "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.9.6" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + } + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "1a820c06a7a049d8b6c9ff300284d06e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "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_d0cfe5dacdfc431a91b4c4741123e2d0", + "placeholder": "​", + "style": "IPY_MODEL_e7f1e1a14bb740d18827dd78bbe7b2e3", + "value": "Batches: 100%" + } }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "id": "LyJY2yW628dl" - }, - "outputs": [], - "source": [ - "from haystack.components.embedders import SentenceTransformersTextEmbedder\n", - "\n", - "text_embedder = SentenceTransformersTextEmbedder(model=\"sentence-transformers/all-MiniLM-L6-v2\")" - ] + "2a3ec74419ae4a02ac0210db66133415": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "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_91e5d4b0ede848319ef0d3b558d57d19", + "placeholder": "​", + "style": "IPY_MODEL_d2428c21707d43f2b6f07bfafbace8bb", + "value": "Batches: 100%" + } }, - { - "cell_type": "markdown", - "metadata": { - "id": "0_cj-5m-O-qb" - }, - "source": [ - "### Initialize the Retriever\n", - "\n", - "Initialize a [InMemoryEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/inmemoryembeddingretriever) and make it use the InMemoryDocumentStore you initialized earlier in this tutorial. This Retriever will get the relevant documents to the query." - ] + "2bc341a780f7498ba9cd475468841bb5": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "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": "" + } }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "id": "-uo-6fjiO-qb" - }, - "outputs": [], - "source": [ - "from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever\n", - "\n", - "retriever = InMemoryEmbeddingRetriever(document_store)" - ] + "36d341ab3a044709b5af2e8ab97559bc": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "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_5f5cfa425cac4d37b2ea29e53b4ed900", + "placeholder": "​", + "style": "IPY_MODEL_3c59a82dac5c476b9a3e3132094e1702", + "value": " 5/5 [00:01<00:00,  3.35it/s]" + } }, - { - "cell_type": "markdown", - "metadata": { - "id": "6CEuQpB7O-qb" - }, - "source": [ - "### Define a Template Prompt\n", - "\n", - "Create a custom prompt for a generative question answering task using the RAG approach. The prompt should take in two parameters: `documents`, which are retrieved from a document store, and a `question` from the user. Use the Jinja2 looping syntax to combine the content of the retrieved documents in the prompt.\n", - "\n", - "Next, initialize a [PromptBuilder](https://docs.haystack.deepset.ai/docs/promptbuilder) instance with your prompt template. The PromptBuilder, when given the necessary values, will automatically fill in the variable values and generate a complete prompt. This approach allows for a more tailored and effective question-answering experience." - ] + "39a68d9a5c274e2dafaa2d1f86eea768": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "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 + } }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "id": "ObahTh45FqOT" - }, - "outputs": [], - "source": [ - "from haystack.components.builders import PromptBuilder\n", - "\n", - "template = \"\"\"\n", - "Given the following information, answer the question.\n", - "\n", - "Context:\n", - "{% for document in documents %}\n", - " {{ document.content }}\n", - "{% endfor %}\n", - "\n", - "Question: {{question}}\n", - "Answer:\n", - "\"\"\"\n", - "\n", - "prompt_builder = PromptBuilder(template=template)" - ] + "3c59a82dac5c476b9a3e3132094e1702": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "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": "" + } }, - { - "cell_type": "markdown", - "metadata": { - "id": "HR14lbfcFtXj" - }, - "source": [ - "### Initialize a Generator\n", - "\n", - "\n", - "Generators are the components that interact with large language models (LLMs). Now, set `OPENAI_API_KEY` environment variable and initialize a [OpenAIGenerator](https://docs.haystack.deepset.ai/docs/OpenAIGenerator) that can communicate with OpenAI GPT models. As you initialize, provide a model name:" - ] + "3fda06f905b445a488efdd2dd08c0939": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "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 + } }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "SavE_FAqfApo", - "outputId": "1afbf2e8-ae63-41ff-c37f-5123b2103356" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter OpenAI API key: ··········\n" - ] - } + "4e6e97b6d54f4f80bb7e8b25aba8e616": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "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_1a820c06a7a049d8b6c9ff300284d06e", + "IPY_MODEL_58ff4e0603a74978a134f63533859be5", + "IPY_MODEL_8bdb8bfae31d4f4cb6c3b0bf43120eed" ], - "source": [ - "import os\n", - "from getpass import getpass\n", - "from haystack.components.generators import OpenAIGenerator\n", - "\n", - "if \"OPENAI_API_KEY\" not in os.environ:\n", - " os.environ[\"OPENAI_API_KEY\"] = getpass(\"Enter OpenAI API key:\")\n", - "generator = OpenAIGenerator(model=\"gpt-4o-mini\")" - ] + "layout": "IPY_MODEL_39a68d9a5c274e2dafaa2d1f86eea768" + } }, - { - "cell_type": "markdown", - "metadata": { - "id": "nenbo2SvycHd" - }, - "source": [ - "> You can replace `OpenAIGenerator` in your pipeline with another `Generator`. Check out the full list of generators [here](https://docs.haystack.deepset.ai/docs/generators)." - ] + "58ff4e0603a74978a134f63533859be5": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "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_3fda06f905b445a488efdd2dd08c0939", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_2bc341a780f7498ba9cd475468841bb5", + "value": 1 + } }, - { - "cell_type": "markdown", - "metadata": { - "id": "1bfHwOQwycHe" - }, - "source": [ - "### Build the Pipeline\n", - "\n", - "To build a pipeline, add all components to your pipeline and connect them. Create connections from `text_embedder`'s \"embedding\" output to \"query_embedding\" input of `retriever`, from `retriever` to `prompt_builder` and from `prompt_builder` to `llm`. Explicitly connect the output of `retriever` with \"documents\" input of the `prompt_builder` to make the connection obvious as `prompt_builder` has two inputs (\"documents\" and \"question\").\n", - "\n", - "For more information on pipelines and creating connections, refer to [Creating Pipelines](https://docs.haystack.deepset.ai/docs/creating-pipelines) documentation." - ] + "5f5cfa425cac4d37b2ea29e53b4ed900": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "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 + } }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "f6NFmpjEO-qb", - "outputId": "89fd1b48-5189-4401-9cf8-15f55c503676" - }, - "outputs": [ - { - "data": { - "image/jpeg": "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1KWhKglcriWW/wD7Bn9f/HH/AIo+M6WuzhSIczGpcqJIbUy8w8cZaHEKLZSVJN3YyMjMjI/HcRe5q7kWRa7wsZx96srcRg4xGya5eu6iUmcaH33W2mEpU6ycZfBhxR962pSdtjSQ6LTTtWW+UHp5NyvADxPHdQUcset49wmcg1nHXJablINppTKnGW1qTx7xPTY1EA7PBey/pnprk9NkOOadWcC1pjfOtcVcOPIhk82bbiGmnJakIQaVGXAk8S6GREZEY52OdnDTfC84ayum04kR7lh56TGWmbzjRHXd+9cjxlyDZYWrkrdTaEme59eo7qi7S2muRypbMTJ22248B608snRX4kSRDZMiekx5DzaWpDSOSeTjSlpLkRmfUcij7QWD5BHp34thYNNXFkiorlTqWdE8skLZceQTXesp5oNtlxXelu3sk/SAY1G7OencHPlZnF06nRL5c720UqNYm1GVL8fKDiplEwbpn1NZt7mfUz3HEsuy7pjb3b9rK02sFyXrRF33SbVaI7c9LpO+UtsJlk024a0kalISRr3USuRKMjya77S2nWP2LlfKu5Ltgiyk1BQ4VTMlvuy47TTrzTbbTKlOGhDzaj4EZdVERmaVEX84P2nNNdRratrqDIlS37KI7OhOvV0qMxKaa277u3nWktrU3yLmglGtHXkRbGA/ido9iFli+T47JwWwcp8ltjvLWN5eReUzO8ac73kUnkj02Gj4oMk+jttsZ79nbYDj19k1tf2eDybCztqZOPTlSnWXGpEBLjjhMLaN82zLk84Znx3PlsZmRERdLH7WGlcqHaTEZOpMCurnrdya7WS2478JpSUuyIzqmiRKbSpxBGpg1kXNP3SHByrta4JRYDneSV7tlcvYjEakyqpFVLYkum9yKLwS4yRqbeWk0peSRt9DUatiMwHAptB9MtH8ayeTAwK1g1cmmfg2Ju2rko01/A1OMtd5KWbSNi961x8C28CGurHsjHZKjPYM637fJcwhpTGPn5BKPyJCoxxjL3/1z6yZp+ucvu+PUTL2stZ8jp+zzXZFircSG3kEhqll1eSUkxqUtMlfcud2lxcdxhTaO+XycaUSiQkySRHufn1AW9S+2N2JJsnKHl1+QtlkzhvWjEduwZYedN5t83UtIeJDThutNrNxtKVGpO+/U98w019kh7J2kFA9TYl7eVUF+SuY/wAq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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } + "6b8334e071a3438397ba6435aac69f58": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "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": "" + } + }, + "7d482188c12d4a7886f20a65d3402c59": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "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_2a3ec74419ae4a02ac0210db66133415", + "IPY_MODEL_ddeff9a822404adbbc3cad97a939bc0c", + "IPY_MODEL_36d341ab3a044709b5af2e8ab97559bc" ], - "source": [ - "from haystack import Pipeline\n", - "\n", - "basic_rag_pipeline = Pipeline()\n", - "# Add components to your pipeline\n", - "basic_rag_pipeline.add_component(\"text_embedder\", text_embedder)\n", - "basic_rag_pipeline.add_component(\"retriever\", retriever)\n", - "basic_rag_pipeline.add_component(\"prompt_builder\", prompt_builder)\n", - "basic_rag_pipeline.add_component(\"llm\", generator)\n", - "\n", - "# Now, connect the components to each other\n", - "basic_rag_pipeline.connect(\"text_embedder.embedding\", \"retriever.query_embedding\")\n", - "basic_rag_pipeline.connect(\"retriever\", \"prompt_builder.documents\")\n", - "basic_rag_pipeline.connect(\"prompt_builder\", \"llm\")" - ] + "layout": "IPY_MODEL_88fc33e1ab78405e911b5eafa512c935" + } }, - { - "cell_type": "markdown", - "metadata": { - "id": "6NqyLhx7O-qc" - }, - "source": [ - "That's it! Your RAG pipeline is ready to generate answers to questions!" - ] + "7fdb2c859e454e72888709a835f7591e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "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 + } }, - { - "cell_type": "markdown", - "metadata": { - "id": "DBAyF5tVO-qc" - }, - "source": [ - "## Asking a Question\n", - "\n", - "When asking a question, use the `run()` method of the pipeline. Make sure to provide the question to both the `text_embedder` and the `prompt_builder`. This ensures that the `{{question}}` variable in the template prompt gets replaced with your specific question." - ] + "88fc33e1ab78405e911b5eafa512c935": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "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 + } }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 86, - "referenced_widgets": [ - "4e6e97b6d54f4f80bb7e8b25aba8e616", - "1a820c06a7a049d8b6c9ff300284d06e", - "58ff4e0603a74978a134f63533859be5", - "8bdb8bfae31d4f4cb6c3b0bf43120eed", - "39a68d9a5c274e2dafaa2d1f86eea768", - "d0cfe5dacdfc431a91b4c4741123e2d0", - "e7f1e1a14bb740d18827dd78bbe7b2e3", - "3fda06f905b445a488efdd2dd08c0939", - "2bc341a780f7498ba9cd475468841bb5", - "d7218475e23b420a8c03d00ca4ab8718", - "a694abaf765f4d1b82fa0138e59c6793" - ] - }, - "id": "Vnt283M5O-qc", - "outputId": "d2843a73-3ad5-4daa-8d1e-a58de7aa2bb0" - }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "4e6e97b6d54f4f80bb7e8b25aba8e616", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Batches: 0%| | 0/1 [00:00