跳到主要内容

高级教程:在 MLflow 中支持 OpenAI 嵌入

下载此笔记本

欢迎阅读本高级指南,了解如何在 MLflow 框架内实现 OpenAI 嵌入。本教程将深入探讨 OpenAI 强大嵌入功能的配置和使用,这是现代机器学习模型中的关键组成部分。

理解嵌入

嵌入是一种表示学习的形式,其中单词、短语甚至整个文档都被转换为高维空间中的向量。这些向量捕获了语义含义,使模型能够更有效地理解和处理语言。嵌入广泛用于自然语言处理 (NLP) 任务,例如文本分类、情感分析和语言翻译。

嵌入的工作原理

嵌入通过将文本数据映射到向量来工作,其中向量之间的距离和方向代表单词或短语之间的关系。例如,在训练良好的嵌入空间中,同义词彼此靠近,而无关的术语则相距较远。这种空间排列允许算法识别上下文和语义,从而增强其解释和响应自然语言的能力。

本教程内容

  • 嵌入端点配置:在 MLflow 中设置和使用 OpenAI 的嵌入端点。
  • 实际应用:通过实际示例比较不同网页的文本内容,以确定其特定上下文内容的相似程度。
  • 效率和精度增强:使用 OpenAI 嵌入改进模型性能的技术。

在本教程结束时,您将全面了解如何在 MLflow 项目中集成和利用 OpenAI 嵌入,从而掌握高级 NLP 技术的强大功能。您还将看到一个实际应用:使用文档的文本嵌入来比较它们的相似性。此用例对于网页内容开发特别有用,是在执行搜索引擎优化 (SEO) 时的一项关键任务,以确保网站页面内容彼此之间不至于过于相似(这可能导致页面排名下降)。

所需软件包

为了运行本教程,您需要从 PyPI 安装 beautifulsoup4

让我们深入了解嵌入的世界,探索它们对机器学习模型的变革性影响!

import warnings

# Disable a few less-than-useful UserWarnings from setuptools and pydantic
warnings.filterwarnings("ignore", category=UserWarning)
import os

import numpy as np
import openai
import requests
from bs4 import BeautifulSoup
from sklearn.metrics.pairwise import cosine_similarity, euclidean_distances

import mlflow
from mlflow.models.signature import ModelSignature
from mlflow.types.schema import ColSpec, ParamSchema, ParamSpec, Schema, TensorSpec

assert "OPENAI_API_KEY" in os.environ, " OPENAI_API_KEY environment variable must be set"

将 OpenAI 模型与 MLflow 集成以进行文档相似性分析

在本教程的这个环节,我们将演示在 MLflow 中设置和使用 OpenAI 嵌入模型来进行文档相似性任务的过程。

关键步骤

  1. 设置 MLflow 实验:我们首先在 MLflow 中设置文档相似性实验的上下文,使用 mlflow.set_experiment("Documentation Similarity")

  2. 在 MLflow 中记录模型:我们启动一个 MLflow 运行,并记录元数据和访问配置参数,以便与特定的 OpenAI 端点进行通信。我们在此选择的 OpenAI 端点指向“text-embedding-ada-002”模型,该模型因其强大的嵌入能力而被选中。在此步骤中,我们将详细介绍这些访问配置、嵌入任务、输入/输出模式以及批量大小等参数。

  3. 加载已记录的模型以供使用:在记录 MLflow 模型后,我们继续使用 MLflow 的 pyfunc 模块加载它。这是在 MLflow 生态系统内应用模型以执行文档相似性任务的关键步骤。

这些步骤对于将 OpenAI 嵌入模型的访问集成到 MLflow 中至关重要,从而促进文档相似性分析等高级 NLP 操作。

mlflow.set_experiment("Documenatation Similarity")

with mlflow.start_run():
model_info = mlflow.openai.log_model(
model="text-embedding-ada-002",
task=openai.embeddings,
name="model",
signature=ModelSignature(
inputs=Schema([ColSpec(type="string", name=None)]),
outputs=Schema([TensorSpec(type=np.dtype("float64"), shape=(-1,))]),
params=ParamSchema([ParamSpec(name="batch_size", dtype="long", default=1024)]),
),
)

# Load the model in pyfunc format
model = mlflow.pyfunc.load_model(model_info.model_uri)

网页文本提取用于嵌入分析

本教程的这一部分介绍了用于从网页提取和准备文本的函数,这是在应用嵌入模型进行分析之前的关键步骤。

函数概述

  1. insert_space_after_tags:

    • 在 BeautifulSoup 对象中的特定 HTML 标签后添加空格,以提高文本的可读性。
  2. extract_text_from_url:

    • 使用 URL 和目标 ID 从指定的网页部分提取文本。过滤和组织来自 <h><li><p> 等标签的文本,并排除某些不相关的部分。

这些函数是预处理网页内容的组成部分,确保输入到嵌入模型的文本是干净、相关且结构良好的。

def insert_space_after_tags(soup, tags):
"""
Insert a space after each tag specified in the provided BeautifulSoup object.

Args:
soup: BeautifulSoup object representing the parsed HTML.
tags: List of tag names (as strings) after which space should be inserted.
"""
for tag_name in tags:
for tag in soup.find_all(tag_name):
tag.insert_after(" ")


def extract_text_from_url(url, id):
"""
Extract and return text content from a specific section of a webpage.
"""
try:
response = requests.get(url)
response.raise_for_status() # Raises HTTPError for bad requests (4XX, 5XX)
except requests.exceptions.RequestException as e:
return f"Request failed: {e}"

soup = BeautifulSoup(response.text, "html.parser")
target_div = soup.find("div", {"class": "section", "id": id})
if not target_div:
return "Target element not found."

insert_space_after_tags(target_div, ["strong", "a"])

content_tags = target_div.find_all(["h1", "h2", "h3", "h4", "h5", "h6", "li", "p"])
filtered_tags = [
tag
for tag in content_tags
if not (
(tag.name == "li" and tag.find("p") and tag.find("a", class_="reference external"))
or (tag.name == "p" and tag.find_parent("ul"))
or (tag.get_text(strip=True).lower() == "note")
)
]

return "
".join(tag.get_text(separator=" ", strip=True) for tag in filtered_tags)

详细工作流程:

  • extract_text_from_url 函数首先使用 requests 库获取网页内容。
  • 然后使用 BeautifulSoup 解析 HTML 内容。
  • 针对特定的 HTML 标签进行文本提取,以确保内容与嵌入分析相关且结构良好。
  • extract_text_from_url 中调用 insert_space_after_tags 函数,以提高提取后的文本可读性。

测量嵌入之间的相似性和距离

在本教程的下一部分,我们将使用 sklearn 中的两个函数来测量文档嵌入之间的相似性和距离,这对于评估和比较基于文本的机器学习模型至关重要。

函数概述

  1. cosine_similarity:

    • 目的:计算两个嵌入向量之间的余弦相似度。
    • 工作原理:此函数通过计算两个向量之间夹角的余弦值来计算相似度,这是一种评估两篇文档在内容上相似程度的常用方法。
    • 相关性:在 NLP 中非常有用,尤其是在文档检索和聚类等任务中,目标是查找内容相似的文档。
  2. euclidean_distances:

    • 目的:计算两个嵌入向量之间的欧几里得距离。
    • 功能:与 cosine_similarity 类似,此函数计算欧几里得距离,即嵌入空间中两点之间的“直线”距离。此度量对于理解两篇文档的差异很有用。
    • 在 NLP 中的相关性:提供更直观的物理距离度量,可用于文档分类和异常检测等任务。

这些函数对于分析和比较嵌入模型的输出至关重要,它们提供了关于不同文本数据之间在相似性和区分性方面的关系的见解。

使用嵌入比较网页

本教程的这一部分介绍了一个名为 compare_pages 的函数,该函数旨在利用嵌入模型比较两个网页的内容。此函数对于理解两个给定网页在文本内容上的相似或不同之处至关重要。

函数概述

  • 函数名称compare_pages
  • 目的:比较两个网页,并根据其内容返回相似度分数。
  • 参数:
    • url1url2:要比较的网页的 URL。
    • id1id2:每个页面上主要文本内容 div 的目标 ID。

工作原理

  1. 文本提取:该函数首先使用 extract_text_from_url 函数从每个网页的指定部分提取文本。
  2. 嵌入预测:然后使用之前加载的 OpenAI 模型为提取的文本生成嵌入。
  3. 相似性和距离测量:该函数计算两个嵌入之间的余弦相似度和欧几里得距离。这些度量提供了量化的度量,可以说明网页内容有多相似或不同。
  4. 结果:返回一个包含余弦相似度分数和欧几里得距离的元组。如果文本提取失败,则返回错误消息。

实际应用

此函数在需要比较不同网页内容的场景中特别有用,例如内容策展、抄袭检测或用于 SEO 目的的相似性分析。

通过利用嵌入和相似性度量的强大功能,compare_pages 提供了一种量化评估网页内容相似性和差异性的稳健方法。

def compare_pages(url1, url2, id1, id2):
"""
Compare two webpages and return the similarity score.

Args:
url1: URL of the first webpage.
url2: URL of the second webpage.
id1: The target id for the div containing the main text content of the first page
id2: The target id for the div containing the main text content of the second page

Returns:
A tuple of floats representing the similarity score for cosine similarity and euclidean distance.
"""
text1 = extract_text_from_url(url1, id1)
text2 = extract_text_from_url(url2, id2)

if text1 and text2:
embedding1 = model.predict([text1])
embedding2 = model.predict([text2])

return (
cosine_similarity(embedding1, embedding2),
euclidean_distances(embedding1, embedding2),
)
else:
return "Failed to retrieve content."

MLflow 文档页面之间的相似性分析

在本教程的这个环节,我们将通过比较 MLflow 文档中的两个特定页面来演示 compare_pages 函数的实际应用。我们的目标是评估 MLflow 2.8.1 版本中主要的 LLM(大型语言模型)页面与 LLM 评估页面的内容相似度。

过程概述

  • 目标网页:
  • 内容 ID:我们使用“llms”作为主要 LLM 页面的 ID,使用“mlflow-llm-evaluate”作为 LLM 评估页面的 ID,以定位特定的内容部分。
  • 比较执行:调用带有这些 URL 和内容 ID 的 compare_pages 函数来执行分析。

结果

  • 余弦相似度和欧几里得距离:该函数返回两个关键度量
    • 余弦相似度:衡量两个页面嵌入向量之间夹角的余弦值。值越高表示相似度越大。
    • 欧几里得距离:表示嵌入空间中两个点之间的“直线”距离,值越低表示相似度越接近。

解释

结果显示余弦相似度很高(0.8792),这表明就上下文和涵盖的主题而言,两个页面的内容非常相似。欧几里得距离为 0.4914,虽然相对较低,但提供了补充的视角,表明内容存在一定程度的独特性。

结论

此分析突显了使用嵌入和相似性度量来比较网页内容的有效性。在实际应用中,它有助于理解文档中的重叠和差异,从而有助于内容优化、冗余减少以及确保主题的全面覆盖。

# Get the similarity between the main LLMs page in the MLflow Docs and the LLM Evaluation page for the 2.8.1 release of MLflow

llm_cosine, llm_euclid = compare_pages(
url1="https://www.mlflow.org/docs/2.8.1/llms/index.html",
url2="https://www.mlflow.org/docs/2.8.1/llms/llm-evaluate/index.html",
id1="llms",
id2="mlflow-llm-evaluate",
)

print(
f"The cosine similarity between the LLMs page and the LLM Evaluation page is: {llm_cosine} and the euclidean distance is: {llm_euclid}"
)
The cosine similarity between the LLMs page and the LLM Evaluation page is: [[0.879243]] and the euclidean distance is: [[0.49144073]]

MLflow LLMs 和 Plugins 页面之间相似性的简要概述

本节演示了 MLflow 2.8.1 版本中 MLflow 大型语言模型 (LLMs) 页面和 Plugins 页面之间进行快速相似性分析。

分析执行

结果

  • 余弦相似度:0.6806,表示内容具有中等程度的相似性。
  • 欧几里得距离:0.7992,表明两个页面所涵盖的上下文和主题存在显著差异。

结果显示 LLMs 页面和 Plugins 页面之间的相似性适中,内容具有显著的独特性。此分析有助于理解 MLflow 文档不同部分之间的关系和内容重叠。

# Get the similarity between the main LLMs page in the MLflow Docs and the Plugins page for the 2.8.1 release of MLflow

plugins_cosine, plugins_euclid = compare_pages(
url1="https://www.mlflow.org/docs/2.8.1/llms/index.html",
url2="https://www.mlflow.org/docs/2.8.1/plugins.html",
id1="llms",
id2="mflow-plugins",
)

print(
f"The cosine similarity between the LLMs page and the MLflow Projects page is: {plugins_cosine} and the euclidean distance is: {plugins_euclid}"
)
The cosine similarity between the LLMs page and the MLflow Projects page is: [[0.68062298]] and the euclidean distance is: [[0.79922088]]

教程回顾:在 MLflow 中利用 OpenAI 嵌入

随着本教程的结束,让我们回顾一下我们所探讨的关于在 MLflow 框架中使用 OpenAI 嵌入的关键概念和技术。

主要收获

  1. 将 OpenAI 模型集成到 MLflow 中:

    • 我们学习了如何在 MLflow 中记录和加载 OpenAI 的“text-embedding-ada-002”模型,这是在机器学习工作流中使用这些嵌入的必要步骤。
  2. 文本提取和预处理:

    • 本教程介绍了从网页提取和预处理文本的方法,以确保数据干净且结构化,适合嵌入分析。
  3. 计算相似性和距离:

    • 我们深入研究了用于测量文档嵌入之间余弦相似度和欧几里得距离的函数,这对于比较文本内容至关重要。
  4. 实际应用:网页内容比较:

    • 通过比较不同的 MLflow 文档页面,我们演示了这些概念的实际应用。我们使用 OpenAI 模型生成的嵌入来分析其内容中的相似性和差异。
  5. 结果解释:

    • 本教程提供了对相似性和距离度量结果的解释,强调了它们在理解内容关系方面的相关性。

结论

本高级教程旨在提高您在 MLflow 中应用 OpenAI 嵌入的技能,重点关注文档相似性分析等实际应用。通过集成这些强大的 NLP 工具,我们展示了如何从文本数据中提取更多价值和见解,这是现代机器学习项目的一个关键方面。

我们希望本指南内容详实,并能帮助您加深对 MLflow 框架内 OpenAI 嵌入的理解和应用。

下一步是什么?

要继续您的学习之旅,请参阅有关 MLflow 的 OpenAI 风味的更多高级教程