这篇文章介绍了一个基于Rust和WebAssembly(Wasm)的解决方案,用于在异构边缘计算设备上快速和便携地进行Llama2模型的推理。与Python相比,这种Rust+Wasm应用程序的体积仅为Python的1/100,速度提升100倍,并且可以在全硬件加速环境中安全运行,不需要更改二进制代码。文章基于GeorgiGerganov创建的项目,将原始的C++程序适配到Wasm上。安装过程包括安装WasmEdge和GGML插件,下载预构建的Wasm应用和模型,然后使用WasmEdge运行Wasm推理应用,并传递GGUF格式的模型文件。此外,文章还提供了多个命令行选项,用于配置与模型的交互方式。
译者|明明如月责编|梦依丹
出品|CSDN(ID:CSDNnews)
与Python相比,Rust+Wasm应用程序的大小可能只有Python的1/100,但速度快100倍。最重要的是,无需对二进制代码进行任何更改,就可以在各种硬件加速器上安全运行。参见:为什么埃隆·马斯克说Rust是AGI的语言?。
我们创建了一个非常简单的Rust程序,用于以原生速度运行llama2模型的推理。当编译为Wasm时,这个二进制应用程序(仅2MB)可以完全跨设备移植,兼容异构硬件加速器。Wasm运行时(WasmEdge)还为云环境提供了一个安全可靠的执行环境。事实上,WasmEdge运行时与容器工具无缝协作,可以在许多不同设备上部署和执行这个可移植应用程序。
在我的MacBook上与llama2模型聊天
这项工作基于GeorgiGerganov创建的项目。我们采用了原始的C++程序在Wasm上运行。它适用于GGUF格式的模型文件。
步骤1.安装WasmEdge和GGML插件
在Linux或Mac设备上使用以下命令安装所有组件。
curl-sSf|bash-s----pluginwasi_nn-ggml
步骤2.下载预构建的Wasm应用和模型
curl-LO
你还应该下载一个GGUF格式的llama2模型。下面的例子下载了一个调整为5位权重的llama27B聊天模型。
curl-LO
步骤3.运行
使用WasmEdge运行wasm推理应用程序,同时加载GGUF模型。现在,你可以输入问题与模型进行聊天了。
wasmedge--dir.:.--nn-preloaddefault:GGML:AUTO:llama-2-7b-chat-q5_k_
配置模型行为
你可以使用命令行选项配置与模型的交互方式。
Options:-m,--model-aliasALIASModelalias[default:default]-c,--ctx-sizeCTX_SIZESizeofthepromptcontext[default:4096]-n,--n-predictN_PRDICTNumberoftokenstopredict[default:1024]-g,--n-gpu-layersN_GPU_LAYERSNumberoflayerstorunontheGPU[default:100]-b,--batch-sizeBATCH_SIZEBatchsizeforpromptprocessing[default:4096]-r,--reverse-promptREVERSE_PROMPTHaltgenerationatPROMPT,returncontrol.-s,--system-promptSYSTEM_PROMPTSystempromptmessagestring[default:"[Defaultsystemmessage
fortheprompttemplate]"]-p,--prompt-templateTEMPLATEPrompttemplate.[default:llama-2-chat][possiblevalues:llama-2-chat,codellama-instruct,,mistrallite,openchat,belle-llama-2-chat,vicuna-chat,chatml]--log-promptsPrintpromptstringstostdout--log-statPrintstatisticstostdout--log-allPrintallloginformationtostdout--stream-stdoutPrinttheoutputtostdoutinthestreamingway-h,--helpPrinthelp
例如,以下命令指定了2048个token的上下文长度和每次响应的最大512个token。它还告诉WasmEdge以流式方式将模型响应逐个token返回到stdout。该程序在低端M2MacBook上每秒生成大约25个token。
wasmedge--dir.:.--nn-preloaddefault:GGML:AUTO:llama-2-7b-chat-q5_k_\
[USER]:Whoisthe"fatheroftheatomicbomb"?(谁是“原子弹之父”?)
----------------[LOG:STATISTICS]-----------------
llama_new_context_with_model:n_ctx=2048llama_new_context_with_model:freq_base=10000.0llama_new_context_with_model:freq_scale=1llama_new_context_with_model:kvselfsize=1024.00MBllama_new_context_with_model:computebuffertotalsize=630.14MBllama_new_context_with_model:maxtensorsize=102.54MB[2023-11-1017:52:12.768][info][WASI-NN]GGMLback:llama_system_info:AVX=0|AVX2=0|AVX512=0|AVX512_VBMI=0|AVX512_VNNI=0|FMA=0|NEON=1|ARM_FMA=1|F16C=0|FP16_VA=1|WASM_SIMD=0|BLAS=0|SSE3=0|SSSE3=0|VSX=0|The"fatheroftheatomicbomb",thesecretresearcicbombandisoftenreferredtoasthe"fatheroftheatomicbomb."llama_print_timings:loadtime=15643.70msllama_print_timings:sampletime=2.60ms/83runs(0.03mspertoken,31886.29tokenspersecond)llama_print_timings:promptevaltime=7836.72ms/54tokens(145.12mspertoken,6.89tokenspersecond)llama_print_timings:evaltime=3198.24ms/82runs(39.00mspertoken,25.64tokenspersecond)llama_print_timings:totaltime=18852.93ms
----------------------------------------------------
下面是它在NvidiaA10G机器上以每秒50个token的速度运行示例。
wasmedge--dir.:.--nn-preloaddefault:GGML:AUTO:llama-2-7b-chat-q5_k_\
[USER]:Whoisthe"fatheroftheatomicbomb"?(谁是“原子弹之父”?)
----------------[LOG:STATISTICS]-----------------llm_load_tensors:usingCUDAforGPUaccelerationllm_load_tensors:memrequired=86.04MBllm_load_tensors:offloading32repeatinglayerstoGPUllm_load_tensors:offloadingnon-repeatinglayerstoGPUllm_load_tensors:offloaded35/35layerstoGPUllm_load_tensors:VRAMused:4474.93MB..llama_new_context_with_model:n_ctx=2048llama_new_context_with_model:freq_base=10000.0llama_new_context_with_model:freq_scale=1llama_kv_cache_init:offloadingvcachetoGPUllama_kv_cache_init:offloadingkcachetoGPUllama_kv_cache_init:VRAMkvself=1024.00MBllama_new_context_with_model:kvselfsize=1024.00MBllama_new_context_with_model:computebuffertotalsize=630.14MBllama_new_context_with_model:VRAMscratchbuffer:624.02MBllama_new_context_with_model:totalVRAMused:6122.95MB(model:4474.93MB,context:1648.02MB)[2023-11-1100:02:22.402][info][WASI-NN]GGMLback:llama_system_info:AVX=1|AVX2=1|AVX512=0|AVX512_VBMI=0|AVX512_VNNI=0|FMA=1|NEON=0|ARM_FMA=0|F16C=1|FP16_VA=0|WASM_SIMD=0|BLAS=1|SSE3=1|SSSE3=1|VSX=0|
llama_print_timings:loadtime=2601.44msllama_print_timings:sampletime=2.63ms/84runs(0.03mspertoken,31987.81tokenspersecond)llama_print_timings:promptevaltime=203.90ms/54tokens(3.78mspertoken,264.84tokenspersecond)llama_print_timings:evaltime=1641.84ms/83runs(19.78mspertoken,50.55tokenspersecond)llama_print_timings:totaltime=4254.95ms
----------------------------------------------------
[ASSISTANT]:The"fatheroftheatomicbomb",thesecretresearchanddicbombandisoftenreferredtoasthe"fatheroftheatomicbomb."(“原子弹之父”这个词通常与物理学家联系在一起。奥本海默是曼哈顿计划的主管,曼哈顿计划是二战期间研发出第一颗原子弹的秘密研发项目。他被广泛认为是原子弹研发的领导人物,常被称为“原子弹之父”。)
LLM代理和应用
我们利用Rust和WasmEdge技术,构建了一个与OpenAI兼容的API服务。它允许你使用任何兼容OpenAI的开发工具,如,来创建LLM代理和应用。
边缘上的Llama,图片由Midjourney生成
为什么不使用Python?
LLM(大型语言模型)如llama2通常在Python(例如PyTorch、Tensorflow和JAX)中进行训练。在AI计算的推理应用中,占比约95%,Python并不适合。
Python包具有复杂的依赖性,难以设置和使用。
Python依赖庞大。Python或PyTorch的Docker镜像通常有几GB甚至几十GB。这对于边缘服务器或设备上的AI推理尤其成问题。
Python是一种非常慢的语言,与C、C++和Rust等编译语言相比,慢达35,000倍。
由于Python慢,大部分实际工作必须委托给Python包装器下的原生共享库。这使得Python推理应用非常适合演示,但根据业务需求进行修改时非常困难。
重度依赖原生库和复杂的依赖管理使得PythonAI程序难以在各种设备上移植,同时利用设备的独特硬件特性。
LLM工具链中常用的Python包相互冲突
ChrisLattner(参与LLVM、Tensorflow和Swift语言开发的著名软件工程师)在ThisWeekinStartup播客上进行了精彩的采访。他讨论了Python在模型训练中的优势,但并不适合推理。
Rust+Wasm的优势
Rust+Wasm技术栈构建了统一的云计算基础设施。它涵盖了从设备、边缘云到本地服务器和公有云的全方位服务。它在AI推理应用中是Python技术栈的有效替代方案。此外,埃隆·马斯克曾评价Rust为AGI(通用人工智能)的理想语言。
超轻量级。推理应用仅为2MB,包含所有依赖,不到典型PyTorch容器大小的1%。
非常快。在推理应用的各个环节,包括预处理、张量计算和后处理,都能达到原生C/Rust的速度。
便携。相同的Wasm字节码应用可以在所有主要计算平台上运行,并支持异构硬件加速。
易于设置、开发和部署。不再有复杂的依赖。只要在你的笔记本上使用标准工具构建单个Wasm文件,就可以在任何地方部署!
安全且适用于云。Wasm运行时旨在隔离不受信任的用户代码。Wasm运行时可以由容器工具管理,并轻松部署在云原生平台上。
Rust推理程序
我们演示的推理程序核心部分是用Rust编写的,其源代码非常简洁,仅包含40行,最终被编译成Wasm格式。该Rust程序负责管理用户输入,跟踪对话历史,它还能将文本转换为llama2的聊天模板,并借助WASINNAPI执行推理操作。
fnmain(){letargs:VecString=env::args().collect();letmodel_name:str=args[1];
letgraph=wasi_nn::GraphBuilder::new(wasi_nn::GraphEncoding::Ggml,wasi_nn::ExecutionTarget::AUTO).build_from_cache(model_name).unwrap();letmutcontext=_execution_context().unwrap();
letsystem_prompt=String::from("SYSYouareahelpful,,whilebeingsafe./SYS");letmutsaved_prompt=String::new();
loop{println!("Question:");letinput=read_input();ifsaved_prompt==""{saved_prompt=format!("[INST]{}{}[/INST]",system_prompt,());}else{saved_prompt=format!("{}[INST]{}[/INST]",saved_prompt,());}
//将用户问题字符串预处理成张量格式后,设置为模型输入张量,以供模型进行下游推理计算。lettensor_data=saved__bytes().to_vec();context.set_input(0,wasi_nn::TensorType::U8,[1],tensor_data).unwrap();
//执行推理计算().unwrap();
//获取输出letmutoutput_buffer=vec![0u8;1000];letoutput_size=_output(0,mutoutput_buffer).unwrap();letoutput=String::from_utf8_lossy(output_buffer[..output_size]).to_string();println!("Answer:\n{}",());
saved_prompt=format!("{}{}",saved_prompt,());}}要自行构建应用,只需安装Rust编译器及其wasm32-wasi编译目标。
curl--proto'=https'--|shrustuptargetaddwasm32-wasi
然后,检出源项目,并运行cargo命令从Rust源项目构建Wasm文件。
构建cargobuild--targetwasm32-wasi--release
#结果wasm文件cptarget/wasm32-wasi/release/
在云端或边缘运行
获取Wasm字节码文件后,你便可以在任何支持WasmEdge运行时的设备上进行部署。你只需要安装带有GGML插件的WasmEdge。我们目前提供的GGML插件支持包括通用Linux和UbuntuLinux在内的多种操作系统,适用于x86和ARMCPU、NvidiaGPU,以及AppleM1/M2/M3。
基于,WasmEdgeGGML插件将自动利用设备上的任何硬件加速来运行llama2模型。例如,如果你的设备有NvidiaGPU,安装程序将自动安装优化了CUDA的GGML插件版本。对于Mac设备,我们专门为MacOS构建了GGML插件,它利用MetalAPI在M1/M2/M3内置的神经处理引擎上执行推理工作负载。LinuxCPU构建的GGML插件使用OpenBLAS库来自动检测和利用现代CPU上的高级计算特性,如AVX和SIMD。
通过使用Rust和Wasm技术,我们可以实现AI模型在异构硬件和平台上的可移植性,同时又不损失性能。
下一步计划
虽然WasmEdgeGGML工具目前已经投入使用,许多云原生客户都在使用,但它仍处于发展的初期阶段。如果你有兴趣贡献于开源项目,并对影响未来的大型语言模型(LLM)推理基础设施的发展方向产生影响,并为开源项目共享力量。
为更多的硬件和操作系统平台添加GGML插件。我们也对Linux和Windows上的TPU、ARMNPU以及其他专门的AI芯片感兴趣。
支持更多配置。我们目前支持从Wasm向GGML插件传递一些配置选项。但我们希望支持GGML提供的所有选项!
在其他兼容Wasm的语言中支持WASINNAPI。我们特别感兴趣的语言包括Go、Zig、Kotlin、JavaScript、C和C++。
其他AI模型
WasmEdge和WASINN作为Python的轻量级、快速、可移植且安全的替代品,可以构建基于多种流行AI模型的推理应用,不只局限于LLM。例如:
mediapipe-rs项目为Google的mediapipeTensorflow模型系列提供了Rust+WasmAPI。
WasmEdgeYOLO项目提供了用于处理YOLOv8PyTorch模型的Rust+WasmAPI。
WasmEdgeADAS演示展示了如何使用IntelOpenVINO模型进行自动驾驶汽车的道路分割。
WasmEdge文档AI项目将为一系列流行的OCR和文档处理模型提供Rust+WasmAPI。
轻量级AI推理在边缘计算领域才刚刚起步,未来可期!





