
A estrutura de dados para dados multimodais
Observe que o ReadMe que você está vendo atualmente é para docarray> 0,30, que apresenta algumas alterações significativas do DocArray 0.21. Se você deseja continuar usando o DocArray mais antigo <= 0,21, certifique -se de instalá -lo via
pip install docarray==0.21. Consulte sua base de código, documentação e sua ramificação de fixes a quente para obter mais informações.
DocArray é uma biblioteca Python criada habilmente para a representação, transmissão, armazenamento e recuperação de dados multimodais. ADIBIRADOS PARA O DESENVOLVIMENTO DE APLICAÇÕES MULTIMODAL DE AI, seu design garante integração perfeita com os extensos ecossistemas de aprendizado de Machine Python e Machine. Em janeiro de 2022, o DocArray é distribuído abertamente sob a licença Apache 2.0 e atualmente desfruta do status de um projeto de sandbox dentro da LF AI & Data Foundation.
Para instalar o DocArray da CLI, execute o seguinte comando:
pip install -U docarrayNota Para usar o docArray <= 0,21, não se esqueça de instalar via
pip install docarray==0.21e consulte sua base de código e documentos e sua filial de fixos a quente.
Novo para docarray? Dependendo do seu caso de uso e plano de fundo, existem várias maneiras de aprender sobre o DocArray:
O DocArray o capacita a representar seus dados de uma maneira que está inerentemente sintonizada com o aprendizado de máquina.
Isso é particularmente benéfico para vários cenários:
Familiarizado com Pydantic? Você ficará satisfeito ao saber que o DocArray não é apenas construído no topo do Pydantic, mas também mantém a compatibilidade completa com ele! Além disso, temos uma seção específica dedicada às suas necessidades!
Em essência, o DocArray facilita a representação de dados de uma maneira que reflete o Python Dataclasses, com o aprendizado de máquina sendo um 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)Vamos dar uma olhada em como você pode representar seus dados com 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 ] = NonePortanto, você não apenas pode definir os tipos de seus dados, mas também especificar a forma dos seus 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])Obviamente, você pode compor documentos em uma estrutura aninhada:
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!' )
) Você raramente trabalha com um único ponto de dados de cada vez, especialmente em aplicativos de aprendizado de máquina. É por isso que você pode coletar facilmente vários Documents :
DocumentsAo construir ou interagir com um sistema ML, geralmente você deseja processar vários documentos (pontos de dados) de uma só vez.
DocArray oferece duas estruturas de dados para isso:
DocVec : Um vetor de Documents . Todos os tensores nos documentos são empilhados em um único tensor. Perfeito para processamento e uso em lote dentro dos modelos ML .DocList : Uma lista de Documents . Todos os tensores nos documentos são mantidos como estão. Perfeito para streaming, renomeamento e arrastamento de dados . Vamos dar uma olhada neles, começando com 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 )
]
) No trecho de código acima, DocVec é parametrizado pelo tipo de documento que você deseja usar com ele: DocVec[Image] .
Isso pode parecer estranho no começo, mas estamos confiantes de que você se acostuma rapidamente! Além disso, permite fazer algumas coisas legais, como ter acesso em massa aos campos que você definiu em seu 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 A segunda estrutura de dados, DocList , funciona de maneira semelhante:
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 )
]
)Você ainda pode acessar a massa dos campos do seu 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 E você pode inserir, remover e anexar documentos ao seu 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 )),
),
) E você pode alternar perfeitamente entre DocVec e 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 facilita a transmissão de seus dados de maneira inerentemente compatível com o aprendizado de máquina.
Isso inclui suporte nativo para Protobuf e GRPC , juntamente com HTTP e serialização para JSON, JSONSCHEMA, BASE64 e bytes.
Esse recurso é benéfico para vários cenários:
Você está familiarizado com o FASTAPI? Você ficará encantado ao saber que o DocArray mantém a compatibilidade total com o FASTAPI! Além disso, temos uma seção dedicada especificamente para você!
Quando se trata de transmissão de dados, a serialização é uma etapa crucial. Vamos nos aprofundar em como o docarray otimiza esse processo:
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 )Obviamente, a serialização não é tudo o que você precisa. Então, confira como o DocArray se integra a Jina e FASTAPI .
Depois de modelar e distribuir seus dados, você normalmente deseja armazená -los em algum lugar. É aí que DocArray entra!
As lojas de documentos fornecem uma maneira perfeita para, como o nome sugere, armazenar seus documentos. Seja localmente ou remotamente, você pode fazer tudo isso na mesma interface do usuário:
A interface do armazenamento de documentos permite empurrar e puxar documentos de e para várias fontes de dados, tudo com a mesma interface do usuário.
Por exemplo, vamos ver como isso funciona com o armazenamento no 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' )Os índices de documentos permitem indexar seus documentos em um banco de dados vetorial para uma recuperação eficiente baseada em similaridade.
Isso é útil para:
Atualmente, os índices de documentos suportam tevadores , QDRANT , Elasticsearch , Redis , Mongo Atlas e Hnswlib , com mais por vir!
A interface do índice de documentos permite indexar e recuperar documentos de vários bancos de dados de vetores, todos com a mesma interface do usuário.
Ele suporta pesquisa de vetor de Ann, pesquisa de texto, filtragem e pesquisa 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' )Dependendo da sua formação e do caso de uso, existem maneiras diferentes de você entender o docarray.
Se você estiver usando a versão DocArray 0.30.0 ou inferior, estará familiarizado com sua API DATACLASS.
Docarray> = 0,30 é essa ideia, levada a sério. Todo documento é criado através de uma interface semelhante a Dataclass, cortesia do Pydantic.
Isso fornece as seguintes vantagens:
Você também pode estar familiarizado com nossas lojas de documentos antigas para a integração do Vector DB. Eles agora são chamados de índices de documentos e oferecem as seguintes melhorias (veja aqui a nova API):
Por enquanto, os índices de documentos suportam tevadores , QDRANT , Elasticsearch , Redis , Mongo Atlas , Search Vizer Exact mais próxima e HNSWLIB , com mais por vir.
Se você vier de Pydantic, poderá ver documentos documentos como modelos pydantic e docarray como uma coleção de guloseimas ao seu redor.
Mais especificamente, partimos para fazer o pydantic se encaixar para o mundo da ML - não substituindo -o, mas construindo em cima dele!
Isso significa que você obtém os seguintes benefícios:
.load() Um URL para imaginar o tensor, o texturl pode carregar e tokenizar documentos de texto, etc. A vantagem mais óbvia aqui é o suporte de primeira classe para dados centrados em ML , como {Torch, TF, ...}Tensor , Embedding , etc.
Isso inclui recursos úteis, como validar a forma de um 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)Se você vier de Pytorch, poderá ver o DocArray principalmente como uma maneira de organizar seus dados à medida que ele flui através do seu modelo .
Ele oferece várias vantagens:
O DOCArray pode ser usado diretamente dentro dos modelos ML para manipular e representar multimodaldata. Isso permite que você raciocine sobre seus dados usando as abstrações do DocArray no fundo do nn.Module e fornece um esquema compatível com FASTAPI que facilita a transição entre treinamento de modelos e porção de modelo.
Para ver o efeito disso, vamos primeiro observar uma implementação de baunilha Pytorch de um modelo Tri-Modal ML:
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 ,
) Não é muito fácil para os olhos, se você nos perguntar. E ainda pior, se você precisar adicionar mais uma modalidade, precisará tocar em todas as partes da sua base de código, alterando o tipo de retorno forward() e fazendo muitas mudanças a jusante disso.
Então, agora vamos ver como é o mesmo código com 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 docsParece muito melhor, não é? Você ganha instantaneamente na legibilidade e manutenção de código. E pelo mesmo preço, você pode transformar seu modelo Pytorch em um aplicativo FASTAPI e reutilizar sua definição de esquema de documentos (veja abaixo). Tudo é tratado de maneira pitônica, contando com dicas de tipo.
Como a abordagem Pytorch, você também pode usar o DocArray com o TensorFlow para lidar e representar dados multimodais dentro do seu modelo ML.
Primeiro, para usar o DocArray com o TensorFlow, precisamos primeiro instalá -lo da seguinte forma:
pip install tensorflow==2.12.0
pip install protobuf==3.19.0
Comparado ao uso do docarray com o pytorch, há uma diferença principal ao usá -lo com o TensorFlowTensor : enquanto TensorFlowTensor TorchTensor de tf.Tensor tf.Tensor uma subclasse de torch.Tensor tf.Tensor .tensor atributo.
Como isso afeta você? Sempre que você quiser acessar os dados do tensor, digamos, faça operações com eles ou entregue -os ao seu modelo ML, em vez de entregar sua instância TensorFlowTensor , você precisa acessar seu atributo .tensor .
Isso seria o seguinte:
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 inputsOs documentos são modelos pydantic (com uma torção) e, como tal, são totalmente compatíveis com o FASTAPI!
Mas por que você deveria usá -los, e não os modelos pydantic que você já conhece e ama? Boa pergunta!
E para selar o acordo, vamos mostrar a facilidade com que documenta o seu aplicativo 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 ())Assim como um modelo de baunilha pydantic!
Jina adotou o DocArray como sua biblioteca para representar e serializar documentos.
A Jina permite servir modelos e serviços construídos com o DocArray, permitindo que você sirva e dimensione esses aplicativos fazendo pleno uso dos capabilites de serialização da 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 )Se você se deparou com o DocArray como um cliente de banco de dados do Vector Universal, poderá pensar melhor nisso como um novo tipo de ORM para bancos de dados vetoriais . O trabalho de DocArray é pegar dados multimodais, aninhados e específicos de domínio e mapeá-los para um banco de dados vetorial, armazená-los lá e, assim, torná-los pesquisáveis:
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' )Atualmente, o DocArray suporta os seguintes bancos de dados do vetor:
Atualmente, uma integração do OpenSearch está em andamento.
Claro que esta é apenas uma das coisas que o docarray pode fazer, por isso o encorajamos a conferir o restante deste Readme!
Com o DocArray, você pode conectar dados externos ao LLMS através do Langchain. O DocArray oferece a liberdade de estabelecer esquemas de documentos flexíveis e escolher entre diferentes back -end para armazenamento de documentos. Depois de criar seu índice de documentos, você pode conectá -lo ao seu aplicativo Langchain usando DocArrayRetriever.
Instale o 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 )Como alternativa, você pode usar lojas vetoriais embutidas. Langchain suporta duas lojas vetoriais: DocArrayInMemorySearch e DocArrayhNswSearch. Ambos são fáceis de usar e são mais adequados para conjuntos de dados pequenos e médios.
DocArray é uma marca registrada da LF AI Projects, LLC