diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1768eec --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +loop_baching.py diff --git a/Arq_batch_embedding.md b/Arq_batch_embedding.md new file mode 100644 index 0000000..4316e48 --- /dev/null +++ b/Arq_batch_embedding.md @@ -0,0 +1,128 @@ +# Arquitectura: Extractive Question Answering + +## Diagrama General + +``` +┌──────────┐ ┌───────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ +│ │ │ │ │ │ │ │ │ │ +│ PREGUNTA │────▶│ RETRIEVER │────▶│ PINECONE │────▶│ READER │────▶│ RESPUESTA │ +│ │ │ │ │ │ │ │ │ │ +└──────────┘ └───────────────┘ └──────────────┘ └──────────────┘ └────────────┘ + │ │ │ + │ │ │ + "multi-qa- base de datos "deepset/ + MiniLM-L6- vectorial electra-base- + cos-v1" (cosine) squad2" +``` + +--- + +## Flujo Paso a Paso + +``` + FASE 1: INDEXACIÓN (se hace UNA sola vez) + ────────────────────────────────────────── + + ┌──────────┐ ┌──────────────┐ ┌──────────────┐ + │ contexto │─────▶│ RETRIEVER │─────▶│ PINECONE │ + │ (texto) │ │ .encode() │ │ .upsert() │ + └──────────┘ └──────────────┘ └──────────────┘ + │ │ + ▼ ▼ + [0.12, -0.34, guarda: id + 0.87, ...] + vector (384 nums) + ↑ + metadata (title, texto) + 384 números + + + FASE 2: CONSULTA (cada vez que hacés una pregunta) + ────────────────────────────────────────────────── + +┌──────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ +│ │ │ │ │ │ │ │ │ │ +│ "How │─────▶│ RETRIEVER │─────▶│ PINECONE │─────▶│ READER │─────▶│ "691,000 │ +│ much │ │ .encode() │ │ .query() │ │ pipeline() │ │ bbl/d" │ +│ oil...?"│ │ │ │ │ │ │ │ │ +└──────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └────────────┘ + │ │ │ + ▼ ▼ ▼ + convierto la busco los top_k por cada contexto, + pregunta en vectores más extraigo la respuesta + 384 números parecidos (cosine) y me quedo con la + ───────────────── de mayor score + devuelve: id + + vector + metadata + +``` + +--- + +## El Loop de Batching (detalle de la Fase 1) + +``` +df (dataframe con 1000+ contextos) +│ +├── Lote 0: filas 0..63 ──▶ encode(64 textos) ──▶ 64 vectores ──▶ upsert a Pinecone +├── Lote 1: filas 64..127 ──▶ encode(64 textos) ──▶ 64 vectores ──▶ upsert a Pinecone +├── Lote 2: filas 128..191──▶ encode(64 textos) ──▶ 64 vectores ──▶ upsert a Pinecone +│ ... +└── Último lote ────────────▶ encode(lo que sobre) ──▶ upsert a Pinecone + +¿Por qué en lotes? + - Mandar 1 por 1 → 1000 llamadas a Pinecone = lentísimo + - Mandar todo junto → posible timeout o memory error + - Batch de 64 → equilibrio entre velocidad y estabilidad +``` + +--- + +## ¿Qué hace cada modelo? + +| Componente | Modelo | Entrada | Salida | Rol | +|------------|--------|---------|--------|-----| +| **Retriever** | `multi-qa-MiniLM-L6-cos-v1` | Texto (pregunta o contexto) | Vector de 384 números | Búsqueda semántica: encontrar contextos relevantes | +| **Pinecone** | - | Vector de 384 números | top_k vectores + metadata | Almacenar y recuperar rápido (sin esto habría que comparar contra todos cada vez) | +| **Reader** | `deepset/electra-base-squad2` | Pregunta + 1 contexto | `{answer, score, start, end}` | Extracción fina: pinpoint la respuesta dentro del texto | + +--- + +## Analogía para no olvidarlo + +``` +Retriever = buscador de Google + ↳ Le das "receta pizza" y te devuelve 5 links relevantes + +Pinecone = el índice de Google + ↳ La base de datos gigante donde Google guardó todas las páginas indexadas + +Reader = tus ojos leyendo la receta + ↳ De los 5 links, abrís uno y encontrás "200g de harina" +``` + +--- + +## El código equivalente + +```python +# FASE 1: Indexar (se hace una vez) +for i in range(0, len(df), 64): + batch = df.iloc[i : i+64] # corto 64 filas + emb = retriever.encode(batch["context"].tolist()) # textos → vectores + meta = [{"title": r.title, "context": r.context} + for r in batch.itertuples()] # guardo de qué texto vino + ids = [str(j) for j in range(i, i+64)] # IDs únicos + index.upsert(vectors=zip(ids, emb, meta)) # subo a Pinecone + + +# FASE 2: Preguntar (cada vez) +def get_context(question, top_k): + xq = retriever.encode(question) # pregunta → vector + xc = index.query(vector=xq, top_k=top_k) # busco en Pinecone + return [match["metadata"]["context"] # extraigo solo el texto + for match in xc["matches"]] + + +def extract_answer(question, contexts): + results = [reader(question=q, context=c) for c in contexts] # reader extrae + return sorted(results, key=lambda r: r["score"], reverse=True) # mejor primero +``` diff --git a/lab-extractive-question-answering.ipynb b/lab-extractive-question-answering.ipynb index 0cf5b39..22e4f0f 100644 --- a/lab-extractive-question-answering.ipynb +++ b/lab-extractive-question-answering.ipynb @@ -54,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "740a3cf7-830c-4f1d-bf8d-90d18f908a99", "metadata": {}, "outputs": [], @@ -87,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "expressed-executive", "metadata": { "colab": { @@ -110,9 +110,17 @@ }, "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], "source": [ - "!pip install -qU datasets pinecone-client sentence-transformers torch" + "pip install -qU datasets pinecone sentence-transformers torch " ] }, { @@ -137,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "J250IJeh7NIb", "metadata": { "colab": { @@ -237,7 +245,16 @@ "id": "J250IJeh7NIb", "outputId": "6f249347-51f8-48be-ab90-a202eee648a7" }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/basstianlopez/miniconda3/envs/langchain-lesson/lib/python3.11/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 datasets import load_dataset\n", "\n", @@ -247,7 +264,125 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, + "id": "4e02a213", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idtitlecontextquestionanswers
05733be284776f41900661182University_of_Notre_DameArchitecturally, the school has a Catholic cha...To whom did the Virgin Mary allegedly appear i...{'text': ['Saint Bernadette Soubirous'], 'answ...
15733be284776f4190066117fUniversity_of_Notre_DameArchitecturally, the school has a Catholic cha...What is in front of the Notre Dame Main Building?{'text': ['a copper statue of Christ'], 'answe...
25733be284776f41900661180University_of_Notre_DameArchitecturally, the school has a Catholic cha...The Basilica of the Sacred heart at Notre Dame...{'text': ['the Main Building'], 'answer_start'...
35733be284776f41900661181University_of_Notre_DameArchitecturally, the school has a Catholic cha...What is the Grotto at Notre Dame?{'text': ['a Marian place of prayer and reflec...
45733be284776f4190066117eUniversity_of_Notre_DameArchitecturally, the school has a Catholic cha...What sits on top of the Main Building at Notre...{'text': ['a golden statue of the Virgin Mary'...
\n", + "
" + ], + "text/plain": [ + " id title \\\n", + "0 5733be284776f41900661182 University_of_Notre_Dame \n", + "1 5733be284776f4190066117f University_of_Notre_Dame \n", + "2 5733be284776f41900661180 University_of_Notre_Dame \n", + "3 5733be284776f41900661181 University_of_Notre_Dame \n", + "4 5733be284776f4190066117e University_of_Notre_Dame \n", + "\n", + " context \\\n", + "0 Architecturally, the school has a Catholic cha... \n", + "1 Architecturally, the school has a Catholic cha... \n", + "2 Architecturally, the school has a Catholic cha... \n", + "3 Architecturally, the school has a Catholic cha... \n", + "4 Architecturally, the school has a Catholic cha... \n", + "\n", + " question \\\n", + "0 To whom did the Virgin Mary allegedly appear i... \n", + "1 What is in front of the Notre Dame Main Building? \n", + "2 The Basilica of the Sacred heart at Notre Dame... \n", + "3 What is the Grotto at Notre Dame? \n", + "4 What sits on top of the Main Building at Notre... \n", + "\n", + " answers \n", + "0 {'text': ['Saint Bernadette Soubirous'], 'answ... \n", + "1 {'text': ['a copper statue of Christ'], 'answe... \n", + "2 {'text': ['the Main Building'], 'answer_start'... \n", + "3 {'text': ['a Marian place of prayer and reflec... \n", + "4 {'text': ['a golden statue of the Virgin Mary'... " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, "id": "FcmeNO97dHDO", "metadata": { "colab": { @@ -257,13 +392,90 @@ "id": "FcmeNO97dHDO", "outputId": "11af1908-8950-4433-f66d-7d363d010c97" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
titlecontext
0University_of_Notre_DameArchitecturally, the school has a Catholic cha...
5University_of_Notre_DameAs at most other universities, Notre Dame's st...
10University_of_Notre_DameThe university is the major seat of the Congre...
15University_of_Notre_DameThe College of Engineering was established in ...
20University_of_Notre_DameAll of Notre Dame's undergraduate students are...
\n", + "
" + ], + "text/plain": [ + " title \\\n", + "0 University_of_Notre_Dame \n", + "5 University_of_Notre_Dame \n", + "10 University_of_Notre_Dame \n", + "15 University_of_Notre_Dame \n", + "20 University_of_Notre_Dame \n", + "\n", + " context \n", + "0 Architecturally, the school has a Catholic cha... \n", + "5 As at most other universities, Notre Dame's st... \n", + "10 The university is the major seat of the Congre... \n", + "15 The College of Engineering was established in ... \n", + "20 All of Notre Dame's undergraduate students are... " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# select only title and context column\n", - "df = None\n", + "df = df[[\"title\", \"context\"]]\n", "# drop rows containing duplicate context passages\n", - "df = None\n", - "df" + "df = df.drop_duplicates(subset=[\"context\"])\n", + "\n", + "df.head()\n" ] }, { @@ -288,7 +500,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "5983bc0e", "metadata": {}, "outputs": [], @@ -298,7 +510,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "092d1e71", "metadata": { "id": "092d1e71" @@ -314,7 +526,7 @@ "# connect to pinecone environment\n", "pc = Pinecone(\n", " api_key = PINECONE_API_KEY,\n", - " environment='us-east-1' # find next to API key in console\n", + " #environment='us-east-1' # find next to API key in console\n", ")" ] }, @@ -330,21 +542,57 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, + "id": "3e3ae67d", + "metadata": {}, + "outputs": [], + "source": [ + "from pinecone import Pinecone, ServerlessSpec" + ] + }, + { + "cell_type": "code", + "execution_count": 9, "id": "b3206184", "metadata": { "id": "b3206184" }, "outputs": [], "source": [ - "index_name = None\n", + "\"\"\" index_name = \"question-answering\"\n", "\n", "# check if the extractive-question-answering index exists\n", "if index_name not in pinecone.list_indexes().names():\n", " # create the index if it does not exist\n", - " None\n", + " pc.create_index(\n", + " name=index_name,\n", + " dimension=384,\n", + " metric=\"cosine\",\n", + " spec=ServerlessSpec(cloud=\"aws\", region=\"us-east-1\")\n", + " )\n", "# connect to extractive-question-answering index we created\n", - "index = pinecone.Index(index_name)" + "index = pinecone.Index(index_name)\n", + "\"\"\"\n", + "\n", + "index_name = \"question-answering\"\n", + "if index_name not in pc.list_indexes().names():\n", + " pc.create_index(\n", + " name=index_name,\n", + " dimension=384,\n", + " metric=\"cosine\",\n", + " spec=ServerlessSpec(cloud=\"aws\", region=\"us-east-1\")\n", + " )\n", + "index = pc.Index(index_name)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "ba46077b", + "metadata": {}, + "outputs": [], + "source": [ + "index = pc.Index(\"question-answering\")" ] }, { @@ -376,7 +624,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "31a85bb3", "metadata": { "colab": { @@ -542,7 +790,22 @@ "id": "31a85bb3", "outputId": "6ee65615-6cd5-4e06-f5b6-97263e4d7474" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "SentenceTransformer(\n", + " (0): Transformer({'transformer_task': 'feature-extraction', 'modality_config': {'text': {'method': 'forward', 'method_output_name': 'last_hidden_state'}}, 'module_output_name': 'token_embeddings', 'architecture': 'BertModel'})\n", + " (1): Pooling({'embedding_dimension': 384, 'pooling_mode': 'mean', 'include_prompt': True})\n", + " (2): Normalize({})\n", + ")" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import torch\n", "from sentence_transformers import SentenceTransformer\n", @@ -550,7 +813,7 @@ "# set device to GPU if available\n", "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", "# load the retriever model from huggingface model hub\n", - "retriever = None #use the 'multi-qa-MiniLM-L6-cos-v1' model from HuggingFace to build the retriever\n", + "retriever = SentenceTransformer(\"multi-qa-MiniLM-L6-cos-v1\")#use the 'multi-qa-MiniLM-L6-cos-v1' model from HuggingFace to build the retriever\n", "retriever" ] }, @@ -576,7 +839,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "a17824ef", "metadata": { "colab": { @@ -600,7 +863,25 @@ "outputId": "c2b46e15-4648-4377-a5aa-19cb01d92a25", "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 296/296 [54:54<00:00, 11.13s/it] \n" + ] + }, + { + "data": { + "text/plain": [ + "DescribeIndexStatsResponse(dimension=384, total_vector_count=18891, metric='cosine', namespaces=1)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from tqdm.auto import tqdm\n", "\n", @@ -609,17 +890,17 @@ "\n", "for i in tqdm(range(0, len(df), batch_size)):\n", " # find end of batch\n", - " None\n", + " i_end = min(i + batch_size, len(df))\n", " # extract batch\n", - " None\n", + " batch = df.iloc[i:i_end]\n", " # generate embeddings for batch\n", - " emb = None\n", + " emb = retriever.encode(batch[\"context\"].tolist()).tolist()\n", " # get metadata\n", - " meta = None\n", + " meta = [{\"title\": row[\"title\"], \"context\": row[\"context\"]} for _, row in batch.iterrows()]\n", " # create unique IDs\n", - " ids = None\n", + " ids = [str(j) for j in range(i, i_end)]\n", " # add all to upsert list\n", - " to_upsert = None\n", + " to_upsert = list(zip(ids,emb, meta))\n", " # upsert/insert these records to pinecone\n", " _ = index.upsert(vectors=to_upsert)\n", "\n", @@ -649,7 +930,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "hg9XTDkIJzH_", "metadata": { "colab": { @@ -716,7 +997,25 @@ "id": "hg9XTDkIJzH_", "outputId": "0309c40e-b037-44f0-b2d1-8da457201b93" }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Device set to use cpu\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from transformers import pipeline\n", "\n", @@ -738,7 +1037,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "id": "lyYaY3QEQiHZ", "metadata": { "id": "lyYaY3QEQiHZ" @@ -748,17 +1047,17 @@ "# gets context passages from the pinecone index\n", "def get_context(question, top_k):\n", " # generate embeddings for the question\n", - " xq = None\n", + " xq = retriever.encode(question).tolist()\n", " # search pinecone index for context passage with the answer\n", - " xc = None\n", + " xc = index.query(vector=xq, top_k=top_k, include_metadata=True)\n", " # extract the context passage from pinecone search result\n", - " c = None\n", + " c = [match[\"metadata\"][\"context\"] for match in xc[\"matches\"]]\n", " return c" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "id": "Dc9VYOiUQA7B", "metadata": { "id": "Dc9VYOiUQA7B" @@ -783,7 +1082,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "id": "5E3a3dkJ5ZQD", "metadata": { "colab": { @@ -792,7 +1091,18 @@ "id": "5E3a3dkJ5ZQD", "outputId": "9c49972e-d87b-47f8-b17a-92c616d14f3f" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['Egypt was producing 691,000 bbl/d of oil and 2,141.05 Tcf of natural gas (in 2013), which makes Egypt as the largest oil producer not member of the Organization of the Petroleum Exporting Countries (OPEC) and the second-largest dry natural gas producer in Africa. In 2013, Egypt was the largest consumer of oil and natural gas in Africa, as more than 20% of total oil consumption and more than 40% of total dry natural gas consumption in Africa. Also, Egypt possesses the largest oil refinery capacity in Africa 726,000 bbl/d (in 2012). Egypt is currently planning to build its first nuclear power plant in El Dabaa city, northern Egypt.']" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "question = \"How much oil is Egypt producing in a day?\"\n", "context = get_context(question, top_k = 1)\n", @@ -811,7 +1121,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "id": "DQ4GWdbMSjPl", "metadata": { "colab": { @@ -820,7 +1130,29 @@ "id": "DQ4GWdbMSjPl", "outputId": "73eabb60-e42a-4983-ed7f-a90e51eb9781" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'answer': '691,000 bbl/d',\n", + " 'context': 'Egypt was producing 691,000 bbl/d of oil and 2,141.05 Tcf of '\n", + " 'natural gas (in 2013), which makes Egypt as the largest oil '\n", + " 'producer not member of the Organization of the Petroleum '\n", + " 'Exporting Countries (OPEC) and the second-largest dry natural '\n", + " 'gas producer in Africa. In 2013, Egypt was the largest consumer '\n", + " 'of oil and natural gas in Africa, as more than 20% of total oil '\n", + " 'consumption and more than 40% of total dry natural gas '\n", + " 'consumption in Africa. Also, Egypt possesses the largest oil '\n", + " 'refinery capacity in Africa 726,000 bbl/d (in 2012). Egypt is '\n", + " 'currently planning to build its first nuclear power plant in El '\n", + " 'Dabaa city, northern Egypt.',\n", + " 'end': 33,\n", + " 'score': 0.9999855201981802,\n", + " 'start': 20}]\n" + ] + } + ], "source": [ "extract_answer(question, context)" ] @@ -837,7 +1169,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "id": "_4NRgV4mGWoj", "metadata": { "colab": { @@ -846,7 +1178,27 @@ "id": "_4NRgV4mGWoj", "outputId": "4140fe3e-32b9-42ad-8631-303d07df6dda" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'answer': 'Hurley and Chen',\n", + " 'context': 'According to a story that has often been repeated in the media, '\n", + " 'Hurley and Chen developed the idea for YouTube during the early '\n", + " 'months of 2005, after they had experienced difficulty sharing '\n", + " \"videos that had been shot at a dinner party at Chen's apartment \"\n", + " 'in San Francisco. Karim did not attend the party and denied that '\n", + " 'it had occurred, but Chen commented that the idea that YouTube '\n", + " 'was founded after a dinner party \"was probably very strengthened '\n", + " 'by marketing ideas around creating a story that was very '\n", + " 'digestible\".',\n", + " 'end': 79,\n", + " 'score': 0.9999276399612427,\n", + " 'start': 64}]\n" + ] + } + ], "source": [ "question = \"What are the first names of the men that invented youtube?\"\n", "context = get_context(question, top_k=1)\n", @@ -855,7 +1207,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "id": "juXlctWgJgMF", "metadata": { "colab": { @@ -864,7 +1216,27 @@ "id": "juXlctWgJgMF", "outputId": "e25d311a-5ff5-4b5a-f1f2-f07bf606a076" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'answer': 'his theories of special relativity and general relativity',\n", + " 'context': 'Albert Einstein is known for his theories of special relativity '\n", + " 'and general relativity. He also made important contributions to '\n", + " 'statistical mechanics, especially his mathematical treatment of '\n", + " 'Brownian motion, his resolution of the paradox of specific '\n", + " 'heats, and his connection of fluctuations and dissipation. '\n", + " 'Despite his reservations about its interpretation, Einstein also '\n", + " 'made contributions to quantum mechanics and, indirectly, quantum '\n", + " 'field theory, primarily through his theoretical studies of the '\n", + " 'photon.',\n", + " 'end': 86,\n", + " 'score': 0.9500380754470825,\n", + " 'start': 29}]\n" + ] + } + ], "source": [ "question = \"What is Albert Eistein famous for?\"\n", "context = get_context(question, top_k=1)\n", @@ -883,7 +1255,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "id": "iXACn71xmett", "metadata": { "colab": { @@ -892,7 +1264,60 @@ "id": "iXACn71xmett", "outputId": "18463177-9144-4145-ef00-1bef3ae175c4" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'answer': 'Armstrong',\n", + " 'context': 'The trip to the Moon took just over three days. After achieving '\n", + " 'orbit, Armstrong and Aldrin transferred into the Lunar Module, '\n", + " 'named Eagle, and after a landing gear inspection by Collins '\n", + " 'remaining in the Command/Service Module Columbia, began their '\n", + " 'descent. After overcoming several computer overload alarms '\n", + " 'caused by an antenna switch left in the wrong position, and a '\n", + " 'slight downrange error, Armstrong took over manual flight '\n", + " 'control at about 180 meters (590 ft), and guided the Lunar '\n", + " 'Module to a safe landing spot at 20:18:04 UTC, July 20, 1969 '\n", + " '(3:17:04 pm CDT). The first humans on the Moon would wait '\n", + " 'another six hours before they ventured out of their craft. At '\n", + " '02:56 UTC, July 21 (9:56 pm CDT July 20), Armstrong became the '\n", + " 'first human to set foot on the Moon.',\n", + " 'end': 80,\n", + " 'score': 0.9998037815093994,\n", + " 'start': 71},\n", + " {'answer': 'Aldrin',\n", + " 'context': 'The first step was witnessed by at least one-fifth of the '\n", + " 'population of Earth, or about 723 million people. His first '\n", + " \"words when he stepped off the LM's landing footpad were, \"\n", + " '\"That\\'s one small step for [a] man, one giant leap for '\n", + " 'mankind.\" Aldrin joined him on the surface almost 20 minutes '\n", + " 'later. Altogether, they spent just under two and one-quarter '\n", + " 'hours outside their craft. The next day, they performed the '\n", + " 'first launch from another celestial body, and rendezvoused back '\n", + " 'with Columbia.',\n", + " 'end': 246,\n", + " 'score': 0.7011016499018297,\n", + " 'start': 240},\n", + " {'answer': 'Frank Borman',\n", + " 'context': 'On December 21, 1968, Frank Borman, James Lovell, and William '\n", + " 'Anders became the first humans to ride the Saturn V rocket into '\n", + " 'space on Apollo 8. They also became the first to leave low-Earth '\n", + " 'orbit and go to another celestial body, and entered lunar orbit '\n", + " 'on December 24. They made ten orbits in twenty hours, and '\n", + " 'transmitted one of the most watched TV broadcasts in history, '\n", + " 'with their Christmas Eve program from lunar orbit, that '\n", + " 'concluded with a reading from the biblical Book of Genesis. Two '\n", + " 'and a half hours after the broadcast, they fired their engine to '\n", + " 'perform the first trans-Earth injection to leave lunar orbit and '\n", + " 'return to the Earth. Apollo 8 safely landed in the Pacific ocean '\n", + " \"on December 27, in NASA's first dawn splashdown and recovery.\",\n", + " 'end': 34,\n", + " 'score': 0.5020979959517717,\n", + " 'start': 22}]\n" + ] + } + ], "source": [ "question = \"Who was the first person to step foot on the moon?\"\n", "context = get_context(question, top_k=3)\n", @@ -911,7 +1336,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "id": "d83f9f55-b099-4280-a12e-1d0192f4f5aa", "metadata": {}, "outputs": [], @@ -926,6 +1351,60 @@ "source": [ "### Add a few more questions. What did you observe?" ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "e206527a", + "metadata": {}, + "outputs": [], + "source": [ + "index_name = \"question-answering\"\n", + "if index_name not in pc.list_indexes().names():\n", + " pc.create_index(\n", + " name=index_name,\n", + " dimension=384,\n", + " metric=\"cosine\",\n", + " spec=ServerlessSpec(cloud=\"aws\", region=\"us-east-1\")\n", + " )\n", + "index = pc.Index(index_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "783af4e1", + "metadata": {}, + "outputs": [], + "source": [ + "question = \"Who create the moon?\"\n", + "context = get_context(question, top_k=3)\n", + "extract_answer(question, context)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4b12d2b", + "metadata": {}, + "outputs": [], + "source": [ + "question = \"who was the creator of Jabon Rey the Colombian brand?\"\n", + "context = get_context(question, top_k=5)\n", + "extract_answer(question, context)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e4f137e", + "metadata": {}, + "outputs": [], + "source": [ + "question = \"what year the babilonian's died all together?\"\n", + "context = get_context(question, top_k=3)\n", + "extract_answer(question, context)" + ] } ], "metadata": { @@ -942,9 +1421,9 @@ }, "gpuClass": "standard", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3.11 (langchain-lesson)", "language": "python", - "name": "python3" + "name": "langchain-lesson" }, "language_info": { "codemirror_mode": { @@ -956,7 +1435,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.11.13" }, "papermill": { "default_parameters": {}, @@ -970,11 +1449,6 @@ "start_time": "2021-04-15T21:06:38.122812", "version": "2.3.3" }, - "vscode": { - "interpreter": { - "hash": "5fe10bf018ef3e697f9035d60bf60847932a12bface18908407fd371fe880db9" - } - }, "widgets": { "application/vnd.jupyter.widget-state+json": { "00b344135da443ac90e6e6a0f53cfe0f": {