VectorFlow est un pipeline d'intégration de vecteur open source, débit élevé et tolérant à la défaut. Avec une simple demande d'API, vous pouvez envoyer des données brutes qui seront gunées, intégrées et stockées dans n'importe quelle base de données vectorielle ou renvoyée à vous.
Cette version actuelle est un MVP. Nous vous recommandons de l'utiliser avec Kubernetes en production (voir ci-dessous pour plus de détails). Pour les fichiers textuels, il prend en charge TXT, PDF, HTML et DOCX.
Avec trois commandes, vous pouvez exécuter VectorFlow localement:
git clone https://github.com/dgarnitz/vectorflow.git
cd vectorflow
./setup.sh
Pour commencer à intégrer des documents localement, installez la bibliothèque Python Client VectorFlow dans l'environnement virtuel de votre application Python.
pip install vectorflow-client
puis exécutez ce qui suit
from vectorflow-client.client.vectorflow import Vectorflow
vectorflow = Vectorflow()
vectorflow.embeddings_api_key = os.getenv("OPEN_AI_KEY")
paths = ['path_to_your_file1', 'path_to_your_file2', ...]
response = vectorflow.upload(paths)
Vous n'avez pas besoin de cloner le repo VectorFlow pour utiliser la fonctionnalité du client via PIP. Pour plus d'instructions, consultez le README.md dans le répertoire client .
Voir l'annexe pour plus de détails sur la façon d'utiliser les scripts testing_clients .
La meilleure façon d'exécuter VectorFlow est via docker compose . Si vous exécutez cela sur Mac, veuillez accorder aux autorisations Docker de lire dans votre dossier Documents comme indiqué ici. Si cela échoue, supprimez la section volume de docker-compose.yml .
Créez d'abord un dossier, env_scripts , dans la racine de toutes les variables d'environnement, puis créez env_vars.env dans le dossier env_scripts pour ajouter toutes les variables d'environnement mentionnées ci-dessous. Il vous suffit de définir la variable LOCAL_VECTOR_DB que si vous exécutez Qdrant, Milvus ou Weavate localement.
INTERNAL_API_KEY=your-choice
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=your-choice
POSTGRES_DB=vectorflow
POSTGRES_HOST=postgres
RABBITMQ_USERNAME=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_HOST=rabbitmq
LOCAL_VECTOR_DB=qdrant | weaviate
API_STORAGE_DIRECTORY=/tmp
MINIO_ACCESS_KEY=minio99
MINIO_SECRET_KEY=minio123
MINIO_ENDPOINT=minio:9000
MINIO_BUCKET=vectorflow
Vous pouvez choisir une variable pour INTERNAL_API_KEY , POSTGRES_PASSWORD et POSTGRES_DB , mais ils doivent être définis.
Assurez-vous de tirer le lapin MQ, Postgres, Min.io dans votre dépôt Docker local. Nous vous recommandons également d'exécuter une base de données vectorielle localement, alors assurez-vous de tirer l'image de celle que vous utilisez. Notre fichier docker-compose fera tourner QDRANT par défaut et créera deux index / collections. Si vous prévoyez d'exécuter milvus ou de vous faire passer, vous devrez les configurer par vous-même.
docker pull rabbitmq
docker pull postgres
docker pull qdrant/qdrant | docker pull semitechnologies/weaviate
docker pull minio/minio
Puis courez:
docker-compose build --no-cache
docker-compose up -d
Notez que les conteneurs init exécutent un script qui configure le schéma de base de données, le Vector DB et Min.io Object Store. Ces conteneurs s'arrêtent une fois le script terminé. Pour QDRANT, assurez-vous de tirer la version 1.9.1 car c'est la version avec laquelle le package Client Python QDRANT est censé fonctionner.
La meilleure façon d'utiliser VectorFlow est avec le client Python.
Pour utiliser VectorFlow pour le développement, faites une demande HTTP à l'URL de votre API - par exemple, localhost:8000 de votre machine de développement, ou vectorflow_api:8000 à partir d'un autre conteneur Docker.
Toutes les demandes nécessitent un en-tête HTTP avec une clé Authorization qui est la même que votre INTERNAL_API_KEY ENV VAR que vous avez défini auparavant (voir ci-dessus). Vous devez transmettre votre clé API de base de données vectorielle avec l'en-tête HTTP X-VectorDB-Key si vous exécutez une connexion à une instance basée sur X-EmbeddingAPI-Key cloud d'une base de base . Les incorporateurs de transformateurs de phrase à câlins ne nécessitent pas de clé API, mais vous devez suivre les étapes ci-dessus pour exécuter le conteneur avec le modèle dont vous avez besoin.
VectorFlow prend actuellement en charge les bases de données vectorielles de PineCone, QDrant et de Weavate.
Pour soumettre un seul fichier pour intégrer, faites une demande POST au point de terminaison /embed avec un fichier joint, l'en-tête 'Content-Type: multipart/form-data' et la charge utile suivante:
{
'SourceData=path_to_txt_file'
'LinesPerBatch=4096'
'EmbeddingsMetadata={
"embeddings_type": "OPEN_AI",
"chunk_size": 512,
"chunk_overlap": 128,
"chunk_strategy": "EXACT | PARAGRAPH | SENTENCE | CUSTOM",
"model": "text-embedding-3-small | text-embedding-3-large | text-embedding-ada-002"
}'
'VectorDBMetadata={
"vector_db_type": "PINECONE | QDRANT | WEAVIATE",
"index_name": "index_name",
"environment": "env_name"
}'
'DocumentID=your-optional-internal-tracking-id'
}
Cela créera un job et vous récupérerez la charge utile suivante:
{
'message': f"Successfully added {batch_count} batches to the queue",
'JobID': job_id
}
À l'heure actuelle, ce point de terminaison ne prend en charge que le téléchargement unique de fichiers à la fois, jusqu'à 25 Mo en raison de problèmes de délai d'attente. Notez qu'il peut être obsolète.
Pour soumettre plusieurs fichiers pour intégrer, faites une demande POST au point de terminaison /jobs . La charge utile est la même que pour l'intégration de fichiers unique, sauf la façon dont vous joignez plusieurs fichiers est différent:
{
'files=[
('file', ('test_pdf.pdf', open(file1_path, 'rb'), 'application/octet-stream')),
('file', ('test_medium_text.txt', open(file2_path, 'rb'), 'application/octet-stream'))
]'
}
Remarque: vous devez stream les fichiers sur le point de terminaison, pas l'envoyer en tant que demande de poste conventionnelle ou il échouera.
Ce point de terminaison créera un job par fichier téléchargé. Vous obtiendrez la charge utile JSON suivante:
{
'successful_uploads': successfully_uploaded_files,
'failed_uploads': failed_uploads,
'empty_files_count': empty_files_count,
'duplicate_files_count': duplicate_files_count
}
Lorsque cela successfully_uploaded_files est une liste de tuples contenant (file name, job id) et failed_uploads est une liste de noms de fichiers qui n'ont pas réussi à télécharger afin que vous puissiez les réessayer.
Pour vérifier l'état d'un job , faites une demande GET à ce point de terminaison: /jobs/<int:job_id>/status . La réponse sera dans la forme:
{
'JobStatus': job_status
}
Pour vérifier l'état du job multiples, faites une demande POST à ce point de terminaison: /jobs/status . Le corps de la demande sera sous la forme:
{
'JobIDs': job_ids
}
Et la réponse sera dans la forme
{
'Jobs': [{'JobID': job_id, 'JobStatus': job_status}, ...]}
Il y a un exemple dans testing_clients/get_jobs_by_ids.py .
VectorFlow applique un schéma standardisé pour télécharger des données dans un magasin vectoriel:
id: string
source_data: string
source_document: string
embeddings: float array
L'ID peut être utilisé pour la déduplication et l'iDEMPOCTY. Veuillez noter pour Weavate, l'ID est appelé vectorflow_id .
Nous prévoyons l'amortissement dans le futur proche pour prendre en charge les schémas détectés et / ou configurables dynamiquement sur la route.
Les Chunkers intégrés de VectorFlow comptent par le jeton et non par le caractère. Un chunk de VectorFlow est un dictionnaire qui a les clés suivantes:
text: str
vector: list[float]
Vous pouvez exécuter un Chunker personnalisé en ajoutant un fichier, custom_chunker.py , avec une méthode, chunker(source_data: list[str]) au répertoire src/worker avant de créer l'image Docker pour le travailleur. Ce morceau doit retourner une liste de dictionnaires chunk conformes à la norme ci-dessus.
Vous pouvez ajouter toutes les clés que vous souhaitez au dictionnaire chunk tant que sa sérialisable JSON , ce qui signifie aucune classe ou fonction personnalisée, types DateTimes ou références de code circulaire. Vous pouvez utiliser ce morceau personnalisé pour télécharger des métadonnées sur la base de données vectorielle avec le schéma que vous désirez.
Si vous souhaitez utiliser VectorFlow uniquement pour le groupe et la génération d'incorporation, passez un paramètre WebhookURL dans le corps de la demande /embed et une X-Webhook-Key comme en-tête. VectorFlow suppose qu'une clé WebHook est requise pour réécrire à n'importe quel point de terminaison. Les intérêts sont renvoyés avec les morceaux source du dictionnaire chunk décrits ci-dessus. Ceci est envoyé comme JSON avec le formulaire suivant:
{
'Embeddings': list[dict],
'DocumentID': str,
'JobID': int
}
Si vous souhaitez valider les morceaux que vous souhaitez intégrer, passez un paramètre ChunkValidationURL dans le corps de la demande /embed . Cela enverra la demande avec la charge utile JSON suivante, {"chunks": chunked_data} , où chunked_data est une liste de dictionnaires chunk . Il s'attendra à un JSON contenant des clés valid_chunks avec une liste de morceaux valides pour l'intégration. Ce point de terminaison sera délai après 30 secondes par défaut mais peut être configuré dans le code d'application.
VectorFlow est intégré à AWS S3. Vous pouvez passer une URL S3 pré-signée dans le corps du HTTP au lieu d'un fichier. Utilisez le champ Form PreSignedURL et appuyez sur le point de terminaison /s3 . Ce point de terminaison a la même configuration et restrictions que le point de terminaison /embed .
VectorFlow utilise Posthog pour collecter de manière anonyme des données sur l'utilisation. Cela ne recueille aucune information personnellement identifiable. Si vous souhaitez le désactiver cependant, ajoutez la variable Enviroment suivante à votre env_vars.env :
TELEMETRY_DISABLED=True
Vous pouvez exécuter VectorFlow localement dans Kubernetes avec Minikube en utilisant ./kube/scripts/deploy-local-k8s.sh , qui appliquera tous les fichiers YAML situés dans kube/ . Ce script ne fonctionnera pas si vous n'avez pas installé Docker, Minikube et Kubectl.
Ce script créera d'abord les images localement, puis les transférera dans Minikube. Si vous souhaitez vérifier les images disponibles dans Minikube, exécutez ce qui suit:
eval $(minikube docker-env)
docker images
Vous devrez exécuter minikube tunnel pour accéder aux ressources situées dans le cluster depuis votre machine de développement. Le script de configuration chargera les images de votre contexte Docker local dans celui de Minikube.
Vous pouvez utiliser les fichiers YAML dans kube/ AS base pour un déploiement de production, mais vous devrez personnaliser légèrement les besoins de votre cluster spécifique. Contactez-nous si vous avez besoin d'aide.
Nous aimons les commentaires de la communauté. Si vous avez une idée de la façon d'améliorer ce projet, nous vous encourageons à ouvrir un problème ou à rejoindre notre discorde. S'il vous plaît, étiquetez dgarnitz et danmeier2 .
Notre feuille de route est décrite dans la section ci-dessous et nous aimerions aider à le construire. Nos problèmes ouverts sont un excellent point de départ et peuvent être consultés ici. Si vous souhaitez travailler sur quelque chose qui ne soit pas répertorié, nous vous recommandons d'ouvrir un problème avec une approche proposée à l'esprit avant de soumettre un RP.
Veuillez marquer dgarnitz sur tous les PR et mettre à jour le ReadMe pour refléter vos modifications.
Lors de la soumission d'un PR, veuillez ajouter des tests d'unités pour couvrir les fonctionnalités que vous avez ajoutées. Veuillez réexaminer les tests existants pour vous assurer qu'il n'y a pas de bugs régressifs. Exécutez à partir du répertoire src . Pour exécuter une utilisation de test individuel:
python -m unittest module.tests.test_file.TestClass.test_method
Pour exécuter tous les tests dans le fichier Utilisez:
python -m unittest module.tests.test_file
Pour les tests de bout en bout, il est recommandé de construire et d'exécuter à l'aide du compose Docker, mais de retirer le conteneur que vous modifiez et de l'exécuter localement sur votre machine de développement. Cela évitera la nécessité de reconstruire constamment les images et de réinstaller les conteneurs. Assurez-vous de modifier les variables d'environnement dans votre terminal de machine de développement en valeurs correctes (c'est-à-dire localhost au lieu de rabbitmq ou postgres ) afin que les conteneurs Docker puissent communiquer avec votre machine de développement. Une fois qu'il fonctionne localement, vous pouvez effectuer un test final avec tout dans Docker-Compose.
Veuillez vérifier que tous les changements fonctionnent avec Docker-Compose avant d'ouvrir un PR.
Nous vous recommandons également d'ajouter des preuves de vérification, telles que des captures d'écran, qui montrent que votre code fonctionne dans un flux de bout en bout.
Un moyen facile d'utiliser VectorFlow est avec les clients de nos tests, situés dans testing_clients/ Directory. Il existe plusieurs scripts, avec différentes configurations pour le téléchargement de données de Qick. Nous recommandons à commencer par le testing_clients/standard_upload_client.py - l'exécution de ce script soumet un seul document à VectorFlow pour intégrer avec Open AI ADA et télécharger sur l'instance QDRANT locale. Vous pouvez modifier les valeurs pour correspondre à votre configuration. Pour télécharger plusieurs fichiers à la fois, utilisez le testing_clients/streaming_upload_client.py
Notez que la variable TESTING_ENV est l'équivalent du champ environment dans le VectorDBMetadata , qui correspond à un environnement de Pincone, une classe de Weavate, une collection dans QDRANT, etc. Le répertoire testing_clients a des exemples de scripts que vous pouvez suivre pour exécuter Vectorflow. Ajoutez vos clés d'intégration et de base de données au script env_scrips/env_vars.sh qui a été généré et définissez la variable filepath dans testing_clients/standard_upload_client.py pour pointer vers le fichier que vous souhaitez intégrer. Puis courez:
source env_scrips/env_vars.sh
python testing-clients/standard_upload_client.py
Pour télécharger plusieurs fichiers à la fois, utilisez le testing_clients/streaming_upload_client.py
Voir ci-dessus pour une description plus détaillée de la façon de configurer et de configurer manuellement le système. Veuillez noter que le script setup ne créera pas un environnement de développement sur votre machine, il configure et exécute uniquement le Docker-Compose. Nous ne conseillons pas d'utiliser VectorFlow sur Windows.
Pour effectuer une recherche, envoyez une demande de POST à /images/search de terminaison avec un fichier d'image joint, l'en-tête 'Content-Type: multipart/form-data' et le corps suivant:
{
'ReturnVectors': boolean,
'TopK': integer, less than 1000,
'VectorDBMetadata={
"vector_db_type": "PINECONE | QDRANT | WEAVIATE",
"index_name": "index_name",
"environment": "env_name"
}'
}
Toutes les demandes nécessitent un en-tête HTTP avec une clé Authorization qui est la même que votre INTERNAL_API_KEY ENV VAR que vous avez défini auparavant (voir ci-dessus). Vous devez transmettre votre clé API de base de données vectorielle avec le HTTP Header X-VectorDB-Key si vous exécutez une connexion à une instance basée sur le cloud d'une base de base de données vectorielle.
Une recherche de similitude d'image renverra un objet de réponse contenant les K supérieurs, plus les vecteurs bruts si demandé, avec le formulaire suivant:
{
"similar_images": list of match objects
"vectors": list of list of floats
}
où les objets «Match» sont définis comme:
{
"id": str,
"score": float,
"metadata": {"source_document" : str}
}
Si vous souhaitez utiliser docker build et docker run pour créer et exécuter des images individuelles au lieu de docker-compose suivez ces étapes:
cd src/docker build --file api/Dockerfile -t vectorflow_api:latest . Pour construire - n'oubliez pas la période à la findocker run --network=vectorflow --name=vectorflow_api -d --env-file=../env_scripts/env_vars.env -p 8000:8000 vectorflow_api:latest pour exécuter l'API. Vous n'avez pas besoin de l'argument du port pour exécuter le travailleur