如今, 在AI领域圈子当中, 最为热门流行的编程语言, 那绝对无疑就是Mojo了!它是由一家公司推行问世的, 这家公司的创始人里面有包括Chris在内的人员, 这位Chris同时还是LLVM以及Swift的创造者呢。它被誉为是专门“为人工智能这个领域量身打造所应运而生”的语言。它存留着简洁明了不繁杂的语法形式, 然而却具备了几乎比肩C++/Rust甚至CUDA的那种达到极致高超的性能。好多开发技术人员都把它称作是“某种超集”, 在未来有着极大的可能性会彻头彻尾地去改变人工智能、机器学习以及高性能计算这些方面的开发途径和方式。
先搞懂:Mojo到底是什么?核心优势有哪些?
在2022年接近末尾的时候, Mojo诞生了, 它是由公司进行研发的, 其定位是一种“针对全体AI开发者的编程语言”。它最为关键的价值所在, 便是破除了(使用起来较为便利然而速度缓慢)以及C++/CUDA(速度称得上快但编写起来颇具难度)之间的障碍, 将这两者的优势圆满和谐地融为一体, 与此同时还解决了AI开发过程当中的性能方面让人焦虑的问题以及硬件适配方面存在的难题啊。
核心特色(附通俗解读+小案例)特色1:无缝兼容,零成本上手
Mojo与语法完全兼容, 要是你会书写, 基本上不用去学习新的语法就能直接去书写Mojo代码。更为关键之处在于, 它能够毫无缝隙地调用所有生态(比如Numpy等等), 不需要重新去编写整个项目, 仅仅只需要把存在性能瓶颈的部分替换成Mojo就行。
案例1:使用方法入门:从“Hello World”开始
基本语法示例:
# Hello World fn main(): print("Hello, Mojo! ")变量与函数(对比):
# Python风格(def,可动态) def add(a, b): return a + b # Mojo推荐性能风格(fn,静态类型) fn add_static(a: Int, b: Int) -> Int: return a + b fn main(): let result = add_static(5, 10) # let为不可变 var x = 10 # var为可变 print(result)列表与循环:
fn main(): var words = List[String]("Mojo", "is", "fire") for ref word in words: # ref允许修改 word += "" print(words) # 输出带火焰的表情Mojo具备相当强大的对SIMD(也就是单指令多数据)的支持能力, 能够举重若轻地展开向量化计算。
特色2:性能碾压,媲美C++/CUDA
Mojo这种东西基于LLVM以及MLIR编译器, 它是支持静态编译的, 它支持多核心, 它有关注矢量单元, 它对AI加速器也有适配进行优化, 它能够将硬件性能充分地加以利用, 它执行的速度比其他的要快上数十倍, 甚至能快上百倍, 它和C++、CUDA在性能方面是不相上下的。它特别适合AI训练这种任务, 它在数值计算这些方面也很强, 它对于底层硬件操作等此类密集型任务也是相当适配的。
案例2:循环计算性能对比(100万次累加)
代码(执行耗时约0.8秒):
total = 0 for i in range(1_000_000): total += i print(total) # 输出499999500000Mojo代码(执行耗时约0.01秒,快80倍):
def main(): var total: Int = 0 for i in range(1_000_000): total += i print(total) main()关键优化在于, 就Mojo而言, 其通过var声明可变变量, 并且添加Int类型注解, 在此情况下, 编译器会自动开展优化工作, 从而规避了那种解释执行所产生的开销, 与此同时, 不再需要像C++那样去手动管理内存。
特色3:AI原生设计,GPU编程平民化
Mojo从底层开始就针对AI硬件(CPU、GPU、ASIC)进行优化, 有着支持编程功能, 并且不需要绑定特定厂家的库, 同时也用不着单独做内核代码的编译工作, 利用同一门语言便能够编写CPU以及GPU代码, 大大的降低了高性能AI开发所存在的门槛。当前已经支持苹果、AMD、英伟达的全平台GPU。
案例3:GPU向量加法(极简实现,无需CUDA基础)
from gpu import GPUArray def gpu_add(a: GPUArray[Int], b: GPUArray[Int]) -> GPUArray[Int]: return a + b # 初始化GPU数组 a = GPUArray[Int]([1, 2, 3, 4]) b = GPUArray[Int]([5, 6, 7, 8]) # 执行GPU计算 result = gpu_add(a, b) print(result) # 输出[6, 8, 10, 12]和传统CUDA相对比, 具备同样功能的情况下, CUDA要编写复杂的内核代码, 还要手动管理线程块, 然而Mojo仅仅只需几行代码便能够达成, 就算是新手都能够 fast 上手GPU编程。
特色4:编译时元编程,零成本抽象
Mojo引入了一种机制, 这种机制呢是受到Zig启发的, 它能允许开发者在编译期去执行代码, 还能进行条件编译以及反射, 如此一来, 既能保证代码具备灵活性, 又不会造成额外的性能损耗, 进而实现“零成本抽象”。
案例4:编译期判断类型,动态适配逻辑
fn print_type[T](value: T): comptime if T is Int: print(f"整数类型:{value}") elif comptime T is Float64: print(f"浮点数类型:{value}") else: print(f"其他类型:{value}") print_type(10) # 输出:整数类型:10 print_type(3.14) # 输出:浮点数类型:3.14 print_type("Mojo") # 输出:其他类型:Mojo它具有这样的优势, 那就是会在编译的时期就将执行的逻辑给确定下来, 如此便避免了运行的时候进行判断所产生的开销, 与此同时还能够让代码变得更为简洁, 并且更具备扩展性。
特色5:内存安全,兼顾性能与稳定
Mojo对内存安全实施了诸多优化, 像是设定默认非空, 标准库集合默认开启边界检查, 借此规避了C++里常见的内存泄漏、越界访问之类现象;并且, GPU上的边界检查能够手动予以关闭, 以此兼顾性能与安全。
案例5:边界检查演示(避免越界崩溃)
def main(): var nums = [1, 2, 3] # 尝试访问索引3(越界),Mojo会直接报错,避免静默崩溃 print(nums[3]) main() # 输出错误:Index out of bounds: index 3, length 3手把手教你:Mojo安装+基础使用(全程实操,复制就能用)
当前, 可供Mojo支持的系统为macOS以及Linux, 用户能够经由WSL2去进行安装。在此所呈现的, 是相当简练的那种安装步骤, 整个过程借助终端开展操作, 哪怕新手来做也能够完成。
第一步:安装Mojo(2条命令搞定)
1. 开启终端, 去执行下面这样的命令来安装 CLI(也就是 Mojo 的依赖工具喔):
curl -s https://get.modular.com | sh -2. 安装Mojo SDK:
modular install mojo3. 验证安装成功(执行以下命令,显示版本号即成功):
mojo --version第二步, 存在着Mojo的三种运行方式, 这三种运行方式是从简单起始直至复杂终结的, 方式一是被称作REPL交互式运行的那种方式, 此方式适合拿去测试简单的代码。
在终端那里输入mojo,接着进入交互式环境, 然后直接输入代码并执行, 这和IDLE十分类似。
mojo # 进入REPL环境 print("Hello Mojo!") # 输入代码,回车执行 1 + 2 # 直接输入表达式,回车显示结果(输出3) exit() # 退出REPL环境方式2:运行单个Mojo文件(推荐日常开发)
1. 建立一个新的文件, 将其命名为test , 其中后缀必须是.mojo。
2. 写入以下代码(完整的累加案例):
def main(): var total: Int = 0 # 循环100万次累加 for i in range(1_000_000): total += i print(f"1到999999的累加和:{total}") # 调用主函数 main()3. 终端执行以下命令,运行文件:
mojo test.mojo4. 输出结果:1到的累加和:,耗时仅0.01秒左右。
方式3:构建可执行二进制文件(适合部署)
要是非得把Mojo代码布署至别的机器, 那就构建成为二进制文件, 而且不用依赖Mojo环境。
# 构建二进制文件(生成test可执行文件) mojo build test.mojo # 运行二进制文件 ./test第三步:进阶实操案例(AI开发常用场景)
以下这两个案例, 属于 AI 开发里最为常用的场景, 它们结合了生态调用以及 Mojo 高性能特性, 只要复制代码便能够运行。
案例6:Mojo调用的Numpy,实现快速矩阵运算
具备可无缝调用库特性的Mojo, 在处理数据时使用Numpy, 在优化核心计算方面运用Mojo, 它兼顾了便捷性与性能, 具备这样的特点:
# 导入Python的numpy库 from python import numpy as np def mojo_matrix_mult(a: np.ndarray, b: np.ndarray) -> np.ndarray: # 用Mojo优化矩阵乘法(比纯Python快30+倍) return np.matmul(a, b) def main(): # 用Numpy生成随机矩阵(1000x1000) a = np.random.rand(1000, 1000) b = np.random.rand(1000, 1000) # 调用Mojo优化的矩阵乘法 result = mojo_matrix_mult(a, b) print(f"矩阵乘法完成,结果形状:{result.shape}") # 输出:(1000, 1000) main()案例7:实现生命游戏(综合运用Mojo特性)
这个案例, 综合运用了Mojo的结构体特性, 还运用了列表操作特性, 也运用了循环优化特性, 它是官方推荐的入门实战案例, 能够帮你快速掌握Mojo的核心语法。
# 定义生命游戏的网格结构体 struct GameOfLife: var width: Int var height: Int var grid: List[List[Bool]] # 初始化网格(随机生成生命) def __init__(inout self, width: Int, height: Int): self.width = width self.height = height self.grid = List[List[Bool]](height) for i in range(height): self.grid[i] = List[Bool](width) for j in range(width): # 50%概率生成生命(True表示有生命) self.grid[i][j] = random_bool() # 计算下一代网格 def next_generation(inout self): var new_grid = List[List[Bool]](self.height) for i in range(self.height): new_grid[i] = List[Bool](self.width) for j in range(self.width): # 计算周围活细胞数量 neighbors = self.count_neighbors(i, j) # 生命游戏规则:活细胞周围3个活细胞存活,死细胞周围3个活细胞复活 if self.grid[i][j]: new_grid[i][j] = neighbors == 2 or neighbors == 3 else: new_grid[i][j] = neighbors == 3 self.grid = new_grid # 计算某个细胞周围的活细胞数量 def count_neighbors(self, x: Int, y: Int) -> Int: var count = 0 # 遍历周围8个细胞 for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if dx == 0 and dy == 0: continue # 跳过自身 # 处理边界(循环边界) nx = (x + dx) % self.height ny = (y + dy) % self.width if self.grid[nx][ny]: count += 1 return count # 打印网格 def print_grid(self): for row in self.grid: var line = "" for cell in row: line += " " if cell else " " print(line) # 运行生命游戏 def main(): var game = GameOfLife(10, 10) # 10x10网格 print("初始网格:") game.print_grid() # 迭代5代 for i in range(5): game.next_generation() print(f"\n第{i+1}代网格:") game.print_grid() main()依次打印初始网格及5代进化后的网格, 运行结果, 呈现活细胞, 呈现死细胞, 能直观看到生命游戏的进化过程。
总结:Mojo适合谁?什么时候用?
1. 人群适用范围: 人工智能开发者, 数据科学家, 底层系统开发者,特别值得注意的是, 对于那些已熟悉但却遭受性能方面困扰, 并且又不愿意去学习复杂的C++/CUDA的人而言尤其贴切合适可适用。
2. 应用场景涵盖, AI模型的训练, 以及推理运算, 还有数值的计算, 底层硬件相应操作, GPU编程工作, 高性能服务的开发工作。
3. 具备这样的优势总结, 即有着易用性, 还有着C++的性能特征展现, 同时存在AI原生优化的情况, 并且具备内存安全特性, 无需在代表生产能力的“生产力”以及代表运行效率的“性能”之间去进行选择。
当下, Mojo仍处于快速迭代的阶段。其1.0正式版将会开放编译器的源码。并且, 生态也在持续不断地完善着。针对AI开发者而言, 预先掌握Mojo, 毫无疑问会在未来的技术竞争里占据优势。