c编程器
说起 Chris Lattner,大家一定不陌生。这位编译器大神,曾经领导了众多大型技术项目。他不仅是 LLVM 项目的主要发起人,还是 Clang 编译器的创作者。同时,他是苹果公司编译器开发团队的首席架构师和苹果新编程语言 Swift 创造者。此外,Chris Lattner 还为 Google Brain 和 TensorFlow 建立和管理了一系列与 AI 相关的编译器、运行时和编程语言团队。
2022 年 1 月,Chris Lattner 和 AI 领域专家 Tim Davis 共同建立了 Modular AI,旨在重建全球 ML 基础设施。
而在近日,编译器的大神 Chris Lattner 在社交平台上官宣了一种全新的编程语言:Mojo!
(n h) s d', h=self.nheads)"],[20,"\\n","24:\\"NmMJ\\"|36:177|direction:\\"ltr\\""],[20," q,k,v = torch.chunk(x, 3, dim=-1)"],[20,"\\n","24:\\"8xN8\\"|36:177|direction:\\"ltr\\""],[20," s = (q@k.transpose(1,2))/self.scale"],[20,"\\n","24:\\"uUzu\\"|36:177|direction:\\"ltr\\""],[20," x = s.softmax(dim=-1)@v"],[20,"\\n","24:\\"tmUp\\"|36:177|direction:\\"ltr\\""],[20," x = rearrange(x, '(n h) s d -> n s (h d)', h=self.nheads)"],[20,"\\n","24:\\"MLpH\\"|36:177|direction:\\"ltr\\""],[20," return self.proj(x)"],[20,"\\n","24:\\"dLJW\\"|36:177|direction:\\"ltr\\""],[20,"\\n","24:\\"Ffnr\\"|direction:\\"ltr\\""],[20,"但实际上,这些操作很复杂。例如,在 "],[20,"CUDA C","16:\\"https%3A%2F%2Fgithub.com%2FHazyResearch%2Fflash-attention%2Ftree%2Fmain%2Fcsrc%2Fflash_attn%2Fsrc\\""],[20," 中进行内存优化的“闪存注意”实现。它还掩盖了这些构建模型的通用方法留下了大量的性能的事实。例如,“块稀疏”方法可以显著提高速度和内存使用。研究人员正在对常见架构的每个部分进行调整,并提出新的架构(以及 SGD 优化器,数据增强方法等)——我们甚至还没有一个每个人都会永久使用的整齐包装的系统。"],[20,"\\n","24:\\"2m79\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"DDgE\\"|direction:\\"ltr\\""],[20,"在实践中,许多用于语言模型的最快代码都是用 C 和 C++ 编写的。例如,Fabrice Bellard 的 TextSynth 和 Georgi Gerganov 的 ggml 都使用 C 语言,因此能够充分利用完全编译语言的性能优势。"],[20,"\\n","24:\\"36PE\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"DN1g\\"|32:1|direction:\\"ltr\\""],[20,"“MLIR 的语法糖”:Mojo"],[20,"\\n","24:\\"8fvq\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"qZNr\\"|direction:\\"ltr\\""],[20,"Chris Lattner 开发的 LLVM,从根本上改变了编译器的创建方式,也为世界上许多广泛使用的语言生态系统打下了坚实的基础。"],[20,"\\n","24:\\"2qgn\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Hgan\\"|7:3|direction:\\"ltr\\""],[20,"之后,他推出了一个建立在 LLVM 之上的 C 和 C++ 编译器 Clang,并被广泛使用。LLVM 包括“中间表示”(IR),这是一种为机器读写(而不是人)设计的特殊语言,它使一个庞大的软件社区能够协同合作,为更广泛的硬件提供更好的编程语言功能。"],[20,"\\n","24:\\"D0CZ\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Q2nA\\"|7:3"],[20,"Chris Lattner 认为 C 和 C++ 并没有完全充分利用 LLVM 的威力,因此他在苹果工作时,设计了一种名为“Swift”的新语言,他将其描述为“LLVM 的语法糖”。如今,Swift 已经成为世界上使用最广泛的编程语言之一,特别是它创建了 iPhone、iPad、MacOS 和 Apple TV 创建 iOS 应用程序的主要方式。"],[20,"\\n","24:\\"zbPx\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"3O23\\"|7:3"],[20,"不幸的是,苹果对 Swift 的控制导致它还没有真正在技术领域大放异彩。Chris Lattner 曾在 Google 试图将 Swift 从苹果的舒适区移出来,成为 AI 模型开发中 Python 的替代品。但遗憾的是,它没有得到苹果或 Google 的支持,最终没有成功。"],[20,"\\n","24:\\"nlZ9\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"LYql\\"|7:3|direction:\\"ltr\\""],[20,"话虽如此,在 Google 期间,Chris 开发了另一个非常成功的项目:MLIR。MLIR 是 LLVM IR 的替代品,适用于现代多核计算和 AI 工作负载。这对于充分利用 GPU、TPU 等硬件的强大功能以及越来越多地添加到服务器级 CPU 中的向量单元至关重要。"],[20,"\\n","24:\\"OfP0\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"7f3L\\"|7:3|direction:\\"ltr\\""],[20,"那么,如果 Swift 是“LLVM 的语法糖”,那么“MLIR 的语法糖”是什么?答案是:Mojo!Mojo 是一种全新的语言,旨在充分利用 MLIR。并且,Mojo 也是 Python。"],[20,"\\n","24:\\"TrBA\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"h70y\\"|7:3|direction:\\"ltr\\""],[20,"也许说 Mojo 是 Python++ 更为恰当。它将(完成后)是 Python 语言的严格超集。但它也有附加功能,因此,开发者可以编写利用现代加速器的高性能代码。"],[20,"\\n","24:\\"FLR3\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"L0bn\\"|7:3|direction:\\"ltr\\""],[20,"在 Jeremy Howard 看来,Mojo 似乎比 Swift 更实用。虽然 Swift 是一种包含了基于编程语言设计最新研究的各种炫酷功能的全新语言,但 Mojo 的核心是 Python。因为 Python 已经被数百万程序员广泛使用,并且经过几十年的使用,它的功能和局限性已经得到了充分完善。"],[20,"\\n","24:\\"OiOW\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"ARV7\\"|7:3|direction:\\"ltr\\""],[20,"用最新的编程语言进行研究很酷,但它可能具有潜在危险。就 Jeremy Howard 个人而言,他经常被 Swift 强大但古怪的类型系统搞糊涂,有时甚至成功地被 Swift 编译器混淆并且完全崩溃!"],[20,"\\n","24:\\"OLt6\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"LtSx\\"|7:3|direction:\\"ltr\\""],[20,"Mojo 的一个关键技巧是,作为开发人员,您可以随时选择加入更快的“模式”。通过使用“fn”而不是“def”来创建函数。在这种模式下,您必须准确确定每个变量的类型,Mojo 可以创建优化的机器代码来实现您的函数。此外,如果使用“struct”而不是“class”,您的属性将被打包到内存中,这样它们可以在数据结构中使用,而无需追踪指针。这些特性使得像 C 这样的语言变得很快,而现在 Python 程序员只需学习一点点新语法即可使用。"],[20,"\\n","24:\\"JP1E\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"f8xX\\""],[20,"Mojo 如何做到的?"],[20,"\\n","24:\\"Mmlv\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"WmBa\\"|direction:\\"ltr\\""],[20,"几十年来,为了创建简洁、灵活、快速、实用和易于使用的编程语言,开发者们进行了数百次尝试。但并没有取得太大成效。而 Mojo 似乎做到了。我们可以得出一些假设:"],[20,"\\n","24:\\"qIMh\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"LMX0\\"|7:3"],[20,"1.Mojo 实际上并没有实现这些目标,精彩的演示掩盖了令人失望的现实表现。"],[20,"\\n","24:\\"qalr\\"|7:3|direction:\\"ltr\\""],[20,"2.Modular 是一家拥有数百名开发人员的大型公司,公司为实现未曾实现过的目标付出了多年的努力。"],[20,"\\n","24:\\"OTD4\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Soar\\"|7:3|direction:\\"ltr\\""],[20,"事实上,这两个假设都不成立。我们举两个例子,(matmul 和 mandelbrot)并不是在尝试了数十种方法后才精心选择的唯一有效方法;相反,它们是我们为演示而尝试的一种方法,并且第一次就成功了!虽然在这个早期阶段,还是有很多功能的缺失(除了在线“playground”之外,Mojo 还没有发布给公众),但您在演示中看到的确实是它的工作方式。事实上,您现在可以在 playground 中自己运行它。"],[20,"\\n","24:\\"505e\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"KmFt\\"|7:3|direction:\\"ltr\\""],[20,"Modulal 是一家仅成立一年的小初创公司。一个小团队是如何在短时间内做到这样的呢?"],[20,"\\n","24:\\"ooEj\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"pDdJ\\"|7:3|direction:\\"ltr\\""],[20,"关键一:基础强大","8:1"],[20,"\\n","24:\\"OspC\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"AdWm\\"|7:3|direction:\\"ltr\\""],[20,"关键在于 Mojo 是建立在一些非常强大的基础之上的。Jeremy Howard 表示,很少见到有软件项目愿意花费时间来打好坚实的基础,并且往往会因此积累大量的技术债务。随着时间的推移,添加功能和修复错误变得越来越困难。然而,在 Mojo 这样一个设计良好的系统中,每个功能都比上一个更容易添加,速度也更快,出错率低,每个功能所构建的基础都越来越好。"],[20,"\\n","24:\\"2Ivi\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"aLN2\\"|7:3|direction:\\"ltr\\""],[20,"其核心是最初是由 Chris Lattner 在 Google 开发的并且使用多年的 MLIR。Chris Lattner 已经意识到“AI 时代编程语言”的核心基础将需要什么,并专注于构建它们。MLIR 就是其中的一个关键部分。就像 LLVM 在过去十年中极大地简化了强大的新编程语言的开发一样(如 Rust、Julia 和Swift,它们都基于 LLVM),MLIR 为建立在其上的语言提供了更强大的核心。"],[20,"\\n","24:\\"RTSF\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"8wMK\\"|7:3|direction:\\"ltr\\""],[20,"关键二:使用 Python 作为语法","8:1"],[20,"\\n","24:\\"Gi3v\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"wV0d\\"|7:3|direction:\\"ltr\\""],[20,"Mojo 快速发展的另一个关键因素是决定使用 Python 作为语法。开发和迭代语法是语言开发中最容易出错、最复杂和最有争议的一部分。通过简单地将其外包给现有的语言,整个部分就会消失!因此,需要少量地在 Python 之上添加的新语法部分来自然适应。"],[20,"\\n","24:\\"7YD5\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"0LoR\\"|7:3|direction:\\"ltr\\""],[20,"接下来是创建一个最小的 Pythonic 方法直接调用 MLIR。这并不是一个大项目,但它需要在此基础上创建所有 Mojo 所需的全部内容,并直接在 Mojo 中处理其他所有工作。这意味着 Mojo 开发人员从一开始就能“dog-food” Mojo。当他们在开发 Mojo 时发现某些东西不太好用时,他们可以为 Mojo 本身添加所需的功能,以便更容易开发下一个 Mojo 部分!"],[20,"\\n","24:\\"VPBX\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"xcXW\\"|7:3"],[20,"这一点和 Julia 很像。Julia 是在"],[20,"最小的类LISP内核","16:\\"https%3A%2F%2Fgithub.com%2FJeffBezanson%2Ffemtolisp\\""],[20,"上开发的,该内核提供 Julia 语言元素,然后将其绑定到基本的 LLVM 操作。Julia 中的几乎所有内容都是建立在它之上的。"],[20,"\\n","24:\\"nkPR\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Q7Nr\\"|7:3|direction:\\"ltr\\""],[20,"Modular 团队内部宣布,决定通过一个视频(包括演示)推出 Mojo,并且他们将时间定在了未来几周之内。那时 Mojo 只是最基本的语言,没有可用的笔记本内核,几乎没有实现任何 Python 语法,也没有进行任何优化。"],[20,"\\n","24:\\"vJt8\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"tuVp\\"|7:3|direction:\\"ltr\\""],[20,"起初,Jeremy Howard 并不理解这个行为。但这段时间,Mojo 的表现让他叹为观止。每隔一两天,就有全新的语言功能被实现。一旦有足够的语言功能来尝试运行算法,它们就能够立即达到或接近最先进的性能水平!Jeremy Howard 突然意识到 Mojo 所有的基础都已经建立好了,并且它们被明确设计用于构建现在正在开发的东西。因此,一切都很顺利,而且运作良好也就不足为奇了。"],[20,"\\n","24:\\"dsta\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"wNnB\\"|7:3"],[20,"这是 Jeremy Howard 对 Mojo 未来持乐观态度的理由。虽然这个项目还处于早期阶段,但根据 Jeremy Howard 在过去几周中观察到的情况,他的猜测是它将比大多数人预期的发展得更快、更远……"],[20,"\\n","24:\\"bQvK\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"vaEI\\"|direction:\\"ltr\\""],[20,"Mojo 关键优势:易于部署"],[20,"\\n","24:\\"kS4U\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"LIXL\\"|direction:\\"ltr\\""],[20,"这是很关键的一点。如果你想把你酷炫的 Python 程序给朋友,你需要让他们"],[20,"\\n","24:\\"5wq6\\"|7:3|direction:\\"ltr\\""],[20,"先安装 Python!或者,你可以给他们一个包含 Python 和你使用的所有库的巨大文件。"],[20,"\\n","24:\\"osAj\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Fz2s\\"|7:3|direction:\\"ltr\\""],[20,"由于 Python 是一种解释型语言,所以你的程序的行为将取决于安装的 python 的确切版本、存在的库的版本以及它们的配置方式。为了避免维护问题,Python 社区已经确定了几种选项来安装 Python 应用程序:环境,每个程序都有一个单独的Python 安装;或容器,为每个应用程序设置一整个操作系统。但这两种方法都会在开发和部署Python 应用程序时产生许多混乱和开销。"],[20,"\\n","24:\\"JFrx\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Wkh2\\"|7:3|direction:\\"ltr\\""],[20,"将其与部署静态编译的 C 应用程序进行比较:您只需将编译的程序直接下载即可。它的大小可能只有 100k 左右,可以快速启动和运行。"],[20,"\\n","24:\\"h5K2\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"vM8Z\\"|7:3|direction:\\"ltr\\""],[20,"还有一种 Go 采用的方法,它不能生成像 C 这样的小型应用程序,而是将“运行时”集成到每个打包的应用程序中。这种方法是 Python 和 C 之间的折中,仍需要数十兆字节的二进制文件,但比 Python 更容易部署。"],[20,"\\n","24:\\"pct9\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"vlLo\\"|7:3"],[20,"作为一种编译语言,Mojo 的部署方式与 C 基本相同。例如,一个包含从头开始编写的 matmul 版本的程序大约是 100 k。"],[20,"\\n","24:\\"UeeQ\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"WKFl\\"|7:3"],[20,"这意味着 Mojo 不仅仅是面向 AI/ML 应用程序的语言。它实际上是 Python 一种版本,可以帮助我们编写快速、小巧、易于部署的应用程序,利用所有可用的核心和加速器!"],[20,"\\n","24:\\"U1qT\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"tRxS\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"7k8z\\"|direction:\\"ltr\\""],[20,"Mojo 的替代品"],[20,"\\n","24:\\"Xpfd\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"eXV2\\"|direction:\\"ltr\\""],[20,"Mojo 并不是解决 Python 性能和部署问题的唯一办法。在语言方面,Julia 可能是目前最强的替代品。它具有 Mojo 的许多优点,并且构建出了很多优秀的项目。但在 Jeremy Howard 看来,Julia 也并不完美:"],[20,"\\n","24:\\"HloO\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"HevC\\"|direction:\\"ltr\\""],[20,"Julia 面临的最大挑战源于其大型运行时,决定在该语言中使用垃圾回收。此外,Julia 中使用的多调度方法虽然打开了很多用语言做很酷的事情的大门,但也会让开发人员的工作变得非常复杂。"],[20,"\\n","24:\\"uFW1\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"YVMU\\"|7:3"],[20,"在 Python 中,目前最好的解决方案可能是 "],[20,"Jax","16:\\"https%3A%2F%2Fjax.readthedocs.io%2Fen%2Flatest%2F\\""],[20,",它有效地使用 Python 创建了一个特定领域的语言(DSL)。这种语言的输出是 XLA,它是一个早于MLIR的机器学习编译器(我相信它正在逐渐转移到MLIR上)。Jax 继承了 Python(例如,该语言无法表示结构,或直接分配内存或创建快速循环)和 XLA(主要针对 TPU,很大程度上限制在机器学习特定的概念上)的限制,但具有巨大的优势,即不需要新的语言或新的编译器。"],[20,"\\n","24:\\"mtFh\\"|7:3|direction:\\"ltr\\""],[20," "],[20,"\\n","24:\\"6g0O\\"|7:3|direction:\\"ltr\\""],[20,"如前所述,还有新的 PyTorch 编译器,Tensorflow 也能够生成 XLA 代码。就 Jeremy Howard个人而言,这种方式使用 Python 最终并不令人满意。Jeremy Howard 实际上并没有使用 Python 的所有功能,但必须使用与其所针对的后端兼容的子集。Jeremy Howard 不能轻松地调试和分析编译后的代码,因为很多不确定性,甚至很难知道最终执行的内容。"],[20,"\\n","24:\\"KE2z\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Pote\\"|7:3|direction:\\"ltr\\""],[20,"Jeremy Howard 甚至无法得到一个独立的二进制文件,而必须使用特殊的运行时并处理复杂的 API。"],[20,"\\n","24:\\"AbgL\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Kq5J\\"|7:3|direction:\\"ltr\\""],[20,"Python 的另一个有趣的方向是 "],[20,"Numba","16:\\"https%3A%2F%2Fnumba.pydata.org%2F\\""],[20," 和 "],[20,"Cython","16:\\"https%3A%2F%2Fcython.org%2F\\""],[20,"。Numba 使用一个特殊的装饰器,使 Python 函数被编译成使用LLVM优化的机器代码。Cython 类似,但还提供了一个类似于 Python 的语言,具有 Mojo 的一些特性,并将这个 Python 方言转换成 C,然后进行编译。这些语言都没有解决部署问题,但它们可以帮助解决性能问题。"],[20,"\\n","24:\\"CRzC\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"mMs8\\"|7:3"],[20,"两者都无法针对具有通用跨平台代码的一系列加速器,尽管 Numba 确实提供了一种非常有用的方法来编写 CUDA 代码(因此可以针对 NVIDIA GPU)。Jeremy Howard 对于 Numba 和 Cython 的存在表示感激,并且认为从它们中获得了很多。但它们完全不同于使用完整的语言和编译器生成独立的二进制文件。它们只是Python性能问题的临时解决方案,对于仅需要解决性能问题的情况是可行的"],[20,"\\n","24:\\"bnE2\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"MRYz\\"|7:3"],[20,"但 Jeremy Howard 更喜欢使用一种既像 Python 一样,又像 C 一样快的语言,能够允许其使用一个语言来编写从应用程序服务器到模型架构以及安装程序的所有内容,并且能在编写代码的语言中直接调试和分析其的代码。"],[20,"\\n","24:\\"qqu3\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"BrEH\\"|7:3"],[20,"你喜欢这样的语言吗?欢迎在评论区留言讨论。"],[20,"\\n","24:\\"yzdJ\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"0SAI\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"hxif\\"|direction:\\"ltr\\""],[20,"参考链接:"],[20,"\\n","24:\\"4Ko2\\"|direction:\\"ltr\\""],[20,"https://www.fast.ai/posts/2023-05-03-mojo-launch.html","0:\\"rgb(65%2C%2070%2C%2075)\\"|16:\\"https%3A%2F%2Fwww.fast.ai%2Fposts%2F2023-05-03-mojo-launch.html\\"|1:\\"rgb(255%2C%20255%2C%20255)\\"|27:\\"9\\"|31:2"],[20,"\\n","24:\\"INNX\\"|direction:\\"ltr\\""],[20,"https://www.modular.com/mojo","0:\\"rgb(65%2C%2070%2C%2075)\\"|16:\\"https%3A%2F%2Fwww.modular.com%2Fmojo\\"|1:\\"rgb(255%2C%20255%2C%20255)\\"|27:\\"9\\"|31:2"]]" data-copy-origin="https://shimo.im">Enlitic 创始人 Jeremy Howard 在试用 Mojo 后表示:「Mojo 是几十年来最大的编程进步」。
Jeremy Howard 直言:
回顾我第一次使用 Visual Basic v1.0 的情景。彼时,它还只是一个针对 DOS 的程序。在此之前,编写程序非常复杂。因此,我除了掌握最基本的玩具应用程序之外,其他方面没有取得太大进展。然而,当我在 VB 屏幕上画了一个按钮,输入了一行代码就得到一个完整的可运行应用程序时,我觉得很惊奇。这种感觉令我难以忘怀。我人生中第二次有这种感觉,是用 Modular1 推出的新编程语言 Mojo 编写代码。
比 Python 快 3500 倍的 Mojo 有何神奇之处?
Mojo 将 Python 的易用性与 C 的性能相结合,释放了 AI 硬件强大的可编程性和 AI 模型的可扩 (n h) s d', h=self.nheads)"],[20,"\\n","24:\\"NmMJ\\"|36:177|direction:\\"ltr\\""],[20," q,k,v = torch.chunk(x, 3, dim=-1)"],[20,"\\n","24:\\"8xN8\\"|36:177|direction:\\"ltr\\""],[20," s = (q@k.transpose(1,2))/self.scale"],[20,"\\n","24:\\"uUzu\\"|36:177|direction:\\"ltr\\""],[20," x = s.softmax(dim=-1)@v"],[20,"\\n","24:\\"tmUp\\"|36:177|direction:\\"ltr\\""],[20," x = rearrange(x, '(n h) s d -> n s (h d)', h=self.nheads)"],[20,"\\n","24:\\"MLpH\\"|36:177|direction:\\"ltr\\""],[20," return self.proj(x)"],[20,"\\n","24:\\"dLJW\\"|36:177|direction:\\"ltr\\""],[20,"\\n","24:\\"Ffnr\\"|direction:\\"ltr\\""],[20,"但实际上,这些操作很复杂。例如,在 "],[20,"CUDA C","16:\\"https%3A%2F%2Fgithub.com%2FHazyResearch%2Fflash-attention%2Ftree%2Fmain%2Fcsrc%2Fflash_attn%2Fsrc\\""],[20," 中进行内存优化的“闪存注意”实现。它还掩盖了这些构建模型的通用方法留下了大量的性能的事实。例如,“块稀疏”方法可以显著提高速度和内存使用。研究人员正在对常见架构的每个部分进行调整,并提出新的架构(以及 SGD 优化器,数据增强方法等)——我们甚至还没有一个每个人都会永久使用的整齐包装的系统。"],[20,"\\n","24:\\"2m79\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"DDgE\\"|direction:\\"ltr\\""],[20,"在实践中,许多用于语言模型的最快代码都是用 C 和 C++ 编写的。例如,Fabrice Bellard 的 TextSynth 和 Georgi Gerganov 的 ggml 都使用 C 语言,因此能够充分利用完全编译语言的性能优势。"],[20,"\\n","24:\\"36PE\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"DN1g\\"|32:1|direction:\\"ltr\\""],[20,"“MLIR 的语法糖”:Mojo"],[20,"\\n","24:\\"8fvq\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"qZNr\\"|direction:\\"ltr\\""],[20,"Chris Lattner 开发的 LLVM,从根本上改变了编译器的创建方式,也为世界上许多广泛使用的语言生态系统打下了坚实的基础。"],[20,"\\n","24:\\"2qgn\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Hgan\\"|7:3|direction:\\"ltr\\""],[20,"之后,他推出了一个建立在 LLVM 之上的 C 和 C++ 编译器 Clang,并被广泛使用。LLVM 包括“中间表示”(IR),这是一种为机器读写(而不是人)设计的特殊语言,它使一个庞大的软件社区能够协同合作,为更广泛的硬件提供更好的编程语言功能。"],[20,"\\n","24:\\"D0CZ\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Q2nA\\"|7:3"],[20,"Chris Lattner 认为 C 和 C++ 并没有完全充分利用 LLVM 的威力,因此他在苹果工作时,设计了一种名为“Swift”的新语言,他将其描述为“LLVM 的语法糖”。如今,Swift 已经成为世界上使用最广泛的编程语言之一,特别是它创建了 iPhone、iPad、MacOS 和 Apple TV 创建 iOS 应用程序的主要方式。"],[20,"\\n","24:\\"zbPx\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"3O23\\"|7:3"],[20,"不幸的是,苹果对 Swift 的控制导致它还没有真正在技术领域大放异彩。Chris Lattner 曾在 Google 试图将 Swift 从苹果的舒适区移出来,成为 AI 模型开发中 Python 的替代品。但遗憾的是,它没有得到苹果或 Google 的支持,最终没有成功。"],[20,"\\n","24:\\"nlZ9\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"LYql\\"|7:3|direction:\\"ltr\\""],[20,"话虽如此,在 Google 期间,Chris 开发了另一个非常成功的项目:MLIR。MLIR 是 LLVM IR 的替代品,适用于现代多核计算和 AI 工作负载。这对于充分利用 GPU、TPU 等硬件的强大功能以及越来越多地添加到服务器级 CPU 中的向量单元至关重要。"],[20,"\\n","24:\\"OfP0\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"7f3L\\"|7:3|direction:\\"ltr\\""],[20,"那么,如果 Swift 是“LLVM 的语法糖”,那么“MLIR 的语法糖”是什么?答案是:Mojo!Mojo 是一种全新的语言,旨在充分利用 MLIR。并且,Mojo 也是 Python。"],[20,"\\n","24:\\"TrBA\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"h70y\\"|7:3|direction:\\"ltr\\""],[20,"也许说 Mojo 是 Python++ 更为恰当。它将(完成后)是 Python 语言的严格超集。但它也有附加功能,因此,开发者可以编写利用现代加速器的高性能代码。"],[20,"\\n","24:\\"FLR3\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"L0bn\\"|7:3|direction:\\"ltr\\""],[20,"在 Jeremy Howard 看来,Mojo 似乎比 Swift 更实用。虽然 Swift 是一种包含了基于编程语言设计最新研究的各种炫酷功能的全新语言,但 Mojo 的核心是 Python。因为 Python 已经被数百万程序员广泛使用,并且经过几十年的使用,它的功能和局限性已经得到了充分完善。"],[20,"\\n","24:\\"OiOW\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"ARV7\\"|7:3|direction:\\"ltr\\""],[20,"用最新的编程语言进行研究很酷,但它可能具有潜在危险。就 Jeremy Howard 个人而言,他经常被 Swift 强大但古怪的类型系统搞糊涂,有时甚至成功地被 Swift 编译器混淆并且完全崩溃!"],[20,"\\n","24:\\"OLt6\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"LtSx\\"|7:3|direction:\\"ltr\\""],[20,"Mojo 的一个关键技巧是,作为开发人员,您可以随时选择加入更快的“模式”。通过使用“fn”而不是“def”来创建函数。在这种模式下,您必须准确确定每个变量的类型,Mojo 可以创建优化的机器代码来实现您的函数。此外,如果使用“struct”而不是“class”,您的属性将被打包到内存中,这样它们可以在数据结构中使用,而无需追踪指针。这些特性使得像 C 这样的语言变得很快,而现在 Python 程序员只需学习一点点新语法即可使用。"],[20,"\\n","24:\\"JP1E\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"f8xX\\""],[20,"Mojo 如何做到的?"],[20,"\\n","24:\\"Mmlv\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"WmBa\\"|direction:\\"ltr\\""],[20,"几十年来,为了创建简洁、灵活、快速、实用和易于使用的编程语言,开发者们进行了数百次尝试。但并没有取得太大成效。而 Mojo 似乎做到了。我们可以得出一些假设:"],[20,"\\n","24:\\"qIMh\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"LMX0\\"|7:3"],[20,"1.Mojo 实际上并没有实现这些目标,精彩的演示掩盖了令人失望的现实表现。"],[20,"\\n","24:\\"qalr\\"|7:3|direction:\\"ltr\\""],[20,"2.Modular 是一家拥有数百名开发人员的大型公司,公司为实现未曾实现过的目标付出了多年的努力。"],[20,"\\n","24:\\"OTD4\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Soar\\"|7:3|direction:\\"ltr\\""],[20,"事实上,这两个假设都不成立。我们举两个例子,(matmul 和 mandelbrot)并不是在尝试了数十种方法后才精心选择的唯一有效方法;相反,它们是我们为演示而尝试的一种方法,并且第一次就成功了!虽然在这个早期阶段,还是有很多功能的缺失(除了在线“playground”之外,Mojo 还没有发布给公众),但您在演示中看到的确实是它的工作方式。事实上,您现在可以在 playground 中自己运行它。"],[20,"\\n","24:\\"505e\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"KmFt\\"|7:3|direction:\\"ltr\\""],[20,"Modulal 是一家仅成立一年的小初创公司。一个小团队是如何在短时间内做到这样的呢?"],[20,"\\n","24:\\"ooEj\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"pDdJ\\"|7:3|direction:\\"ltr\\""],[20,"关键一:基础强大","8:1"],[20,"\\n","24:\\"OspC\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"AdWm\\"|7:3|direction:\\"ltr\\""],[20,"关键在于 Mojo 是建立在一些非常强大的基础之上的。Jeremy Howard 表示,很少见到有软件项目愿意花费时间来打好坚实的基础,并且往往会因此积累大量的技术债务。随着时间的推移,添加功能和修复错误变得越来越困难。然而,在 Mojo 这样一个设计良好的系统中,每个功能都比上一个更容易添加,速度也更快,出错率低,每个功能所构建的基础都越来越好。"],[20,"\\n","24:\\"2Ivi\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"aLN2\\"|7:3|direction:\\"ltr\\""],[20,"其核心是最初是由 Chris Lattner 在 Google 开发的并且使用多年的 MLIR。Chris Lattner 已经意识到“AI 时代编程语言”的核心基础将需要什么,并专注于构建它们。MLIR 就是其中的一个关键部分。就像 LLVM 在过去十年中极大地简化了强大的新编程语言的开发一样(如 Rust、Julia 和Swift,它们都基于 LLVM),MLIR 为建立在其上的语言提供了更强大的核心。"],[20,"\\n","24:\\"RTSF\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"8wMK\\"|7:3|direction:\\"ltr\\""],[20,"关键二:使用 Python 作为语法","8:1"],[20,"\\n","24:\\"Gi3v\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"wV0d\\"|7:3|direction:\\"ltr\\""],[20,"Mojo 快速发展的另一个关键因素是决定使用 Python 作为语法。开发和迭代语法是语言开发中最容易出错、最复杂和最有争议的一部分。通过简单地将其外包给现有的语言,整个部分就会消失!因此,需要少量地在 Python 之上添加的新语法部分来自然适应。"],[20,"\\n","24:\\"7YD5\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"0LoR\\"|7:3|direction:\\"ltr\\""],[20,"接下来是创建一个最小的 Pythonic 方法直接调用 MLIR。这并不是一个大项目,但它需要在此基础上创建所有 Mojo 所需的全部内容,并直接在 Mojo 中处理其他所有工作。这意味着 Mojo 开发人员从一开始就能“dog-food” Mojo。当他们在开发 Mojo 时发现某些东西不太好用时,他们可以为 Mojo 本身添加所需的功能,以便更容易开发下一个 Mojo 部分!"],[20,"\\n","24:\\"VPBX\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"xcXW\\"|7:3"],[20,"这一点和 Julia 很像。Julia 是在"],[20,"最小的类LISP内核","16:\\"https%3A%2F%2Fgithub.com%2FJeffBezanson%2Ffemtolisp\\""],[20,"上开发的,该内核提供 Julia 语言元素,然后将其绑定到基本的 LLVM 操作。Julia 中的几乎所有内容都是建立在它之上的。"],[20,"\\n","24:\\"nkPR\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Q7Nr\\"|7:3|direction:\\"ltr\\""],[20,"Modular 团队内部宣布,决定通过一个视频(包括演示)推出 Mojo,并且他们将时间定在了未来几周之内。那时 Mojo 只是最基本的语言,没有可用的笔记本内核,几乎没有实现任何 Python 语法,也没有进行任何优化。"],[20,"\\n","24:\\"vJt8\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"tuVp\\"|7:3|direction:\\"ltr\\""],[20,"起初,Jeremy Howard 并不理解这个行为。但这段时间,Mojo 的表现让他叹为观止。每隔一两天,就有全新的语言功能被实现。一旦有足够的语言功能来尝试运行算法,它们就能够立即达到或接近最先进的性能水平!Jeremy Howard 突然意识到 Mojo 所有的基础都已经建立好了,并且它们被明确设计用于构建现在正在开发的东西。因此,一切都很顺利,而且运作良好也就不足为奇了。"],[20,"\\n","24:\\"dsta\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"wNnB\\"|7:3"],[20,"这是 Jeremy Howard 对 Mojo 未来持乐观态度的理由。虽然这个项目还处于早期阶段,但根据 Jeremy Howard 在过去几周中观察到的情况,他的猜测是它将比大多数人预期的发展得更快、更远……"],[20,"\\n","24:\\"bQvK\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"vaEI\\"|direction:\\"ltr\\""],[20,"Mojo 关键优势:易于部署"],[20,"\\n","24:\\"kS4U\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"LIXL\\"|direction:\\"ltr\\""],[20,"这是很关键的一点。如果你想把你酷炫的 Python 程序给朋友,你需要让他们"],[20,"\\n","24:\\"5wq6\\"|7:3|direction:\\"ltr\\""],[20,"先安装 Python!或者,你可以给他们一个包含 Python 和你使用的所有库的巨大文件。"],[20,"\\n","24:\\"osAj\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Fz2s\\"|7:3|direction:\\"ltr\\""],[20,"由于 Python 是一种解释型语言,所以你的程序的行为将取决于安装的 python 的确切版本、存在的库的版本以及它们的配置方式。为了避免维护问题,Python 社区已经确定了几种选项来安装 Python 应用程序:环境,每个程序都有一个单独的Python 安装;或容器,为每个应用程序设置一整个操作系统。但这两种方法都会在开发和部署Python 应用程序时产生许多混乱和开销。"],[20,"\\n","24:\\"JFrx\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Wkh2\\"|7:3|direction:\\"ltr\\""],[20,"将其与部署静态编译的 C 应用程序进行比较:您只需将编译的程序直接下载即可。它的大小可能只有 100k 左右,可以快速启动和运行。"],[20,"\\n","24:\\"h5K2\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"vM8Z\\"|7:3|direction:\\"ltr\\""],[20,"还有一种 Go 采用的方法,它不能生成像 C 这样的小型应用程序,而是将“运行时”集成到每个打包的应用程序中。这种方法是 Python 和 C 之间的折中,仍需要数十兆字节的二进制文件,但比 Python 更容易部署。"],[20,"\\n","24:\\"pct9\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"vlLo\\"|7:3"],[20,"作为一种编译语言,Mojo 的部署方式与 C 基本相同。例如,一个包含从头开始编写的 matmul 版本的程序大约是 100 k。"],[20,"\\n","24:\\"UeeQ\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"WKFl\\"|7:3"],[20,"这意味着 Mojo 不仅仅是面向 AI/ML 应用程序的语言。它实际上是 Python 一种版本,可以帮助我们编写快速、小巧、易于部署的应用程序,利用所有可用的核心和加速器!"],[20,"\\n","24:\\"U1qT\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"tRxS\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"7k8z\\"|direction:\\"ltr\\""],[20,"Mojo 的替代品"],[20,"\\n","24:\\"Xpfd\\"|32:1|direction:\\"ltr\\""],[20,"\\n","24:\\"eXV2\\"|direction:\\"ltr\\""],[20,"Mojo 并不是解决 Python 性能和部署问题的唯一办法。在语言方面,Julia 可能是目前最强的替代品。它具有 Mojo 的许多优点,并且构建出了很多优秀的项目。但在 Jeremy Howard 看来,Julia 也并不完美:"],[20,"\\n","24:\\"HloO\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"HevC\\"|direction:\\"ltr\\""],[20,"Julia 面临的最大挑战源于其大型运行时,决定在该语言中使用垃圾回收。此外,Julia 中使用的多调度方法虽然打开了很多用语言做很酷的事情的大门,但也会让开发人员的工作变得非常复杂。"],[20,"\\n","24:\\"uFW1\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"YVMU\\"|7:3"],[20,"在 Python 中,目前最好的解决方案可能是 "],[20,"Jax","16:\\"https%3A%2F%2Fjax.readthedocs.io%2Fen%2Flatest%2F\\""],[20,",它有效地使用 Python 创建了一个特定领域的语言(DSL)。这种语言的输出是 XLA,它是一个早于MLIR的机器学习编译器(我相信它正在逐渐转移到MLIR上)。Jax 继承了 Python(例如,该语言无法表示结构,或直接分配内存或创建快速循环)和 XLA(主要针对 TPU,很大程度上限制在机器学习特定的概念上)的限制,但具有巨大的优势,即不需要新的语言或新的编译器。"],[20,"\\n","24:\\"mtFh\\"|7:3|direction:\\"ltr\\""],[20," "],[20,"\\n","24:\\"6g0O\\"|7:3|direction:\\"ltr\\""],[20,"如前所述,还有新的 PyTorch 编译器,Tensorflow 也能够生成 XLA 代码。就 Jeremy Howard个人而言,这种方式使用 Python 最终并不令人满意。Jeremy Howard 实际上并没有使用 Python 的所有功能,但必须使用与其所针对的后端兼容的子集。Jeremy Howard 不能轻松地调试和分析编译后的代码,因为很多不确定性,甚至很难知道最终执行的内容。"],[20,"\\n","24:\\"KE2z\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Pote\\"|7:3|direction:\\"ltr\\""],[20,"Jeremy Howard 甚至无法得到一个独立的二进制文件,而必须使用特殊的运行时并处理复杂的 API。"],[20,"\\n","24:\\"AbgL\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"Kq5J\\"|7:3|direction:\\"ltr\\""],[20,"Python 的另一个有趣的方向是 "],[20,"Numba","16:\\"https%3A%2F%2Fnumba.pydata.org%2F\\""],[20," 和 "],[20,"Cython","16:\\"https%3A%2F%2Fcython.org%2F\\""],[20,"。Numba 使用一个特殊的装饰器,使 Python 函数被编译成使用LLVM优化的机器代码。Cython 类似,但还提供了一个类似于 Python 的语言,具有 Mojo 的一些特性,并将这个 Python 方言转换成 C,然后进行编译。这些语言都没有解决部署问题,但它们可以帮助解决性能问题。"],[20,"\\n","24:\\"CRzC\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"mMs8\\"|7:3"],[20,"两者都无法针对具有通用跨平台代码的一系列加速器,尽管 Numba 确实提供了一种非常有用的方法来编写 CUDA 代码(因此可以针对 NVIDIA GPU)。Jeremy Howard 对于 Numba 和 Cython 的存在表示感激,并且认为从它们中获得了很多。但它们完全不同于使用完整的语言和编译器生成独立的二进制文件。它们只是Python性能问题的临时解决方案,对于仅需要解决性能问题的情况是可行的"],[20,"\\n","24:\\"bnE2\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"MRYz\\"|7:3"],[20,"但 Jeremy Howard 更喜欢使用一种既像 Python 一样,又像 C 一样快的语言,能够允许其使用一个语言来编写从应用程序服务器到模型架构以及安装程序的所有内容,并且能在编写代码的语言中直接调试和分析其的代码。"],[20,"\\n","24:\\"qqu3\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"BrEH\\"|7:3"],[20,"你喜欢这样的语言吗?欢迎在评论区留言讨论。"],[20,"\\n","24:\\"yzdJ\\"|7:3|direction:\\"ltr\\""],[20,"\\n","24:\\"0SAI\\"|direction:\\"ltr\\""],[20,"\\n","24:\\"hxif\\"|direction:\\"ltr\\""],[20,"参考链接:"],[20,"\\n","24:\\"4Ko2\\"|direction:\\"ltr\\""],[20,"https://www.fast.ai/posts/2023-05-03-mojo-launch.html","0:\\"rgb(65%2C%2070%2C%2075)\\"|16:\\"https%3A%2F%2Fwww.fast.ai%2Fposts%2F2023-05-03-mojo-launch.html\\"|1:\\"rgb(255%2C%20255%2C%20255)\\"|27:\\"9\\"|31:2"],[20,"\\n","24:\\"INNX\\"|direction:\\"ltr\\""],[20,"https://www.modular.com/mojo","0:\\"rgb(65%2C%2070%2C%2075)\\"|16:\\"https%3A%2F%2Fwww.modular.com%2Fmojo\\"|1:\\"rgb(255%2C%20255%2C%20255)\\"|27:\\"9\\"|31:2"]]" data-copy-origin="https://shimo.im" style="outline: 0px; font-size: 15px; color: rgba(0, 0, 0, 0.9); font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif; visibility: visible;">展性。使用 Mojo 可以编写比 C 更快、可移植的代码,并与 Python 生态系统无缝交互。最重要的是,Mojo 具备了使用 Python 库整个生态系统的能力。
一、可用性和可编程性
Mojo 能够对大量低级 AI 硬件进行编程,无需 C++ 或 CUDA。
二、性能
在用最先进的编译器和异构运行时,Mojo 能够利用硬件的全部功能,包括多核、向量单元和加速器单元,在不复杂的前提下,实现与 C++ 和 CUDA 相当的性能。
除此之外,根据官网测试结果,Mojo 比 Python 快 35000 倍。
三、互操作性
Mojo 可以访问 Numpy 和 Matplotlib 等任意库以及所有用户自定义代码。
四、可扩展性
Mojo 可以通过预处理和后处理操作轻松扩展模型,或将操作替换为自定义操作。并且能够利用内核融合、图形重写、形状函数等。
目前,Mojo 仍在不断完善中,但开发者可以在 Modular AI 基于 JupyterHub 的 Playground 进行试用。用户可以通过阅读教程编写自己的 Mojo 代码。
Mojo 的官宣在网上引起了不小的讨论,Jeremy Howard 体验后更是发长文向大家安利了 Mojo。在他看来,Mojo 是 Python++ 更为恰当,并且比 Swift 更实用。他直言自己更喜欢使用一种既像 Python 优雅,又像 C 一样快的语言,能够允许其使用一个语言来编写从应用程序服务器到模型架构以及安装程序的所有内容,并且能在编写代码的语言中直接调试和分析其代码。
为什么不直接使用 Python ?
缺点一:性能缺陷
Python 有几乎完美的核心,它可以做任何事情。但它也有一个缺点:性能。Python 比像 C++ 这样的语言慢几千倍。因此,将 Python 用于代码性能的关键部分不切实际。
但 Python 有一个绝招:它可以调用快速语言编写的代码。因此,Python程序员不用 Python 来实现性能关键部分的代码。比如 Numpy 和 PyTorch 这样的库为高性能代码提供了“pythonic”接口,让 Python 程序员有种宾至如归的感觉。
缺点二:“双语言"问题
如今,几乎所有的 AI 模型都是用 Python 开发,这要归功于其灵活、完美的编程语言、高效的工具和生态系统,以及高性能的编译库。
但这种“双语言”方法有严重的缺点。例如,AI 模型通常必须用 Python 转换为更快的实现,如 ONNX 或 torchscript。但这些部署方法不能支持 Python 的所有功能,因此 Python 程序员必须学会使用与其部署目标匹配的语言子集。并且,很难对部署版本的代码进行分析或调试,也不能保证它能够和 Python 版本完全相同地运行。
这种双语言问题妨碍了学习,使得开发者无法在代码运行时执行算法的实现,或者跳转到感兴趣的方法定义,而是陷入 C 库和二进制文件的细节中。对于 AI 领域的快速发展,开发者们都需要学习。但无论是经验丰富的开发者还是入门的学生,仍面临很多困难。
当尝试调试代码或查找和解决性能问题时,同样会出现这个问题。双语言问题意味着,一旦我们进入后端实现语言,Python 程序员熟悉的工具就不再适用。
即使使用最快的编译实现语言来编写库,也会出现无法避免的性能问题。一个主要问题是缺乏“融合”——也就是说,连续调用一堆编译函数会带来大量的开销,因为数据被转换为 Python 格式和从 Python 格式转换,并且必须重复从 Python 到 C 的切换成本。
因此,我们必须编写常见函数组合的特殊“融合”版本,并从 Python 调用这些融合版本。这意味着需要实现和记忆更多的库函数,稍有差错,就很难有一个合适的融合版本。
我们还必须处理 Python 中缺乏有效并行处理的问题。如今,我们都有具备多个内核的计算机,但 Python 通常只会一次使用一个内核。有一些笨重的方法可以编写使用多个核的并行代码,但它们要么必须在完全分离的内存上工作(并且启动开销大),要么必须交替访问内存(可怕的“全局解释器锁定”通常使并行代码比单线程代码实际上更慢!)
像 PyTorch 这样的库一直在开发越来越巧妙的方法来处理这些性能问题,新发布的 PyTorch 2 甚至包括一个 compile() 函数,该函数使用复杂的编译后端来创建 Python 代码的高性能实现。然而,这样的功能不能发挥魔力:基于语言本身的设计,Python 的可能性存在根本性限制。
除此之外,它们总体上都是非常基本的算法,例如,transformer 模型几乎完全由多层感知器(MLP)和注意力实现,只需几行 Python 和 PyTorch 即可实现。以下是 MLP 的实现:
nn.Sequential(nn.Linear(ni,nh), nn.GELU(), nn.LayerNorm(nh), nn.Linear(nh,ni))这是一个自我注意层:
def forward(self, x): x = self.qkv(self.norm(x)) x = rearrange(x, 'n s (h d) -> (n h) s d', h=self.nheads) q,k,v = torch.chunk(x, 3, dim=-1) s = (q@k.transpose(1,2))/self.scale x = s.softmax(dim=-1)@v x = rearrange(x, '(n h) s d -> n s (h d)', h=self.nheads) return self.proj(x)但实际上,这些操作很复杂。例如,在 CUDA C 中进行内存优化的“闪存注意”实现。它还掩盖了这些构建模型通用方法所留下的大量性能事实。例如,“块稀疏”方法可以显著提高速度和内存使用。研究人员正在对常见架构的每个部分进行调整,并提出新的架构(以及 SGD 优化器,数据增强方法等)——我们甚至还没有适合每个人都会永久使用的整齐包装系统。
在实践中,许多用于语言模型的最快代码都是用 C 和 C++ 编写的。例如,Fabrice Bellard 的 TextSynth 和 Georgi Gerganov 的 ggml 都使用 C 语言,因此能够充分利用完全编译语言的性能优势。
“MLIR 的语法糖”:Mojo
Chris Lattner 开发的 LLVM,从根本上改变了编译器的创建方式,也为世界上许多广泛使用的语言生态系统打下了坚实的基础。
之后,他推出了一个建立在 LLVM 之上的 C 和 C++ 编译器 Clang,并被广泛使用。LLVM 包括“中间表示”(IR),这是一种为机器读写(而不是人)设计的特殊语言,它使一个庞大的软件社区能够协同合作,为更广泛的硬件提供更好的编程语言功能。
Chris Lattner 认为 C 和 C++ 并没有完全充分利用 LLVM 的威力,因此他在苹果工作时,设计了一种名为“Swift”的新语言,他将其描述为“LLVM 的语法糖”。如今,Swift 已经成为世界上使用最广泛的编程语言之一,它是 iPhone、iPad、MacOS 和 Apple TV 创建 iOS 应用程序的主要方式。
不幸的是,苹果对 Swift 的控制导致它还没有真正在技术领域大放异彩。Chris Lattner 曾在 Google 试图将 Swift 从苹果的舒适区移出来,成为 AI 模型开发中 Python 的替代品。但遗憾的是,它没有得到苹果或 Google 的支持,最终没有成功。
话虽如此,在 Google 期间,Chris 开发了另一个非常成功的项目:MLIR。MLIR 是 LLVM IR 的替代品,适用于现代多核计算和 AI 工作负载。这对于充分利用 GPU、TPU 等硬件的强大功能以及越来越多地添加到服务器级 CPU 中的向量单元至关重要。
那么,如果 Swift 是“LLVM 的语法糖”,那么“MLIR 的语法糖”是什么?答案是:Mojo!Mojo 是一种全新的语言,旨在充分利用 MLIR。并且,Mojo 也是 Python。
也许说 Mojo 是 Python++ 更为恰当。它将(完成后)是 Python 语言的严格超集。但它还会有额外的功能,因此,开发者可以编写利用现代加速器的高性能代码。
在 Jeremy Howard 看来,Mojo 似乎比 Swift 更实用。虽然 Swift 是一种包含了基于编程语言设计最新研究的各种炫酷功能的全新语言,但 Mojo 的核心是 Python。因为 Python 已经被数百万程序员广泛使用,并且经过几十年的使用,它的功能和局限性已经得到了充分完善。
用最新的编程语言进行研究很酷,但它可能具有潜在危险。就 Jeremy Howard 个人而言,他经常被 Swift 强大但古怪的类型系统搞糊涂,有时甚至成功地被 Swift 编译器混淆并且完全崩溃!
Mojo 的一个关键技巧是,作为开发人员,您可以随时选择加入更快的“模式”。通过使用“fn”而不是“def”来创建函数。在这种模式下,您必须准确确定每个变量的类型,Mojo 可以创建优化的机器代码来实现函数。此外,如果使用“struct”而不是“class”,您的属性将被打包到内存中,这样它们可以在数据结构中使用,而无需追踪指针。这些特性使得像 C 这样的语言变得很快,而现在 Python 程序员只需学习一点点新语法即可使用。
Mojo 如何做到的?
几十年来,为了创建简洁、灵活、快速、实用和易于使用的编程语言,开发者们进行了数百次尝试。但并没有取得太大成效。而 Mojo 似乎做到了。我们可以得出一些假设:
1.Mojo 实际上并没有实现这些目标,精彩的演示掩盖了令人失望的现实表现;
2.Modular 是一家拥有数百名开发人员的大型公司,公司为实现未曾实现过的目标付出了多年的努力。
事实上,这两个假设都不成立。我们举两个例子,(matmul 和 mandelbrot)并不是在尝试了数十种方法后才精心选择的唯一有效方法;相反,它们是我们为演示而尝试的一种方法,并且第一次就成功了!虽然在早期阶段还有很多功能的缺失(除了在线“playground”之外,Mojo 还没有发布给公众),但在演示中看到的确实是它的工作方式。事实上,您现在可以在 playground 中自己运行它。
Modulal 是一家仅成立一年的小初创公司。一个小团队是如何在短时间内做到这样的呢?
关键一:基础强大
关键在于 Mojo 是建立在一些非常强大的基础之上的。Jeremy Howard 表示,很少见到有软件项目愿意花费时间来打好坚实的基础,并且往往会因此积累大量的技术债务。随着时间的推移,添加功能和修复错误变得越来越困难。然而,在 Mojo 这样一个设计良好的系统中,每个功能都比上一个更容易添加,速度也更快,出错率低,每个功能所构建的基础都越来越好。
其核心是最初是由 Chris Lattner 在 Google 开发的并且使用多年的 MLIR。Chris Lattner 已经意识到“AI 时代编程语言”的核心基础将需要什么,并专注于构建它们。MLIR 就是其中的一个关键部分。就像 LLVM 在过去十年中极大地简化了强大的新编程语言的开发一样(如 Rust、Julia 和Swift,它们都基于 LLVM),MLIR 为建立在其上的语言提供了更强大的核心。
关键二:使用 Python 作为语法
Mojo 快速发展的另一个关键因素是使用 Python 作为语法。开发和迭代语法是语言开发中最容易出错、最复杂和最有争议的一部分。通过简单地将其外包给现有的语言,整个部分就会消失!因此,需要少量地在 Python 之上添加的新语法部分来自然适应。
接下来是创建一个最小的 Pythonic 方法直接调用 MLIR。这并不是一个大项目,但它需要在此基础上创建所有 Mojo 所需的全部内容,并直接在 Mojo 中处理其他所有工作。这意味着 Mojo 开发人员从一开始就能“dog-food” Mojo。当他们在开发 Mojo 并发现某些东西不太好用时,他们可以为 Mojo 本身添加所需的功能,以便更容易开发下一个 Mojo 部分!
这一点和 Julia 很像。Julia 是在最小类 LISP 内核上开发的,该内核提供 Julia 语言元素,然后将其绑定到基本的 LLVM 操作。Julia 中的几乎所有内容都是建立在它之上。
Modular 团队决定通过视频(包括演示)推出 Mojo,并且他们将时间定在了未来几周之内。那时 Mojo 只是最基本的语言,没有可用的笔记本内核,几乎没有实现任何 Python 语法,也没有进行任何优化。
起初,Jeremy Howard 并不理解这个行为。但这段时间,Mojo 的表现让他叹为观止。每隔一两天,就有全新的语言功能被实现。一旦有足够的语言功能来尝试运行算法,它们就能够立即达到或接近最先进的性能水平!Jeremy Howard 突然意识到 Mojo 所有的基础都已经建好了,并且它们被明确设计用于构建现在正在开发的东西。因此,一切都很顺利,而且运作良好。
这是 Jeremy Howard 对 Mojo 未来持乐观态度的理由。虽然这个项目还处于早期阶段,但根据 Jeremy Howard 在过去几周中观察到的情况,他的猜测是它将比大多数人预期的发展得更快、更远……
Mojo 关键优势:易于部署
这是很关键的一点。如果你想把你酷炫的 Python 程序给朋友,你需要让他们先安装 Python!或者,你可以给他们一个包含 Python 和你使用的所有库的巨大文件。
由于 Python 是一种解释型语言,所以程序的执行将取决于所安装 Python 的确切版本、存在的库的版本以及它们的配置方式。为了避免维护问题,Python 社区已经确定了几种选项来安装 Python 应用程序:环境,每个程序都有一个单独的 Python 安装或容器,为每个应用程序设置一整个操作系统。但这两种方法都会在开发和部署 Python 应用程序时产生许多混乱和开销。
将其与部署静态编译的 C 应用程序进行比较:您只需将编译的程序直接下载即可。它的大小可能只有 100k 左右,可以快速启动和运行。
还有一种 Go 采用的方法,它不能生成像 C 这样的小型应用程序,而是将“运行时”集成到每个打包的应用程序中。这种方法是 Python 和 C 之间的折中,仍需要数十兆字节的二进制文件,但比 Python 更容易部署。
作为一种编译语言,Mojo 的部署方式与 C 基本相同。例如,一个包含从头开始编写的 matmul 版本的程序大约是 100 k。
这意味着Mojo不仅仅是用于AI/ML应用的语言。它实际上是Python的一个版本,允许开发者编写快速、小巧、易于部署的应用程序,并利用所有可用的核心和加速器!
Mojo 的替代品
Mojo 并不是解决 Python 性能和部署问题的唯一办法。在语言方面,Julia 可能是目前最强的替代品。它具有 Mojo 的许多优点,并且构建出了很多优秀的项目。但在 Jeremy Howard 看来,Julia 也并不完美。
Julia 面临的最大挑战源于其大型运行时,决定在该语言中使用垃圾回收。此外,Julia 中使用的多调度方法虽然打开了很多用语言做很酷的事情的大门,但也会让开发人员的工作变得非常复杂。
在 Python 中,目前最好的解决方案可能是 Jax,它有效地使用 Python 创建了一个特定领域的语言(DSL)。这种语言的输出是 XLA,它是一个早于 MLIR 的机器学习编译器。Jax 继承了 Python(例如,该语言无法表示结构,或直接分配内存或创建快速循环)和 XLA(主要针对 TPU,很大程度上限制在机器学习特定的概念上)的限制,但具有巨大的优势,即不需要新的语言或新的编译器。
如前所述,还有新的 PyTorch 编译器,Tensorflow 也能够生成 XLA 代码。就 Jeremy Howard 个人而言,这种方式使用 Python 最终并不令人满意。Jeremy Howard 实际上并没有使用 Python 的所有功能,但必须使用与其所针对的后端兼容的子集。Jeremy Howard 不能轻松地调试和分析编译后的代码,因为很多不确定性,甚至很难知道最终执行的内容。
Jeremy Howard 甚至无法得到一个独立的二进制文件,而必须使用特殊的运行时并处理复杂的 API。
Python 的另一个有趣的方向是 Numba 和 Cython。Numba 使用一个特殊的装饰器,使 Python 函数被编译成使用 LLVM 优化的机器代码。Cython 类似,但还提供了一个类似于 Python 的语言,具有 Mojo 的一些特性,并将这个 Python 方言转换成 C,然后进行编译。这些语言都没有解决部署问题,但它们可以帮助解决性能问题。
两者都无法针对具有通用跨平台代码的一系列加速器,尽管 Numba 确实提供了一种非常有用的方法来编写 CUDA 代码(因此可以针对 NVIDIA GPU)。Jeremy Howard 对于 Numba 和 Cython 的存在表示感激,并从中受益匪浅。然而,它们并不像使用完整语言和编译器生成独立二进制文件一样。它们只是 Python 性能问题的临时解决方案,在仅需要这些功能的情况下可以使用。
Jeremy Howard 最后表示,他更喜欢使用一种既优雅如 Python,又快速如专业编写的 C 语言,允许他使用同一种语言编写应用程序服务器、模型架构以及安装程序,并可以直接在自己编写代码的语言中进行调试和分析。
你喜欢这样的语言吗?欢迎在评论区留言讨论。
参考链接:
https://www.fast.ai/posts/2023-05-03-mojo-launch.html
https://www.modular.com/mojo
","gnid":"9110b362b1f76a917","img_data":[{"flag":2,"img":[{"desc":"","height":"80","s_url":"https://p0.ssl.img.360kuai.com/t013d73ffee4a20366b_1.gif","title":"","url":"https://p0.ssl.img.360kuai.com/t013d73ffee4a20366b.gif","width":"640"},{"desc":"","height":"988","title":"","url":"https://p0.ssl.img.360kuai.com/t0101f7afcbae5029ab.jpg","width":"1080"},{"desc":"","height":"1032","title":"","url":"https://p0.ssl.img.360kuai.com/t014559696ddbb879ca.jpg","width":"1080"},{"desc":"","height":"544","s_url":"https://p0.ssl.img.360kuai.com/t0171a4f9a52def6751_1.gif","title":"","url":"https://p0.ssl.img.360kuai.com/t0171a4f9a52def6751.gif","width":"847"},{"desc":"","height":"421","s_url":"https://p0.ssl.img.360kuai.com/t01adcaf8a866d6e723_1.gif","title":"","url":"https://p0.ssl.img.360kuai.com/t01adcaf8a866d6e723.gif","width":"1079"},{"desc":"","height":"385","title":"","url":"https://p0.ssl.img.360kuai.com/t01e228d30a7e09a629.jpg","width":"1080"},{"desc":"","height":"555","s_url":"https://p0.ssl.img.360kuai.com/t01d824dd84faeb1d40_1.gif","title":"","url":"https://p0.ssl.img.360kuai.com/t01d824dd84faeb1d40.gif","width":"1079"},{"desc":"","height":"496","s_url":"https://p0.ssl.img.360kuai.com/t017fdd27188524ad8c_1.gif","title":"","url":"https://p0.ssl.img.360kuai.com/t017fdd27188524ad8c.gif","width":"1079"}]}],"original":0,"pat":"art_src_1,fts0,sts0","powerby":"hbase","pub_time":1683204609000,"pure":"","rawurl":"http://zm.news.so.com/88690c239698a6b34b3176d485258794","redirect":0,"rptid":"8dd880b57705f596","rss_ext":[],"s":"t","src":"CSDN","tag":[{"clk":"ktechnology_1:chris","k":"chris","u":""}],"title":"编译器大神 Chris Lattner 官宣新编程语言:Mojo,比 Python 快 35000 倍!
编程器和烧录器的区别在哪?
简单来说,编程器和烧录器的区别在于它们所针对的设备类型和写入方式。编程器主要用于写入可编程设备,而烧录器则主要用于写入只读存储器或闪存。此外,编程器通常具有更广泛的应用范围,可以用于多种类型的可编程设备,而烧录器则更专注于特定的存储器芯片。在实际应用中,编程器和烧录器可能会有重叠的使用...
编程器、烧录器、仿真器的区别是什么?
烧录器实际上是一个把可编程的集成电路写上数据的工具,烧录器主要用于单片机(含嵌入式)\/存储器(含BIOS)之类的芯片的编程(或称刷写)。仿真器(emulator)以某一系统复现另一系统的功能。与计算机模拟系统(Computer Simulation)的区别在于,仿真器致力于模仿系统的外在表现、行为,而不是模拟系统的抽...
编程器使用方法怎么用
首先,建议在编写代码时,使用合适的缩进和注释,以提高代码的可读性。其次,应该经常保存代码,并保持良好的代码组织和文件命名规范,以便后续维护和分享代码。此外,掌握一些常用的快捷键和命令,可以更高效地使用编程器。最后,及时更新编程器和相关插件,以获得最新的功能和修复已知的问题。总之,通过合理...
第5代stc单片机自动编程器如何使用
该设备使用方法步骤如下:1、连接设备:将编程器与电脑或其他设备通过USB线连接起来。2、下载编程软件:下载并安装与编程器配套的编程软件,通常软件会包含一个简单易用的界面,让用户可以轻松进行操作。3、编程:在编程软件中选择下载程序,然后根据需要进行编程。在编程过程中,需要注意编程的格式和内容是...
编程器是干什么的
编程器为可编程的集成电路写入数据的工具。编程器主要用于单片机(含嵌入式)\/存储器(含BIOS)之类的芯片的编程(或称刷写)。编程器主要修改只读存储器中的程序,编程器通常与计算机连接,再配合编程软件使用。编程器通过数据线与计算机并口(打印机接口)联接,独立的外接电源,使用操作更方便,编程更稳定...
vvdi超级编程器要交费吗
不需要交费的。VVDI超级编程器的机器是需要单独购买的,购买完机器之后的使用是不需要交费的,VVDI是通用编程器,定位是专门用来读写数据的,是不收费的。VVDI编程器,中国人自主研发的中文编程器,中国人都能看懂的防盗数据读写神器。做新款老款宝马、保时捷、老款奔驰摩托罗拉锁头。读写新款宝马CAS4数据...
欧姆龙手持编程器用法
回答:欧姆龙手持编程器的用法: PLC接通电源后,编程器上显示出PASSWORD“口令”字样,按CLR MONTR键后,该口令消失,再次按下CLR键,屏幕上显示出地址0000,然后方可进行各项操作。 1、内存清除清除内存操作必须在PROGRAM模式下进行。 1>、内存全清除 将存储器中的程序、继电器、定时器\/计数器、数据存储器中的...
在手机上怎么下载源码编程器软件呢
如果你想在手机上下载源码编程器软件,你可以按照以下步骤进行操作:1. 打开手机的应用商店,如App Store(苹果手机)或Google Play(安卓手机)。2. 在搜索栏中输入“源码编程器”或相关的关键词,如“代码编辑器”、“开发工具”等。3. 应用商店会显示与你搜索相关的软件列表,浏览并选择一个你感...
西尔特编程器校准方法
1、首先使用西尔特编程器610p需要先根据芯片型号选择对应的编程器和编程软件。2、其次将编程器与计算机连接,接着将芯片插入编程器的插座中。3、最后在编程软件中选择要烧录的程序或数据,并进行相应的设置和操作,最后点击烧录按钮即可完成校准。
编程器是什么???求答。谢谢
编程器在台湾叫烧录器,因台湾半导体产业发展早,在大陆,根据英文名”PROGRAMMER“命名为“编程器”,编程器为可编程的集成电路写入数据的工具,编程器主要用于单片机(含嵌入式)\/存储器(含BIOS)之类的芯片的编程(或称刷写)。编程器主要修改只读存储器中的程序,编程器通常与计算机连接,再配合编程软件...
舟山市瓜霜回答: 现在大部分学校使用的都是VC++6.0,虽然老但是对于初学者来说很好用,关于这个软件的书籍,和视频教程都很多.使用起来方便.上网搜索VC++6.0就有了.
谷邱19659105691问: 推荐一个好用的c++编程器 - ?
舟山市瓜霜回答: Dev-C++是一个Windows环境下C/C++/C++11的集成开发环境(IDE),它是一款自由软件,遵守GPL许可协议分发源代码.它集合了MinGW等众多自由软件,并且可以取得最新版本的各种工具支持,而这一切工作都是来自全球的狂热者所做的...
谷邱19659105691问: C语言编程器的下载(汉化版的)?
舟山市瓜霜回答: 用迅雷下载 ftp://202.102.240.76/bckf/bcgj/Microsoft_Visual_C++_6.0_简体中文企业版.rar 解压密码 www.soft168.com 用DEAMON TOOLS加载ISO映像文件后自动读盘,就能安装了
谷邱19659105691问: C语言编程器下载哪里有啊? - ?
舟山市瓜霜回答: 直接在百度的搜索栏里输入C语言编辑器,就可以了,电脑上自带有VC++的蛮,microsoft里有吧
谷邱19659105691问: 学C语言用什么编程器好?
舟山市瓜霜回答: vc++6.0,很羞又,不过随着windows系统的升级,兼容性问题越来越突出. 可以试着安装visual studio express版本,如果单纯学习c、c++的话,也可以选择codeblocks、eclipse等,不过个人建议,学习c语言,一定不能脱离Unix、Linux,你要知道,c语言创建出来的目的就是为了重写Unix
谷邱19659105691问: 运用C语言编程,最好用哪个编程器??
舟山市瓜霜回答: 我用win-tc
谷邱19659105691问: 关于C语言编程器的使用 - ?
舟山市瓜霜回答: TURBO C2.0是C语言的编辑器,如果是C语言的话推荐使用WINTC这个编辑器,这是WIN环境下使用的编辑器.如果是C++的话就用VisualC++,可以在WIN环境下使用的编辑器
谷邱19659105691问: 求c语言编程的软件 最实用的吧 - ?
舟山市瓜霜回答: visual studio 2010 是最好用的 在我看来,除了使用WPF重新开发了用户界面之外,这个版本在其他方面基本上没有什么重大的改变.实际上,除添加了这些华而不实的东西之外,在其它许多方面也得到了一定的改善.一 多个配置文...
谷邱19659105691问: C编程工具用哪个??
舟山市瓜霜回答: TUBOO不错
谷邱19659105691问: 谁有C语言编程器啊?
舟山市瓜霜回答: Dev-C++和CodeBlocks体积小巧,相比VC++而言更加方便好用,我个人一直在用CodeBlocks 下载地址: http://downloads.sourceforge.net/project/codeblocks/Binaries/8.02/codeblocks-8.02-setup.exe?use_mirror=cdnetworks-kr-1