← 返回博客
跳至主要内容

为什么、何时以及如何微调自定义嵌入模型

·阅读 13 分钟
Leonie Monigatti

Fine-tuning an embedding model

嵌入模型是许多自然语言处理 (NLP) 任务的核心,包括依赖检索的生成式 AI 系统。然而,现成的嵌入模型通常仅限于通用知识,而不是公司或领域特定的知识。通过微调自定义嵌入模型可以提高检索性能,从而提高您的 检索增强生成 (RAG) 系统的端到端性能。

本文解释了为什么、何时以及何时不应该微调嵌入模型,以及关键注意事项,包括最佳实践和常见陷阱。请注意,这篇博客文章重点关注文本嵌入模型,尽管许多概念也适用于多模态模型。

为什么应该微调嵌入模型

当现成的模型无法有效捕捉领域特定细微差别时,微调嵌入模型可以提高检索管道的性能。嵌入模型为现代向量搜索管道提供支持。当您的向量搜索管道的性能未达到您的性能要求时,导致这一问题的原因有很多。(参见“何时(以及何时不)微调嵌入模型”)例如,如果模型遗漏了领域特定的语义关系,则微调它可能会提高检索性能。

预训练的嵌入模型通常在大型通用数据集上进行训练,例如 书籍维基百科网络爬取数据。这种局限性可能导致在针对专业任务或领域(例如法律、医疗或技术领域)使用这些预训练嵌入时性能不佳。

已经有专门处理金融、法律或医疗文档的嵌入模型可用。您可以参考 MTEB 排行榜,看看是否有针对您目的的领域特定模型,但请注意,排行榜性能并不总是转化为特定用例的性能。

但是,即使是这些领域特定模型也可能不足,如果您在一个专业领域工作或需要模型来理解您领域或公司特定的术语。

因此,如果您的现成嵌入模型不能充分捕捉领域或公司特定的上下文关系,那么在自定义数据集上微调它可能具有以下优势

  • 提高检索性能,从而提高下游任务的性能(例如,RAG 系统性能)
  • 潜在地降低成本和延迟,因为较小的微调嵌入模型有时在领域特定任务上可以胜过较大的通用替代模型

何时(以及何时不)微调嵌入模型

当您的检索性能不令人满意时,您是否应该始终微调嵌入模型? 否。

向量搜索可能导致性能不佳的原因有很多。以下是一些问题,可以帮助您调试检索管道可能未达到性能要求的原因

  • 您是否有许多需要精确关键字匹配的查询?那么,您可能需要在花费时间和计算资源微调嵌入模型之前,探索 关键字混合搜索技术。
  • 您是否正在使用正确的分块技术?也许您当前使用的分块技术导致分块的上下文过少、分块不规则或分块过大。查看一些分块,并评估您是否需要尝试另一种分块技术,例如 延迟分块
  • 您的嵌入模型是否能够捕捉足够的上下文细微差别?如果它不理解一般的语义关系和领域知识,请先尝试具有更多维度的模型或 延迟交互模型
  • 您的嵌入模型是否仅无法捕捉领域或公司特定的语义关系?那么微调可能是正确的选择。

如您所见,在盲目地微调嵌入模型之前,重要的是评估您的用例是否能够从领域特定的微调中受益。

微调嵌入模型的关键注意事项

本节解释了微调嵌入模型的关键注意事项。它涵盖了计算要求、选择合适的基模型、创建微调数据集、微调的工作原理以及评估其对检索质量的影响。

微调的成本和计算要求

微调预训练的嵌入模型通常不需要像预训练一个模型那样多的计算资源

  • 使用较小数据集微调较小模型的管道甚至可以在消费级 GPU 或 Google Colab 的免费层上运行。
  • 如果您想扩展您的微调管道,您可能需要将训练管道调整为在更大的 GPU 或合适的云平台(如 AWS 或 Google Cloud)上运行。

由于微调可以使用比预训练更少的计算资源完成,并且通常只需要训练几个 epoch,因此微调模型的总成本可能低至 几美元,用于更简单的任务。

选择用于微调的基础嵌入模型

首先,您需要决定将哪个模型用作您的起点。大规模文本嵌入基准 (MTEB) 是查找适合您目的的嵌入模型的绝佳来源。我们建议从轻量级模型开始。 一般假设是,较小的微调模型在领域特定任务上可以胜过较大的通用模型。

请注意,您的模型选择将影响您可以如何自定义它

  • 具有宽松许可的预训练开放权重模型,例如 all-MiniLM-L6-v2BAAI/bge-base-en-v1.5,可以使用 Hugging Face 的 sentence-transformers Python 库进行微调。
  • 对于 OpenAI 或 Cohere 等提供商的专有嵌入模型,请事先检查是否可以通过 API 提供微调。

评估用于微调的基础嵌入模型

我们建议设置一个评估管道,以查看微调是否可以提高您的任务的检索效果。这使您可以将基线模型的性能与微调模型的性能进行比较。

更改嵌入模型会影响下游结果,并需要额外的工作,例如重新嵌入和重新索引所有数据。您应该仅在它能够提高足够的性能以证明成本的情况下才更改模型。

因此,重要的是首先评估基线模型在您的用例上的性能,以确定您的用例是否能够从自定义嵌入模型中受益。此评估还将作为比较微调模型的基础线模型。

为了评估检索性能,我们需要首先准备一个评估数据集。请注意,检索性能是使用包含查询及其对应于语料库中相关文档的评估数据集来评估的。因此,评估数据集的结构与微调数据集的结构不同(参见“准备和整理微调数据集”)。与其他机器学习训练类似,请确保您的训练数据集与评估数据集分开,以避免过拟合和数据泄漏。

在评估期间,根据嵌入模型评估与每个查询对应的最相似的 k 个文档与地面真实的相关文档,并使用 检索指标,例如

  • 平均倒数排名 (MRR),
  • 召回率@k 和精确率@k,
  • 平均平均精度 (MAP) 和
  • 归一化折损累积增益 (NDCG)。

如果您已经在使用 Hugging Faces sentence-transformers 库,可以使用 InformationRetrievalEvaluator。或者,还有其他库可用,例如 pytrec_eval

准备和整理微调数据集

您的训练数据集的质量将极大地影响您微调后的嵌入模型的质量。因此,仔细整理高质量的数据集是微调过程中的重要一步,类似于训练其他机器学习模型。

您可以采用三种不同的方法来获取用于微调嵌入模型训练数据集

  • 使用 Hugging Face、Kaggle 或类似平台上的现有数据集
  • 手动创建数据集
  • 生成合成数据集

微调文本嵌入模型所需的样本数量取决于任务的复杂性

  • 对于简单的任务,例如二元分类,少量高质量样本是一个好的起点。
  • 对于更复杂的任务,您可能需要更多样本,因为模型需要捕捉术语之间细微的语义关系。

一个好的做法是从大约 1,000 到 5,000 个高质量样本的基线开始,用于词汇重叠良好且领域范围较窄的数据,并在验证集上评估性能。如果结果达到平台期,则逐步添加更多数据。为具有专业术语的复杂领域规划 10,000+ 个样本。

请注意,- 取决于您的损失函数 - 确保您没有重复的数据点也很重要。一些损失函数,例如多负样本排序损失,将批处理中的其他样本视为负样本对(请参阅下一节)。

微调嵌入模型是如何工作的?

简单来说,微调嵌入模型调整了向量空间中特定文本的距离。与微调大型语言模型 (LLM) 不同,微调嵌入模型使用不同的对比方法。这些方法根据您的目标在训练数据格式和损失函数上有所不同。

与需要显式标签的传统监督学习不同,对比微调利用训练数据中固有的结构。核心原则是,模型通过回答问题“给定这个锚点数据点,哪个候选点最相似?”来学习向量表示。

损失函数在微调过程中起着关键作用,因为它衡量了嵌入模型在给定数据批次上的表现如何,并相应地指导优化过程。损失函数的选择取决于您的目标任务,并影响所需的数据集格式。

让我们探讨一些方法,以便更好地理解

  • 多负样本排序损失:需要相关的句子对(query, context)。它不需要您显式提供负样本,因为它将批处理中的所有其他示例视为负样本,这使其成为一种流行的技术。许多现代嵌入模型使用这种损失的变体来执行语义搜索等任务。 multiple negatives ranking loss
  • 三元组损失:需要由 (anchor, positive, negative) 组成的三元组文本,需要仔细准备数据才能找到有意义的三元组。这非常适合您需要精确控制相似或不相似内容的情况,但由于您需要找到有意义的困难负样本以避免琐碎的三元组,因此很难整理好的数据集。困难负样本是指与锚点相似但应低于正样本排名的示例。 triplet loss
  • 余弦嵌入损失:需要带有相似度分数的句子对,指示它们的相关程度 (sentence_A, sentence_B, score)。这对于您具有不同相似度级别而不是二元相关/不相关判断的情况非常理想。 cosine embedding loss

在训练过程中,优化过程调整模型的参数,以便在嵌入空间中将正样本对拉近,同时将负样本对推远。这创建了一个表示空间,其中语义相似的内容自然地聚集在一起,从而实现有效的检索和相似性搜索。

微调过程的最佳实践

与常见的机器学习微调一样,建议通过广泛的实验进行超参数调整,以避免过拟合等问题。对关键超参数(例如 epoch 数、学习率、批大小等)进行超参数扫描可以帮助您找到最佳超参数配置,从而获得最佳检索性能。确保您有健全的交叉验证策略。

此外,使用模型注册表来跟踪您的嵌入模型可能很有帮助,尤其是在您计划定期使用新数据更新它们时。

如何将自定义嵌入模型与 Weaviate 向量数据库一起使用

您可以使用任何自定义微调的密集嵌入模型与 Weaviate 向量数据库实例一起使用,方法是使用 自带向量 (BYOV) 方法 在导入和查询时手动指定向量。

但是,对于某些自定义模型,您可以选择通过 Weaviate 的向量化模块使用它们。本节介绍如何将自定义微调的嵌入模型用作 Weaviate 的向量化器,以便在导入和查询时自动生成嵌入,而无需手动操作。

本文档假定您已经微调了一个嵌入模型并将其推送到 Hugging Face Hub。一旦嵌入模型在 Hugging Face Hub 上可用,您就可以通过 Hugging Face 集成 或通过 AWS 集成 将其用作向量化器,后者是将模型部署为 Amazon SageMaker 端点(确保您至少有版本 v1.31.2 才能使用此选项)。

选项 1:使用 Hugging Face 模块进行向量化

Weaviate 与 Hugging Face 紧密集成。您可以通过 Hugging Face 集成 轻松地将托管在 Hugging Face Hub 上的任何密集、单向量嵌入模型与您的 Weaviate 向量数据库实例一起使用。

要使用 Hugging Face 集成,您需要在连接到 Weaviate 客户端时提供您的 Hugging Face API 密钥,以及 Weaviate Cloud API 密钥和 URL。

import os
import weaviate
from weaviate.classes.init import Auth

weaviate_url = os.environ["WEAVIATE_URL"]
weaviate_api_key = os.environ["WEAVIATE_API_KEY"]
hf_token = os.environ["HF_TOKEN"]

headers = {
"X-HuggingFace-Api-Key": hf_token,
}

client = weaviate.connect_to_weaviate_cloud(
cluster_url=weaviate_url,
auth_credentials=Auth.api_key(weaviate_key),
headers=headers
)

使用 Hugging Face 集成,使用自定义微调的嵌入模型就像在定义集合时将模型名称作为您的向量化器一样简单。

from weaviate.classes.config import Configure

client.collections.create(
name="DemoCollection",
vector_config=[
Configure.Vectors.text2vec_huggingface(
name="title_vector",
source_properties=["title"],
model="<custom_embedding_model_name>",
),
# Additional parameters not shown
)

选项 2:使用 Amazon SageMaker 模块进行向量化

Weaviate 与 Amazon SageMaker 紧密集成。通过 AWS SageMaker 集成,您可以轻松地将部署为 Amazon SageMaker 端点的任何密集、单向量嵌入模型与您的 Weaviate 向量数据库实例一起使用。

一旦您已经 将嵌入模型从 Hugging Face Hub 部署到 SageMaker 端点,请验证您的端点是否已成功部署并且可以用于推理。为此,您可以在 AWS 管理控制台的 SageMaker 中检查。在导航窗格的“推理”下,您可以选择“端点”并验证您的嵌入模型是否已成功部署。

image.png

要使用 Amazon SageMaker 集成,您需要提供您的 基于访问密钥的 AWS 凭证,以及 Weaviate Cloud API 密钥和 URL,在连接到 Weaviate 客户端时。

import os
import weaviate
from weaviate.classes.init import Auth

weaviate_url = os.environ["WEAVIATE_URL"]
weaviate_api_key = os.environ["WEAVIATE_API_KEY"]
aws_access_key = os.environ["AWS_ACCESS_KEY"]
aws_secret_key = os.environ["AWS_SECRET_KEY"]

headers = {
"X-AWS-Access-Key": aws_access_key,
"X-AWS-Secret-Key": aws_secret_key,
}

client = weaviate.connect_to_weaviate_cloud(
cluster_url=weaviate_url,
auth_credentials=Auth.api_key(weaviate_key),
headers=headers
)

使用 AWS SageMaker 集成,您可以通过将 service 定义为 "sagemaker"、您特定的 AWS region 和您的 SageMaker 端点名称(例如“TEI-…”)来使用自定义微调的嵌入作为您的向量化器。

from weaviate.classes.config import Configure

client.collections.create(
"DemoCollection",
vector_config=[
Configure.Vectors.text2vec_aws(
name="title_vector",
source_properties=["title"],
region="eu-north-1",
service="sagemaker",
endpoint="<custom_sagemaker_url>",
)
],
# Additional parameters not shown
)

请注意,完成使用 SageMaker 端点后不要忘记将其删除。

总结

本文向您介绍了确定您的应用程序是否可以从微调文本嵌入模型中受益,以提高 RAG 系统中的检索性能,以及如何实现它。人们经常在构建 RAG 应用程序或推荐系统时会忽略微调嵌入模型。本文概述了微调嵌入模型的关键点。它涵盖了如何创建自定义微调数据集以及如何检查您的微调模型是否值得更改。

您可以在 Weaviate 的 recipes GitHub 存储库中找到如何使用 Hugging Face 和 Amazon SageMaker 模块的示例笔记本

准备开始构建了吗?

请查看 快速入门教程,或使用 Weaviate Cloud (WCD) 的免费试用版构建令人惊叹的应用程序。

不想错过另一篇博文?

注册我们的双周时事通讯以保持更新!


提交后,我同意 服务条款 隐私政策.