Fleet Context Embeddings - 为Llamaindex库构建混合搜索引擎
在本指南中,我们将使用 Fleet Context 下载 LlamaIndex 文档的嵌入向量,并基于此构建一个混合稠密/稀疏向量检索引擎。
!pip install llama-index!pip install --upgrade fleet-contextimport osimport openai
os.environ["OPENAI_API_KEY"] = "sk-..." # add your API key here!openai.api_key = os.environ["OPENAI_API_KEY"]从 Fleet Context 下载嵌入向量
Section titled “Download Embeddings from Fleet Context”我们将使用 Fleet Context 下载整个 LlamaIndex 文档的嵌入向量(约1.2万个文本块,约100MB内容)。您可以通过指定库名称作为参数,下载前1220个热门库中任意一个的嵌入。您可以在页面底部此处查看支持的完整库列表。
我们这样做是因为 Fleet 构建了一个嵌入管道,能够保留许多重要信息,这些信息将提升检索和生成效果,包括页面位置(用于重新排序)、区块类型(类/函数/属性等)、父级章节等更多内容。您可以在他们的Github 页面上了解更多相关信息。
from context import download_embeddings
df = download_embeddings("llamaindex")输出:
100%|██████████| 83.7M/83.7M [00:03<00:00, 27.4MiB/s] id \ 0 e268e2a1-9193-4e7b-bb9b-7a4cb88fc735 1 e495514b-1378-4696-aaf9-44af948de1a1 2 e804f616-7db0-4455-9a06-49dd275f3139 3 eb85c854-78f1-4116-ae08-53b2a2a9fa41 4 edfc116e-cf58-4118-bad4-c4bc0ca1495e# Show some examples of the metadatadf["metadata"][0]display(Markdown(f"{df['metadata'][8000]['text']}"))输出:
classmethod from_dict(data: Dict[str, Any], kwargs: Any) → Self classmethod from_json(data_str: str, kwargs: Any) → Self classmethod from_orm(obj: Any) → Model json(, include: Optional[Union[AbstractSetIntStr, MappingIntStrAny]] = None, exclude: Optional[Union[AbstractSetIntStr, MappingIntStrAny]] = None, by_alias: bool = False, skip_defaults: Optional[bool] = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, encoder: Optional[Callable[[Any], Any]] = None, models_as_dict: bool = True*, dumps_kwargs: Any) → unicode Generate a JSON representation of the model, include and exclude arguments as per dict().在LlamaIndex中为混合搜索创建Pinecone索引
Section titled “Create Pinecone Index for Hybrid Search in LlamaIndex”我们将创建一个Pinecone索引并在其中上传向量,以便能够同时使用稀疏向量和密集向量进行混合检索。请确保您已拥有Pinecone账户再继续操作。
import loggingimport sys
logging.basicConfig(stream=sys.stdout, level=logging.INFO)logging.getLogger().handlers = []logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))import pinecone
api_key = "..." # Add your Pinecone API key herepinecone.init( api_key=api_key, environment="us-east-1-aws") # Add your db region here# Fleet Context uses the text-embedding-ada-002 model from OpenAI with 1536 dimensions.
# NOTE: Pinecone requires dotproduct similarity for hybrid searchpinecone.create_index( "quickstart-fleet-context", dimension=1536, metric="dotproduct", pod_type="p1",)
pinecone.describe_index( "quickstart-fleet-context") # Make sure you create an index in pineconefrom llama_index.vector_stores.pinecone import PineconeVectorStore
pinecone_index = pinecone.Index("quickstart-fleet-context")vector_store = PineconeVectorStore(pinecone_index, add_sparse_vector=True)批量将向量更新插入到Pinecone
Section titled “Batch upsert vectors into Pinecone”Pinecone建议每次上传100个向量。我们将在稍微修改数据格式后执行此操作。
import randomimport itertools
def chunks(iterable, batch_size=100): """A helper function to break an iterable into chunks of size batch_size.""" it = iter(iterable) chunk = tuple(itertools.islice(it, batch_size)) while chunk: yield chunk chunk = tuple(itertools.islice(it, batch_size))
# generator that generates many (id, vector, metadata, sparse_values) pairsdata_generator = map( lambda row: { "id": row[1]["id"], "values": row[1]["values"], "metadata": row[1]["metadata"], "sparse_values": row[1]["sparse_values"], }, df.iterrows(),)
# Upsert data with 1000 vectors per upsert requestfor ids_vectors_chunk in chunks(data_generator, batch_size=100): print(f"Upserting {len(ids_vectors_chunk)} vectors...") pinecone_index.upsert(vectors=ids_vectors_chunk)在LlamaIndex中构建Pinecone向量存储
Section titled “Build Pinecone Vector Store in LlamaIndex”最后,我们将通过LlamaIndex构建Pinecone向量存储并查询它以获取结果。
from llama_index.core import VectorStoreIndexfrom IPython.display import Markdown, displayindex = VectorStoreIndex.from_vector_store(vector_store=vector_store)query_engine = index.as_query_engine( vector_store_query_mode="hybrid", similarity_top_k=8)response = query_engine.query("How do I use llama_index SimpleDirectoryReader")display(Markdown(f"<b>{response}</b>"))输出:
<b>To use the SimpleDirectoryReader in llama_index, you need to import it from the llama_index library. Once imported, you can create an instance of the SimpleDirectoryReader class by providing the directory path as an argument. Then, you can use the `load_data()` method on the SimpleDirectoryReader instance to load the documents from the specified directory.</b>