From 4fd270ef097af7937b5f0a02ad3507f487c5eea9 Mon Sep 17 00:00:00 2001 From: Amna Mubashar Date: Fri, 6 Dec 2024 15:07:16 +0500 Subject: [PATCH 1/8] Updated tutorial 27 --- tutorials/27_First_RAG_Pipeline.ipynb | 2818 +++++++++++++------------ 1 file changed, 1426 insertions(+), 1392 deletions(-) diff --git a/tutorials/27_First_RAG_Pipeline.ipynb b/tutorials/27_First_RAG_Pipeline.ipynb index d9467ff3..1e5b0b60 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/wAq6S+7IfXsSnXXXVqccWZJSXJajPZJF4EQpVABciv2SXs9wtdV57AuLfye2oipLqI7TukbncuqdivI8SUae9kNqI9tyWgyP0Nj4OBdtTsUaY5S1kWNVVxX2rCHWoi1QZj7UFDh/XExWnHFNxiV4GTSUEZdPDoKfAAWf9nbtOdkrS6gxiflCLG4zunlSpiZzUefIhNPOSHVtutMOKJpLhNrQXMmiURkexn4nLbHsgfZCiapP6ix0ZBFy+QkkyJseJMbbkGTRtEp1hLhMuLJs+JLUg1EW2x9CFMoALdsh7eHZgqtA77S3T2Ta4rT3aH4b21ZIX5OzLcPyxxBqNSjc7tx3gRnsSjSXopLpX/22NUMO1f7QFpkOA9+WJ+QV8GCiQwbKkIYitM8eJ9SIuGxfeIQSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsc9i7wLO8nxxvIMNiY7Zt4rlTtjIr8hs34KHXnK1cZlSFNRn9+KX3z6kXXjt96uMcyBd2NUhSIU+VDQs91JYeUgjP7p7GA9E9vprnuV5kxmFzV4i9YRsPnUTNC5YyJEBUqVKaW9zcVGSo2VMxmUmru+W6llx2Lc8MhdnTUik07xyvgTKKTKpM2ZySDjNhcTHq6FXtR1Nt17U1bCnjSh0yfSpTWyTIkEkkpIUK/Vfff8AW7H525+8Pqvvv+t2Pztz94C9nH5Luqmonawp8cu6djPJUOLjcGLJmbHGJqs2J9aUpU4TJSZrxEokHuaDLx3Ic6V2XM41Lw+ooc2taLGazGsdlU+PVeMOvzEtS3oC4KZz77rbJqNppxfBtLadjWZmo9i2oY+q++/63Y/O3P3h9V99/wBbsfnbn7wF7ubdlfO9W8RhRcklYvQTsdx9NLj9dUvSJcJxzv4jrrslS2mlJbcTBaZ7pKVcEOOHyWZltn+X4Pqll9vpvlUisxBF5ittMmOUZXMryNxt6E5GQ4mV5Jz7xHeuHxNkiMlbciMtz88f1X33/W7H525+8d7md9Z1V4piFmNhdME02ryspaz3M0kZp98fgfT/ALAL29KOznnGIZTV5NfWFBNuosfJ5zvkTjxMrtrSe062siU3uTTcdlLfXdRGoyIjLqfCb7Il3MwLC8Tl3UKLEo9NrXFXJsVbi3fbae1GadloSaU7tkTT5kZmSjN3wLqYoU+q++/63Y/O3P3h9V99/wBbsfnbn7wF8NZ2Srl/Sibj82spK7IZCa2oVYfVPaXKCqW5cd2Y0ycxBqjJcbZMkx2y4ciRyWZERlkOq3Z5y/M7bU63rZdIuVfzcaVXRJ77yGnoVY+mS5HkLS0o2u9dXILdCXPRUnfxMi8/v1X33/W7H525+8Pqvvv+t2Pztz94C9LtW5ZFzjI9P8AlTqpeS1cW0yjIKetmlIOCpimkJa33Slfdm9KQaFLQk1EnfYvAqFx2q8svHEKQu5sFIUWxpVKWZGX3PEdUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzrT3R+21KgypNXOrmfJnCbcZlOrS4W5bkrZKFFsfUi6/wBkxm+pXZ6nwCsLqtOrgVEOH3y4/fuqWZob3XtujbdRkexb+v1DDdEc6+obOIzj7nd1s3+bStz6JIz9FZ/4VbdfuGoSz2oc68hqYuMxXNnpmz8rY+pNEfopP/Eot/8AyffAazgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4nsF9mLSjUjsx4veZPp/Q3Vu73qXJsqGlTiyJXTkfr8fExsJ7ibQj4q8a+ZJGFexqfaiYj/ie/WGzkyZHrob8uW+3FisNqddfeWSENoSW6lKUfQiIiMzM/ABDHuJtCPirxr5kkPcTaEfFXjXzJIz7F9Y8Bzi0KtxzOMbv7E2u/KHV20eS8be2/PghZnx2677bBB1jwG0v26KHnGNy7t2Q7ERWsW0dclbze/etE2S+RrRsfJO25bHvsAwH3E2hHxV418ySHuJtCPirxr5kkSRW6m4dc5RJxqvyyjnZFF5d/URrJlyW1x99zZSo1p29e5dB16tbtOkWia1WfYumxU44yUM7mMTxrbUaHEkjnvulSVJUW25GRkfUgGD+4m0I+KvGvmSQ9xNoR8VeNfMkiQYWrmC2eN2GRQ80x6Vj9crjNtWLVhcWKfTo46S+KD6l74y8SH80usGB5Ixav1GbY5aM1LKpFg5CtmHkw2kkZqW8aVn3aSIjMzVsRbAMA9xNoR8VeNfMkjkTuxvolaSDkTdNKCW+ZEk3X4vNWxFsRbme+xEREOw7PnaUwvtJYkm6xewYTIJTvf0z0plU+I2l5bSFvNNrUbZOEjknfxJRbGYz3NMgVieHXt4lgpKqyA/NJk1cScNttS+O+x7b8dt9gEVe4m0I+KvGvmSQ9xNoR8VeNfMkjsezv2isd11wPHLBu6om8qn1zc+bj0GybekQ+RbmSm+XMiLcuqiIZu5qdhzNBa3rmWUaKSqkLiWFkqyZKNDfSokqaec5cW1kpSUmlRkZGoi26gI39xNoR8VeNfMkh7ibQj4q8a+ZJHKvu0TGg6gZri9ZErLT6msWcyB6WxeRnHSfTuZRXIiTN5sjQaF94ZcdlkXrLfn6W66VmSaB4jqRmNhUYjHuYDMt9yZMTHisrcLckE46oi/Bue5gOm9xNoR8VeNfMkh7ibQj4q8a+ZJH00P7SVbqzA1Lt5btVVY7ieSSaZi2RPSuNIjNNtqKSp09kESu836Httt1PxGfxNWMIn4lKymNmWPyMYintIumrRhUJk9yLZbxL4J6qIup+svugI89xNoR8VeNfMkgrsTaEEk//wCleNfMkiTsW1AxfOXJ7eN5JUZA5AWluWmrntSTjKPfZLhIUfAz2PYj28DHfK96f4AHmy1bhR6zVbNIcNhqLEj3U1plhlBIQ2hL6ySlKS6ERERERF4bDExmWtP2Y87+Xp/7QsYaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvY9jU+1ExH/ABPfrCc9Y/sRZx8hzv2dYgz2NT7UTEf8T36w2RyWhj5TjlrSy1uNxbGI7DdWyZEtKHEGhRpMyMiPYz23I/wAKv8ASu8wTUDE+yxjemNS2/qvQ31dPv51bUOR3IUBBLOacmR3aSWle6f7Rkrbx6lyn3sj6dwp+Da931LUwE569m+Sx666Wwjyll3iaGSQ6ZckERuK8DIvTV90xtZpdp3W6S6eY/htQ/Kk1lJERCjuzVpW8tCS2I1mlKUmf4El+AZQAqw09Rh9ziXZ6wnBsafr9d6DLIkrJVFUusToLTa3DnOTHzQXJtZGn0TUe5bFt02Hyy3Asbs+zLqxdS6Guk3B60vxzsHYqFSO6Oe0g0d4ZcuPFay477ekf3RaoACtbtKY/V4blHavqaGuiUtW7gtLJXBr2UsMm6T/ABJfBJEW+25b7esZFpvYaeaudpnRR3SCjjO11Dj9jFzmZCplw4amHYaW2Ysjk2gnVd7y9EyPx367Htuxq7pfVa0abX2E3ciZFqrljyeQ9XrQh9KeRK3Qa0qSR7pLxSYyWprWqaqhV7ClqZiMoYQpwyNRpSkkkZ7EXXYgGnvsad9iFVpd9QCYjVdqdQuzyyCGqtWzJbR5c6bXeOmgiWXFxBEXI9uvToNndY/sRZx8hzv2dY/NUtO3NTsbbqGssyTDVIkJke2OLTERZSuKVF3ZrW2suB8tzLbxSnr0Ee4l2XJWKZNWXC9adVrxMJ9L511tesOxJOx78HUFGSakH6yIy/CA0k0kfwfNKTsvY9plRpa1doLqBPyawr6dyK7DrkoWczyt820ktLhKTtupXLfofpFy4uqeqNDgXZo7S2lV2qdDzqdnE+fGqzgPnziOzY7jcnvCRwS0aUKMlGot+m3vi3tXABpDkVO2Xa51Mar4SClTtE1LWmO0RLfeN9SCM9i3UoySlO/j0IvUIhp7jGKrEeyTlWpEJVrpBXY7MhSlvwVy4MO1JJIQqS0SVb+9NKd0nsaTMvAzFngAKiLeG1kmk+ZWmIoKFpdG1sfnWPktEuTGi13k7RsPO1/1s1x0GaTNoyIuqdy8CGWX+F4+72a+0RnuKaj12X1dlVQq2XCo8PXj0An25DK0PJQbhpWripSTNKS6me57i0sAGG6S4LjuA4JTQccpIFJFOFH5ogx0Nd4ZNJIlLNJEalbes9zGYq96f4B+j8V70/wAPNxrT9mPO/l6f+0LGGjMtafsx538vT/2hYw0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABex7Gp9qJiP+J79YbRDV32NT7UTEf8T36w2iABhGuOcO6aaOZtlMY/55U08qVFLjy5PpaV3SdvXuviW33xm4xjUnT6v1RxGRjlq/Kj18h+M+6cNaUrX3L7b5IM1JUXFRtklRbbmlSiIyM9yDWXH9dtRcAhWV5OPJtR8bjVERta8jx9OOvu3kibHjNRYnKMwpbau+cMzU0okmlBcz3MS5b60ZfDvXsYgYRV2WWwq47mxilkKm4UOGpa0MEcg4vJT7ptO7Nk3xLu1buEXEzkHOsBr9QYtPGsnpLbFZbRLhtEZSUk69GdJ1pK+ST3RzSlRkWx+iXUhi2d6B1Oc5PYXft9f0D1tWt09wxTSWmm7OIhTikNumtpa0GXfOkS2VNr2WZcvDYIvt+2dMXi1pk2N4IVvQ1WK1eVzX5twUN1DUxLqkxkNkw5zfJLRGRbklXL3yfR5d3Zdp3IKGzyCls9P228hr5tFFiwI14l1MpNnIW02SnDZSTbrZNLUtGyk7EWyzI9xls/s2YlNqcprEOT4dfkL1YuRHirbShhmAlhLEZkjbPiyZMESknyM+8c2NO5ccV1U7Pk3J9SKS0pLG3rm7TImbu8t4r8XvK8odY8xEQwh1tRGRvLQsyUhzqazPYjIiDptQe0VnDWJ5fR1eOVtFqRWX1Tj7LZ2py4ajsFNEy+06cYjUaUuGakLaLiSVK9LYiVjnaD1l1Qo8tsodGi5rmsaw9F5dNYgiusWI8x514mSfcmtIdWwlEV1R9w13hke/Eum8uTezHj8vGE1yb7IY9yd41kjuUIksrs3p7aeCHVmtpTRkTZEgm+64EkiIklsONkvZdrMqyPJbOZm2XtRcliRYVzVRJUVmPOZYaNpKFLTHJ9JKJThqJDqSM3F+BHsQdMz2nn6zTXP76VVRb1/C62uNcqulKaj3M6RCZkd20SmzNlBqkMkRnyPZzqRGWx47qxq5mKKbtAxI8k6tVNErcfpDgySWbVjObIkvJWTTbiHCOZF9Hksi4pNJkZmQze07J2M2EiyZZvsirMesbeDdycbgvx0QHJMUo5N77sG73akxGUqb7zjsW5Ek9jLvbns94/dVGTQnLG2Yevsij5Q7OZda7+PNYOMbBt8mzRwR5IzslaVl0PffcBG2tevmQ41gmpUDCMeduo+HVp1k7JJdv5O63YrjINtDCe7Wp9xHfMLWalN9V7EaldB8aLtbQ4WYQcCqIkTKXqi2jYpOeev0ncyJKVIZkSWoXdrW6y0o1G486tsvrbhly23POcp7LWP5Tb3cheRZJXVN3bxL2xoIMplMGTMYUyZOKJTKnNllHbJaCWST232JWyiyXDtG4mCZZbW9RkN41W2U2RYvY6t1hUBMp9RredRu13xclqUvj3vAlKMySQDh6S6qXuqkq3nJxeNV4nEs7Gri2jlobkiauLKVH71DBMkRNLNtzqbnIjTtxURkoSYMb04wGv0wwqsxmrekyYUFKyS/MUlTzqlrU4tazSlJGo1LUZ7EXj4DJAAfiven+Afo/Fe9P8ADzca0/Zjzv5en/tCxhozLWn7Med/L0/8AaFjDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF7Hsan2omI/4nv1htENXfY1PtRMR/xPfrDaIAAAAAAAAAAAAAAAAAAAAAAAAB+K96f4B+j8V70/wAPNxrT9mPO/l6f+0LGGjMtafsx538vT/wBoWMNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXsexqfaiYj/ie/WG0Q1d9jU+1ExH/E9+sNogAAGl1yWn+dU+tub6suxrayo7uxpKutmSDJyrYjl3cVERolboffVs6S0FzWbqCI9iIgG6IDSBnUfU/HdKMwk2eokiivcDxqliIrFwYklyxvVVqH3IzxutqccN1bzDeyFJVyUZkoupCRaB+xu9ftUcrtMytaRrFKKvrXaeH5Etlha4S5cjYnGFr2SbzLiVErc1IMlGtBEhIbNANOdJMryGJhOD4c/mBaexYeAtZzeXrEOGb7jst91ZoSl5pTKENqJ1Tpk3uZrbIjRvufTu65aq5FpXmWWP5S9iEvFsCqrZcGJVRVnJuX2ZL3BZPNrNCFoOISmy2URrLipGx8g3eHDh3ddYWE+DFnxZM6vUhEyMy8lbkZS0ktBOJI90GpJkoiPbcjIy6DVXJtZc5uHV2MXL04s+nOYGEVlBEixXG5zpPsInvSFPNrcMuKpKkJaU3sltBmajV0lDszqK6Y1IyszJxV/mlmaHPWbMNSa5svwbQtyL/wAQCZgGokvJsmhZ7n0zHb5US0yLUiqxCFOfgxnVNxY8NEiUjiTaSWlBKmJSat1Fw6q6bj6UmpWfWmaR8I/lCkNtfVrb131QPV8EpbtZDrG3HEmnuSZ5olvEklk2XRHpEotyMNtwGqej2uOV5FnWM09plLE/H2PqonSL16PHYTb1sKTHjRZClJSSElzecM1tcEqJolbcTHQYPkmSa7ZpotJsM4s6lx2Be5iSYLMJtKo6piY1e2SHI6yV/NpSkGZkZ7J5bksyUA3LAa4Y1qNkatTtQqfK86OhSzXTbSmdaZgOUrFYbpNR5vfce9J5o+jrb6yQpRmafRLpPmLR5kTGaliwtk309uI0iRapZQyUxwkESniQj0UEs91cU9C32LoA7Mfiven+Afo/Fe9P8ADzca0/Zjzv5en/ALQsYaMy1p+zHnfy9P8A2hYw0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABex7Gp9qJiP+J79YbRDV32NT7UTEf8AE9+sNogAY3K0zw+dljWUScUpJGTNbE3dO1zKpiNi2LZ408y2Lw6jJAARlhugGMY5lt9ldnV1F/lNlcv2rN1Jq2ilw0LShDbDbquSyJCG0luRlue57FvsMrmab4lYXs66lYvSybmfEVXy7F6vZXIkRlFsphxw08ltmRERoMzIy9QyIAGNXemWH5MqqVcYpR2qqkiKvOdXMvHD2227nkk+722L3u3gX3BzJuFY9ZN2rcuhrJSLZxt2wS9DbWUxbZJS2p4jT9cNJNoIjVvsSE7eBDuQAYrK0owidkh5DJw6gkX5utvnau1bCpXeNmk2196aeXJJpSZHvuXEtvAh3dRj1Xj/AJb7V1sOt8tkrmSvJGENeUPqIiW6viRclnxLdR7mexdeg54AOmawvHo8hmQ1RVjb7E12yadRDbJTctxKkOyEntuTq0rWlSy9IyWojM9zGB5H2ccPy3UKBf3FHR2VNDgzmU0EunZdjrmS5LD701XLdJuqOOkjM0cjNSjNXUSqADGrzTLD8naqmrnE6O2bqS2r0Tq5l4oZbEX1klJPu+iUl6O3gX3Ac0xw51ePrXidGtWOpSimUqtZM6xKSIklG9H6yRElJFw224l9wZKADFK3STBqavuIEDDMegwbkjKzixqphtqcR77k8kkETm+5++38TGUMMNxWW2WW0tMtpJCG0JJKUpItiIiLwIiH9gAD8V70/wAA/R+K96f4AHm41p+zHnfy9P8A2hYw0ZlrT9mPO/l6f+0LGGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL2PY1PtRMR/xPfrDaIau+xqfaiYj/AInv1htEAAAAACCM70m1Vve09huaUeoftTpvWQ+5tMX7x0vKnN3Nz7si7tfIlNlyUZGnh03E7gADTTtUSI9Tf6p3Od4rbZDAg4u39RDiat6bWRpRtPd64pSEqbjyO/Nku8d4qJKUcD8SPHp+DXeK4BqnpvHxPJH7fIX6HFYT0GnkOQiqEQoMRcg5SUd1xSaphqLlyT1MyJO6iDewcexsY1RXyp815EaHFaU+884eyW0JI1KUZ/cIiMxpvD0dus+1/wAiRmSZcN5nJETaiwLFJTrkWtjG27GahW3fHGitrJvi42lsnVKW4R78iMsdvcBn2uG67e0+A218xfVjq27y5xl6JfG5LlmqRC4up5TEx0ElxpaE7I4IQk1GRGA3Q/lBoTr8ZnJmOLi5ItpurcRFdUT5uMqeRvsndsjbQo918SLbY9jMiGRDV3J9Poz+W6YzNMcDRRMY/j+RW9YtdCdciLMcYajx2FpW2g2luqfWs0LIlK7rkZHx3KJrfT62mYCmfhGD5JAyNnB7Guye0s6mTHn3drNZaYQ24TiSclmh1Tr5ukSm0EgiSrY9iDfsdVZ5PW1FxU1Uh/aytVOJiRkJNS1k2nk4syIvRQkjTuo9iI1oTvupJHC+kukcPTvtDZQrH6F6lx2NilXCclkytDdtNN+Upx5Sz6POobQ0SlmZqLvdjPwHBusptsf1v1iyZuinZHYY5jFRAx+ogsqcckKkrkuLJJJIzJLjyWUrX4JSxufRB7BMFHqfj2R6h5PhVfM8ovsbjw5Fk0ki4slJJw2kb79VcWuRlt0JaOvXplY0aocA1O0SyC6tLfE27m4u8DvF2FnjD0m0OyuUPJktm8nyVruVLN91tpojX6KSSR+h1/jNezLLoaqwp8VxqRHnVmlZJenMML2t7dqTHejIcdPo68hUFWxGZqSTyfBJkA3VybJa7D6SRb20jySujmjvpBpM0tkpZJ5K28EkaiMz8CIjM+hGOyV70/wDSPJJMzWHQXU3UONFeK41YXHxPE4UlOzrdYbnk7Hon1TyNyXLX9xBkZ+9G7SUd2ySeRq4p25H4mA83WtP2Y87+Xp/7QsYaMy1p+zHnfy9P/aFjDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF7Hsan2omI/4nv1htENXfY1PtRMR/xPfrDaIAAAAAAAHTZhh9RnuPSKO+ieX1UhTa3Y/eLbJZtuJcRuaDI9uSEntvse2x7kZkO5AAAAAAAAABxUVMNu1ds0xm02DrCIzkkk7LW0hSlIQo/WSTWsy38OatvExygAB0Gc4LS6kY3JoMgjOzKmSaTejsyno/eER78VKaWlRpP1p32MuhkZdB34AOpi4jSwSpij1kVhFMycetbbbJKIaDQSNm0l0T6BEkjItySZkXQzI+1V70/wAA/R+K96f4AHm41p+zHnfy9P8A2hYw0ZlrT9mPO/l6f+0LGGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALtvY7tRMYxzso4lDtL+ur5RG6o2ZEhKFERr6HsZ/eMbKfyxYN8LKj54j9482oAPSV/LFg3wsqPniP3h/LFg3wsqPniP3jzagA9JX8sWDfCyo+eI/eH8sWDfCyo+eI/ePNqAD0lfyxYN8LKj54j94fyxYN8LKj54j9482oAPSV/LFg3wsqPniP3j+l6vYS2rivKqlJ/cVLQX/+x5sxIevP2QXPxKL/AKKQHoH/AJYsG+FlR88R+8P5YsG+FlR88R+8ebUAHpK/liwb4WVHzxH7w/liwb4WVHzxH7x5tQAekr+WLBvhZUfPEfvD+WLBvhZUfPEfvHm1AB6Sv5YsG+FlR88R+8fitYsH4n/+rKjw/vaP3jzbAAzDWVxLur+crQoloVezjSpJ7kZeUL6kMPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEh68/ZBc/Eov8AopEeCQ9efsgufiUX/RSAjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABeX2btdtCMP7PuA02Sqgou6bGahVys8bkyUQzehtPIckPojqbQlSFpVzUok+JGZGRkVGgtq7I+p7mF6f6iU0bBMpzawuMZxiPEjUVSuXGcdVjsZBNvul6LKTNRbqc2LjvtvtsA3OzLVLQ3A76HSWrNSu3m1qLeJCrcfdsHZURalJS60mOw53hboUZ8dzIi5GRJ6j432r+geMZuvE7N2gjXTUhmG+XtKpcaK+7t3bL8lLJssuK5J2Q4tKupdOoj/s6aOZHpjrRgsS7rpD50ej1fQv25MqXFTLRNNTkdD+3EzIiSfEj34kk9thgGY41llPpHrVom3p3kd3lGaZLaSqq7YrlOVMhifIJ1uW/N/o2lMpVspKzJRGyniRkZAJ1y7XLs+YJe3FReOU0KbSym4dptjzzjVe44htbZyHUMGhpCkuo2cWokGfIiVulRFy6TVzQfIYOTS4Sac2ccq1XdiT+PusLTASlSjlNIcYSp9rZCtltEtJ9CIzMy3hjPdNsqXpJ2w61uht7KfcutJq+EB1TlrxqIbZrYSSd3d3ELT6G/pEZeJGOy7T2NWyMoze69qpqadrQbI4D1j5Oso6JBrYWhlTm3EnOKXFEgz32JR7bEYCVcK1b0J1Ct0VdGzVv2D0JVlGjycceiqmxkkSlORu+YR5QREZGfdc/EdX2Z9VdPe0hjUyfDwaNUz4suW07Fk4+82yTTcp1lpSX3Y7bbilJbJSkIM1Nmo0qIjIxHeDWlvrjl/Z1RUYTlFFW4LGO0tsgvqxcFgyVWqjIjRlr/AKfvFOkajRunigj3PwEg9j2VaYdQ3Omt9i2QVFvT3NzN9spVa4msmMP2Tz7K2JW3duGpEhJ8SPkXFW5FsAmv+TrFPgxTfo9r6I6aia03zedbR6qNjdxOqZKoNgwwww49EeQZpNt1O3JB9OhGRbl1Lch98swm/v8AL6C2rc7tsdrK9aVS6SHFiuR7IiWSjS6t1pTiSMi4/W1JPY/u9RgFjoDbZ3rPAzzJ7KupSoZprqGMWj9zOlsJV6CZ85Rd440otjVGQSEeo1OEAy/UJGmmlWG2eV5TUUtVQVqEuS5h1SXSaSpaUEfFttSj9JSS6EfiMUxfU/Q/MXr1itj1RS6SCq0nRJ2POw5CIiSPeQhp5hC3Wunv2yUkzMi33Mt+r7fbhtdkXUNZIU4aWIquCPfK/njHQvviO85cv+0Bqm7k1LgmVY7TYtg9/XPSr+pcgyLSXNbaS1FYZX6bpI7lSuRFx5KIiMzPqEk1GtegF5iFnlcVVN9TNdGYlP3D+PusRVIeM0tpbdWwlLrhqI0G02alkv0TSSug+kLWXQGbhV5lneUUWkopMeLauT6NcV6A4+4htnv2HWUutpWpxOy1IJO26t9kmZR7kenGQx+yZ2d3YeMT58zBJGM3lrjLEfjNdbjxiRIbSyrY1PNqc7zuz2M1Nbe+2GAa041letb+q2eUmDZNV002vxaihV1lUux7C1djXaJL8nyQ096lDTbnHktJbklR+CTMBNDvaS7OTC7Bpw4TcqvQT0qEvEZhSWWTLfyhTJxe8Jjbr33Huy3L0upDvcr1c0Jwywq4NgzWSJdpVJvILVVjj1iciCpXEpCPJmHN0dSPf1F18Oo4M7FbZ7tVai2p081dRM05gQGZ3kqzYffTLnmplK9uKlklaDNBHuRKT06kNedF8um6HZ9o+WQYhls+xj6LRoUmqp6R6XOjOpmt+i7HSXNGxp4mZlsRmRHsAmnUztCaR4LC0utKzGqzKKDObFcZmzqKR2WllhDLi1uJQxHcUtwloSjuei+qz22bXtSB2mHokntH6qvQGjYguZXarjtGwpg0NnMdNJd2oiNGxbeiZEZeBkWwt0rtPczwXTLTXNJ+F3Kji6o2OZz8Wqoxy59VXzinJbQTDe5rU35Q0paEbmXJXT0TFRPaVtk33aM1Ts0RpUJE3KrWSmNPYUxIaJct1XBxtXVCy32NJ9SMjI/ABHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANx9EvZNcw0Ex8q7HMDxNUh2HBiTbCUc1bswokZEZha0+UcEqJptJHwSkj23Mt+o04ABYf57LVr4E4X+al/xw89lq18CcL/ADUv+OK8AAWH+ey1a+BOF/mpf8cdXlXsxepGa4xcY9dYBhc2nt4b0CbG4zm+9YdQaHEckyCUndKjLdJkZb9DIxoIACwOn9mb1PoKiDVwMEwtiDCYRGjtcJquDaEklKdzkGZ7ERFuZmY5nnstWvgThf5qX/HFeAAPTLohm93qlo1g2ZTjgQ5uQUkO0ejx4y+7aW8yhxSU7uGexGrYtxm6mp5n6MmMRffjqP8A/wCxqB2SdXMrj0WkWEWJ1OM42rC6l6qXY1sh16+QmrbdkLjy0upZaUy4fFTC0KWaEqWRkRlty9NtVtWarQ3A8ilXNFk+Q6lZPHKoanVsmO3DiSnJElfI/KlmpKIje7SUkjgSSJXenuow087VvsnOZt5xqTpPcYJiN9i9fdSqlSZHlzLkhuPJMkKUpqSkyPdtJnxMv/sOp89lq18CcL/NS/441D7Vbc1ntN6rospDEqwTlNmUh+KwphpxzylzkpDalrNCTPcySa1GRdOR+IiwBYf57LVr4E4X+al/xw89lq18CcL/ADUv+OK8AAWH+ey1a+BOF/mpf8cY+fsuuennyc1PTvC/qmTWHTlO/n//ALobpOm3w8p4e/Ij5ceXq326DRAAFh/nstWvgThf5qX/ABxolqPm8vUzUPKMvsGGI0/ILSVbSGIxGTTbj7qnVJRyMz4kazItzM9vWMdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFwXZj7U3ZH030z0+k3uYOt5tX45GgzWp7FzOZhvqjNtyUstKQtho1cTSpTKSJRFtuZGJKrO052ONHV47TMZg/B+puUq0qIspF5NTBcdiqj7t94lZJR3Dikpb94jkZpSkz3FGYkPXn7ILn4lF/0UgP77SGWVWedoPUrJKKX5fS2+R2E6FKJtTffMOSFrQvisiUndJkeyiIy9ZCOQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH0jR3ZkhphhtTrzqyQhCS3NSjPYiL/uJCLs46oGX9Q735kv9wCOQEj+5w1R+Ad78yX+4Pc4ao/AO9+ZL/cAjgBI/ucNUfgHe/Ml/uD3OGqPwDvfmS/3AI4ASP7nDVH4B3vzJf7g9zhqj8A735kv9wCOAEj+5w1R+Ad78yX+4Pc4ao/AO9+ZL/cAjgBI/ucNUfgHe/Ml/uD3OGqPwDvfmS/3AI4ASP7nDVH4B3vzJf7g9zhqj8A735kv9wCOAEj+5w1R+Ad78yX+4Pc4ao/AO9+ZL/cAjgBI/ucNUfgHe/Ml/uD3OGqPwDvfmS/3AI4ASP7nDVH4B3vzJf7g9zhqj8A735kv9wDm6JacY1qSdhDtJdhGs4+zraYrraULaPYjPZSFHuSvHr/aL74k3W7SvGm6i0ymfOntTGYqWWGkONk2txKSQ0RkaNz3PbfY/DfwGCYJo5qvhGV19wzgd+ZMOF3raYavrjZ9Fp8PWW+339j9QkXtD4BqNmMuBVVGG3cmrjpKQ463DXxcdUXQvD+yk/wD7qMvUA1UASP7nDVH4B3vzJf7g9zhqj8A735kv9wCOAEj+5w1R+Ad78yX+4Pc4ao/AO9+ZL/cAjgBI/ucNUfgHe/Ml/uD3OGqPwDvfmS/3AI4ASP7nDVH4B3vzJf7g9zhqj8A735kv9wCOAEj+5w1R+Ad78yX+4Pc4ao/AO9+ZL/cAjgBI/ucNUfgHe/Ml/uD3OGqPwDvfmS/3AI4ASP7nDVH4B3vzJf7g9zhqj8A735kv9wCOAEj+5w1R+Ad78yX+4Pc4ao/AO9+ZL/cAjgBI/ucNUfgHe/Ml/uD3OGqPwDvfmS/3AI4ASP7nDVH4B3vzJf7hieWYTfYJYNwchqJdNMcbJ5DExo21qQZmRKIj9W5GX/YB0gAADucK/rlQ/j8f/USPSnRf8Ervxdv9Uh5rMK/rlQ/j8f8A1Ej0p0X/AASu/F2/1SAc4AAAAAAAAAAAAAAAAAAAAAAAAAAAAYTrldzsa0U1At6ySuHZV+PWEuLIRtyadbjOKQst+m5KIj/7AM2AacYJqtl9hmXY5hScgmvRcqxKfPu21r39sH0VjDiHHT8VGS1qV+E9x36PZFsBVXQLM8Oz9NPPsHKiNZpo0rjvT0qUkoqFIdM1urNHokkjI99jMjJREG1ACNdGdfKLWtzI4lfWXWP3eOyURbWkyGGUaZFU4jm2pSUqUnitO5pMlHuRCSgAAAAAAAAAAAAAAAAAAAAAAAAAAABS57Lf9tQj5Ei/5rF0Ypc9lv8AtqEfIkX/ADWA0oAAAdzhX9cqH8fj/wCokelOi/4JXfi7f6pDzWYV/XKh/H4/+okelOi/4JXfi7f6pAOcAAAAAAAAAAAAAAAAAAAAAAAAAAAxHWHGZua6SZvj1alCrG2o50CMlxXFJuux1oRufqLkouoy4fCFPjWLKnokhqU0lxbRuMrJaSWhZoWncvWlSVJMvEjSZH1IBqNhOiWodTkHZLtpmMkynBaKfS5Gx5fHUuEpyE1HbcIyWZOpNTe5kg1GRGMWoOzVqRC7O+k+MPY5wvKPVNjI7CL5dGPuK9M2Q6b3InOKvQcQfBJmvrtx3IyG9IAIL0h00yTF+0/r/ltnXeTY9lKqA6eZ37a/KvJoKmn/AEEqNaOKzIvTJO/iW5dROgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKXPZb/tqEfIkX/NYujFLnst/21CPkSL/msBpQAAA7nCv65UP4/H/1Ej0p0X/BK78Xb/VIeazCv65UP4/H/wBRI9KdF/wSu/F2/wBUgHOAAAAAAAAAAAAAAAAAAABE/arzK2wLQHLLmjmHWWSER4qLEi3OCh+S0w5J/wD7SHVubn0LhuYgLUWqwjQzO8VnaYG1HuaSkubzJ7GHKOQ6/WtVzvduT1mZ96tyUcdSFObmZoUZdCMbnzIcexiPRZbDcqK+g23WHkEtDiDLY0qSfQyMuhkYjfLuz/jFppdkWEYvV1GEQbxKWpaqiqaaQtHNJuEptvgSjUglo3M+nPfrtsYQLkmueoejcNqbJyhOos5vAZOQXNXIhxY7NXNT5MmMslsIQpLTq3X90uKUZpZWpJpIunJezrWqkxaXMk3k2K9ay6OmrXL2LUOOt2Mme0h9bLUFTiCilHWo9nnFuH4kovfHs5jum2I4fWTq2hxalpK6eajlxK6uZjtSNyMj7xCEkS9yMyPcj8R/FJpfhmNVseuqMSoqqvjzCsWYkKtZZaalEWxPpQlJETm3TmRctvWA1uyPXbL9OIOqlAV/NzS+YvYmOYtIVUodllLfgNSZClMQ2SN5uMh03jJLZq4oNJmozIxH+EvRT0Lc0jiSLWTGPVWJj6FXkV+NOdhOPs2zq3Wn0IcSpbRSN+SS36n4GRjdyPg2NxLorhjH6pm3J16R5e3CbS/3jqUIdX3hJ5clpabSo991E2gj3JJbFYLjarxV0ePVR3CpKZh2BwmvKDfSybCXe848uZMmbZK33JBmnfboA03ym8xHItOdVdTs9o6rUXJKLILGuaxW9tDjorIsaSphiPHRwcJt5xCUukokcnFOl6RFttl+S6oauZxqhmGO4S1Kx9vGpkKqipZOrVBVIWwzIeXPOQs5JtcXiShMZojUSDMl77kjYudpRhNnlCMlmYdQS8jQaVJuH6thctJp96ZPGnn02Lbr6hypOn2LTcsj5RIxqnfyaMju2Lp2A0qY0nYy4peNPNJbGZbEfrMBrijU7UCZcU2RR8wdVUWmpr+LQKEq6L5PIrmXn2nzU53femtJRZC0qStJbJIlErxHX6Ma1apaht1GotmqXVYW4xPtrSule1fte1XoadNluKbS1zFSErJnvFvG2gtnC4EfEhtJHwrHobda2xQ1jDdZIclwUNw20lEfc5k460RJ9Bau9d5KTsZ94vc/SPfgwdLMLrHrt6HiFDEdvELbtXGKxlCrBCt+SXzJP10j5HuS999z+6AgDGMw1NawnSGFbZw87l+o7TTsqc9XQ249Ky3DcmPnHbS0XJ9SeDX101o3I1kgiI0nh8XJcg1ki6WVT2pdqqDaZzdyYN7GarkPSq2r79LDii8m7lavKGmlFs2STSszNKtkmW3WQ4HjOXU8epvcdqbqqjqStmDYwWn2GlJLZJpQtJpIyIzIti6EY4D+kmDSquvrHsMx56tr5Sp0OG5VMKZjSFKNanm0GjZDhqUpRqIiMzMz33MBr5mOsGauxctyCnyxVe5j+XRsRqMVKHFdO6eJ2O26clSmzd5u964pJMm0SEIJZ8i32krQS2yvUBV9l9vlcqRROX9tCp6VmJGbjlCYlLjNLWsmu9WvdlaiPmRbLLcldDEiJ08xVGWqypOM05ZOpHdquygNeWmnbjxN7jz226bb+A7Snpa/Hq5qBVQY1bAa5G3FhspaaRyUalbJSREW5mZn98zMBzAAAAAAAAAAAAAAAAAAAABS57Lf9tQj5Ei/5rF0Ypc9lv8AtqEfIkX/ADWA0oAAAdzhX9cqH8fj/wCokelOi/4JXfi7f6pDzWYV/XKh/H4/+okelOi/4JXfi7f6pAOcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClz2W/wC2oR8iRf8ANYujFLnst/21CPkSL/msBpQAAA7nCv65UP4/H/1Ej0p0X/BK78Xb/VIeazCv65UP4/H/ANRI9KdF/wAErvxdv9UgHOAAAAAAAAAAAAAAAAAAAAEd552g8B01uHaq/vVM2DDBSpLEODJmnDZPfZ2R3DayYQex7Kc4kex9egkQanU1vk2nLWsePt4BkV5nuTZFYy62a3XLXWzY76SRCW7OP6022y0TaFIWolJ7tXFJ79Q2prrGLcV8WfBkNTIUppL7EhhZLbdbURKStKi6GRkZGRl4kY4RZVVKypeNlMQq8RCTYrhkkzUmOazbS4Z7bERqSoi3Pc+KtvAxoQjSuuep9RcBYxO0zTM6qqqcKxu5arH1Q4UqNWNEc0pnHuoxtPSFLP00ucWyJJHuRCZa3Da6r1x1dvMi0+fyLJI1HDTT3D+NKkt2DLFaaX+7kk2pPfOuPOMqa5c1pQktlJItg2SxfKK3MqVm2qXnH4Dq3G0OOsOMqNTbim1+g4lKi2UhRdS67bluRkY7UaU0+nR4ZS6cY5nOA3OZ4lVafRW4NFEp3ZsZy/UpRyifbQk0Muce6Jtx8koRzd2Uk9xjtloDkknSfUdrLsXm5Xl1Ng1NjFItyO7J5WBMPOLkRj2PvVMuzUJJ9O5p7hfpF6RAN+BjOL6gV2XZJltNBZlE9jM1qvmSHUpJlx5cZqRxbMlGZ8UPtkrci2M9uviNRcwwmfkWUuV+SYZkWR5g9n9ZEjZA9SyJDFTQR5EdSXo8rgbbZOobV3ptq58n3Dc2SnpsJ2baufAo83lW9dMrLixzG4mSGZkdbW6DkGiMpClEROoOMiPstBmnxLfdJkQSPAyits8gtaSO84uyq0MOS2lMOJShLxKNvZZpJK9yQrfiZ7bddtyHajUC10qnZNkuRtOYrOiQss1YivTO5hOMI9rYEJCzkLUki2Q6/FWXeGZEs3y2M+XXCnMXosV1Hrcdu8JtE4c7m2Q38bGK2hkymyhxoMevQpMRltR+TuvyFObknu1cyM/RMwG+g6q2yqqorWlrZ0xDE+5fXGgMGkzU+4hpbqyLYj22bbWozPYunj1Iah6dY1d6XZrgltcYdkUTFY/1UWlPS1dY9PXVqlSIyYUJxDJLTHPycn1FyNLaDcUjkWw4ummmDcjItEJGoenMuwbfp7m2fXMx5c0otxY2DMkm5Z92ryc2kreMlO8SI9+pGnYBu2A1FwimiVee6tZBJwDIMnx6wrZ02RZTcbkRL9bj7uzlSwbnBUtngndo29ibIkoJR77jaPD6ivx/E6WrqYTlbVQoTMeJCe5c2GUIJKG1cjNW6UkRHuZn06mYDtwAAAAAAAAAAAAAAAAAAABS57Lf9tQj5Ei/5rF0Ypc9lv8AtqEfIkX/ADWA0oAAAdzhX9cqH8fj/wCokelOi/4JXfi7f6pDzWYV/XKh/H4/+okelOi/4JXfi7f6pAOcAAAAAAAAAAAAAAAAAAAAAAA6fG8RqcRTZpqYnkpWU56zlmbi3DdkOmRuL3UZ7b7F0LYiIiIiIh3AAAAAAAAAAOnXiNS5l7OUKicr1mAusblm4v0Y63EOLQSN+PVbaDM9t/RIt9h3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAClz2W/7ahHyJF/zWLoxS57Lf9tQj5Ei/wCawGlAAADucK/rlQ/j8f8A1Ej0p0X/AASu/F2/1SHmswr+uVD+Px/9RI9KdF/wSu/F2/1SAc4AAAHQY5qDi+YWlxW0WRVVzYU73k9lEgTW33YbnUuDqUmZoPdKi2Vt1SovEjHfiKNIezFgeh2Y5jk2KwZMa0yqR5RPU/JU6hJ81LNDST96nktR7dfV12IiASuI5r+0LgNtmEfGYl06/ZyXpLDDia6V5I8uOlSpBIlG33C+74KJfFZ8T2I9jMiEhyH0RWHHnVcGm0mtSvuERbmY0ZwHBKzVHNMsw2gydnKcOcxm6jYxb1Es3GMTKbwbWw+33STVJWbzqkmt5SyQ0pPBBbqMNlI/ak0xkxLKYnJFJgwK962XMdrpbcd+G0pKXX47qmiRJbSa0EamTWRck/dIdhXdoXT+yg5JMLIChRscaafs12cORC7lp3l3LhE82g3EOGhRIWjklZlskzMQ/Xdla4f0umUUytpq+/kJrqk5/wBUlnboKqblMOS2mjloM46VttGSWGy4bkjksyIjLs9X+zLf6lXeeWyJ1eT1lYUEmrjLmSY5OR641OKZfeZInGDU68+aVtGo07Nq8S2IJB901pymqcnvXcqG23YR6pUabUTY8spL6TUw35M4yTv1xJGaVcNlbdDMfTJu0lp/hzDbtxaT4ZnETPfZ9pJy3oUdSjSl2U2lg1xUmaVERvkjfif3DGJ0PZ9lxrPTywegVtc5V3ki/vke3My2flyChvxYm0uUjvX+CXiVu5wJPEiSWw6HUDQLUC7ss+g1D2Nv0eY5JWXM2wspchE0oUdMRDkAm0sKTxMoy+K+fg6pJoIz5EEiwu0DTS9T8zw46q7T9S8NmTJsWqea8ytxTS3ltJNDBp5JbS2pJct3DdIkEoyMdfSdqLEXNPsXyW/ecqnb6sO4ar66LLsnG4e+5SVk0xzQzxNJm44hCS32M+g4ETS/PqtzW5mK5QOFmK5M6mtVzH0yGpCoLEVhmQ13JkltvuSPmhazMj94R7jHkdnzNsPkW0PD5lB7X3WI1eKuT7N15MinTDaea7yOyltSX0ml81EhS2tlluZmR7AJCyftNaa4g883ZZGZExCjWbzsSBKlNMxH+XcyVuNNKShpXA/rijJJdNzLct5QSolJIyMjI+pGXrGtVj2WrZvTzU3FaqbXtRsij09FWHIec3Zp4kaPHcQ6om/6Qy8sMiSRpPmjdRbnxlpOsuPpnFCKuysnCc7kjLDrcmiPfb+k8l4cf/Fvx2677AMQxftKUzljmjGSTY0NNVa2rcJmDFeee9rq9pHlMl5KOZls8T6SVsklHwQkjX45rY604RVRrd+VkUVpupp2r+aWylKZgu8+7e4kRmfLu17JIjUfQtvSTvEGiPZgu9K726lzZdXZxM1jzVZcybri1lMckvutORVqb3U2aJK21tq4ERpStO5msldFgHYbPGZenE63yM7awrGOOWOmRn7em15MqCye5f0MdcRniR7bpQe5emoBNr3aCwRjKo2Oqt5KrN+Y1XEbdXLXHbluJJSIzsgmjaaeMjI+6WtKy9ZEPhB7R+ntjTWdwxdvqp65xxl+xVWS0RjdRI8nNlt1TRJdd73ZBNoNS1bpNJGRkZxdjOgeo9FZYJWuu4vJxnGMktcifknMkHMtn5KJpx3XEdxxbU25LSak81krbkSi4kk/vl+B1WlXZQxLEcly6oxbIapuGqDkU1w0wWr1r+cJfUpSSI0G+hatnCIlEexluewDP2+1Hpw7AclItrE1onuVioPtDYeW+UttJddb8l7jvvQbWhSj4bJJRcjLchnWTZpU4hhljlVrJOLS18Jc999aDJSWko5n6Jlvy28E7b79NtxqTh+kmX6p6S10ukg19TkMi4sLBzPLC5lJskzTdJn2ziE1FaS8w8y0nZhZMtqQTaTI0kRnPPajxmflmillXQkOSTKfVyZTTaeSnIjNhHdklsXj9ZbcPYvHbb1gOJZa45CdtS4tR4Qm3zybVldT6mTZlEi1ERazS35TJ7tZ94pRGkkIbVubbh9Ep5HxsZ7WWJzq5LWRR7DHsnak2EOVj8WFItHkOwnUNyTbOM0vvEJ71pRKIiM0r32LZW395Hp3qDjer+RZrgKsant5LWQoM+Lkb8hg4jsVT/dOtGy2vvEmmQrk2fDqkjJZbmImwLTnNsD1rva3DXaLIr2qx1K7m9yGQ9FSqytZ0iVJfbZaac5kXkzH1o1I9Huy59DMBM1n2mcXZybTysqWbHI4mZx3p0Wyqa6VKaaitkku9V3TK+neONIUR8e758lmktt/vXdovHHFZlIszcrKygvyxtl048lyTPmdy24tpqL3BOrWRuGSSaJwlpTzSZl4YvgGgOQaTZzgT9JJq7vHqXGF49Ndsn3I8xDjklMh+UyhDa0LN1SE7tqUjjxLZR+A62NoFmuPW9Dldc5QWuSQMpv72RWzpj8eI83PNxtk0vpYWpLrTHcp6tGR7uJI9tlGEiOdpDT1upqrAruQ6i0kyYcSKzVzHJjkiP8A07BxktG8l1Gx7tqQSvvBI7SOnjGN0t6i9enQbhl6TCbrqyXLlOtNK4vOHGaaU8hLavRWpSCJB9FbGMQ087Pt7imoVHk9pZV9k6w1eWU/uObZOW1i/GUXdpNJ7MtMMKaJRq5HuRmXUxHNT2WtUcMwe5raCxxaXfX+FtY9Ks58uS2VZLN2Y9JcjpSwo3W3XJhnuo2zSptKjSr3oCVrbtDILJLV+oVCnYdW4AeZuzlNuE6vvVrOLsZmRJQpqPIUZGnl73qWxkfQ0Wt+psar09qpWNY/l+c5XTv5C9EgSHaWNWxG24u7ajc8qU453kokErdCVbeCdjEf9oXBJmkmkOrdhPnVUGjyiloMWjPJkqQuC2SkwnG1ckEnukpkPOEvkXQ1bpLbc5LyHDNQLHVyNnmnTmGS8dlYkxTVsyznSFHGSp9T6322WmTS8hafJ9i75G/d+PUB2mJdp6szKfgkCLSzINnkUyygzIVgS0KrHIBOplJU4htbK1JdbJPHvEmaVkot/Ac667UWDQNP8ty+ukWN3VY7CcmuSIdTM8nlkkzSRR5Btd08Rq2I1tqUlJHyUZJIzGFReybMgxq+pbyEnoMfFb+tdt3SMpr1vbPNOSJxtkXEiLi4ZFz3LmSS6FuOwutKtSMr7OkvAJ8bEauzix62JAKBNkuQ5TMZ5pTqHuTCVMpdQ0bfFKXOJLPqoBzrnWjKMkybS2jxCNFopeURZ9jZpyilmG9CYiEylxBMLXGcJRuvJQlay2MvSJJkZb9llPaowmjwDL8qrVWeQRsdjKeUmFUyyamL5m0hDD5s926SnS4Gts1JT1NRkRGYw+kys7ftizYNpKpoOX1OAMR2KhE81oXJlSnHnyZNSEOONoTFj8lk2RkSiM0luRDpy7N2oCsEy+tjOY5StWdpUWULD41nLkU7KosxMmWSXlskthMo0kRtttGhHHciUa1GAmGV2gcRqmcdbtF20G2voj8yHT+0NguctDCkJf8A5uUfvi4m4n3yEmpO6iI0kZlJAitOHX8fU2VqJcIgNri4c3VsQq83pq2pZvLfl8Uk2hTjZ8IyUcSJa+B7pSexH3cGXqDZ6Mx5DkOmrdS5NOlSorziyr41gpvqSjInFcELPqRct9ttz33AYvjfaEi5R2ish03hw+VfT1S5KrbY+L0xpxkpLCD8Fd0iTG5bdSUs0/2TCL2utKJlb7YN5O6mvVWnbtS3ama2y/EJTaVuMrUyRO8FOtkskGo0cvSJOx7Rqx2RMtwV7FpOJZ3Iu5NXVXsOQWSGwyk5E9jmbyFRohOKNUxDTizeWsySRmkzMtlf1qvoZW4/p/FTlV9VUuDY9ppLwtqW+pw1MS5fkrBPEgkdS2jtJTsfI1K24+ACd8nz2Iife4zUXUKDl0CpK3V5dBekx4jClrQh14kKbIyM23Nkd6lRkgzLoW4hrCNddRsiidnqZMTjbRahsOSLSA3WyEuMtJiOy++YcOSZILgTCOK0r9Jwz5eBCPHsjsNO+yHnuc55Mi1OqGpdc8mJAku9y8pZxvJoEVpC9lKUlvi6aNiUSnXNyLqMzgZBjcDtAY3UVlgzdV2lGCy48mPUqKS6zNeejR245oRuffG3FcIm/fbrLp1AT3pln7Oo2Py56GCiyINpPp5bBL5kh+JKcjrMj2LdKjb5F95Rb9dxUR7Lf9tQj5Ei/wCaxav2c9PrLTjSuDCveBZHYypd1bkhRKSiZLkLkOoIy6GSDc4bl48N/WKqPZb/ALahHyJF/wA1gNKAAAHc4V/XKh/H4/8AqJHpTov+CV34u3+qQ81mFf1yofx+P/qJHpTov+CV34u3+qQDnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApc9lv8AtqEfIkX/ADWLoxS57Lf9tQj5Ei/5rAaUAAAOxxue1VZFVzX+XcxpTTy+JbnxSsjPb/sQtvgey9aWQoMaOdDerNltLfLgkt9iItxT+AC4fzwelnwfvfyUh54PSz4P3v5KRTwAC4fzwelnwfvfyUh54PSz4P3v5KRTwAC4fzwelnwfvfyUh54PSz4P3v5KRTwAC4fzwelnwfvfyUh54PSz4P3v5KRTwAC4fzwelnwfvfyUh54PSz4P3v5KRTwAC4fzwelnwfvfyUh54PSz4P3v5KRTwAC4fzwelnwfvfyUh54PSz4P3v5KRTwAC4fzwelnwfvfyUjuLv2VnTnHq+plzcfuWys2DksNFxNwm99kqUXqJXiX3RUFp9ix5lmFbVGZpYdc5SF77cGklyWe/q9Ej/77D6akZUWYZhOntESISVExEbItiQwj0UEReroW+33TMBbD54PSz4P3v5KQ88HpZ8H738lIp4ABcP54PSz4P3v5KQ88HpZ8H738lIp4ABcP54PSz4P3v5KQ88HpZ8H738lIp4ABclU+y5aX3FpEgNUdy07JdSyhb3FKCUo9i3P1FufiP6uvZa9NsftpdbNxu9alxXVNOJ4pMtyP1H6y9ZGKayM0mRkexl4GQkjU0iyzGsfzVsiORKR7XWRl/eWi9FR/fWjY/wABEAs/88HpZ8H738lIeeD0s+D97+SkU8AAuH88HpZ8H738lIeeD0s+D97+SkU8AAuH88HpZ8H738lIeeD0s+D97+SkU8AAuH88HpZ8H738lIeeD0s+D97+SkU8AAuH88HpZ8H738lIeeD0s+D97+SkU8AAuH88HpZ8H738lIeeD0s+D97+SkU8AAuH88HpZ8H738lIeeD0s+D97+SkU8AAuH88HpZ8H738lIr/AO3N2gaDtKays5djseXFhe1rMVbMxJEtK0Grfw8S2Mj/AO414AAAAAAAAAAAAAAAAAAAAAAAByK6A/a2EaFFR3smS6llpG5FyWoyJJbn0LqZeIDjgNrfNadpv4t0fp6t/wBwHmtO038W6P09W/7gBqkA2t81p2m/i3R+nq3/AHAea07Tfxbo/T1b/uAEMYcr6k9MckyEvRm2SypYavWlKi5vKL/ykRb+oxHI3gzP2NbtGSsTxKjq9PkvMwIq35R+3den+cuq3Wk95Bb8SIi3LcuvQxHWTexr9ovD8btr630/TFqqqI7OmP8At3Xr7tlpBrcVxTINR7JSZ7ERme3QgGsgAAAAAAAAAAkbStX1R02S4e56Zz4pzIRespTJciIv8SdyP7xCORtxpP7Hn2jvL8WzGq0/KRVSCYnsPFd16DdjOJJW/FUglFybV4GW5b9SAajgNxcx9i27RS8qtV1GnqH6xyStcdZXdcj0DPci2OQRltvt1L1Dp/Nadpv4t0fp6t/3ADVIBtb5rTtN/Fuj9PVv+4GHatdhLW/Q3B5mX5thaabHoi223phW0J/ipxZIQXBp5Sj3Uoi6F+EBAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7/AE+/r7jXynG/1UjoB3+n39fca+U43+qkBfdR9sqa/gGWah32CJx/T3GpVjBlWrl0lyTJfjSlR20x2O5SSkurJCeS3G+K1KL0iTzPqMT7fNbc2dnV2FRjx2iKGwva9rGszh3jb3kjXeuR5CmE7xnDT1I+K0HsvZRmnY8hh9lOdc9ljKtJ763jwp1va2VlHsq3k8iMt20cnRFmS0oNRoUbXJPQjMlER7bGP29q9VYujupKtQ4eBxozOJWLTTmKlJU/If8AJ17urN1CCaQaSP62XM9z9/sXUORg/akyCysNNl5lp2nE6DUJptNJbRLxFgSZLkY5LceS33LZtmttC+KkmsjNOx8d+kWY9qrk0LseafXU9+7vF2Gae11jbsZG5CsGG1ZA6yzs4pp03m+jbamjNO7W6SURbDu9DdKdSdTsY0Css1l4vBwXDq2Bd1kOkXIdm2Ekq/uYypHeIShkm0PLUaUGvkr1kXh28PsvZvD0I/k0VaUEiPV5pGvKicS321uV6bZNg4iQngoifLdxCSRuk9kbmnczAcTU32QXHsEyzLa+DAobSsxOQuHbLnZhCrbJ15tJKfRCgu+nING5p9JTfNaVJRy23HXa1dqGdqNiuseIYhh7VtSVeIOvz7mVdNxJKWJlYp9uQzDU2anWkocSRq5p9LciI9hl9XojqhpfnGaHgbuD2uI5VePZCs8pbklNq5Mg0nKS2lpJpfbUpJrSSltmk1GRmZDAO3boXnOpeO5PeNxsKqqHG65+yhZFH8pRkDcVmGtUiCfFJNqbeV3iT+uEkkL6oUZbmFFgAAAAAAAAAAvNwHtgZBhWhkmXA0z9usc03pqhi6sjvm47rjK6yJINcdk2T5rQl4+SFKQWyUmlajUaU0ZC9PTXs0ZPk3ZP1Jp4s+obk6lUNW7ULeedJDBFSw4384MmzNJ82VH6BL9Ey9e5EEpR+1e7i91kUDUrEDwhFZirmZMPxrRFiT8Btwm3UqJLaOD6VLbLu080may2WYxbTXt2w9QM4pMXOmxxFjkjElVI3T5rCtXO/aYU+lmc2wk1RTUlCi5J71JKLbcz23yXV3suydYc6mP2dhGi41P07n4dIUypRy2pL8qM8h5CDTxNCSYM+qiPfiW2xmZZDovjWrlDNgw89Rgb9VXwTjJsqBEny+c8XFKHlpcQlDO6SWakpNzdSi2MiLYwwLsxa2aq5X2bZWZZRjFbd2TPlTsF9F+2yqxNM2QhxL3KO21FQ0lBESuS+SUb7JPoeuPbR7TkbXvsc6t0r1bW1l7jU+lVKTSXzF1BeakSiNtbUppKSMyNpxKkGkjSZF47ic/csalnoTdaRu2GJScbhWftlRynXJXOxbKz8t8ksWSb4paUk1NKNtS9y2PifUjgDt56PZzh2herub5M3iUKHkcPH4PtVjRv8YDkScrghJrbSTqVIfUZubNmRkSSQZFyAVKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADv9Pi3z3GvlON/qpHQDv9Pv6+418pxv8AVSA9OFY/j107Par3Kye7XyDhzERjbcVGfJKVm04Sd+CyStCuJ7HstJ7bGQUr2PZJXN2FQustYDiloRKhG280pSFmhZEpO5GaVJUk+vQ0mR9SGqvZq7QWmknS3OJLubUz+TXlrkmSy6SHbJRYNxyefUjYkLJxBpiMtHyLY0kW5GW24wvF7WViMbs849NzKxuJz1PVtWuG1WQSoNs3NmupeXZqJtW8xlHJwnUPHxSglL3Mz2MN1rK0xipi3D8p2ubRTxzlWCUpStcVrga+S0JI1ERpSoy6dSI9txwNPMtxbVLF42RY7GedqZPVh6fTyIC3U7EZLS3IabWaDIyMlknifqMxpbkk6h/k07WNzXXU1zUC3vJ+NPVT91KdOIzJdYrIhqiLdNCeZka2nOG5IXwQokESSlLWa9i4trdpni9flMubXxkQahWDUV5IrbJhTjyUt2XdsGXlbCG0GTrbuyEIJS99z2MNnGCpZ82ZGZKBIlxFJTJZRwU4yakkpJLIuqTNJkZb+JGRiIe2HlGNaf8AZyz163YcjpsqWdWxXYlW9JSmQ7GcQ0TimW1Eyk1GlPeOcUEZkRqLchr7WW9ZE0m7RORYxk9pD1Lu8rm0T0ZF9MXIqlSrFNZAWcZTxpZdNDTa23CSS0oIkoUSEkRZN7IJRlgPZBs8YrbK2spGQW0VDsq5sn5r7vcp8seMlOKPgk24Cz7tskoLdWyS3MBRKAAAsn9h9xHT3IajVuZqBS4zZRY0mkjxZGSxI7qGnH1Sm0toU8RklTi+7SSS6qVxLqewsrn6D6H1UyviTdO9P4cuwdUxDYfpIKHJLhINZobSaN1qJKVKMk7nskz8CFPXseuc47jL6q3J7yvx+nmZxj9jLm2khDEdDUGPZy08lqMi6vtxkl99RCzjPtRMaz3WfT3I8ezZg8Zp8UyLIH72FPVIrWyQbENp02krNp1SFvSepkavrSk7+JAJRs+z9orSV8ifY6bYFAgx0G49JlUUJtptJeKlKU2REX3zGMZLgvZ7xPN6HELDTXFlZHdtqehQoWFFL+tJcQ2p11bMZaWWyW62RuOmhJcvHxGtE+/rsg7OK6vLcmtLCndzqkpLvOCy2dKp7GOlbT8iZHfWtJMMuJNbK20/Wm3TIkmZoSoporcgq8X1q1Xy+JJemUWnmnVfFjyJk12Yt0nPK57qlPuqUtwzbbimalKMz6HuAzjGNPuzZm1tNq8dxrSu+s4RqTKhVkCtkvMGk9lEtCEmadj6HuRdRKOOM4vPre7oUVEmBBcXA4VxNKajraPu1s7I6JNBp4mjoaTLbYthpJo+jF84xzs11WELjXV9h5NXmV5fWo3YrmTgveWRnJaSIlOPvvce5Soz2QpSiIkkY/nTTLItThuj1Pnua3eE4Jf49YZYqyO7lQ5NvOlTSeYiOWBL781NsSORIJwluGadzUSTIBvQoqZVmmtV5Adh3PfpiHw73uiVx5kjx47mRb7bbnsMX071EwrVZNsvGEOT49ZKXDflPU0iLHW6hxxpZMuvNIQ+SVtLSamjWRGXU+pbwHRzcPxrtS6x31teWSchw7H69uvrJeQTCW/AYgLffkGwbvB9o1SCSZqSpJOtqX0cUpSo8ubd7S3suaFQ3cqfj2RVCbmywusuZFTbZCuUgnFphvx/rinm3n1KJkvRdM9lGRFuA3mNFIVmVdxge2BsnIKJsjvTa5cefDx47mRb7bb9B8MgwTGssrHK27x6qua5w0qXEsITT7KjI9yM0LSZHsZEZdBqjYZDi2IdoTXvL7G7sGMrwvFYi6yrk3spJvRGK1yQ6/5N3vdvNGuQlJ8kqQl1tSiInFKUqXtCYsHSzH8DxfJcqv7vUHI6Jp95y+sJk05TkVlByFI5mppk0m+W5FxUstjVzNJqAdrfaD6JYvR2FzbabYLAq6+O5LlSnsehkhlpCTUtaj7vwJJGf/Yfat7PejNvXRZ8PTDCH4kppD7LqcdibLQoiUlRfW/WRkYjLtTXM7VDKqrR+nxq4y6m4t3GaxqF6I08iDurySKpUl9lBd+83upJL5d0ystjJe5Rxonk0zVTFdDces8hvaCpoMAs5GTIqLV6Ct92JIjV7aXHGFkojJceWvklRHugyI9jURhs77mrSH4q8J//AMdh/wAMYTb4f2d6LUOJg83TTGWclmQ3p0aMWDc2pDLSeTptvpim0tSSNO6ErNW6kltuoiPW7GtXdRsZxLEaZeRXNhlmq2AU8fGXLGQ48cawXKfS9JIzPYltQ5bDzivFXkxGrcxsRVVzTXa2qq9ybJnwcC04Js5lg+p97vZstKe8dcUZmpw26wzUoz3PkZn4gKevZFLXBLrtHSpOnNZGqMcKuZYOJGpnKnu5Da3G30qjONNqQsloUk+SCPdI1jE1dqwn5Wa0NxKJXlOQ0/1RuGv3x+XzJUwjP/yvpEKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA51DaqoryuskNk6uHJbkE2o9iUaFErbf7+w4IALNfPg5T8VdR+lnf4YefByn4q6j9LO/wxWUADfzWP2Wi71nxOPQzsETRNx7KJatTKe3STyX4zyXmej0Z1Ckk4hCjSpBkfEvUMyg+zc5XEhR2HNNK2Y402lCpD9qvvHTItjWri0lO5+J7ERbn0IvAVogAtIxn2bO6s7+DDstNqqDCfdJtySi0cPut+hKMjb8CPbf724iHtLeyHZJqHmMqDkeKOxU1USdCh1TFo37XoekwpETy00nF75a+6lKNJG8SS2T6JHvvoqJMvC/lI07YvEFzv8fQmJYEXvn4v/wAN775p6kZ/hM/UAjMAABs72Lu3La9jRrL0VuKQ8mLIlRFOHKlrY7nuO+224pPffvj/ACRsx58HKfirqP0s7/DFZQALNfPg5T8VdR+lnf4Yj/D/AGWC+wvU7NM0iYYuS7lbjT86olW7aobbrbLTKHGuMUniMm2Up2U6pPpKPbc9y0KABZr58HKfirqP0s7/AAxlGQ+zIZJjeKUc+VppVFaWpKkIhe2bhE3H8ErUfDfdR9S+9uKztM8RayzIi8uX3NLBbOZYPn0JDKOplv8AdV4fd6mfqHCzvLHc1yiZaLR3LKzJuOwXQmWU9EIIvDoXjt6zMBvlqR7MRe6naf5JiFjptDhV99Xv1kmRAuFofQ08g21mhSmVJJXFR9TSf4B98H9mZyrCcSq6JWBRr0oDJMJn2VoRSHEkZ8SUTMdtv0S2SXFCeiS33PczrnABZr58HKfirqP0s7/DHWuezP272Qs3jmkVM5asRlRGZC7h9RtNKUSlpQRo2TyNKORkRGrggjMySW1bgALNfPg5T8VdR+lnf4YefByn4q6j9LO/wxWUADfp72WK1nasRs/sdPk2ljAYWxV10q9WcGrNxCW3XGGksEfeLSkyNa1LMiUok8SMyGKOeyV5G59Xsj2tuUXGZlHZsLdNvDKSzGZS6luMyXtf3aWyS+4W5oUvrvz36jTAAEk686xlrZlNPaNUjePxKmjg0MWE3IN/ZmK13bajXxTuZpIt9iIhGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIsCy93CsjZnk35REWRsS4quqX2FdFoMvwdS++RDHQAZbqRhzeKXLbsBflNFYo8qrpJdSW0fXiZ/8yd9jLx8D9YxISdplKaziofwCyM93zXJqJOxqONIJJqUk/8AwKIj3+519Z7l9820PewTTaNdT31qulykJfjtqI2WWlJPZO+26lkok7mR7dTIt9tzCKgHa4pilvnGR19BQV79rc2DxMRYcZPJbqz9RfcLxMzPoREZmZERiRe0L2X857M97CrsvgoJuYyl2POiKNcdwzLdSCVsXpJPcjL734QESj+mmlvuoabQpxxaiSlCS3NRn4ERDItOMTRm+a1dK66thmS4feuNkXIkJSa1bb9CMySZEZ77GfgfgJTY0se0RK0yu2Nm48gIk1SWEKNJvLUaUOOkZehx6HtuZbqIiVvtuGK5s4jTvD4+FxlJ9tpnCZduoPfie27cff7iS6n9/wDCYjIfefOkWk1+ZKdU/JfWpx11Z9VKM9zM/wDuPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlLRfWOPpr5TCm1iJEOW6TjktgiKQjYttj39+kupkW5bGpR9d9hPeTtt666ezqnDD9v7OYtlEaJG/pTd7xJkk0nsaTPY/fbFtufgNR8VxW3zjI6+goK9+1uLB4mIsOMnkt1Z+ovuF4mZn0IiMzMiIXa9hrsN1HZhxxN1dJYtdRLBkilziLkiEg+vcMb+r/AJleKjL1EREQOw12Gqjsw44m6uksWuolgyRS5xFyRCQfU2GDPwL/AJleKjL1EREU661aK4xr1gc7FMqgplQpCT7t0i+uR3PU4g/UZHsM7ABSRL7JmTdmbtBSIF42qRSNw35NbcpTs1Ib3SnYz8CWRLPcvvH9/bptSu0Pj9PGlVlWy1kUlxCmnCUXKIRGRkZKP+2X3i6GXrIXLaz6MYxrvgk/FcphJlQpKD7t0i+uR17dFoV4kZCintT9ljKOy7njtRbtLl0shRqrbdCfrclv1EZ+pZF4l/8AzsEMyZCpUh19ZIStxZrUTbaW0kZnv0SkiJJfeIiIvUPmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADtcVxW3zjI6+goK9+1uLB4mIsOMnkt1Z+ovuF4mZn0IiMzMiIdUMhwDP77TDLa7JcasXay4guE4y+0oy/Cky9aT9ZALqew12Gqjsw44i6ukMWuolgyRS5xFyRCQfU2GDPwL/mV4qMvURERbYDWjsX9tCh7UmJJjyFNVmbwWyKfWGoi7zp/StfdSf3PV/lsuA6nL51lWYpczKeO1Lto8N52Iw8lakOPJQZoSokEazIzIi2SRmfq6iOezRk2o2T4RLc1Kp1VF1HmKbbQ8Wzzjakk6k18Wm2zJJOJQRtkfvDJXpkoS4AAME1p0WxfXnA52K5VBRLgyEn3bu31yO56nEH6jIxnYxfUzUzG9H8Js8syyzaqqSvb5uvOdTUf9lCE+KlqPoSS6mZgKF+1P2WMo7LueO1Fu0uXSyFGqtt0J+tyW/URn6lkXiX/wDO0KjYPthdsPJO1bmxyH+9qcPgLUmpoyX0bT/813bot1ReJ+CS6J9Znr4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyHAM/vtMMtr8lxqxdrLeC4TjL7SjL19UmXrSfrIXidjDtn0PakxFLLymqzNoLZFYVZq27z/6rX3Un/6f5UNDIdP9QL7S7Lq7JcasXay4guE40+0e2/3UqL1pP1kA9LIDWrsYds+h7UmIpZeU1WZtBbIrCrNW3ef/AFWvupP/ANP8pt1M1MxvR/CbPLMss2qqkr2+brznU1H/AGUIT4qWo+hJLqZmAamamY3o/hNnlmWWbVVSV7fN15zqaj/soQnxUtR9CSXUzMUYdsPth5J2rs28okd7VYdXuKKooyXuTZeHfO7dFPKLxPwSR8U+s1O2H2w8k7V2beUSO9qsOr3FFUUZL3JsvDvnduinlF4n4JI+KfWatfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZDp/qBfaXZdXZLjVi7WXEFwnGn2j23+6lRetJ+shKPag7X+cdqi1rHMjdbgVFayhManhKMo5PcCJx9Rf2lqPfqfvUnxL1mcGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//Z", - "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 Date: Fri, 6 Dec 2024 15:16:31 +0500 Subject: [PATCH 2/8] Small fixes --- tutorials/27_First_RAG_Pipeline.ipynb | 182 ++------------------------ 1 file changed, 9 insertions(+), 173 deletions(-) diff --git a/tutorials/27_First_RAG_Pipeline.ipynb b/tutorials/27_First_RAG_Pipeline.ipynb index 1e5b0b60..62095dcb 100644 --- a/tutorials/27_First_RAG_Pipeline.ipynb +++ b/tutorials/27_First_RAG_Pipeline.ipynb @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -63,157 +63,11 @@ "id": "UQbU8GUfO-qZ", "outputId": "c33579e9-5557-43bd-a3c5-63b8373770c7" }, - "outputs": [ - { - "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" - ] - }, - { - "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" - ] - }, - { - "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" - ] - }, - { - "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" - ] - }, - { - "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" - ] - }, - { - "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" - ] - } - ], + "outputs": [], "source": [ "%%bash\n", "\n", - "pip install haystack-ai==2.8.0\n", + "pip install haystack-ai\n", "pip install \"datasets>=2.6.1\"\n", "pip install \"sentence-transformers>=3.0.0\"" ] @@ -231,20 +85,11 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "id": "A76B4S49O-qa" }, - "outputs": [ - { - "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" - ] - } - ], + "outputs": [], "source": [ "from haystack.telemetry import tutorial_running\n", "\n", @@ -347,7 +192,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -355,16 +200,7 @@ "id": "EUmAH9sEn3R7", "outputId": "ee54b59b-4d4a-45eb-c1a9-0b7b248f1dd4" }, - "outputs": [ - { - "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" - ] - } - ], + "outputs": [], "source": [ "from haystack.components.embedders import SentenceTransformersDocumentEmbedder\n", "\n", @@ -588,7 +424,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -611,7 +447,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, "outputs": [ { From 9e978778b7d6477f250d64f16fdd85ce5b3cba94 Mon Sep 17 00:00:00 2001 From: Amna Mubashar Date: Sun, 8 Dec 2024 20:50:33 +0100 Subject: [PATCH 3/8] Update tutorial 28 --- .../28_Structured_Output_With_Loop.ipynb | 1009 +++++++++-------- tutorials/auto-correct-pipeline.png | Bin 0 -> 86236 bytes 2 files changed, 529 insertions(+), 480 deletions(-) create mode 100644 tutorials/auto-correct-pipeline.png diff --git a/tutorials/28_Structured_Output_With_Loop.ipynb b/tutorials/28_Structured_Output_With_Loop.ipynb index 331c6978..8e1d3ded 100644 --- a/tutorials/28_Structured_Output_With_Loop.ipynb +++ b/tutorials/28_Structured_Output_With_Loop.ipynb @@ -1,492 +1,541 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "AVBtOVlNJ51C" - }, - "source": [ - "# Tutorial: Generating Structured Output with Loop-Based Auto-Correction\n", - "\n", - "- **Level**: Intermediate\n", - "- **Time to complete**: 15 minutes\n", - "- **Prerequisites**: You must have an API key from an active OpenAI account as this tutorial is using the gpt-4o-mini model by OpenAI.\n", - "- **Components Used**: `PromptBuilder`, `OpenAIGenerator`, `OutputValidator` (Custom component)\n", - "- **Goal**: After completing this tutorial, you will have built a system that extracts unstructured data, puts it in a JSON schema, and automatically corrects errors in the JSON output from a large language model (LLM) to make sure it follows the specified structure.\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)..\n", - "\n", - "## Overview\n", - "This tutorial demonstrates how to use Haystack 2.0's advanced [looping pipelines](https://docs.haystack.deepset.ai/docs/pipelines#loops) with LLMs for more dynamic and flexible data processing. You'll learn how to extract structured data from unstructured data using an LLM, and to validate the generated output against a predefined schema.\n", - "\n", - "This tutorial uses `gpt-4o-mini` to change unstructured passages into JSON outputs that follow the [Pydantic](https://github.com/pydantic/pydantic) schema. It uses a custom OutputValidator component to validate the JSON and loop back to make corrections, if necessary." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "jmiAHh1oGsKI" - }, - "source": [ - "## Preparing the Colab Environment\n", - "\n", - "Enable the debug mode of logging:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Vor9IHuNRvEh" - }, - "outputs": [], - "source": [ - "import logging\n", - "\n", - "logging.basicConfig()\n", - "logging.getLogger(\"canals.pipeline.pipeline\").setLevel(logging.DEBUG)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ljbWiyJkKiPw" - }, - "source": [ - "## Installing Dependencies\n", - "Install Haystack and [colorama](https://pypi.org/project/colorama/) with pip:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "kcc1AlLQd_jI", - "outputId": "efc4bbab-a9fe-46ee-d8af-9d86edacaf04" - }, - "outputs": [], - "source": [ - "%%bash\n", - "\n", - "pip install haystack-ai\n", - "pip install colorama" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "nTA5fdvCLMKD" - }, - "source": [ - "### Enabling Telemetry\n", - "\n", - "Enable telemetry to let us know you're using this tutorial. (You can always opt out by commenting out this line). For details, see [Telemetry](https://docs.haystack.deepset.ai/docs/telemetry)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Apay3QSQLKdM" - }, - "outputs": [], - "source": [ - "from haystack.telemetry import tutorial_running\n", - "\n", - "tutorial_running(28)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Cmjfa8CiCeFl" - }, - "source": [ - "## Defining a Schema to Parse the JSON Object\n", - "\n", - "Define a simple JSON schema for the data you want to extract from a text passsage using the LLM. As the first step, define two [Pydantic models](https://docs.pydantic.dev/1.10/usage/models/), `City` and `CitiesData`, with suitable fields and types." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "xwKrDOOGdaAz" - }, - "outputs": [], - "source": [ - "from typing import List\n", - "from pydantic import BaseModel\n", - "\n", - "\n", - "class City(BaseModel):\n", - " name: str\n", - " country: str\n", - " population: int\n", - "\n", - "\n", - "class CitiesData(BaseModel):\n", - " cities: List[City]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "zv-6-l_PCeFl" - }, - "source": [ - "> You can change these models according to the format you wish to extract from the text." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ouk1mAOUCeFl" - }, - "source": [ - "Then, generate a JSON schema from Pydantic models using `schema_json()`. You will later on use this schema in the prompt to instruct the LLM.\n", - "\n", - "To learn more about the JSON schemas, visit [Pydantic Schema](https://docs.pydantic.dev/1.10/usage/schema/). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "8Lg9_72jCeFl" - }, - "outputs": [], - "source": [ - "json_schema = CitiesData.schema_json(indent=2)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "KvNhg0bP7kfg" - }, - "source": [ - "## Creating a Custom Component: OutputValidator\n", - "\n", - "`OutputValidator` is a custom component that validates if the JSON object the LLM generates complies with the provided [Pydantic model](https://docs.pydantic.dev/1.10/usage/models/). If it doesn't, OutputValidator returns an error message along with the incorrect JSON object to get it fixed in the next loop.\n", - "\n", - "For more details about custom components, see [Creating Custom Components](https://docs.haystack.deepset.ai/docs/custom-components)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "yr6D8RN2d7Vy" - }, - "outputs": [], - "source": [ - "import json\n", - "import random\n", - "import pydantic\n", - "from pydantic import ValidationError\n", - "from typing import Optional, List\n", - "from colorama import Fore\n", - "from haystack import component\n", - "\n", - "# Define the component input parameters\n", - "@component\n", - "class OutputValidator:\n", - " def __init__(self, pydantic_model: pydantic.BaseModel):\n", - " self.pydantic_model = pydantic_model\n", - " self.iteration_counter = 0\n", - "\n", - " # Define the component output\n", - " @component.output_types(valid_replies=List[str], invalid_replies=Optional[List[str]], error_message=Optional[str])\n", - " def run(self, replies: List[str]):\n", - "\n", - " self.iteration_counter += 1\n", - "\n", - " ## Try to parse the LLM's reply ##\n", - " # If the LLM's reply is a valid object, return `\"valid_replies\"`\n", - " try:\n", - " output_dict = json.loads(replies[0])\n", - " self.pydantic_model.parse_obj(output_dict)\n", - " print(\n", - " Fore.GREEN\n", - " + f\"OutputValidator at Iteration {self.iteration_counter}: Valid JSON from LLM - No need for looping: {replies[0]}\"\n", - " )\n", - " return {\"valid_replies\": replies}\n", - "\n", - " # If the LLM's reply is corrupted or not valid, return \"invalid_replies\" and the \"error_message\" for LLM to try again\n", - " except (ValueError, ValidationError) as e:\n", - " print(\n", - " Fore.RED\n", - " + f\"OutputValidator at Iteration {self.iteration_counter}: Invalid JSON from LLM - Let's try again.\\n\"\n", - " f\"Output from LLM:\\n {replies[0]} \\n\"\n", - " f\"Error from OutputValidator: {e}\"\n", - " )\n", - " return {\"invalid_replies\": replies, \"error_message\": str(e)}" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "vQ_TfSBkCeFm" - }, - "source": [ - "Then, create an OutputValidator instance with `CitiesData` that you have created before." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "bhPCLCBCCeFm" - }, - "outputs": [], - "source": [ - "output_validator = OutputValidator(pydantic_model=CitiesData)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "xcIWKjW4k42r" - }, - "source": [ - "## Creating the Prompt\n", - "\n", - "Write instructions for the LLM for converting a passage into a JSON format. Ensure the instructions explain how to identify and correct errors if the JSON doesn't match the required schema. Once you create the prompt, initialize PromptBuilder to use it. \n", - "\n", - "For information about Jinja2 template and PromptBuilder, see [PromptBuilder](https://docs.haystack.deepset.ai/docs/promptbuilder)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "ohPpNALjdVKt" - }, - "outputs": [], - "source": [ - "from haystack.components.builders import PromptBuilder\n", - "\n", - "prompt_template = \"\"\"\n", - "Create a JSON object from the information present in this passage: {{passage}}.\n", - "Only use information that is present in the passage. Follow this JSON schema, but only return the actual instances without any additional schema definition:\n", - "{{schema}}\n", - "Make sure your response is a dict and not a list.\n", - "{% if invalid_replies and error_message %}\n", - " You already created the following output in a previous attempt: {{invalid_replies}}\n", - " However, this doesn't comply with the format requirements from above and triggered this Python exception: {{error_message}}\n", - " Correct the output and try again. Just return the corrected output without any extra explanations.\n", - "{% endif %}\n", - "\"\"\"\n", - "prompt_builder = PromptBuilder(template=prompt_template)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "KM9-Zq2FL7Nn" - }, - "source": [ - "## Initalizing the Generator\n", - "\n", - "[OpenAIGenerator](https://docs.haystack.deepset.ai/docs/openaigenerator) generates\n", - "text using OpenAI's `gpt-4o-mini` model by default. Set the `OPENAI_API_KEY` variable and provide a model name to the Generator." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Z4cQteIgunUR" - }, - "outputs": [], - "source": [ - "import os\n", - "from getpass import getpass\n", - "\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()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "zbotIOgXHkC5" - }, - "source": [ - "## Building the Pipeline\n", - "\n", - "Add all components to your pipeline and connect them. Add connections from `output_validator` back to the `prompt_builder` for cases where the produced JSON doesn't comply with the JSON schema. Set `max_runs_per_component` to avoid infinite looping." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "eFglN9YEv-1W" - }, - "outputs": [], - "source": [ - "from haystack import Pipeline\n", - "\n", - "pipeline = Pipeline(max_runs_per_component=5)\n", - "\n", - "# Add components to your pipeline\n", - "pipeline.add_component(instance=prompt_builder, name=\"prompt_builder\")\n", - "pipeline.add_component(instance=generator, name=\"llm\")\n", - "pipeline.add_component(instance=output_validator, name=\"output_validator\")\n", - "\n", - "# Now, connect the components to each other\n", - "pipeline.connect(\"prompt_builder\", \"llm\")\n", - "pipeline.connect(\"llm\", \"output_validator\")\n", - "# If a component has more than one output or input, explicitly specify the connections:\n", - "pipeline.connect(\"output_validator.invalid_replies\", \"prompt_builder.invalid_replies\")\n", - "pipeline.connect(\"output_validator.error_message\", \"prompt_builder.error_message\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-UKW5wtIIT7w" - }, - "source": [ - "### Visualize the Pipeline\n", - "\n", - "Draw the pipeline with the [`draw()`](https://docs.haystack.deepset.ai/docs/drawing-pipeline-graphs) method to confirm the connections are correct. You can find the diagram in the Files section of this Colab." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "RZJg6YHId300" - }, - "outputs": [], - "source": [ - "pipeline.draw(\"auto-correct-pipeline.png\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "kV_kexTjImpo" - }, - "source": [ - "## Testing the Pipeline\n", - "\n", - "Run the pipeline with an example passage that you want to convert into a JSON format and the `json_schema` you have created for `CitiesData`. For the given example passage, the generated JSON object should be like:\n", - "```json\n", - "{\n", - " \"cities\": [\n", - " {\n", - " \"name\": \"Berlin\",\n", - " \"country\": \"Germany\",\n", - " \"population\": 3850809\n", - " },\n", - " {\n", - " \"name\": \"Paris\",\n", - " \"country\": \"France\",\n", - " \"population\": 2161000\n", - " },\n", - " {\n", - " \"name\": \"Lisbon\",\n", - " \"country\": \"Portugal\",\n", - " \"population\": 504718\n", - " }\n", - " ]\n", - "}\n", - "```\n", - "The output of the LLM should be compliant with the `json_schema`. If the LLM doesn't generate the correct JSON object, it will loop back and try again." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "yIoMedb6eKia", - "outputId": "4a9ef924-cf26-4908-d83f-b0bc0dc03b54" - }, - "outputs": [], - "source": [ - "passage = \"Berlin is the capital of Germany. It has a population of 3,850,809. Paris, France's capital, has 2.161 million residents. Lisbon is the capital and the largest city of Portugal with the population of 504,718.\"\n", - "result = pipeline.run({\"prompt_builder\": {\"passage\": passage, \"schema\": json_schema}})" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "WWxmPgADS_Fa" - }, - "source": [ - "> If you encounter `PipelineMaxLoops: Maximum loops count (5) exceeded for component 'prompt_builder'.` error, consider increasing the maximum loop count or simply rerun the pipeline." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "eWPawSjgSJAM" - }, - "source": [ - "### Print the Correct JSON\n", - "If you didn't get any error, you can now print the corrected JSON." - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "AVBtOVlNJ51C" + }, + "source": [ + "# Tutorial: Generating Structured Output with Loop-Based Auto-Correction\n", + "\n", + "- **Level**: Intermediate\n", + "- **Time to complete**: 15 minutes\n", + "- **Prerequisites**: You must have an API key from an active OpenAI account as this tutorial is using the gpt-4o-mini model by OpenAI.\n", + "- **Components Used**: `PromptBuilder`, `OpenAIChatGenerator`, `OutputValidator` (Custom component)\n", + "- **Goal**: After completing this tutorial, you will have built a system that extracts unstructured data, puts it in a JSON schema, and automatically corrects errors in the JSON output from a large language model (LLM) to make sure it follows the specified structure.\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)..\n", + "\n", + "## Overview\n", + "This tutorial demonstrates how to use Haystack 2.0's advanced [looping pipelines](https://docs.haystack.deepset.ai/docs/pipelines#loops) with LLMs for more dynamic and flexible data processing. You'll learn how to extract structured data from unstructured data using an LLM, and to validate the generated output against a predefined schema.\n", + "\n", + "This tutorial uses `gpt-4o-mini` to change unstructured passages into JSON outputs that follow the [Pydantic](https://github.com/pydantic/pydantic) schema. It uses a custom OutputValidator component to validate the JSON and loop back to make corrections, if necessary." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jmiAHh1oGsKI" + }, + "source": [ + "## Preparing the Colab Environment\n", + "\n", + "Enable the debug mode of logging:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "Vor9IHuNRvEh" + }, + "outputs": [], + "source": [ + "import logging\n", + "\n", + "logging.basicConfig()\n", + "logging.getLogger(\"canals.pipeline.pipeline\").setLevel(logging.DEBUG)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ljbWiyJkKiPw" + }, + "source": [ + "## Installing Dependencies\n", + "Install Haystack and [colorama](https://pypi.org/project/colorama/) with pip:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, + "id": "kcc1AlLQd_jI", + "outputId": "efc4bbab-a9fe-46ee-d8af-9d86edacaf04" + }, + "outputs": [], + "source": [ + "%%bash\n", + "\n", + "pip install haystack-ai==2.8.0\n", + "pip install colorama" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nTA5fdvCLMKD" + }, + "source": [ + "### Enabling Telemetry\n", + "\n", + "Enable telemetry to let us know you're using this tutorial. (You can always opt out by commenting out this line). For details, see [Telemetry](https://docs.haystack.deepset.ai/docs/telemetry)." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "Apay3QSQLKdM" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "BVO47gXQQnDC", - "outputId": "460a10d4-a69a-49cd-bbb2-fc4980907299" - }, - "outputs": [], - "source": [ - "valid_reply = result[\"output_validator\"][\"valid_replies\"][0]\n", - "valid_json = json.loads(valid_reply)\n", - "print(valid_json)" - ] - }, + "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(28)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Cmjfa8CiCeFl" + }, + "source": [ + "## Defining a Schema to Parse the JSON Object\n", + "\n", + "Define a simple JSON schema for the data you want to extract from a text passsage using the LLM. As the first step, define two [Pydantic models](https://docs.pydantic.dev/1.10/usage/models/), `City` and `CitiesData`, with suitable fields and types." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "xwKrDOOGdaAz" + }, + "outputs": [], + "source": [ + "from typing import List\n", + "from pydantic import BaseModel\n", + "\n", + "\n", + "class City(BaseModel):\n", + " name: str\n", + " country: str\n", + " population: int\n", + "\n", + "\n", + "class CitiesData(BaseModel):\n", + " cities: List[City]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zv-6-l_PCeFl" + }, + "source": [ + "> You can change these models according to the format you wish to extract from the text." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ouk1mAOUCeFl" + }, + "source": [ + "Then, generate a JSON schema from Pydantic models using `schema_json()`. You will later on use this schema in the prompt to instruct the LLM.\n", + "\n", + "To learn more about the JSON schemas, visit [Pydantic Schema](https://docs.pydantic.dev/1.10/usage/schema/). " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "8Lg9_72jCeFl" + }, + "outputs": [], + "source": [ + "json_schema = CitiesData.schema_json(indent=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KvNhg0bP7kfg" + }, + "source": [ + "## Creating a Custom Component: OutputValidator\n", + "\n", + "`OutputValidator` is a custom component that validates if the JSON object the LLM generates complies with the provided [Pydantic model](https://docs.pydantic.dev/1.10/usage/models/). If it doesn't, OutputValidator returns an error message along with the incorrect JSON object to get it fixed in the next loop.\n", + "\n", + "For more details about custom components, see [Creating Custom Components](https://docs.haystack.deepset.ai/docs/custom-components)." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "yr6D8RN2d7Vy" + }, + "outputs": [], + "source": [ + "import json\n", + "import random\n", + "import pydantic\n", + "from pydantic import ValidationError\n", + "from typing import Optional, List\n", + "from colorama import Fore\n", + "from haystack import component\n", + "from haystack.dataclasses import ChatMessage\n", + "\n", + "\n", + "# Define the component input parameters\n", + "@component\n", + "class OutputValidator:\n", + " def __init__(self, pydantic_model: pydantic.BaseModel):\n", + " self.pydantic_model = pydantic_model\n", + " self.iteration_counter = 0\n", + "\n", + " # Define the component output\n", + " @component.output_types(valid_replies=List[str], invalid_replies=Optional[List[str]], error_message=Optional[str])\n", + " def run(self, replies: List[ChatMessage]):\n", + "\n", + " self.iteration_counter += 1\n", + "\n", + " ## Try to parse the LLM's reply ##\n", + " # If the LLM's reply is a valid object, return `\"valid_replies\"`\n", + " try:\n", + " output_dict = json.loads(replies[0].content)\n", + " self.pydantic_model.parse_obj(output_dict)\n", + " print(\n", + " Fore.GREEN\n", + " + f\"OutputValidator at Iteration {self.iteration_counter}: Valid JSON from LLM - No need for looping: {replies[0]}\"\n", + " )\n", + " return {\"valid_replies\": replies}\n", + "\n", + " # If the LLM's reply is corrupted or not valid, return \"invalid_replies\" and the \"error_message\" for LLM to try again\n", + " except (ValueError, ValidationError) as e:\n", + " print(\n", + " Fore.RED\n", + " + f\"OutputValidator at Iteration {self.iteration_counter}: Invalid JSON from LLM - Let's try again.\\n\"\n", + " f\"Output from LLM:\\n {replies[0]} \\n\"\n", + " f\"Error from OutputValidator: {e}\"\n", + " )\n", + " return {\"invalid_replies\": replies, \"error_message\": str(e)}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vQ_TfSBkCeFm" + }, + "source": [ + "Then, create an OutputValidator instance with `CitiesData` that you have created before." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "bhPCLCBCCeFm" + }, + "outputs": [], + "source": [ + "output_validator = OutputValidator(pydantic_model=CitiesData)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xcIWKjW4k42r" + }, + "source": [ + "## Creating the Prompt\n", + "\n", + "Write instructions for the LLM for converting a passage into a JSON format. Ensure the instructions explain how to identify and correct errors if the JSON doesn't match the required schema. Once you create the prompt, initialize PromptBuilder to use it. \n", + "\n", + "For information about Jinja2 template and ChatPromptBuilder, see [ChatPromptBuilder](https://docs.haystack.deepset.ai/docs/chatpromptbuilder)." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "ohPpNALjdVKt" + }, + "outputs": [], + "source": [ + "from haystack.components.builders import ChatPromptBuilder\n", + "\n", + "\n", + "prompt_template = [ChatMessage.from_user(\"\"\"\n", + "Create a JSON object from the information present in this passage: {{passage}}.\n", + "Only use information that is present in the passage. Follow this JSON schema, but only return the actual instances without any additional schema definition:\n", + "{{schema}}\n", + "Make sure your response is a dict and not a list.\n", + "{% if invalid_replies and error_message %}\n", + " You already created the following output in a previous attempt: {{invalid_replies}}\n", + " However, this doesn't comply with the format requirements from above and triggered this Python exception: {{error_message}}\n", + " Correct the output and try again. Just return the corrected output without any extra explanations.\n", + "{% endif %}\n", + "\"\"\")]\n", + "prompt_builder = ChatPromptBuilder(template=prompt_template)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "KM9-Zq2FL7Nn" + }, + "source": [ + "## Initalizing the ChatGenerator\n", + "\n", + "[OpenAIChatGenerator](https://docs.haystack.deepset.ai/docs/openaichatgenerator) generates\n", + "text using OpenAI's `gpt-4o-mini` model by default. Set the `OPENAI_API_KEY` variable and provide a model name to the ChatGenerator." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "Z4cQteIgunUR" + }, + "outputs": [], + "source": [ + "import os\n", + "from getpass import getpass\n", + "\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()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zbotIOgXHkC5" + }, + "source": [ + "## Building the Pipeline\n", + "\n", + "Add all components to your pipeline and connect them. Add connections from `output_validator` back to the `prompt_builder` for cases where the produced JSON doesn't comply with the JSON schema. Set `max_runs_per_component` to avoid infinite looping." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "id": "eFglN9YEv-1W" + }, + "outputs": [ { - "cell_type": "markdown", - "metadata": { - "id": "Egz_4h2vI_QL" - }, - "source": [ - "## What's next\n", - "\n", - "🎉 Congratulations! You've built a system that generates structured JSON out of unstructured text passages, and auto-corrects it by using the looping functionality of Haystack pipelines.\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!" + "data": { + "text/plain": [ + "\n", + "🚅 Components\n", + " - prompt_builder: ChatPromptBuilder\n", + " - llm: OpenAIChatGenerator\n", + " - output_validator: OutputValidator\n", + "🛤️ Connections\n", + " - prompt_builder.prompt -> llm.messages (List[ChatMessage])\n", + " - llm.replies -> output_validator.replies (List[ChatMessage])\n", + " - output_validator.invalid_replies -> prompt_builder.invalid_replies (Optional[List[str]])\n", + " - output_validator.error_message -> prompt_builder.error_message (Optional[str])" ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" } - ], - "metadata": { - "accelerator": "GPU", + ], + "source": [ + "from haystack import Pipeline\n", + "\n", + "pipeline = Pipeline(max_runs_per_component=5)\n", + "\n", + "# Add components to your pipeline\n", + "pipeline.add_component(instance=prompt_builder, name=\"prompt_builder\")\n", + "pipeline.add_component(instance=chat_generator, name=\"llm\")\n", + "pipeline.add_component(instance=output_validator, name=\"output_validator\")\n", + "\n", + "# Now, connect the components to each other\n", + "pipeline.connect(\"prompt_builder.prompt\", \"llm.messages\")\n", + "pipeline.connect(\"llm.replies\", \"output_validator\")\n", + "# If a component has more than one output or input, explicitly specify the connections:\n", + "pipeline.connect(\"output_validator.invalid_replies\", \"prompt_builder.invalid_replies\")\n", + "pipeline.connect(\"output_validator.error_message\", \"prompt_builder.error_message\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-UKW5wtIIT7w" + }, + "source": [ + "### Visualize the Pipeline\n", + "\n", + "Draw the pipeline with the [`draw()`](https://docs.haystack.deepset.ai/docs/drawing-pipeline-graphs) method to confirm the connections are correct. You can find the diagram in the Files section of this Colab." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "id": "RZJg6YHId300" + }, + "outputs": [], + "source": [ + "pipeline.draw(\"auto-correct-pipeline.png\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kV_kexTjImpo" + }, + "source": [ + "## Testing the Pipeline\n", + "\n", + "Run the pipeline with an example passage that you want to convert into a JSON format and the `json_schema` you have created for `CitiesData`. For the given example passage, the generated JSON object should be like:\n", + "```json\n", + "{\n", + " \"cities\": [\n", + " {\n", + " \"name\": \"Berlin\",\n", + " \"country\": \"Germany\",\n", + " \"population\": 3850809\n", + " },\n", + " {\n", + " \"name\": \"Paris\",\n", + " \"country\": \"France\",\n", + " \"population\": 2161000\n", + " },\n", + " {\n", + " \"name\": \"Lisbon\",\n", + " \"country\": \"Portugal\",\n", + " \"population\": 504718\n", + " }\n", + " ]\n", + "}\n", + "```\n", + "The output of the LLM should be compliant with the `json_schema`. If the LLM doesn't generate the correct JSON object, it will loop back and try again." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { "colab": { - "gpuType": "T4", - "provenance": [] + "base_uri": "https://localhost:8080/" }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" + "id": "yIoMedb6eKia", + "outputId": "4a9ef924-cf26-4908-d83f-b0bc0dc03b54" + }, + "outputs": [], + "source": [ + "passage = \"Berlin is the capital of Germany. It has a population of 3,850,809. Paris, France's capital, has 2.161 million residents. Lisbon is the capital and the largest city of Portugal with the population of 504,718.\"\n", + "result = pipeline.run({\"prompt_builder\": {\"passage\": passage, \"schema\": json_schema}})" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "WWxmPgADS_Fa" + }, + "source": [ + "> If you encounter `PipelineMaxLoops: Maximum loops count (5) exceeded for component 'prompt_builder'.` error, consider increasing the maximum loop count or simply rerun the pipeline." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eWPawSjgSJAM" + }, + "source": [ + "### Print the Correct JSON\n", + "If you didn't get any error, you can now print the corrected JSON." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" }, - "language_info": { - "name": "python" + "id": "BVO47gXQQnDC", + "outputId": "460a10d4-a69a-49cd-bbb2-fc4980907299" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'cities': [{'name': 'Berlin', 'country': 'Germany', 'population': 3850809}, {'name': 'Paris', 'country': 'France', 'population': 2161000}, {'name': 'Lisbon', 'country': 'Portugal', 'population': 504718}]}\n" + ] } + ], + "source": [ + "valid_reply = result[\"output_validator\"][\"valid_replies\"][0].content\n", + "valid_json = json.loads(valid_reply)\n", + "print(valid_json)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Egz_4h2vI_QL" + }, + "source": [ + "## What's next\n", + "\n", + "🎉 Congratulations! You've built a system that generates structured JSON out of unstructured text passages, and auto-corrects it by using the looping functionality of Haystack pipelines.\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" }, - "nbformat": 4, - "nbformat_minor": 0 + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/tutorials/auto-correct-pipeline.png b/tutorials/auto-correct-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..a0fe89e4b064fcc2fe36a85bb3024529e7784307 GIT binary patch literal 86236 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 E0OMTGK>z>% literal 0 HcmV?d00001 From 523b7f3cfb103717fce0dbef2259b4c177a8a7f5 Mon Sep 17 00:00:00 2001 From: Amna Mubashar Date: Sun, 8 Dec 2024 21:11:47 +0100 Subject: [PATCH 4/8] delete extra file --- tutorials/auto-correct-pipeline.png | Bin 86236 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tutorials/auto-correct-pipeline.png diff --git a/tutorials/auto-correct-pipeline.png b/tutorials/auto-correct-pipeline.png deleted file mode 100644 index a0fe89e4b064fcc2fe36a85bb3024529e7784307..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86236 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 E0OMTGK>z>% From 4e2ab125ba603f8dc39bc729186dd600c1047c43 Mon Sep 17 00:00:00 2001 From: Amna Mubashar Date: Sun, 8 Dec 2024 22:18:34 +0100 Subject: [PATCH 5/8] Updated tutorial 29 --- .../28_Structured_Output_With_Loop.ipynb | 2 +- tutorials/29_Serializing_Pipelines.ipynb | 218 ++++++++++-------- 2 files changed, 126 insertions(+), 94 deletions(-) diff --git a/tutorials/28_Structured_Output_With_Loop.ipynb b/tutorials/28_Structured_Output_With_Loop.ipynb index 8e1d3ded..75b4014e 100644 --- a/tutorials/28_Structured_Output_With_Loop.ipynb +++ b/tutorials/28_Structured_Output_With_Loop.ipynb @@ -71,7 +71,7 @@ "source": [ "%%bash\n", "\n", - "pip install haystack-ai==2.8.0\n", + "pip install haystack-ai\n", "pip install colorama" ] }, diff --git a/tutorials/29_Serializing_Pipelines.ipynb b/tutorials/29_Serializing_Pipelines.ipynb index 9e6d3493..6b606fae 100644 --- a/tutorials/29_Serializing_Pipelines.ipynb +++ b/tutorials/29_Serializing_Pipelines.ipynb @@ -10,7 +10,7 @@ "\n", "- **Level**: Beginner\n", "- **Time to complete**: 10 minutes\n", - "- **Components Used**: [`HuggingFaceLocalGenerator`](https://docs.haystack.deepset.ai/docs/huggingfacelocalgenerator), [`PromptBuilder`](https://docs.haystack.deepset.ai/docs/promptbuilder)\n", + "- **Components Used**: [`HuggingFaceLocalChatGenerator`](https://docs.haystack.deepset.ai/docs/huggingfacelocalchatgenerator), [`ChatPromptBuilder`](https://docs.haystack.deepset.ai/docs/chatpromptbuilder)\n", "- **Prerequisites**: None\n", "- **Goal**: After completing this tutorial, you'll understand how to serialize and deserialize between YAML and Python code.\n", "\n", @@ -65,48 +65,7 @@ "id": "CagzMFdkeBBp", "outputId": "e304450a-24e3-4ef8-e642-1fbb573e7d55" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: haystack-ai in /usr/local/lib/python3.10/dist-packages (2.0.0b5)\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.10.0)\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.3.3)\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.1)\n", - "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.10/dist-packages (from haystack-ai) (4.9.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.26.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) (1.10.14)\n", - "Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from openai>=1.1.0->haystack-ai) (1.3.0)\n", - "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from haystack-bm25->haystack-ai) (1.23.5)\n", - "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->haystack-ai) (2.1.4)\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.3.post1)\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) (2023.11.17)\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.2)\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: 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" - ] - } - ], + "outputs": [], "source": [ "%%bash\n", "\n", @@ -150,22 +109,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "id": "odZJjD7KgO1g" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "🚅 Components\n", + " - builder: ChatPromptBuilder\n", + " - llm: HuggingFaceLocalChatGenerator\n", + "🛤️ Connections\n", + " - builder.prompt -> llm.messages (List[ChatMessage])" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from haystack import Pipeline\n", - "from haystack.components.builders import PromptBuilder\n", - "from haystack.components.generators import HuggingFaceLocalGenerator\n", + "from haystack.components.builders import ChatPromptBuilder\n", + "from haystack.dataclasses import ChatMessage\n", + "from haystack.components.generators.chat import HuggingFaceLocalChatGenerator\n", "\n", - "template = \"\"\"\n", + "template = [ChatMessage.from_user(\"\"\"\n", "Please create a summary about the following topic:\n", "{{ topic }}\n", - "\"\"\"\n", - "builder = PromptBuilder(template=template)\n", - "llm = HuggingFaceLocalGenerator(\n", + "\"\"\")]\n", + "builder = ChatPromptBuilder(template=template)\n", + "llm = HuggingFaceLocalChatGenerator(\n", " model=\"google/flan-t5-large\", task=\"text2text-generation\", generation_kwargs={\"max_new_tokens\": 150}\n", ")\n", "\n", @@ -173,7 +149,7 @@ "pipeline.add_component(name=\"builder\", instance=builder)\n", "pipeline.add_component(name=\"llm\", instance=llm)\n", "\n", - "pipeline.connect(\"builder\", \"llm\")" + "pipeline.connect(\"builder.prompt\", \"llm.messages\")" ] }, { @@ -186,15 +162,7 @@ "id": "W-onTCXfqFjG", "outputId": "e81cd5ea-db66-4f0e-f787-5aed7a7b4692" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Climate change is a major threat to the planet.\n" - ] - } - ], + "outputs": [], "source": [ "topic = \"Climate change\"\n", "result = pipeline.run(data={\"builder\": {\"topic\": topic}})\n", @@ -214,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -230,21 +198,39 @@ "components:\n", " builder:\n", " init_parameters:\n", - " template: \"\\nPlease create a summary about the following topic: \\n{{ topic }}\\n\"\n", - " type: haystack.components.builders.prompt_builder.PromptBuilder\n", + " required_variables: null\n", + " template:\n", + " - content: '\n", + "\n", + " Please create a summary about the following topic:\n", + "\n", + " {{ topic }}\n", + "\n", + " '\n", + " meta: {}\n", + " name: null\n", + " role: user\n", + " variables: null\n", + " type: haystack.components.builders.chat_prompt_builder.ChatPromptBuilder\n", " llm:\n", " init_parameters:\n", " generation_kwargs:\n", " max_new_tokens: 150\n", + " stop_sequences: []\n", " huggingface_pipeline_kwargs:\n", - " device: cpu\n", + " device: mps\n", " model: google/flan-t5-large\n", " task: text2text-generation\n", - " token: null\n", - " stop_words: null\n", - " type: haystack.components.generators.hugging_face_local.HuggingFaceLocalGenerator\n", + " streaming_callback: null\n", + " token:\n", + " env_vars:\n", + " - HF_API_TOKEN\n", + " - HF_TOKEN\n", + " strict: false\n", + " type: env_var\n", + " type: haystack.components.generators.chat.hugging_face_local.HuggingFaceLocalChatGenerator\n", "connections:\n", - "- receiver: llm.prompt\n", + "- receiver: llm.messages\n", " sender: builder.prompt\n", "max_runs_per_component: 100\n", "metadata: {}\n", @@ -270,21 +256,40 @@ "components:\n", " builder:\n", " init_parameters:\n", - " template: \"\\nPlease create a summary about the following topic: \\n{{ topic }}\\n\"\n", - " type: haystack.components.builders.prompt_builder.PromptBuilder\n", + " required_variables: null\n", + " template:\n", + " - content: '\n", + "\n", + " Please create a summary about the following topic:\n", + "\n", + " {{ topic }}\n", + "\n", + " '\n", + " meta: {}\n", + " name: null\n", + " role: user\n", + " variables: null\n", + " type: haystack.components.builders.chat_prompt_builder.ChatPromptBuilder\n", " llm:\n", " init_parameters:\n", + " init_parameters:\n", " generation_kwargs:\n", " max_new_tokens: 150\n", + " stop_sequences: []\n", " huggingface_pipeline_kwargs:\n", - " device: cpu\n", + " device: mps\n", " model: google/flan-t5-large\n", " task: text2text-generation\n", - " token: null\n", - " stop_words: null\n", - " type: haystack.components.generators.hugging_face_local.HuggingFaceLocalGenerator\n", + " streaming_callback: null\n", + " token:\n", + " env_vars:\n", + " - HF_API_TOKEN\n", + " - HF_TOKEN\n", + " strict: false\n", + " type: env_var\n", + " type: haystack.components.generators.chat.hugging_face_local.HuggingFaceLocalChatGenerator\n", "connections:\n", - "- receiver: llm.prompt\n", + "- receiver: llm.messages\n", " sender: builder.prompt\n", "max_runs_per_component: 100\n", "metadata: {}\n", @@ -300,12 +305,12 @@ "source": [ "## Editing a Pipeline in YAML\n", "\n", - "Let's see how we can make changes to serialized pipelines. For example, below, let's modify the promptbuilder's template to translate provided `sentence` to French:" + "Let's see how we can make changes to serialized pipelines. For example, below, let's modify the `ChatPromptBuilder`'s template to translate provided `sentence` to French:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "id": "U332-VjovFfn" }, @@ -315,21 +320,32 @@ "components:\n", " builder:\n", " init_parameters:\n", - " template: \"\\nPlease translate the following to French: \\n{{ sentence }}\\n\"\n", - " type: haystack.components.builders.prompt_builder.PromptBuilder\n", + " template:\n", + " - content: 'Please translate the following to French: \\n{{ sentence }}\\n'\n", + " meta: {}\n", + " name: null\n", + " role: user\n", + " variables: null\n", + " type: haystack.components.builders.chat_prompt_builder.ChatPromptBuilder\n", " llm:\n", " init_parameters:\n", " generation_kwargs:\n", " max_new_tokens: 150\n", + " stop_sequences: []\n", " huggingface_pipeline_kwargs:\n", - " device: cpu\n", + " device: mps\n", " model: google/flan-t5-large\n", " task: text2text-generation\n", - " token: null\n", - " stop_words: null\n", - " type: haystack.components.generators.hugging_face_local.HuggingFaceLocalGenerator\n", + " streaming_callback: null\n", + " token:\n", + " env_vars:\n", + " - HF_API_TOKEN\n", + " - HF_TOKEN\n", + " strict: false\n", + " type: env_var\n", + " type: haystack.components.generators.chat.hugging_face_local.HuggingFaceLocalChatGenerator\n", "connections:\n", - "- receiver: llm.prompt\n", + "- receiver: llm.messages\n", " sender: builder.prompt\n", "max_runs_per_component: 100\n", "metadata: {}\n", @@ -349,15 +365,15 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "id": "OdlLnw-9wVN-" }, "outputs": [], "source": [ "from haystack import Pipeline\n", - "from haystack.components.builders import PromptBuilder\n", - "from haystack.components.generators import HuggingFaceLocalGenerator\n", + "from haystack.components.builders import ChatPromptBuilder\n", + "from haystack.components.generators.chat import HuggingFaceLocalChatGenerator\n", "\n", "new_pipeline = Pipeline.loads(yaml_pipeline)" ] @@ -368,12 +384,12 @@ "id": "eVPh2cV6wcu9" }, "source": [ - "Now we can run the new pipeline we defined in YAML. We had changed it so that the `PromptBuilder` expects a `sentence` and translates the sentence to French:" + "Now we can run the new pipeline we defined in YAML. We had changed it so that the `ChatPromptBuilder` expects a `sentence` and translates the sentence to French:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -382,13 +398,20 @@ "outputId": "ec6eae9f-a7ea-401d-c0ab-792748f6db6f" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No chat template is set for this tokenizer, falling back to a default class-level template. This is very error-prone, because models are often trained with templates different from the class default! Default chat templates are a legacy feature and will be removed in Transformers v4.43, at which point any code depending on them will stop working. We recommend setting a valid chat template before then to ensure that this model continues working without issues.\n" + ] + }, { "data": { "text/plain": [ - "{'llm': {'replies': ['Je me félicite des capybaras !']}}" + "{'llm': {'replies': [ChatMessage(content='|im_start|>user', role=, name=None, meta={'finish_reason': 'stop', 'index': 0, 'model': 'google/flan-t5-large', 'usage': {'completion_tokens': 7, 'prompt_tokens': 43, 'total_tokens': 50}})]}}" ] }, - "execution_count": 15, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -421,7 +444,16 @@ "name": "python3" }, "language_info": { - "name": "python" + "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" } }, "nbformat": 4, From 9af354e77047aa1a08ed9a09d21cb664025d0eea Mon Sep 17 00:00:00 2001 From: Amna Mubashar Date: Sun, 8 Dec 2024 23:00:20 +0100 Subject: [PATCH 6/8] Fixed error caused by chat_template --- tutorials/29_Serializing_Pipelines.ipynb | 115 ++++++++++++++++++----- 1 file changed, 91 insertions(+), 24 deletions(-) diff --git a/tutorials/29_Serializing_Pipelines.ipynb b/tutorials/29_Serializing_Pipelines.ipynb index 6b606fae..fcc17d11 100644 --- a/tutorials/29_Serializing_Pipelines.ipynb +++ b/tutorials/29_Serializing_Pipelines.ipynb @@ -57,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -65,7 +65,60 @@ "id": "CagzMFdkeBBp", "outputId": "e304450a-24e3-4ef8-e642-1fbb573e7d55" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Requirement already satisfied: haystack-ai 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) (0.3.0)\n", + "Requirement already satisfied: jinja2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (3.1.4)\n", + "Requirement already satisfied: lazy-imports in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (0.3.1)\n", + "Requirement already satisfied: more-itertools in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (10.2.0)\n", + "Requirement already satisfied: networkx in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (3.2.1)\n", + "Requirement already satisfied: numpy in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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) (1.31.1)\n", + "Requirement already satisfied: pandas in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (2.2.2)\n", + "Requirement already satisfied: posthog in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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.9.0.post0)\n", + "Requirement already satisfied: pyyaml in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (6.0.1)\n", + "Requirement already satisfied: requests in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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) (8.3.0)\n", + "Requirement already satisfied: tqdm in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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) (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) (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) (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) (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.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) (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.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) (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) (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) (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) (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.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) (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) (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) (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) (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) (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) (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) (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) (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.18.4)\n" + ] + }, + { + "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", @@ -85,11 +138,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "id": "ikIM1o9cHNcS" }, - "outputs": [], + "outputs": [ + { + "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", @@ -109,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 14, "metadata": { "id": "odZJjD7KgO1g" }, @@ -117,7 +179,7 @@ { "data": { "text/plain": [ - "\n", + "\n", "🚅 Components\n", " - builder: ChatPromptBuilder\n", " - llm: HuggingFaceLocalChatGenerator\n", @@ -125,7 +187,7 @@ " - builder.prompt -> llm.messages (List[ChatMessage])" ] }, - "execution_count": 3, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -140,9 +202,12 @@ "Please create a summary about the following topic:\n", "{{ topic }}\n", "\"\"\")]\n", + "chat_template = \"{% for message in messages %}{% if message['role'] == 'user' %}{{ ' ' }}{% endif %}{{ message['content'] }}{% if not loop.last %}{{ ' ' }}{% endif %}{% endfor %}{{ eos_token }}\"\n", + "\n", "builder = ChatPromptBuilder(template=template)\n", "llm = HuggingFaceLocalChatGenerator(\n", - " model=\"google/flan-t5-large\", task=\"text2text-generation\", generation_kwargs={\"max_new_tokens\": 150}\n", + " model=\"google/flan-t5-large\", task=\"text2text-generation\", generation_kwargs={\"max_new_tokens\": 150},\n", + " chat_template=chat_template\n", ")\n", "\n", "pipeline = Pipeline()\n", @@ -154,7 +219,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -162,11 +227,19 @@ "id": "W-onTCXfqFjG", "outputId": "e81cd5ea-db66-4f0e-f787-5aed7a7b4692" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Climate change is a major threat to the planet.\n" + ] + } + ], "source": [ "topic = \"Climate change\"\n", "result = pipeline.run(data={\"builder\": {\"topic\": topic}})\n", - "print(result[\"llm\"][\"replies\"][0])" + "print(result[\"llm\"][\"replies\"][0].content)" ] }, { @@ -182,7 +255,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -310,7 +383,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 17, "metadata": { "id": "U332-VjovFfn" }, @@ -337,6 +410,7 @@ " model: google/flan-t5-large\n", " task: text2text-generation\n", " streaming_callback: null\n", + " chat_template : \"{% for message in messages %}{% if message['role'] == 'user' %}{{ ' ' }}{% endif %}{{ message['content'] }}{% if not loop.last %}{{ ' ' }}{% endif %}{% endfor %}{{ eos_token }}\"\n", " token:\n", " env_vars:\n", " - HF_API_TOKEN\n", @@ -365,7 +439,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 18, "metadata": { "id": "OdlLnw-9wVN-" }, @@ -389,7 +463,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 19, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -398,20 +472,13 @@ "outputId": "ec6eae9f-a7ea-401d-c0ab-792748f6db6f" }, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "No chat template is set for this tokenizer, falling back to a default class-level template. This is very error-prone, because models are often trained with templates different from the class default! Default chat templates are a legacy feature and will be removed in Transformers v4.43, at which point any code depending on them will stop working. We recommend setting a valid chat template before then to ensure that this model continues working without issues.\n" - ] - }, { "data": { "text/plain": [ - "{'llm': {'replies': [ChatMessage(content='|im_start|>user', role=, name=None, meta={'finish_reason': 'stop', 'index': 0, 'model': 'google/flan-t5-large', 'usage': {'completion_tokens': 7, 'prompt_tokens': 43, 'total_tokens': 50}})]}}" + "{'llm': {'replies': [ChatMessage(content='Je me félicite des capybaras', role=, name=None, meta={'finish_reason': 'stop', 'index': 0, 'model': 'google/flan-t5-large', 'usage': {'completion_tokens': 13, 'prompt_tokens': 16, 'total_tokens': 29}})]}}" ] }, - "execution_count": 14, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } From 1f36ee6083989614c1b20fda0856c55a1cf2c7fb Mon Sep 17 00:00:00 2001 From: Amna Mubashar Date: Sun, 8 Dec 2024 23:12:53 +0100 Subject: [PATCH 7/8] Small fix --- tutorials/29_Serializing_Pipelines.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/29_Serializing_Pipelines.ipynb b/tutorials/29_Serializing_Pipelines.ipynb index fcc17d11..114d4001 100644 --- a/tutorials/29_Serializing_Pipelines.ipynb +++ b/tutorials/29_Serializing_Pipelines.ipynb @@ -350,7 +350,7 @@ " max_new_tokens: 150\n", " stop_sequences: []\n", " huggingface_pipeline_kwargs:\n", - " device: mps\n", + " device: cpu\n", " model: google/flan-t5-large\n", " task: text2text-generation\n", " streaming_callback: null\n", @@ -383,7 +383,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "id": "U332-VjovFfn" }, @@ -406,7 +406,7 @@ " max_new_tokens: 150\n", " stop_sequences: []\n", " huggingface_pipeline_kwargs:\n", - " device: mps\n", + " device: cpu\n", " model: google/flan-t5-large\n", " task: text2text-generation\n", " streaming_callback: null\n", From ca0a0e4eb9cf97f36730feafd3635abe262aa361 Mon Sep 17 00:00:00 2001 From: Amna Mubashar Date: Thu, 12 Dec 2024 11:05:18 +0100 Subject: [PATCH 8/8] Replace content with text --- tutorials/27_First_RAG_Pipeline.ipynb | 39 ++++++++-- .../28_Structured_Output_With_Loop.ipynb | 8 +- tutorials/29_Serializing_Pipelines.ipynb | 77 ++++--------------- 3 files changed, 48 insertions(+), 76 deletions(-) diff --git a/tutorials/27_First_RAG_Pipeline.ipynb b/tutorials/27_First_RAG_Pipeline.ipynb index 62095dcb..d8a4fc49 100644 --- a/tutorials/27_First_RAG_Pipeline.ipynb +++ b/tutorials/27_First_RAG_Pipeline.ipynb @@ -248,7 +248,14 @@ "name": "stderr", "output_type": "stream", "text": [ - "Batches: 100%|██████████| 5/5 [00:01<00:00, 3.09it/s]\n" + "Batches: 0%| | 0/5 [00:00\n", + "\n", "🚅 Components\n", " - text_embedder: SentenceTransformersTextEmbedder\n", " - retriever: InMemoryEmbeddingRetriever\n", @@ -499,7 +506,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -526,14 +533,30 @@ "name": "stderr", "output_type": "stream", "text": [ - "Batches: 100%|██████████| 1/1 [00:00<00:00, 4.19it/s]\n" + "Batches: 100%|██████████| 1/1 [00:00<00:00, 1.77it/s]\n", + "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", + "To disable this warning, you can either:\n", + "\t- Avoid using `tokenizers` before the fork if possible\n", + "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n" ] }, { "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" + "The Colossus of Rhodes was a statue of the Greek sun-god Helios, standing approximately 70 cubits (about 33 meters or 108 feet) tall. Although no complete descriptions of its appearance exist, scholars believe it featured the following characteristics:\n", + "\n", + "1. **Facial Features**: The head of the statue likely had curly hair, with spikes resembling bronze or silver flames radiating outward. This style is similar to depictions found on contemporary Rhodian coins.\n", + "\n", + "2. **Posture**: While the exact pose is uncertain, it is suggested that the statue may have been constructed in a pose where Helios is depicted shielding his eyes with one hand, a common representation of someone looking toward the sun.\n", + "\n", + "3. **Construction Materials**: The structure was built using iron tie bars and brass plates, which formed the skin of the statue. The interior was filled with stone blocks.\n", + "\n", + "4. **Height and Scale**: The Colossus was positioned on a 15-metre-high (49-foot) pedestal, making it one of the tallest statues of the ancient world, towering over the harbor entrance.\n", + "\n", + "5. **Symbolic Representation**: The statue was meant to symbolize the victory and freedom of the Rhodians after successfully defending their city against an invader.\n", + "\n", + "Overall, the Colossus of Rhodes was an impressive and monumental statue designed to celebrate and symbolize the strength and resilience of the city of Rhodes.\n" ] } ], @@ -542,7 +565,7 @@ "\n", "response = basic_rag_pipeline.run({\"text_embedder\": {\"text\": question}, \"prompt_builder\": {\"question\": question}})\n", "\n", - "print(response[\"llm\"][\"replies\"][0])" + "print(response[\"llm\"][\"replies\"][0].text)" ] }, { diff --git a/tutorials/28_Structured_Output_With_Loop.ipynb b/tutorials/28_Structured_Output_With_Loop.ipynb index 75b4014e..217d1f0d 100644 --- a/tutorials/28_Structured_Output_With_Loop.ipynb +++ b/tutorials/28_Structured_Output_With_Loop.ipynb @@ -187,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "id": "yr6D8RN2d7Vy" }, @@ -219,7 +219,7 @@ " ## Try to parse the LLM's reply ##\n", " # If the LLM's reply is a valid object, return `\"valid_replies\"`\n", " try:\n", - " output_dict = json.loads(replies[0].content)\n", + " output_dict = json.loads(replies[0].text)\n", " self.pydantic_model.parse_obj(output_dict)\n", " print(\n", " Fore.GREEN\n", @@ -474,7 +474,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -492,7 +492,7 @@ } ], "source": [ - "valid_reply = result[\"output_validator\"][\"valid_replies\"][0].content\n", + "valid_reply = result[\"output_validator\"][\"valid_replies\"][0].text\n", "valid_json = json.loads(valid_reply)\n", "print(valid_json)" ] diff --git a/tutorials/29_Serializing_Pipelines.ipynb b/tutorials/29_Serializing_Pipelines.ipynb index 114d4001..b98eaf2c 100644 --- a/tutorials/29_Serializing_Pipelines.ipynb +++ b/tutorials/29_Serializing_Pipelines.ipynb @@ -57,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -65,60 +65,7 @@ "id": "CagzMFdkeBBp", "outputId": "e304450a-24e3-4ef8-e642-1fbb573e7d55" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Defaulting to user installation because normal site-packages is not writeable\n", - "Requirement already satisfied: haystack-ai 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) (0.3.0)\n", - "Requirement already satisfied: jinja2 in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (3.1.4)\n", - "Requirement already satisfied: lazy-imports in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (0.3.1)\n", - "Requirement already satisfied: more-itertools in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (10.2.0)\n", - "Requirement already satisfied: networkx in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (3.2.1)\n", - "Requirement already satisfied: numpy in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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) (1.31.1)\n", - "Requirement already satisfied: pandas in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (2.2.2)\n", - "Requirement already satisfied: posthog in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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.9.0.post0)\n", - "Requirement already satisfied: pyyaml in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (6.0.1)\n", - "Requirement already satisfied: requests in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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) (8.3.0)\n", - "Requirement already satisfied: tqdm in /Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages (from haystack-ai) (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) (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) (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) (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) (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.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) (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.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) (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) (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) (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) (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.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) (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) (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) (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) (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) (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) (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) (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) (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.18.4)\n" - ] - }, - { - "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" - ] - } - ], + "outputs": [], "source": [ "%%bash\n", "\n", @@ -147,6 +94,8 @@ "name": "stderr", "output_type": "stream", "text": [ + "/Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020\n", + " warnings.warn(\n", "/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" ] @@ -171,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 3, "metadata": { "id": "odZJjD7KgO1g" }, @@ -179,7 +128,7 @@ { "data": { "text/plain": [ - "\n", + "\n", "🚅 Components\n", " - builder: ChatPromptBuilder\n", " - llm: HuggingFaceLocalChatGenerator\n", @@ -187,7 +136,7 @@ " - builder.prompt -> llm.messages (List[ChatMessage])" ] }, - "execution_count": 14, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -219,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -239,7 +188,7 @@ "source": [ "topic = \"Climate change\"\n", "result = pipeline.run(data={\"builder\": {\"topic\": topic}})\n", - "print(result[\"llm\"][\"replies\"][0].content)" + "print(result[\"llm\"][\"replies\"][0].text)" ] }, { @@ -383,7 +332,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "id": "U332-VjovFfn" }, @@ -439,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 6, "metadata": { "id": "OdlLnw-9wVN-" }, @@ -463,7 +412,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -478,7 +427,7 @@ "{'llm': {'replies': [ChatMessage(content='Je me félicite des capybaras', role=, name=None, meta={'finish_reason': 'stop', 'index': 0, 'model': 'google/flan-t5-large', 'usage': {'completion_tokens': 13, 'prompt_tokens': 16, 'total_tokens': 29}})]}}" ] }, - "execution_count": 19, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" }