为什么选择 Mojo

当我们开始 Modular 时,我们没有打算构建一种新的编程语言。但是,当我们构建平台以统一全球的机器学习/人工智能基础设施时,我们发现在整个堆栈上进行编程太复杂了。此外,我们手动编写了很多 MLIR,并且感到不太方便。

我们想要一种创新且可扩展的编程模型,可以针对加速器和其他在人工智能领域中普遍存在的异构系统。这意味着一种具有强大的编译时元编程、自适应编译技术集成、在整个编译流程中的缓存以及其他现有语言不支持的功能的编程语言。

虽然加速器很重要,但其中一种最普遍且有时被忽视的“加速器”是宿主 CPU。现在,CPU 有许多类似于张量核心的加速器块和其他 AI 加速单元,但它们也充当专门加速器无法处理的操作的“后备”,例如数据加载、预处理和后处理以及与外部系统的集成。因此很明显,仅仅使用一个与特定处理器一起工作的“加速器语言”是无法实现 AI 的。

应用人工智能系统需要解决所有这些问题,我们认为没有理由不能只用一种语言来实现这一点。因此,Mojo 诞生了。

一种用于下一代编译器技术的语言。

当我们意识到现有的语言无法解决 AI 计算中的挑战时,我们开始了对如何设计和实现编程语言进行一次原则性的重新思考,以解决我们面临的问题。由于我们需要为各种加速器提供高性能支持,传统的编译器技术如 LLVM 和 GCC 并不适合(基于它们的任何语言和工具都不足以满足需求)。虽然它们支持广泛的 CPU 和一些常用的 GPU,但这些编译器技术是在几十年前设计的,无法完全支持现代芯片架构。现在,专门用于机器学习加速器的标准技术是 MLIR。

MLIR 是一种相对较新的开源编译器基础设施,由谷歌启动(其领导者已转移到 Modular),并在机器学习加速器社区得到广泛采用。MLIR 的优势在于其构建特定领域编译器的能力,特别是针对非传统 CPU 和 GPU 的奇怪领域,例如 AI ASICs、量子计算系统、FPGAs 和自定义硅片。

鉴于我们在 Modular 的目标是构建下一代人工智能平台,我们已经在使用 MLIR 的一些基础设施,但我们没有一个能够充分发挥 MLIR 潜力的编程语言来覆盖我们的整个堆栈。虽然现在许多其他项目也在使用 MLIR,但 Mojo 是第一个专门为 MLIR 设计的主要语言,这使得 Mojo 在为 AI 工作负载编写系统级代码时具有独特的强大优势。

Python 家族的一员。

Mojo 语言的目标包括编译器内部创新和支持当前和新兴加速器。但是,我们认为没有必要在语言语法或社区方面进行创新。因此,我们选择拥抱 Python 生态系统,因为它被广泛使用,受到 AI 生态系统的喜爱,而且因为我们相信它是一种非常好的语言。

Mojo 语言有着崇高的目标:我们希望与 Python 生态系统完全兼容,希望具有可预测的低级性能和低级控制能力,还需要能够将代码子集部署到加速器上。此外,我们不希望创建碎片化的软件生态系统——我们不希望采用 Mojo 的 Python 用户将其与从 Python 2 到 3 的痛苦迁移进行比较。这些都是不小的目标!

幸运的是,尽管 Mojo 是一个全新的代码库,但我们在概念上并不是从零开始。广泛拥抱 Python 简化了我们的设计工作,因为大部分语法已经指定了。我们可以专注于构建 Mojo 的编译模型和系统编程功能。我们还受益于其他语言(如 Rust、Swift、Julia、Zig、Nim 等)以及我们之前的经验,从迁移开发人员到新的编译器和语言中受益,并利用现有的 MLIR 编译器生态系统。

此外,我们决定 Mojo 的长期正确目标是提供 Python 的超集(即使 Mojo 与现有的 Python 程序兼容),并接受 CPython 实现以获得长期支持的生态系统。如果您是一名 Python 程序员,我们希望 Mojo 立即熟悉起来,同时提供新工具来开发安全且高性能的系统级代码,否则需要使用低于 Python 的 C 和 C++。

我们不是试图说服世界“静态最好”或“动态最好”。相反,我们认为当用于正确的应用程序时两者都很好,因此我们设计了 Mojo,以便让您作为程序员来决定何时使用静态或动态。

为什么选择 Python

Python 在机器学习和其他领域占据主导地位。它易于学习,被重要的程序员群体所熟知,拥有令人惊叹的社区,拥有大量的有价值的软件包,并且具有广泛的优秀工具。通过其动态编程功能,Python 支持开发美丽而富有表现力的 API,这使得像 TensorFlow 和 PyTorch 这样的机器学习框架将 Python 作为其用 C++ 实现的高性能运行时的前端。

对于今天的 Modular,Python 是我们 API 表面堆栈中不可协商的部分——这是由我们的客户决定的。鉴于我们堆栈中的其他一切都可以协商,因此我们应该从“以 Python 为先”的方法开始。

更主观地说,我们认为 Python 是一种美丽的语言。它设计有简单可组合的抽象,避免了在实践中与缩进冗余的不必要的标点符号,并具有强大的(动态)元编程功能。所有这些都为我们提供了扩展语言以满足 Modular 需求的途径。我们希望 Python 生态系统中的人们看到我们对 Mojo 的方向是将 Python 推向下一个级别——完成它——而不是与之竞争。

Python 兼容性

我们计划与 Python 生态系统完全兼容,但实际上有两种类型的兼容性,因此我们现在在这两个方面的立场如下:

在您能够导入现有 Python 模块并在 Mojo 程序中使用它们的能力方面,Mojo 是完全兼容的,因为我们使用 CPython 进行互操作。

在您能够将任何 Python 代码迁移到 Mojo 的能力方面,目前还不完全兼容。Mojo 已经支持了许多来自 Python 的核心功能,包括异步/等待、错误处理、可变参数等。然而,Mojo 仍然很年轻,缺少许多其他来自 Python 的功能。Mojo 甚至还没有支持类!

还有很多工作要做,但我们有信心我们会达到那里,我们的团队有经验构建其他主要技术,它们有自己的兼容性之旅:

到达 Clang 编译器的旅程(一种为 C、C++、Objective-C、CUDA、OpenCL 等编写的编译器),它是 GCC、MSVC 和其他现有编译器的“兼容替代”。很难直接进行比较,但 Clang 问题的复杂性似乎比实现 Python 的兼容替代要大一个数量级。

到达 Swift 编程语言的旅程,它拥抱了 Objective-C 运行时和语言生态系统,并逐步迁移了数百万程序员(和大量的代码)。通过 Swift,我们学到了如何与遗留运行时合作并获得“运行时兼容性”的经验教训。

在您希望混合 Python 和 Mojo 代码的情况下,我们期望 Mojo 直接与 CPython 运行时合作,并具有类似集成 CPython 类和对象的支持,而无需编译代码本身。这为现有代码的庞大生态系统提供了插件兼容性,并实现了增量迁移方法,即向 Mojo 的增量迁移会产生增量效益。

总体而言,我们相信通过专注于语言设计和逐步朝着与 Python 完全兼容的方向取得进展,我们将及时达到我们需要的目标。

然而,重要的是要理解,当您编写纯粹的 Mojo 代码时,实现、编译或运行时没有任何使用任何现有 Python 技术的内容。它本身就是一种全新的语言,具有全新的编译和运行时系统。