IBM ResearchとRed Hatから、LLMのカスタマイズとチューニングを効率的に行うためのプラットフォームであるInstructLabというオープンソースプロジェクトが発表されました。
InstructLabで扱うモデルはGGUF形式になっておりアプリからこれらのモデルを使う方法を調べたところ、OpenAIのAPIを使用してアクセスすることができましたのでその方法をまとめます。
モデルの起動
InstructLabのコマンドラインツール「ilab」を使ってモデルを起動します。
ilab model serve --model-path <モデルパス>
で実行するとモデルが提供されます。
すると以下のような出力が表示されます。
# ilab model serve --model-path models/granite-7b-lab-Q4_K_M.gguf
INFO 2024-08-14 05:15:07,262 serve.py:51: serve Using model 'models/granite-7b-lab-Q4_K_M.gguf' with -1 gpu-layers and 4096 max context size.
INFO 2024-08-14 05:15:08,285 server.py:218: server Starting server process, press CTRL+C to shutdown server...
INFO 2024-08-14 05:15:08,285 server.py:219: server After application startup complete see http://127.0.0.1:8000/docs for API.
APIはhttp://127.0.0.1:8000/docs
を見よというメッセージ出力されたので、このページを確認します。
APIドキュメントの確認
curl http://127.0.0.1:8000/docs
で確認したところ、タイトルが "🦙 llama.cpp Python API - Swagger UI" というSwagger UIを使用したAPIドキュメントのようでした。
さらに'/openapi.json' が指定されており、さらにこのファイルを確認しました。
# curl http://127.0.0.1:8000/openapi.json | python -m json.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 33284 100 33284 0 0 15.8M 0 --:--:-- --:--:-- --:--:-- 15.8M
{
"openapi": "3.1.0",
"info": {
"title": "\ud83e\udd99 llama.cpp Python API",
"version": "0.2.75"
},
"paths": {
"/v1/completions": {
"post": {
"tags": [
"OpenAI V1"
],
"summary": "Completion",
"operationId": "create_completion_v1_completions_post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateCompletionRequest"
}
}
},
"required": true
},
(省略)
llama.cpp PythonにはOpenAI互換の仕組みがあるようで、上記のAPIドキュメントにも"OpenAI V1"
の記載があります。
そこでOpenAPIやOpenAIのインタフェースでアクセスしてみました。
OPEN APIのREST APIでアクセス
curlコマンドでアクセスしてみます。
curl -s 'http://127.0.0.1:8000/v1/chat/completions' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{"model": "models/granite-7b-lab-Q4_K_M.gguf", "messages": [ { "role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is the highest mountain in the world?" } ]}'
以下のような答えが返ってきました!
{"id":"chatcmpl-7a674e47-74cd-4834-bcb0-bc900fe377a0","object":"chat.completion","created":1723613439,"model":"models/granite-7b-lab-Q4_K_M.gguf","choices":[{"index":0,"message":{"content":"The highest mountain in the world is Mount Everest, which has an elevation of 8,848.86 meters (29,031.7 feet) above sea level. It's located on the border between Nepal and China in the Himalayas.","role":"assistant"},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":23,"completion_tokens":61,"total_tokens":84}}
OPEN AIのSDKでアクセス
次にOpenAIのPythonSDKでアクセスしてみます。
from openai import OpenAI
client = OpenAI(
base_url= "http://127.0.0.1:8000/v1/",
api_key= "myapi",
max_retries= 3,
timeout= 1200
)
stream = client.chat.completions.create(
model= "models/granite-7b-lab-Q4_K_M.gguf",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the highest mountain in the world?" }
],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="")
api_key
は何かしら指定しないとエラーになるため、適当な文字列を指定しました。
これを実行するとストリーム表示で出力されました!
$ python InstructLab_openaiSDK_stream.py
The highest mountain in the world is Mount Everest, which has an elevation of approximately 8,848.86 meters (29,031.7 feet) above sea level, as confirmed by a 2020 survey conducted by China and Nepal.
LangChainのSDKでアクセス
最後にLangChainでアクセスしてみます。
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage
model = ChatOpenAI(
model_name="models/granite-7b-lab-Q4_K_M.gguf",
base_url="http://127.0.0.1:8000/v1/",
api_key="myapi"
)
messages = [
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content="What is the highest mountain in the world?")
]
for chunk in model.stream(messages):
print(chunk.content, end="", flush=True)
こちらもアクセスできました。
$ python InstructLab_langchain_stream.py
The highest mountain in the world is Mount Everest, which has an elevation of 8,848.86 meters (29,031.7 feet) above sea level. It's located on the border between Nepal and China's autonomous region of Tibet.
LangChainにはローカルのGGUFモデルにアクセスする他の方法もありそうなのですが、馴染みのあるAPIで簡単にアクセスできそうなことがわかりました!
参考