llama_index [问题]:检索器文档,嵌入 = None

zpqajqem  于 2个月前  发布在  其他
关注(0)|答案(1)|浏览(21)

问题验证

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

问题

你好,
我有一个关于嵌入的问题,当我使用.retrieve时,我得到了一个NodeWithScore的列表,但是嵌入总是设置为None。我想知道为什么?
以下是我创建检索器的代码:

index = VectorStoreIndex.from_documents([doc], embed_model=embedding_model, transformations=[TokenTextSplitter(
    chunk_size=128, chunk_overlap=50, id_func=my_id_func 
)]  )
 

base_retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=15,
)

r = base_retriever.retrieve(query)
m528fe3b

m528fe3b1#

你好,@Shiro-LK!我在这里帮助你解决任何问题或疑问。我是一个可以帮助你解决bug、回答问题的机器人。让我们一起解决这个问题!
.retrieve方法返回的NodeTextWithScore对象中,嵌入始终设置为None的原因是,VectorIndexRetriever类在其构造的NodeWithScore对象中不包含嵌入。负责创建NodeWithScore对象列表的_build_node_list_from_query_result方法没有设置嵌入属性。
以下是相关代码:

def _build_node_list_from_query_result(
        self, query_result: VectorStoreQueryResult
    ) -> List[NodeWithScore]:
    if query_result.nodes is None:
        # NOTE: vector store does not keep text and returns node indices.
        # Need to recover all nodes from docstore
        if query_result.ids is None:
            raise ValueError(
                "Vector store query result should return at "
                "least one of nodes or ids."
            )
        assert isinstance(self._index.index_struct, IndexDict)
        node_ids = [
            self._index.index_struct.nodes_dict[idx] for idx in query_result.ids
        ]
        nodes = self._docstore.get_nodes(node_ids)
        query_result.nodes = nodes
    else:
        # NOTE: vector store keeps text, returns nodes.
        # Only need to recover image or index nodes from docstore
        for i in range(len(query_result.nodes)):
            source_node = query_result.nodes[i].source_node
            if (not self._vector_store.stores_text) or (
                source_node is not None and source_node.node_type != ObjectType.TEXT
            ):
                node_id = query_result.nodes[i].node_id
                if self._docstore.document_exists(node_id):
                    query_result.nodes[i] = self._docstore.get_node(
                        node_id
                    )  # type: ignore[index]

    log_vector_store_query_result(query_result)

    node_with_scores: List[NodeWithScore] = []
    for ind, node in enumerate(query_result.nodes):
        score: Optional[float] = None
        if query_result.similarities is not None:
            score = query_result.similarities[ind]
        node_with_scores.append(NodeWithScore(node=node, score=score))

    return node_with_scores

如您所见,NodeWithScore对象仅使用nodescore属性创建,而embedding属性未设置。
要包含嵌入,您需要修改_build_node_list_from_query_result方法,以便在NodeWithScore对象中设置embedding属性。然而,这需要访问来自query_result的嵌入。
如果您需要嵌入被包含,您可能需要扩展VectorIndexRetriever类的功能,或者在应用程序逻辑中单独处理嵌入。此外,您可以查看负责检索带有嵌入的节点的_get_nodes_with_embeddings方法,以确保嵌入得到正确处理并包含在结果中。
SummaryIndexEmbeddingRetriever类中,_retrieve方法展示了如何处理嵌入:

def _retrieve(
        self,
        query_bundle: QueryBundle,
    ) -> List[NodeWithScore]:
    """Retrieve nodes."""
    node_ids = self._index.index_struct.nodes
    # top k nodes
    nodes = self._index.docstore.get_nodes(node_ids)
    query_embedding, node_embeddings = self._get_embeddings(query_bundle, nodes)

    top_similarities, top_idxs = get_top_k_embeddings(
        query_embedding,
        node_embeddings,
        similarity_top_k=self._similarity_top_k,
        embedding_ids=list(range(len(nodes))),
    )

    top_k_nodes = [nodes[i] for i in top_idxs]

    node_with_scores = []
    for node, similarity in zip(top_k_nodes, top_similarities):
        node_with_scores.append(NodeWithScore(node=node, score=similarity))

    logger.debug(f"> Top {len(top_idxs)} nodes:\n")
    nl = "\n"
    logger.debug(f"{ nl.join([n.get_content() for n in top_k_nodes]) }")
    return node_with_scores

此方法确保嵌入包含在查询中并用于检索相关节点。您可以采用类似的方法来确保嵌入包含在您的NodeWithScore对象中。

  • 要继续与@dosu对话,请提及@dosu。*

相关问题