人工智能控制器接口(AICI)使您可以实时构建控制大型语言模型(LLM)的控制器。控制器是灵活的程序,能够实现受限的解码,提示和生成文本的动态编辑,并在多个并行世代进行协调执行。在LLM请求期间,Controller在令牌解码过程中合并了自定义逻辑并保持状态。这允许各种控制器策略,从程序化或基于查询的解码到多代理对话,都可以有效地执行与LLM本身的紧密集成。
AICI的目的是使建立和实验以改善LLM世代的现有和全新的控制器策略。通过将基础LLM推理和服务引擎的实施细节抽象,AICI旨在简化控制器的开发,使其更容易编写快速控制器,并在LLM推理和服务引擎中均简化兼容性。
AICI专为本地和云执行而设计,包括(最终)多租户LLM部署。控制器的实现为轻型WebAssembly(WASM)模块,该模块与LLM推理引擎在同一机器上运行,而GPU忙于代币生成时,使用CPU。 AICI是推理堆栈中的一层,旨在允许控制库,例如Guidance,LMQL和其他人在其顶部运行,并获得效率和性能提高,以及LLM推理和服务引擎的可移植性。
AICI目前与Llama.CPP,HuggingFace Transferesers和RLLM(基于自定义TCH的LLM推理引擎)集成在一起,并与VLLM一起进行。
AICI是:
AICI是一个原型,在Microsoft Research设计和建造。
在此QuickStart中,我们将指导您完成以下步骤:
要编译AICI组件,您需要为Rust设置开发环境。对于此快速启动,您还需要Python 3.11或更高版本才能创建控制器。
笔记
Windows用户:请使用WSL2或随附的DevContainer。此处跟踪添加本机窗户支持。
MACOS用户:请确保通过运行xcode-select -p安装Xcode命令行工具,如果未安装,请运行xcode-select --install 。
CUDA :CUDA构建依赖于特定的Libtorch安装。强烈建议您使用随附的Devcontainer。
如果您使用的是DevContainer,则可以跳到下一节。
使用系统软件包管理器,安装在存储库中构建代码的必要工具,包括git , cmake和ccache 。
例如,在WSL / Ubuntu中使用apt :
sudo apt-get install --assume-yes --no-install-recommends
build-essential cmake ccache pkg-config libssl-dev libclang-dev clang llvm-dev git-lfs
或在MacOS上使用自制型:
brew install git cmake ccache
然后按照此处和此处提供的说明安装Rust,Rustup和货物:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
安装后,通过从终端运行来访问rustup --version命令。如果命令未识别,请尝试打开新的终端会话。
下一个安装WASM32-WASI RUST组件:
rustup target add wasm32-wasi
如果您已经安装了生锈,或者正在从货物上收到有关过时版本的投诉,请运行:
rustup update
最后,要使用Python控制器和脚本(如本教程),请运行此命令以安装所需的软件包:
pip install pytest pytest-forked ujson posix_ipc numpy requests
RLLM服务器有两个后端,一个基于libtorch和Cuda( rllm-cuda ),另一个基于llama.cpp ( rllm-llamacpp )。
rllm-cuda后端仅与NVIDIA GPU一起使用Compute 8.0或更高版本(A100及以后; RTX 30x0及以后),并且需要一个借助的Libtorch设置 - 强烈建议使用随附的DevContainer使用。虽然本指南重点关注rllm-llamacpp后端,但对于rllm-cuda ,构建步骤相同,Modulo the文件夹名称。
在上面设置开发后,克隆AICI存储库,然后继续下面概述的下一步。
使用以下命令来构建和运行aicirt和rllm-llamacpp :
cd rllm/rllm-llamacpp
./server.sh phi2
您可以将其他模型名称作为参数传递(run ./server.sh而无需参数以查看可用模型)。您也可以使用拥抱面URL到.gguf文件或.gguf文件的本地路径。 (对于rllm-cuda请使用huggingface模型ID或通往文件夹的路径)。
./server.sh orca
您可以在此处找到有关rllm-llamacpp的更多详细信息。
RLLM服务器提供了一个HTTP接口,用于配置任务和处理请求。您也可以使用此接口及时验证其状态。例如,如果您打开http://127.0.0.1:4242/v1/models,则应该查看:
{
"object" : " list " ,
"data" : [
{
"object" : " model " ,
"id" : " TheBloke/phi-2-GGUF " ,
"created" : 946810800 ,
"owned_by" : " owner "
}
]
}确认所选模型已加载。
AICI允许托管自定义逻辑(称为控制器) ,该逻辑可以启动,终止和与LLMS代币生成。控制器使用输入参数,处理它们,并使用日志,LLM令牌和变量返回结果。
存储库包括一些示例,特别是:
在此示例中,我们将使用PYCTRL使用简单的Python脚本来管理令牌生成。如果需要,您可以构建和上传Pyctrl,但是默认情况下,服务器将自动从GitHub下载Pyctrl的最新版本。
通常,控制器需要构建和部署,而每个请求都会发送脚本(Python或JavaScript)。
以下说明了RLLM服务器,AICI运行时和控制器之间的关系:
Erdiagram
主机|| - | {cpu:“”
主机|| - | {gpu:“”
CPU || - || “ RLLM服务器”:执行
CPU || - | {“ AICI Runtime”:执行
“ AICI运行时” || - || “控制器”:实例化
gpu || - | {“ LLM令牌生成”:执行
假设我们旨在使模型生成列表,并遵守特定格式,仅包含五个项目。
通常,实现这一目标涉及及时的工程,并通过清晰的说明精确地制作及时的及时,例如:
What are the five most popular types of vehicles?
Return the result as a numbered list.
Do not add explanations, only the list.
鉴于每个模型都倾向于添加解释并以不同的方式理解说明,提示也将根据使用中的模型而有所不同。
使用AICI,我们将控制权转移到代码,我们可以简化提示:
What are the most popular types of vehicles?
使用代码:
让我们创建一个list-of-five.py python文件,其中包含以下内容:
import pyaici . server as aici
# Force the model to generate a well formatted list of 5 items, e.g.
# 1. name 1
# 2. name 2
# 3. name 3
# 4. name 4
# 5. name 5
async def main ():
# This is the prompt we want to run.
# Note how the prompt doesn't mention a number of vehicles or how to format the result.
prompt = "What are the most popular types of vehicles? n "
# Tell the model to generate the prompt string, ie. let's start with the prompt "to complete"
await aici . FixedTokens ( prompt )
# Store the current position in the token generation process
marker = aici . Label ()
for i in range ( 1 , 6 ):
# Tell the model to generate the list number
await aici . FixedTokens ( f" { i } ." )
# Wait for the model to generate a vehicle name and end with a new line
await aici . gen_text ( stop_at = " n " )
await aici . FixedTokens ( " n " )
# Store the tokens generated in a result variable
aici . set_var ( "result" , marker . text_since ())
aici . start ( main ())运行脚本与发送提示没有太大不同。在这种情况下,我们将一起发送控制逻辑和指令。
要查看最终结果,请执行以下命令:
./aici.sh run list-of-five.py
结果:
Running with tagged AICI Controller: gh:microsoft/aici/pyctrl
[0]: FIXED 'What are the most popular types of vehicles?n'
[0]: FIXED '1.'
[0]: GEN ' Carsn'
[0]: FIXED '2.'
[0]: GEN ' Motorcyclesn'
[0]: FIXED '3.'
[0]: GEN ' Bicyclesn'
[0]: FIXED '4.'
[0]: GEN ' Trucksn'
[0]: FIXED '5.'
[0]: GEN ' Boatsn'
[0]: FIXED 'n'
[DONE]
[Response] What are the most popular types of vehicles?
1. Cars
2. Motorcycles
3. Bicycles
4. Trucks
5. Boats
response saved to tmp/response.json
Usage: {'sampled_tokens': 16, 'ff_tokens': 37, 'cost': 69}
Timing: {'http_response': 0.05193686485290527, 'data0': 0.05199289321899414, 'first_token': 0.0658726692199707, 'last_token': 0.1784682273864746}
Tokens/sec: {'prompt': 861.0913072488067, 'sampling': 89.65181217019571}
Storage: {'result': '1. Carsn2. Motorcyclesn3. Bicyclesn4. Trucksn5. Boatsnn'}
该存储库包含许多组件,并且您需要哪些组件取决于您的用例。
您可以使用现有的控制器模块。我们提供PYCTRL和JSCTRL,可分别使用服务器端Python和JavaScript脚本控制器。 PYAICI软件包包含aici命令行工具,可让您使用任何控制器上传并运行脚本(我们还为好奇心提供了REST API定义)。
?
我们预计将在控制器之上构建库。我们提供了Postlib的示例-Postlib-客户端Python库,该库通过Pyaici软件包与Declctrl生成互动。
?示例笔记本,该笔记本使用ficterlib与dectctrl进行交互。
控制器可以在云或启用AICI的本地LLM推理引擎中运行。您可以使用libtorch+cuda或llama.cpp后端在本地运行提供的参考引擎(RLLM) 。
要开发一个新的控制器,请使用一个显示AICI_ABI库的Rust Starter项目,该项目简化了实现低级AICI接口。
?示例代码,用于最小的新控制器,以使您启动
为了在新的LLM推理引擎中添加AICI支持,您将需要实现与AICI运行时对话的协议的LLM端。
最后,您可能需要修改任何提供的组件 - 最欢迎PRS!
AICI从控制器和反之亦然中抽象LLM推理引擎,如下图所示。圆形节点是有抱负的。可以在顶部建造其他层 - 我们提供Pickerlib,但我们坚信指导,LMQL,SGLANG,大纲,JSONFORMER,LMFE等也可以在AICI的顶部运行(使用定制控制器或使用Pyctrl或JSCTRL)。
图TD
pyctrl- aici-> aicirt [aici-runtime]
jsctrl- aici-> aicirt
指南([guidancectrl]) - aici-> aicirt
lmql([lmql ctrl]) - aici-> aicirt
AICIRT -POSIX SHM-> RLLM
AICIRT -POSIX SHM-> LLAMA [LLAMA.CPP]
aicirt -posix shm-> pyaici
pyaici- python-> vllm(vllm)
pyaici- python-> HF [HF变形金刚]
PYAICI软件包使将AICI与基于Python的LLM推理引擎更容易。看看与HuggingFace Transformers的集成,尽管注意到它不支持分叉(并行生成多个序列)。 VLLM REST服务器当前已过时。请暂时使用rllm-cuda或rllm-llama.cpp。
aicirt在单独的过程中运行,并且可以在与LLM引擎不同的用户下运行aici_host_*函数,在hostimpl.rs中实现aicirt还暴露了部分WASI接口;但是,几乎所有功能都是无效的,除了fd_write shims文件描述符1和2(stdout and stderr)以打印调试消息特别是,WASM模块无法访问文件系统,网络或任何其他资源。它们也无法旋转线程或访问任何计时器(这与Spectre/Meltdown攻击有关)。
AICI控制器中的大多数计算都与GPU上的logit生成并行发生在CPU上。这一生成发生在步骤中,其中逻辑是在批处理中为每个序列的新令牌并行生成的(通常在1到50之间)。这涉及从GPU存储器中读取整个模型和KV缓存的序列。对于最佳批处理吞吐量,模型和KV缓存应使用GPU内存的主要部分,并且在A100 GPU(80GB)上读取整个内存大约需要40ms。
因此,生成的每个步骤都采用20-50ms的顺序。通过仔细的工程,这足以计算汇集给WASM的Rust中的允许令牌集。这些可以在生锈中本地组合,也可以通过我们提供的Python或JavaScript口译员组合。
例如,在Llama模型的32000杆词汇中设置的计算允许令牌设置为:
上面的数字是针对单个序列的,但是每个序列都是在单独的过程中处理的,因此,如果核心比序列多(通常是典型),则它们不会改变。它们还包括在WASM中实现的python demander的开销,然后返回生成的生产的WASM代码以进行约束本身。它们都很好,在20-50ms的预算之内,因此根本不会影响发电时间。
采样的临界路径中也有一些开销。当并行执行10个序列时,每一代步骤约为0.3ms(这是不考虑使用的约束)。对于40个序列,开销高达0.7ms(尽管尚未完全优化)。
与本机代码相比,WebAssembly的设计最小。根据我们的经验,在WASMTIME运行时,高度优化的Rust Code速度慢2倍。这比JavaScript或Python好10-100x。
使用80GB VRAM的NVIDIA A100 GPU对AMD EPYC 7V13进行的所有测量。
AICI运行时提供的低级接口允许:
它可以从编译到WASM的任何语言中使用。
该存储库提供了一个生锈库,使其易于在Rust中实现控制器,并提供了特定约束(正则表达式,YACC语法,子字)的有效实现。我们还提供Python和JavaScript口译员,可以将这些约束粘合在一起。所有这些都可以很容易地扩展。
如果您发现AI控制器接口及其在LLM推理堆栈中定义新层的想法有用,请使用以下参考引用包:
Bibtex:
@misc { Moskal2024 ,
author = { Moskal, Michal and Musuvathi, Madan and {Ki ci man}, Emre } ,
title = { {AI Controller Interface} } ,
year = { 2024 } ,
publisher = { {GitHub} } ,
journal = { {GitHub} repository } ,
howpublished = { url{https://github.com/microsoft/aici/} }
}该项目欢迎贡献和建议。大多数捐款要求您同意撰写贡献者许可协议(CLA),宣布您有权并实际上授予我们使用您的贡献的权利。有关详细信息,请访问https://cla.opensource.microsoft.com。
当您提交拉动请求时,CLA机器人将自动确定您是否需要提供CLA并适当装饰PR(例如状态检查,评论)。只需按照机器人提供的说明即可。您只需要使用我们的CLA在所有存储库中进行一次。
该项目采用了Microsoft开源的行为代码。有关更多信息,请参见《行为守则常见问题守则》或与其他问题或评论联系[email protected]。
该项目可能包含用于项目,产品或服务的商标或徽标。 Microsoft商标或徽标的授权使用受到了Microsoft的商标和品牌准则的约束。在此项目的修改版本中使用Microsoft商标或徽标不得引起混乱或暗示Microsoft赞助。任何使用第三方商标或徽标都遵守这些第三方政策。