为什么我不再推荐你用Julia?

从诞生之日起,Julia 已经走过了十多个年头。

作为一个面向科学计算的高性能动态高级程序设计谈话,Julia 在许多情况下拥有能与编译型谈话相媲美的性能,且足够灵活。

曾有开发者盛言赞美 Julia,从速度、通用性、多重派发等多个维度出发,认为 Julia 甚至比 Python 更胜一筹。

当然,也有人创造了 Julia 尚存留一些不足之处,开发者 Yuri Vishnevsky 就写了一篇博客控诉 Julia,并表示自己在利用多年后,已经正式停用了 Julia。

以下是博客内容:

多年来,我一直利用 Julia 谈话来转换、清理、分析和可视化数据、进行统计和执行模拟。

我还发布了一些开源包,例如最近邻搜索等。但不久前我停止利用 Julia 了,我也不再推荐利用它,现在我来阐述一下原因。

根据我的经验,在我利用过的所有编程系统中,Julia 及其包的毛病率最高,我来举例说明一下:

对概率密度进行采样会出现毛病;

对数组进行采样会产生有偏差的结果;

乘积函数可能对 8 位、16 位和 32 位整数产生不精确的结果;

将直方图拟合到 Float64 数组会出现毛病;

基本函数 sum!、prod!、any! 和 all!可能会前往不精确的结果。

还有一些开发者也提出了类似的成绩:

OrderedDict 可能会损坏密钥; 

dayofquarter () 函数在闰年的情况下会出现毛病;

利用带有 error bar 的数字类型时,模拟结果不精确;

stdout=IOStream 的 pipeline 乱序写入; 

由于某些 copyto! 方法不检查别名而产生毛病的结果;

if-else 控制流程存留 bug。

我经常会遇到这样严重的毛病,足以让我质疑 Julia 中复杂计算的精确性,在测验考试新的包或者函数的组合时尤其如此。

例如,我创造 Distance 包中的 Euclidean distance 不适用于 Unitful vector;还有人创造 Julia 运行外部命令的函数不适用于 substring,Julia 对缺失值的支持在某些情况下会破坏矩阵乘法,标准库的 @distributed 宏不适用于 OffsetArrays……

尤其是 OffsetArrays 被证明是 correctness bug 的重要来源。这个包提供了一种数组类型,它利用 Julia 灵活的自定义索引功能来创建数组,而不必从 0 或 1 开始。

这可能会招致内存走访越界,如果你很幸运,将招致 segfault;如果不幸运,则会招致毛病的结果。我曾经在 Julia 核心代码中创造一个 bug—— 即利用户和库作者都编辑了精确的代码,它也可能招致内存走访越界。

我向 JuliaStats 组织提交了一些与索引相关的成绩,该组织负责管理诸如 Distributions 之类的统计数据包和 StatsBase。我列出的成绩包括:

存留 offset axes 的情况下,大多数采样方法都是不安全且不精确的;

拟合 DiscreteUniform 分布会前往不精确的答案;

counteq、countne、sql2dist、L2dist、L1dist、L1infdist、gkldiv、meanad、maxad、msd、rmsd 和 psnr 可能会前往带有 offset 索引的毛病结果;

@inbounds 的不精确利用会招致统计数据计算毛病;

Colwise 和 pairwise 会前往不精确的 distance;

offset 数组的权重向量走访内存越界。

这些成绩背后的根本原因不单单是索引,还有当与 Julia 中的 @inbounds 一起利用时,就允许 Julia 从数组走访中删除边界检查。

上面的代码让 i 从 1 迭代到数组的长度。如果将一个具有异常索引范围的数组传给它,就会招致内存走访越界,并且毛病地利用 @inbounds 招致程序中删除了边界检查。

然而,这段代码正是多年来如何利用 @inbounds 的官方示例。

为什么我不再推荐你用Julia?

该成绩现已修复,但令人担忧的是,@inbounds 很容易被滥用,招致数据损坏和不精确的数学结果。根据我的经验,这些成绩包括但不限于 Julia 生态系统中的数学部分。

我在测验考试完成 JSON 编码 、发出 HTTP 请求、将 Arrow 文件与 DataFrames 一起利用,以及利用 Pluto 编辑 Julia 代码等日常任务时,创造一些库中也存留 bug。

当我开始好奇我的经历是否具有代表性时,一些 Julia 用户私下分享了类似的故事。

例如,Patrick Kidger 描述了他利用 Julia 进行机器学习研究的测验考试:

在 Julia Discourse 上看到帖子说「XYZ 库不 work」是很常见的,随后其中一位库维护者的回复说「这是 XYZ 依赖的 ABC 库的新版本 a.b.c 中的上游毛病。我们会尽快修复。」

Patrick 还谈到:

我记得我的一个 Julia 模型训练失败的时候,我非常不开心。我断断续续地花了几个月的时间试图让它 work,测验考试了能想到的每一个 trick。

最终我创造了毛病:Julia/Flux/Zygote 前往了不精确的梯度。在花了这么多精力之后,我放弃了。经过两个小时的开发工作,我成功地在 PyTorch 中训练了模型。

在讨论中,其他人表示也有类似的经历:

@Samuel_Ainsworth:像 @patrick-kidger 一样,我被 Zygote/ReverseDiff.jl 中的梯度毛病 bug 所困扰。我花费了数周的时间,彻底动摇了我对整个 Julia AD 领域的信心。在利用 PyTorch/TF/JAX 的时候,我从未遇到过这样的梯度 bug。

@JordiBolibar:从我开始利用 Julia 进行研究以来,我在 Zygote 中遇到了两个 bug,这使我的工作减慢了几个月。积极的一面是,这迫使我深入研究代码,并了解到很多关于我正在利用的库的信息。但是我创造自己需要花费大量时间调试代码,而不是进行本职研究。

可见,Julia 的成绩是如此普遍。Julia 没有正式的接口概念,泛型函数倾向于在边缘情况下不指定其语义,并且许多常见隐式接口的性质尚未明确(例如,Julia 社区对数字是什么没有达成一致意见) 。

Julia 社区有非常多有能力、有才华的人,他们用自己的时间、工作和专业知识为 Julia 的改进做出了贡献。但一些系统性成绩很少能自下而上解决,我的感觉是开发团队 leader 不承认存留严重的精确性成绩。他们接受个别孤立成绩的存留,但不接受这些成绩背后的根本模式存留毛病。

例如,在 Julia 机器学习生态系统还不够成熟的时候,该谈话的一位联合创始人就兴奋地谈到在自动驾驶汽车生产中利用 Julia:

为什么我不再推荐你用Julia?

另一位联合创始人曾表示 Julia 有一个很大的优势是利于代码复用:

我认为最重要的不是 Julia 是一门多棒的谈话,而是它的设计让实现代码复用的能力提升了一大截。在 Julia 中,利用者可以有效地联合利用由一个人编辑的通用算法和由其他人编辑的自定义类型。谈话设计者不应该仿照 Julia 的所有功能,但他们至少应该理解为什么它会如此有效,并且能够在未来的设计中实现类似级别的代码复用。

从社区的角度看,每当出现一篇批评 Julia 的帖子时,社区内都会有开发者为其辩驳

例如:

2016 年时存留这个成绩,但现在已经得到了很好的解决。 

在 Julia 中,没有对一致性的强制执行,但泛型函数是很有效的。 

Julia 当然有 bug,但没有一个是严重的。

这些说法在小范围内似乎是合理的,但如果一直如此会造成利用者的合法体验被削弱或淡化,更深层次的根本成绩没有得到承认和解决。

凭借过去十年在编程谈话和开源社区方面的经验,我认为至少在基本精确性方面,Julia 目前并不可靠,也许正在变可靠的路上。Julia 及其开发者必须重新审视和修改它的可靠性。

参考链接:

https://yuri.is/not-julia/

https://news.ycombinator.com/item?id=31396861

给TA打赏
共{{data.count}}人
人已打赏
AI

AI翻新标杆指南:呆板之心Pro·AI 趋势前锋 Insight 榜单发布

2022-5-14 16:53:00

AI

大神Goodfellow去向定了:回归google,在DeepMind继续近程办公

2022-5-18 14:57:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
搜索