人工智能控制器接口(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贊助。任何使用第三方商標或徽標都遵守這些第三方政策。