02_DocQA 无需API key,使用开源Embedding模型嵌入空间向量 | 豆包MarsCode AI 刷题

382 阅读4分钟

文章首发CSDN——《使用开源Embedding模型嵌入高维空间向量》

发现问题

今天在学AI的时候发现一个问题:我想将分割后的文档嵌入到Qdrant数据库中,并用moonshot访问。但是我发现moonshot模型不适合生成嵌入,也就是说,没有通常意义下的embeddings方法。

探索过程

这个问题困扰了我好长时间,一直在搜资料怎样让moonshot可以生成嵌入,最终也没找到方法...

不过过程中ai还是给出了一个可行的解决方法

AI:可以使用OpenAI的嵌入模型

我:???

我肯定知道OpenAI的模型能用啊...

这里还是贴一下OpenAI使用的代码吧,有条件的可以使用这个:

需要再安装一个库

pip install qdrant-client
#将分割嵌入并存储在矢量数据库Qdrant中
from langchain.vectorstores import Qdrant
from langchain.embeddings import OpenAIEmbeddings
vectorstore = Qdrant.from_documents(
    documents=chunked_documents, # 以分块的文档
    embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入
    location=":memory:",  # in-memory 存储
    collection_name="my_documents",) # 指定collection_name

需要提前配置好OpenAI的key

进一步探索

其实上面的回答并不能解决实际问题,毕竟,要是能用OpenAI的模型也就不去费这个劲了~

那么,看看火山模型是怎么解决的!

from langchain_community.vectorstores import Qdrant
from volcenginesdkarkruntime import Ark
from langchain.pydantic_v1 import BaseModel
from typing import Dict, List, Any
from langchain.embeddings.base import Embeddings

# 火山模型
class DoubaoEmbeddings(BaseModel, Embeddings):
    client: Ark = None
    api_key: str = ""
    model: str

    def __init__(self, **data: Any):
        super().__init__(**data)
        if self.api_key == "":
            self.api_key = os.environ["OPENAI_API_KEY"]
        self.client = Ark(
            base_url=os.environ["OPENAI_BASE_URL"],
            api_key=self.api_key
        )

    def embed_query(self, text: str) -> List[float]:
        embeddings = self.client.embeddings.create(model=self.model, input=text)
        return embeddings.data[0].embedding
        
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [self.embed_query(text) for text in texts]

    class Config:
        arbitrary_types_allowed = True


vectorstore = Qdrant.from_documents(
    documents=chunked_documents,  # 以分块的文档
    embedding=DoubaoEmbeddings(
        model=os.environ["EMBEDDING_MODELEND"],
    ),  # 用OpenAI的Embedding Model做嵌入
    location=":memory:",  # in-memory 存储
    collection_name="my_documents",
)  # 指定collection_name

诶! 我有个主意

我们把里面的换成moonshot的不就行了?

答案是:不行!

会报如下错:

    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
AttributeError: 'Moonshot' object has no attribute 'embeddings'

也是,拿过来改改就能用也太不合理了

最终探索

到了这步有点进行不下去了,突然想到一个问题:

嵌入模型必须和语言模型一致才能使用吗?

诶,还真不是!

Embedding模型在NLP中只负责将词汇映射为高维空间向量,与后续的语言模型并不需要使用统一个。

那现在问题就很简单了,有没有什么开源的Embedding模型呢?

Sentence Transformers (Sentence-BERT):这是一个基于 BERT 的嵌入模型,可以生成高质量的句子嵌入。

上手!

先下载一下对应的库

pip install transformers

接下来就是见证奇迹的时刻

from langchain_community.vectorstores import Qdrant
from typing import Dict, List, Any
from sentence_transformers import SentenceTransformer

class SentenceBERTEmbeddings:
    def __init__(self, model_name='all-MiniLM-L6-v2'):
        self.model = SentenceTransformer(model_name)

    def embed_query(self, text: str) -> List[float]:
        return self.model.encode(text).tolist()

    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [self.embed_query(text) for text in texts]

    def __call__(self, text: str) -> List[float]:
        return self.embed_query(text)

    class Config:
        arbitrary_types_allowed = True


vectorstore = Qdrant.from_documents(
    documents=chunked_documents, # 以分块的文档
    embedding=SentenceBERTEmbeddings(), # 用OpenAI的Embedding Model做嵌入
    location=":memory:",  # in-memory 存储
    collection_name="my_documents",) # 指定collection_name

在这里插入图片描述

搞定!

拓展

什么是NLP?

NLP(Natural Language Processing),也就是人们常说的 自然语言处理,就是研究如何让计算机读懂人类语言,即将人的自然语言转换为计算机可以阅读的指令。

分词是 NLP 任务的一个起始,分词的好坏会影响整体模型的好坏。并且分词不一样,语义不一样。

hanLP 是 NLP 处理工具,它是处理文本的工具,hanlp 拥有:中文分词、命名实体识别、摘要关键字、句法分析、简繁拼音转换、智能推荐。

NLP 还有很多处理工具,不同的处理工具处理的方法不一样,例如对一个词标注的标注可能不一样。

开源Embedding模型只有Sentence-BERT这一个吗?

当然不是,这里简单列举几个:

  1. Word2Vec:由Google提出的一种词向量化方法,基于分布假设——出现在相似上下文中的单词往往具有相似的意义。
  2. GloVe (Global Vectors for Word Representation) :由斯坦福大学的研究人员提出,结合全局统计信息与局部上下文信息来构建词向量。
  3. BERT (Bidirectional Encoder Representations from Transformers) :基于Transformer架构设计而成的预训练语言模型,能够在双向上下文中对句子进行编码。
  4. FastText:由Facebook提出,可以捕捉到词汇的n-gram特征,从而更好地处理词的形态变化和拼写错误。

更多的可以去 Huggingface上的MTEB排行榜了解一下

MTEB Leaderboard - a Hugging Face Space by mteb