目标
了解嵌入模型的概念及使用
嵌入模型为一段文本创建了一个向量表示。
这很有用,因为这意味着我们可以将文本视为 向量空间 中的内容,并进行诸如语义搜索之类的操作,在向量空间中寻找最相似的文本片段。
Embeddings类是一个设计用来与文本嵌入模型交互的类。
有许多嵌入模型提供商(如OpenAI、百度、智谱等)——这个类旨在为所有这些提供商提供一个标准的接口。
LangChain中的基础Embeddings类提供了两种方法:
一种用于嵌入文档,另一种用于嵌入查询。
前者接受多个文本作为输入,而后者接受单个文本。
之所以将这两个方法分开,是因为一些嵌入提供商对于文档(搜索对象)和查询(搜索查询本身)有不同的嵌入方法。
bge-base-en-v1.5
https://modelscope.cn/models/AI-ModelScope/bge-base-en-v1.5/summary
Rerank模型
bge-large-zh-v1.5
https://modelscope.cn/models/AI-ModelScope/bge-large-zh-v1.5/summary
嵌入模型的使用
本地
#本地 BGE 模型
bge_en_v1p5_model_path = "D:\LLM\Bge_models\bge-base-en-v1.5"
bge_zh_v1p5_model_path = "D:\LLM\Bge_models\bge-large-zh-v1.5"
# 使用GPU
bge_en_emb_model = HuggingFaceEmbeddings(
model_name=bge_en_v1p5_model_path,
model_kwargs={'device': 'cuda:0'},
encode_kwargs={'batch_size': 32, 'normalize_embeddings': True, }
)
# 使用CPU
bge_zh_emb_model = HuggingFaceEmbeddings(
model_name=bge_zh_v1p5_model_path,
model_kwargs={'device': 'cpu'},
encode_kwargs={'batch_size': 32, 'normalize_embeddings': True, }
)
en_embeddings = bge_en_emb_model.embed_documents(
[
"Hi there!",
"Oh, hello!",
"What's your name?",
"My friends call me World",
"Hello World!"
]
)
len(en_embeddings), len(en_embeddings[0])
en_embedded_query = bge_en_emb_model.embed_query("What was the name mentioned in the conversation?")
zh_embeddings = bge_zh_emb_model.embed_documents(
[
"哈喽啊",
"干啥呢!",
"你看啥",
"快去上学!",
"嗯嗯,我知道了"
]
)
len(en_embeddings), len(en_embeddings[0])
zh_embedded_query = bge_zh_emb_model.embed_query("明天怎么去上班?")
远程模型使用
远程百度调用
os.environ["QIANFAN_ACCESS_KEY"] = os.getenv('MY_QIANFAN_ACCESS_KEY')
os.environ["QIANFAN_SECRET_KEY"] = os.getenv('MY_QIANFAN_SECRET_KEY')
# 千帆 bge_large_en or bge_large_zh
embeddings_model = QianfanEmbeddingsEndpoint(model="bge_large_zh", endpoint="bge_large_zh")
baidu_en_embeddings = embeddings_model.embed_documents(
[
"哈喽啊",
"干啥呢!",
"你看啥",
"快去上学!",
"嗯嗯,我知道了"
]
)
len(baidu_en_embeddings), len(baidu_en_embeddings[0])
pass
嵌入模型通过将文本转换为高维空间中的向量来表示文本的语义内容。
这些向量捕获了文本的语义和上下文信息,使得语义上相似的文本在向量空间中彼此接近。
度量这些向量之间相似度的常见方法有以下几种:
- 余弦相似度(Cosine Similarity) :
- 余弦相似度是度量两个向量之间角度的最常用方法,它返回值介于-1(完全不同)和1(完全相同)之间。
- 公式为:cos(θ) = (A·B) / (||A|| ||B||),其中A和B是两个向量,·表示点积,||A||和||B||分别是向量A和B的欧几里得范数(即长度)。
- 余弦相似度不考虑向量的长度,只考虑它们之间的角度,因此它对于度量文本的语义相似度非常有效。
- 欧几里得距离(Euclidean Distance) :
- 欧几里得距离是向量空间中两点之间的直线距离,也称为L2范数。
- 公式为:d(A, B) = √(∑(Ai - Bi)²),其中Ai和B_i是两个向量中的对应元素。
- 欧几里得距离越小,表示两个向量越相似。但是,由于它考虑了向量的长度,它可能不如余弦相似度适合度量文本的语义相似度。
- 曼哈顿距离(Manhattan Distance) :
- 曼哈顿距离是向量空间中两点之间的城市街区距离,也称为L1范数。
- 公式为:d(A, B) = ∑|Ai - Bi|,其中Ai和B_i是两个向量中的对应元素。
- 曼哈顿距离在特定情况下也可能用于度量相似度,但它不像余弦相似度那样直接反映向量的方向关系。
- 皮尔逊相关系数(Pearson Correlation Coefficient) :
- 皮尔逊相关系数用于度量两个变量之间的线性相关性。
- 公式为:ρX,Y = cov(X, Y) / (σX σY),其中cov(X, Y)是X和Y的协方差,σX和σY分别是X和Y的标准差。
- 皮尔逊相关系数的值介于-1和1之间,值越接近1表示正相关性越强,值越接近-1表示负相关性越强,值为0表示没有线性相关性。 在实际应用中,选择哪种相似度度量方法取决于具体的应用场景和需求。例如,在文本检索和推荐系统中,余弦相似度是一种非常流行的选择,因为它能够有效地捕捉文本的语义相似性。而在某些需要考虑向量长度和方向的综合影响的场景中,可能会选择欧几里得距离或曼哈顿距离。皮尔逊相关系数则更多用于分析两个变量之间的关系。
en_question = "What kinds of pets do I like?"
document = "My favorite pet is a cat."
chn_question = "我喜欢什么宠物?"
en_query_result = embeddings_model.embed_query(en_question)
document_result = embeddings_model.embed_query(document)
chn_question_result = embeddings_model.embed_query(chn_question)
en_similarity = cosine_similarity(en_query_result, document_result)
chn_similarity = cosine_similarity(chn_question_result, document_result)
qvq_similarity = cosine_similarity(chn_question_result, en_query_result)
print("EN Cosine Similarity:", en_similarity)
print("CHN Cosine Similarity:", chn_similarity)
print("qvq Cosine Similarity:", qvq_similarity)
------
# 输出
EN Cosine Similarity: 0.8519668706051049
CHN Cosine Similarity: 0.784625358639582
qvq Cosine Similarity: 0.8550725627294596
完整代码
import os
import numpy as np
from langchain_community.embeddings import HuggingFaceEmbeddings, QianfanEmbeddingsEndpoint
def cosine_similarity(vec1, vec2):
dot_product = np.dot(vec1, vec2)
norm_vec1 = np.linalg.norm(vec1)
norm_vec2 = np.linalg.norm(vec2)
return dot_product / (norm_vec1 * norm_vec2)
if
name
== '
__main__
':
# 本地 BGE 模型
bge_en_v1p5_model_path = "D:\LLM\Bge_models\bge-base-en-v1.5"
bge_zh_v1p5_model_path = "D:\LLM\Bge_models\bge-large-zh-v1.5"
# 使用GPU
bge_en_emb_model = HuggingFaceEmbeddings(
model_name=bge_en_v1p5_model_path,
model_kwargs={'device': 'cuda:0'},
encode_kwargs={'batch_size': 32, 'normalize_embeddings': True, }
)
# 使用CPU
bge_zh_emb_model = HuggingFaceEmbeddings(
model_name=bge_zh_v1p5_model_path,
model_kwargs={'device': 'cpu'},
encode_kwargs={'batch_size': 32, 'normalize_embeddings': True, }
)
en_embeddings = bge_en_emb_model.embed_documents(
[
"Hi there!",
"Oh, hello!",
"What's your name?",
"My friends call me World",
"Hello World!"
]
)
len(en_embeddings), len(en_embeddings[0])
en_embedded_query = bge_en_emb_model.embed_query("What was the name mentioned in the conversation?")
zh_embeddings = bge_zh_emb_model.embed_documents(
[
"哈喽啊",
"干啥呢!",
"你看啥",
"快去上学!",
"嗯嗯,我知道了"
]
)
len(en_embeddings), len(en_embeddings[0])
zh_embedded_query = bge_zh_emb_model.embed_query("明天怎么去上班?")
# 远程百度调用
os.environ["QIANFAN_ACCESS_KEY"] = os.getenv('MY_QIANFAN_ACCESS_KEY')
os.environ["QIANFAN_SECRET_KEY"] = os.getenv('MY_QIANFAN_SECRET_KEY')
# 千帆 bge_large_en or bge_large_zh
embeddings_model = QianfanEmbeddingsEndpoint(model="bge_large_zh", endpoint="bge_large_zh")
baidu_zh_embeddings = embeddings_model.embed_documents(
[
"哈喽啊",
"干啥呢!",
"你看啥",
"快去上学!",
"嗯嗯,我知道了"
]
)
len(baidu_zh_embeddings), len(baidu_zh_embeddings[0])
pass
en_question = "What kinds of pets do I like?"
document = "My favorite pet is a cat."
chn_question = "我喜欢什么宠物?"
en_query_result = embeddings_model.embed_query(en_question)
document_result = embeddings_model.embed_query(document)
chn_question_result = embeddings_model.embed_query(chn_question)
en_similarity = cosine_similarity(en_query_result, document_result)
chn_similarity = cosine_similarity(chn_question_result, document_result)
qvq_similarity = cosine_similarity(chn_question_result, en_query_result)
print("EN Cosine Similarity:", en_similarity)
print("CHN Cosine Similarity:", chn_similarity)
print("qvq Cosine Similarity:", qvq_similarity)