MLflow 跟踪模式

本文档提供了跟踪模式及其组成部分的详细视图。MLflow 跟踪 兼容 OpenTelemetry 规范,但我们还在 OpenTelemetry 跨度之上定义了几个额外的结构层,以提供有关跟踪的额外元数据。

跟踪的结构

TL;DR: Trace = TraceInfo + TraceData 其中 TraceData = List[Span]

Trace Structure

A Trace in MLflow consists of two components: Trace Info and Trace Data.

The metadata that aids in explaining the origination of the trace, the status of the trace, and the information about the total execution time is stored within the Trace Info. The Trace Data is comprised entirely of the instrumented Span objects that make up the core of the trace.

跟踪

一个跟踪由两个组件组成:

小技巧

有关如何转换或提取这些数据类对象中的数据的更多信息,请查看API文档中的辅助方法。

跟踪信息

Trace Info 是一个包含关于跟踪的元数据的 dataclass 对象。这些元数据包括关于跟踪来源、状态的信息,以及在使用 mlflow.client.MlflowClient.search_traces() 和在 MLflow UI 中导航跟踪时有助于检索和过滤跟踪的各种其他数据。

要了解更多关于 TraceInfo 元数据如何用于搜索的信息,您可以查看 这里的示例

TraceInfo 对象中包含的数据用于填充 MLflow 跟踪 UI 中的跟踪视图页面,如下所示。

TraceInfo 在 MLflow UI 中的使用

MLflow TraceInfo 对象的主要组件如下所示。

属性

描述

注意

请求ID

用于跟踪的唯一标识符。该标识符在 MLflow 和集成系统中用于解析被捕获的事件,并为外部系统提供映射记录的跟踪到原始调用者的关联。

此值由跟踪后端生成且不可变。在跟踪客户端API中,您需要有意将此值传递给 span创建API 以确保给定的span与跟踪相关联。

experiment_id

记录跟踪的实验的ID。所有记录的跟踪都与生成跟踪时(在调用被检测对象期间)当前活动的实验相关联。

此值是不可变的,由跟踪后端设置。它是一个系统控制的值,在使用 搜索跟踪 API 时非常有用。

timestamp_ms

标记跟踪根跨度创建时刻的时间。这是一个以毫秒为单位的Unix时间戳。

此属性反映的时间是跟踪创建的时间,而不是向您的应用程序发出请求的时间。因此,它不考虑处理请求到应用程序所在环境所需的时间,这可能会根据网络配置为总往返时间引入额外的延迟。

execution_time_ms

标记结束追踪调用时刻的时间。这是一个以毫秒为单位的Unix时间戳。

此次时间不包括将响应从生成跟踪的环境发送到正在消费应用程序调用结果的环境所关联的网络时间。

状态

一个表示跟踪状态的枚举值。

TraceStatus 值是以下之一:

  • OK - 跟踪和插桩调用成功。

  • 错误 - 在检测应用程序时发生了一个错误。该错误可以在跟踪的跨度数据中看到。

  • 进行中 - 跟踪已经开始并且当前正在运行。这是一个临时状态,将在记录跨度到跟踪时更新。

  • TRACE_STATUS_UNSPECIFIED - 不应在记录的跟踪中看到的内部默认状态。

请求元数据

请求元数据是与 Trace 相关联的附加键值对信息,由跟踪后端设置和修改。

这些内容不允许用户添加或修改,但可以提供关于跟踪的额外上下文,例如与跟踪相关的 MLflow run_id

标签

用户定义的键值对,可以应用于跟踪以添加额外的上下文,有助于 搜索功能 ,或在创建跟踪或在成功记录跟踪后提供额外信息。

这些标签是完全可变的,并且可以在任何时候更改,甚至在将跟踪记录到实验之后很长时间也可以更改。

跟踪数据

MLflow 的 TraceData 对象是一个数据类对象,它包含了跟踪数据的核心。该对象包含以下元素:

属性

描述

注意

请求

request 属性是整个跟踪的输入数据。输入的 str 是一个包含跟踪输入数据的 JSON 序列化字符串,通常是作为对应用程序调用提交的最终用户请求。

由于输入到由MLflow Tracing进行检测的应用程序的结构各异,为了兼容性,所有输入都被JSON序列化。这使得无论输入数据的结构如何,输入数据都能以一致的格式存储。

跨度

此属性是一个 Span 对象列表,表示跟踪的各个步骤。

关于 Span 对象结构的更多信息,请参见下文。

响应

response 属性是应用程序调用返回给调用者的最终输出数据。

类似于请求属性,此值是一个JSON序列化的字符串,以最大化不同格式之间的兼容性。

Span 模式

跨度是跟踪数据的核心。它们记录了您的 genai 应用程序中每个步骤的关键、关键数据。

当你在 MLflow UI 中查看你的追踪时,你看到的是一系列的跨度,如下所示。

MLflow UI 中的跨度

以下部分提供了对span结构的详细视图。

属性

描述

注意

输入

输入数据以 JSON 序列化字符串的形式存储,代表传递到应用程序特定阶段(步骤)的输入数据。由于 GenAI 应用程序各阶段之间可以传递的输入数据种类繁多,这些数据可能非常大(例如在使用向量存储检索步骤的输出时)。

审查各个阶段的输入和输出可以显著提高诊断和调试应用程序响应中存在的问题的能力。

输出

输出被存储为 JSON 序列化字符串,表示从应用程序的特定阶段(步骤)传递出来的输出数据。

与输入类似,输出也可能非常大,这取决于各阶段之间传递的数据的复杂性。

属性

属性是与应用程序中给定步骤相关联的元数据。这些属性是键值对,可用于提供对函数和方法调用的行为修改的洞察,从而了解这些修改如何影响应用程序的性能。

与给定跨度相关联的常见属性示例包括:

  • 模型

  • 温度

  • document_count

这些属性为 outputs 属性中存在的跨度结果提供了额外的上下文和见解。

事件

事件是一个系统级属性,仅在跨度执行期间出现问题时才会选择性地应用于跨度。这些事件包含有关在检测调用中抛出的异常的信息,以及堆栈跟踪。

这些数据被结构化在一个 SpanEvent 对象中,包含以下属性:

  • 名称

  • 时间戳

  • 属性

属性 属性包含在执行跨度期间抛出的异常的堆栈跟踪,如果在执行期间发生了此类错误。

parent_id

parent_id 属性是一个标识符,用于建立给定跨度与其父跨度之间的层次关联。这用于建立跨度的事件链,有助于确定应用程序执行中哪个步骤跟随另一个步骤。

一个 span 必须 设置 parent_id

span_id

span_id 是一个为跟踪中的每个跨度生成的唯一标识符。此标识符用于区分不同的跨度,并允许在跟踪中其他跨度的顺序执行中正确关联该跨度。

当创建一个跨度时,会设置一个 span_id,并且它是不可变的。

请求ID

request_id 属性是一个唯一标识符,为每个 跟踪 生成,并传播到该跟踪的每个成员跨度。

request_id 是一个系统生成的属性,并且是不可变的。

名称

name 跟踪的名称可以是用户定义的(在使用 fluent 和客户端 API 时可选),或者是通过 CallBack 集成自动生成的,或者在调用 fluent 或客户端 API 时省略 name 参数时自动生成。如果名称未被覆盖,名称将根据被检测的函数或方法的名称生成。

在使用客户端或流式API进行手动检测时,建议为您的跨度提供一个唯一且与正在执行的功能相关的名称。跨度的通用名称或令人困惑的名称可能会在查看跟踪时难以诊断问题。

状态

一个 span 的状态通过枚举对象 SpanStatusCode 中的一个值来反映。span 状态对象包含一个可选的描述,如果 status_code 反映了一个发生的错误。状态可能的值有:

  • OK - 跨度和底层检测调用成功。

  • UNSET - 该跨度的状态尚未设置(这是默认值,不应在记录的跟踪事件中看到)。

  • 错误 - 在被检测的调用中发生了问题。description 属性将包含有关发生的错误的更多信息。

评估跨度的状态可以大大减少诊断应用程序问题所需的时间和精力。

start_time_ns

span 开始时的 Unix 时间戳(以纳秒为单位)。

此属性的精度高于跟踪开始时间,允许对非常短暂的跨度的执行时间进行更细粒度的分析。

end_time_ns

span 结束时的 Unix 时间戳(以纳秒为单位)。

此精度高于跟踪时间戳,类似于上面的 start_time_ns 时间戳。

特定跨度类型的模式

MLflow 有一组 10 种预定义的跨度类型(参见 mlflow.entities.SpanType),某些跨度类型具有在 UI 中启用额外功能和下游任务(如评估)所需的属性。

检索器跨度

RETRIEVER 跨度类型用于涉及从数据存储中检索数据的操作(例如,从向量存储中查询文档)。RETRIEVER 跨度类型具有以下模式:

属性

描述

注意

输入

对跨度输入没有限制

输出

输出必须是类型 List[ mlflow.entities.Document ],或与数据类结构匹配的字典*。数据类包含以下属性:

  • id (Optional[str]) - 文档的可选唯一标识符。

  • page_content (str) - 文档的文本内容。

  • metadata (Optional[Dict[str,any]]) - 与文档相关的元数据。有两个重要的元数据键是为MLflow UI和评估指标保留的:

    • "doc_uri" (str): 文档的URI。这用于在UI中渲染链接。

    • "chunk_id" (str): 如果你的文档在你的数据存储中被分成了多个块,这个键可以用来标识文档所属的块。一些评估指标会使用这个键。

如果通过 MLflow autologging 为 LangChain 和 LlamaIndex 风格生成跟踪,则保证提供此输出结构。通过符合此规范,RETRIEVER 跨度将在 MLflow UI 中以更用户友好的方式呈现,并且下游任务(如评估)将按预期运行。

属性

对跨度属性没有限制

* For example, both [Document(page_content="Hello world", metadata={"doc_uri": "https://example.com"})] and [{"page_content": "Hello world", "metadata": {"doc_uri": "https://example.com"}}] are valid outputs for a RETRIEVER span.