自从5月2日首次亮相以来,Modular公司的Mojo编程语言一直备受开发人员关注。已有超过12万名开发人员注册使用Mojo Playground,还有19万名开发者积极参与Discord和GitHub的讨论。Fast.ai联合创始人、数据科学家Jeremy Howard甚至表示:“Mojo可能是近几十年来最大的编程语言进步。”
2023年9月7日,Modular公司正式宣布Mojo的发布,Mojo现在可以在本地下载了,初步支持Linux系统,并将很快提供Mac和Windows版本。
Modular公司由LLVM和Swift编程语言的联合创始人Chris Lattner创办,该公司最近刚刚获得了1亿美元(约7亿人民币)的融资。Chris Lattner表示,这一轮融资总额达到了1.3亿美元,这笔资金将用于产品扩展、硬件支持以及推动自研AI编程语言Mojo的进一步发展。
Mojo Playground提供的仅仅是一套简单的语言展示,而本地Mojo工具链将帮助开发人员完成更多工作。本地开发者工具将开放全部Mojo功能,包括一套完整的编译器功能和IDE工具,使开发人员能够轻松构建和迭代Mojo应用程序。
Mojo是一种面向AI开发者的新型编程语言。随着时间的推移,它将逐步发展成为Python的超集。Mojo已经支持与任何Python代码的无缝集成,并提供可扩展的编程模型以支持各种关键性能系统,包括在AI场景中普遍存在的加速器(例如GPU)。
Mojo能够满足开发者的需求,引导他们逐步采用新功能,从而在需要时获得高性能的体验。具体来说,Mojo可以为开发者带来以下主要收益:
一种语言编写所有内容:Mojo可以随时为AI开发者提供服务,将Python的易用性与以往强制开发者使用C、C++或CUDA的系统编程功能结合起来。开发者可以在公共代码库上工作,从而简化从研究到生产的整个工作流程。
突破Python性能极限:Python目前已经广泛应用,但对于需要更高性能或特殊硬件的任务,Python的性能往往不尽人意。Mojo能够充分发挥CPU的性能潜力,并且很好地支持GPU和ASIC等外部加速器,提供与C++和CUDA相媲美的卓越性能。
与完整的Python生态系统对接:Mojo提供与Python生态系统全面互操作的能力,使其能够无缝利用Python库资源,同时发挥Mojo自身的功能和性能优势。例如,开发者可以轻松将NumPy和Matplotlib与自己的Mojo代码混合使用。
升级AI工作负载:Mojo紧密集成了模块化AI引擎,允许开发者通过自定义操作轻松扩展其AI工作负载,包括预处理、后处理操作和高性能数学算法。开发者还可以引入内核融合、图重写、sharp函数等。
通过对现有Python代码进行简单修改,开发者可以使用Mojo显著加速高计算强度的工作负载(最高可提速6.8万倍)。
为什么能比Python快68000倍?
Mojo是Python家族的一员,但它有着远大的目标,即与Python生态系统完全兼容,以便开发人员可以继续使用他们熟悉的工具。Mojo旨在通过保留Python的动态特性,同时为系统编程添加新的原语,逐渐演变成为Python的超集。Modular公司的CEO Chris Lattner表示:“我们的目标不是使动态Python神奇地变快。虽然我们在动态代码方面要快得多(因为我们有编译器而不是解释器),但这并不是通过‘足够聪明’的编译器来消除动态性。”
最初,Mojo的目标是比Python快35000倍,但最近,Mojo团队表示,Mojo将动态和静态语言的优点结合起来,将性能提高了Python的68000倍。Mojo团队在一系列博文中介绍了如何将Mojo的性能提高到比Python快68000倍:在第一篇博文中,团队尝试将代码移植为Mojo,获得了约90倍的性能提升;在第二篇博文中,团队对代码进行了矢量化和并行化,进一步提高了性能,达到了2.6万倍;在第三篇博文中,团队展示了如何通过新的性能技术将程序加速目标全面超越3.5万倍。
具体来说,Mojo团队首先通过简单的端口将Python程序加速了89倍,然后通过针对性的优化和充分利用现代CPU的算力潜力,将速度提高了2.6万倍。Mojo团队提出的并行策略是,每个CPU核心都应负责处理同等数量的代码行。然而,只有在跨行工作负载相同时,对负载进行拆分以确保各个线程worker获取其中一组代码行才具有可行性。但曼德勃罗集并不是这样。以这种方式进行拆分会引发负载不均衡问题,这是因为曼德勃罗集中的一个像素可能在单次迭代后完成,而另一个像素可能经历多次迭代。也就是说,各个行的迭代次数并不相等,会导致某些线程率先完成计算的线程处于闲置状态,不利于充分发挥性能潜力。
各个行所执行的迭代总数(以对数坐标系显示)并非均匀分布。某些行(例如图像中央部分的行)可能需要80多万次迭代,而两端的行则只需要800次左右迭代。如果硬性为各个线程分配一定数量的连续行,就会导致全体线程都在等待,直至中间某组代码行(被分配给某个核心)完成运行。解决这个问题的方法有很多,但最简单的当然是过度拆分。也就是说,各个线程所获得的不是一组平均分配的行,而是建立起一个工作负载池,再为每个行创建相应的工作项。各线程则以循环方式不断从线程池中拾取这些工作项。
好消息是,Mojo拥有一个性能出色的并发运行时,所以我们用不着自行创建线程池或者设计循环拾取/执行。Mojo的运行时提供了不少高级功能,可以充分利用这样的多核心系统。到这里,Mojo团队获得了2.3倍于并行版本的加速效果,甚至达到了矢量化实现版本的78倍。那么,在每个行中进一步划分会不会让性能更上一层楼?如果单行很大,那也许可以。但Mojo团队这个示例中的最大单行长度也不过4096。另外,同一行内的各像素间往往更具相关性。这时候更适合采用单指令流多数据流(SIMD),避免工作被白白浪费在矢量通道中。
回顾整个旅程,Mojo团队首先对Python代码实现了2.6万倍的性能提升,然后使用超额订阅达成了提速68847倍的最终成绩,并最终实现了6.8万倍的Python提速效果。在应用超额订阅之后,性能在之前并行版本的基础上又提高了1倍。
如何使用Mojo?
目前,开发者可以将Mojo下载到自己的本地计算机上。Modular公司表示,Mojo不仅仅是一个编译器,它提供了丰富的工具选项,包括:
Mojo驱动程序:提供用于read-eval-print-loop(REPL)的shell,允许开发者构建并运行Mojo程序、打包Mojo模块、生成文档和格式化代码。
面向Visual Studio Code(VS Code)的扩展:支持各种生产力功能,例如语法高亮显示、代码补全等。
Jupyter内核:支持构建和运行Mojo notebook,包括使用Python代码。
调试支持(即将推出):进入并检查正在运行的Mojo程序,甚至可以将C++与Mojo堆栈帧混合在一起。最初版本的SDK支持x86/Linux系统,后续更新将进一步扩展到其他操作系统、硬件和工具功能。
Mojo驱动程序允许开发者像运行Python命令一样在REPL中进行编程。此外,Mojo还允许开发者构建静态编译的可执行文件,无需任何依赖项即可部署。这个静态编译的22KB二进制文件非常强大,得益于Mojo紧凑的依赖项管理机制。
对于全球最流行的IDE之一,Visual Studio Code(VS Code),Mojo已经发布了官方扩展,提供语法高亮显示、诊断和修复、定义和引用、悬停帮助、格式化、代码补全等支持。Jupyter内核允许开发者在其中使用Jupyter notebook,提供强大的交互式开发环境。此外,Mojo的调试支持即将推出,将在VS Code中提供交互式调试体验,并能够混合操作Mojo/C/C++代码,进一步增强开发者处理高度专业化代码的能力。