diff --git a/.gitignore b/.gitignore index bb71e3b..f92bfe3 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ qdrant_101_image_data/image_search_app.py .venv/ */.DS_Store +.claude/ diff --git a/multivector-turbo4/Multivector_Turbo4.ipynb b/multivector-turbo4/Multivector_Turbo4.ipynb new file mode 100644 index 0000000..0832494 --- /dev/null +++ b/multivector-turbo4/Multivector_Turbo4.ipynb @@ -0,0 +1,1513 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "version_major": 2, + "version_minor": 0, + "state": { + "bfcc824d037b49958905fa6723e3036a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_4793bc5ea4fd4e168fb7209b5fef5efd", + "IPY_MODEL_d81107d1e2d0490a96f9a8bd25c3e8c8", + "IPY_MODEL_05691e91ee47419cbc576f665bcc3495" + ], + "layout": "IPY_MODEL_abdaa184152d4633b701a6b5258ec242" + } + }, + "4793bc5ea4fd4e168fb7209b5fef5efd": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_1ad6275878314d0184e4d8d638948b52", + "placeholder": "​", + "style": "IPY_MODEL_afda0da11be045ce980c86b0ca00885c", + "value": "Download complete: : " + } + }, + "d81107d1e2d0490a96f9a8bd25c3e8c8": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_0d0c5e2fe01149ecb9bb59c8bb8603dc", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_2dffcf32a8b648869367ddba6afce4d5", + "value": 0 + } + }, + "05691e91ee47419cbc576f665bcc3495": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_7fe259725e124625984af9ee863c9cda", + "placeholder": "​", + "style": "IPY_MODEL_278a210a07564eef917799c512bc7209", + "value": "  0.00B            " + } + }, + "abdaa184152d4633b701a6b5258ec242": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "1ad6275878314d0184e4d8d638948b52": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "afda0da11be045ce980c86b0ca00885c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "0d0c5e2fe01149ecb9bb59c8bb8603dc": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "20px" + } + }, + "2dffcf32a8b648869367ddba6afce4d5": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "7fe259725e124625984af9ee863c9cda": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "278a210a07564eef917799c512bc7209": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "0e2f084b9eb04577aa1f4fc1c494415a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_6f7af866011145cf8af9b86b5bbe8d04", + "IPY_MODEL_ea566d7d78f44b90bc58c909c867b9ad", + "IPY_MODEL_454ff35f531b444bbbc0381064445892" + ], + "layout": "IPY_MODEL_3cd2998ca29649958e0aca5f3c7949d1" + } + }, + "6f7af866011145cf8af9b86b5bbe8d04": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_955d5555ca4148e3b106abe76756aec6", + "placeholder": "​", + "style": "IPY_MODEL_7c66fbb17a364db6a297f2812c66b657", + "value": "Reconstruction complete: " + } + }, + "ea566d7d78f44b90bc58c909c867b9ad": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_82af8dc0f66c44dcbbed82a589043bbb", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_f947d53f83244cb29b1287dae9178eea", + "value": 0 + } + }, + "454ff35f531b444bbbc0381064445892": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a1cff3e5c0e54b4999ac55cca3c5c373", + "placeholder": "​", + "style": "IPY_MODEL_aa534ac616d44de9bc5744984ecbe138", + "value": "  0.00B /  0.00B            " + } + }, + "3cd2998ca29649958e0aca5f3c7949d1": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "955d5555ca4148e3b106abe76756aec6": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7c66fbb17a364db6a297f2812c66b657": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "82af8dc0f66c44dcbbed82a589043bbb": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "20px" + } + }, + "f947d53f83244cb29b1287dae9178eea": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "a1cff3e5c0e54b4999ac55cca3c5c373": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "aa534ac616d44de9bc5744984ecbe138": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "08f89441642b4dae97bb81d0e1007015": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_b76a532bc01b4fc9920e4b45aed3fbde", + "IPY_MODEL_8c79eda0aa304edba9edf596f417f00e", + "IPY_MODEL_2fd541e934234dc7a57f21b78856f8d1" + ], + "layout": "IPY_MODEL_8b16515f5d4e4555b8178fb3066f04e8" + } + }, + "b76a532bc01b4fc9920e4b45aed3fbde": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_2c3a7d0e6cf74e9dbc97feb46a6a31e1", + "placeholder": "​", + "style": "IPY_MODEL_f93876be57fd4714bd4d82f7f7f78ed0", + "value": "Fetching 1 files: 100%" + } + }, + "8c79eda0aa304edba9edf596f417f00e": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_d14faf82ef304e448db0b4974d2aba42", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_f2d44bb90e0b4a889791234213ed123c", + "value": 1 + } + }, + "2fd541e934234dc7a57f21b78856f8d1": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_1e803a96417a497db0c20827eedd1411", + "placeholder": "​", + "style": "IPY_MODEL_ddb469d24d194e5fa7b72c3d6471b78a", + "value": " 1/1 [00:00<00:00, 52.04it/s]" + } + }, + "8b16515f5d4e4555b8178fb3066f04e8": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "2c3a7d0e6cf74e9dbc97feb46a6a31e1": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "f93876be57fd4714bd4d82f7f7f78ed0": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "d14faf82ef304e448db0b4974d2aba42": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "f2d44bb90e0b4a889791234213ed123c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "1e803a96417a497db0c20827eedd1411": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "ddb469d24d194e5fa7b72c3d6471b78a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + } + } + } + } + }, + "cells": [ + { + "cell_type": "markdown", + "source": "# Multivector Search Using the `turbo4` Datatype\n\nAs of [Qdrant 1.19](https://qdrant.tech/blog/qdrant-1.19.x/), Qdrant supports the `turbo4` datatype, which stores dense vectors on disk as 4-bit values per dimension instead of the 32 bits per dimension that `float32` uses, at some cost to recall.\n\nThis is possible thanks to [Google's TurboQuant](https://research.google/blog/turboquant-redefining-ai-efficiency-with-extreme-compression/) quantization technique: each vector is mathematically rotated so its information spreads evenly across all dimensions, which keeps the loss during compression low. Each rotated value is then stored as one of 16 levels, which fits in 4 bits and shrinks the vector to an eighth of its original size.\n\n`turbo4` is inspired by this quantization method, but it is a **standalone data type** that you can quantize further. For example, you can combine `turbo4` with 1-bit TurboQuant quantization.\n\n`turbo4` also works with multivector representations, and that is what this notebook demonstrates.", + "metadata": { + "id": "wryi4MlW8XBx" + } + }, + { + "cell_type": "markdown", + "source": "## Setup\n\nWe will use [Qdrant Cloud Inference](https://qdrant.tech/documentation/cloud/inference/) to generate embeddings and [Qdrant collections](https://qdrant.tech/documentation/concepts/collections/) to store them, so the `qdrant-client` package is the only Qdrant dependency we need.\n\nWe will also use `huggingface-hub` and `polars` to download and process the dataset.", + "metadata": { + "id": "cwAxHKCf_QDd" + } + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "SxlWeHGa8SmW" + }, + "outputs": [], + "source": [ + "! pip -q install qdrant-client huggingface-hub polars httpx" + ] + }, + { + "cell_type": "markdown", + "source": "## Dataset\n\nWe will download the [`McAuley-Lab/Amazon-Reviews-2023`](https://huggingface.co/datasets/McAuley-Lab/Amazon-Reviews-2023) dataset, specifically its `Pet_Supplies` category, and load it with Polars.", + "metadata": { + "id": "YxrCxatGEFK4" + } + }, + { + "cell_type": "code", + "source": [ + "from huggingface_hub import snapshot_download\n", + "\n", + "path = snapshot_download(\n", + " \"McAuley-Lab/Amazon-Reviews-2023\",\n", + " repo_type=\"dataset\",\n", + " allow_patterns=[\"raw/meta_categories/meta_Pet_Supplies.jsonl\"],\n", + ")\n", + "\n", + "print(path)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 131, + "referenced_widgets": [ + "bfcc824d037b49958905fa6723e3036a", + "4793bc5ea4fd4e168fb7209b5fef5efd", + "d81107d1e2d0490a96f9a8bd25c3e8c8", + "05691e91ee47419cbc576f665bcc3495", + "abdaa184152d4633b701a6b5258ec242", + "1ad6275878314d0184e4d8d638948b52", + "afda0da11be045ce980c86b0ca00885c", + "0d0c5e2fe01149ecb9bb59c8bb8603dc", + "2dffcf32a8b648869367ddba6afce4d5", + "7fe259725e124625984af9ee863c9cda", + "278a210a07564eef917799c512bc7209", + "0e2f084b9eb04577aa1f4fc1c494415a", + "6f7af866011145cf8af9b86b5bbe8d04", + "ea566d7d78f44b90bc58c909c867b9ad", + "454ff35f531b444bbbc0381064445892", + "3cd2998ca29649958e0aca5f3c7949d1", + "955d5555ca4148e3b106abe76756aec6", + "7c66fbb17a364db6a297f2812c66b657", + "82af8dc0f66c44dcbbed82a589043bbb", + "f947d53f83244cb29b1287dae9178eea", + "a1cff3e5c0e54b4999ac55cca3c5c373", + "aa534ac616d44de9bc5744984ecbe138", + "08f89441642b4dae97bb81d0e1007015", + "b76a532bc01b4fc9920e4b45aed3fbde", + "8c79eda0aa304edba9edf596f417f00e", + "2fd541e934234dc7a57f21b78856f8d1", + "8b16515f5d4e4555b8178fb3066f04e8", + "2c3a7d0e6cf74e9dbc97feb46a6a31e1", + "f93876be57fd4714bd4d82f7f7f78ed0", + "d14faf82ef304e448db0b4974d2aba42", + "f2d44bb90e0b4a889791234213ed123c", + "1e803a96417a497db0c20827eedd1411", + "ddb469d24d194e5fa7b72c3d6471b78a" + ] + }, + "id": "riWz-wXuB56B", + "outputId": "154e1198-f5b8-4807-887c-b744197f093f" + }, + "execution_count": 2, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Downloading bytes: | 0.00B " + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "bfcc824d037b49958905fa6723e3036a" + } + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Reconstructing (incomplete total...): | | 0.00B / 0.00B " + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "0e2f084b9eb04577aa1f4fc1c494415a" + } + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Fetching 1 files: 0%| | 0/1 [00:00 0) & (pl.col(\"description\").list.len() > 0))\n", + "print(f\"Dataset size: {df.height}\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "8E4DcpVCDo98", + "outputId": "492f3b78-3ef8-402c-9ce7-9a7d817905be" + }, + "execution_count": 18, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Dataset size: 49310\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": "# Create a Qdrant Collection\n\nFirst, create a [Qdrant cluster](https://qdrant.tech/documentation/cloud/create-cluster/#standard-clusters), save its URL and API key, and use them to instantiate the Qdrant client.", + "metadata": { + "id": "0otP2AXEJ3X_" + } + }, + { + "cell_type": "code", + "source": [ + "from qdrant_client import AsyncQdrantClient\n", + "from getpass import getpass\n", + "\n", + "client = AsyncQdrantClient(\n", + " url=getpass(\"Qdrant URL: \"),\n", + " api_key=getpass(\"Qdrant API key: \"),\n", + " timeout=600,\n", + " cloud_inference=True,\n", + ")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "EfqK_EoKKTAR", + "outputId": "fb6d2d3f-3920-4d53-cd89-22ce8a3e6f21" + }, + "execution_count": 31, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Qdrant URL: ··········\n", + "Qdrant API key: ··········\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": "Now let's create a collection with the different vectors we will search over, using `turbo4` as the datatype for the dense vectors.\n\nNote that the `description` vector sets `multivector_config` with `MAX_SIM` as the comparator. This tells Qdrant to score each document by its best-matching token pair, which is how ColBERT's late-interaction retrieval works.", + "metadata": { + "id": "HS_GUHWYMb0Y" + } + }, + { + "cell_type": "code", + "source": [ + "from qdrant_client import models\n", + "\n", + "await client.create_collection(\n", + " collection_name=\"pet_supplies\",\n", + " vectors_config={\n", + " \"description\": models.VectorParams(\n", + " size=96,\n", + " distance=models.Distance.COSINE,\n", + " multivector_config=models.MultiVectorConfig(\n", + " comparator=models.MultiVectorComparator.MAX_SIM\n", + " ),\n", + " datatype=models.Datatype.TURBO4,\n", + " ),\n", + " \"image\": models.VectorParams(\n", + " size=512,\n", + " distance=models.Distance.COSINE,\n", + " datatype=models.Datatype.TURBO4,\n", + " ),\n", + " },\n", + " sparse_vectors_config={\n", + " \"title\": models.SparseVectorParams(modifier=models.Modifier.IDF)\n", + " }\n", + ")" + ], + "metadata": { + "id": "SbvPWkHwMa-g" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": "## Upload Data\n\nWith the collection created, we can upload the data and let Cloud Inference embed it server-side, so we never have to load an embedding model locally.", + "metadata": { + "id": "bFnNcCsQOC2d" + } + }, + { + "cell_type": "code", + "source": [ + "import uuid\n", + "from typing import Any\n", + "\n", + "\n", + "def get_image(img_dict: dict[str, Any]) -> str:\n", + " try:\n", + " return img_dict[\"large\"]\n", + " except KeyError:\n", + " return img_dict[next(iter(img_dict))]\n", + "\n", + "for batch in df.iter_slices(1):\n", + " points = [\n", + " models.PointStruct(\n", + " id=str(uuid.uuid4()),\n", + " vector={\n", + " \"description\": models.Document(\n", + " text=\"\\n\".join(row[\"description\"]),\n", + " model=\"answerdotai/answerai-colbert-small-v1\",\n", + " ),\n", + " \"image\": models.Image(\n", + " image=get_image(row[\"images\"][0]),\n", + " model=\"qdrant/clip-vit-b-32-vision\"\n", + " ),\n", + " \"title\": models.Document(\n", + " text=row[\"title\"],\n", + " model=\"qdrant/bm25\"\n", + " )\n", + " },\n", + " payload={\n", + " \"price\": row[\"price\"],\n", + " \"details\": row[\"details\"],\n", + " \"title\": row[\"title\"],\n", + " \"image\": get_image(row[\"images\"][0]),\n", + " \"description\": \"\\n\".join(row[\"description\"]),\n", + " },\n", + " )\n", + " for row in batch.iter_rows(named=True)\n", + " ]\n", + " await client.upsert(collection_name=\"pet_supplies\", points=points)" + ], + "metadata": { + "id": "4-k3RftzMYnp" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": "## Querying\n\nNow let's query the data. We will [prefetch](https://qdrant.tech/documentation/concepts/hybrid-queries/#query-api) candidates using either the image or the title vector, then re-score them with the ColBERT `description` vector through late interaction.", + "metadata": { + "id": "rEb4Qb2IXFhe" + } + }, + { + "cell_type": "code", + "source": [ + "query = \"Orijen dry cat food\"\n", + "image_query = models.Document(\n", + " text=query,\n", + " model=\"qdrant/clip-vit-b-32-text\"\n", + ")\n", + "title_query = models.Document(\n", + " text=query,\n", + " model=\"qdrant/bm25\",\n", + ")\n", + "colbert_query = models.Document(\n", + " text=query,\n", + " model=\"answerdotai/answerai-colbert-small-v1\"\n", + ")" + ], + "metadata": { + "id": "CFSPSSieYg0J" + }, + "execution_count": 47, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "response = await client.query_points(\n", + " collection_name=\"pet_supplies\",\n", + " prefetch=models.Prefetch(\n", + " query=image_query,\n", + " using=\"image\"\n", + " ),\n", + " query=colbert_query,\n", + " limit=1,\n", + " with_payload=True,\n", + " using=\"description\"\n", + ")" + ], + "metadata": { + "id": "aBNPEy6FaYi5" + }, + "execution_count": 51, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "result = response.points[0]\n", + "\n", + "print(result.payload[\"title\"])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "H1k-POplbF6a", + "outputId": "18e1090e-899d-4c11-82a3-261da35b6412" + }, + "execution_count": 52, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "ORIJEN® Dry Adult Cat Food, Grain Free, Premium, High Protein, Fresh & Raw Animal Ingredients, Guardian 8, 10lb\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "import httpx\n", + "\n", + "from io import BytesIO\n", + "from PIL import Image\n", + "\n", + "image_url = result.payload[\"image\"]\n", + "\n", + "\n", + "async with httpx.AsyncClient() as http_client:\n", + " img_resp = await http_client.get(image_url)\n", + " img_resp.raise_for_status()\n", + " content = img_resp.content\n", + "\n", + "Image.open(BytesIO(content))" + ], + "metadata": { + "id": "o1hfk9iUciJM" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "response_bm25 = await client.query_points(\n", + " collection_name=\"pet_supplies\",\n", + " prefetch=models.Prefetch(\n", + " query=title_query,\n", + " using=\"title\"\n", + " ),\n", + " query=colbert_query,\n", + " limit=10,\n", + " with_payload=True,\n", + " using=\"description\"\n", + ")" + ], + "metadata": { + "id": "jOQ5_eeqcKTD" + }, + "execution_count": 55, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from textwrap import wrap\n", + "\n", + "result_bm25 = response_bm25.points[0]\n", + "\n", + "print(result_bm25.payload[\"title\"])\n", + "print()\n", + "print(\"\\n\".join(wrap(result_bm25.payload[\"description\"])))" + ], + "metadata": { + "id": "d9XhPjOYdDSG" + }, + "execution_count": null, + "outputs": [] + } + ] +}