人工知能コントローラーインターフェイス(AICI)を使用すると、大規模な言語モデル(LLM)の出力をリアルタイムで制約および直接的なコントローラーを構築できます。コントローラーは、制約されたデコード、プロンプトの動的編集と生成されたテキストの動的編集、および複数の並行世代にわたって実行の調整を実装できる柔軟なプログラムです。コントローラーは、トークンバイトークンデコード中にカスタムロジックを組み込み、LLMリクエスト中に状態を維持します。これにより、プログラマティックまたはクエリベースのデコードからマルチエージェント会話まで、LLM自体との緊密な統合で効率的に実行される多様なコントローラー戦略が可能になります。
AICIの目的は、LLM世代を改善するための既存および完全に新しいコントローラー戦略の両方を簡単に構築および実験できるようにすることです。基礎となるLLM推論とサービスエンジンの実装の詳細を抽象化することにより、AICIはコントローラーの開発を簡素化し、高速コントローラーの書き込みを容易にし、LLMの推論とエンジンのサービスを容易にすることを目指しています。
AICIは、(最終的に)マルチテナントLLM展開を含む、ローカルとクラウドの両方の実行用に設計されています。コントローラーは、LLM推論エンジンと同じマシンで実行される軽量のWebAssembly(WEBSEM)モジュールとして実装され、GPUがトークンの世代で忙しい間にCPUを利用します。 AICIは、推論スタック内の1つのレイヤーであり、ガイダンス、LMQLなどの制御ライブラリがその上で実行され、効率とパフォーマンスの改善の両方を獲得し、LLMの推論とサービスエンジン全体の携帯性を得るように設計されています。
AICIは現在、llama.cpp、Huggingface Transformers、およびRLLM(カスタムTCHベースのLLM推論エンジン)と統合されており、VLLMは作品にあります。
aiciは次のとおりです。
AICIは、Microsoft Researchで設計および構築されたプロトタイプです。
このQuickStartでは、次の手順をご案内します。
AICIコンポーネントをコンパイルするには、錆のために開発環境をセットアップする必要があります。このクイックスタートには、コントローラーを作成するにはPython 3.11以降も必要です。
注記
Windowsユーザー:WSL2または付属のDevContainerを使用してください。ここでは、ネイティブWindowsサポートの追加が追跡されます。
MACOSユーザー: xcode-select -pを実行して、インストールしていない場合はxcode-select --install実行していない場合、Xcodeコマンドラインツールがインストールされていることを確認してください。
CUDA :CUDAビルドは、特定のLibtorchのインストールに依存しています。付属のDevContainerを使用することを強くお勧めします。
DevContainerを使用している場合は、次のセクションにスキップできます。
System Package Managerを使用して、 git 、 cmake 、 ccacheなど、リポジトリにコードを構築するために必要なツールをインストールします。
たとえば、 aptを使用したWSL / ubuntuで:
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でHomebrewを使用してください:
brew install git cmake ccache
次に、こちらとこちらに提供される指示に従って、さび、ラスタップ、貨物を取り付けます。
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サーバーには2つのバックエンドがあり、1つはlibtorchとCuda( rllm-cuda )に基づいており、もう1つはllama.cpp ( rllm-llamacpp )に基づいています。
rllm-cudaバックエンドは、計算機能8.0以降(A100以降; RTX 30x0以降)を備えたNVIDIA GPUSでのみ動作し、Libtorchのfiddlyセットアップを必要とします。このガイドではrllm-llamacppバックエンドに焦点を当てていますが、ビルドステップはrllm-cudaで同じです。フォルダ名はモジュロです。
上記のDev envセットアップの後、AICIリポジトリをクローンし、以下に概説する次の手順を進めます。
次のコマンドを使用して、 aicirtとrllm-llamacppを構築および実行します。
cd rllm/rllm-llamacpp
./server.sh phi2
他のモデル名を引数として渡すことができます(利用可能なモデルを見るために引数なしでrun ./server.sh )。また、Huggingface 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トークン生成":実行
特定の形式に準拠し、5つのアイテムのみを含む、リストを生成するモデルを目指しているとします。
通常、これを達成するには、迅速なエンジニアリングが含まれ、次のような明確な指示で迅速に迅速に作成されます。
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コンテンツを含む。
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'}
このリポジトリには多くのコンポーネントが含まれており、必要なコンポーネントはユースケースに依存します。
既存のコントローラーモジュールを使用できます。それぞれサーバー側のPythonとJavaScriptを使用してスクリプトコントローラーを作成できるPyctrlとJSCTRLを提供します。 Pyaiciパッケージには、任意のコントローラーでスクリプトをアップロードおよび実行できるaiciコマンドラインツールが含まれています(CuriousのREST API定義も提供します)。
scripting pyctrlとjavascript hello world for jsctrlのためのPythonコードサンプル
ライブラリがコントローラーの上に構築されると予想されます。 Promptlibの例を提供します - Pyaiciパッケージを介してDeclctrlとの対話を生成するクライアント側のPythonライブラリです。
?comptlibを使用してDeclctrlと対話する例。
コントローラーは、クラウドまたはローカルAICI対応LLM推論エンジンで実行できます。 Libtorch+Cudaまたはllama.cppバックエンドで、提供された参照エンジン(RLLM)をローカルに実行できます。
新しいコントローラーを開発するには、AICI_ABIライブラリの使用を示すRust Starterプロジェクトを使用して、低レベルのAICIインターフェイスの実装を簡素化します。
?
新しいLLM推論エンジンにAICIサポートを追加するには、AICIランタイムに対応するプロトコルのLLMサイドを実装する必要があります。
最後に、提供されたコンポーネントのいずれかを変更することをお勧めします-PRは大歓迎です!
以下の写真のように、AICIはコントローラーからLLM推論エンジンを抽象化し、その逆も同様です。丸いノードは意欲的です。追加のレイヤーを上に構築できます - Promptlibを提供しますが、ガイダンス、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_*関数にのみアクセスできますaicirt 、部分的なWASIインターフェイスも公開しています。ただし、デバッグメッセージを印刷するためにファイル記述子1および2(STDOUTおよびSTDERR)をシムするfd_writeを除き、ほとんどすべての機能はNO-OPです。特に、WASMモジュールは、ファイルシステム、ネットワーク、またはその他のリソースにアクセスできません。また、スレッドをスピンしたり、タイマーにアクセスすることもできません(これは、Specter/Meltdown攻撃に関連しています)。
AICIコントローラーの計算のほとんどは、GPUのロジット生成と並行して、CPUで発生します。生成は、バッチ内の各シーケンスの新しいトークンに対してロジットが並行して生成されるステップで発生します(通常は1〜50)。これには、GPUメモリからのバッチ内のシーケンスについて、モデル全体とKVキャッシュを読み取ります。最適なバッチスループットの場合、モデルとKVキャッシュはGPUメモリの大部分を利用する必要があり、A100 GPU(80GB)でメモリ全体を読むには約40msかかります。
したがって、生成の各ステップは20〜50ミリ秒の順になります。慎重なエンジニアリングを使用すると、これはWASMにコンパイルされた錆の許可されたトークンのセットを計算するのに十分です。これらは、ネイティブに錆、または私たちが提供するPythonまたはJavaScript通訳を介して組み合わせることができます。
たとえば、LLAMAモデルの32000強力な語彙でセットされたトークンをコンピューティング許可します。
上記の数値は単一のシーケンス用ですが、各シーケンスは別々のプロセスで処理されるため、シーケンス(典型的な)よりも多くのコアがある場合、それらは変更されません。また、WASMに実装されたPythonインタープリターへの呼び出しのオーバーヘッドが含まれ、制約自体の錆びたWASMコードに戻ります。それらはすべて20〜50msの予算内でうまくいっているので、生成時間にまったく影響しないでください。
サンプリングの重要なパスには、いくつかのオーバーヘッドもあります。並列で10のシーケンスを実行すると、世代のステップあたり約0.3msになります(これは、使用される制約に関係なく)。オーバーヘッドは40シーケンスで約0.7msに上がります(ただし、まだ完全には最適化されていません)。
WebAssemblyは、ネイティブコードと比較して、最小限のオーバーヘッドを持つように設計されています。私たちの経験では、WASMTIMEではネイティブよりも2倍遅く、高度に最適化された錆コードが2倍遅くなります。これは、JavaScriptやPythonよりも10〜100倍優れています。
AMD EPYC 7V13でNVIDIA A100 GPUを使用して80GBのVRAMで行われたすべての測定。
AICIランタイムが提供する低レベルのインターフェイスは、次のことを可能にします。
WASMにコンパイルするあらゆる言語から利用できます。
このリポジトリは、Rustのコントローラーを簡単に実装できるRustライブラリを提供し、特定の制約(正規表現、YACC文法、サブストリング)の効率的な実装を提供します。また、これらの制約を接着できるPythonおよびJavaScriptの通訳も提供します。これらはすべて簡単に拡張できます。
AIコントローラーインターフェイスと、LLM Inferenceスタックの新しいレイヤーを定義するためのそのアイデアが役立つ場合は、次のリファレンスを使用してパッケージを引用してください。
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を使用して、すべてのレポでこれを1回だけ行う必要があります。
このプロジェクトは、Microsoftのオープンソース行動規範を採用しています。詳細については、FAQのコードを参照するか、追加の質問やコメントについては[email protected]にお問い合わせください。
このプロジェクトには、プロジェクト、製品、またはサービスの商標またはロゴが含まれる場合があります。 Microsoftの商標またはロゴの承認された使用は、Microsoftの商標およびブランドガイドラインに従うものであり、従わなければなりません。このプロジェクトの変更されたバージョンでのMicrosoft商標またはロゴの使用は、混乱を引き起こしたり、Microsoftのスポンサーシップを暗示したりしてはなりません。サードパーティの商標またはロゴの使用は、これらのサードパーティのポリシーの対象となります。