网站内页标题,城市建设灯具网站,做外贸网站报价单,网站建设项目实践报告9 月 7 日#xff0c;Modular 公司宣布正式发布 Mojo#xff1a;Mojo 现在已经开放本地下载——初步登陆 Linux 系统#xff0c;并将很快提供 Mac 与 Windows 版本。据介绍#xff0c;Mojo 最初的目标是比 Python 快 35000 倍#xff0c;近日该团队表示#xff0c;Mojo 将…9 月 7 日Modular 公司宣布正式发布 MojoMojo 现在已经开放本地下载——初步登陆 Linux 系统并将很快提供 Mac 与 Windows 版本。据介绍Mojo 最初的目标是比 Python 快 35000 倍近日该团队表示Mojo 将动态与静态语言的优点结合起来一举将性能提升达 Python 的 68000 倍。那么未来的人工智能的语言是 Rust 还是 Mojo 张汉东从 Rust 和 Mojo 语言的特性、生态和其在 LLM 大模型时代的角色进行了剖析。
编程语言是推动时代齿轮的抓手
我从 2006 年入软件行业截止今年我的职业生涯已经走过十七个年头。
这十七年我虽然没有什么光彩履历但却很幸运我还能在这个行业坚守并能不断成长。同样很幸运我经历了桌面软件没落 Web 2.0 崛起以及移动互联网的兴盛当下基础设施系统软件开始复兴的诸多历程。
这么多年我思考最多的两个问题就是
编程语言对于程序员来说到底意味着什么我们为什么要不断地学习新的编程语言能不能学一门就行 这两个问题的答案取决于你如何看待编程语言。
在社区经常会听到一句话“编程语言就是工具”。编程语言确实是工具用于谋生的工具用于编写软件的工具。在我看来编程语言不仅仅是工具更是思想的集合时代的缩影。编程语言的发展跟随计算机的发展一路走来其中蕴含着推动时代变革的解决不同问题的思想。 编程语言背后都有共同的东西比如计算机基础和其他领域知识。这些是可以在不同语言之间迁移的知识只需要学一遍。但是编程语言的设计思想却是不同的这就是编程语言吸引人的地方之一。就像同样都叫威士忌可能会有不同的味道。
编程语言如何设计一般都和它想要解决的问题有关。而它想解决的问题通常都与语言创造者所处的时代和眼界有关。
C 语言的诞生是为了解决操作系统快速交付的难题背后是 70 年代操作系统的发展Cpp 语言的诞生是为了给 C 语言引入面向对象提升开发效率背后是 80 年代工业软件快速增长需求Python / Java 语言的诞生是为了让开发者专注于业务而非语言细节背后是 90 年代日益增长的 Web 开发需求。
随着互联网的高速发展2010 年编程语言领域迎来一个拐点Rust 语言之父 Graydon 认为未来互联网应该是安全和性能并重所以他集过去四十年众语言优势为一体创造了 Rust 语言。到了 2022 年 Mojo 语言作者 Chris 认为 AI 基础设施生态的碎片化已经阻碍了 AI 的发展所以他创造 Mojo 语言想一统 AI 生态解决碎片化问题实现 All in One 理想。
回顾历史我们看得出来。时代在不断变化编程语言是推动时代齿轮的抓手。当新的时代到来时有些语言是必须要学习的。让我们从 Rust 和 Mojo 语言的特性、生态和其在 LLM 大模型时代的角色来探索这两门语言的未来。
Rust vs Mojo 雄心与现状
Rust
Rust语言之父 Graydon 带着内存安全和性能并重的设计初衷于 2009 年创立了 Rust 语言幸运的是这颗种子是种在了 Mozilla 这片开放的土壤中在 2015 年结出了开放的花朵。
Rust 语言并不是要百分百地解决内存安全问题而是消除过去五十年导致系统编程语言中 70% 安全 Bug 中的内存安全问题
引用空指针。使用未初始化内存。释放后使用即悬垂指针。缓冲区溢出比如数组越界。非法释放已释放过或未分配的内存。并发场景下的数据竞争。
为了达成此目标语言设计需要在六个原则中进行权衡
可靠性代码编译即正确。高性能代码执行效率可以媲美 C/Cpp。支持性为用户提供多方面支持比如 IDE、用户友好的编译错误信息等。生产力让开发更有效率事半功倍。透明性让用户对底层资源具有透明控制力。多样性多个领域都可以用 Rust 。
Rust 语言是在这些原则中权衡的结果客观情况无法做到同时满足这六大原则。所以导致的问题就是学习曲线较其他语言更高对学习和使用者的基础有一定的要求。
因为 Rust 语言面对的这个问题领域本身就非常复杂。从 Rust 语言架构层面来看Rust 语言为了解决内存安全和高性能并重的问题给出的方案其实非常简洁。 首先Rust 语言是一门编译语言。Rustc 是其编译前端在编译过程中通过精心设计的类型系统通过对代码中类型的检查来实现对内存安全进行管理以及更好地优化代码。编译后端包括 LLVM 和 Cranelift以及正在支持的 GCC 后端和 SPIR-V GPU IR。
其次在类型系统之上Rust 语言也提供了更高级的抽象范式支持面向对象风格和函数式编程风格甚至可以直接向写 C 那样遵循过程式范式。并且引入了很多现代化语言特性比如 trait 和 enum 允许开发者易于编写出更具可扩展性的系统。
从 2015 年 Rust 1.0 稳定版发布到写本文之时 2023 年 9 月Rust 已经发布了 72 个语义化版本三个 Edition 版次每三年发布一次的大版本。在 Stackoverflow 的年度调研报告中Rust 连续八年收获最受欢迎语言称号。
一门语言最重要的就是其生态。截止目前crates.io 上面 crate 数量已经超 12 万下载量已达到 393 亿次。虽然Rust 学习曲线较高但也没有阻碍生态的发展。 并且其生态从 2020 年起每年下载量以 1.7 倍速度增长。 并且其生态基本能覆盖到 C/Cpp/Java/Go 等语言的应用领域。 截止今年Rust 语言已经证明了其在系统编程领域的优势。曾经流行的 Rewrite it in Rust 梗已经变为了现实目前能用 Rust 重写的基本都已经用 Rust 重写了。包括一些新的系统Rust 也是第一选择。这里说的系统目前是指基础设施领域的系统包括 AI 基础设施。
Mojo 语言
据 Mojo 官方声称Chris 在 2022 年创建 Modular 公司时并未打算创造 Mojo 语言。他们在构建下一代推理引擎 Modular 时发现整个技术栈的编程模型过于复杂并且手动编写了大量的 MLIR开发效率极低。因此他们萌生了创建新的编程语言来统一整个技术栈的想法Mojo 就诞生了。
Mojo 想要的是一种创新且可扩展的编程模型能够针对在人工智能领域中普遍存在的加速器和其他异构系统进行编程。这意味 Mojo 要成为一种具有强大的编译时元编程能力、集成自适应编译技术、在整个编译流程中进行缓存以及其他现有语言不支持的功能的编程语言。
从 Mojo 语言架构层面来看Mojo 如何解决这个问题 首先Mojo 的语法兼容了 Python 语法。因为 AI 生态中 Python 库占据生态位想要一统天下必须坐拥 Python。曾经 Chris 在 Apple 就有过类似经历Swift 可以与 ObjectiveC 的库混编用了五年时间完成了语言之间的过渡。
$ cat hello.
def main():print(hello world)for x in range(9, 0, -3):print(x)
$ mojo hello.
hello world
9
6
3
$语法虽然与 Python 相似但是 Mojo 的 def 定义中允许强类型检查因为 Mojo 是 Python 的超集。
struct MyPair:var first: Intvar second: Int# We use fn instead of def here - well explain that soonfn __init__(inout self, first: Int, second: Int):self.first firstself.second secondfn __lt__(self, rhs: MyPair) - Bool:return self.first rhs.first or(self.first rhs.first andself.second rhs.second)看上去像不像 Rust 代码更准确来说是披着 Python 皮的 Rust 。从这一点来看Chris 也许也很喜欢 Rust 的设计否则不会借鉴。
话说回来Mojo 提供了 fn 相比 def 具有更加严格的检查适合于系统编程。而 struct 的结构和内容是预先设置的在程序运行时无法更改。与 Python 不同你无法在运行过程中随意添加、删除或更改对象的属性。Mojo 不允许这样做。Mojo 支持 AOT 和 JIT 两种方式。
在 Mojo 语法之下是 MLIR。
MLIR即 Multi-Level IR是一种可扩展的中间表示IR格式用于编译器设计。许多不同的编程语言和编译器将其源程序转换为 MLIR因为 Mojo 提供了对 MLIR 功能的直接访问这意味着 Mojo 程序可以享受到这些工具的好处。
Mojo 可以使用 MLIR 自定义类型。比如使用 Mojo 的 struct 关键字来定义一个新的类型 OurBool
struct OurBool:var value: __mlir_type.i1fn __init__(inout self):self.value __mlir_op.index.bool.constant[value : __mlir_attr.false,]()一个布尔值可以表示 0 或 1true 或 false。为了存储这个信息 OurBool 有一个单一成员称为 value 。它的类型使用 MLIR 内置类型 i1 。实际上在 Mojo 中可以使用任何 MLIR 类型只需在类型名称前加上 __mlir_type 。
为了初始化底层的 i1 值我们使用了来自 index 方言的 MLIR 算子称为 index.bool.constant 。
let a OurBool()
# error: OurBool does not implement the __copyinit__ method
let b a创建一个 a 然后将其赋值给 b则会报错。因为 Mojo 语言中默认为 值语义OurBool 并未实现 copyinit 方法所以无法复制。
register_passable(trivial)
struct OurBool:var value: __mlir_type.i1fn __init__() - Self:return Self {value: __mlir_op.index.bool.constant[value : __mlir_attr.false,]()}通过为结构体增加装饰器 register_passable(“trivial”) 就可以复制其实例变量了。trivial 代表是“平凡的”或“平平无奇的”简单值可以安全复制。这里有点类似于 Rust 语言的复制语义。
MLIR 是模块化和可扩展的。MLIR 由越来越多的“方言Dialects”组成。每个方言定义了算子Operation和优化例如“math”方言提供了诸如正弦和余弦等数学操作“amdgpu”方言提供了针对 AMD 处理器的特定操作等等。方言经过降级之后Mojo 代码将被编译到指定平台的机器指令。
MLIR 的每个方言都可以互操作。这就是为什么说 MLIR 可以解锁异构计算的原因。随着新的、更快的处理器和架构的开发新的 MLIR 方言被实现以生成适用于这些环境的最优代码。任何新的 MLIR 方言都可以无缝地转换为其他方言因此随着更多方言的添加所有现有的 MLIR 都变得更加强大。
利用 MLIR 这种特性就实现了底层异构系统大统一。这就是 Mojo 解决问题的方式。
Rust vs Mojo : 对立还是融合
Mojo 官方观点
七月份Modular 官方博客发布标题为《未来的人工智能的语言是 Rust 还是 Mojo 》的一篇文章。其中谈到 Rust 的语言特性在 AI 领域相比于 Python 和 Cpp 是一门更好的语言这是一种认可。但是因为 Rust 语言是从零开始设计其在 AI 领域的生态位还相当年轻不如 Python 和 Cpp 。虽然生态中有一些 Rust 绑定库比如 OpenCV-rust 或者 libonnxruntime 的绑定 ort 都是独立贡献者维护的从 2019 年到现在进展不大。虽然现在也有更好的 Rust 实现比如 tract-onnx 但是缺乏贡献者和运营者进展缓慢。并且声称绝大多数人工智能研究人员都是使用 Python而且对学习 Rust 不感兴趣因此很不可能在机器学习领域得到广泛应用。
反观 Mojo 可以复用任何一个 Python 库。并且在语法上兼容 Python 会受到广大人工智能研究人员的喜爱。除此之外Mojo 也能简化当前 Python Cpp 的麻烦比如如果想加速代码可能还得学习如何在 C 中使用 SIMD 指令集作为备选方案等。官方给出了一个用 Mojo 做快速均值模糊 (Box Blur) 的示例。其中用到了 MLIR 提供的 SIMD 功能和 自己编写的用于将表示地址的 Python 整数转换为具有给定数据类型的 Mojo 指针的功能代码如下。
from DType import DType
from Pointer import DTypePointerfn numpy_data_pointer(numpy_array: PythonObject) raises - DTypePointer[DType.uint32]:return DTypePointer[DType.uint32](__mlir_op.pop.index_to_pointer[_type:__mlir_type.!pop.pointerscalarui32](SIMD[DType.index,1](numpy_array.__array_interface__[data][0].__index__( DType.index,1)).value))其中pop 是 Modular 团队开发的 MLIR 方言。它并不是为了普通程序员需要理解这个语法随着时间的推移有用的东西将会被编译器工程师封装成一个漂亮的 API供系统工程师和 Python 程序员未来的 Mojo 程序员在更高的层次上使用。但开发者仍然有能力定义自己的方言或使用 MLIR 生态系统中已经定义好的方言之一这使得供应商可以轻松加速他们的硬件例如 gpu 方言 [6] 。
以上是 Mojo 官方的观点。总结为一句话就是Rust 很好但其生态位不足Mojo 才是 AI 的未来。
Mojo 官方忽略的问题大模型时代开启资本推动与时间差
Mojo 官方提供的观点论据都很足很有道理。但是我认为官方忽视了一个重要问题一门语言成熟所需的周期。
虽然 MLIR 功能强大极具潜力但 Mojo 语言当前还是一个小火苗。它还需要很长时间来兑现它的承诺安全、高性能、像 Python 一样简单易用。Rust 语言从发布到成熟花了八年Go 语言十三年Swift 差不多也是八年。那么 Mojo 语言需要几年呢
从上面官方给出的各种示例中发现Mojo 标准库目前还未建立如果用 Mojo 开发还需要开发者懂 MLIR 各种方言这学习曲线也许比 Rust 更高一个量级。难道这就是 Python 开发者喜欢的
Mojo 语言目前只被用于其母公司产品 Modular 推理引擎的开发中。从小道消息处得知有些 AI 公司也已经投入了 Mojo 的前期培训。
而 Rust 语言2023 年之前确实在 AI 生态上进展缓慢但今年大语言模型时代开启资本大量涌入 AI 生态。在 Mojo 兑现承诺的这段时间差中Rust 语言极有可能在 AI 生态中占据一席之地。
因为据我观察2023 年 AI 领域的一些独角兽已经开始采用 Rust 了。
Rust 的 AI 生态位
我们简单盘点一下当前 Rust 在 AI 领域的生态位。 AI 领域涉及模型训练、模型部署、到智能应用这一系列流程。在这整个流程过程中都能看到 Rust 语言的影子。我们简单将其分为下面五类
高性能数据分析深度学习框架及其依赖推理引擎开源大模型大模型应用相关基础设施
高性能数据分析
Polars 在数据操作层面每个人都喜欢 Pandas 的 API。它快速、简单且有据可查。但在生产方面Pandas 有点棘手。Pandas 不能很好地扩展……没有多线程……它不是线程安全的……它不是内存效率。这一切都是 Rust 存在的理由。
Polars用 Rust 实现的新 Dataframe 库具有方便的 Python 绑定。它试图做到以线程安全的方式进行读取、写入、过滤、应用函数、分组和合并。Polars 建立在 Apache Arrow 规范的 安全 Arrow2 实现之上 可实现高效的资源使用和处理性能。它还可以与 Arrow 生态系统中的其他工具无缝集成。
Polars 有两个优势
它是性能杀手参考 db-benchmark。它的 API 非常简单。哪怕不懂 Rust 语法也能看懂该接口要做什么。
也有三个缺点
构建 Dataframe API 很困难Pandas 花了 12 年才达到 1.0.0而 Polars 很年轻所以目前还不够成熟。使用它的时候不仅仅要熟悉 Polars API还需要熟悉 Arrow API因为很多繁重工作是 arrow 来完成的。编译时间太慢可能需要 6 分钟左右。
Polars 现在主要由 Xomnia公司赞助。Xomnia 是荷兰一家人工智能公司在研究自动驾驶船只被人称为水上特斯拉。
Linfa 是一组 Rust 高级库的集合提供了常用的数据处理方法和机器学习算法。Linfa 对标 Python 上的 scikit-learn专注于日常机器学习任务常用的预处理任务和经典机器学习算法目前 Linfa 已经实现了 scikit-learn 中的全部算法这些算法按算法类型组织在各子包中。
目前 Linfa 的中期 Roadmap[13] 距离与 Python 的 scikit-learn 目前可用的 ML 算法和预处理程序相媲美的实现的最终目标。
深度学习框架及其依赖
candle
candle是 AI 独角兽 HuggingFace 出品的专注于性能包括 GPU 支持和易用性的 Rust 极简机器学习框架。
candle 框架的特点是
语法简单看起来和使用起来都像 PyTorch。多后端支持。优化的 CPU 后端可选支持 x86 的 MKL 和 mac 的 AccelerateCUDA 后端以高效地在 GPU 上运行通过 NCCL 实现多 GPU 分布。WASM 支持允许在浏览器中运行模型。多模型支持。LLMs: LLaMA v1 和 v2FalconStarCoder。Whisper多语言支持。Stable Diffusion。计算机视觉DINOv2EfficientNetyolo-v3yolo-v8。支持从 safetensors、npz、ggml 或 PyTorch 文件中加载模型支持在 CPU 上 Serverless 部署使用 llama.cpp 的量化类型来支持量化
Candle 的核心目标是实现无服务器推理。像 PyTorch 这样的完整机器学习框架非常庞大这使得在集群上创建实例变得缓慢。Candle 允许部署轻量级二进制文件。
HuggingFace 其他 Rust 开源库
safetensors安全存储和分发张量tensor并且是高性能零拷贝。该库主要是为了消除默认情况下使用的 pickle 的需要因为 pickle 是不安全的有运行任意代码风险。
Burn
Burn是一款开源的致力于成为全面的深度学习框架。它提供卓越的灵活性并且使用 Rust 语言实现。目标是通过简化实验、训练和部署模型的过程为研究人员和实践者提供服务。
Burn 的进展非常快目前已经发布 0.9 版本。它的特点是
可定制、直观且用户友好的神经网络模块。全面的训练工具包括 metrics 、 logging 和 checkpointing。
多功能的张量可插拔的后端工具箱
Torch[20] 后端支持 CPU 和 GPUNdarray[21] 后端与 no_std 兼容性确保了通用平台的适应性WebGPU[22] 后端提供跨平台、包含浏览器的基于 GPU 的计算Candle[23] 后端。Autodiff[24] 自动微分后端。Dataset[25] 包含各种实用工具和资源的容器。Import[26] 是用于导入一个简化预训练模型集成的包。
社区也有第三方基于 Burn 实现了开源大模型
stable-diffusion-burn[28] 将 Stable Diffusion v1.4 移植到 Burn 框架中。stable-diffusion-xl-burn[29] 将 stable diffusion xl 移植到 Rust 深度学习框架 burn 中。llama2-burn[30] 将 Meta 的大型语言模型 Llama2 移植到 Rust 深度学习框架 Burn 上。whisper-burn[31]是使用 Rust 深度学习框架 Burn 实现的 OpenAI Whisper 转录模型的 Rust 版本。
其他框架
tch-rs[32] 是 Pytorch 的 Cpp API 的 Rust 绑定目前正在活跃维护中。
tensorflow-rs[33] 是 Tensorflow 官方提供的 Rust 绑定目前正在活跃维护中。
dfdx[34]是一个强大的 crate其中包含了类型中的形状。这样一来编译器就可以立即检测到形状不匹配的问题从而避免了很多麻烦。
自动微分器 EnzymeAD Rust 前端
Enzyme[35] 是 MIT 提出的自动微分框架用于对可静态分析的 LLVM 和 MLIR 进行自动微分。当前PyTorch、TensorFlow 等机器学习框架已经成为了人们开发的重要工具。计算反向传播、贝叶斯推理、不确定性量化和概率编程等算法的梯度时我们需要把所有的代码以微分型写入框架内。这对于将机器学习引入新领域带来了问题在物理模拟、游戏引擎、气候模型中原领域组件不是由机器学习框架的特定领域语言DSL编写的。因此在将机器学习引入科学计算时重写需求成为了一个挑战。
为了解决这一问题现在的发展趋势包含构建新的 DSL让重写过程变得简单或者在编程时直接进行构建。这些方法可以让我们获得有效的梯度但是仍然需要使用 DSL 或可微分的编程语言进行重写。为了方便开发者来自 MIT 的研究者开源了 Enzyme。
目前Enzyme 团队 fork Rust 语言项目开始实施 EnzymeAD Rust 前端 [36] 工作正在进行中。
依赖的基础库
pyo3[37] 主要用于创建原生 Python 的扩展模块。PyO3 还支持从 Rust 二进制文件运行 Python 代码并与之交互可以实现 Rust 与 Python 代码共存。因此pyo3 是 Rust 和 AI 生态中的 Python 库交互必不可少的依赖库。目前 pyo3 维护非常活跃。
llm[38] 是一个用于处理大型语言模型的 Rust 库生态系统 - 它是基于快速高效的 GGML[39] 机器学习库构建的。llm 由 ggml 张量库提供支持旨在将 Rust 的稳健性和易用性带入大型语言模型的世界。目前推理仅在 CPU 上进行但后续希望通过备用后端在将来支持 GPU 推理。
推理引擎
tract为嵌入式而生的推理引擎
Sonos[40] 是一款家庭智能音箱该公司开源了一款 Rust 实现的推理引擎 tract[41] 。tract 的设计是为了在小型嵌入式 CPU 上运行神经网络。
AI 大模型时代算力是一个很大的问题。目前 AI 基本是被部署到云端推理在云端完成用户数据将被发送到云端经过模型处理后结果将被发送回终端用户的设备。有时候使用云服务并不是一个好的选择。自动驾驶汽车不能在进入隧道时停止行驶。当世界另一边的数据中心出现问题时人们不应该被锁在家外面。而且我们中的一些人只愿意与自己拥有的设备进行交互而不是与那个神秘的云共享生活的一部分。所以AI 芯片通常分为三个关键应用领域云端训练、云端推理和边缘推理。
边缘推理场景下大模型可以在消费级终端上面进行推理包括 HuggingFace 开源的 candle 也是为了边缘计算。这背后有个大的目标就是万物大模型。
tract 架构背景
模型训练和推理是两个独立过程。训练模型是一项艰巨且复杂的任务而推理则相对简单。模型设计和训练也是该领域大部分研究的重点。
在模型设计和训练过程中机器学习团队注重预测的准确性。虽然整体计算预算是一个已知的限制条件但目标是找出最佳的模型设计和训练过程以获得最佳的准确性。
在推理过程中效率至关重要。模型和硬件在这个阶段是固定的实体问题是尽可能高效地使给定的模型在给定的硬件上运行。首先要适应硬件然后尽可能释放更多资源以供未来的发展使用。
一旦网络训练完成并冻结训练的相关性就消失了。随之而来的是许多对模型设计和训练有用的抽象变得多余当执行两个值的乘法时CPU 并不太关心这个操作属于哪个高级神经网络概念比如卷积或者归一化层。
当今 AI 生态中 ONNX Open Neural Network eXchange非常重要ONNX 构建了一个开放的生态系统它使人工智能开发人员在推进项目时选择合适的工具不用被框架或者生态系统所束缚。这种针对机器学习所设计的开放式的文件格式用于存储训练好的模型得不同的人工智能框架如 Pytorch、MXNet可以采用相同格式存储模型数据并交互。
但 ONNX 仍然非常注重模型设计和训练。从推理引擎实现的角度来看它仍然包含许多冗余的运算符。2017 年由开源组织 Khronos Group 制定的 NNEF 神经网络交换标准则使用了一个更低级的表示其中训练语义被抹去了。
NNEF 格式对于推理目的来说几乎是理想的但该格式并不够主流大多数软件集成商希望能够直接支持 ONNX 或 TensorFlow。所以tract 引入了 tract-opl它在语义上与 NNEF 非常接近专注于简单操作而不考虑 ONNX 和 TensorFlow 格式编码的高级训练特性。它被设计为一组 NNEF 扩展如果模型不使用 NNEF 不包含的任何特性或运算符tract 实际上可以将 tract-opl 序列化为纯 NNEF。这也意味着 tract 可以从 ONNX 和 TensorFlow 转换为 NNEF。 模型推理是计算密集型的任务。神经网络背后都会涉及到卷积和矩阵运算。tract 为了提供高性能和跨平台利用 Rust 和 SIMD以及内联汇编技术来优化卷积和矩阵运算。比如自 2014 年至今移动 SoCs 最广泛使用的 CPU 架构 Cortex-A53以及 苹果 M1 采用的 ARMv8 芯片如果想充分利用这类芯片的性能则需要汇编的加持。
目前 tract 还算是 Rust AI 生态中比较流行的推理引擎该框架也处于积极维护中。
开源大模型
LLama2 Rust 今年 7 月份杨立昆在 X 上转发了来自 Sasha Rush 的开源大模型 LLama2 的纯 Rust 实现[42] 。 而 Sasha Rush 是 HuggingFace 的工程师。看来 HuggingFace 内部对于 Rust 语言很是喜欢。 llama2.rs 的目标是在 CPU 上进行推理这样的好处就是想要部署开源大模型的公司不必要专门去寻找包括 GPU 的机器了也算是降本增效吧
商业大模型 Deepgram[43] 是一家基础人工智能公司提供语音转文本和语言理解能力使数据能够被人类或机器读取和应用。Deepgram 是人类语音识别领域真正的专家。该服务使用先进的技术将音频文件无缝转换为文本。这家自然语言处理公司提供使用该服务转换电话、会议等的选项。所有这些都可以使公司的工作变得更加简单。去年年底完成 7200 万美元 B 轮融资。
去年 Deepgram 发布了一篇官方博客文章 介绍了其平台为何使用 Rust 重写 [44] 。Deepgram 的语音搜索 AI 大脑神经语音引擎 V4 版用 Rust 进行了重写前三个版本都是 Python 实现的。
Rust 重写之后为他们解决了下列问题
内存占用极大地降低了。可以放心地引入并发解决了 CPU 和 GPU 的性能瓶颈。在这之前因为音频识别领域需要靠 CPU 处理很多前置工作比如解码之类之前用 Python 导致 CPU 的性能跟不上 GPU 而导致了性能瓶颈。用了 Rust 之后可以放心地使用并发并期待 GPU 成为瓶颈了。让开发人员专注于业务而非把时间浪费在改 Bug 找 Bug 。
大模型应用相关基础设施
BlindAI : 快速且注重隐私的 Rust AI 部署解决方案
如今大多数人工智能工具都没有隐私保护机制因此当数据被发送给第三方进行分析时数据就会暴露在恶意使用或潜在泄露的风险之中。比如使用 AI 语音助手时音频录音经常被发送到云端进行分析这样会导致对话内容暴露在外被未经用户知情或同意的情况下进行泄露和未受控制的使用。尽管可以通过 TLS 安全地发送数据但在其中一些利益相关者的环节中仍然有可能被看到和暴露数据租用机器的人工智能公司、云服务提供商或恶意内部人员。
BlindAI [45] 是一个利用安全隔离技术的 AI 部署解决方案使远程托管的 AI 模型更加注重隐私保护。利用 tract[46] 项目作为推理引擎在隔离环境中提供 ONNX 格式的 AI 模型服务。还使用 Rust SGX SDK[47] 在安全隔离环境中使用 Rust 语言。用户可以从云中的 AI 模型中受益而无需向 AI 提供商或云提供商披露其明文数据。
bastionlab[48] 提供一个简单的隐私框架用于数据科学协作涵盖数据探索和人工智能训练。允许数据所有者和数据科学家可以在不暴露数据的情况下安全地合作为那些过于冒险而不敢考虑的项目铺平道路。项目使用 Polars 进行数据探索还使用了 Torchtch-rs 这是一个流行的用于 AI 训练的库。
其主公司 Mithril Security 目前处于 Pre Seed 融资120 万欧元。
向量数据库
商业向量数据库 Pinecone 向量数据库随着大语言模型时代的开启而迅速走上风口 Pinecone 则属于向量数据库行业内的独角兽。
Pinecone 虽然是闭源产品但其在官方博客和 Rust 社区活动中都有相关的技术输出。就在去年年底官方博客发表一篇文章《用 Rust 重写一个高性能的向量数据库》[49] 其中记录了 Pinecone 从 Python Cpp 到 Rust 重写的心路历程。
Pinecone 在 Python Cpp 的版本下经常会遇到性能问题但是却很难找到同时具备 Python 和 C 经验的开发人员来解决这些问题。所以 Pinecone 就用 Rust 重写了整个数据库。2023 年 4 月Pinecone 拿到了 1 亿美元 B 轮融资。
虽然 Pinecone 用 Rust 重写了整个数据库但并不意味着他们可以摆脱 Python 毕竟 Python 是 AI 应用场景中占主导地位的语言 。就在前几天Pinecone 工程师发文吐槽《 Python 的痛苦与诗意》[50] 并指明期待 Mojo 语言的到来。文中痛斥了 Python 项目的打包、测试、分发和测试工具生态系统并使用 Poetry 来管理 Pinecone Python 客户端可以使用它来创建、更新和查询 Pinecone 向量数据库索引因为他们认为它对 Pinecone 的内部维护人员、客户和社区贡献者提供了最多的好处。
开源向量数据库
Qdrant 是一个向量数据库和向量相似度搜索引擎。Qdrant 是目前唯一一个纯 Rust 实现的开源向量数据库。
向量数据库作为大语言模型的「长期记忆」能力当下很火。qdrant 目前融资 750 万美元种子轮。
传统数据库可以通过添加向量存储和向量搜索来提供向量数据库的功能但是面对海量数据量想要平衡向量搜索的准确度和性能还需要专门的向量数据库。Qdrant 商业开源和 Pinecone 商业闭源就是专业的向量数据库。从 Qdrant 的实现看出其在向量内存占用优化和向量海量搜索算法上下了不少功夫。内存占用优化使用 Product Quantization(乘积量化) 技术使用 K-Means 聚类算法来平衡准确性和搜索性能。
开源 AI Agent
Chidor 也许是一个 LangChain 的替代品同样可以方便的构建 AI Agent主要优势是反应式编程。由 Rust 开发能支持 Python、Nodejs 和 Rust 构建 Agent。它目前处于 alpha 阶段尚未准备好投入生产使用。以下是它的一些特点
从头开始构建代理运行时由 Rust 编写开箱即支持 Python 和 Node.js构建可实际运行的代理LLM 缓存可最大限度地降低开发成本针对长时间运行的人工智能工作流进行了优化嵌入式代码解释器支持时间旅行调试
Chidori 是专注于 LLM 代码执行的具体操作方式而不是提供特定的提示组合。其他框架没有关注这个领域而这是一个重要的领域。Chidori 减少了构建长时间运行代理系统时的意外复杂性这有助于开发人员构建成功的系统。
Chidori 是 火影忍者中卡卡西忍术的名称 它在日语中得名称是 Thousand Birds千鸟而千鸟是指一群鸟或称为鸟群以及由它们之间的互动产生的群体行为。千鸟是对长时间运行的代理人行为、它们内部执行的 LLM 单元以及由它们之间的互动产生的群体行为的一个很好的类比。
llm-chain[53] 提供了一组 Rust crate帮助开发者创建高级的 LLM 应用程序如聊天机器人、代理等等。作为一个全面的 LLM-Ops 平台对云端和本地托管的 LLM 都有强大的支持。还提供强大的支持包括提示模板和多步骤链式提示的链接使得在单个步骤中无法处理的复杂任务成为可能。还提供向量存储集成使用户的模型能够轻松获得长期记忆和专业知识。允许开发者构建复杂的应用程序。
infino[54]是 Rust 实现的一个可观测性平台用于大规模存储指标和日志并以更低的成本实现。可以集成到不同平台中尤其是用于大模型相关基础设施和应用的可观测性。
四、总结
Rust 语言发布后经过八年的发展已经成为当下系统编程语言的最佳选择目前常用于构建基础设施包括 AI 基础设施。
Mojo 语言在 AI 领域极具潜力但目前还未成熟还需要很长时间来给开发者兑现承诺。
大模型时代开启商业竞争激烈资本推动下Rust 将在 Mojo 成长的这段时间差内抢占一定比例的 AI 生态位。而 Mojo 目前唯一的应用很可能只是 Modular 推理引擎这个状态和 Rust 早期与 Servo 浏览器内核共同演进的历史非常相似。
所以短期内 Rust 和 Mojo 在各自适合的场景内逐渐发展。长期来看Mojo 如果发展的好就可以顺利地将 Python 生态过渡到 Mojo 从而抢占一定的 AI 生态位。Mojo 还有一个更大的野心就是也想成为通用语言。如果 Mojo 成熟到一定地步那么会和 Rust 产生竞争毕竟 Mojo 的语法相比 Rust 更好上手但学习曲线不一定更低。在被 Rust 抢占的 AI 生态位Mojo 也会与 Rust 进行交互融合。
以上就是我对于大模型时代编程语言的一些观点不知道读者您有什么看法欢迎留言讨论。