
La estructura de datos para datos multimodales
Tenga en cuenta que el ReadMe que está viendo actualmente es para Darterray> 0.30, que introduce algunos cambios significativos de Darterray 0.21. Si desea continuar usando el Darterray más antiguo <= 0.21, asegúrese de instalarlo a través de
pip install docarray==0.21. Consulte su Base de código, documentación y su rama de fijados en caliente para obtener más información.
Darterray es una biblioteca de Python elaborada por la representación, transmisión, almacenamiento y recuperación de datos multimodales. Administrada para el desarrollo de aplicaciones de IA multimodales, su diseño garantiza una integración perfecta con los extensos ecosistemas de aprendizaje de Python y Machine. A partir de enero de 2022, Darterray se distribuye abiertamente bajo la Licencia de Apache 2.0 y actualmente disfruta del estado de un proyecto Sandbox dentro de la LF AI & Data Foundation.
Para instalar DarCarray desde la CLI, ejecute el siguiente comando:
pip install -U docarrayNota Para usar DarCarray <= 0.21, asegúrese de instalar a través de
pip install docarray==0.21y consulte su base de código y documentos y su rama de fijados en caliente.
¿Nuevo en Dargarray? Dependiendo de su caso de uso y antecedentes, hay múltiples formas de aprender sobre Darterray:
Darterray le permite representar sus datos de una manera inherentemente en sintonía con el aprendizaje automático.
Esto es particularmente beneficioso para varios escenarios:
Familiarizado con Pydantic? ¡Te complacerá saber que Darterray no solo está construido sobre Pydantic, sino que también mantiene una compatibilidad completa con él! Además, ¡tenemos una sección específica dedicada a sus necesidades!
En esencia, Darterray facilita la representación de datos de una manera que refleje las dataclases de Python, con el aprendizaje automático como un componente integral:
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)Echemos un vistazo más de cerca a cómo puede representar sus datos con Darterray:
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 ] = NoneEntonces, no solo puede definir los tipos de sus datos, ¡incluso puede especificar la forma de sus tensores!
# 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])Por supuesto, puede componer documentos en una estructura anidada:
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!' )
) Raramente trabaja con un solo punto de datos a la vez, especialmente en aplicaciones de aprendizaje automático. Es por eso que puede recopilar fácilmente múltiples Documents :
DocumentsAl construir o interactuar con un sistema ML, generalmente desea procesar múltiples documentos (puntos de datos) a la vez.
Darterray ofrece dos estructuras de datos para esto:
DocVec : un vector de Documents . Todos los tensores en los documentos están apilados en un solo tensor. Perfecto para el procesamiento por lotes y usar dentro de los modelos ML .DocList : una lista de Documents . Todos los tensores en los documentos se mantienen tal cual. Perfecto para transmitir, volver a rangar y barajar datos . Echemos un vistazo a ellos, comenzando con 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 )
]
) En el fragmento de código anterior, DocVec se parametriza mediante el tipo de documento que desea usar con él: DocVec[Image] .
¡Esto puede parecer extraño al principio, pero estamos seguros de que se acostumbrará rápidamente! Además, nos permite hacer algunas cosas interesantes, como tener acceso a granel a los campos que definió en su documento:
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 segunda estructura de datos, DocList , funciona de manera similar:
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 )
]
)Todavía puede acceder a gran parte de los campos de su documento:
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 Y puede insertar, eliminar y agregar documentos a su 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 )),
),
) Y puede cambiar sin problemas entre DocVec y DocList :
vec_2 = dl . to_doc_vec ()
assert isinstance ( vec_2 , DocVec )
dl_2 = vec_2 . to_doc_list ()
assert isinstance ( dl_2 , DocList )Darterray facilita la transmisión de sus datos de manera inherentemente compatible con el aprendizaje automático.
Esto incluye apoyo nativo para ProtoBuf y GRPC , junto con HTTP y serialización a JSON, Jsonschema, Base64 y Bytes.
Esta característica resulta beneficiosa para varios escenarios:
¿Estás familiarizado con Fastapi? ¡Estará encantado de saber que Darterray mantiene una compatibilidad completa con Fastapi! Además, ¡tenemos una sección dedicada específicamente para usted!
Cuando se trata de la transmisión de datos, la serialización es un paso crucial. Vamos a profundizar en cómo DarCarray optimiza este proceso:
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 )Por supuesto, la serialización no es todo lo que necesitas. Así que vea cómo Dargarray se integra con Jina y Fastapi .
Después de modelar y posiblemente distribuir sus datos, generalmente querrá almacenarlos en algún lugar. ¡Ahí es donde interviene Darterray!
Las tiendas de documentos proporcionan una forma perfecta, como su nombre indica, almacenar sus documentos. Ya sea local o remotamente, puede hacerlo todo a través de la misma interfaz de usuario:
La interfaz del almacén de documentos le permite presionar y extraer documentos hacia y desde múltiples fuentes de datos, todas con la misma interfaz de usuario.
Por ejemplo, veamos cómo funciona con el almacenamiento en el disco:
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' )Los índices de documentos le permiten indexar sus documentos en una base de datos vectorial para una recuperación eficiente basada en similitud.
Esto es útil para:
Actualmente, los índices de documentos admiten Weaviate , Qdrant , Elasticsearch , Redis , Mongo Atlas y Hnswlib , ¡con más por venir!
La interfaz de índice de documentos le permite indexar y recuperar documentos de múltiples bases de datos vectoriales, todas con la misma interfaz de usuario.
Admite búsqueda de vectores ANN, búsqueda de texto, filtrado y búsqueda híbrida.
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' )Dependiendo de sus antecedentes y su caso de uso, hay diferentes formas para que comprenda Darterray.
Si está utilizando DarCarray Version 0.30.0 o inferior, estará familiarizado con su API de DataClass.
Darterray> = 0.30 es esa idea, tomada en serio. Cada documento se crea a través de una interfaz de dataclass, cortesía de Pydantic.
Esto ofrece las siguientes ventajas:
También puede estar familiarizado con nuestras antiguas tiendas de documentos para la integración de Vector DB. Ahora se les llama índices de documentos y ofrecen las siguientes mejoras (ver aquí para la nueva API):
Por ahora, los índices de documentos son compatibles con Weaviate , Qdrant , Elasticsearch , Redis , Mongo Atlas , Exact Search y Hnswlib , con más por venir.
Si viene de Pydantic, puede ver documentos de Darterray como modelos Pydantic Juguese y Darterray como una colección de golosinas a su alrededor.
Más específicamente, nos propusimos hacer que Pydantic se ajuste al mundo ML , no reemplazándolo, sino construyendo encima de él!
Esto significa que obtiene los siguientes beneficios:
.load() una URL al tensor de imagen, Texturl puede cargar y tokenizar documentos de texto, etc. La ventaja más obvia aquí es el soporte de primera clase para los datos centrados en ML , como {Torch, TF, ...}Tensor , Embedding , etc.
Esto incluye características útiles, como validar la forma de un tensor:
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 viene de Pytorch, puede ver Darterray principalmente como una forma de organizar sus datos a medida que fluye a través de su modelo .
Te ofrece varias ventajas:
Darterray se puede usar directamente dentro de los modelos ML para manejar y representar multimodaldata. Esto le permite razonar sobre sus datos utilizando las abstracciones de Dargarray en el fondo del nn.Module , y proporciona un esquema compatible con FastAPI que facilita la transición entre el entrenamiento del modelo y el servicio del modelo.
Para ver el efecto de esto, primero observemos una implementación de vainilla pytorch de un modelo 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 ,
) No es muy fácil para los ojos si nos preguntas. Y lo que es peor, si necesita agregar una modalidad más, debe tocar cada parte de su base de código, cambiar el tipo de retorno forward() y hacer muchos cambios aguas abajo de eso.
Entonces, ahora veamos cómo se ve el mismo código con Dargarray:
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 docsSe ve mucho mejor, ¿no? Usted ganas instantáneamente en legibilidad y capacidad de mantenimiento. Y por el mismo precio, puede convertir su modelo Pytorch en una aplicación Fastapi y reutilizar su definición de esquema de documentos (ver más abajo). Todo se maneja de manera pitónica confiando en pistas de tipo.
Al igual que el enfoque de Pytorch, también puede usar Darterray con TensorFlow para manejar y representar datos multimodales dentro de su modelo ML.
En primer lugar, para usar DarCarray con TensorFlow primero necesitamos instalarlo de la siguiente manera:
pip install tensorflow==2.12.0
pip install protobuf==3.19.0
En comparación con el uso de DarCarray con Pytorch, hay una diferencia principal cuando se usa con TensorFlow: mientras que TorchTensor de DarCarray es una subclase de torch.Tensor , este no es el caso del TensorFlowTensor : debido a algunas limitaciones técnicas de tf.Tensor , TensorFlowTensor de TFArray, sino que no es un subclass de tf.Tensor , sino que también es un tf.Tensor de tf. su atributo .tensor .
¿Cómo te afecta esto? Siempre que desee acceder a los datos del tensor, digamos, realice operaciones con él o entregamos a su modelo ML, en lugar de entregar su instancia TensorFlowTensor , debe acceder a su atributo .tensor .
Esto se vería como lo siguiente:
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 inputs¡Los documentos son modelos pydánticos (con un giro), y como tal son totalmente compatibles con Fastapi!
Pero, ¿por qué deberías usarlos, y no los modelos pydánticos que ya conoces y amas? ¡Buena pregunta!
Y para sellar el trato, permítanos mostrarle con qué facilidad los documentos de los documentos en su aplicación 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 ())¡Al igual que una modelo pydantic de vainilla!
Jina ha adoptado Dargarray como su biblioteca para representar y serializar documentos.
Jina permite servir modelos y servicios construidos con Dargarray, lo que le permite servir y escalar estas aplicaciones que hacen uso completo de las capacilitas de serialización de Darterray.
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 se encontró con Dargarray como un cliente de base de datos de Vector Universal, puede pensarlo mejor como un nuevo tipo de ORM para las bases de datos de vectores . El trabajo de Darterray es tomar datos multimodales, anidados y específicos de dominio y asignarlo a una base de datos vectorial, almacenarlo allí y, por lo tanto, hacer que se pueda buscar:
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' )Actualmente, Darterray admite las siguientes bases de datos de vectores:
Actualmente está en progreso una integración de OpenSearch.
Por supuesto, esta es solo una de las cosas que Darraray puede hacer, ¡así que le recomendamos que revise el resto de este Readme!
Con Darterray, puede conectar datos externos a LLM a través de Langchain. Darterray le brinda la libertad de establecer esquemas de documentos flexibles y elegir entre diferentes backends para el almacenamiento de documentos. Después de crear su índice de documentos, puede conectarlo a su aplicación Langchain utilizando DarArrayRetRiever.
Instalar langchain a través de:
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 )Alternativamente, puede usar tiendas vectoriales incorporadas. Langchain admite dos tiendas vectoriales: DarArrayInMemorySearch y DartarrayhnswSearch. Ambos son fáciles de usar y son los más adecuados para conjuntos de datos pequeños a medianos.
Dargarray es una marca registrada de LF AI Projects, LLC