ラベル ONNX の投稿を表示しています。 すべての投稿を表示
ラベル ONNX の投稿を表示しています。 すべての投稿を表示

2025年5月23日金曜日

macOSのMicrosoft AI Foundry LocalでLLMを実行しOracle APEXのアプリケーションから呼び出す

最近パブリックプレビューがリリースされたMicrosoft AI Foundry LocalでLLMを実行し、Oracle APEXのアプリケーションから呼び出してみます。作業はmacOSで行い、LLMを呼び出すOracle APEXは、ローカルのpodmanのコンテナで実行します。

ローカル環境でのOracle APEXの構成について、以下の記事で紹介しています。

podmanを使ってOracle Database FreeとOracle REST Data Servicesをコンテナとして実行する

また、Oracle APEXの著名な開発パートナーであるUnited Codesさんが、GitHubにAPEXの構築スクリプトを含むリポジトリを公開しています。

Containerized APEX Development Environment
https://github.com/United-Codes/uc-local-apex-dev

今回の記事はMicrosoft AI Foundry Localの動作確認を目的としています。そのため、すでに以下の記事で作成済みのAPEXアプリケーションを使って動作を確認します。

Qwen3 30B A3B MLXをMacのLM Studioで実行しAPEXアプリケーションからツール呼び出しを行う

この記事で作成したAPEXアプリケーションのエクスポートは以下です。このアプリケーションでは、データベース・サーバーからLLMを呼び出します
https://github.com/ujnak/apexapps/blob/master/exports/chat-with-generative-ai-hc-242.zip

日本語を追加学習したサイバーエージェントのDeepSeek-R1のモデルで小説を生成して共有するアプリを作る
https://apexugj.blogspot.com/2025/01/deepseek-r1-novel-generator.html

少々アプリケーションを改変したエクスポートを以下に置きました。このアプリケーションでは、ブラウザからLLMを呼び出します
https://github.com/ujnak/apexapps/blob/master/exports/novel-generator-242.zip

以下よりMicrosoft AI Foundry LocalをmacOSで実行するために行なった作業を記録します。

作業にあたって、Microsoftのサイトから参照できるFoundry Localの概要クイックスタートを参照しました。

macOSでは最初に以下のコマンドを実行します。

brew tap microsoft/foundrylocal

% brew tap microsoft/foundrylocal

==> Tapping microsoft/foundrylocal

Cloning into '/opt/homebrew/Library/Taps/microsoft/homebrew-foundrylocal'...

remote: Enumerating objects: 126, done.

remote: Counting objects: 100% (22/22), done.

remote: Compressing objects: 100% (14/14), done.

remote: Total 126 (delta 12), reused 8 (delta 8), pack-reused 104 (from 1)

Receiving objects: 100% (126/126), 313.79 KiB | 1.92 MiB/s, done.

Resolving deltas: 100% (65/65), done.

Tapped 2 formulae (17 files, 335.2KB).


foundrylocalをインストールします。

brew install foundrylocal

% brew install foundrylocal

==> Downloading https://formulae.brew.sh/api/formula.jws.json

==> Downloading https://formulae.brew.sh/api/cask.jws.json

==> Fetching microsoft/foundrylocal/foundrylocal

==> Downloading https://github.com/microsoft/Foundry-Local/releases/download/v0.3.9267/FoundryLocal-osx-arm64-0.3.9267.42993.zip

==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-2e65be/958239663/158c7cec-ee9a-4694-a3b7-cb3091759f6c?X-Amz-Al

################################################################################################################################################## 100.0%

==> Installing foundrylocal from microsoft/foundrylocal

🍺  /opt/homebrew/Cellar/foundrylocal/0.3.9267.42993: 9 files, 75.6MB, built in 1 second

==> Running `brew cleanup foundrylocal`...

Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.

Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).

               


以上でFoundry Localのインストールは完了です。

Foundry Localで利用可能なモデルを一覧します。

foundry model list

% foundry model list

Alias                          Device     Task               File Size    License      Model ID            

-----------------------------------------------------------------------------------------------

phi-4                          GPU        chat-completion    8.37 GB      MIT          Phi-4-generic-gpu   

                               CPU        chat-completion    10.16 GB     MIT          Phi-4-generic-cpu   

--------------------------------------------------------------------------------------------------------

mistral-7b-v0.2                GPU        chat-completion    4.07 GB      apache-2.0   mistralai-Mistral-7B-Instruct-v0-2-generic-gpu

                               CPU        chat-completion    4.07 GB      apache-2.0   mistralai-Mistral-7B-Instruct-v0-2-generic-cpu

-------------------------------------------------------------------------------------------------------------------------------------

phi-3.5-mini                   GPU        chat-completion    2.16 GB      MIT          Phi-3.5-mini-instruct-generic-gpu

                               CPU        chat-completion    2.53 GB      MIT          Phi-3.5-mini-instruct-generic-cpu

------------------------------------------------------------------------------------------------------------------------

phi-3-mini-128k                GPU        chat-completion    2.13 GB      MIT          Phi-3-mini-128k-instruct-generic-gpu

                               CPU        chat-completion    2.54 GB      MIT          Phi-3-mini-128k-instruct-generic-cpu

---------------------------------------------------------------------------------------------------------------------------

phi-3-mini-4k                  GPU        chat-completion    2.13 GB      MIT          Phi-3-mini-4k-instruct-generic-gpu

                               CPU        chat-completion    2.53 GB      MIT          Phi-3-mini-4k-instruct-generic-cpu

-------------------------------------------------------------------------------------------------------------------------

phi-4-mini-reasoning           GPU        chat-completion    3.15 GB      MIT          Phi-4-mini-reasoning-generic-gpu

                               CPU        chat-completion    4.52 GB      MIT          Phi-4-mini-reasoning-generic-cpu

-----------------------------------------------------------------------------------------------------------------------

deepseek-r1-14b                GPU        chat-completion    10.27 GB     MIT          deepseek-r1-distill-qwen-14b-generic-gpu

-------------------------------------------------------------------------------------------------------------------------------

deepseek-r1-7b                 GPU        chat-completion    5.58 GB      MIT          deepseek-r1-distill-qwen-7b-generic-gpu

------------------------------------------------------------------------------------------------------------------------------

phi-4-mini                     GPU        chat-completion    3.72 GB      MIT          Phi-4-mini-instruct-generic-gpu

----------------------------------------------------------------------------------------------------------------------

qwen2.5-0.5b                   GPU        chat-completion    0.68 GB      apache-2.0   qwen2.5-0.5b-instruct-generic-gpu

                               CPU        chat-completion    0.80 GB      apache-2.0   qwen2.5-0.5b-instruct-generic-cpu

------------------------------------------------------------------------------------------------------------------------

qwen2.5-coder-0.5b             GPU        chat-completion    0.52 GB      apache-2.0   qwen2.5-coder-0.5b-instruct-generic-gpu

                               CPU        chat-completion    0.80 GB      apache-2.0   qwen2.5-coder-0.5b-instruct-generic-cpu

------------------------------------------------------------------------------------------------------------------------------

qwen2.5-1.5b                   GPU        chat-completion    1.51 GB      apache-2.0   qwen2.5-1.5b-instruct-generic-gpu

                               CPU        chat-completion    1.78 GB      apache-2.0   qwen2.5-1.5b-instruct-generic-cpu

------------------------------------------------------------------------------------------------------------------------

qwen2.5-7b                     GPU        chat-completion    5.20 GB      apache-2.0   qwen2.5-7b-instruct-generic-gpu

                               CPU        chat-completion    6.16 GB      apache-2.0   qwen2.5-7b-instruct-generic-cpu

----------------------------------------------------------------------------------------------------------------------

qwen2.5-coder-1.5b             GPU        chat-completion    1.25 GB      apache-2.0   qwen2.5-coder-1.5b-instruct-generic-gpu

                               CPU        chat-completion    1.78 GB      apache-2.0   qwen2.5-coder-1.5b-instruct-generic-cpu

------------------------------------------------------------------------------------------------------------------------------

qwen2.5-coder-7b               GPU        chat-completion    4.73 GB      apache-2.0   qwen2.5-coder-7b-instruct-generic-gpu

                               CPU        chat-completion    6.16 GB      apache-2.0   qwen2.5-coder-7b-instruct-generic-cpu

----------------------------------------------------------------------------------------------------------------------------

qwen2.5-14b                    GPU        chat-completion    9.30 GB      apache-2.0   qwen2.5-14b-instruct-generic-gpu

                               CPU        chat-completion    11.06 GB     apache-2.0   qwen2.5-14b-instruct-generic-cpu

-----------------------------------------------------------------------------------------------------------------------

qwen2.5-coder-14b              GPU        chat-completion    8.79 GB      apache-2.0   qwen2.5-coder-14b-instruct-generic-gpu

                               CPU        chat-completion    11.06 GB     apache-2.0   qwen2.5-coder-14b-instruct-generic-cpu

% 


今の所、利用できるモデルは、Phi(Microsoft - 米国)、Mistral(Mistral AI - フランス)、DeepSeek-R1(DeepSeek - 中国)、Qwen2.5(アリババ - 中国)のようです。

確認作業にPhi-4を使うことにします。

model runコマンドを実行します。実行するモデルに別名のphi-4を指定すると、ローカルのマシンにあった(GPUの有無など)モデルが自動的に選択されます。

foundry model run phi-4
 
モデルがローカルになければ、モデルのダウンロードが開始します。その後、モデルがロードされ呼び出し可能になります。

% foundry model run phi-4

Downloading model...

[####################################] 100.00 % [Time remaining: about 0s]        29.3 MB/s

🕚 Loading model... 

🟢 Model Phi-4-generic-gpu loaded successfully


Interactive Chat. Enter /? or /help for help.


Interactive mode, please enter your prompt

> /exit

% 


-----------------------------------------------------------------------------------------------------------------------

foundry modelコマンドを使っていて気になる点がいくつかありました。

model runコマンドのヘルプを見ると--interactiveというオプションがあり、falseの指定で対話モードにならないと解釈できます。実際には--interactive falseをつけて実行しても、対話モードになります。

foundry model run phi-4 --interactive false

% foundry model run phi-4 --interactive false

Model phi-4 was found in the local cache.


Interactive Chat. Enter /? or /help for help.


Interactive mode, please enter your prompt

> 


非対話モードでモデルを動かすにはmodel loadコマンドを使用します。

foundry model load phi-4

% foundry model load phi-4              

🕓 Loading model... 

🟢 Model phi-4 loaded successfully

%


ただし、model loadコマンドはモデルのダウンロードをしません。

% foundry model load phi-4              

🕛 Loading model... Exception: Failed: Loading model phi-4 from http://localhost:5273/openai/load/Phi-4-generic-gpu?ttl=600&ep=webgpu

Bad Request

Failed loading model Phi-4-generic-gpu

Model was not found locally. Please run 'foundry model download <model name>'.

% 


そのためmodel loadの前にmodel downloadを実行し、あらかじめモデルをキャッシュしておきます。

foundry model download phi-4
foundry cache ls

% foundry model download phi-4

Downloading model...

[####################################] 100.00 % [Time remaining: about 0s]        31.0 MB/s

Tips:

- To find model cache location use: foundry cache location

- To find models already downloaded use: foundry cache ls

% foundry cache ls

Models cached on device:

   Alias                         Model ID

💾 phi-4                         Phi-4-generic-gpu

% 


TTLのデフォルトは600、つまり未使用状態が10分続くとモデルはアンロードされます。TTLを延長するには、--ttlオプションに秒数を与えます。

foundry model load phi-4 --ttl 3600

% foundry model load phi-4 --ttl 3600

🕓 Loading model... 

🟢 Model phi-4 loaded successfully

% 


model runコマンドで別のモデルをロードすると、ロード済みのモデルがアンロードされます。ロード済みのモデルを維持するには、オプションとして--retain trueを与えます。model loadでロードする場合は、ロード済みのモデルは維持されます。

foundry model run deepseek-r1-14b

% foundry model run deepseek-r1-14b                            

Model deepseek-r1-14b was found in the local cache.

Unloading existing models. Use --retain true to keep additional models loaded.

🕔 Loading model... 

🟢 Model deepseek-r1-distill-qwen-14b-generic-gpu loaded successfully


Interactive Chat. Enter /? or /help for help.


Interactive mode, please enter your prompt

/exit

% foundry service ps

Models running in service:

    Alias                          Model ID            

🟢  deepseek-r1-14b                deepseek-r1-distill-qwen-14b-generic-gpu

% 


Aliasが指定できるのはmodel runmodel downloadmodel loadコマンドです。model unloadコマンドではModel IDを指定する必要があります。

foundry model unload deepseek-r1-distill-qwen-14b-generic-gpu

% foundry model unload deepseek-r1-14b

Exception: Failed: Unloading model deepseek-r1-14b

Bad Request

Failed unloading model deepseek-r1-14b

Model was not found locally. Please run 'foundry model download <model name>'.

% foundry model unload deepseek-r1-distill-qwen-14b-generic-gpu

Model deepseek-r1-distill-qwen-14b-generic-gpu was unloaded

ynakakoshi@Ns-Macbook ~ % 


-----------------------------------------------------------------------------------------------------------------------

モデルが実行されているどうかは、service psコマンドで確認できます。

foundry service ps

% foundry service ps

Models running in service:

    Alias                          Model ID            

🟢  phi-4                          Phi-4-generic-gpu   

% 


Foundry LocalはOpenAI互換のChat Completions APIをサポートしています。APIのエンドポイントはservice statusコマンドで確認できます。

foundry service status

Foundry Localのサービスがhttp://localhost:5273/で待ち受けしていることが確認できます。これよりOpenAI Chat Completions APIのエンドポイントは以下になります。

http://localhost:5273/v1/chat/completions

% foundry service status

🟢 Model management service is running on http://localhost:5273/openai/status

% 


Foundry Localがサービスを待ち受けるサービスURLのポートは固定ではありません。Microsoftから提供されているFoundry Local SDKでは、FoundryLocaclManagerというクラスが提供されていて、そのクラスからFoundry LocalのサービスURLを取得することができます。APEXからFoundry Localを呼び出す場合はSDKが使えないため、必ずサービスURLを確認してアプリケーションに設定する必要があります。


ツール呼び出しの確認


最初にChat with Generative AI(chat-with-generative-ai-hc-242.zip)をインストールして、Foundry Localで実行しているPhi-4を呼び出してみます。

コンテナで動作しているデータベースからFoundry Localを呼び出すため、API Endpointhttp://host.containers.internal:5273/v1/chat/completionsModel NamePhi-4-generic-gpuを指定します。

最終的な応答は以下でした。
日本の人口を取得するために、WKSP_APEXDEVスキーマ内の関連するテーブルをクエリする必要があります。通常、人口データは「COUNTRIES」テーブルに格納されています。以下は、日本の人口を取得するためのSQL SELECT文です: ```sql SELECT POPULATION FROM WKSP_APEXDEV.COUNTRIES WHERE COUNTRY_NAME = 'Japan'; ``` このクエリは、国名が「Japan」であるレコードの人口を取得します。
質問の回答にはなっていますが、ツール呼び出しが行われていません。


Foundry Local REST APIリファレンスを参照すると、リクエストボディにfunctionsやfunction_callが含まれていて、toolsは追加のファウンドリローカルプロパティになっています。OpenAIのChat Completions APIではtoolsとtool_callsの使用が推奨されていて、このAPEXアプリケーションが使用しているパッケージUTL_OPENAI_CHAT_APIでもtoolsとtool_callsを使用しています。

この部分は少し気になりますが、実際にはモデルがツール呼び出しに対応していないようです。

Foundry Localが提供しているカスタムAPIの/foundry/listを呼び出すと、Foundry Localで使用可能なモデルの一覧をJSON形式で取得できます。その中のモデルの属性にsupportsToolCallingがあり、すべてのモデルについてfalseになっていました。つまり、Foundry Localが提供しているモデルの中でツール呼び出しに対応しているモデルは、現時点では無いみたいです。

curl http://localhost:5273/foundry/list | jq -r '.[] | [.name, .maxOutputTokens, .supportsToolCalling ] | @tsv' | column -t

% curl http://localhost:5273/foundry/list | jq -r '.[] | [.name, .maxOutputTokens, .supportsToolCalling ] | @tsv' | column -t

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100 38716  100 38716    0     0  26890      0  0:00:01  0:00:01 --:--:-- 26886

Phi-4-generic-gpu                               2048  false

Phi-4-generic-cpu                               2048  false

mistralai-Mistral-7B-Instruct-v0-2-generic-gpu  2048  false

mistralai-Mistral-7B-Instruct-v0-2-generic-cpu  2048  false

Phi-3.5-mini-instruct-generic-gpu               2048  false

Phi-3.5-mini-instruct-generic-cpu               2048  false

Phi-3-mini-128k-instruct-generic-gpu            2048  false

Phi-3-mini-128k-instruct-generic-cpu            2048  false

Phi-3-mini-4k-instruct-generic-gpu              2048  false

Phi-3-mini-4k-instruct-generic-cpu              2048  false

Phi-4-mini-reasoning-generic-gpu                2048  false

Phi-4-mini-reasoning-generic-cpu                2048  false

deepseek-r1-distill-qwen-14b-generic-gpu        2048  false

deepseek-r1-distill-qwen-7b-generic-gpu         2048  false

Phi-4-mini-instruct-generic-gpu                 2048  false

qwen2.5-0.5b-instruct-generic-gpu               2048  false

qwen2.5-0.5b-instruct-generic-cpu               2048  false

qwen2.5-coder-0.5b-instruct-generic-gpu         2048  false

qwen2.5-coder-0.5b-instruct-generic-cpu         2048  false

qwen2.5-1.5b-instruct-generic-gpu               2048  false

qwen2.5-1.5b-instruct-generic-cpu               2048  false

qwen2.5-7b-instruct-generic-gpu                 2048  false

qwen2.5-7b-instruct-generic-cpu                 2048  false

qwen2.5-coder-1.5b-instruct-generic-gpu         2048  false

qwen2.5-coder-1.5b-instruct-generic-cpu         2048  false

qwen2.5-coder-7b-instruct-generic-gpu           2048  false

qwen2.5-coder-7b-instruct-generic-cpu           2048  false

qwen2.5-14b-instruct-generic-gpu                2048  false

qwen2.5-14b-instruct-generic-cpu                2048  false

qwen2.5-coder-14b-instruct-generic-gpu          2048  false

qwen2.5-coder-14b-instruct-generic-cpu          2048  false

% 



ストリーム出力の確認


小説生成器(novel-generator-242.zip)をインストールして、Foundry Localで実行しているPhi-4を呼び出してみます。

Foundry Localをブラウザから呼び出すため、Endpoint URLhttp://localhost:5273/v1/chat/completionsになります。Model NamePhi-4-generic-gpuです。


ブラウザからFoundry Localのモデルを呼び出すことができ、また、ストリーミングも上手く動作しています。

気になった点としてtemperatureがあります。temperatureに2を指定しても(Foundry Localでは0から2の範囲で指定可)、まったく同じ小説が生成されます。送信メッセージにtemperatureは正しく含まれているはずなのですが、理由は不明です。

モデルのロード時にTTLを指定していないとデフォルトの10分間になります。10分間が過ぎてモデルがアンロードされていると、そのモデルへのリクエストを受け付けた時点でモデルのロードが始まります。Foundry Localを実行している環境に依存すると思いますが、Phi-4-generic-gpuで30秒程度ロードに時間がかかり、ロードが完了するまで画面はエラー・メッセージも出さずに止まった状態になります。これはFoundry Localの応答が遅いわけではありません。作業内容によってはTTLは延長した方がよいでしょう。


カスタムAPI


Foundry LocalはOpenAI互換のChat Completions APIに加えて、Foundry Local固有のカスタムAPIを提供しています。

GET /foundry/listとGET /openai/modelsの結果を表示する簡単なAPEXアプリケーションを作成して、動作を確認してみました。
https://github.com/ujnak/apexapps/blob/master/exports/foundry-local-custom-api.zip

GET /foundry/listはfoundry model lsに対応する情報が得られますが、それよりも遥かに詳細です。


GET /openai/modelsでは、foundry cache lsに対応する情報が得られます。


ロード済みのモデルを一覧したり、モデルのロードやアンロードもAPI呼び出しで実行できるので、便利かもしれません。

今回の記事は以上になります。