单元测试是现代协作软件开发的重要组成部分。特别是随着项目贡献者数量的增长,严格的单元测试覆盖有助于监视和实施高质量。拥有一个良好的系统来生成测试用例对于识别代码中困难的边缘用例非常重要。
我们使用NumPy而且PyTorch在Uber AI建立了许多机器学习(ML)模型。我们的内部超参数调优服务大量使用PyTorch,并将张量值作为其函数的输入。
为了使这些ML模型的单元测试更容易,我们引入假设顾函数这是Uber创建的一个新的开源Python包。的扩展假设假设GU Func允许对向量化NumPy函数进行基于属性的测试。这个工具在发现Uber AI实验室内部开发的工具的错误方面很有用,现在,随着它的开源发布,可以被更广泛的ML社区利用。
假设和基于属性的测试
ML模型的重复性和随意性使得标准单元测试非常困难。最常见的单元测试类型被称为黄金测试,如下所示:
科学家们经常为机器学习代码编写黄金测试,因为他们觉得选择很少:很难指定正确的输出应该是什么。
然而,基于属性的测试是一种替代方法。使用这种单元测试方法,用户生成许多用例,试图覆盖整个空间,然后测试所需的属性是否被遵守,这种技术通常称为自动生成测试或模糊测试。
假设是用于基于属性测试的流行Python包(带有其他语言的端口)吗.这个库提供了一个鉴于允许策略构建测试用例的装饰器。假设已经证明了基于属性的测试是在边缘情况下发现错误的单元测试的一种非常有效的形式。以这种形式编写单元测试表现在以下方面:测试一个函数喷火,可以这样写:
例如,属性可以是输出z等于较慢实现的输出,foo_slow.有时其他属性如“z已排序”也适用;或者,我们可以称之为逆函数。经典的例子来自假设快速启动是编码器-解码器测试:
此策略不包括对通过NumPy函数签名指定其允许输入的函数的支持,这使得调试更加困难。
NumPy支持
许多机器学习软件依赖于NumPy(或类似的张量库,如PyTorch或TensorFlow),而不是像上面所示的那样测试离散代码。假说包支持为NumPy生成测试用例。事实上,假说中对NumPy支持的最初贡献来自于条纹.在Stripe博客上的一篇文章中,前Stripe工程雷竞技到底好不好用师Sam Ritchie写道:“假设是我们发现的唯一一个为测试机器学习的代码提供有效工具的项目,而在这个领域,测试和正确性是出了名的困难。”
的hypothesis.extra.numpy功能支持单元测试策略,如:
假设GU函数可拓
假说的NumPy支持对我们的目的来说不够好,因为我们想要跨变量大小的输入进行测试,并遵守相互的大小限制。所以我们决定编写自己的扩展。
大多数基于numpy的函数在参数之间有相互维度兼容性约束。例如,np.dot函数接受一个(m,n)数组和一个(n,p)数组。NumPy在其通用(GU)函数中发展了函数签名的概念API.例如,np.dot签名”(m, n),(氮、磷)- > (m, p)”。
这个约束使我们能够生成以前不容易生成的测试用例,仅仅通过指定功能签名。
将此功能进一步扩展,假说GU Func可以采用功能签名并定义生成与签名兼容的测试用例的策略。从我们的文档中,我们有这样的测试:
测试广播
另一个难以测试的功能是广播.我们想测试任何向量化函数是否正确处理广播。这个测试是特别重要的,因为现代的批处理训练方法经常涉及一些广播和惯例可能有点复杂。例如,烟花Uber的团队已经注意到,Pyro中至少50%的bug是由广播错误引起的。
NumPy定义了一个公约向量化应该如何执行。例如,如果用户使用额外维度填充输入,例如(3,2,m,n)而不是(m,n),则向量化代码应该等价于在额外维度上循环。定义了一个约定np.vectorize指定向量化正确方法的函数。假设-gufuncs策略可以生成具有与广播兼容的额外维度的输入,这在测试向量化是否已正确完成时非常有用。假设-gufuncs允许用户用以下代码测试广播约定:
提供max_dims_extra=3在每个参数上最多提供三个广播兼容维度。
在发布的代码中查找错误
通过使用这些策略测试我们自己的例程,我们独立地重新发现了NumPy本身的开放bug。例如,像NumPy问题这样的极端情况# 9884报告了该案件存在的问题:np。unravel_index (0, ()).我们还发现NumPy本身的广播问题# 7014在类似的案例中显示了不一致的广播np。np.inf isclose (0)不返回标量。
火炬的支持
Torch是一个越来越受欢迎的开源机器学习库,已经成为Uber AI单元测试栈的重要组成部分。为了支持我们代码库中的这个元素,我们为假说GU Func添加了Torch功能。
用户可以用以下代码生成Torch变量进行测试:
开始
要使用假设GU Func,请查看我们的文档用这个PIP命令简单地安装扩展:
pip安装hypothesis-gufunc
在Uber AI,研究人员使用Hypothesis GU Func更快速有效地对边缘雷竞技是骗人的用例进行单元测试,从而实现更快的ML洞察和更好的模型。
我们正在寻找贡献者,并希望用户拿出这个包进行测试驱动。





