
โครงสร้างข้อมูลสำหรับข้อมูลหลายรูปแบบ
หมายเหตุ readme ที่คุณกำลังดูอยู่สำหรับ docarray> 0.30 ซึ่งแนะนำการเปลี่ยนแปลงที่สำคัญบางอย่างจาก docarray 0.21 หากคุณต้องการใช้ docarray รุ่นเก่าต่อไป <= 0.21 ตรวจสอบให้แน่ใจว่าคุณติดตั้งผ่าน
pip install docarray==0.21อ้างถึง Codebase เอกสารและสาขา Hot-Fixes สำหรับข้อมูลเพิ่มเติม
Docarray เป็นห้องสมุด Python ที่สร้างขึ้นอย่างเชี่ยวชาญสำหรับการเป็นตัวแทนการส่งการจัดเก็บและการดึงข้อมูลหลายรูปแบบ ได้รับการปรับแต่งสำหรับการพัฒนาแอพพลิเคชั่น AI แบบหลายรูปแบบการออกแบบรับประกันการรวมเข้ากับระบบนิเวศของ Python และการเรียนรู้ของเครื่องจักรที่กว้างขวาง ณ เดือนมกราคม 2565 DOCARRAY มีการแจกจ่ายอย่างเปิดเผยภายใต้ Apache License 2.0 และปัจจุบันมีสถานะของโครงการ Sandbox ภายใน LF AI & Data Foundation
ในการติดตั้ง docarray จาก CLI ให้เรียกใช้คำสั่งต่อไปนี้:
pip install -U docarrayหมายเหตุ ที่จะใช้ docarray <= 0.21 ตรวจสอบให้แน่ใจว่าคุณติดตั้งผ่าน
pip install docarray==0.21และตรวจสอบ codebase และ docs และสาขาการแก้ไขร้อน
ใหม่สำหรับ docarray? ขึ้นอยู่กับกรณีการใช้งานและพื้นหลังของคุณมีหลายวิธีในการเรียนรู้เกี่ยวกับ docarray:
Docarray ช่วยให้คุณเป็น ตัวแทนของข้อมูลของคุณ ในลักษณะที่ปรับให้เข้ากับการเรียนรู้ของเครื่องโดยเนื้อแท้
สิ่งนี้เป็นประโยชน์อย่างยิ่งสำหรับสถานการณ์ต่าง ๆ :
คุ้นเคยกับ Pydantic? คุณจะยินดีที่จะเรียนรู้ว่า Docarray ไม่เพียง แต่สร้างขึ้นบน Pydantic เท่านั้น แต่ยังรักษาความเข้ากันได้อย่างสมบูรณ์ด้วย! นอกจากนี้เรามีส่วนเฉพาะที่อุทิศให้กับความต้องการของคุณ!
ในสาระสำคัญ Docarray อำนวยความสะดวกในการเป็นตัวแทนข้อมูลในลักษณะที่สะท้อน Dataclasses 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 เทนเซอร์ทั้งหมดในเอกสารจะถูกซ้อนกันเป็นเทนเซอร์เดียว เหมาะสำหรับการประมวลผลแบบแบทช์และการใช้งานภายในรุ่น MLDocList : รายการ 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 จะถูก parametrized ตามประเภทของเอกสารที่ คุณต้องการใช้กับมัน: 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 และ Serialization ถึง JSON, JSONSCHEMA, BASE64 และ BYTES
คุณสมบัตินี้พิสูจน์ได้ว่าเป็นประโยชน์สำหรับหลาย ๆ สถานการณ์:
คุณคุ้นเคยกับ 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 อย่างไร
หลังจากการสร้างแบบจำลองและอาจแจกจ่ายข้อมูลของคุณคุณจะต้อง จัดเก็บไว้ ที่ไหนสักแห่ง นั่นคือสิ่งที่ Docarray ก้าวเข้ามา!
ที่เก็บเอกสาร เป็นวิธีที่ไร้รอยต่อตามชื่อแนะนำเก็บเอกสารของคุณ ไม่ว่าจะเป็นในพื้นที่หรือจากระยะไกลคุณสามารถทำได้ทั้งหมดผ่านส่วนต่อประสานผู้ใช้เดียวกัน:
อินเทอร์เฟซที่เก็บเอกสารช่วยให้คุณผลักดันและดึงเอกสารไปและกลับจากแหล่งข้อมูลหลายแหล่งทั้งหมดที่มีส่วนต่อประสานผู้ใช้เดียวกัน
ตัวอย่างเช่นเรามาดูกันว่าใช้งานได้อย่างไรกับที่เก็บข้อมูลบนดิสก์:
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 Vector, การค้นหาข้อความ, การกรองและการค้นหาแบบไฮบริด
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 หรือต่ำกว่าคุณจะคุ้นเคยกับ Dataclass API
Docarray> = 0.30 เป็นความคิดนั้นอย่างจริงจัง เอกสารทุกฉบับถูกสร้างขึ้นผ่านอินเทอร์เฟซที่มีลักษณะคล้ายดาต้าเลสได้รับความอนุเคราะห์จาก Pydantic
สิ่งนี้ให้ข้อได้เปรียบต่อไปนี้:
คุณอาจคุ้นเคยกับร้านค้าเอกสารเก่าของเราสำหรับการรวม DB Vector ตอนนี้พวกเขาเรียกว่า ดัชนีเอกสาร และเสนอการปรับปรุงต่อไปนี้ (ดูที่นี่สำหรับ API ใหม่):
สำหรับตอนนี้ดัชนีเอกสารสนับสนุน Weaviate , Qdrant , Elasticsearch , Redis , Mongo Atlas , การค้นหาเพื่อนบ้านที่ใกล้ที่สุดและ HNSWLIB พร้อมอีกมากมาย
หากคุณมาจาก Pydantic คุณสามารถเห็นเอกสาร Docarray เป็นแบบจำลอง Pydantic และ Docarray เป็นคอลเลกชันของสารพัดรอบ ๆ พวกเขา
โดยเฉพาะอย่างยิ่งเรามุ่งมั่นที่จะ ทำให้ Pydantic พอดีกับ ML World - ไม่ใช่โดยการแทนที่ แต่โดยการสร้างด้านบนของมัน!
ซึ่งหมายความว่าคุณได้รับประโยชน์ต่อไปนี้:
.load() URL ไปยัง Tensor Image, TextUrl สามารถโหลดและ tokenize เอกสารข้อความ ฯลฯ ข้อได้เปรียบที่ชัดเจนที่สุดที่นี่คือ การสนับสนุนชั้นหนึ่งสำหรับข้อมูล ML Centric เช่น {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 เพื่อจัดการและเป็นตัวแทนของ Multimodaldata สิ่งนี้ช่วยให้คุณมีเหตุผลเกี่ยวกับข้อมูลของคุณโดยใช้ abstractions ของ Docarray ลึกลงไปใน nn.Module และให้สคีมาที่เข้ากันได้กับ Fastapi ซึ่งช่วยลดการเปลี่ยนแปลงระหว่างการฝึกอบรมแบบจำลองและการให้บริการแบบจำลอง
หากต้องการดูผลของสิ่งนี้ก่อนอื่นมาสังเกตการใช้งาน Vanilla Pytorch ของโมเดล MOL 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 ,
) ไม่ง่ายมากในสายตาถ้าคุณถามเรา และยิ่งแย่ไปกว่านั้นหากคุณต้องการเพิ่มวิธีการอีกหนึ่งรูปแบบที่คุณต้องสัมผัสทุกส่วนของฐานรหัสของคุณเปลี่ยนประเภทการส่งคืน 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 และนำคำจำกัดความของเอกสารของคุณกลับมาใช้ใหม่ (ดูด้านล่าง) ทุกอย่างได้รับการจัดการในรูปแบบ Pythonic โดยอาศัยคำแนะนำประเภท
เช่นเดียวกับวิธี Pytorch คุณยังสามารถใช้ docarray กับ tensorflow เพื่อจัดการและแสดงข้อมูลหลายรูปแบบภายในโมเดล ML ของคุณ
ก่อนอื่นต้องใช้ docarray กับ tensorflow ก่อนอื่นเราต้องติดตั้งมันดังนี้:
pip install tensorflow==2.12.0
pip install protobuf==3.19.0
เมื่อเปรียบเทียบกับการใช้ docarray กับ pytorch มีความแตกต่างหลักอย่างหนึ่งเมื่อใช้กับ tensorflow: tf.Tensor ขณะที่ TorchTensor ของ Docarray เป็น subclass ของ torch.Tensor tf.Tensor นี่ไม่ใช่กรณีของ TensorFlowTensor TensorFlowTensor tf.Tensor แอตทริบิวต์ .tensor
สิ่งนี้ส่งผลกระทบต่อคุณอย่างไร? เมื่อใดก็ตามที่คุณต้องการเข้าถึงข้อมูลเทนเซอร์ให้พูดว่าดำเนินการกับมันหรือส่งไปยังโมเดล 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เอกสารเป็นโมเดล Pydantic (ด้วยการบิด) และเช่นนี้จึงเข้ากันได้อย่างสมบูรณ์กับ Fastapi!
แต่ทำไมคุณควรใช้พวกเขาและไม่ใช่โมเดล Pydantic ที่คุณรู้จักและชื่นชอบอยู่แล้ว? คำถามที่ดี!
และเพื่อปิดผนึกข้อตกลงให้เราแสดงให้คุณเห็นว่าเอกสารสล็อตลงในแอพ 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 ())เหมือนรุ่นวานิลลา pydantic!
Jina ได้นำ Docarray มาใช้เป็นห้องสมุดของพวกเขาสำหรับการเป็นตัวแทนและการจัดลำดับเอกสาร
Jina อนุญาตให้บริการแบบจำลองและบริการที่สร้างขึ้นด้วย 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 เป็นไคลเอนต์ฐานข้อมูลเวกเตอร์สากลคุณสามารถคิดได้ดีที่สุดว่าเป็น ORM รูปแบบใหม่สำหรับฐานข้อมูลเวกเตอร์ งานของ Docarray คือการใช้ข้อมูลแบบหลายรูปแบบซ้อนกันและเฉพาะโดเมนและทำแผนที่ไปยังฐานข้อมูลเวกเตอร์เก็บไว้ที่นั่นและทำให้สามารถค้นหาได้:
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 ของคุณโดยใช้ docarrayRetriever
ติดตั้ง 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, LLC