교육 목적으로 최소 벡터 데이터베이스.
태그 라인 : 간단하게 유지하면 배우게됩니다 ...
더 배우고 싶습니까? 아래의 '참조'섹션을 확인하십시오.

이 예에서는 초등학교 수학 8K (GSM8K) 데이터 세트를 사용할 것입니다.
from datasets import load_dataset
# Number of samples we want to process
N_SAMPLES = 100
# Load dataset
# https://huggingface.co/datasets/openai/gsm8k
ds = load_dataset ( "openai/gsm8k" , "main" , split = "train" )[: N_SAMPLES ]
questions = ds [ 'question' ]
answers = ds [ 'answer' ] 여기에는 "고품질 question-answer
### Question
Natalia sold clips to 48 of her friends in April, and then she sold half as many clips in May.
How many clips did Natalia sell altogether in April and May?
### Answer
Natalia sold 48/2 = <<48/2=24>>24 clips in May.
Natalia sold 48+24 = <<48+24=72>>72 clips altogether in April and May. #### 72
우리의 목표는 이러한 question-answer 쌍을 삽입으로 바꾸고 VektordB에 보관하고 일부 작업을 수행하는 것입니다.
임베딩은 일반적으로 벡터 형태의 정보 조각의 수치 표현 일뿐입니다. 모든 종류의 데이터를 임베딩으로 바꿀 수 있으며 원본 데이터의 의미를 보존합니다 . 임베딩에 대해 자세히 알아 보려면 의미에서 벡터 및 뒤로 매핑 임베딩을 확인하십시오.
Amazon Bedrock을 통해 Cohere Imbed 모델을 호출하는 도우미 기능을 정의하자
import json
import boto3
# Initialize Bedrock client
bedrock = boto3 . client ( "bedrock-runtime" )
def embed ( texts : list , model_id = "cohere.embed-english-v3" ):
"""Generates embeddings for an array of strings using Cohere Embed models."""
model_provider = model_id . split ( '.' )[ 0 ]
assert model_provider == "cohere" ,
f"Invalid model provider (Got: { model_provider } , Expected: cohere)"
# Prepare payload
accept = "*/*"
content_type = "application/json"
body = json . dumps ({
'texts' : texts ,
'input_type' : "search_document"
})
# Call model
response = bedrock . invoke_model (
body = body ,
modelId = model_id ,
accept = accept ,
contentType = content_type
)
# Process response
response_body = json . loads ( response . get ( 'body' ). read ())
return response_body . get ( 'embeddings' )그리고 그것을 사용하여 데이터의 작은 부분 집합에 대한 임베딩을 생성하는 데 사용하십시오 (지금은 답변 만).
from tqdm import tqdm
# Text call limit for Cohere Embed models via Amazon Bedrock
# https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-embed.html
MAX_TEXTS_PER_CALL = 96
embeddings = []
for idx in tqdm ( range ( 0 , len ( answers ), MAX_TEXTS_PER_CALL ), "Generating embeddings" ):
embeddings += embed ( answers [ idx : idx + MAX_TEXTS_PER_CALL ])이제 VekTordB를 초기화하고 데이터로드를 시작할 준비가되었습니다.
from vektordb import ANNVectorDatabase
from vektordb . types import Vector
# Initialize database
vector_db = ANNVectorDatabase ()
# Load embeddings into the database
for idx in tqdm ( range ( len ( embeddings )), "Loading embeddings" ):
vector_db . insert ( idx , Vector ( embeddings [ idx ], { 'answer' : answers [ idx ][: 20 ]}))사전 확인으로 데이터베이스의 작은 샘플을 인쇄 할 수 있습니다.
vector_db . display (
np_format = {
'edgeitems' : 1 ,
'precision' : 5 ,
'threshold' : 3 ,
'suppress' : True
},
keys = range ( 10 )
) +-----+-------------------------+------------------------------------+
| Key | Data | Metadata |
+-----+-------------------------+------------------------------------+
| 0 | [-0.00618 ... -0.00047] | {'answer': 'Natalia sold 48/2 = '} |
| 1 | [-0.01997 ... -0.01791] | {'answer': 'Weng earns 12/60 = $'} |
| 2 | [-0.00623 ... -0.0061 ] | {'answer': 'In the beginning, Be'} |
| 3 | [-0.07849 ... 0.00721] | {'answer': 'Maila read 12 x 2 = '} |
| 4 | [-0.01669 ... 0.01263] | {'answer': 'He writes each frien'} |
| 5 | [0.02484 ... 0.05185] | {'answer': 'There are 80/100 * 1'} |
| 6 | [-0.01807 ... -0.01859] | {'answer': 'He eats 32 from the '} |
| 7 | [ 0.01265 ... -0.02016] | {'answer': 'To the initial 2 pou'} |
| 8 | [-0.00504 ... 0.0143 ] | {'answer': 'Let S be the amount '} |
| 9 | [-0.0239 ... -0.00905] | {'answer': 'She works 8 hours a '} |
+-----+-------------------------+------------------------------------+
VEKTORDB 인스턴스는 이진 트리를 사용하여 초 공간의 다른 파티션/분할을 나타내는 대략적인 가장 가까운 이웃 (ANN) 검색의 구현으로 뒷받침됩니다.
이 파티션은 두 개의 벡터를 무작위로 선택하여 두 벡터를 임명 한 다음 두 벡터를 임명 한 다음 어느쪽에 있는지에 따라 다른 지점을 left 과 right 으로 나누어 생성됩니다.
이 프로세스는 각 노드에 최대 k 항목이있을 때까지 반복됩니다 (파티션)
나무의 숲을 생성하여 더 나은 결과를 얻을 수 있습니까? 그리고 그들 모두를 검색하므로 그렇게합시다.
import random
# Set seed value for replication
random . seed ( 42 )
# Plant a bunch of trees ?️
vector_db . build ( n_trees = 3 , k = 3 )
print ( vector_db . trees [ 0 ], " n " )다음은 우리 숲 의 첫 번째 나무를 나타내는 것입니다 (노드는 각 파티션의 인스턴스 수를 보여줍니다).
__________100______________
/
________________________________________________63______ __________37___________
/ /
_51__ _12_ 16____ ___21____
/ / / /
6 45____________________ _7 5 2 _14___ _10_ _11_____
/ / / / / / /
3 3 3 __________42_____________ 4 3 2 3 5 _9 _5 5 4 ___7
/ / / / / / / /
___18____ _____24____ 2 2 3 2 6 3 4 1 2 3 3 1 6_ 1
/ / / / /
_8_ _10_ ___11___ _13_ 3 3 1 3 2 4
/ / / / /
4 4 4 6_ 6_ _5 5 8_ 3 1
/ / / / / / / /
2 2 3 1 1 3 2 4 2 4 4 1 2 3 3 5
/ / / /
1 3 3 1 2 2 2 3
마지막으로, 대상 질문과 유사한 답변을 위해 데이터베이스를 단순히 검색하여 쿼리를 실행할 수 있습니다.
우리는 아래에 표시된 것과 같은 거리 기능을 사용하여 두 벡터가 서로 얼마나 유사한지를 정량화합니다.
예를 들어 교육 데이터 세트에서 첫 번째 질문을하면
from vektordb . utils import print_similarity_scores
# Extract first question
query = questions [ 0 ]
print ( " n Query:" , query , " n " )
# Run search and display similarity scores
results = vector_db . search ( embed ([ query ])[ 0 ], 3 )
print_similarity_scores ( results ) 동일한 인덱스 ( 0 )의 답변이 가장 큰 결과가 될 것으로 기대합니다.
Query: Natalia sold clips to 48 of her friends in April, and then she sold half as many clips in May.
How many clips did Natalia sell altogether in April and May?
+-----+---------------------+
| Key | Score |
+-----+---------------------+
| 0 | 0.15148634752350043 |
| 15 | 0.6105711817572272 |
| 83 | 0.6823805943068366 |
+-----+---------------------+
COS 597A (Princeton) : AI의 장기 메모리 - 벡터 검색 및 데이터베이스CMU 15-445/645 (Carnegie Mellon) : 데이터베이스 시스템