
La structure de données pour les données multimodales
Remarque La lecture que vous consultez actuellement concerne Docarray> 0,30, qui introduit des changements significatifs par rapport à Docarray 0,21. Si vous souhaitez continuer à utiliser l'ancien DocArray <= 0,21, assurez-vous de l'installer via
pip install docarray==0.21. Reportez-vous à sa base de code, à la documentation et à sa branche à chaud pour plus d'informations.
Docarray est une bibliothèque Python expertise pour la représentation, la transmission, le stockage et la récupération des données multimodales. Adminée au développement d'applications d'IA multimodales, sa conception garantit une intégration transparente avec les vastes écosystèmes de python et d'apprentissage automatique. En janvier 2022, Docarray est ouvertement distribué sous la licence 2.0 Apache et bénéficie actuellement du statut d'un projet de bac à sable au sein de la LF AI & Data Foundation.
Pour installer Docarray à partir de la CLI, exécutez la commande suivante:
pip install -U docarrayRemarque pour utiliser DocArray <= 0,21, assurez-vous d'installer via
pip install docarray==0.21et consulter sa base de code et ses documents et sa branche Hot Fixes.
Nouveau sur docarray? Selon votre cas d'utilisation et votre arrière-plan, il existe plusieurs façons de se renseigner sur Docarray:
Docarray vous permet de représenter vos données d'une manière intrinsèquement à l'écoute de l'apprentissage automatique.
Ceci est particulièrement bénéfique pour divers scénarios:
Familié avec Pydontic? Vous serez heureux d'apprendre que DoCarray est non seulement construit au sommet de Pyndantique, mais maintient également une compatibilité complète avec elle! De plus, nous avons une section spécifique dédiée à vos besoins!
Essentiellement, DocArray facilite la représentation des données d'une manière qui reflète les classes de données Python, avec l'apprentissage automatique étant un composant intégral:
from docarray import BaseDoc
from docarray . typing import TorchTensor , ImageUrl
import torch
# Define your data model
class MyDocument ( BaseDoc ):
description : str
image_url : ImageUrl # could also be VideoUrl, AudioUrl, etc.
image_tensor : TorchTensor [ 1704 , 2272 , 3 ] # you can express tensor shapes!
# Stack multiple documents in a Document Vector
from docarray import DocVec
vec = DocVec [ MyDocument ](
[
MyDocument (
description = "A cat" ,
image_url = "https://example.com/cat.jpg" ,
image_tensor = torch . rand ( 1704 , 2272 , 3 ),
),
]
* 10
)
print ( vec . image_tensor . shape ) # (10, 1704, 2272, 3)Examinons de plus près comment vous pouvez représenter vos données avec DocArray:
from docarray import BaseDoc
from docarray . typing import TorchTensor , ImageUrl
from typing import Optional
import torch
# Define your data model
class MyDocument ( BaseDoc ):
description : str
image_url : ImageUrl # could also be VideoUrl, AudioUrl, etc.
image_tensor : Optional [
TorchTensor [ 1704 , 2272 , 3 ]
] = None # could also be NdArray or TensorflowTensor
embedding : Optional [ TorchTensor ] = NoneAinsi, vous pouvez non seulement définir les types de vos données, mais vous pouvez même spécifier la forme de vos tenseurs!
# Create a document
doc = MyDocument (
description = "This is a photo of a mountain" ,
image_url = "https://upload.wikimedia.org/wikipedia/commons/2/2f/Alpamayo.jpg" ,
)
# Load image tensor from URL
doc . image_tensor = doc . image_url . load ()
# Compute embedding with any model of your choice
def clip_image_encoder ( image_tensor : TorchTensor ) -> TorchTensor : # dummy function
return torch . rand ( 512 )
doc . embedding = clip_image_encoder ( doc . image_tensor )
print ( doc . embedding . shape ) # torch.Size([512])Bien sûr, vous pouvez composer des documents dans une structure imbriquée:
from docarray import BaseDoc
from docarray . documents import ImageDoc , TextDoc
import numpy as np
class MultiModalDocument ( BaseDoc ):
image_doc : ImageDoc
text_doc : TextDoc
doc = MultiModalDocument (
image_doc = ImageDoc ( tensor = np . zeros (( 3 , 224 , 224 ))), text_doc = TextDoc ( text = 'hi!' )
) Vous travaillez rarement avec un seul point de données à la fois, en particulier dans les applications d'apprentissage automatique. C'est pourquoi vous pouvez facilement collecter plusieurs Documents :
DocumentsLorsque vous construisez ou interagissez avec un système ML, vous souhaitez généralement traiter plusieurs documents (points de données) à la fois.
Docarray propose deux structures de données pour cela:
DocVec : un vecteur de Documents . Tous les tenseurs des documents sont empilés dans un seul tenseur. Parfait pour le traitement par lots et l'utilisation à l'intérieur des modèles ML .DocList : une liste de Documents . Tous les tenseurs des documents sont conservés tels quels. Parfait pour le streaming, le reconstitution et le mélange des données . Jetons un œil à-les, en commençant par DocVec :
from docarray import DocVec , BaseDoc
from docarray . typing import AnyTensor , ImageUrl
import numpy as np
class Image ( BaseDoc ):
url : ImageUrl
tensor : AnyTensor # this allows torch, numpy, and tensor flow tensors
vec = DocVec [ Image ]( # the DocVec is parametrized by your personal schema!
[
Image (
url = "https://upload.wikimedia.org/wikipedia/commons/2/2f/Alpamayo.jpg" ,
tensor = np . zeros (( 3 , 224 , 224 )),
)
for _ in range ( 100 )
]
) Dans l'extrait de code ci-dessus, DocVec est paramétré par le type de document que vous souhaitez utiliser avec lui: DocVec[Image] .
Cela peut être bizarre au début, mais nous sommes convaincus que vous vous y habituez rapidement! De plus, cela nous permet de faire des choses sympas, comme avoir un accès en vrac aux champs que vous avez définis dans votre document:
tensor = vec . tensor # gets all the tensors in the DocVec
print ( tensor . shape ) # which are stacked up into a single tensor!
print ( vec . url ) # you can bulk access any other field, too La deuxième structure de données, DocList , fonctionne de manière similaire:
from docarray import DocList
dl = DocList [ Image ]( # the DocList is parametrized by your personal schema!
[
Image (
url = "https://upload.wikimedia.org/wikipedia/commons/2/2f/Alpamayo.jpg" ,
tensor = np . zeros (( 3 , 224 , 224 )),
)
for _ in range ( 100 )
]
)Vous pouvez toujours accéder aux champs de votre document: vous
tensors = dl . tensor # gets all the tensors in the DocList
print ( type ( tensors )) # as a list of tensors
print ( dl . url ) # you can bulk access any other field, too Et vous pouvez insérer, supprimer et ajouter des documents à votre DocList :
# append
dl . append (
Image (
url = "https://upload.wikimedia.org/wikipedia/commons/2/2f/Alpamayo.jpg" ,
tensor = np . zeros (( 3 , 224 , 224 )),
)
)
# delete
del dl [ 0 ]
# insert
dl . insert (
0 ,
Image (
url = "https://upload.wikimedia.org/wikipedia/commons/2/2f/Alpamayo.jpg" ,
tensor = np . zeros (( 3 , 224 , 224 )),
),
) Et vous pouvez basculer de manière transparente entre DocVec et DocList :
vec_2 = dl . to_doc_vec ()
assert isinstance ( vec_2 , DocVec )
dl_2 = vec_2 . to_doc_list ()
assert isinstance ( dl_2 , DocList )Docarray facilite la transmission de vos données d'une manière intrinsèquement compatible avec l'apprentissage automatique.
Cela inclut la prise en charge native pour Protobuf et GRPC , ainsi que HTTP et sérialisation à JSON, JsonSchema, Base64 et octets.
Cette fonctionnalité s'avère bénéfique pour plusieurs scénarios:
Connaissez-vous Fastapi? Vous serez ravi d'apprendre que Docarray maintient une compatibilité complète avec Fastapi! De plus, nous avons une section dédiée spécifiquement pour vous!
En ce qui concerne la transmission des données, la sérialisation est une étape cruciale. Plongeons comment Docarray rationalise ce processus:
from docarray import BaseDoc
from docarray . typing import ImageTorchTensor
import torch
# model your data
class MyDocument ( BaseDoc ):
description : str
image : ImageTorchTensor [ 3 , 224 , 224 ]
# create a Document
doc = MyDocument (
description = "This is a description" ,
image = torch . zeros (( 3 , 224 , 224 )),
)
# serialize it!
proto = doc . to_protobuf ()
bytes_ = doc . to_bytes ()
json = doc . json ()
# deserialize it!
doc_2 = MyDocument . from_protobuf ( proto )
doc_4 = MyDocument . from_bytes ( bytes_ )
doc_5 = MyDocument . parse_raw ( json )Bien sûr, la sérialisation n'est pas tout ce dont vous avez besoin. Découvrez donc comment Docarray s'intègre à Jina et Fastapi .
Après la modélisation et éventuellement la distribution de vos données, vous voudrez généralement les stocker quelque part. C'est là que Docarray intervient!
Les magasins de documents fournissent un moyen transparent, comme son nom l'indique, stocker vos documents. Que ce soit localement ou à distance, vous pouvez tout faire via la même interface utilisateur:
L'interface du magasin de documents vous permet de pousser et de tirer des documents vers et depuis plusieurs sources de données, le tout avec la même interface utilisateur.
Par exemple, voyons comment cela fonctionne avec le stockage sur le disque:
from docarray import BaseDoc , DocList
class SimpleDoc ( BaseDoc ):
text : str
docs = DocList [ SimpleDoc ]([ SimpleDoc ( text = f'doc { i } ' ) for i in range ( 8 )])
docs . push ( 'file://simple_docs' )
docs_pull = DocList [ SimpleDoc ]. pull ( 'file://simple_docs' )Les index de documents vous permettent d'indexer vos documents dans une base de données vectorielle pour une récupération efficace basée sur la similitude.
Ceci est utile pour:
Actuellement, les index de documents prennent en charge Weavate , Qdrant , Elasticsearch , Redis , Mongo Atlas et Hnswlib , avec plus à venir!
L'interface d'index de documents vous permet d'indexer et de récupérer des documents à partir de plusieurs bases de données vectorielles, toutes avec la même interface utilisateur.
Il prend en charge la recherche de vecteur ANN, la recherche de texte, le filtrage et la recherche hybride.
from docarray import DocList , BaseDoc
from docarray . index import HnswDocumentIndex
import numpy as np
from docarray . typing import ImageUrl , ImageTensor , NdArray
class ImageDoc ( BaseDoc ):
url : ImageUrl
tensor : ImageTensor
embedding : NdArray [ 128 ]
# create some data
dl = DocList [ ImageDoc ](
[
ImageDoc (
url = "https://upload.wikimedia.org/wikipedia/commons/2/2f/Alpamayo.jpg" ,
tensor = np . zeros (( 3 , 224 , 224 )),
embedding = np . random . random (( 128 ,)),
)
for _ in range ( 100 )
]
)
# create a Document Index
index = HnswDocumentIndex [ ImageDoc ]( work_dir = '/tmp/test_index' )
# index your data
index . index ( dl )
# find similar Documents
query = dl [ 0 ]
results , scores = index . find ( query , limit = 10 , search_field = 'embedding' )Selon votre arrière-plan et votre cas d'utilisation, il existe différentes façons de comprendre Docarray.
Si vous utilisez Docarray version 0.30.0 ou moins, vous serez familier avec son API DataClass.
Docarray> = 0,30 est cette idée, prise au sérieux. Chaque document est créé via une interface de type DataClass, gracieuseté de Pydontic.
Cela donne les avantages suivants:
Vous pouvez également être familier avec nos anciens magasins de documents pour l'intégration Vector DB. Ils sont maintenant appelés index de documents et offrent les améliorations suivantes (voir ici pour la nouvelle API):
Pour l'instant, les index de documents prennent en charge Weavate , Qdrant , Elasticsearch , Redis , Mongo Atlas , la recherche de voisin le plus proche et le HNSWLIB , avec plus à venir.
Si vous venez de Pyndantic, vous pouvez voir des documents Docarray comme des modèles pydatiques justifiés et Docarray comme une collection de goodies autour d'eux.
Plus précisément, nous avons décidé de faire un ajustement pydatique pour le monde ML - non pas en le remplaçant, mais en construisant par-dessus!
Cela signifie que vous obtenez les avantages suivants:
.load() Une URL pour l'image tenseur, TexTUrl peut charger et tokensiner des documents texte, etc. L'avantage le plus évident ici est le support de première classe pour les données centrées sur ML , telles que {Torch, TF, ...}Tensor , Embedding , etc.
Cela comprend des caractéristiques pratiques telles que la validation de la forme d'un tenseur:
from docarray import BaseDoc
from docarray . typing import TorchTensor
import torch
class MyDoc ( BaseDoc ):
tensor : TorchTensor [ 3 , 224 , 224 ]
doc = MyDoc ( tensor = torch . zeros ( 3 , 224 , 224 )) # works
doc = MyDoc ( tensor = torch . zeros ( 224 , 224 , 3 )) # works by reshaping
try :
doc = MyDoc ( tensor = torch . zeros ( 224 )) # fails validation
except Exception as e :
print ( e )
# tensor
# Cannot reshape tensor of shape (224,) to shape (3, 224, 224) (type=value_error)
class Image ( BaseDoc ):
tensor : TorchTensor [ 3 , 'x' , 'x' ]
Image ( tensor = torch . zeros ( 3 , 224 , 224 )) # works
try :
Image (
tensor = torch . zeros ( 3 , 64 , 128 )
) # fails validation because second dimension does not match third
except Exception as e :
print ()
try :
Image (
tensor = torch . zeros ( 4 , 224 , 224 )
) # fails validation because of the first dimension
except Exception as e :
print ( e )
# Tensor shape mismatch. Expected(3, 'x', 'x'), got(4, 224, 224)(type=value_error)
try :
Image (
tensor = torch . zeros ( 3 , 64 )
) # fails validation because it does not have enough dimensions
except Exception as e :
print ( e )
# Tensor shape mismatch. Expected (3, 'x', 'x'), got (3, 64) (type=value_error)Si vous venez de Pytorch, vous pouvez voir DocArray principalement comme un moyen d' organiser vos données lorsqu'il traverse votre modèle .
Il vous offre plusieurs avantages:
Docarray peut être utilisé directement à l'intérieur des modèles ML pour gérer et représenter Multimodaldata. Cela vous permet de raisonner sur vos données en utilisant les abstractions de DocArray au plus profond de nn.Module , et fournit un schéma compatible FastAPI qui assouplit la transition entre la formation modèle et le service du modèle.
Pour voir l'effet de cela, observons d'abord une mise en œuvre de pytorch à la vanille d'un modèle ML tri-modal:
import torch
from torch import nn
def encoder ( x ):
return torch . rand ( 512 )
class MyMultiModalModel ( nn . Module ):
def __init__ ( self ):
super (). __init__ ()
self . audio_encoder = encoder ()
self . image_encoder = encoder ()
self . text_encoder = encoder ()
def forward ( self , text_1 , text_2 , image_1 , image_2 , audio_1 , audio_2 ):
embedding_text_1 = self . text_encoder ( text_1 )
embedding_text_2 = self . text_encoder ( text_2 )
embedding_image_1 = self . image_encoder ( image_1 )
embedding_image_2 = self . image_encoder ( image_2 )
embedding_audio_1 = self . image_encoder ( audio_1 )
embedding_audio_2 = self . image_encoder ( audio_2 )
return (
embedding_text_1 ,
embedding_text_2 ,
embedding_image_1 ,
embedding_image_2 ,
embedding_audio_1 ,
embedding_audio_2 ,
) Pas très facile aux yeux si vous nous le demandez. Et pire encore, si vous avez besoin d'ajouter une modalité de plus, vous devez toucher chaque partie de votre base de code, modifier le type de retour forward() et apporter beaucoup de changements en aval.
Alors, voyons maintenant à quoi ressemble le même code avec Docarray:
from docarray import DocList , BaseDoc
from docarray . documents import ImageDoc , TextDoc , AudioDoc
from docarray . typing import TorchTensor
from torch import nn
import torch
def encoder ( x ):
return torch . rand ( 512 )
class Podcast ( BaseDoc ):
text : TextDoc
image : ImageDoc
audio : AudioDoc
class PairPodcast ( BaseDoc ):
left : Podcast
right : Podcast
class MyPodcastModel ( nn . Module ):
def __init__ ( self ):
super (). __init__ ()
self . audio_encoder = encoder ()
self . image_encoder = encoder ()
self . text_encoder = encoder ()
def forward_podcast ( self , docs : DocList [ Podcast ]) -> DocList [ Podcast ]:
docs . audio . embedding = self . audio_encoder ( docs . audio . tensor )
docs . text . embedding = self . text_encoder ( docs . text . tensor )
docs . image . embedding = self . image_encoder ( docs . image . tensor )
return docs
def forward ( self , docs : DocList [ PairPodcast ]) -> DocList [ PairPodcast ]:
docs . left = self . forward_podcast ( docs . left )
docs . right = self . forward_podcast ( docs . right )
return docsÇa a l'air beaucoup mieux, n'est-ce pas? Vous gagnez instantanément dans la lisibilité au code et la maintenabilité. Et pour le même prix, vous pouvez transformer votre modèle Pytorch en une application FastAPI et réutiliser la définition de votre schéma de document (voir ci-dessous). Tout est traité de manière pythonique en s'appuyant sur des indices de type.
Comme l'approche Pytorch, vous pouvez également utiliser Docarray avec TensorFlow pour gérer et représenter des données multimodales dans votre modèle ML.
Tout d'abord, pour utiliser Docarray avec TensorFlow, nous devons d'abord l'installer comme suit:
pip install tensorflow==2.12.0
pip install protobuf==3.19.0
Par rapport à l'utilisation de Docarray avec Pytorch, il y a une différence principale lors de l'utilisation avec Tensorflow: Bien que TorchTensor de Docarray soit une sous-classe de torch.Tensor , ce n'est pas le cas pour le TensorFlowTensor : en raison de certaines limites techniques tf.Tensor tf.Tensor tf.Tensor TensorFlowTensor Son attribut .tensor .
Comment cela vous affecte-t-il? Chaque fois que vous souhaitez accéder aux données du tenseur, disons, effectuez des opérations avec elle ou le remettez-le à votre modèle ML, au lieu de remettre votre instance TensorFlowTensor , vous devez accéder à son attribut .tensor .
Cela ressemblerait à ce qui suit:
from typing import Optional
from docarray import DocList , BaseDoc
import tensorflow as tf
class Podcast ( BaseDoc ):
audio_tensor : Optional [ AudioTensorFlowTensor ] = None
embedding : Optional [ AudioTensorFlowTensor ] = None
class MyPodcastModel ( tf . keras . Model ):
def __init__ ( self ):
super (). __init__ ()
self . audio_encoder = AudioEncoder ()
def call ( self , inputs : DocList [ Podcast ]) -> DocList [ Podcast ]:
inputs . audio_tensor . embedding = self . audio_encoder (
inputs . audio_tensor . tensor
) # access audio_tensor's .tensor attribute
return inputsLes documents sont des modèles pydatiques (avec une torsion), et en tant que tels, ils sont entièrement compatibles avec Fastapi!
Mais pourquoi devriez-vous les utiliser, et non les modèles pydatiques que vous connaissez et aimez déjà? Bonne question!
Et pour sceller l'accord, laissez-nous vous montrer à quel point les documents sont facilités dans votre application Fastapi:
import numpy as np
from fastapi import FastAPI
from docarray . base_doc import DocArrayResponse
from docarray import BaseDoc
from docarray . documents import ImageDoc
from docarray . typing import NdArray , ImageTensor
class InputDoc ( BaseDoc ):
img : ImageDoc
text : str
class OutputDoc ( BaseDoc ):
embedding_clip : NdArray
embedding_bert : NdArray
app = FastAPI ()
def model_img ( img : ImageTensor ) -> NdArray :
return np . zeros (( 100 , 1 ))
def model_text ( text : str ) -> NdArray :
return np . zeros (( 100 , 1 ))
@ app . post ( "/embed/" , response_model = OutputDoc , response_class = DocArrayResponse )
async def create_item ( doc : InputDoc ) -> OutputDoc :
doc = OutputDoc (
embedding_clip = model_img ( doc . img . tensor ), embedding_bert = model_text ( doc . text )
)
return doc
input_doc = InputDoc ( text = '' , img = ImageDoc ( tensor = np . random . random (( 3 , 224 , 224 ))))
async with AsyncClient ( app = app , base_url = "http://test" ) as ac :
response = await ac . post ( "/embed/" , data = input_doc . json ())Tout comme un modèle pydante de vanille!
Jina a adopté Docarray comme bibliothèque pour représenter et sérialiser les documents.
Jina permet de servir des modèles et des services construits avec DocArray vous permettant de servir et de faire évoluer ces applications en utilisant pleinement les capacités de sérialisation de Docarray.
import numpy as np
from jina import Deployment , Executor , requests
from docarray import BaseDoc , DocList
from docarray . documents import ImageDoc
from docarray . typing import NdArray , ImageTensor
class InputDoc ( BaseDoc ):
img : ImageDoc
text : str
class OutputDoc ( BaseDoc ):
embedding_clip : NdArray
embedding_bert : NdArray
def model_img ( img : ImageTensor ) -> NdArray :
return np . zeros (( 100 , 1 ))
def model_text ( text : str ) -> NdArray :
return np . zeros (( 100 , 1 ))
class MyEmbeddingExecutor ( Executor ):
@ requests ( on = '/embed' )
def encode ( self , docs : DocList [ InputDoc ], ** kwargs ) -> DocList [ OutputDoc ]:
ret = DocList [ OutputDoc ]()
for doc in docs :
output = OutputDoc (
embedding_clip = model_img ( doc . img . tensor ),
embedding_bert = model_text ( doc . text ),
)
ret . append ( output )
return ret
with Deployment (
protocols = [ 'grpc' , 'http' ], ports = [ 12345 , 12346 ], uses = MyEmbeddingExecutor
) as dep :
resp = dep . post (
on = '/embed' ,
inputs = DocList [ InputDoc ](
[ InputDoc ( text = '' , img = ImageDoc ( tensor = np . random . random (( 3 , 224 , 224 ))))]
),
return_type = DocList [ OutputDoc ],
)
print ( resp )Si vous êtes tombé sur DoCarray en tant que client de base de données Vector Universal, vous pouvez mieux le considérer comme un nouveau type d'ORM pour les bases de données vectorielles . Le travail de Docarray consiste à prendre des données multimodales, imbriquées et spécifiques au domaine et de les cartographier dans une base de données vectorielle, de les stocker là-bas et ainsi de la rendre consultable:
from docarray import DocList , BaseDoc
from docarray . index import HnswDocumentIndex
import numpy as np
from docarray . typing import ImageUrl , ImageTensor , NdArray
class ImageDoc ( BaseDoc ):
url : ImageUrl
tensor : ImageTensor
embedding : NdArray [ 128 ]
# create some data
dl = DocList [ ImageDoc ](
[
ImageDoc (
url = "https://upload.wikimedia.org/wikipedia/commons/2/2f/Alpamayo.jpg" ,
tensor = np . zeros (( 3 , 224 , 224 )),
embedding = np . random . random (( 128 ,)),
)
for _ in range ( 100 )
]
)
# create a Document Index
index = HnswDocumentIndex [ ImageDoc ]( work_dir = '/tmp/test_index2' )
# index your data
index . index ( dl )
# find similar Documents
query = dl [ 0 ]
results , scores = index . find ( query , limit = 10 , search_field = 'embedding' )Actuellement, DocArray prend en charge les bases de données vectorielles suivantes:
Une intégration d'OpenSearch est actuellement en cours.
Bien sûr, ce n'est qu'une des choses que Docarray peut faire, nous vous encourageons donc à consulter le reste de ce lecture!
Avec DocArray, vous pouvez connecter des données externes aux LLM via Langchain. Docarray vous donne la liberté d'établir des schémas de documents flexibles et de choisir parmi différents backends pour le stockage de documents. Après avoir créé votre index de document, vous pouvez le connecter à votre application Langchain à l'aide de DocarrayRever.
Installez Langchain via:
pip install langchain from docarray import BaseDoc , DocList
from docarray . typing import NdArray
from langchain . embeddings . openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings ()
# Define a document schema
class MovieDoc ( BaseDoc ):
title : str
description : str
year : int
embedding : NdArray [ 1536 ]
movies = [
{ "title" : "#1 title" , "description" : "#1 description" , "year" : 1999 },
{ "title" : "#2 title" , "description" : "#2 description" , "year" : 2001 },
]
# Embed `description` and create documents
docs = DocList [ MovieDoc ](
MovieDoc ( embedding = embeddings . embed_query ( movie [ "description" ]), ** movie )
for movie in movies
) from docarray . index import (
InMemoryExactNNIndex ,
HnswDocumentIndex ,
WeaviateDocumentIndex ,
QdrantDocumentIndex ,
ElasticDocIndex ,
RedisDocumentIndex ,
MongoDBAtlasDocumentIndex ,
)
# Select a suitable backend and initialize it with data
db = InMemoryExactNNIndex [ MovieDoc ]( docs ) from langchain . chat_models import ChatOpenAI
from langchain . chains import ConversationalRetrievalChain
from langchain . retrievers import DocArrayRetriever
# Create a retriever
retriever = DocArrayRetriever (
index = db ,
embeddings = embeddings ,
search_field = "embedding" ,
content_field = "description" ,
)
# Use the retriever in your chain
model = ChatOpenAI ()
qa = ConversationalRetrievalChain . from_llm ( model , retriever = retriever )Alternativement, vous pouvez utiliser des magasins vectoriels intégrés. Langchain prend en charge deux magasins vectoriels: DocarRayInMemorySearch et DocarrayhswSearch. Les deux sont conviviaux et sont les mieux adaptés aux ensembles de données de petite à moyenne taille.
Docarray est une marque de commerce de LF AI Projects, LLC