LangChain 在 MLflow 中(实验性)

注意

langchain 风格目前正在积极开发中,并被标记为实验性。公共API正在演变,并且正在添加新功能以增强其功能。

概述

LangChain 是一个用于创建由语言模型驱动的应用程序的 Python 框架。它提供了独特的功能,用于开发利用语言模型进行推理和生成响应的上下文感知应用程序。这种与 MLflow 的集成简化了复杂 NLP 应用程序的开发和部署。

LangChain 的技术本质

  • 上下文感知应用: LangChain 专注于将语言模型连接到各种上下文源,使它们能够生成更相关和准确的输出。

  • 推理能力:它利用语言模型的能力来推理给定的上下文,并根据其采取适当的行动。

  • 灵活的链式组合: LangChain 表达语言 (LCEL) 允许从基本组件轻松构建复杂的链,支持流式处理、并行处理和日志记录等功能。

使用 LangChain 构建链

  • 基本组件: LangChain 有助于将提示模板、模型和输出解析器等组件链接在一起,以创建复杂的流程。

  • 示例 - 笑话生成器: - 一个基本的链可以通过一个主题生成笑话,使用提示模板、ChatOpenAI模型和输出解析器的组合。 - 这些组件通过 | 操作符链接在一起,类似于Unix管道,允许一个组件的输出作为下一个组件的输入。

  • 高级用例: - LangChain 还支持更复杂的设置,例如检索增强生成 (RAG) 链,这种链可以在回答问题时添加上下文。

与 MLflow 的集成

  • 简化日志记录和加载:MLflow 的 langchain 风格提供了 log_model()load_model() 等功能,使得在 MLflow 生态系统中轻松记录和检索 LangChain 模型成为可能。

  • 简化部署:在 MLflow 中记录的 LangChain 模型可以被解释为通用的 Python 函数,简化了它们在各种应用中的部署和使用。通过将依赖管理直接整合到您记录的模型中,您可以部署应用程序,确保用于训练模型的环境将用于服务模型。

  • 多功能模型交互:该集成允许开发者在结合MLflow强大的模型跟踪和管理能力的同时,利用LangChain的独特功能。

  • 自动记录:MLflow 的 langchain 风格提供了 LangChain 模型的自动记录功能,该功能会自动记录用于推理的工件、指标和模型。

langchain 模型风格通过 mlflow.langchain.save_model()mlflow.langchain.log_model() 函数,支持以 MLflow 格式记录 LangChain 模型。使用这些函数还会将 python_function 风格添加到它们生成的 MLflow 模型中,允许通过 mlflow.pyfunc.load_model() 将模型解释为用于推理的通用 Python 函数。

你也可以使用 mlflow.langchain.load_model() 函数来加载一个保存或记录的 MLflow 模型,该模型带有 langchain 风格,作为模型属性的字典。

基本示例:在 MLflow 中记录 LangChain LLMChain

import os

from langchain.chains import LLMChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate

import mlflow

# Ensure the OpenAI API key is set in the environment
assert "OPENAI_API_KEY" in os.environ, "Please set the OPENAI_API_KEY environment variable."

# Initialize the OpenAI model and the prompt template
llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
    input_variables=["product"],
    template="What is a good name for a company that makes {product}?",
)

# Create the LLMChain with the specified model and prompt
chain = LLMChain(llm=llm, prompt=prompt)

# Log the LangChain LLMChain in an MLflow run
with mlflow.start_run():
    logged_model = mlflow.langchain.log_model(chain, "langchain_model")

# Load the logged model using MLflow's Python function flavor
loaded_model = mlflow.pyfunc.load_model(logged_model.model_uri)

# Predict using the loaded model
print(loaded_model.predict([{"product": "colorful socks"}]))

示例的输出如下所示:

输出
["\n\nColorful Cozy Creations."]

简单 LLMChain 示例展示了什么

  • 集成灵活性:该示例展示了如何将由 OpenAI 模型和自定义提示模板组成的 LangChain 的 LLMChain 轻松记录在 MLflow 中。

  • 简化模型管理:通过 MLflow 的 langchain 风格,链条被记录下来,实现了版本控制、追踪和轻松检索。

  • 部署简易性:记录的 LangChain 模型使用 MLflow 的 pyfunc 模块加载,展示了在 MLflow 中部署 LangChain 模型的直接过程。

  • 实际应用:最终的预测步骤展示了模型在现实场景中的功能,根据给定的产品生成公司名称。

使用 MLflow 记录 LangChain 代理

什么是代理?

LangChain 中的代理利用语言模型来动态确定和执行一系列操作,这与链中硬编码的序列形成对比。要了解更多关于代理的信息并查看 LangChain 中的其他示例,您可以 阅读 LangChain 文档中的代理部分

代理的关键组件

代理
  • 核心链驱动决策,利用语言模型和提示。

  • 接收输入,如工具描述、用户目标和先前执行的步骤。

  • 输出下一个动作集(AgentActions)或最终响应(AgentFinish)。

工具
  • 代理调用以完成任务的函数。

  • 提供适当的工具并准确描述它们以实现有效使用至关重要。

工具包
  • 为特定任务量身定制的工具集合。

  • LangChain 提供了一系列内置工具包,并支持自定义工具包的创建。

AgentExecutor
  • 执行代理决策的运行时环境。

  • 处理诸如工具错误和代理输出解析等复杂问题。

  • 确保全面的日志记录和可观测性。

附加代理运行时
  • 除了 AgentExecutor,LangChain 还支持 Plan-and-execute Agent、Baby AGI 和 Auto GPT 等实验性运行时。

  • 自定义运行时逻辑的创建也得到了支持。

记录 LangChain 代理的示例

这个示例展示了在MLflow中记录LangChain代理的过程,突出了LangChain复杂代理功能与MLflow强大模型管理功能的集成。

import os

from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.llms import OpenAI

import mlflow

# Note: Ensure that the package 'google-search-results' is installed via pypi to run this example
# and that you have a accounts with SerpAPI and OpenAI to use their APIs.

# Ensuring necessary API keys are set
assert "OPENAI_API_KEY" in os.environ, "Please set the OPENAI_API_KEY environment variable."
assert "SERPAPI_API_KEY" in os.environ, "Please set the SERPAPI_API_KEY environment variable."

# Load the language model for agent control
llm = OpenAI(temperature=0)

# Next, let's load some tools to use. Note that the `llm-math` tool uses an LLM, so we need to pass that in.
tools = load_tools(["serpapi", "llm-math"], llm=llm)

# Finally, let's initialize an agent with the tools, the language model, and the type of agent we want to use.
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

# Log the agent in an MLflow run
with mlflow.start_run():
    logged_model = mlflow.langchain.log_model(agent, "langchain_model")

# Load the logged agent model for prediction
loaded_model = mlflow.pyfunc.load_model(logged_model.model_uri)

# Generate an inference result using the loaded model
question = "What was the high temperature in SF yesterday in Fahrenheit? What is that number raised to the .023 power?"

answer = loaded_model.predict([{"input": question}])

print(answer)

上述示例的输出如下所示:

输出
["1.1044000282035853"]

简单代理示例展示了什么

  • 复杂代理日志记录:展示了如何使用 MLflow 记录 LangChain 的复杂代理,该代理利用了多种工具和语言模型。

  • 高级工具的集成:展示了如何将 ‘serpapi’ 和 ‘llm-math’ 等额外工具与 LangChain 代理结合使用,强调了框架集成复杂功能的能力。

  • 代理初始化与使用: 详细介绍了使用特定工具和模型设置初始化 LangChain 代理的过程,以及如何使用它来执行复杂查询。

  • 高效模型管理和部署:展示了使用 MLflow 从日志记录到预测,管理和部署复杂 LangChain 代理的便捷性。

使用 LangChain 和 GenAI LLMs 的实时流输出

备注

通过 predict_stream API 的流响应仅在 MLflow 版本 >= 2.12.2 中可用。MLflow 的早期版本不支持流响应。

流输出功能概述

在 MLflow 中集成 LangChain 可以实现从支持该功能的各种 GenAI 语言模型(LLMs)实时流式输出。此功能对于需要即时、增量响应的应用程序至关重要,有助于实现动态交互,如对话代理或实时内容生成。

支持的流媒体模型

LangChain 旨在与任何提供流输出功能的 LLM 无缝协作。这包括来自 OpenAI 等提供商的某些模型(例如,特定版本的 ChatGPT),以及其他支持类似功能的来自不同供应商的 LLM。

使用 predict_stream 进行流式输出

MLflow pyfunc LangChain 风格中的 predict_stream 方法旨在处理同步输入并以流式方式提供输出。此方法特别适用于通过在模型响应可用时立即交付部分响应,而不是等待整个响应生成完成,从而保持用户的参与体验。

示例用法

以下示例演示了如何设置并使用 predict_stream 函数与在 MLflow 中管理的 LangChain 模型,突出了实时响应生成的功能:

from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain_openai import OpenAI
import mlflow


template_instructions = "Provide brief answers to technical questions about {topic} and do not answer non-technical questions."
prompt = PromptTemplate(
    input_variables=["topic"],
    template=template_instructions,
)
chain = LLMChain(llm=OpenAI(temperature=0.05), prompt=prompt)

with mlflow.start_run():
    model_info = mlflow.langchain.log_model(chain, "tech_chain")

# Assuming the model is already logged in MLflow and loaded
loaded_model = mlflow.pyfunc.load_model(model_uri=model_info.model_uri)

# Simulate a single synchronous input
input_data = "Hello, can you explain streaming outputs?"

# Generate responses in a streaming fashion
response_stream = loaded_model.predict_stream(input_data)
for response_part in response_stream:
    print("Streaming Response Part:", response_part)
    # Each part of the response is handled as soon as it is generated

通过回调的高级集成

LangChain 的架构还支持在流输出上下文中使用回调。这些回调可以通过允许在流处理过程中触发操作来增强功能,例如记录中间响应或在交付前修改它们。

备注

大多数回调处理程序的使用涉及记录在链或检索器中对服务和工具的各种调用中的跟踪。为了简单起见,下面展示了一个简单的 stdout 回调处理程序。实际的回调处理程序必须是来自 LangChain 的 BaseCallbackHandler 类的子类。

from langchain_core.callbacks import StdOutCallbackHandler

handler = StdOutCallbackHandler()

# Attach callback to enhance the streaming process
response_stream = loaded_model.predict_stream(input_data, callback_handlers=[handler])
for enhanced_response in response_stream:
    print("Enhanced Streaming Response:", enhanced_response)

这些示例和解释展示了开发者如何在 MLflow 中利用 LangChain 模型的实时流输出功能,从而创建高度响应和交互式的应用程序。

使用 MLflow 增强 RetrievalQA 链的管理

LangChain 与 MLflow 的集成引入了一种更高效的方式来管理和利用 RetrievalQA 链,这是 LangChain 能力的关键方面。这些链巧妙地将数据检索与问答过程结合起来,利用语言模型的优势。

检索QA链的关键见解

  • RetrievalQA 链功能: 这些链代表了 LangChain 的一个复杂功能,其中信息检索与基于语言模型的问答无缝融合。它们在需要语言模型参考特定数据或文档以提供准确回答的场景中表现出色。

  • 检索对象的作用: 在 RetrievalQA 链的核心是检索对象,其任务是根据查询获取相关的文档或数据。

RAG 过程的详细概述

  • 文档加载器:从多种多样的来源加载文档,拥有超过100个加载器和集成。

  • 文档转换器:通过将文档转换和分割成可管理的部分,为检索准备文档。

  • 文本嵌入模型: 生成文本的语义嵌入,增强数据检索的相关性和效率。

  • 向量存储:专门用于存储和促进文本嵌入搜索的数据库。

  • 检索器:采用各种检索技术,从简单的语义搜索到更复杂的方法,如父文档检索器和集成检索器。

使用 MLflow 澄清向量数据库管理

  • 传统 LangChain 序列化:LangChain 通常需要手动管理检索器对象的序列化,包括向量数据库的处理。

  • MLflow的简化:MLflow中的``langchain``风格极大地简化了这一过程。它自动执行序列化,管理``persist_dir``的内容以及``loader_fn``函数的pickling。

关键 MLflow 组件和向量数据库日志记录

  1. persist_dir: 检索器对象(包括向量数据库)存储的目录。

  2. loader_fn: 用于从存储位置加载检索器对象的函数。

重要考虑事项

  • 向量数据库日志:MLflow 通过其 langchain 风格,确实管理了检索器对象中的向量数据库。然而,向量数据库本身并没有在 MLflow 中明确地作为单独的实体进行日志记录。

  • 运行时向量数据库维护: 在训练和运行时环境中保持向量数据库的一致性至关重要。虽然MLflow管理检索器对象的序列化,但确保在运行时可以访问相同的向量数据库对于保持一致的性能仍然至关重要。

记录 LangChain RetrievalQA 链的一个示例

import os
import tempfile

from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS

import mlflow

assert "OPENAI_API_KEY" in os.environ, "Please set the OPENAI_API_KEY environment variable."

with tempfile.TemporaryDirectory() as temp_dir:
    persist_dir = os.path.join(temp_dir, "faiss_index")

    # Create the vector db, persist the db to a local fs folder
    loader = TextLoader("tests/langchain/state_of_the_union.txt")
    documents = loader.load()
    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    docs = text_splitter.split_documents(documents)
    embeddings = OpenAIEmbeddings()
    db = FAISS.from_documents(docs, embeddings)
    db.save_local(persist_dir)

    # Create the RetrievalQA chain
    retrievalQA = RetrievalQA.from_llm(llm=OpenAI(), retriever=db.as_retriever())

    # Log the retrievalQA chain
    def load_retriever(persist_directory):
        embeddings = OpenAIEmbeddings()
        vectorstore = FAISS.load_local(persist_directory, embeddings)
        return vectorstore.as_retriever()

    with mlflow.start_run() as run:
        logged_model = mlflow.langchain.log_model(
            retrievalQA,
            artifact_path="retrieval_qa",
            loader_fn=load_retriever,
            persist_dir=persist_dir,
        )

# Load the retrievalQA chain
loaded_model = mlflow.pyfunc.load_model(logged_model.model_uri)
print(loaded_model.predict([{"query": "What did the president say about Ketanji Brown Jackson"}]))

上述示例的输出如下所示:

输出(截断)
[" The president said..."]

在MLflow中记录和评估LangChain检索器

MLflow 中的 langchain 风格扩展了其功能,包括记录和单独评估检索器对象。这一功能对于在不通过大型语言模型(LLM)处理的情况下评估检索器检索到的文档质量特别有价值。

记录个别检索器的目的

  • 独立评估:允许评估检索器在获取相关文档方面的性能,与其在后续LLMs中的使用无关。

  • 质量保证:有助于评估检索器在获取准确且上下文相关文档方面的有效性。

MLflow 中日志记录检索器的要求

  • persist_dir: 指定检索器对象的存储位置。

  • loader_fn:详细说明了从存储位置加载检索器对象所使用的函数。

  • 这些要求与记录 RetrievalQA 链的要求一致,确保了过程的一致性。

记录 LangChain 检索器的一个示例

import os
import tempfile

from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS

import mlflow

assert "OPENAI_API_KEY" in os.environ, "Please set the OPENAI_API_KEY environment variable."

with tempfile.TemporaryDirectory() as temp_dir:
    persist_dir = os.path.join(temp_dir, "faiss_index")

    # Create the vector database and persist it to a local filesystem folder
    loader = TextLoader("tests/langchain/state_of_the_union.txt")
    documents = loader.load()
    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    docs = text_splitter.split_documents(documents)
    embeddings = OpenAIEmbeddings()
    db = FAISS.from_documents(docs, embeddings)
    db.save_local(persist_dir)

    # Define a loader function to recall the retriever from the persisted vectorstore
    def load_retriever(persist_directory):
        embeddings = OpenAIEmbeddings()
        vectorstore = FAISS.load_local(persist_directory, embeddings)
        return vectorstore.as_retriever()

    # Log the retriever with the loader function
    with mlflow.start_run() as run:
        logged_model = mlflow.langchain.log_model(
            db.as_retriever(),
            artifact_path="retriever",
            loader_fn=load_retriever,
            persist_dir=persist_dir,
        )

# Load the retriever chain
loaded_model = mlflow.pyfunc.load_model(logged_model.model_uri)
print(loaded_model.predict([{"query": "What did the president say about Ketanji Brown Jackson"}]))

上述示例的输出如下所示:

输出(截断)
[
    [
        {
            "page_content": "Tonight. I call...",
            "metadata": {"source": "/state.txt"},
        },
        {
            "page_content": "A former top...",
            "metadata": {"source": "/state.txt"},
        },
    ]
]

MLflow Langchain 自动记录

请参阅 MLflow Langchain 自动记录 文档,以获取有关如何为 Langchain 模型启用自动记录的更多详细信息。