OR stack exchange 高分问题
和许多浏览这个网站的人一样,我也在运筹学(OR)和统计学/机器学习(ML)的项目中工作。这些领域中开源软件的不同状态常常令作为一个运筹学专业人士的我感到沮丧。
在统计学中,它们的社区文化鼓励研究人员将他们的贡献实现于领域特定语言R中,以便从业者可以和白皮书一起使用工作软件。
在机器学习领域,像谷歌和Facebook这样的公司投入巨额资金开发诸如TensorFlow和PyTorch这样的开源工具,这些工具为大众提供了最先进的机器学习环境。
统计学和机器学习中的开源软件状态允许个别研究人员的增量贡献能够被其研究社区快速地吸收和利用。
但在运筹学(特别是整数规划和组合优化)中,Gurobi Optimizer和CPLEX对最先进技术形成了垄断。使用开源求解器意味着你放弃了性能上的提升。结果是,这些领域的学术研究影响力较小,因为任何想要使用这些研究成果的人都必须支付昂贵的许可费用。这很令人沮丧,我相信这也是相较于运筹学,机器学习和统计学越来越受欢迎(并且被视为越来越有价值的技能集)的原因之一。
是什么解释了这些领域之间开源软件社区文化的差异?我们可以做些什么来改善这种情况,以便让更多的人可以使用我们的工作?
如另一个答案中提到的,线性规划/混合整数规划求解器已经存在了30多年(有趣的事实:从技术上讲,解决线性规划和混合整数规划的问题比软件本身还要早)。这意味着在几十年的时间里持续开发,每年都有增量改进,累积起来就是理查德所说的“残酷的性能”。在我看来,开源工具和商业工具之间的主要区别就在这里:后者受益于多年的持续支持和改进,而前者通常在其主要开发者退休或转行时就会停滞不前。
不过,并非一切都是黯淡的。SCIP(尽管从技术上讲不是开源的)得到了Zib和几个工业伙伴的机构支持。Google的OR-Tools是开源的。最近,HiGHS团队已经设法找到一些工业伙伴来资助(部分?)开发。
这引出了以下问题:为什么开源的机器学习/统计工具比运筹学工具得到更多的公司支持?为什么谷歌在TensorFlow上投入了这么多钱却不卖许可证?为什么在运筹学中没有类似的情况?
答案1:文化。TensorFlow的前身是Theano(现已停止使用),其学术开发者希望它是开源的。所以当TensorFlow(后来是Pytorch)出现时,人们已经有了强大的开源替代品,因此,将其保持为闭源的价值就不大了。机器学习社区现在确实非常支持开源。
答案2:内在价值。在机器学习领域,核心价值不在于机器学习算法本身,而在于你输入的数据和拥有的计算能力。谷歌开源了TF,但你没有看到谷歌(或任何其他大公司)开源他们的数据。相比之下,在运筹学中,能够首先解决问题本身就具有很大的价值。数据仍然扮演着重要角色,但算法的相对重要性比机器学习中要大。
我相信这种趋势有几个原因:
首先,这些行业是在不同的时期“诞生”的。Bob Bixby在1988年左右(或大约那时)创立了CPLEX,而PyTorch是在2016年首次发布的。
这也意味着这两个行业处于不同的生命周期。在过去的20-30年里,运筹学行业(特别是在LP/MIP方面)已经非常巩固,导致了我们今天看到的情况:只有少数商业求解器提供了远超最佳性能。
情况并非总是如此:例如,在00年代中期,bonmin包发布时,它在许多情况下比当时最先进的CPLEX还要好。另一方面,机器学习软件仍在不断发展,每次会议都会涌现出新的方法和范式(至少看起来是这样)。再过10-20年,当许多尘埃落定时,这个行业将发展到什么程度,这将是非常有趣的。
最后,与生命周期相关的还有一个关于性能的问题:商业求解器的代码性能极其强大。为了达到这个水平,你不能让太多的“厨师”在厨房里。TensorFlow或PyTorch将如何达到这种性能,机器学习世界中甚至存在这样的竞争性能基准(相同的训练集,相同的算法类型等)吗?
同时,即使在运筹学领域,也有大量的开源活动,特别是在非线性优化方面。由于学者们可以免费获得Gurobi等软件,他们中的许多人将其作为他们的LP/MIP求解器,然后解决非常复杂的非线性或随机规划模型。例如,看看帝国理工学院Ruth Misener小组的GitHub仓库。这些工作非常棒,都是开源的,而且在许多情况下确实是尖端的。
我们的日常工作围绕着一遍又一遍地精心运行问题,分析到底发生了什么,并思考我们如何改进:
我们不断地发现并消除代码级别的瓶颈。
我们思考如何跳过不必要的计算。这通常是特定于数学的,即如果我的问题具有某种特定结构,我真的需要执行这段代码吗?
当我们用尽代码级别的改进后,我们会回到数学上,尝试识别并利用特殊结构。阐明特殊结构通常需要花费大量时间来将新特性编码到求解器中。
有时我们发现我们的求解器架构限制了我们的发展,即实际上由于代码中的某些设计选择,我们无法以高性能编写我们想要的东西。如果我们足够多次发现这一点,我们会花时间(可能需要几个月)来重新架构整个代码库。
我们会精心运行成千上万的问题的基准测试,调整容差、参数、工作限制以及各种小事情,以在不影响剩余10,000个问题的性能的情况下,为少数问题提高性能。经过多年的积累,性能提高了许多倍。
当其他方法都不起作用时,我们会花时间研究新算法,通常只是为了解决少数问题。
当我们打破某些性能里程碑时,例如,当我们的求解器现在比两年前快了100倍时,我们会回过头来重新审视新的性能是否为几年前不可能的算法选项打开了大门。在这一点上,我们会重复整个过程。
这就是让求解器变得高效所需的过程。耐心、知识和长期往往没有回报的细致工作,直到我们让它发挥作用。
在这里,我们需要做的事情与机器学习开发者需要做的事情有着鲜明的对比。在机器学习代码中,更多关注的是提供一个整体架构,该架构提供高吞吐量,以及提供用户表达自由以创建他们算法的好API。这与手动运行事物并将性能与特定用户输入相关联的做法要少得多。这就是为什么新的机器学习框架不断出现:一旦机器学习框架被设计出来,真正改进它的唯一方式就是设计一个新的框架。在其核心,这是一种文化差异。机器学习用户通常习惯于调整/设计自己的算法,而求解器用户希望它能开箱即用。
鉴于以上情况,您可能会看到这一过程在开源环境中发生是多么困难。提高性能通常不是关于做一些新的令人兴奋的事情。它是关于花费很长时间一遍又一遍地运行相同的事情,直到我们找出那些可以让一个问题快100倍的小调整,而不在任何其他地方退步。尽管我个人觉得这非常令人满意,但大多数人会觉得这很无聊,因为他们没有做“新”的事情。更重要的是,在学术环境中,这项工作的绝大部分真的不值得发表——人们不能真的写一篇关于他们花了100个小时来找出将内部容差从1.e-5改为3.45e-5从而使测试集中的问题数量增加5个的论文。如果您想知道为什么会这样,不幸的是,这些小事情几乎总是特定于实现的,即它们在我们的求解器中有效是因为不同的系统以混沌的方式相互交互,但它们不能转移到任何其他求解器。
有趣的事实:就在上周,我找到了如何解决我过去两年一直在尝试解决的问题。在那段时间里,我几乎每天都在花几分钟时间处理那个问题,偶尔做出小小的改进。这些改进累积起来,到最后一次改进将解决时间从大约100小时减少到700秒(8个核)。尽管我承认之后我跳了一段小小的舞蹈,但我无法告诉你我们为什么现在能解决这个问题,因为这是两年的数百个小事情,更不用说写一篇论文了。这与机器学习社区非常不同——如果有人解决了一个未解决的机器学习问题,第二天就会成为新闻,因为它具有更广泛的应用性。我不认为这是坏事,但您可能会看到,由于时间和回报的比例本质上是更好的,机器学习会吸引更多有才华的人。这种在问题上工作的有才华人数量的差异,最终是我们观察到的差异的主要原因之一。
既然你更新了你的问题,我也来插一句,因为我经常在代码级别与COIN-OR软件打交道。根据我的经验,许多开源优化代码库(例如CBC)在成为出色的求解器方面取得了成功,但在成为伟大的开源项目方面失败了。任何成功开源项目(这里“成功”指的是许多人决定贡献的项目)的核心是其代码库的可读性和设计,而不是软件本身的性能。这是因为可读性和良好的设计使贡献者相信,如果他们尝试得足够久,他们可以大幅改善事物。你希望在一个开源项目中看到的是人们可以立即参与并开始做小事的设计。如果他们需要花费数月/数年时间才能理解发生了什么,然后才能开始动手,他们就会选择放弃。
从求解器开发者的角度来看,最主要的原因是许多这些项目使用autotools而不是CMake作为构建系统。尽管这可能看起来不是什么大问题,但不幸的是,这是一个交易破坏者。原因很简单。如果我们以CBC为例,它基本上是一个包含大量依赖关系的巨大代码文件。这非常难以阅读,更不用说改进了,即使对于像我这样以此为生的人来说也是如此(hhh)。如果项目是用CMake构建的,我可以做的事情是慢慢重构代码,将其拆分为许多文件和类,并改进封装,这样它就会变得更容易阅读、理解、维护和随着时间的推移改进,不仅对我自己,也对其他人来说是这样。当然,有人可能会争辩说,我也可以用autotools做同样的事情,但简单的事实是,人们不再使用autotools了。我需要花费数月全职来做这件事,而我根本没有这个时间。然而,如果项目能够用CMake构建,随着时间的推移,我就可以轻易地做出小小的改变。
因此,我的建议是:将项目迁移到CMake,这样更多的开发者能够为开源代码库做出贡献。这不仅仅是纯粹的猜测。尽管CBC/CLP已经存在了20年,但HIGHS已经有了更多的贡献者,尽管它更年轻。从开发者的角度来看,这是有道理的。代码的可读性更强,而且项目是用CMake构建的。这造成了巨大的差异。另一个有趣的事实是,当年将CLP/CBC链接到我们的求解器花了几个星期的时间,尤其是我们还需要为Windows做同样的事情。而为HIGHS做同样的事情只花了2天时间 - 1天链接和构建,1天测试。
点一点「在看」支持我们~