【MLOps】第 5 章 : 生产准备

文章讨论了将机器学习模型从开发转移到生产环境的步骤,包括环境适应、工具注意事项、性能考虑和验证过程。强调了模型风险评估和质量保证的重要性,涵盖了模型的公平性、可审计性和安全性。此外,提到了对抗性攻击和模型不当行为的管理,以及如何通过MLOps流程来降低风险和增强安全性。
摘要由CSDN通过智能技术生成

 🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎

📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​

📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】  深度学习【DL】

​​

 🖍foreword

✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。

如果你对这个系列感兴趣的话,可以关注订阅哟👋

文章目录

运行时环境

从开发到生产环境的适应

工具注意事项

性能考虑

验证和投入生产之前的数据访问

关于运行时环境的最终想法

模型风险评估

模型验证的目的

机器学习模型风险的起源

机器学习的质量保证

关键测试注意事项

分析模型公平性

再现性和可审计性

机器学习安全

对抗性攻击

其他漏洞

风险缓解模型

不断变化的环境

模型之间的交互

模型不当行为

总结


确认某事实验室中的工作从来都不是它在现实世界中能很好工作的确定标志,机器学习模型也不例外。不仅生产环境通常与开发环境有很大不同,而且与生产中的模型相关的商业风险也更大。重要的是要了解和测试过渡到生产的复杂性,并充分降低潜在风险。

本章探讨了准备生产所需的步骤(在图 5-1 的整个生命周期背景中突出显示)。目标是通过扩展来说明稳健 MLOps 系统必须考虑的元素。

图 5-1 在机器学习项目生命周期的大背景下突出强调生产准备

运行时环境

将模型投入生产的第一步是确保其在技术上可行。正如第 3 章中所讨论的,理想的 MLOps 系统有利于快速、自动化的部署,而不是劳动密集型流程,并且运行时环境对哪种方法流行有很大影响。

生产环境有多种形式:定制服务、数据科学平台、专用服务(如 TensorFlow Serving)、底层基础设施(如 Kubernetes 集群)、嵌入式系统上的 JVM 等。为了使事情变得更加复杂,请考虑在一些组织中,多个异构生产环境共存。

理想情况下,在开发环境中运行的模型将被验证并按原样发送到生产环境;这最大限度地减少了适应工作量,并提高了模型在生产中的表现与在开发中一样的机会。不幸的是,这种理想情况并不总是可能的,而且团队完成一个长期项目后才意识到它不能投入生产的情况并非闻所未闻。

从开发到生产环境的适应

在适配方面工作,在一端光谱,开发和生产平台来自同一供应商或以其他方式可互操作,并且开发模型可以在生产中无需任何修改即可运行。在这种情况下,将模型投入生产所需的技术步骤减少为几次点击或命令,并且所有工作都可以集中在验证上。

另一方面,在某些情况下,模型需要从头开始重新实现——可能是由另一个团队,也可能是使用另一种编程语言。考虑到所需的资源和时间,今天很少有这种方法有意义的案例。然而,这在许多组织中仍然是现实,并且通常是缺乏适当的工具和流程的结果。现实情况是,将模型移交给另一个团队来重新实现并适应生产环境意味着该模型要几个月(也许几年)才能投入生产,甚至根本不会投入生产。

在这两种极端情况之间,可以对模型执行大量转换或与其环境交互以使其与生产兼容。在所有情况下,在尽可能模仿生产的环境中而不是在开发环境中执行验证至关重要。

工具注意事项

要求的格式发送到生产应该尽早考虑,因为它可能对模型本身和将其生产化所需的工作量产生很大影响。例如,当使用 scikit-learn (Python) 开发模型并且生产是基于 Java 的环境,需要 PMML 或 ONNX 作为输入时,显然需要转换。

在这种情况下,团队应该在开发模型时设置工具,最好是在模型的第一个版本完成甚至开始之前。未能预先创建此管道会阻止验证过程(当然,不应在 scikit-learn 模型上执行最终验证,因为它不会投入生产)。

性能考虑

可能需要转换的另一个常见原因是性能。例如,与转换为 C++ 的等效模型相比,Python 模型对单个记录进行评分的延迟通常更高。生成的模型可能会快几十倍(尽管显然这取决于很多因素,而且结果也可能是一个慢几十倍的模型)。

当生产模型必须在低功耗设备上运行时,性能也会发挥作用。例如,在深度神经网络的特定情况下,经过训练的模型可能会变得非常大,具有数十亿或数千亿的参数。在小型设备上运行它们是根本不可能的,并且在标准服务器上运行它们可能会很慢且昂贵。

对于这些模型,优化的运行时间是不够的。为了获得更好的性能,必须优化模型定义。一种解决方案是使用压缩技术:

  • 通过量化,模型可以使用 32 位浮点数进行训练,并用于较低精度的推理,从而使模型需要更少的内存,速度更快,同时基本保持准确性。

  • 通过剪枝,我们可以简单地从神经网络中删除权重(甚至整个层)。这是一种相当激进的方法,但有些方法可以保持准确性。

  • 通过蒸馏,较小的“学生”网络被训练来模仿更大、更强大的网络。如果做得适当,这可以产生更好的模型(与尝试直接从数据训练较小的网络相比)。

如果初始模型的训练方式能够在执行时减少信息丢失,那么这些方法是有效的,因此这些操作不仅仅是事后训练模型的转换,而是指导模型的训练方式。这些方法仍然是非常新的并且相当先进,但已经被普遍使用用自然语言处理 (NLP) 预训练模型。

验证和投入生产之前的数据访问

验证前需要解决的另一个技术问题投入生产是数据访问。例如,评估公寓价格的模型可能使用邮政编码区域的平均市场价格;然而,请求评分的用户或系统可能不会提供这个平均值,而很可能只提供邮政编码,这意味着需要查找才能获取平均值。

在某些情况下,数据可以被冻结并与模型捆绑在一起。但是,当这是不可能的时候(例如,如果数据集太大或者丰富数据需要始终是最新的),生产环境应该访问数据库,从而具有通信所需的适当的网络连接、库或驱动程序安装了数据存储,并且身份验证凭据以某种形式的生产配置存储。

在实践中管理此设置和配置可能非常复杂,因为它再次需要适当的工具和协作(特别是扩展到数十个模型)。使用外部数据访问时,在与生产密切匹配的情况下进行模型验证更为重要,因为技术连接是生产故障的常见来源。

关于运行时环境的最终想法

训练模型是通常是最令人印象深刻的计算,需要高水平的软件复杂性、海量数据量以及具有强大 GPU 的高端机器。但在模型的整个生命周期中,很可能大部分计算都花费在推理时间(即使此计算简单且更快几个数量级)。这是因为模型经过一次训练,就可以使用数十亿次进行推理。

对复杂模型进行缩放推理可能成本高昂,并且会对能源和环境产生重大影响。降低模型的复杂性或压缩极其复杂的模型可以降低运行机器学习模型的基础设施成本。

重要的是要记住,并非所有应用程序都需要深度学习,事实上,并非所有应用程序都需要机器学习。控制生产复杂性的一个有价值的做法是开发复杂的模型只是为了提供看似可实现的基准。投入生产的模型可以是一个简单得多的模型,具有降低操作风险、提高计算性能和降低功耗的优点。如果简单模型足够接近高复杂度基线,那么它可能是更理想的生产解决方案。

模型风险评估

在探索如何进行之前验证应该是在理想的 MLOps 系统中完成时,考虑验证的目的很重要。正如第 4 章所讨论的,模型试图模仿现实,但它们并不完美。它们的实现可能存在错误,它们执行的环境也可能存在错误。模型在生产中可能产生的间接的、现实世界的影响永远无法确定,看似微不足道的齿轮发生故障可能会在复杂的系统中产生巨大的后果。

模型验证的目的

就是,为了一些在一定程度上可能(更不用说绝对必要)预测生产中模型的风险,从而进行设计和验证以尽量减少这些风险。随着组织变得越来越复杂,必须了解非自愿故障或恶意攻击在企业中大多数机器学习的使用中都具有潜在的威胁,而不仅仅是在金融或安全相关的应用程序中。

在将模型投入生产之前(实际上从机器学习项目一开始就不断),团队应该问一些令人不安的问题:

  • 如果模型以最糟糕的方式运行怎么办?

  • 如果用户设法提取训练数据或模型的内部逻辑怎么办?

  • 财务、商业、法律、安全和声誉风险有哪些?

对于高风险应用程序,整个团队(尤其是负责验证的工程师)必须充分了解这些风险,以便他们能够适当地设计验证过程,并应用适合风险程度的严格性和复杂性。风险。

在许多方面,机器学习风险管理涵盖了在银行业和保险业等许多行业中成熟的模型风险管理实践。然而,机器学习引入了新型风险和责任,并且随着数据科学的民主化,它涉及到许多没有传统模型风险管理经验的新组织或团队。

机器学习模型风险的起源

风险 ML 模型的大小由于数学原因,可能会带来难以建模,而且还因为风险的具体化是通过现实世界的后果而产生的。机器学习指标,特别是成本矩阵,允许团队评估在“名义”情况下运行模型的平均成本,即与运行完美的神奇模型相比的交叉验证数据。

尽管计算这一预期成本非常重要,但很多事情都可能出现远远超出预期成本的问题。在某些应用中,风险可能是财务上无限的责任、个人的安全问题或组织的生存威胁。ML 模型风险主要来源于:

  • 设计、训练或评估模型(包括数据准备)中的错误、错误

  • 运行时框架中的错误、模型后处理/转换中的错误或模型与其运行时之间隐藏的不兼容性

  • 训练数据质量低

  • 生产数据与训练数据差异较大

  • 预期的错误率,但失败的后果比预期的要严重

  • 滥用模型或误解其输出

  • 对抗性攻击

  • 特别是源自版权侵权或模型输出责任的法律风险

  • 有信誉的由于偏见、不道德地使用机器学习等而产生的风险。

风险发生的概率及其严重程度可以通过以下方式放大:

  • 模型的广泛使用

  • 快速变化的环境

  • 模型之间的复杂交互

以下部分提供了有关这些威胁以及如何缓解这些威胁的更多详细信息,这应该是组织部署的任何 MLOps 系统的最终目标。

机器学习的质量保证

软件工程有开发了一套成熟的的工具和质量保证 (QA) 方法论,但数据和模型的等效方法仍处于起步阶段,这使得纳入 MLOps 流程具有挑战性。统计方法和记录最佳实践是众所周知的,但大规模实施它们并不常见。

尽管它作为生产准备章节的一部分进行了介绍,但需要明确的是,机器学习的 QA 不仅仅发生在最终验证阶段;相反,它应该伴随模型开发的所有阶段。其目的是确保符合流程以及机器学习和计算性能要求,其详细程度与风险级别成比例。

如果负责验证的人员不是开发模型的人员,则他们必须接受足够的机器学习培训并了解风险,以便他们能够设计适当的验证或检测模型提出的验证中的漏洞开发团队。同样重要的是,组织的结构和文化赋予他们适当报告问题和促进持续改进的权力,或者在风险水平合理的情况下阻止生产。

强大的 MLOps 实践表明,在发送到生产之前执行 QA 不仅仅是技术验证。这也是创建文档并根据组织准则验证模型的机会。特别是,这意味着应该知道所有输入数据集、预训练模型或其他资产的来源,因为它们可能受到法规或版权的约束。出于这个原因(尤其是出于计算机安全原因),一些组织选择只允许列入白名单的依赖项。虽然这会显着影响数据科学家快速创新的能力,尽管可以部分自动报告和检查依赖项列表,但它也可以提供额外的安全性。

关键测试注意事项

显然,模型测试将包括将模型应用于精心策划的数据并根据要求验证测量结果。如何选择或生成数据以及需要多少数据是至关重要的,但这将取决于模型解决的问题。

在某些情况下,测试数据不应始终与“真实世界”数据匹配。例如,准备一定数量的场景可能是一个好主意,虽然其中一些场景应该与实际情况相匹配,但其他数据应该以可能有问题的方式专门生成(例如,极值、缺失值)。

必须同时收集指标统计(准确性、精确度、召回率等)以及计算(平均延迟、第 95 个延迟百分位数等)方面,以及测试场景应该失败如果对它们的某些假设没有得到验证。例如,如果模型的准确率低于 90%,平均推理时间超过 100 毫秒,或者超过 5% 的推理时间超过 200 毫秒,则测试应该失败。这些假设也可以称为期望检查断言,就像在传统软件工程中一样。

也可以对结果进行统计检验,但通常用于亚群体。能够将模型与其之前的版本进行比较也很重要。它可以允许实施冠军/挑战者方法或检查指标是否突然下降。

分析模型公平性

通过基于“敏感”变量(可能会或可能不会用作模型的特征)将数据拆分为子总体来设计测试场景可能很有用。这就是评估公平性(通常在性别之间)的方式。

几乎所有适用于人的模​​型应该从公平性角度进行分析。评估模型公平性的失败将越来越多地对组织产生业务、监管和声誉影响。。

除了验证 ML 和计算性能指标外,模型稳定性是需要考虑的重要测试属性。当稍微改变一项功能时,人们期望结果会有微小的变化。虽然这并不总是正确的,但它通常是一个理想的模型属性。一个非常不稳定的模型除了提供令人沮丧的体验外,还会引入很多复杂性和漏洞,因为即使该模型具有不错的性能,也会让人感觉不可靠。模型稳定性没有单一的答案,但一般来说,更简单的模型或更正则化的模型表现出更好的稳定性。

再现性和可审计性

MLOps 中的再现性不相同与学术界一样的意思。在学术界,可重复性本质上意味着对实验结果的描述足够好,以至于另一个有能力的人可以仅使用解释来复制该实验,并且如果这个人没有犯任何错误,他们将得出相同的结论。

一般来说,MLOps 的再现性还涉及轻松重新运行完全相同的实验的能力。这意味着该模型附带详细的文档、用于训练和测试的数据,以及捆绑模型实现及其运行环境的完整规范的工件(请参阅“版本管理和可再现性” 。可重复性对于证明模型结果至关重要,对于调试或建立在以前的实验上也是必不可少的。

可审核性是与再现性有关,但它增加了一些要求。为了使模型可审计,必须能够从可靠的中央存储访问机器学习管道的完整历史记录,并轻松获取所有模型版本的元数据,包括:

  • 完整的文档

  • 允许使用其确切的初始环境运行模型的工件

  • 测试结果,包括模型解释和公平性报告

  • 详细的模型日志和监控元数据

可审计性可以在一些受到严格监管的应用程序中,这是一项义务,但它对所有组织都有好处,因为它可以促进模型调试、持续改进以及跟踪操作和责任。用于机器学习的完整 QA 工具链(以及 MLOps 流程)应该提供关于需求的模型性能的清晰视图,同时也促进可审计性。 

即使 MLOps 框架允许数据科学家(或其他人)找到包含所有元数据的模型,理解模型本身仍然具有挑战性。

为了产生强大的实际影响,可审计性必须允许人类直观地理解系统的所有部分及其版本历史。这并没有改变理解机器学习模型(即使是相对简单的模型)需要适当培训的事实,但根据应用程序的重要性,更广泛的受众可能需要能够理解模型的细节。因此,完全可审计性的代价应该与模型本身的关键性相平衡。

机器学习安全

作为一个软件,部署模型运行在其服务框架可能会带来多种安全问题,从低级故障到社会工程。机器学习引入了一系列新的潜在威胁,攻击者提供旨在导致模型出错的恶意数据。

有许多潜在攻击的案例。例如,垃圾邮件过滤器是机器学习的早期应用,基本上基于对字典中的单词进行评分。垃圾邮件创建者避免检测的一种方法是避免编写这些确切的单词,同时仍然使他们的消息易于人类读者理解(例如,使用奇异的 Unicode 字符、自愿引入拼写错误或使用图像)。

对抗性攻击

更现代的但非常类似的例子机器学习模型安全问题是针对深度神经网络的对抗性攻击在这种网络中,人眼看似微小甚至不可能注意到的图像修改可能会导致模型极大地改变其预测。其核心思想在数学上相对简单:由于深度学习推理本质上是矩阵乘法,因此精心选择的系数小扰动可能会导致输出数字发生较大变化。

其中一个例子是,粘在路标上的小贴纸可能会迷惑自动驾驶汽车的计算机视觉系统,使标志看不见或被系统错误分类,但人类仍然完全可见和理解。攻击者对系统了解得越多,就越有可能找到令系统困惑的示例。

人类可以使用理性来找到这些示例(特别是对于简单模型)。然而,对于深度学习等更复杂的模型,攻击者可能需要执行许多查询,并使用暴力测试尽可能多的组合或使用模型搜索有问题的示例。对策的难度随着模型的复杂性和可用性的增加而增加。逻辑回归等简单模型本质上是免疫的,而开源预训练深度神经网络基本上总是容易受到攻击,即使有先进的内置攻击检测器。

对抗性攻击不一定发生在推理时。如果攻击者可以访问训练数据,即使是部分数据,然后他们就可以控制系统。这种攻击传统上被称为计算机安全中的中毒攻击

著名的例子是微软2016年发布的Twitter聊天机器人。发布后仅几个小时,该机器人就开始生成非常具有攻击性的推文。这是由机器人适应其输入引起的;当意识到一些用户提交了大量令人反感的内容时,机器人开始复制。理论上,中毒攻击可能是由于入侵而发生的,甚至是通过预训练模型以更复杂的方式发生的。但在实践中,人们应该主要关心从易于操纵的数据源收集的数据。发送到特定帐户的推文就是一个特别明显的例子。

其他漏洞

有些模式本身并不利用机器学习漏洞,但它们确实使用了机器学习模型的方式会导致不良情况。一个例子是信用评分:对于给定的金额,灵活性较差的借款人倾向于选择较长的期限来降低还款额,而不关心自己还款能力的借款人可能会选择较短的期限来降低总成本的信用。销售人员可能会建议那些分数不够好的人缩短付款时间。这增加了借款人和银行的风险,并且不是一个有意义的行动方案。相关性不是因果关系!

模型还可以通过多种方式泄漏数据。由于机器学习模型从根本上可以被视为对其所训练的数据的总结,因此它们可能会泄漏有关训练数据的或多或少精确的信息,在某些情况下甚至会泄露完整的训练集。例如,想象一下,一个模型使用最近邻算法来预测某人的工资。如果知道在该服务上注册的某个人的邮政编码、年龄和职业,就很容易获得该人的确切收入。有多种攻击可以通过这种方式从模型中提取信息。

除了技术强化和审计之外,治理在安全方面也发挥着关键作用。必须明确分配责任,并确保安全性和执行能力之间的适当平衡。建立反馈机制也很重要,员工和用户应该有一个简单的渠道来沟通违规行为(包括可能奖励报告漏洞的“错误赏金计划”)。围绕系统建立安全网以降低风险也是可能且必要的。

机器学习安全与一般计算机系统安全有许多共同特征,其中一个主要思想是安全不是系统的附加独立特征;也就是说,通常您无法保护未设计为安全的系统,并且组织流程必须从一开始就考虑到威胁的性质。强大的 MLOps 流程(包括本章中描述的所有生产准备步骤)可以帮助使这种方法成为现实。

风险缓解模型

一般来说,如讨论过第 1 章详细介绍,模型部署越广泛,风险就越大。当风险影响足够高时,控制新版本的部署至关重要,这正是严格控制的 MLOps 流程尤其发挥作用的地方。渐进式或金丝雀式部署应该是一种常见的做法,首先将新版本的模型提供给组织或客户群的一小部分,然后慢慢增加该比例,同时监控行为并在适当的情况下获取人工反馈。

不断变化的环境

快速变化的环境也会增加风险,因为本章前面提到过。投入的变化是一个相关且明确的风险,后面深入探讨了这些挑战以及如何更详细地解决这些挑战。但值得注意的是,变化的速度可能会放大风险,具体取决于应用程序。变化可能如此之快,甚至在监控系统发送警报之前就已经产生了后果。也就是说,即使拥有有效的监控系统和重新训练模型的程序,补救所需的时间也可能是一个关键威胁,特别是如果简单地根据新数据重新训练模型是不够的,并且必须开发新模型的话。在此期间,生产系统出现故障可能会给组织造成巨大损失。

为了控制这种风险,通过 MLOps 进行的监控应该具有足够的反应性(通常,每周计算的分布警报可能还不够),并且该程序应考虑补救所需的时间。例如,除了重新训练或推出策略之外,该过程还可以定义将触发系统降级模式的阈值。降级模式可能只是向最终用户显示警告消息,但也可能像关闭功能失调的系统以避免损害一样激烈,直到可以部署稳定的解决方案。

足够频繁的不太引人注目的问题也可能造成很快变得难以控制的损害。如果环境经常变化,即使修复似乎从来不紧急,模型也可能总是略有偏差,永远不会在其名义情况下运行,并且运营成本可能难以评估。这只能通过专用 MLOps 来检测,包括相对长期的监控和重新评估运行模型的成本。

在许多情况下,在更多数据上重新训练模型将逐渐改进模型,并且这个问题最终会消失,但这可能需要时间。在这种融合之前,解决方案可能是使用不太复杂的模型,该模型可能具有较低的评估性能,并且在频繁变化的环境中可能更加一致。

模型之间的交互

模型之间复杂的交互可能是最具挑战性的风险来源。随着 ML 模型的普及,此类问题将越来越受到关注,并且它是 MLOps 系统的一个重要的潜在关注领域。显然,添加模型通常会增加组织的复杂性,但复杂性不一定与模型数量成比例线性增长;拥有两个模型比理解总和更复杂,因为它们之间存在潜在的相互作用。

此外,总体复杂性在很大程度上取决于如何在本地范围内设计与模型的交互并在组织范围内进行管理。在链中使用模型(其中一个模型使用来自另一个模型的输入)会产生显着的额外复杂性以及完全出乎意料的结果,而在独立的并行处理链中使用模型(每个链都尽可能短且可解释)更具可持续性设计大规模部署机器学习的方法。

首先,模型之间缺乏明显的交互使得复杂度接近于线性增长(但请注意,在实践中,这种情况很少见,因为即使模型没有连接,现实世界中也总是存在交互)。此外,在冗余处理链中使用的模型可以避免错误——也就是说,如果一个决策是基于几个独立的处理链,并且方法尽可能不同,它会更稳健。

最后,一般来说,模型越复杂,它与其他系统的交互可能越复杂,因为它可能有很多边缘情况,在某些领域稳定性较差,对上游模型的变化反应过度,或者混淆敏感的下游模型等。在这里,我们再次看到模型复杂性是有成本的,而且是一种潜在的高度不可预测的成本。

模型不当行为

可采取多项措施实施以避免模型不当行为,包括实时检查其输入和输出。在训练模型时,可以通过检查训练和验证模型的时间间隔来表征其适用范围。如果推理时的特征值超出范围,系统可以触发适当的措施(例如,拒绝样本或发出警告消息)。

控制特征值区间很有用技术简单,但可能还不够。例如,在训练评估汽车价格的算法时,数据可能提供了近期轻型汽车和旧重型汽车的示例,但没有近期重型汽车的示例。这些复杂模型的性能是不可预测的。当特征数量很大时,由于维数灾难,这个问题变得不可避免——即组合的数量相对于特征的数量呈指数增长。

在这些情况下,可以使用更复杂的方法,包括异常检测以识别模型在其应用程序域之外使用的记录。评分后,可以在确认推论之前检查模型的输出。在分类的情况下,许多算法除了预测之外还提供确定性分数,并且可以固定阈值以接受推理输出。请注意,这些确定性分数通常不会转化为概率,即使它们在模型中以这种方式命名。

共形预测是一组有助于校准这些分数可以获得正确概率的准确估计。对于回归,可以根据预定间隔检查该值。例如,如果模型预测一辆汽车的成本为 50 美元或 500,000 美元,您可能不想在此预测上投入任何业务。所实施技术的复杂性应与风险级别相关:高度复杂、高度关键的模型将需要更彻底的保障措施。

总结

在实践中,准备生产模型从开发阶段开始;也就是说,在开发模型时应考虑生产部署的要求、安全影响和风险缓解方面。MLOps 包括在将模型发送到生产之前有一个明确的验证步骤,成功准备生产模型的关键思想是:

  • 清楚地识别风险的性质及其严重程度

  • 了解模型复杂性及其在多个层面上的影响,包括延迟增加、内存和功耗增加、生产中解释推理的能力降低以及更难以控制的风险

  • 提供简单但明确的质量标准,确保团队接受适当的培训,并且组织结构允许快速可靠的验证过程

  • 自动化所有可以自动化的验证,以确保其正确且一致地执行,同时保持快速部署的能力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sonhhxg_柒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值