Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BGE-M3如何在RAG应用中使用Hybrid Retrieve #458

Open
weiminw opened this issue Feb 11, 2024 · 14 comments
Open

BGE-M3如何在RAG应用中使用Hybrid Retrieve #458

weiminw opened this issue Feb 11, 2024 · 14 comments

Comments

@weiminw
Copy link

weiminw commented Feb 11, 2024

首先感谢BGE提供的这么强大的模型, 我们在之前的RAG应用中, 对企业的文档通过BGE将资料转成向量存储到milvus中, 用户查询时通过dense retrieve 从milvus召回文档,我们使用的是langchain作为框架. 请问如果用BGE配合使用做 dense+sparse retrieve 有没有例子可以参考. 目前是在不知道如何进行. 万分感谢.

@weiminw
Copy link
Author

weiminw commented Feb 11, 2024

我能想到的使用流程大概是这样的, 对原始的文档, 通过BGE-M3 进行向量化, 由于M3 可以同时返回dense 和 sparse embeding. 将两种向量同时存入miluvs中不同的列, 检索的时候, 使用M3 将query同时向量化dense和sparse 同时进行检索. 获得dense+ sparse 再进行rerank. 这个思路是否正确?

@staoxiao
Copy link
Collaborator

感谢对我们工作的关注!
sparse embeding不能像dense embedding那样使用,需要其他方法建立索引。目前miluvs似乎已经支持sprase索引,参考milvus-io/milvus#29419 。后面我们会逐步与开源社区合作把混合检索这块弄得更简单使用。

建好索引后,可让dense和sparse索引分别检索一部分数据,再获得dense+ sparse进行重排,也可以利用其他方法重排。

@weiminw
Copy link
Author

weiminw commented Feb 12, 2024

非常感谢您的回复,祝新年快乐,bge越来越好

@Mrfranken
Copy link

@weiminw @staoxiao hi, 不好意思打扰了。最近拜读了贵项目文件夹目录下MLDR的相关检索代码。
其中包含了spaser和dense结合FAISS的应用,请问是否有关于multi-vector(Colbert)结合FAISS的示例呢。我查阅了很多资料,似乎都没有Colbert verctor和FAISS结合的例子,先感谢您的回复了~

@Mrfranken
Copy link

@weiminw BTW , MLDR目录下似乎已经有了使用hybrid检索的例子,您可以看一下

@staoxiao
Copy link
Collaborator

@weiminw @staoxiao hi, 不好意思打扰了。最近拜读了贵项目文件夹目录下MLDR的相关检索代码。 其中包含了spaser和dense结合FAISS的应用,请问是否有关于multi-vector(Colbert)结合FAISS的示例呢。我查阅了很多资料,似乎都没有Colbert verctor和FAISS结合的例子,先感谢您的回复了~

multi-vector(Colbert)在第一阶段比较难使用,空间和时间消耗都很大,该向量需要进一步压缩,暂时不推荐使用。

@aus70
Copy link

aus70 commented Feb 24, 2024

qdrant 支持稠密向量和稀疏向量,我打算试一试,实现 Vespa 使用的加权稠密/稀疏/科尔伯特检索。

@Mrfranken
Copy link

qdrant 支持稠密向量和稀疏向量,我打算试一试,实现 Vespa 使用的加权稠密/稀疏/科尔伯特检索。

hi 请问您qdrant研究有进展吗,能否交流一下

@aus70
Copy link

aus70 commented Feb 26, 2024

我刚刚完成了我的小型平台,该平台可以批量处理文档,并将嵌入内容保存为 avro 格式。我使用 Podman 而不是 Docker 启动了一个 qdrant 实例,没有出现任何问题。今天晚些时候,我将开始为向量编制索引,并向大家汇报进展情况。

@Mrfranken
Copy link

我刚刚完成了我的小型平台,该平台可以批量处理文档,并将嵌入内容保存为 avro 格式。我使用 Podman 而不是 Docker 启动了一个 qdrant 实例,没有出现任何问题。今天晚些时候,我将开始为向量编制索引,并向大家汇报进展情况。

If you could, could u make a tutorial for how to use podman to run qdrant and combine them with BGE M3, I think that will be great!

@dl942702882
Copy link

dl942702882 commented Mar 13, 2024

qdrant 支持稠密向量和稀疏向量,我打算试一试,实现 Vespa 使用的加权稠密/稀疏/科尔伯特检索。

我刚才试过了,本地模式下,还是采用的暴力求解的方式,通过计算2个稀疏向量的dot #product后排序完成检索过程(https://github.com/qdrant/qdrant-client/blob/master/qdrant_client/local/sparse.py#L60);

不过这不是我想要的,在大数据集下,应该有一种合适的存储 & 索引机制同时能够满足 低成本的存储 以及 高效的topn检索。跟dense向量类似。

qdrant的代码可以参考下面的:

from qdrant_client import QdrantClient, models

COLLECTION_NAME = "sparse_collection"


def cal_text_sparse(text):
    query = bge_m3.encode([text],
                          return_dense=True, return_sparse=True, return_colbert_vecs=True)
    query_sparse = query['lexical_weights'][0]
    print(query_sparse)
    query_sparse_indices = list(query_sparse.keys())
    query_sparse_values = list(query_sparse.values())
    return query_sparse_indices, query_sparse_values

if __name__ == '__main__':
  
    client = QdrantClient(":memory:")
    client.recreate_collection(
        collection_name=COLLECTION_NAME,
        vectors_config={},
        sparse_vectors_config={
            "text": models.SparseVectorParams(
                index=models.SparseIndexParams(
                    on_disk=True,
                )
            )
        },
    )
    doc1_indices, doc1_values = cal_text_sparse("北京是中国的首都")
    doc2_indices, doc2_values = cal_text_sparse("原神是米哈游开发的一款画质精美的二次元游戏")
    doc3_indices, doc3_values = cal_text_sparse("腾讯是中国的一家游戏,社交公司,开发了王者荣耀")
    doc4_indices, doc4_values = cal_text_sparse("众神派对是一款不氪金的手游,画质非常不错")
    client.upsert(
        collection_name=COLLECTION_NAME,
        points=[
            models.PointStruct(
                id=1,
                payload={},
                vector={
                    "text": models.SparseVector(
                        indices=doc1_indices, values=doc1_values
                    )
                },
            ),
            models.PointStruct(
                id=2,
                payload={},
                vector={
                    "text": models.SparseVector(
                        indices=doc2_indices, values=doc2_values
                    )
                },
            ),
            models.PointStruct(
                id=3,
                payload={},
                vector={
                    "text": models.SparseVector(
                        indices=doc3_indices, values=doc3_values
                    )
                },
            ),
            models.PointStruct(
                id=4,
                payload={},
                vector={
                    "text": models.SparseVector(
                        indices=doc4_indices, values=doc4_values
                    )
                },
            )
        ],
    )

    # Preparing a query vector
    query_text = "给我推荐一个画质漂亮的手游吧"
    query_indices, query_values = cal_text_sparse(query_text)
    # Searching for similar documents
    result = client.search(
        collection_name=COLLECTION_NAME,
        query_vector=models.NamedSparseVector(
            name="text",
            vector=models.SparseVector(
                indices=query_indices,
                values=query_values,
            ),
        ),
        with_vectors=True,
    )
    print(len(result))

    for item in result:
        print(item)

@staoxiao
Copy link
Collaborator

The new version of Milvus has been released. Now, you can use the hybrid retrieval of bge-m3 following https://github.com/milvus-io/pymilvus/blob/master/examples/hello_hybrid_sparse_dense.py

@c121914yu
Copy link

The new version of Milvus has been released. Now, you can use the hybrid retrieval of bge-m3 following https://github.com/milvus-io/pymilvus/blob/master/examples/hello_hybrid_sparse_dense.py

似乎就是分别计算2个向量得分后通过RRF进行重新排序。

@Mycroft-s
Copy link

The new version of Milvus has been released. Now, you can use the hybrid retrieval of bge-m3 following https://github.com/milvus-io/pymilvus/blob/master/examples/hello_hybrid_sparse_dense.py

@staoxiao @c121914yu 不好意思打扰了,感谢BGE模型卓越的性能,请问对于[dense,sparse]的混合搜索结果,能否有方法使用大模型的api进行rerank。目前设计的hybrid_earch方法似乎是根据两种向量的相似度得分用RRF进行rerank的,貌似都是基于milvus的向量之间的重排。您觉得对于RRF之后的结果使用大模型再次重排是否有必要。以及能否有机会针对两种向量使用大模型对于语义进行混合的重排,我们之前的RAG模块是用dense向量找到文本对于文本进行大模型的重排序。再次感谢BGE做出的不可替代的贡献。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants