Python + Docker 还是 Rust + WebAssembly?
在不断发展的技术世界中,由大语言模型驱动的应用程序,通常被称为“LLM 应用”,已成为各种行业技术创新背后的驱动力。随着这些应用程序的普及,用户需求的大量涌入对底层基础设施的性能、安全性和可靠性提出了新的挑战。
Python 和 Docker 一直是构建机器学习应用程序的主流选择。然而,当涉及到为大型语言模型(LLM)应用程序构建基础设施时,这种组合的一些缺点变得更加严重,例如 Python 的性能问题和 Docker 的冷启动问题。本演讲重点关注为 LLM 生态构建基础设施的主要场景,并深入探讨 Python 和 Docker 组合的问题,更重要的是,为什么 Rust + WebAssembly (WASM) 优于 Python + Docker。最后,我们将演示如何在 flows.network 平台上构建一个代码检查机器人。
现有解决方案:Python + Docker 方法
在机器学习领域,Python 几乎称王,主要得益于以下三个特点:
-
易于学习: Python 是一种高级语言,语法简单,易于学习和使用。对于 AI 新手或需要快速原型设计和测试想法的开发者,这可能至关重要。
-
庞大的社区: Python 拥有庞大且活跃的开发者社区,这意味着有许多库和工具可用于 AI 开发。对于需要快速找到常见问题解决方案的开发者来说,这是个优势。
-
灵活性: Python 用途多样,可用于广泛的 AI 任务,包括数据分析、机器学习和自然语言处理。对于需要从事多个 AI 项目的开发者而言很有吸引力。
Docker 容器作为当今最流行的容器管理工具之一,为应用部署提供了极大的便利:
-
可移植性: Docker 容器被设计为可移植的,这意味着它们可以在不同环境之间轻松移动。对于需要将 AI 应用程序部署到多个平台或云提供商的开发者来说,这可能是一个优势。
-
隔离: Docker 容器在应用程序和主机操作系统之间提供了高度的隔离,可以提高安全性和稳定性。对于需要高级别安全性的组织来说,这可能是一个优势。
-
可扩展性: Docker 容器可以轻松扩展或缩小以满足不断变化的需求,这对于需要大量计算或需要处理大型数据集的 AI 应用程序来说是一个优势。
对于传统机器学习应用的开发和部署,Python+Docker 模式展现了其优势。然而,在 LLM 生态的基础设施建设中,却面临着挑战。
Python + Docker 的挑战
Python 和 Docker 的优点自然也带来了一些缺点。然而,在 LLM 生态基础设施建设的过程中,这些缺陷变得更加突出,成为关键障碍。让我们先看看 Python 存在的问题。
Python 的缺点
性能瓶颈
Python 是一种解释性语言,这意味着它可能比 C++ 或 Rust 等编译语言慢。当处理需要大量计算的大型数据集或复杂模型时,这可能是一个缺点。
在图 1 中,前三行分别显示了用 Python、Java 和 C 编写的将两个 4096 x 4096 矩阵相乘的编程性能。从“运行时间(秒)”一栏的统计数据可以看出,(1)Java(作为静态编程语言)比 Python(作为动态编程语言)快 10 倍;(2) C(作为非 GC 编程语言)比 Python(作为 GC 编程语言)快 50 倍。

图 1 程序性能工程的加速 将两个 4096×4096 矩阵相乘。
-
并行性 Python 的全局解释器锁 (GIL) 通常被认为是并行执行时的限制。GIL 确保单个进程中一次只有一个线程执行 Python 字节码,这会阻碍多核处理器的充分利用并影响并行性能。
-
内存管理 Python 的动态类型和垃圾收集会带来内存管理的开销。虽然垃圾收集器有助于自动内存管理,但有时会导致效率低下,特别是在实时性能至关重要的情况下。
混合编程:Python + C/C++/Rust
为了改善 Python 语言本身的性能问题,常见的做法是使用 Python 作为负责与用户交互的前端语言,同时选择 C/C++/Rust 等高性能编程语言作为后端 语言来处理繁重的计算任务。Python 生态中很多知名库都采用这种方式来满足高性能计算的需求,比如 Numpy。然而,这种混合编程方法不可避免地需要额外的工具(或库)作为“连接”两种不同编程语言的桥梁。因此,这个过程可能会带来新的问题。
维护成本
假设我们想要“绑定” Python 和 C++ API,我们必须使用第三方库来自动化这个转换过程,例如 Pybind11。图 2 中的示例代码展示了如何使用 Pybind11 “绑定” C++ 和 Python 程序。不难看出,尽管 Pybind11 极大地简化了转换过程,但添加或删除任何 C++ API 都需要对转换代码进行相应的更改,并且更改的难度与变更内容密切相关。从成本角度来看,这个过程不仅增加了开发者的学习成本,也增加了项目的开发和维护成本。


图 2 将 C++ 和 Python“粘合”在一起。
可移植性问题
-
混合编程可能会带来可移植性挑战。由于 Python 与本机库交互的方式或不同环境中的系统级依赖关系存在差异,在一个平台上无缝运行的代码可能会在另一个平台上遇到问题。
集成复杂性
-
如图 2 所示,将 Python 与其他语言绑定通常需要仔细管理数据类型、内存分配和错误处理。尽管有第三方库可以改进绑定任务,例如 Pybind11,但这种“粘合”过程仍然容易出错,并且需要对 Python 和所使用的其他语言有深入的了解。这会在一定程度上增加开发时间和风险。
Docker 容器的局限性
冷启动性能
-
Docker 容器虽然高效,但有时会面临冷启动性能的挑战。“冷启动”是指容器实例化后开始运行所需的时间。就 Docker 而言,启动时间通常为秒级。这可能看起来不多,但在快速扩展和响应能力至关重要的环境中,这些时间可能会导致明显的延迟并降低用户满意度。
磁盘空间消耗
-
Docker 容器有时可能非常庞大,消耗的磁盘空间达到千兆字节 (GB) 的量级。当容器包含所有必要的依赖项和运行时环境时尤其如此。如此大的容器大小可能会导致存储成本增加、部署时间变慢以及管理和分发容器映像方面的挑战。
硬件加速器支持
-
虽然 Docker 容器可以利用硬件加速器来提高性能,但有一个问题。他们通常需要特定版本的软件来确保兼容性。这意味着组织可能需要维护多个版本的容器或更新其硬件加速器以满足软件要求,从而增加了复杂性和管理开销。
可移植性问题
-
Docker 的主要卖点之一是它的可移植性。然而,这种可移植性有时取决于 CPU 架构。虽然 Docker 容器被设计为在不同环境中一致运行,但在不同 CPU 架构之间移动时可能会存在差异。这可能会给确保不同部署环境中的一致性能和行为带来挑战。
安全依赖
-
Docker 容器依赖主机操作系统的用户权限来保证安全。这意味着容器的安全性在一定程度上依赖于底层操作系统的安全配置。如果主机操作系统受到损害或配置错误,则可能会使容器面临安全漏洞。
这些限制凸显了对替代解决方案的需求,例如 Rust + WebAssembly,它有望解决其中一些痛点,并为部署 LLM 应用程序提供更高效、更安全的环境。
AGI 将是由 Rust 和
WebAssembly 构建
为什么 Rust 和 WebAssembly 可以成为 AGI 的语言?

Rust:AGI 时代的最佳选择
-
性能。 Rust 是一种编译语言,以其极快的性能而闻名。当与基于堆栈的虚拟机的二进制指令格式 WebAssembly 结合使用时,这两个组合有望提供无与伦比的执行速度。
-
内存安全。 Rust 的突出特点之一是它强调内存安全而不牺牲性能。这确保了应用程序既快速又安全。
-
并发性。 Rust 的并发性方法是独一无二的。它确保在编译时捕获数据竞争(并发系统中最常见和最具挑战性的错误之一)。这意味着开发者可以编写并发代码,而不必担心引入难以检测的运行时错误。
-
富有表现力的类型系统。 Rust 拥有强大且富有表现力的类型系统。该系统不仅有助于在编译时捕获错误,而且还允许开发者以清晰简洁的方式表达他们的意图。
-
现代包管理。 Cargo,Rust 的包管理器,简化了管理依赖项、构建项目甚至发布库的过程。因其易用性和高效性而受到赞誉的工具。
-
快速增长的生态。 Rust 的生态正在蓬勃发展。像“ndarray”、“llm”、“candle”和“burn”这样的库证明了社区积极参与扩展 Rust 的能力。
WASM 容器:更快、更轻、更安全
Shivraj Jadhav 从多个维度比较了 Docker 容器和 WASM。

表 1 WASM 与 Docker
-
可移植性。 WebAssembly 被设计为用于编译高级语言的可移植目标,允许部署在 Web 和 服务端,跨不同硬件。
-
沙箱机制。 WebAssembly 引入了沙箱机制,提供更安全的生产环境。这可以确保代码在隔离的环境中运行,从而最大限度地减少潜在风险。
-
保护用户数据和系统资源。 WebAssembly 的设计考虑了安全性。它确保用户数据和系统资源免受潜在威胁。
-
字节码验证。 在执行之前,WebAssembly 字节码会经过验证过程,以防止恶意代码运行。这增加了额外的安全层。
-
隔离执行环境。 WebAssembly 中的模块在隔离环境中运行。这意味着即使一个模块出现问题,也不会影响其他模块的正常运行。
-
占用空间更小。 使用 Rust 和 WebAssembly,开发者可以事半功倍。编译后的代码通常要小得多,从而加快加载时间并提高执行效率。
WASI-NN 标准
除了上述优点之外,WebAssembly 针对机器学习应用的 WASI-NN 标准也是一个重要因素。
-
主流机器学习推理引擎。 WASI-NN 旨在与流行的机器学习推理引擎(如 TensorFlow、PyTorch 和 OpenVINO)无缝协作。
-
大型语言模型的扩展。 借助“Llama2.c”和“llama.cpp”等工具和库,WASI-NN 提供为大型模型应用程序量身定制的功能,确保开发者拥有他们需要的的工具,以处理广泛的数据集和复杂的模型。
最新发布的 WasmEdge 0.13.5 已经支持使用 Rust 和 Wasm 运行 llama2 系列大模型,包括但不限于我们熟知的 Codellama、Mistral、OpenChat、BELLE-Llama2、Yi-34B 等等。详情请查看 llama-utils。
应用场景:代码检查代理(Agent)
在本节中,我们将演示如何使用“flows.network”平台构建代码检查代理。在深入讨论具体示例之前,我们首先看一下“Agent”和“flows.network”平台的概念模型。
Agent 的概念模型
这是 Lilian Weng 提出的基于 LLM 的 AI Agent 的概念框架。

图 3 LLM 驱动的自治代理系统概述
在这个模型中,LLM 函数扮演了智能体大脑的角色,负责核心推理和决策,但它仍然需要额外的模块来启用关键能力:规划、长 / 短期记忆和工具使用。
“flows.network”平台是基于与 Lilian 提出的模型类似的理念构建的。图 4 显示了其主要组件。整个平台是用 Rust 编写的,编译为 wasm 模块,并在 WasmEdge Runtime 上运行。

图 4 Flows.network 的主要组件
代码检查代理
在“flows.network”平台上,我们提供了一个代理(一个机器人模版)来帮助 GitHub 上开源项目的维护者审核 PR。将其命名为“代码检查机器人”。
代理的抽象设计如图 5 所示。图中中心的红色块code-review-function 定义了核心代理函数,而红色块周围的每个虚线圆圈与直接连接到图 3 中“代理”块的对应部分相匹配。

图 5 Code Review Bot 抽象设计
图 6 描述了Code Review Bot的架构。除了 GitHub Service 等外部资源外,代理由 wasm 模块组成,并在 WasmEdge Runtime 上运行。集成 wasm 模块负责通过 Web API 将 WebAssembly 函数连接到外部资源。例如,“code-review-function” wasm 模块将审核中的代码提取为提示词,然后“openai-integration” wasm 模块将提示词发送到 ChatGPT 服务并等待响应;最后,将评论发送到 code-review-function wasm 模块。

图.6 架构代码检查机器人
图 7 显示了 Code Review Bot 的 PR 检查摘要示例。它总结了目标 PR,列出了隐藏的风险和重大改变等。这些信息可以帮助检查者将注意力集中在关键部分,节省时间。

图 7 代码检查机器人 PR 审核总结示例
代码检查机器人可以在几分钟内完成部署。如果你想在自己的项目中使用它,可参考本指南。
结 论
在 AI 基础设施开发领域,虽然 Python 和 Docker 为我们提供了很好的服务,但探索和采用能够带来更好性能、安全性和效率的新技术也至关重要。Rust 和 WebAssembly 的结合反映了这种演变,为开发者和组织提供了一个有吸引力的替代方案。
参考资料
flows.network: 驱动 AI 工作负载的低代码 Serverless 平台。https://flows.network/
llama-utils: 请访问 https://github.com/second-state/llama-utils
作者简介
Sam Liu, QCon 北京 2023 演讲嘉宾,Second State 工程师,CNCF WasmEdge 维护者 & Miley Fu,CNCF 大使,WasmEdge DevRel。
完整幻灯片下载:
https://qcon.infoq.cn/202309/beijing/presentation/5466
相关文章:
Python + Docker 还是 Rust + WebAssembly?
在不断发展的技术世界中,由大语言模型驱动的应用程序,通常被称为“LLM 应用”,已成为各种行业技术创新背后的驱动力。随着这些应用程序的普及,用户需求的大量涌入对底层基础设施的性能、安全性和可靠性提出了新的挑战。 Python 和…...
[汇编实操]DOSBox工具: unable to open input file: 文件名.asm问题解决
出错原因1 :将文件放在debug文件下,mount后发现并没有该文件 解决方案 :重启DOSBox,重新mount,直到dir后可以看到该asm文件 出错原因2:DOS系统不支持8位以上的文件名 解决方案 :将文件名改为8…...
Windows安装MongoDB
1、下载MongoDB的zip,解压 2、创建目录 mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\db mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\log 3、创建一个配置文件mongod.cfg,…...
HandBrake 1.7 近日发布
导读HandBrake 1.7 近日发布,作为这个开源、免费和跨平台视频转码器应用程序的重大更新,适用于 GNU/Linux、macOS 和 Windows 系统。 在 HandBrake 1.6 发布近一年后,HandBrake 1.7 版本为 Linux 用户提供了许多好处,包括视频摘要…...
Vue3的watch使用介绍及场景
目录 一、watch的使用 1. 监听一个变量 2. 监听一个对象的属性 3. 监听一个函数的返回值 二、watch的使用场景 1. 监听表单的变化 2. 监听路由参数的变化 3. 监听Vuex中的数据变化 三、watch的效果图 四、watch的示例 以上就是Vue3的watch的介绍,watch是…...
Java设计原则和设计模式
目录 第一部分:设计原则 单一职责原则 (Single Responsibility Principle)开闭原则 (Open-Closed Principle)里氏替换原则 (Liskov Substitution Principle)接口隔离原则 (Interface Segregation Principle)依赖倒置原则 (Dependency Inversion Principle)合成/聚…...
webshell之基于框架免杀
thinkphp array_map_recursive函数 array_map_recursive函数分析 这里存在一个call_user_func命令执行函数 免杀效果 B函数 免杀效果 B函数分析 exec函数分析 在exec函数用存在有个类调用,且所有的参数都可控 smarty_php_tag函数 免杀效果 smarty_php_tag函数分析…...
QT QJsonObject 插入 QByteArray十六进制数据
场景描述 有一组十六进制数使用QByteArray进行存储;需要将其插入QJsonObject,然后通过网络发送出去;接收到后,再转换回QByteArray; 操作代码 1. QByteArray转换QString插入QJsonObject QString str ""; …...
概要设计文档案例分享
1引言 1.1编写目的 1.2项目背景 1.3参考资料 2系统总体设计 2.1整体架构 2.2整体功能架构 2.3整体技术架构 2.4运行环境设计 2.5设计目标 3系统功能模块设计 3.1个人办公 4性能设计 4.1响应时间 4.2并发用户数 5接口设计 5.1接口设计原则 5.2接口实现方式 6运行设计 6.1运行模块…...
微服务qiankun通信方式
qiankun: 是一种类似于微服务的架构,是将一个大型应用拆分成若干个更小、更简单,可以独立开发、测试和部署的子应用,然后由一个基座应用根据路由进行应用切换,主要是为了解决大型工程在变更、维护、扩展等方面的困难而…...
【Azure 架构师学习笔记】-Azure Storage Account(7)- 权限控制
本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Storage Account】系列。 接上文 【Azure 架构师学习笔记】-Azure Storage Account(6)- File Layer 前言 存储帐户作为其中一个数据终端存储,对安全性的要求非常高,不管…...
听GPT 讲Rust源代码--src/tools(2)
题图来自AI生成 File: rust/src/tools/rust-installer/src/util.rs 在Rust源代码中,rust/src/tools/rust-installer/src/util.rs文件是安装程序的一个辅助文件,它提供了一些实用函数和结构体来处理安装过程中需要的一些操作。 这个文件中定义了几个结构体…...
【python学习】基础篇-常用模块-collections模块:数据结构,如列表、元组、字典和集合等
Python中的collections模块提供了一些有用的数据结构,如列表、元组、字典和集合等。 以下是collections模块中一些常用数据结构的用法: Counter类 Counter类是一个字典子类,用于计数可哈希对象。 它可以接受一个可迭代对象作为参数ÿ…...
【电路笔记】-电源电压
电源电压 文章目录 电源电压1、概述1.1 交流发电机1.2 电池1.3 理想电压源1.4 实际电压源1.5 连接规则 2、相关源2.1 压控电压源 (VCVS)2.2 电流控制电压源 (CCVS) 3、总结 在本文中,我们详细介绍了称为电源电压的重要电子元件的架构、功能和使用。 我们首先提出理想…...
kali部署ARL灯塔资产系统及使用教程
网上有很多ARL部署到centos系统的教程,但是部署到ubuntu或kali linux系统的教程都是乱七八糟,互相抄,而且没有一个能部署成功,鉴于此,写下此教程,帮助大家出坑 一、安装docker环境(网上什么弄钥匙呀,什么稳定源啊都是垃圾) 准备一个纯净的最新的kali linux系统 1、配…...
一、用户管理
一、后端数据库初始化 1.1 因为版本问题,始终报错,按照报错信息去查询解决方案,无法解决 灵机一动: 网址: Spring Boot 3.0 升级 实战踩坑记录 - 掘金 (juejin.cn) 1.2 个人配置【运行成功…...
Could not publish to the server. java.lang.NullPointerException
publishing to tomcat v8.0 server at localhost has encontered a problem. Could not publish to the server. java.lang.NullPointerException 解决办法: 关闭eclipse在自己设置的workspace目录下面,打开目录:.metadata.plugins\org.ecl…...
SpringMVC(三)
十、拦截器 1、拦截器的配置 SpringMVC中的拦截器用于拦截控制器方法的执行 SpringMVC中的拦截器需要实现HandlerInterceptor SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置: <bean class"com.atguigu.interceptor.FirstInterceptor">…...
打印菱形-第11届蓝桥杯选拔赛Python真题精选
[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第9讲。 打印菱形ÿ…...
『亚马逊云科技产品测评』活动征文|搭建Squoosh图片在线压缩工具
搭建Squoosh图片在线压缩工具 前言一、Squoosh是什么?二、准备一台Lightsail实例1.进入控制台2.创建实例3.开放端口4.部署Squoosh5.预览 三、搭建反向代理1. 安装宝塔2. 配置反向代理3. 预览代理效果 提示:授权声明:本篇文章授权活动官方亚马…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
