首页
学习
活动
专区
圈层
工具
发布

Mojo

修改于 2026-09-28 17:16:57
185
概述

Mojo 是由 Modular 公司开发的一门编译型编程语言,定位为面向人工智能与异构硬件的系统级编程语言。它在语法上高度接近 Python,同时引入静态类型、所有权与生命周期检查、编译期元编程等系统语言能力,并通过 LLVM 与 MLIR 作为编译基础设施,将同一份代码降到 CPU、GPU、各类 AI 加速器上执行。Mojo 于 2023 年首次公开测试,2026 年 8 月 11 日发布 1.0 正式版并承诺源码稳定性,同年 8 月 18 日将编译器与工具链以 Apache 2.0 许可(附带 LLVM 例外条款)开源。2026 年 9 月 17 日,Modular 发布 26.6 版本,随 Mojo 1.1 正式开放编译器的外部贡献。Modular 已于 2026 年 7 月 29 日被高通公司完成收购,Mojo、MAX 与 Modular Cloud 继续作为独立产品和品牌运营。

一、Mojo 的设计目标是为了解决什么问题?

1. 缓解 AI 软件栈的碎片化

Modular 在设计整套技术栈时发现,横跨编译器、算子库、推理框架、服务层等多层环境进行编程过于复杂,不同厂商、不同层级的组件各自为政,形成难以扩展也难以优化的脆弱堆栈。Mojo 的出发点正是用一个语言层把这些层级串起来,降低跨层开发与调优的成本。

2. 统一 CPU 与 GPU 的编程模型

Mojo 的目标之一是提供灵活且可扩展的编程模型,使其能够面向 CPU、GPU、AI 加速器以及其他在 AI 领域普遍存在的异构系统,让开发者不必为每一种加速器重写代码,从而统一 AI 软件基础设施。

3. 补齐传统语言缺失的编译能力

Mojo 官方明确指出,现有语言未能很好地支持其所需要的能力,包括强大的编译期元编程、自适应编译技术的集成,以及编译流程缓存等特性。这些能力被作为语言的原生组成部分纳入设计,而非事后追加的外部工具。

4. 保持与 Python 生态的共存而非替代

Mojo 并不打算一开始就与 Python 生态切割。它采用接近 Python 的语法,支持直接导入并调用 Python 模块,并提供从 Python 调用 Mojo 的绑定机制,使项目可以按模块粒度逐步迁移,而不是一次性重写。

二、Mojo 的编译流程是怎样的?

1. 采用提前编译而非解释执行

Mojo 是一门编译型语言。mojo build 与 mojo run 两条命令执行的都是提前编译(AOT),即先把源代码整体编译为目标机器码,再执行,不存在边解释边运行的环节。

2. 以中间表示逐级下降

Mojo 不直接把源码翻译成某一种硬件的指令,而是把源码转换成中间表示,再按照 dialect 体系逐级下降(lowering)。每一级 dialect 承担不同抽象层次的语义,越靠近底层越贴近具体硬件,最终由后端生成目标代码。

3. 经由 LLVM 与 MLIR 后端产出目标码

在硬件下降环节,Mojo 使用 LLVM 层面的 dialect 来支持其硬件目标,并在适用场景下采用其他基于 MLIR 的代码生成后端。正是这种结构使 Mojo 能够相对容易地扩展到新的硬件后端,而不是为每款芯片重写一套编译通路。

4. 编译期完成大量工作以减少运行时开销

由于 1.0 版本强调编译期计算,参数化的代码会在编译阶段被展开与特化。例如编译器可以为一个特定参数值生成专属版本的函数实现,运行时需要完成的计算因此减少。

三、MLIR 在 Mojo 的编译体系中扮演什么角色?

1. 作为多级中间表示的基础设施

MLIR 是 LLVM 项目下的多级中间表示框架,Mojo 将其作为编译体系的中间层。借助 dialect 机制,Mojo 可以在同一套编译流程中表达从高层语言语义到底层硬件指令的多级抽象,而不必为每种硬件单独设计前端。

2. 支撑架构无关的栈设计

Modular 官方把 Mojo 与 MAX 的快速移植能力归因于三点设计:架构无关的设计,即 Mojo 与 MAX 不把 GPU 相关知识和优化硬编码进语言,而是把硬件细节委派给库;库导向的执行,即卸载、调度与指令选择通过抽象层控制,而非写死在编译器流程中;参数化算子,即用可针对新硬件重新调优的参数化 kernel 替代 SIMD 宽度、分块形状这类写死的常量。官方给出的量化口径是,这套栈有 99.9% 的部分是与具体架构无关的。

3. 显著缩短新硬件的适配周期

在 AMD Instinct MI355 的实际案例中,Modular 从拿到硬件到完成适配只用了约两周时间,修改集中在 20 个小规模代码合并请求上,核心投入只有约 1.5 名工程师的工作量。之所以能够做到这一点,是因为新增一款 GPU 所需的大部分改动只落在少量 kernel 与参数调优上。

四、Mojo 的静态类型与类型推断机制是如何工作的?

1. 类型在编译期确定且不可变更

Mojo 变量是静态定型的:变量的类型在编译时确定,运行期间不再改变。一旦某个名称在某个作用域内完成绑定,它的类型就固定下来,不能被重新绑定为另一种类型。

2. 省略类型标注时由首次赋值推断

开发者可以选择不写类型标注,此时 Mojo 依据第一次赋给该变量的值推断其类型。例如不标注类型的变量被赋整数值后,即被推断为 Int 类型,随后再赋字符串会触发编译错误。

3. 支持显式标注以提高可读性

变量既可以同时给出值和类型标注,也可以只给出类型标注而暂不赋值。官方文档的建议是标注得越充分,代码越清晰,也越容易维护。

4. 需要切换类型时使用变体类型

如果确实需要让同一个变量持有不同类型的值,Mojo 提供了 Variant 类型,可在其枚举的类型范围内切换。此时变量本身仍然保持静态类型,即 Variant 本身,变化的只是它所承载的具体值。

5. 函数签名中的类型要求

函数可用 def 关键字定义,参数和返回值都可以声明类型。结构体方法中的 self 参数是唯一不需要写类型的参数,因为编译器已经知道它所属的类型。

五、Mojo 的核心技术架构由哪些部分组成?

1. 语言层

语言层即 Mojo 本体,包含语法、类型系统、所有权与生命周期规则、编译期参数化机制以及 trait 体系。Mojo 的标准类型如 Int、String 等都是用 struct 实现的,并未硬编码进语言内部,这使得用户自定义类型与标准库类型享有同等能力。

2. 编译层

编译层以 LLVM 与 MLIR 为基础,负责从源码到异构硬件目标代码的转换,包括中间表示的逐级下降、编译期求值、代码生成与优化。该层已于 2026 年 8 月随编译器一同开源。

3. 标准库层

标准库提供了编写 Mojo 程序所需的大部分基础能力,涵盖基础数据类型、集合类型、可复用算法以及支撑 GPU 编程的模块。标准库自 2024 年起接受社区贡献。

4. 平台层

Mojo 是 Modular Platform 的组成部分。按 Modular 官方博客的划分,该软件栈由 Mojo 语言、MAX 推理框架与 Mammoth 分布式服务系统构成,分别承担编程入口、推理执行与分布式服务的角色,其中 Mammoth 是一套面向大规模分布式 AI 服务的 Kubernetes 原生控制平面、路由器与底座。需要说明的是,Mojo 语言本身采用 Apache 2.0 许可,而 MAX 推理引擎按其自身条款以源码可得方式提供,两者许可并不相同。

5. 工具层

工具层包括 mojo 命令行工具、语言服务器 mojo-lsp-server、代码格式化工具、基于 LLDB 的调试器、交互式 REPL、面向 AI 编码助手的 Mojo AI skills,以及用于从源码构建编译器与标准库的 Bazel 构建配置。

六、Mojo 标准库包含哪些主要模块?

1. 语言地基与内存

  • builtin:内置类型、trait 与基础操作
  • prelude:自动导入的基础类型、trait 和操作
  • traits:对象生命周期与值语义相关的核心 trait
  • origin:Mojo 的 origin 类型定义,用于引用生命周期追踪
  • memory:底层内存管理,包括指针、分配与地址空间
  • reflection:编译期反射工具,用于内省 Mojo 类型与函数
  • ffi:外部函数接口,用于调用 C 代码与加载库

2. 数据结构与迭代

  • collections:核心数据结构,包含 List、Dict、Set、Optional、String 等,其下还包含 string、array、binary_heap、bitset、counter、deque、dict、interval、linked_list、list、optional、set、span、type_dict 等模块
  • iter:迭代 trait 与工具,包含 Iterable、IterableOwned、Iterator、enumerate、zip、map 等
  • itertools:用于惰性序列生成与转换的迭代器工具
  • utils:通用工具,包含索引、变体、静态元组与线程同步

3. 数值、算法与编码

  • algorithm:高性能数据操作,包括向量化、函数式 map 与分块 tiling
  • math:数学函数与常量,覆盖三角函数、指数、对数与特殊函数
  • complex:复数类型及其 SIMD 版本与相关运算
  • bit:位操作,包括位操作、计数、旋转与二的幂次工具
  • random:伪随机数生成,支持均匀分布与正态分布
  • hashlib:加密与非加密哈希,算法可自定义
  • atomic:原子操作与内存排序
  • base64:二进制数据编码,提供 base64 与 base16 的编解码函数
  • format:用于把类型转换为文本的格式化 trait

4. 编译内省与文档

  • compile:运行时函数编译与内省,包括汇编、IR、链接与元数据
  • documentation:文档内置能力,包含用于文档生成的装饰器与工具
  • simd:SIMD 原语与抽象,Int、SIMD 等基础数值类型即由该模块实现

5. 系统、文件与工程工具

  • sys:系统运行时,包含 I/O、硬件信息、内部函数与编译期工具;GPU 检测函数 has_accelerator()、has_nvidia_gpu_accelerator()、has_amd_gpu_accelerator()、has_apple_gpu_accelerator() 即位于该包
  • runtime:运行时服务,包含运行时初始化与工作线程查询
  • os:操作系统接口层,涵盖环境、文件系统与进程控制
  • io:核心 I/O 操作,包含控制台输入输出、文件处理与写入 trait
  • pathlib:文件系统路径操作与导航
  • tempfile:临时文件与目录管理
  • subprocess:执行外部进程与命令
  • time:计时操作,包含单调时钟、性能计数器、睡眠与 time_function
  • stat:文件类型常量与 stat 系统调用检测
  • pwd:用户账户信息的密码数据库查询
  • logger:支持可配置严重级别的日志记录
  • testing:单元测试,包含断言与测试套件
  • benchmark:性能基准测试,提供统计分析与详细报告

6. Python 互操作

  • python:Python 互操作能力,包含包与模块的导入、函数调用与类型转换

七、Mojo 的 GPU 编程模型是如何组织的?

1. 主机与设备的分工

Mojo 通过 MAX 加速器库(MAX accelerator library)提供 GPU 编程支持,该库提供设备管理、GPU 抽象与张量运算等 Mojo API。CPU 作为主机负责管理程序流程、协调 GPU 操作,GPU 作为设备负责在大量线程上并行执行计算。主机与设备各自拥有独立内存空间,二者之间的数据交换需要显式管理。

2. 一次典型 GPU 程序的四个步骤

  1. 在主机内存中初始化数据
  2. 分配设备内存,并把数据从主机传输到设备
  3. 在 GPU 上执行 kernel 函数处理数据
  4. 把结果从设备传回主机内存

整个过程通常是异步的:GPU 计算期间 CPU 可以并行处理其他任务,CPU 在需要确认 GPU 已完成操作(例如拷贝结果之前)时,必须显式调用 synchronize() 进行同步。

3. 线程的组织层次

线程的最顶层组织是网格(grid),网格由若干线程块(thread block)构成,二者都可以按一维、二维或三维组织。流式多处理器会把线程块进一步拆分为 warp,其大小依架构通常为 32 或 64 个线程;若线程块线程数不能整除 warp 大小,剩余线程仍会占满一个 warp 的资源,编码时需留意越界访问。

kernel 内部可直接访问以下索引与维度,均为 Int 类型:

  • grid_dim:网格各维度大小
  • block_dim:线程块各维度大小
  • block_idx:当前线程块在网格中的索引
  • thread_idx:当前线程在线程块中的索引
  • global_idx:线程的全局偏移,例如 global_idx.x = block_dim.x * block_idx.x + thread_idx.x

4. kernel 的编写约束

  • kernel 必须是不抛错(non-raising)的函数,如需表达错误,可使用不分配堆内存的自定义类型
  • 参数必须符合 DevicePassable trait,如 SIMD、DeviceBuffer(设备侧为 Pointer)、TileTensor 以及 Int32、Int64 等定宽类型;Int 与 UInt 不能直接传入
  • kernel 不能有返回值,结果必须写入传入的内存缓冲区
  • 需要自行做越界检查,例如通过 if global_idx.x < size 判断

5. 关键 API 与启动流程

主机侧主要通过 max.gpu.host 包工作,核心类型包括表示 GPU 逻辑实例的 DeviceContext、设备与主机内存缓冲区 DeviceBuffer 与 HostBuffer,以及维度描述结构 Dim。典型流程为:创建 DeviceContext,通过 enqueue 系列接口创建缓冲区并完成主机与设备间拷贝,调用 compile_function 编译 kernel 或直接用 enqueue_function 一步完成编译并入队,最后调用 synchronize() 等待执行完成。

6. 硬件厂商支持

目前通过 api 参数与探测函数明确支持三家厂商:

厂商

api 参数

检测函数

NVIDIA

cuda

has_nvidia_gpu_accelerator()

AMD

hip

has_amd_gpu_accelerator()

Apple

metal

has_apple_gpu_accelerator()

上述检测函数位于标准库 sys 包中,通常在编译期用 comptime if 求值,以便在无 GPU 环境下只编译对应的 CPU 分支。在多 GPU 系统中,设备以从 0 开始的整数索引标识,可通过 DeviceContext.number_of_devices() 查询数量。

需要说明的是,GPU 编程原语并不在标准库内,而是由 MAX 加速器库的 max.gpu 包提供,其下包含 host(主机与设备的交互)、memory(GPU 内存操作)、sync(同步原语)、primitives(warp、block 与 cluster 操作)以及 compute(MMA 与 tensor core 操作)等子包;上文的 grid_dim、block_dim、block_idx、thread_idx、global_idx 等索引别名同样从 max.gpu 导入。

八、Mojo 的编译器与工具链包含哪些组件?

1. 编译器本体

Mojo 编译器现已完全开源,与工具链一并托管在 Modular 的 GitHub 主仓库中,采用 Apache 2.0 许可并附带 LLVM 例外条款。这意味着开发者可以扩展语言本身、把它移植到新平台,并在其上构建任意应用。开源之初 Modular 暂不接受对编译器的外部代码贡献,标准库自 2024 年起即已接受贡献。2026 年 9 月 17 日,Modular 随 26.6 版本发布 Mojo 1.1,宣布正式开始接受编译器贡献,并把内部 issue 迁移到公开的 GitHub Issues,同时调整仓库目录结构,将编译器与标准库统一放置在顶层 Mojo 目录下。目前编译器、标准库与文档三个方向均接受社区贡献。

2. 命令行工具

用户主要通过 mojo 命令使用语言,其中 mojo run 与 mojo build 执行提前编译,mojo doc 用于从 docstring 生成 API 参考文档。此外工具链还提供代码格式化工具、基于 LLDB 的调试器以及交互式 REPL。官方同时提供一个精简的 mojo-compiler 包,只包含命令行工具、标准库与 mojo Python 包,适用于仅需调用或构建既有 Mojo 代码的生产环境,而不含语言服务器与调试器。

3. 语言服务器

工具链包含名为 mojo-lsp-server 的语言服务器,为 VS Code 及其他编辑器提供补全、重构等编辑能力。1.0 版本对其默认行为做了调整:默认不再解析与类型检查 docstring 内的代码块以避免误报,可通过启动参数 -check-docstrings 重新启用;同时不再对外声明折叠区域支持,使 VS Code 回退到基于缩进的折叠,从而修复了 Mojo 文件代码折叠异常的问题。

4. 构建系统

Modular 内部使用 Bazel 管理 Mojo 与 MAX 的复杂构建流程与缓存。开发者克隆仓库后可用单条命令从源码构建 Mojo 编译器并运行测试;若不修改编译器本身,也可使用预构建配置,让构建系统直接下载最新的 nightly 编译器发行包以节省编译时间。需要定制 MAX kernel 或模型的场景,目前仍必须使用预构建的 Mojo 编译器。

5. 面向 AI 编码助手的技能包

Mojo 官方提供 Mojo AI skills,开发者可通过 npx skills add modular/skills 安装。该技能包用于让 AI 编码助手掌握最新的 Mojo 语法与语言特性,覆盖新建项目、GPU 编程以及从其他语言移植等任务。

九、Mojo 的内存安全机制有哪些特点?

1. 以所有权取代垃圾回收

Mojo 采用所有权语义并配合即时析构(ASAP destruction):编译器清楚知道一个值最后一次被使用的时刻,值在此刻即被销毁,无需等待垃圾回收器运行。这既避免了 C 与 C++ 中手工管理内存带来的释放与重复释放风险,也避免了垃圾回收带来回收时机不可控的问题。

2. 编译期生命周期检查

Mojo 编译器内置生命周期检查器,这是一个分析程序数据流的编译器过程,用于判断变量何时有效,并在变量生命周期结束时插入析构调用。检查通过一个称为 origin 的特殊值追踪变量的生命周期与引用的有效性,回答两个问题:这个值由哪个变量拥有,以及能否通过这个引用修改该值。origin 的追踪与生命周期检查全部在编译期完成。

3. 引用自动延长宿主生命周期

Mojo 会利用 origin 延长被引用值的生命周期,确保值不会过早销毁。只要存在活跃引用指向某个值,被引用值就会保持存活。

4. 容器内部引用的失效检查

1.0 版本引入了内部 origin(interior origin)这一实验性能力,生命周期检查器开始能够感知容器内部结构。List、Dict、String 及其他若干容器类型现在返回绑定到内部 origin 的元素引用。一旦容器发生 append、pop 等可能导致重分配的变更,此前取得的元素引用会被检查器判定失效并拒绝编译,而不是像过去那样静默悬空。在官方路线图中,「最终确定内部 origin」仍列为 Phase 2 中尚未开始的工作项。

5. 不安全性下沉到操作而非类型

1.0 版本把此前的 Pointer 与 UnsafePointer 合并为统一的 Pointer 类型,不安全性不再标记在整个类型上,而是标记在单个操作上。相应的不安全操作统一改为 unsafe_ 前缀命名,例如 [i] 改为 [unsafe_offset=i],load() 改为 unsafe_load(),store() 改为 unsafe_store()。这样做的效果是让不安全写法更冗长,从而降低误用概率。

6. 保留底层手动控制

Mojo 仍提供完整的指针与内存分配能力供底层场景使用,包括不被生命周期检查器追踪的非托管内存。使用这类不安全接口时,开发者需自行负责生命周期管理,例如在结构体的析构函数中释放内存。

十、Mojo 的所有权与借用检查机制有哪些规则?

1. 三条基本规则

  • 每个值在同一时刻只有一个所有者
  • 所有者的生命周期结束时,Mojo 销毁该值
  • 若仍存在指向某值的引用,Mojo 会延长所有者的生命周期

2. 变量与结构体的归属关系

变量拥有其值,结构体拥有其字段。引用则允许访问由其他变量拥有的值,引用分为可变访问与不可变访问两类。引用在函数调用时被创建,函数也可以返回引用,此时可通过 ref 关键字创建引用绑定来捕获它。

3. 六类参数约定

约定

是否获得所有权

是否可变

典型用途

默认(不可变借用)

否

否

只读访问,为默认行为

mut

否

是

原地修改调用方的值

var

是

是

需要一份本地可变副本或独占所有权

ref

否(引用)

跟随被引用值

返回或持有带有 origin 的引用

out

是(成为该值)

是

用于构造函数与具名结果

deinit

是(消耗该值)

是

用于析构函数与消耗式移动

未显式声明约定的参数,默认采用不可变只读借用;1.0 版本起该默认约定的关键字名为 imm,此前名为 read。Mojo 通过这种设计实现默认的值语义,同时作为系统语言仍保留对引用语义的完整控制。

4. 三种值类型 trait

  • ImplicitlyCopyable:可不显式声明地被复制,通常是 Int、Float64、Bool 这类简单值类型
  • Copyable:可通过 copy() 方法或拷贝初始化器显式复制,复制原值不受影响
  • Movable:可通过转移操作符 ^ 转移所有权,转移后源变量处于未初始化状态

5. 转移操作符与引用绑定

^ 是唯一真正改变值归属的操作,复制不会改变所有权。引用绑定使用 ref 关键字创建,对引用绑定的读写会直接作用于被引用的对象,且引用绑定本身不能被重新赋值。

十一、Mojo 中 var 显式声明与隐式声明变量有什么区别?

1. var 声明完成三件事

一条 var 声明同时承担三项职责:声明一个与特定类型绑定的逻辑存储位置;把名称绑定到该存储位置;用新建的值初始化这块存储空间,使变量成为该值的所有者。

2. 两种写法都支持类型推断

显式声明与是否写出类型标注是两个独立维度。var a = 5 由编译器推断类型为 Int,var b: Float64 = 3.14 则显式指定类型,也可以写成 var c: String 只创建名称而暂不初始化。

3. 变量使用块级词法作用域

无论哪种写法,Mojo 变量都使用词法作用域,即变量的定义由它在源码中的位置决定,而非运行时的执行时机。作用域级别取决于声明方式,变量具有块级作用域:嵌套代码可以读取和修改外层作用域的变量,外层作用域无法读取内层作用域的变量。内层块中用同名 var 声明的变量会创建全新变量并遮蔽外层同名变量。

4. 1.0 起隐式声明已被弃用

从 1.0 版本开始,所有变量声明都应使用 var。不使用 var 的隐式声明已被弃用,编译时会给出警告并提供自动修复提示以插入 var。除直接赋值外,首次赋值、walrus 操作符目标以及裸类型注解形式同样会触发警告。

5. 不受影响的形式

已经明示绑定方式的写法无需修改,包括 for 循环目标、with ... as、except ... as、推导式目标以及下划线丢弃符。

十二、Mojo 的参数化与编译期元编程能力体现在哪些方面?

1. 参数是编译期变量而实参是运行时值

Mojo 中的参数是编译期变量,会在编译后成为运行时常量,声明在函数或结构体的方括号中;而放在圆括号中的函数实参是运行时值。很多语言把 parameter 与 argument 混用,在 Mojo 中二者是严格区分的概念。

2. comptime 关键字指定编译期求值

comptime 关键字告诉编译器在编译期而非运行时完成求值。例如在循环前加上 comptime,编译器会在编译阶段展开该循环。

3. 编译器为不同参数生成特化版本

把某个值指定为参数后,编译器可以据此做针对性优化,因为这个值在运行期间不再改变。编译器会为该参数取值生成专有的函数版本,运行时的计算量因此减少。

4. 参数化类型

结构体同样可以携带参数,从而依据参数值在编译期定义出该类型的不同变体。例如集合类型在声明时可指定元素类型,属于典型的参数化用法。

5. trait 提供多态约束

trait 是结构体特征的模板,结构体必须实现 trait 中的每一个要求才算符合该 trait。借助 trait,可以编写接受「任何符合某 trait 的类型」的参数化函数,而不必绑定到某个具体类型,编译器会在编译阶段校验该方法确实存在。

十三、Mojo 与 Python 生态的互操作是如何实现的?

1. 官方目标是完整兼容而非语法相似

Mojo 官方的规划是与 Python 生态实现完整兼容,并支持两个方向的互操作:从 Mojo 调用 Python,以及从 Python 调用 Mojo。

2. 从 Mojo 调用 Python

开发者可以在 Mojo 程序中直接导入已有的 Python 模块并使用。官方将其描述为 100% 兼容,原因是 Mojo 直接使用未经修改的 CPython 运行时,把它作为动态库加载。这意味着现有 Python 库、Python 对象的构造以及 Python 函数调用都可以在 Mojo 中原样进行。

3. 从 Python 调用 Mojo

由于 Mojo 是编译型语言,无法像脚本那样被直接求值式地调用。做法是先在 Mojo 侧声明哪些函数与类型对外开放(即声明绑定),然后在 Python 代码中像导入普通模块一样导入,整个过程不需要额外的编译步骤。这为逐步迁移提供了路径:先用 Mojo 重写热点部分,再逐步扩展。

4. 版本要求与依赖说明

Mojo 本身并不依赖 Python;只有使用上述双向互操作特性时才需要 Python 环境,官方支持的版本范围为 Python 3.10~3.14。此外,待调用的 Python 模块需要事先安装在运行 Mojo 的环境中。

5. 迁移工具支持

Mojo AI skills 除了辅助新建项目与 GPU 编程外,也能帮助 AI 编码助手把既有 Python 代码翻译为 Mojo,从而降低迁移门槛。

十四、Mojo 的性能表现体现在哪些方面?

1. 接近甚至超过厂商调优库的矩阵乘法表现

在 AMD Instinct MI355 的适配案例中,Modular 公开了 M=N=K=8192 规模下的实测数据:上线当天初始版本的 Mojo matmul kernel 达到 1,202,302.79 GFlop/s,AMD 的 hipBLASLt 库为 1,561,446.68 GFlop/s,经过约一天的参数调整后,Mojo kernel 提升到 1,610,514.29 GFlop/s,即比当时的业界最优水平快约 3%。需要说明,该组数据由 Modular 官方在自家博客中披露,属于厂商自测结果。

2. 少量代码即可承载核心算子

同一案例中,整套 matmul 实现只有约 500 行带有完整注释的代码。而且同一份代码在 MI300、MI325、MI355 三代 AMD 硬件上都能保持接近最优的性能,跨代移植主要靠参数化调整完成。

3. 端到端推理吞吐优势

在相同场景的下游对比中,MAX 相比 AMD 优化过的 vLLM 分支,在多种工作负载下最高达到 2.2 倍的领先幅度,同时保持了对 MI300、MI325、MI355 的完整可移植性。

4. 开发者效率层面的性能收益

Mojo 的性能价值不仅体现在运行时,也体现在工程效率上。上述新硬件适配仅耗时约两周、投入约 1.5 名工程师、提交 20 个小规模代码合并请求,官方将其归因于参数化算子与架构无关设计带来的工程杠杆。

十五、Mojo 适合用于哪些 AI 与大模型开发场景?

1. AI 算法与 GPU kernel 开发

Mojo 官方列出的用途包括开发 AI 算法、GPU kernel、高性能计算(HPC)以及数据转换等。由于语言本身支持 NVIDIA(cuda)、AMD(hip)与 Apple(metal)三条主流 GPU 路线,同一套语言技能可以覆盖不同厂商的加速器。

2. 推理框架底层算子

Mojo 是 Modular Platform 的实现语言,该平台的 CPU 与 GPU 图算子全部由 Mojo 编写。因此这类对延迟与吞吐极为敏感的底层算子库,是 Mojo 最直接的生产落地形式。

3. 新 AI 硬件的快速适配

对于硬件厂商与平台团队而言,Mojo 适合承担新芯片、新加速器的软件 bring-up 工作。由于栈中绝大部分内容与架构无关,新增一款加速器所需的改动主要集中在少量 kernel 与参数空间调整上。

4. 面向异构环境的端到端部署

Modular Platform 已支持的硬件范围从 CPU 与 GPU 扩展到 AWS Trainium、Google TPU 以及高通 Cloud AI 100 Ultra 与 Dragonfly 加速器。据 Chris Lattner 在 2026 年 9 月 23 日骁龙峰会上的表述,该平台当时已支持来自六家不同硬件厂商的六种数据中心加速器架构。Modular 自身的表述是让开发者实现一次编写、跨 CPU、GPU、NPU 与定制 ASIC 的部署,且无需针对每种加速器重写;高通方面也表示正把这套栈扩展到包括骁龙在内的产品组合上。

5. 云端与自有环境的推理服务

Modular Cloud 已正式对外提供服务,通过共享端点与专属部署两种形式承载开源模型:共享端点兼容 OpenAI 接口并采用按 token 计费,专属部署则可在 Modular 自有算力或用户自有算力上以预留隔离实例运行。这类生产环境的底层执行同样建立在 Mojo 编写的算子之上。

十六、Mojo 的上手路径与学习门槛如何?

1. 安装方式

官方给出的安装命令是通过 Python 包管理器直接安装,例如在命令行执行 uv pip install --upgrade mojo 获取 Mojo,执行 uv pip install max[all] 获取完整的 MAX 依赖。如需精简安装,MAX 也支持按 serve、benchmark 等粒度分别安装所需依赖。需要留意的是,原先统一的 modular 包已在 26.6 版本退役,需改用上述 max 系列包。若要做 GPU 编程,官方建议安装包含 MAX 框架与 Mojo 的 max 包,而非单独的 mojo 包。

2. 官方入门教程

官方提供名为「Get started with Mojo」的动手教程,通过构建一个 Conway 生命游戏模拟来串联 Mojo 的核心语法,官方标注完成时长约 45~60 分钟。教程每节都设有要点小结,帮助有 C++ 或 Python 背景的开发者把转移操作符、编译期变量等新概念映射到已有认知上。

3. 其他学习资源

  • 语言手册与参考:覆盖语法、关键字等的语言参考部分
  • 速查表:可按概念整体组织的可打印参考卡片
  • Mojo Quest:通过解谜练习 Mojo 语法的网页游戏
  • 示例代码:可直接克隆 Modular 的 GitHub 仓库获取官方示例

4. 官方明确提示不建议编程初学者入门

Mojo 官方文档直言该语言仍处于演进阶段,目前并不适合编程初学者,连基础章节也默认读者具备一定编程经验,只是不假定读者熟悉某种特定语言。因此更适合的人群是已有 Python、C++ 或 Rust 等语言基础、且需要处理异构硬件性能的开发者。

5. 操作系统支持情况

Mojo 原生支持 macOS 与 Linux,Windows 用户此前通过 WSL 使用。微软在 2026 年 8 月的 ModCon 大会上透露其团队正与 Modular 合作开发 Mojo 的原生 Windows 支持,并在同年 9 月 23 日的骁龙峰会上由微软 Windows 平台与开发者副总裁进一步确认:Mojo 将可在 Windows 上直接安装、进行系统级编程并运行于操作系统层面,无需虚拟化,微软计划与高通的 Modular 团队合作提供一流的 Mojo 开发体验。

十七、Mojo 的 struct 与 Python 的 class 有什么不同?

Python 的 class 动态灵活,可以在运行时增删属性、混合类型并自由覆盖行为;Mojo 的 struct 则是静态替代方案,绑定在编译期完成,编译器因此可以激进优化。下面是逐项对照。

维度

Python class

Mojo struct

绑定时机

运行时动态分发,可运行时绑定实例字段

编译期绑定,运行时不能添加方法或字段

运行时修改

支持 monkey-patching 等动态改写

不支持运行时修改结构体

继承

支持子类化

不支持继承,改用实现 trait

类属性

支持被所有实例共享的类属性

不支持静态数据成员

字段声明

无需显式声明

所有字段必须用 var 显式声明

内存管理

由引用计数与垃圾回收器管理

采用值语义与所有权模型,字段与结构体实例同生命周期,在值最后一次被使用时析构,无需垃圾回收

静态方法

支持

支持(用 @staticmethod 声明),但不接收 self,也无法访问字段

两者都支持方法、运算符重载以及用于元编程的装饰器。Mojo 官方文档同时说明,未来 Mojo 也会支持与 Python class 行为一致的类类型,但在当下,struct 是自定义类型的首选形式。

十八、Mojo 与 C++ 在 AI 系统编程上有什么差异?

两者都提供系统级的底层控制能力,Mojo 官方文档也承认自己与 C++、Rust 这类语言有不少共同之处,但在获得这份控制力的方式上存在明显区别。

维度

C++

Mojo

语法风格

C 系语法,模板、头文件与宏体系复杂

接近 Python 的语法,学习曲线相对平缓

内存安全

依赖 RAII、智能指针等约定,悬垂引用与重复释放需人工规避

编译期所有权与生命周期检查,容器引用失效由编译器拒绝

Python 互操作

需通过 pybind11 等外部绑定方案

语言原生支持双向互操作,直接复用未修改的 CPython 运行时

硬件后端

依赖 CUDA、HIP 等厂商专用扩展与工具链

经由统一的中间表示与库导向执行,同一套代码面向多种加速器

元编程

模板与 constexpr

编译期参数、comptime 求值,并与 MLIR dialect 衔接

生态成熟度

生态庞大且历经数十年积累

2023 年首次发布,2026 年 8 月才发布首个稳定版

需要说明的是,C++ 生态的成熟度与工具链完备性仍是当前阶段 Mojo 难以比拟的;Mojo 的优势集中在以统一语言覆盖异构硬件、并在编译期拦截内存安全问题这两项上。

十九、Mojo 与 Rust 在系统编程定位上有什么不同?

Rust 与 Mojo 都把所有权与借用检查作为编译期保障内存安全的核心机制,但二者选择了不同的语法取向与目标场景。

维度

Rust

Mojo

语法取向

自成体系的语法,学习曲线较陡

接近 Python,对 Python 开发者更友好

所有权模型

借用检查器严格默认不可变,生命周期标注显式

以「单一所有者 + 即时析构」为基础,参数默认为不可变借用,另有 mut、ref 等约定

析构时机

在作用域结束时析构

在值最后一次被使用时析构(ASAP destruction)

目标重心

通用系统编程,强调安全并发与零成本抽象

AI 与异构硬件编程,强调 CPU、GPU、加速器统一编程

Python 互操作

依赖 PyO3 等第三方绑定

语言原生双向互操作

发展阶段

已进入稳定成熟期

1.0 于 2026 年 8 月发布,路线图中一等公民的 async 支持、代数数据类型与模式匹配等能力仍标记为「尚未开始」

值得一并提及的是,Mojo 的路线图把当前阶段定义为「系统应用编程」,目标是在深化异构硬件系统编程能力的同时,把生态扩展到服务端、网络、微控制器与机器人等场景,并最终成为覆盖 CPU、GPU 与其他硬件的通用编程语言。该阶段规划中的能力包括一等公民的 async 支持、代数数据类型与模式匹配、存在类型与动态 trait、结构体扩展、访问控制等,官方均标记为尚未开始。官方同时明确表示,Mojo 并不以逐项对标 Rust 或 C++ 为目标,而是希望保持一门相对精简、易学的语言。因此二者当前的定位差异,一部分来自语言发展阶段的不同,而非仅有设计取向上的分歧。

相关文章
  • mojo入门介绍
    1.3K
  • Mojo Vision:无形计算(技术解答)
    812
  • 机器学习|Mojo语言入门
    952
  • AI 届新语言 Mojo 要🔥?
    740
  • Mojo变量知识点解读
    414
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
领券