为什么埃隆·马斯克说Rust是AGI的语言?
大喵点评:本文作者的观点不代表我的观点,另有人视频里指出Mojo比Python快 35000倍的测评有失偏颇。请见👇视频。
但,本篇的价值在于
以及为什么WasmEdge是AGI采用Rust的关键路径上的一部分!
更新:零Python依赖、可移植和超快的llama2运行时已经发布!由Rust编写并在WasmEdge上运行。观看演示视频并查找下面的源代码存储库。
为什么不使用Python?
今天的LLM应用程序,包括推理应用程序和代理,大多数都是用Python编写的。但这即将发生改变。
Python太慢、太臃肿,而且矛盾地对于新一波开发者来说太难掌握。事实上,LLVM、Clang和Swift的发明者Chris Lattner曾经证明,Python可能比编译语言慢35,000倍,这就是他发明Mojo语言作为Python替代品的原因。
根据Chris Lattner的说法,编译语言可能比Python快35,000倍(大喵质疑数值,恰好有人也只出测评存在的问题,见本文篇首的视频)。
迫使开发者将越来越多的应用程序逻辑推向本机编译代码,例如C、C++和Rust。例如,像llama.cpp、whisper.cpp和llama2.c这样的非常流行的项目都没有Python依赖。
Greg Brockman是OpenAI的联合创始人和总裁。他也认为Python太慢了。
这反过来降低了Python开发者的体验。事实上,为了云部署而管理Python安装已经成为一项重大挑战。
Chris Albon是维基媒体的机器学习主任。他甚至也难以理解“现代”Python。 换句话说,Python不仅非常慢,而且在开发LLM应用程序方面也难以使用。
请参考Python安装的关键细节:
https://blog.jeremarc.com/posts/python-env/
Textual
是一个用于Python的快速应用程序开发框架。它提供了一个简单的Python API,可用于构建复杂的用户界面,并在终端和(即将推出的)Web浏览器中运行应用程序。
https://github.com/Textualize/textual
Textual通过受现代Web开发启发的API为Rich添加了交互性,支持现代终端软件,可使用1670万种颜色、鼠标支持和流畅的无闪烁动画。
它还具备强大的布局引擎和可重复使用的组件,使您可以构建媲美桌面和Web体验的应用程序。
Textual兼容Linux、macOS和Windows,要安装它,可以使用pip命令。
此外,Textual还提供示例和文档,以帮助开发人员入门,同时欢迎加入它们的Discord社区。此外,Textual还提供了一些参考命令,用于预览其样式、动画和颜色设计系统。
例如:计算器的UI
from decimal import Decimalfrom textual import events, on
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.css.query import NoMatches
from textual.reactive import var
from textual.widgets import Button, Digitsclass CalculatorApp(App):"""A working 'desktop' calculator."""CSS_PATH = "calculator.tcss"numbers = var("0")show_ac = var(True)left = var(Decimal("0"))right = var(Decimal("0"))value = var("")operator = var("plus")NAME_MAP = {"asterisk": "multiply","slash": "divide","underscore": "plus-minus","full_stop": "point","plus_minus_sign": "plus-minus","percent_sign": "percent","equals_sign": "equals","minus": "minus","plus": "plus",}def watch_numbers(self, value: str) -> None:"""Called when numbers is updated."""self.query_one("#numbers", Digits).update(value)def compute_show_ac(self) -> bool:"""Compute switch to show AC or C button"""return self.value in ("", "0") and self.numbers == "0"def watch_show_ac(self, show_ac: bool) -> None:"""Called when show_ac changes."""self.query_one("#c").display = not show_acself.query_one("#ac").display = show_acdef compose(self) -> ComposeResult:"""Add our buttons."""with Container(id="calculator"):yield Digits(id="numbers")yield Button("AC", id="ac", variant="primary")yield Button("C", id="c", variant="primary")yield Button("+/-", id="plus-minus", variant="primary")yield Button("%", id="percent", variant="primary")yield Button("÷", id="divide", variant="warning")yield Button("7", id="number-7", classes="number")yield Button("8", id="number-8", classes="number")yield Button("9", id="number-9", classes="number")yield Button("×", id="multiply", variant="warning")yield Button("4", id="number-4", classes="number")yield Button("5", id="number-5", classes="number")yield Button("6", id="number-6", classes="number")yield Button("-", id="minus", variant="warning")yield Button("1", id="number-1", classes="number")yield Button("2", id="number-2", classes="number")yield Button("3", id="number-3", classes="number")yield Button("+", id="plus", variant="warning")yield Button("0", id="number-0", classes="number")yield Button(".", id="point")yield Button("=", id="equals", variant="warning")def on_key(self, event: events.Key) -> None:"""Called when the user presses a key."""def press(button_id: str) -> None:"""Press a button, should it exist."""try:self.query_one(f"#{button_id}", Button).press()except NoMatches:passkey = event.keyif key.isdecimal():press(f"number-{key}")elif key == "c":press("c")press("ac")else:button_id = self.NAME_MAP.get(key)if button_id is not None:press(self.NAME_MAP.get(key, key))@on(Button.Pressed, ".number")def number_pressed(self, event: Button.Pressed) -> None:"""Pressed a number."""assert event.button.id is not Nonenumber = event.button.id.partition("-")[-1]self.numbers = self.value = self.value.lstrip("0") + number@on(Button.Pressed, "#plus-minus")def plus_minus_pressed(self) -> None:"""Pressed + / -"""self.numbers = self.value = str(Decimal(self.value or "0") * -1)@on(Button.Pressed, "#percent")def percent_pressed(self) -> None:"""Pressed %"""self.numbers = self.value = str(Decimal(self.value or "0") / Decimal(100))@on(Button.Pressed, "#point")def pressed_point(self) -> None:"""Pressed ."""if "." not in self.value:self.numbers = self.value = (self.value or "0") + "."@on(Button.Pressed, "#ac")def pressed_ac(self) -> None:"""Pressed AC"""self.value = ""self.left = self.right = Decimal(0)self.operator = "plus"self.numbers = "0"@on(Button.Pressed, "#c")def pressed_c(self) -> None:"""Pressed C"""self.value = ""self.numbers = "0"def _do_math(self) -> None:"""Does the math: LEFT OPERATOR RIGHT"""try:if self.operator == "plus":self.left += self.rightelif self.operator == "minus":self.left -= self.rightelif self.operator == "divide":self.left /= self.rightelif self.operator == "multiply":self.left *= self.rightself.numbers = str(self.left)self.value = ""except Exception:self.numbers = "Error"@on(Button.Pressed, "#plus,#minus,#divide,#multiply")def pressed_op(self, event: Button.Pressed) -> None:"""Pressed one of the arithmetic operations."""self.right = Decimal(self.value or "0")self._do_math()assert event.button.id is not Noneself.operator = event.button.id@on(Button.Pressed, "#equals")def pressed_equals(self) -> None:"""Pressed ="""if self.value:self.right = Decimal(self.value)self._do_math()if __name__ == "__main__":CalculatorApp().run()
Reference Case
Rust!
Python的问题为高性能编译语言创造了机会。由于C和C++在一般开发者社区中失去了地位,Rust取得了突破。
埃隆·马斯克指出,Rust可能成为AGI的语言。
让这个事实沉淀下来!
Rust被StackOverflow连续七年评为最受喜爱的编程语言,其市场份额稳步增长。
Rust + Wasm 两者兼得
然而,将Rust直接编译成本机机器代码存在其他问题。
安全性。本机二进制文件可能会使整个系统崩溃。
可移植性。本机二进制文件特定于底层操作系统和硬件。
性能。由于安全性和可移植性要求,通常需要本机二进制文件在Linux容器内运行。
这种容器会为程序增加启动和运行时开销,显著降低性能。
Wasm已经成为Rust应用程序的主要安全运行时,以解决这些问题。有了面向云的优化Wasm运行时WasmEdge,开发者现在可以选择在LLM应用程序堆栈的每一层中使用高性能的Rust,作为Python的高性能替代品。
使用Rust + Wasm代替Python,以增强性能、减少占用空间,并提高安全性。
代理层:用于接收互联网事件、连接数据库和调用其他Web服务的网络密集型任务。
Rust和WasmEdge为高密度和高性能的代理应用程序提供异步和非阻塞I/O。示例:flows.network。
推理层:CPU密集型任务,用于将数据(例如单词和句子)预处理为数字,并将数字后处理为句子或结构化JSON数据。
这些功能可以用Rust编写,以实现最佳性能,并在WasmEdge中运行,以实现安全性和可移植性。示例:mediapipe-rs。
张量层:GPU密集型任务,通过WasmEdge的WASI-NN插件从Wasm传递给本机张量库,如llama.cpp、PyTorch和Tensorflow。
结论
Rust和Wasm可能是Python今天的高性能和开发者友好的替代品。
它们与底层GPU张量库更好地集成在一起,这些库也是用C/C++/Rust编写的。 在实现特定于应用程序的预处理和后处理数据函数方面,它们更有效率,这占据了推理工作负载的大部分。
在实现网络密集型和长时间运行的LLM代理所需的任务方面,它们更有效率。
它们的容器映像大小远远小于Python映像(几MB对几百MB)。
由于有限的软件供应链和减少的攻击面,它们比Python容器更安全。
它们更容易安装和管理依赖关系,而不像Python程序那样复杂。
资源
“顶端还有足够的空间:摩尔定律之后将推动计算机性能的是什么?”
MIT的Leiserson和Thompson等人的Science,2020年,第368卷,第6495期。它证明了Python可能比优化的C程序慢超过62,000倍。
作者预测,从Python到编译语言的大规模迁移将带来新的计算机革命。
Long、Tai、Hsieh和Yuan的“面向服务器无函数作为服务的轻量级设计”,IEEE Software,2021年,第38卷,第1期,第75-80页。
它演示了经过AOT优化的Wasm应用程序在启动和运行时都可以远远超过Linux容器应用程序。
WasmEdge的WASI-NN插件允许在WasmEdge中运行Pytorch和Tensorflow推理应用程序的Rust程序。
mediapipe-rs箱是一个供开发人员使用Google的mediapipe系列AI模型创建应用程序的Rust库。它可以编译并在WasmEdge中运行。
Yuan的“在WasmEdge中运行llama2.c”,Medium,2023年。它展示了如何在WasmEdge中运行llama2模型的完整推理应用程序。
flow.network是基于WasmEdge构建的LLM代理的无服务器平台。
https://stackademic.com/
感谢您阅读到最后。请考虑关注作者和本出版物。访问Stackademic,了解有关我们如何在全球普及免费编程教育的更多信息。