
Структура данных для мультимодальных данных
Примечание. Readme, который вы в настоящее время просматриваете, предназначен для Docarray> 0,30, что вносит некоторые существенные изменения от Docarray 0.21. Если вы хотите продолжить использование более старого Docarray <= 0,21, убедитесь, что вы установите его через
pip install docarray==0.21. Обратитесь к его кодовой базе, документации и филиалу Hot-Fixes для получения дополнительной информации.
Docarray - это библиотека Python, искусно созданная для представления, передачи, хранения и поиска мультимодальных данных. Приспособленная для разработки мультимодальных применений ИИ, его дизайн гарантирует бесшовную интеграцию с обширными экосистемами питона и машинного обучения. По состоянию на январь 2022 года Docarray открыто распределен по Apache License 2.0 и в настоящее время имеет состояние проекта Sandbox в рамках Foundation LF и Data Data.
Чтобы установить Docarray из CLI, запустите следующую команду:
pip install -U docarrayПРИМЕЧАНИЕ , чтобы использовать Docarray <= 0,21, убедитесь, что вы установите
pip install docarray==0.21и ознакомьтесь с его кодовой базой и документами и его фиксами горячих фиксиров.
Новичок в Docarray? В зависимости от вашего варианта использования и фона есть несколько способов узнать о Docarray:
Docarray дает вам возможность представлять ваши данные таким образом, который по своей сути настроена на машинное обучение.
Это особенно полезно для различных сценариев:
Знаком с пидантикой? Вам будет приятно узнать, что Docarray не только построен на питданте, но и поддерживает полную совместимость с ним! Кроме того, у нас есть конкретный раздел, посвященный вашим потребностям!
По сути, Docarray облегчает представление данных таким образом, чтобы отражать обработки данных Python, причем машинное обучение является интегральным компонентом:
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)Давайте внимательно посмотрим на то, как вы можете представлять свои данные с помощью 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 ] = NoneТак что вы можете не только определить типы ваших данных, вы можете даже указать форму ваших тензоров!
# 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])Конечно, вы можете составить документы в вложенную структуру:
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!' )
) Вы редко работаете с одной точкой данных за раз, особенно в приложениях машинного обучения. Вот почему вы можете легко собрать несколько Documents :
DocumentsПри построении или взаимодействии с системой ML, обычно вы хотите обработать несколько документов (точки данных) одновременно.
Docarray предлагает две структуры данных для этого:
DocVec : вектор Documents . Все тензоры в документах сложены в один тензор. Идеально подходит для обработки партии и использования внутри моделей ML .DocList : список Documents . Все тензоры в документах хранятся как есть. Идеально подходит для потоковой передачи, повторной оценки и перетасовки данных . Давайте посмотрим на них, начиная с 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 )
]
) В приведенном выше фрагменте кода DocVec параметризован типом документа, который вы хотите использовать с ним: DocVec[Image] .
Сначала это может выглядеть странно, но мы уверены, что вы привыкнете к этому быстро! Кроме того, это позволяет нам делать несколько крутых вещей, например, иметь массовый доступ к полям, которые вы определили в своем документе:
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 Вторая структура данных, DocList , работает аналогичным образом:
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 )
]
)Вы все еще можете получить доступ к полям вашего документа:
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 И вы можете вставить, удалять и добавлять документы в свой 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 )),
),
) И вы можете плавно переключаться между DocVec и 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 облегчает передачу ваших данных способом по своей сути совместимой с машинным обучением.
Это включает в себя собственную поддержку ProtoBuf и GRPC , а также HTTP и сериализацию на JSON, Jsonschema, Base64 и байты.
Эта функция оказывается полезной для нескольких сценариев:
Вы знакомы с FASTAPI? Вы будете рады узнать, что Docarray поддерживает полную совместимость с Fastapi! Кроме того, у нас есть выделенный раздел специально для вас!
Когда дело доходит до передачи данных, сериализация является важным шагом. Давайте углубимся в то, как Docarray оптимизирует этот процесс:
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 )Конечно, сериализация - это не все, что вам нужно. Так что посмотрите, как Docarray интегрируется с Jina и Fastapi .
После моделирования и, возможно, распределения ваших данных, вы обычно захотите хранить их где -нибудь. Вот где вступает докрай!
Магазины документов обеспечивают бесшовный способ, как следует из названия, хранить ваши документы. Будь то локально или удаленно, вы можете сделать это на всех пользовательских интерфейсах:
Интерфейс хранилища документов позволяет вам нажимать и вытащить документы в и из нескольких источников данных, все с одним и тем же пользовательским интерфейсом.
Например, давайте посмотрим, как это работает с хранением на диск:
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' )Индексы документов позволяют индексировать ваши документы в векторной базе данных для эффективного поиска на основе сходства.
Это полезно для:
В настоящее время индексы документов поддерживают Weaviate , Qdrant , Elasticsearch , Redis , Mongo Atlas и Hnswlib , а также больше!
Интерфейс индекса документов позволяет индексировать и извлекать документы из нескольких векторных баз данных, все с одним и тем же пользовательским интерфейсом.
Он поддерживает поиск в векторе Ann, поиск текста, фильтрацию и гибридный поиск.
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' )В зависимости от вашего фонового и использования, у вас есть разные способы понять Docarray.
Если вы используете Docarray версию 0.30.0 или ниже, вы будете знакомы с его API DataClass.
Docarray> = 0,30 - это идея, воспринятая всерьез. Каждый документ создается через интерфейс, похожий на DataClass, любезно предоставлена Pydantic.
Это дает следующие преимущества:
Вы также можете быть знакомы с нашими старыми магазинами документов для векторной интеграции DB. Теперь они называются индексами документов и предлагают следующие улучшения (см. Здесь для нового API):
На данный момент индексы документов поддерживают Weaviate , Qdrant , Elasticsearch , Redis , Mongo Atlas , точный ближайший поиск соседей и Hnswlib , и еще больше.
Если вы приехали из Pydantic, вы можете увидеть документы Docarray как соки Pydantic Models, а Docarray - как коллекция вкусностей вокруг них.
Более конкретно, мы намеревались сделать Pydantic пригодным для мира ML - не заменив его, а построившись на вершине!
Это означает, что вы получаете следующие преимущества:
.load() URL -адрес для тензора изображения, Texturl может загружать и токенизировать текстовые документы и т. Д. Наиболее очевидным преимуществом здесь является первоклассная поддержка для ML-ориентированных данных , таких как {Torch, TF, ...}Tensor , Embedding и т. Д.
Это включает в себя удобные функции, такие как проверка формы тензора:
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)Если вы приехали из Pytorch, вы можете увидеть Docarray в основном как способ организации ваших данных, поскольку они протекают через вашу модель .
Он предлагает вам несколько преимуществ:
Docarray может использоваться непосредственно внутри моделей ML для обработки и представления мультимодальдаты. Это позволяет вам рассуждать о ваших данных, используя абстракции Docarray глубоко внутри nn.Module , и обеспечивает схему, совместимую с FastAPI, которая облегчает переход между обучением модели и модельным обслуживанием.
Чтобы увидеть эффект этого, давайте впервые соблюдаем ванильную реализацию тримодальной 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 ,
) Не очень легко на глазах, если вы спросите нас. И еще хуже, если вам нужно добавить еще одну модальность, вы должны прикоснуться к каждой части вашей базы кода, изменить тип возврата forward() и внести множество изменений вниз по течению от этого.
Итак, теперь посмотрим, как выглядит тот же код с 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Выглядит намного лучше, не так ли? Вы мгновенно выигрываете в чтении и обслуживаемости кода. А по той же цене вы можете превратить свою модель Pytorch в приложение Fastapi и повторно использовать определение схемы документа (см. Ниже). Все обрабатывается питоническим образом, полагаясь на подсказки типа.
Как и подход Pytorch, вы также можете использовать Docarray с TensorFlow для обработки и представления мультимодальных данных внутри вашей модели ML.
Во -первых, чтобы использовать Docarray с TensorFlow, нам сначала нужно установить его следующим образом:
pip install tensorflow==2.12.0
pip install protobuf==3.19.0
По сравнению с использованием Docarray с Pytorch, есть одно основное отличие при использовании его с Tensorflow: хотя TorchTensor Docarray является подклассом torch.Tensor , это не относится к TensorFlowTensor : из -за некоторых технических ограничений tf.Tensor , Docrary's TensorFlowTensor не является подполков tf.Tensor , но в то же время, скорее, в то tf.Tensor время. .tensor Attribute.
Как это влияет на вас? Всякий раз, когда вы хотите получить доступ к данным тензора, скажем, выполните операции с ним или передайте их модели ML, вместо того, чтобы вручить экземпляр TensorFlowTensor , вам необходимо получить доступ к его атрибуту .tensor .
Это будет выглядеть следующим образом:
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Документы - это пиджанские модели (с поворотом), и поэтому они полностью совместимы с Fastapi!
Но почему вы должны их использовать, а не пидбанские модели, которые вы уже знаете и любите? Хороший вопрос!
И чтобы заключить сделку, позвольте нам показать вам, как легко документируют слот в ваше приложение 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 ())Так же, как модель ванильной пидбайки!
Джина приняла Docarray в качестве своей библиотеки для представления и сериализации документов.
Джина позволяет обслуживать модели и услуги, которые построены с Docarray, позволяя вам обслуживать и масштабировать эти приложения, в полной мере используя конфиденциальныематы 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 )Если вы наткнулись на Docarray как клиент Universal Vector Database, вы можете лучше всего думать об этом как о новом виде ORM для векторных баз данных . Задача Докаррея состоит в том, чтобы брать мультимодальные, вложенные и специфичные для домена данные и отобразить их в векторную базу данных, сохранить их там и сделать их возможными: доступными для поиска:
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' )В настоящее время Docarray поддерживает следующие векторные базы данных:
Интеграция OpenSearch в настоящее время ведется.
Конечно, это только одна из вещей, которые может сделать Docarray, поэтому мы рекомендуем вам проверить остальную часть этого Readme!
С Docarray вы можете подключить внешние данные к LLMS через Langchain. Docarray дает вам свободу установить гибкие схемы документов и выбирать из разных бэкэндов для хранения документов. После создания индекса документов вы можете подключить его к приложению Langchain с помощью Docarrayretriver.
Установите Langchain через:
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 )В качестве альтернативы вы можете использовать встроенные векторные магазины. Langchain поддерживает два векторных магазина: docarrayinmemorysearch и docarrayhnswsearch. Оба удобны для пользователя и лучше всего подходят для малых и средних наборов данных.
Docarray является товарным знаком LF AI Projects, LLC