跳到主要内容

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

下载此 Notebook

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

理解嵌入

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

嵌入如何工作

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

在本教程中

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

通过学习本教程,您将全面了解如何在 MLflow 项目中集成和利用 OpenAI 嵌入,驾驭先进自然语言处理技术的强大力量。您还将看到使用文档文本嵌入来比较它们相似性的实际应用。此用例对于网站内容开发特别有用,它是执行搜索引擎优化 (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 至关重要,有助于执行文档相似性分析等高级自然语言处理操作。

mlflow.set_experiment("Documenatation Similarity")

with mlflow.start_run():
model_info = mlflow.openai.log_model(
model="text-embedding-ada-002",
task=openai.embeddings,
artifact_path="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:

    • 目的:计算两个嵌入向量之间的余弦相似度。
    • 工作原理:此函数通过计算两个向量之间夹角的余弦来计算相似度,这是评估两个文档内容相似程度的常用方法。
    • 相关性:在自然语言处理中非常有用,特别是对于文档检索和聚类等任务,目标是找到内容相似的文档。
  2. euclidean_distances:

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

这些函数对于分析和比较嵌入模型的输出至关重要,能够深入了解不同文本数据在相似性和区别方面的关系。

使用嵌入比较网页

本教程的此部分介绍了一个函数 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 版本中主大型语言模型 (LLMs) 页面与 LLM 评估页面的内容有多相似。

过程概览

  • 目标网页:
  • 内容 ID:我们使用 'llms' 作为主 LLMs 页面,使用 'mlflow-llm-evaluate' 作为 LLM 评估页面,以定位特定的内容部分。
  • 比较执行:使用这些 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 大型语言模型 (LLMs) 页面与 2.8.1 版本中的 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. 在 MLflow 中集成 OpenAI 模型:

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

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

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

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

    • 本教程提供了关于解读相似度和距离指标结果的见解,突显了它们在理解内容关系方面的相关性。

结论

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

我们希望本指南信息丰富,并有助于增进您在 MLflow 框架内对 OpenAI 嵌入的理解和应用。

下一步是什么?

要继续您的学习之旅,请参阅 MLflow OpenAI 风味的其他高级教程