如何构建一个实验追踪工具【来自Neptune背后的工程师的经验总结】

Building an Experiment Tracking Tool Insights from Neptune Engineers

作为您团队的MLOps工程师,您经常被要求通过为您的数据科学家增加ML平台的功能或构建独立工具来改进他们的工作流程。

实验追踪是一种这样的能力。既然您正在阅读本文,那么您支持的数据科学家可能已经寻求帮助。他们运行的实验正在不断扩展并变得越来越复杂;跟踪他们的实验并确保其可复制性变得更加困难。

构建一个用于管理实验的工具可以帮助您的数据科学家;

  • 1
    保持对不同项目的实验跟踪,
  • 2
    保存与实验相关的元数据,
  • 3
    随时间复现和比较结果,
  • 4
    与团队成员共享结果,
  • 5
    或将实验输出推送到下游系统。

本文是我们在过去五年中构建和维护最受欢迎的实验追踪工具中所学到的总结。

基于我们自己的Piotr Łusakowski(架构师)、Adam Nieżurawski(后端技术负责人)以及neptune.ai的其他工程师的见解,您将学到:

  • 如何为您的实验追踪工具制定需求,
  • 理想的实验追踪工具的组成部分以及它们如何满足需求,
  • 如何设计实验追踪工具的后端层,
  • 构建实验追踪工具时需要考虑的技术因素。

本指南的重点是为您提供构建适合您团队的工具所需的基本要素。本文不涵盖构建实验追踪工具的技术考虑或编写构建工具的代码。

我们将重点放在基本要素上,因为任何编写的代码在一周后都不重要,而任何工具在六个月后很可能会被遗忘。

制定实验追踪工具的需求

在开发方面,构建实验追踪工具时您需要解决三个主要问题,包括:

  • 帮助您的数据科学家处理数据和模型来源的元数据和工件血统。
  • 为您的数据科学家提供监控和评估实验性能的界面,以进行有效的决策和调试。
  • 为您的数据科学家提供跟踪其ML项目进展的平台。
您需要构建实验追踪工具的三个原因

处理数据和模型来源的元数据和工件血统

实验追踪工具可以帮助您的数据科学家追踪实验工件的血统,包括其数据和模型来源,存储生成的元数据并对其进行管理。应该可以确定实验的数据和模型来自哪里,以便您的数据科学家可以探索实验的过程和导致结果的过程。

这带来了两个重要的好处:

  • 可复制性:确保您的数据科学家运行的每个实验都是可复制的。
  • 可解释性:确保他们能够解释实验结果。

确保可复制的实验结果

实验结果应该易于复制,以便您的数据科学家可以更好地与其他团队和成员合作,并实现良好的工作流程。将可复制性视为使用相同的代码、相同的环境配置和相同的数据来获得相同或类似的实验结果。

为了使复制工作正常进行,您需要构建组件,以跟踪实验元数据(如参数、结果、配置文件、模型和数据版本等)、代码更改以及数据科学家的训练环境(或基础设施)配置。

如果无法端到端地追踪数据的血统和跟踪,几乎不可能重现模型并修复错误和流程。

您的用户应该能够跟踪对模型开发代码库(数据处理代码、流程代码、实用脚本等)的更改,这直接影响了他们运行实验和相应结果的方式。

确保数据科学家能够解释实验结果

当数据科学家运行实验并构建符合预期性能要求的模型时,他们还需要理解结果,以判断为什么他们的模型会做出某些预测。当然,并非所有情况都是如此,但在需要了解模型如何以及为何进行预测的情况下,“可解释性”变得至关重要。

如果无法追踪实验数据的来源(其血统)、数据的处理方式、运行实验所使用的参数以及实验结果,那么就无法将可解释性添加到他们的工作流程中。

实验跟踪工具应该允许您的数据科学家:

  • 查看他人的实验并轻松分享自己的实验。
  • 比较任何已创建实验的行为。
  • 追踪和审计每个实验以排除不必要的偏见和其他问题。
  • 调试和比较实验,其中训练数据、代码或参数丢失。

法律合规性是解释性至关重要的另一个原因。例如,GDPR要求您的组织收集和跟踪有关数据集的元数据,并记录和报告实验生成的模型的工作原理。

监控和评估实验性能以进行有效决策

大多数情况下,比较使用不同数据集版本和参数进行的实验结果是有意义的。实验跟踪解决方案可以帮助数据科学家衡量模型参数变化对实验的影响,他们将看到模型在不同数据版本下的性能变化。

当然,这对他们构建强大且高性能的机器学习模型非常有帮助。如果没有监控和评估实验,他们无法确定训练模型(或模型)是否能够泛化到未见过的数据。数据科学团队可以利用这些信息选择最佳的模型、参数和性能指标。

跟踪机器学习项目的进展

使用实验跟踪解决方案,数据科学团队和其他相关利益相关者可以检查项目的进展情况,并查看是否符合预期的性能要求。

功能和非功能需求

如果我说为任何软件工具开发有效的需求需要考虑很多因素,那我就是对牛弹琴了。首先,您必须了解与业务和产品使用相关的需求。然后,您必须在软件开发生命周期中指定、分析、测试和管理这些需求。

创建用户故事、分析它们并验证需求都是需求开发的组成部分,它们都值得拥有自己的文章。本节将概述跟踪实验的理想工具的最重要的功能和非功能需求

了解您的用户

根据您的团队结构和组织设置,您可能有不同的用户需要使用实验跟踪工具。但理想情况下,数据科学家将是您的实验跟踪工具的用户。从高层次来看,以下是您的数据科学家希望通过实验跟踪工具完成的工作:

  • 实时查看模型训练运行:当在远程服务器或计算机外训练模型时,他们希望实时查看模型训练运行,以便在运行失败时能够快速反应或在运行完成后分析结果。
  • 在一个位置查看所有模型训练元数据:当与团队合作或独自工作时,他们希望将所有模型构建元数据放在一个位置,以便在需要时能够快速找到最佳的模型元数据,并确保始终可用。
  • 比较模型训练运行:当他们有不同版本的训练模型时,他们希望比较模型并查看哪个模型表现最佳、哪些参数有效以及输入/输出有何不同。

功能需求

在前一节中,您了解了使用实验跟踪工具解决的问题;这些问题也是构建功能性实验跟踪工具所需完成的工作。

要开始设计实验跟踪软件,您必须制定代表理想实验跟踪工具应具备的功能需求。我已将功能需求按照用户需要完成的工作和相应特征的结果进行分类,详见下表。

需求

功能

与生态系统中的工具无缝集成。

与您用于实验(模型训练和数据工具)的ML框架集成。

与工作流编排器和CI/CD工具集成(如果您的堆栈处于此级别)。

支持多种数据类型的元数据记录。

记录整数、浮点数、字符串等简单数据类型。

记录系列浮点数、字符串、图像、文件和文件目录等复杂数据类型。

使用编程方式和UI消费已记录的元数据。

查看运行列表和运行详细信息,例如训练数据版本、模型参数、性能指标、工件、所有者、持续时间和创建时间。

按属性对实验进行排序和过滤。例如,您可能希望仅显示在数据集Y的X版本上训练且准确度超过0.93的运行,并按创建者对其进行分组,并按创建时间排序。

比较不同实验,了解不同参数、模型架构和数据集对模型准确性、训练成本和硬件利用率的影响。

非功能性要求

实验跟踪工具的非功能性要求应包括:

质量

描述

可靠性

您不希望实验跟踪工具破坏训练作业 – 这可能很昂贵,当然也是一个绝对不能接受的问题。

性能

API和集成需要低延迟,以便不会拖慢训练作业和ML管道(这会增加成本)。

效率

架构和技术应优化成本效益,因为您的用户可以运行和跟踪许多实验,成本可能会迅速增加。

可扩展性

ML在您的组织中的重要性只会增加。您不希望因为您早期采取的某些捷径而需要重写系统,当时只有一个数据科学家在使用它。

健壮性

您需要一个弹性数据模型来支持:不同的团队规模和结构(仅一个数据科学家,或者一个数据科学家团队,4个机器学习工程师,2个DevOps工程师等)。不同的工作流程,以便用户可以决定要跟踪的内容。有些人只会跟踪训练后阶段。有些人希望跟踪整个数据转换的流程,而其他人将监视生产中的模型。不断变化的环境 – 数据模型需要能够支持生态系统中的每个新的ML框架和工具。否则,您的集成可能很快变得混乱且难以维护。

外部集成要求:集成应设置,以便软件可以收集有关用户将用于实验的数据集的元数据。

实验跟踪系统的架构

理想的实验跟踪系统将有三(3)个层次

  • 1
    前端/UI。
  • 2
    后端。
  • 3
    客户端库(API / 生态系统集成)。

一旦您了解这些组件的作用以及我们为什么需要它们,您就能够构建一个根据您的实验跟踪需求定制的系统。

实验跟踪软件的不同层之间的交互

构建实验系统的前端层

前端拦截大多数用户请求并将其发送到后端服务器以运行任何实验跟踪逻辑。由于大多数请求和响应都必须经过前端层,因此它将获得大量的流量并需要能够处理最高并发级别。

前端层还是您可以可视化和与您运行的实验进行交互的方式。对于实验跟踪系统的前端部分来说,最重要的部分是什么?

可视化实验元数据

数据科学中的许多实验涉及到可视化,从可视化数据到训练模型及其性能的实时监控。前端层必须能够显示各种类型的实验元数据,包括简单的字符串、嵌入式Jupyter笔记本、源代码、视频和自定义报告。

显示具有属性的数百次运行

您希望能够在运行期间和之后随时查看实验的详细信息,包括相关属性和记录的元数据。此类元数据包括:

  • 使用的算法。
  • 性能指标和结果。
  • 实验持续时间。
  • 输入数据集。
  • 实验开始时间。
  • 运行的唯一标识符。
  • 您认为可能需要的其他属性。

您还需要根据它们的结果比较运行,并可能跨实验进行比较。

如果这对您的使用案例很重要,您可能希望使用这些属性为您的实验添加可解释性功能和属性。当然,您也可能希望从此视图中推广或下载您的模型。

neptune.ai中的运行表|在应用程序中查看

管理状态和优化性能是构建UI组件最复杂的部分之一。比如说,比较具有成千上万个属性的十个运行,其中许多属性需要显示在动态图表中,可能会引起很多麻烦。即使是VoAGI级别的项目,如果您不正确处理,可能会经常导致浏览器冻结。

除了性能之外,还有其他UI调整可以让您仅显示项目属性的子集,按特定属性分组运行,按其他属性排序,使用带有提示和补全的过滤查询编辑器等。

系统后端

系统后端支持您的实验跟踪解决方案的逻辑。这一层是您编码实验跟踪领域规则并确定数据如何创建、存储和修改的地方。

前端是该层的客户端之一。您可以拥有其他客户端,比如与模型注册表、数据质量监控组件等的集成。与大多数传统软件一样,创建此层和API层中的服务将是有效的。

对于基本的实验跟踪工具,您需要实现要构建的系统后端的两个主要组件:

  • 1
    用户、项目和工作区注册表。
  • 2
    实际跟踪组件。

用户、项目和工作区注册表

此组件帮助您管理实验跟踪工具的用户并跟踪他们运行的实验的活动。此组件需要执行的主要任务包括:

  • 处理身份验证和授权,
  • 项目管理和权限,
  • 每个项目或工作区的配额(每秒请求次数、存储量)。

您想要实现的权限级别详细程度是多少?您可以在细粒度权限、自定义角色和粗粒度预定义角色之间进行选择。

跟踪组件

跟踪组件是您需要实现的实际实验跟踪逻辑。以下是您应考虑实现的一些部分:

  • 属性存储
  • Blob文件存储
  • 序列存储
  • 查询引擎

属性存储

您的运行具有属性(参数、指标、数据样本等),您需要一种方法将此类数据与运行关联起来。这就是属性存储和表中的常规数据组织发挥作用的地方,因此数据查找对用户来说很容易进行。当然,关系数据库在这里非常有价值。

您希望的一致性水平是什么?您可以接受最终一致性吗?还是您更愿意在API层面上以更高的延迟为代价获得强一致性?

Blob和文件存储

一些属性不容易适应数据库字段,您需要一个数据模型来处理这个问题。Blob存储是一种高性价比的解决方案。其主要优势在于您可以存储大量的非结构化数据。您的用户可能希望存储源代码、数据样本(CSV、图像、Pickled DataFrames等)、模型权重、配置文件等。这个解决方案非常方便。

关键的考虑因素是存储服务的长期成本效益和低延迟访问

序列存储

您需要确定一种存储序列的方式,特别是数字序列,这些是需要特别关注的属性。根据您的用例,它们可能有数十个到数百万个元素。以一种让用户可以在UI中访问数据的方式存储它们可能是具有挑战性的。您还可以将您支持的序列数量限制为,比如,1,000个元素,这对于许多用例来说已经足够。

关键的考虑因素是:

  • 1. 长期存储成本效益。
  • 2. 功能之间的权衡。
  • 3. 相对实现的简单性。

查询引擎

您还需要添加一个过滤具有非常不同结构的运行的功能,这意味着您需要一个强大的数据库引擎来处理这些类型的查询。当数据量不是微不足道时,简单的关系数据库无法有效地处理这些查询。另一种选择是严格限制您可以过滤或分组的实验属性的数量。如果您更深入地进行操作,几个数据库技巧就足以解决这个问题。

关键的考虑因素是用户可以过滤、排序或按组查询的属性数量与实现的简单性之间的权衡

客户端库(API和生态系统集成)

在高级别上,API层用于屏蔽客户端对结构、组织甚至特定操作所暴露的服务的知识,这非常有用。它不应该像后端层一样改变任何东西或运行逻辑。相反,它应提供一个标准的代理接口,公开您配置它公开的服务端点和API操作。

构建实验追踪工具时,通常原始(本地)API是不够的。为了使解决方案对用户可用,它需要与他们的代码无缝集成。如果您首先定义API层,只要API合同不改变,客户端在对代码库进行基础重构时需要进行最小的甚至没有更改。

实际上,这意味着您可以使用一个库(最好是Python)来处理与后端服务器的日志记录和查询数据的繁重工作。它处理重试和退避;您可能希望从一开始实现一个持久的异步队列-持久以保证数据的持久性,异步以确保它不会拖慢用户的模型训练过程。

由于实验追踪工具还需要与您的数据、训练和模型推广工具等等一起工作,因此您的API层需要与ML和数据生态系统中的工具集成。

ML和数据生态系统在不断发展,因此构建集成不是终点。它需要与其工作的工具的新版本进行测试,并在API被弃用或更改(通常是没有警告的情况下)时进行更新。您还可以通过将用户导向集成的旧版本而不强迫他们对实验代码进行更改来解决此问题。

实验追踪软件架构(后端)的考虑因素

评估可行性是建立实验跟踪系统结构和评估是否构建正确的重要部分。这意味着根据您所建立的要求开发一个高层次的架构。

架构设计应该展示出您所分析的层和组件应该如何在分层架构中相互配合。所谓“分层架构”,是指将前端架构与后端架构区分开来。本文重点关注后端架构的考虑因素,即实验跟踪逻辑编码的地方。

一旦您了解了后端架构,您还可以遵循领域驱动设计原则来构建前端架构。

后端架构层

为了构建系统架构,遵循一些有助于使结构尽可能简单高效的软件架构原则。其中一个原则描述了模块化。您希望软件具有模块化和良好的结构,以便您可以快速理解源代码,节省构建系统的时间,并可能减少技术债务。

您用于跟踪实验的工具几乎肯定会发展,因此当您开发第一个架构时,它将是初步的,只是能工作的东西。由于您的架构将随着时间的推移而发生变化,它将需要遵循一致的设计模式,以节省维护和添加新功能的时间。

下面是一个基本实验跟踪解决方案的后端架构层示例,考虑了之前列出的要求和组件:

理想实验跟踪工具的后端架构

使用之前解释的部分,您可以在架构中找到不同的模块,并了解它们如何相互配合。

架构考虑因素:分离身份验证和授权

您可能已经注意到,在架构中,身份验证与授权是分开的。由于您可能有不同的用户,您希望他们通过身份验证组件验证其凭据。

通过授权组件,软件管理员可以管理每个用户的权限和访问级别。您可以在本文中详细了解身份验证和授权之间的区别。

用户管理组件的配额管理部分将帮助管理用户可用的存储限制。

在构建实验跟踪工具之前需要考虑的事项

就其价值而言,您已经在最高层次上了解了构建实验跟踪软件所需的内容。那么接下来的问题就是:“在构建实验跟踪工具之前,我需要考虑哪些因素?”

嗯,也许这是一个愚蠢的问题,不是您会问的问题,如果您的组织的战略软件——核心产品提供——是一个实验跟踪工具。如果不是,您应该继续阅读!

您可能已经熟悉了这个软件开发困境:构建还是购买。如果实验跟踪工具是您组织的运营软件(用于支持数据和机器学习团队的常规运营),那么回答这个问题的下一个重要考虑因素将是您组织在以下方面的成熟程度:

  • 经验
  • 人才
  • 以及资源时间金钱)。
决定是构建还是购买实验跟踪工具时需要考虑的因素

让我们看看在尝试做出这个决策时,您需要问自己的一些问题。

您的组织曾经开发过实验跟踪工具吗?

例如,如果您的组织从未开发过实验跟踪器,那么要适应行业标准、最佳实践、安全性和合规性,需要更多的时间、试验和错误。如果没有现成的“基础”可供构建,尤其是来自您的工程团队,那么可能无法满足行业标准和公司期望的hacky构建可能会失败。

您和其他利益相关者必须考虑公司能否承担试错成本,或者是否需要一个有效、更安全、更可靠的现成解决方案。

有哪些可用于构建的人才?

如果您是一家产品或软件公司,您可能已经有软件开发人员在为您的战略产品工作。您必须考虑将内部开发人员的技能投入到构建实验跟踪工具中的机会成本,而不是利用他们的技能来改进您的主要产品。

在内部开发实验追踪器可以显著提高产品或机器学习团队工作流程的效率。然而,这可能会使开发人员的技能和时间从构建其他更有意义的差异化因素或最终浪费时间和精力的事物中分散开来。

我们建设的成本是多少?

内部建设实验追踪器的成本主要是维护成本。组织是否能够承担保持软件更新、修复漏洞和添加新功能的成本?

预算包括保持工具运行所需的基础设施和在原始开发人员离开时雇佣新人的费用。考虑昂贵且耗时的软件开发项目的长期影响,而不仅仅是短期节省。

降低维护成本的重要一部分是减少高额、意外的费用同时出现的机会。换句话说,就像一般维护成本一样,管理风险的最佳时机是在软件生命周期的早期,确定是否需要构建或外包某个功能。

构建实验追踪工具需要多长时间?

你必须考虑机会成本。例如,如果制作一个定制工具需要两个月的时间,那么在这段时间内你还能构建什么?实施追踪组件是否需要更长时间?从原型到最终稳定版本构建工具需要多少个开发周期?

如果你是一个大型企业的一部分,有足够的开发周期来构建实验追踪器,那可能不是一个问题。但当不是这种情况,特别是与你的用例无关的问题时,获取一个能够与你的堆栈集成,让你专注于构建战略性软件的现成解决方案可能更好。

很可能你没有足够的开发周期来达到从标准实验管理工具中获得所需的复杂性和功能丰富性的水平,所以将开发周期用于它可能不值得。

例如,在neptune.ai,我们过去五年来一直专注于构建一个强大的元数据存储库,用于管理用户的所有模型构建元数据和跟踪他们的实验。我们从客户和机器学习社区中吸取经验,并不断改进产品,使其在各种用例和工作负载中具备稳健性。

以快速编码为代价的设计和架构几乎总是错误的选择。特别是当软件是运营中的时候,因为你没有太多时间专注于良好的架构和构建必须具备的功能。毕竟,它不是直接影响或定义你的组织的战略性软件。

最后的思考

在本文中我们涵盖了很多内容,让我们回顾一下一些关键的要点:

  • 实验追踪是一项强度很大的活动。使用正确的工具和自动化使其易于使用和高效。
  • 为实验追踪工具制定有效的需求应该要求:考虑到用户将如何利用软件以及它如何与数据堆栈和下游服务集成。基本上,考虑到启动并运行所需的最低要求,不涉及复杂性。
  • 实验追踪软件的后端层是最重要的层。您需要确保实施跟踪组件和工作空间注册表以顺利管理用户会话。

您建设实验追踪器的目标是确保为用户提供记录实验数据、跟踪这些实验并安全协作的组件。如果他们能够在几乎没有额外工作量的情况下完成这些任务,那么您可能已经构建了适合您团队的工具。

在大多数情况下,我们发现构建第一个版本只是第一步,特别是如果它不是您组织的核心软件组件。随着用户需求清单的增加,由于出现新问题,您可能会发现添加新功能变得具有挑战性。

您和相关利益相关者需要考虑将资源投入到满足用户需求和潜在行业标准的需要上的价值。

下一步

那么你接下来要做什么?是否有兴趣进行构建?还是认为采用现成的解决方案更好?

我们考虑过的大多数模型注册平台都假设存储模型的特定形式。这种形式是实验,每个模型都是一系列中的下一个。在 Stitch Fix 的情况下,我们的模型并不遵循线性定位模式。

它们可以适用于特定地区、业务线、实验等,并且彼此之间可以在某种程度上互换。如何轻松管理这些维度对于数据科学家需要访问其模型至关重要。

— Elijah Ben Izzy 和 Stefan Krawczyk,《免费部署;Stitch Fix 数据科学家的机器学习平台》

这是Stefan Krawczyk谈论为什么他们决定构建一个模型注册表而不是使用现有的解决方案。在同样的背景下,除非您有特殊的用户需求,现有的开源或付费解决方案无法满足,构建和维护一个实验追踪工具可能不是开发人员时间和精力的最有效利用。

您想更深入地了解还是只是聊聊构建实验追踪器?请与我们联系;我们非常乐意交流经验。

当然,如果您决定跳过构建过程,而是使用 Neptune,那么请随时注册并先试用一下。如果您有任何问题,请与我们联系!

参考资料和资源

  • 使用DALEX和Neptune进行可解释和可重现的机器学习模型开发 – neptune.ai
  • 您应该购买还是构建软件?- YouTube