llama_index 如何部署开源嵌入模型在自动合并检索器中:ValueError:形状(1024,)和(384,)不匹配:1024 (dim 0) != 384 (dim 0)

jdg4fx2g  于 10个月前  发布在  其他
关注(0)|答案(3)|浏览(146)

问题验证

  • 我已经在文档和discord上寻找答案。

问题

我想在自动合并检索中使用开源嵌入模型,如BAAI/bge-m3。我运行了以下代码,但嵌入输出与查询引擎的输入大小不兼容。错误是:ValueError: shapes (1024,) 和 (384,) 不对齐:1024 (dim 0) != 384 (dim 0)
当我使用较小的模型,如BAAI/bge-small-en-v1.5时,代码可以正常工作。有人能解释一下如何调整不同的嵌入模型以适应查询引擎吗?

  1. import os
  2. from llama_index.core import Settings, StorageContext, VectorStoreIndex, load_index_from_storage
  3. from llama_index.core.node_parser import HierarchicalNodeParser, get_leaf_nodes
  4. from llama_index.core.retrievers import AutoMergingRetriever
  5. from llama_index.core.query_engine import RetrieverQueryEngine
  6. from llama_index.embeddings.huggingface import HuggingFaceEmbedding
  7. from llama_index.core import Document
  8. from llama_index.llms.azure_openai import AzureOpenAI
  9. def build_automerging_index(document, LLM, save_dir=None, chunk_sizes=None):
  10. if save_dir is None:
  11. save_dir = os.path.join(os.path.expanduser("~"), "merging_index")
  12. if not os.path.exists(save_dir):
  13. os.makedirs(save_dir)
  14. chunk_sizes = chunk_sizes or [2048, 512, 128]
  15. node_parser = HierarchicalNodeParser.from_defaults(chunk_sizes=chunk_sizes)
  16. nodes = node_parser.get_nodes_from_documents(document)
  17. leaf_nodes = get_leaf_nodes(nodes)
  18. Settings.llm = LLM
  19. Settings.embed_model = Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-m3")
  20. storage_context = StorageContext.from_defaults()
  21. docstore_path = os.path.join(save_dir, 'docstore.json')
  22. if os.path.exists(docstore_path):
  23. automerging_index = load_index_from_storage(StorageContext.from_defaults(persist_dir=save_dir))
  24. else:
  25. storage_context.docstore.add_documents(nodes)
  26. automerging_index = VectorStoreIndex(leaf_nodes, storage_context=storage_context)
  27. automerging_index.storage_context.persist(persist_dir=save_dir)
  28. return automerging_index
  29. def get_automerging_query_engine(automerging_index, similarity_top_k=10):
  30. base_retriever = automerging_index.as_retriever(similarity_top_k=similarity_top_k)
  31. retriever = AutoMergingRetriever(base_retriever, automerging_index.storage_context, verbose=True)
  32. auto_merging_engine = RetrieverQueryEngine.from_args(retriever)
  33. return auto_merging_engine
  34. content = "example...."
  35. document = Document(id="1", text=content)
  36. # Configuration for Azure OpenAI
  37. azure_openai_api_key = "...."
  38. azure_openai_endpoint = "...."
  39. azure_openai_api_version = "....."
  40. # Instantiate OpenAI with Azure configuration
  41. llm = AzureOpenAI(
  42. model="gpt-4o",
  43. deployment_name="deployment_name",
  44. api_key=azure_openai_api_key,
  45. azure_endpoint=azure_openai_endpoint,
  46. api_version=azure_openai_api_version,
  47. )
  48. index = build_automerging_index(
  49. [document],
  50. LLM = llm,
  51. save_dir="./merging_index"
  52. )
  53. query_engine = get_automerging_query_engine(index, similarity_top_k=10)
  54. query = "What is the example content about?"
  55. response = query_engine.query(query)
  56. print(response)
gr8qqesn

gr8qqesn1#

嘿 @Sajad7010!我是一个机器人,可以帮助你解决任何错误、问题或贡献。在我们等待人工协助的同时,让我们一起解决这个问题。
要调整不同的嵌入模型以与您自动合并检索器设置中的查询引擎兼容,您需要确保嵌入模型已集成到向量存储和检索器组件中。以下是根据您提供的代码的逐步指南:

  1. 安装所需软件包:
  1. %pip install llama-index-llms-openai
  2. %pip install llama-index-embeddings-cohere
  1. 设置API密钥:
  1. import os
  2. os.environ["OPENAI_API_KEY"] = "YOUR OPENAI KEY"
  3. os.environ["COHERE_API_KEY"] = "YOUR COHEREAI API KEY"
  1. 加载数据:
  1. from llama_index.core import SimpleDirectoryReader
  2. documents = SimpleDirectoryReader("./data/paul_graham/").load_data()
  1. 创建节点:
  1. from llama_index.core.node_parser import SentenceSplitter
  2. node_parser = SentenceSplitter(chunk_size=512)
  3. nodes = node_parser.get_nodes_from_documents(documents)
  4. for idx, node in enumerate(nodes):
  5. node.id_ = f"node_{idx}"
  1. 定义嵌入模型:
  1. from llama_index.embeddings.cohere import CohereEmbedding
  2. from llama_index.legacy.embeddings.openai import OpenAIEmbedding, OpenAIEmbeddingModelType, OpenAIEmbeddingMode
  3. def cohere_embedding(model_name: str, input_type: str, embedding_type: str) -> CohereEmbedding:
  4. return CohereEmbedding(
  5. api_key=os.environ["COHERE_API_KEY"],
  6. model_name=model_name,
  7. input_type=input_type,
  8. embedding_type=embedding_type,
  9. )
  10. def openai_embedding(model_name: str, mode: str) -> OpenAIEmbedding:
  11. return OpenAIEmbedding(
  12. api_key=os.environ["OPENAI_API_KEY"],
  13. model=model_name,
  14. mode=mode,
  15. )
  1. 为不同嵌入类型创建检索器:
  1. from llama_index.core import VectorStoreIndex
  2. def retriever(nodes, embedding_type="float", model_name="embed-english-v3.0", provider="cohere"):
  3. if provider == "cohere":
  4. embed_model = cohere_embedding(model_name, "search_document", embedding_type)
  5. elif provider == "openai":
  6. embed_model = openai_embedding(model_name, OpenAIEmbeddingMode.TEXT_SEARCH_MODE)
  7. else:
  8. raise ValueError("Unsupported provider")
  9. vector_index = VectorStoreIndex(
  10. nodes,
  11. embed_model=embed_model,
  12. )
  13. retriever = vector_index.as_retriever(
  14. similarity_top_k=2,
  15. embed_model=embed_model,
  16. )
  17. return retriever
  18. retriever_float = retriever(nodes)
  19. retriever_int8 = retriever(nodes, "int8")
  20. retriever_binary = retriever(nodes, "binary")
  21. retriever_ubinary = retriever(nodes, "ubinary")
  22. retriever_openai = retriever(nodes, model_name=OpenAIEmbeddingModelType.TEXT_EMBED_ADA_002, provider="openai")
  1. 将检索器插入查询引擎:
  1. from llama_index.core.query_engine import RetrieverQueryEngine
  2. query_engine_float = RetrieverQueryEngine.from_args(retriever_float)
  3. query_engine_int8 = RetrieverQueryEngine.from_args(retriever_int8)
  4. query_engine_binary = RetrieverQueryEngine.from_args(retriever_binary)
  5. query_engine_ubinary = RetrieverQueryEngine.from_args(retriever_ubinary)
  6. query_engine_openai = RetrieverQueryEngine.from_args(retriever_openai)
  1. 查询引擎:
  1. query_str = "What did the author do growing up?"
  2. response_float = query_engine_float.query(query_str)
  3. response_int8 = query_engine_int8.query(query_str)
  4. response_binary = query_engine_binary.query(query_str)
  5. response_ubinary = query_engine_ubinary.query(query_str)
  6. response_openai = query_engine_openai.query(query_str)
  7. print("Float Embedding Response:", str(response_float))
  8. print("Int8 Embedding Response:", str(response_int8))
  9. print("Binary Embedding Response:", str(response_binary))
  10. print("UBinary Embedding Response:", str(response_ubinary))
  11. print("OpenAI Embedding Response:", str(response_openai))

此外,您还可以使用 AdapterEmbeddingModel 来 Package 任何嵌入模型,并在其上添加适配器层。这对于在下游任务上微调嵌入模型非常有用。以下是如何使用 AdapterEmbeddingModel 的示例:

  1. from llama_index.legacy.embeddings.adapter import AdapterEmbeddingModel
  2. def adapter_embedding(base_embed_model, adapter_path, transform_query=True, device=None):
  3. return AdapterEmbeddingModel(
  4. base_embed_model=base_embed_model,
  5. adapter_path=adapter_path,
  6. transform_query=transform_query,
  7. device=device
  8. )

通过遵循这些步骤,您可以调整不同的嵌入模型以与您自动合并检索器设置中的查询引擎兼容。关键是确保嵌入模型已正确集成到向量存储和检索器组件中。此外,您还可以使用诸如Hit-Rate和MRR(Mean-Reciprocal-Rank)之类的指标来评估不同嵌入类型的性能,以选择最适合您需求的最佳模型 1(https://github.com/run-llama/llama_index/blob/main/docs/docs/examples/retrievers/auto_merging_retriever.ipynb)2(https://github.com/run-llama/llama_index/blob/main/llama-index-integrations/embeddings/llama-index-embeddings-adapter/llama_index/embeddings/adapter/base.py)3(https://github.com/run-llama/llama_index/blob/main/docs/docs/examples/cookbooks/cohere_retriever_eval.ipynb)4(https://github.com/run-llama/llama_index/blob/main/llama-index-legacy/llama_index/legacy/embeddings/adapter.py)5(https://github.com/run-llama/llama_index/blob/main/llama-index-legacy/llama_index/legacy/embeddings/openai.py)。

  • 要继续与 Dosu 对话,请提及 @dosu。*
展开查看全部
xzv2uavs

xzv2uavs2#

@Sajad7010听起来你用了一个嵌入模型来构建索引,然后用另一个模型进行查询。
如果你想更换嵌入模型,你需要重建索引。非常重要的一点是,用于构建和查询的嵌入模型必须相同。

w6mmgewl

w6mmgewl3#

@Sajad7010 听起来你用了一个嵌入模型构建索引,然后用另一个嵌入模型进行查询。
如果你想更换嵌入模型,你需要重建索引。非常重要的一点是,用于构建和查询的嵌入模型必须相同。
@logan-markewich 我不明白你的观点。我只调用了 build_automerging_index 函数来构建嵌入模型,仅此而已。我觉得问题可能是一些嵌入模型生成的大向量尺寸与查询不匹配,但我不知道该如何调整!

相关问题