Ce projet est super tôt, pas prêt pour la production.
Store de vecteur sans serveur, léger et rapide au-dessus de DynamoDB
Whiplash est un magasin vectoriel léger construit sur AWS DynamoDB. Il utilise une variante de hachage sensible à la localité (LSH) pour indexer les vecteurs dans une table DynamoDB. Ceci est destiné à être un magasin vectoriel mimimaliste, évolutif et rapide et est destiné à être extrêmement facile à utiliser, à maintenir et à s'auto-hôte.
Il y a plusieurs composants principaux à Whiplash:
pip install whiplash-client
# OR
poetry add whiplash-clientnpm install -g serverless
serverless install --url https://github.com/ericmillsio/whiplash
cd whiplash
npm installPréparez-vous au déploiement:
cp .env.example .env
# Change AWS_PROFILE within .env to your AWS profile
# Adjust other values if you wantDéployer sur AWS:
serverless deploy --stage dev --region us-east-2La sortie attendue est inférieure. Notez la clé API pour l'accès et les points de terminaison à utiliser.
Running " serverless " from node_modules
Deploying whiplash to stage dev (us-east-2)
✔ Service deployed to stack whiplash-dev (64s)
api keys:
dev-api-key: < YOUR API KEY WILL BE HERE >
endpoints:
GET - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}
POST - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects
GET - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects
POST - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}/collections
GET - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}/collections
GET - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}/collections/{collectionId}
POST - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}/collections/{collectionId}/items
POST - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}/collections/{collectionId}/items/batch
GET - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}/collections/{collectionId}/items/{itemId}
GET - https://API_ID.execute-api.us-east-2.amazonaws.com/dev/projects/{projectId}/collections/{collectionId}/search
functions:
getProject: whiplash-dev-getProject (12 kB)
createProject: whiplash-dev-createProject (12 kB)
listProjects: whiplash-dev-listProjects (12 kB)
createCollection: whiplash-dev-createCollection (12 kB)
listCollections: whiplash-dev-listCollections (12 kB)
getCollection: whiplash-dev-getCollection (12 kB)
createItem: whiplash-dev-createItem (12 kB)
createItems: whiplash-dev-createItems (12 kB)
getItem: whiplash-dev-getItem (12 kB)
searchItems: whiplash-dev-searchItems (12 kB)Il existe trois façons d'utiliser WHUPLASH: en tant que client direct, en tant qu'API sans serveur, ou en tant que bibliothèque se proxyant via l'API.
La bibliothèque est le moyen le plus flexible d'utiliser le coup de lapin. Il peut être utilisé dans n'importe quel projet Python et peut être utilisé pour créer des applications personnalisées au-dessus du Whiplash sans déployer l'API. Il gérera directement les tables. Il est recommandé d'être utilisé à l'intérieur de l'AWS pour éviter la latence du réseau, mais peut être utilisé à l'extérieur pour les tests / évaluations.
import numpy as np
from whiplash import Vector , Whiplash
# AWS_PROFILE must be set in environment variables for boto3
whiplash = Whiplash ( "us-east-2" , "dev" )
# First time only setup
whiplash . setup ()
collection = whiplash . create_collection ( "test_collection" , n_features = 3 )
# Insert a vector
item = Vector ( "some_id" , np . ndarray ([ 1 , 2 , 3 ]))
collection . insert ( item )
# Search for the inserted vector
result = collection . search ( item . vector , limit = 1 )L'API sans serveur est un microservice entièrement fonctionnel et peut être déployé sur AWS avec quelques commandes. L'API est construite à l'aide de Serverless et AWS Lambda.
Points de terminaison API:
/projects/projects/{projectId}/projects/{projectId}/collections/projects/{projectId}/collections/{collectionId}/projects/{projectId}/collections/{collectionId}/items/projects/{projectId}/collections/{collectionId}/items/{itemId}/projects/{projectId}/collections/{collectionId}/searchEn-têtes obligatoires:
x-api-key: API_KEYContent-Type: application/jsonVous pouvez choisir d'interagir directement avec l'API ou d'utiliser la bibliothèque client Whiplash. Un fichier api.yaml est inclus dans le projet à utiliser avec Postman ou Insomnia.
La bibliothèque peut être utilisée pour proxy via l'API. Ceci est recommandé si vous souhaitez utiliser une bibliothèque mais que vous ne souhaitez pas gérer directement les tables. Ceci est plus stable et probablement plus rapide que la bibliothèque client directe pour les opérations d'insertion en vrac, mais plus lente pour les opérations d'insertion unique (en supposant que vous appelez de l'extérieur de la région AWS).
Cela ne peut être utilisé que si l'API est déployée. Cela évite également la dépendance Numpy, mais je n'ai pas encore éclaté les packages.
import time
from whiplash . api . client import Whiplash
query = [ 0.5472 ,...]
whiplash = Whiplash (
"https://API-ID.execute-api.us-east-2.amazonaws.com/STAGE" ,
"API_KEY" ,
)
collection = whiplash . get_collection ( "example" )
assert collection is not None
start = time . time ()
results = collection . search ( query )
print ( "Search took" , time . time () - start , "seconds" )
print ( "Results:" , results )Whiplash utilise le hachage sensible à la localité (LSH) pour indexer les vecteurs dans une table DynamoDB. Ceci est destiné à être un magasin vectoriel mimimaliste, évolutif et rapide construit au-dessus de l'infrastructure de qualité de production AWS.
Le lapin de lapin varie de la LSH traditionnelle en ce qu'il utilise un nombre différent de bits pour chaque clé de hachage. Cela permet un réglage dynamique et automatique du nombre de seaux, ce qui donne une flexibilité à la mise à l'échelle de l'index au fil du temps. Lorsque des seaux sur la plus petite touche de hachage sont proches de la taille maximale d'un élément DynamoDB, une nouvelle couche de fonction de hachage / touches est ajoutée.
Whiplash utilise plusieurs tables de dynamo pour stocker les vecteurs et les seaux:
PROJECT_STAGE_COLLECTION_vectors - stocke le { vector_id: binary(vector) }PROJECT_STAGE_COLLECTION_buckets - stocke le { hash: set of vector_ids }whiplash_metadata - Stocke les métadonnées à propos de chaque collection { collection_id: { n_features: 256, uniform_planes: {0: [binary]} ...} }Le coup de lapin utilise une projection aléatoire pour les vecteurs de hachage en seaux. Les vecteurs sont projetés sur un ensemble de plans aléatoires, et le signe de la projection détermine de quel côté du plan dans lequel se trouve le vecteur. Les plans sont générés à l'aide de la distribution gaussienne pour garantir que les vecteurs sont répartis uniformément.
Les touches de hachage sont générées en convertissant le tableau des résultats booléens d'une projection aléatoire en une chaîne binaire, puis convertis en base 36.
poetry install
poetry run pytestWhiplash (et LSH en général) à des fins de recherche algorithmique approximative le plus proche du voisin (Ann) a des compromis par rapport aux magasins vectoriels actuels:
Avantages:
Inconvénients:
Je voulais construire cela parce que j'étais frustré par le coût élevé des magasins de vecteurs gérés et la complexité de l'auto-hébergement d'autres magasins de vecteurs open source. Il n'y a pas non plus de bonne solution sans serveur (même si AWS pousse Elasticsearch "sans serveur", UGH). Le coup de lapin est si simple et construit sur une infrastructure prête pour la production qui aura très peu de maintenance.
Comparaison du coût de stockage seul à Pinecone:
Pinone:
Coup de fouet:
Sans ordre particulier:
Si vous êtes Amazon et que vous souhaitez l'utiliser, veuillez me contacter et payer un tas d'argent à l'avance. Sinon, ceci est concédé sous licence sous Apache 2.0.