{ "cells": [ { "cell_type": "markdown", "id": "6a151ade-7d86-4a2e-bfe7-462089f4e04c", "metadata": {}, "source": [ "# Approach\n", "There are a number of aspects of choosing a vector db that might be unique to your situation. You should think through your HW, utilization, latency requirements, scale, etc before choosing. \n", "\n", "Im targeting a demo (low utilization, latency can be relaxed) that will live on a huggingface space. I have a small scale that could even fit in memory. I like [Qdrant](https://qdrant.tech) for this. " ] }, { "cell_type": "markdown", "id": "b1b28232-b65d-41ce-88de-fd70b93a528d", "metadata": {}, "source": [ "# Imports" ] }, { "cell_type": "code", "execution_count": 1, "id": "88408486-566a-4791-8ef2-5ee3e6941156", "metadata": { "tags": [] }, "outputs": [], "source": [ "from IPython.core.interactiveshell import InteractiveShell\n", "InteractiveShell.ast_node_interactivity = 'all'" ] }, { "cell_type": "code", "execution_count": 2, "id": "abb5186b-ee67-4e1e-882d-3d8d5b4575d4", "metadata": { "tags": [] }, "outputs": [], "source": [ "from pathlib import Path\n", "import json\n", "\n", "from tqdm.notebook import tqdm\n", "import lancedb" ] }, { "cell_type": "code", "execution_count": 3, "id": "c4b82ea2-8b30-4c2e-99f0-9a30f2f1bfb7", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/home/ec2-user/arabic-wiki\n" ] } ], "source": [ "proj_dir = Path.cwd().parent\n", "print(proj_dir)" ] }, { "cell_type": "markdown", "id": "76119e74-f601-436d-a253-63c5a19d1c83", "metadata": {}, "source": [ "# Config" ] }, { "cell_type": "code", "execution_count": 4, "id": "f6f74545-54a7-4f41-9f02-96964e1417f0", "metadata": { "tags": [] }, "outputs": [], "source": [ "files_in = list((proj_dir / 'data/embedded/').glob('*.ndjson'))" ] }, { "cell_type": "markdown", "id": "d2dd0df0-4274-45b3-9ee5-0205494e4d75", "metadata": { "tags": [] }, "source": [ "# Setup\n", "Read in our list of dictionaries. This is the upper end for the machine Im using. This takes ~10GB of RAM. We could easily do this in batches of ~100k and be fine in most machines. " ] }, { "cell_type": "code", "execution_count": 5, "id": "3c08e039-3686-4eca-9f87-7c469e3f19bc", "metadata": { "tags": [] }, "outputs": [], "source": [ "with open(files_in[0], 'r') as f:\n", " first_line = f.readline().strip() # read only the first line\n", " document = json.loads(first_line)\n", " document['vector'] = document.pop('embedding')" ] }, { "cell_type": "markdown", "id": "98aec715-8d97-439e-99c0-0eff63df386b", "metadata": {}, "source": [ "Convert the dictionaries to `Documents`" ] }, { "cell_type": "code", "execution_count": 6, "id": "4821e3c1-697d-4b69-bae3-300168755df9", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "{'content': 'الماء مادةٌ شفافةٌ عديمة اللون والرائحة، وهو المكوّن الأساسي للجداول والبحيرات والبحار والمحيطات وكذلك للسوائل في جميع الكائنات الحيّة، وهو أكثر المركّبات الكيميائيّة انتشاراً على سطح الأرض. يتألّف جزيء الماء من ذرّة أكسجين مركزية ترتبط بها ذرّتا هيدروجين على طرفيها برابطة تساهميّة بحيث تكون صيغته الكيميائية H2O. عند الظروف القياسية من الضغط ودرجة الحرارة يكون الماء سائلاً؛ أمّا الحالة الصلبة فتتشكّل عند نقطة التجمّد، وتدعى بالجليد؛ أمّا الحالة الغازية فتتشكّل عند نقطة الغليان، وتسمّى بخار الماء.\\nإنّ الماء هو أساس وجود الحياة على كوكب الأرض، وهو يغطّي 71% من سطحها، وتمثّل مياه البحار والمحيطات أكبر نسبة للماء على الأرض، حيث تبلغ حوالي 96.5%. وتتوزّع النسب الباقية بين المياه الجوفيّة وبين جليد المناطق القطبيّة (1.7% لكليهما)، مع وجود نسبة صغيرة على شكل بخار ماء معلّق في الهواء على هيئة سحاب (غيوم)، وأحياناً أخرى على هيئة ضباب أو ندى، بالإضافة إلى الزخات المطريّة أو الثلجيّة. تبلغ نسبة الماء العذب حوالي 2.5% فقط من الماء الموجود على الأرض، وأغلب هذه الكمّيّة (حوالي 99%) موجودة في الكتل الجليديّة في المناطق القطبيّة، في حين تتواجد 0.3% من الماء العذب في الأنهار والبحيرات وفي الغلاف الجوّي.\\nأما في الطبيعة، فتتغيّر حالة الماء بين الحالات الثلاثة للمادة على سطح الأرض باستمرار من خلال ما يعرف باسم الدورة المائيّة (أو دورة الماء)، والتي تتضمّن حدوث تبخّر ونتح (نتح تبخّري) ثم تكثيف فهطول ثم جريان لتصل إلى المصبّ في المسطّحات المائيّة.\\n',\n", " 'content_type': 'text',\n", " 'score': None,\n", " 'meta': {'id': '7',\n", " 'revid': '2080427',\n", " 'url': 'https://ar.wikipedia.org/wiki?curid=7',\n", " 'title': 'ماء',\n", " '_split_id': 0,\n", " '_split_overlap': [{'doc_id': '725ec671057ef790ad582509a8653584',\n", " 'range': [887, 1347]}]},\n", " 'id_hash_keys': ['content'],\n", " 'id': '109a29bb227b1aaa5b784e972d8e1e3e',\n", " 'vector': [-0.07318115,\n", " 0.087646484,\n", " 0.03274536,\n", " 0.034942627,\n", " 0.097961426,\n", " '...']}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "doc = document.copy()\n", "doc['vector'] = doc['vector'][:5] + ['...']\n", "doc" ] }, { "cell_type": "markdown", "id": "676f644c-fb09-4d17-89ba-30c92aad8777", "metadata": {}, "source": [ "Instantiate our `DocumentStore`. Note that Im saving this to disk, this is for portability which is good considering I want to move from this ec2 instance into a Hugging Face Space. \n", "\n", "Note that if you are doing this at scale, you should use a proper instance and not saving to file. You should also take a [measured ingestion](https://qdrant.tech/documentation/tutorials/bulk-upload/) approach instead of using a convenient loader. " ] }, { "cell_type": "code", "execution_count": 7, "id": "78033b87-8f68-4a44-899e-36fa8167cacf", "metadata": { "tags": [] }, "outputs": [], "source": [ "from lancedb.embeddings.registry import EmbeddingFunctionRegistry\n", "from lancedb.embeddings.sentence_transformers import SentenceTransformerEmbeddings\n", "\n", "\n", "db = lancedb.connect(proj_dir/\".lancedb\")\n", "tbl = db.create_table('arabic-wiki', [document])" ] }, { "cell_type": "code", "execution_count": 8, "id": "21d5fa58-519e-4a23-9fc6-eed31e4723b5", "metadata": { "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "789efc342218412aa31d5a5a74b34c52", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Wiki Files: 0%| | 0/23 [00:00