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

2025年3月7日金曜日

macOSのpodmanでOpen WebUIのコンテナを実行しAPEXのアプリの非モーダル・ダイアログとして開く

手元のMacbook ProでOpen WebUIを実行し、Oracle APEXのアプリケーションの非モーダル・ダイアログにiframeを使って埋め込んでみました。Open WebUIのコンテナはpodmanで実行しています。

ボタンをクリックしてOpen WebUIの画面を開きます。ユーザー認証はAPEXとOpen WebUIは別なので、それぞれ認証が必要です。


Ollamaはインストール済みで、ポート11434でアクセスできることを前提とします。また、podmanもインストール済みとします。

以下より、行った作業を紹介します。

Open WebUIのインストールについては、以下のGitHubのページを参照しています。

Open WebUIの設定などを保存するボリュームをあらかじめ作成します。

podman volume create open-webui

Open WebUIのインストールには、以下のコマンドを実行します。Open WebUIはコンテナ内ではポート8080で接続を待ち受けていますが、ホストの3000にマップしています。ホスト側で空いているポート番号を選びます。-vオプションでボリュームopen-webuiをマウントしているため、コンテナを再作成してもそれまでの設定は維持されます。

podman run -d -p 3000:8080 -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://host.containers.internal:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:main

% podman volume create open-webui

open-webui

% podman run -d -p 3000:8080 -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://host.containers.internal:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:main

Trying to pull ghcr.io/open-webui/open-webui:main...

Getting image source signatures

Copying blob sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1

Copying blob sha256:157e623d29844846bf1486ce1dc24b08b60c3c63a22c471a6ee19a86a7a5cbd5

Copying blob sha256:d51c377d94dadb60d549c51ba66d3c4eeaa8bace4935d570ee65d8d1141d38fc

Copying blob sha256:076b75118273dbd55842b522fbb55dc6d875eead95ef440121cde3d50cdd1ff2

Copying blob sha256:40d5353a5918e3b19dc38afc63437b08abe0d9f4ce2b36fbdd3cc53e9213b5f4

Copying blob sha256:987cac002684c8b2119edb1ec5fe98f5448ad8d2a2c6562214ec315072fe6657

Copying blob sha256:aebeb0b4e5d065f21d330eef147cd2ef7436852afebc7cf9dfcb96840a5fafc7

Copying blob sha256:03f562834d64768bdacbebf494f199f9034b63185d90330352efddee466a89c6

Copying blob sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1

Copying blob sha256:dc0f62a912f5d72123e4692b9061a84b7a9a760c13d3446e3a24c98e1ff1ace7

Copying blob sha256:93fdf9ebd111ee9c74695c24c27f88550f9b0703b6468c3c457b969e2f2a3ff0

Copying blob sha256:596be9ce6130cfeb35c532972dd08c024074442834fb7ff56810579df977a9cc

Copying blob sha256:07dc67f42781ccc91d3c05a4d19950c92b1bd09895fa433ac18c0601ac658c14

Copying blob sha256:7c2ef53b15e7b7715ffa172a0b8fd725b91ffc7086f4585c714f18aed424b30e

Copying blob sha256:e5511c24fa695881d58f8270fdcb752a72298908c3fc2daf41e4e431ed7ae481

Copying blob sha256:69de4f91fd3852c3e97ca94e14f39fe09a7438517ce13b27fc5dd9f0e010f6c7

Copying config sha256:92fc28ffd2eee83035f08f369fa321dbdcc0b733722bf18fb15248e3c9281397

Writing manifest to image destination

1bd8927fa97a7a2ab92ff36bf55483f10b3eb8aff5f44db7e25b6d25d7edf76b

% 


以上でOpen WebUIが実行されました。Open WebUIにアクセスします。

http://localhost:3000

Get startedをクリックします。


初回接続時は、管理者ユーザーの作成を求められます。

名前メールアドレスパスワードを入力し、Create Admin Accountをクリックします。


Open WebUIにサインインします。OK, 始めましょう!をクリックします。


Ollamaとチャットをする画面が開きます。


Open WebUIのインストールはできました。

Oracle APEXのアプリケーションからこの画面を、非モーダル・ダイアログとして開きます。

空のAPEXアプリケーションを作成します。名前Open WebUIとします。


アプリケーションが作成されたら、非モーダル・ダイアログとなるページを作成します。

ページの作成をクリックします。


空白ページを選択します。


作成するページの名前Open WebUIとします。

ページ作成ウィザードではページ・モードとして非モーダル・ダイアログは選択できないので、モーダル・ダイアログを選択します。モーダル・ダイアログとして作成されたページは、ページの装飾が最低限になります。

ページの作成をクリックします。


ページが作成されます。

外観ページ・モード非モーダル・ダイアログに変更します。テンプレート・オプションRemove Body Paddingチェックし、詳細Content PaddingRemove Paddingを選択します。ページの装飾は極力削除します。


テンプレート・オプションの設定です。


Content Bodyに新たにリージョンを作成します。

識別名前Open WebUIタイプURLを選択します。外観テンプレートなしを選択します。


リージョンの属性を開きます。

設定URLにOpen WebUIのURL、http://localhost:3000を設定します。組入れモードiFrameです。


ダイアログに組み込まれたiFrameがウィンドウにフィットするように、ページ・プロパティCSSインラインに以下を記述します。
iframe {
    width: 100%;
    height: 100vh; /* Full viewport height */
    border: none;  /* Optional: removes the border */
}

以上でOpen WebUIを開くページは完成です。

非モーダル・ダイアログのページを開くボタンを作成します。

動作アクションこのアプリケーションのページにリダイレクトを選択し、ターゲット非モーダル・ダイアログのページを指定します。


以上でアプリケーションは完成です。

アプリケーションを実行すると、APEXアプリケーションへのサインインが求められます。

APEXアプリケーションのアカウントでサインインします。


Open WebUIを開くボタンをクリックします。


Open WebUIの画面が開きます。

Open WebUIへのサインインを求められます。APEXアプリケーションのサインインとは別です。ただし、Open WebUI(http://localhost:3000)にサインイン済みであれば、その認証が引き継がれます。


Ollamaとチャットする画面が開きます。

テーマについてはAPEXの設定を引き継いでいるようです。


テーマ・ローラーを使ってテーマを切り替えると、Open WebUIの画面に反映されます。ただし、APEXアプリケーション全体に影響します。


あとは、普通に生成AIとチャットしてみましょう。


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

2024年12月13日金曜日

Oracle Database 23ai Freeをベクトル・ストアとしたDifyのローカル環境を作成する

オープンソースのLLMアプリ開発プラットフォームのDifyをApple MシリーズのMacbook Proにインストールします。インストールにあたって、ベクトル・ストアとしてOracle Database 23ai Freeを使用します。ベクトル検索の確認にはエンべディングの生成が必要ですが、それにはローカルで実行しているOllamaを呼び出します。

2025年7月14日追記 - Dify 1.6.0を使用した手順に更新しました。

ベクトル・ストアとして、すでにAPEX向けに作成したワークスペース・スキーマを使用します。DifyのDocker Composeはデフォルトで、Oracle Database 23ai Freeのコンテナを新規作成します。docker-compose.yamlのoracleprofilesの設定をoracleからoracle-skipへ変更することにより、すでに作成済みのスキーマへの接続に切り替えることができます。

謝辞:oracle-skipの設定については、以下の記事を参考にしています。
DifyでOracle Base Database Service(23ai)を利用する設定手順

以下より、Difyを動かすまでに行った作業を紹介します。作業を行ったマシンは、M4を積んだApple Macbook Pro、OSはmacOS Sequoia 15.5です。

概ね以下のDifyのドキュメントの記載に従って作業を行います。ただし、作業にはdockerの変わりにpodmanを使用します。podman composeを実行する際に外部のcompose providerとしてdocker-composeが呼び出されるように、docker-composeもインストールしておきます。

brewにてpodmanpodman-composeおよびdocker-composeをインストールします。

brew install podman podman-compose docker-compose

私の環境ではすでにインストール済みだったので、そのように報告されました。

% brew install podman podman-compose docker-compose

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

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

Warning: podman 5.5.2 is already installed and up-to-date.

To reinstall 5.5.2, run:

  brew reinstall podman

Warning: podman-compose 1.5.0 is already installed and up-to-date.

To reinstall 1.5.0, run:

  brew reinstall podman-compose

Warning: docker-compose 2.38.2 is already installed and up-to-date.

To reinstall 2.38.2, run:

  brew reinstall docker-compose

% 


podmanの構成コマンドは以下になります。CPU数やメモリ量(ディスクサイズはデフォルトで100GB)は、環境に合わせて調整します。

podman machine init
podman machine set --cpus 8 --memory 16384
podman machine ls
podman machine start

Difyをクローンします。

git clone https://github.com/langgenius/dify.git

% git clone https://github.com/langgenius/dify.git


Cloning into 'dify'...

remote: Enumerating objects: 184984, done.

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

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

remote: Total 184984 (delta 966), reused 683 (delta 669), pack-reused 183776 (from 4)

Receiving objects: 100% (184984/184984), 101.73 MiB | 7.09 MiB/s, done.

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

% 


Difyのリポジトリに含まれるdockerのディレクトリへ移動します。

cd dify/docker

% cd dify/docker

docker % ls

certbot elasticsearch ssrf_proxy

couchbase-server generate_docker_compose startupscripts

docker-compose-template.yaml middleware.env.example tidb

docker-compose.middleware.yaml nginx volumes

docker-compose.png pgvector

docker-compose.yaml README.md

docker % 


構成ファイルとして.envを作成します。雛形の.env.exampleをコピーします。

cp .env.example .env

docker % cp .env.example .env

docker % 


.envの設定を変更します。

私の環境ではpodmanをルートレス・モードで起動しているため、DifyのHTTPポートに80番を使用できません。以下のEXPOSE_NGINX_PORTEXPORT_NGINX_SSL_PORTの番号を変更します。以下ではそれぞれ80848484に変更しています。

# ------------------------------

# Docker Compose Service Expose Host Port Configurations

# ------------------------------

EXPOSE_NGINX_PORT=8084

EXPOSE_NGINX_SSL_PORT=8484


謝辞:EXPOSE_NGINX_PORTについては、Aran NakayamaさんのQiitaの記事を参考にしています。
podmanを使ってDifyをローカルで動かしてみる(Macユーザー向け)

VECTOR_STOREの設定をoracleに変更します。

# ------------------------------

# Vector Database Configuration

# ------------------------------ 


# The type of vector store to use.

# Supported values are `weaviate`, `qdrant`, `milvus`, `myscale`, `relyt`, `pgvector`, `pgvecto-rs`, `chroma`, `opensearch`, `oracle`, `tencent`, `elasticsearch`, `elasticsearch-ja`, `analyticdb`, `couchbase`, `vikingdb`, `oceanbase`, `opengauss`, `tablestore`,`vastbase`,`tidb`,`tidb_on_qdrant`,`baidu`,`lindorm`,`huawei_cloud`,`upstash`, `matrixone`.

VECTOR_STORE=oracle


Oracle Databaseへの接続先を設定します。

ORACLE_USERに接続先となるデータベース・ユーザー名ORACLE_PASSWORDに、その接続先ユーザーのパスワードを設定します。接続先となるOracle Databaseはホスト・ポートの1521で接続の待ち受けを行なっているので、ORACLE_DSNの設定はhost.containers.internal:1521/FREEPDB1になります。

ORACLE_IS_AUTONOMOUSはデフォルトでfalseになっています。ORACLE_CONFIG_DIRORACLE_WALLET_LOCATIONORACLE_WALLET_PASSWORDは接続先データベースとしてAutonomous Databaseを選択したときに意味を持つ設定と思われるため、そのままの設定にしています。

# Oracle configuration, only available when VECTOR_STORE is `oracle`

ORACLE_USER=<接続するデータベース・ユーザー>

ORACLE_PASSWORD=<ORACLE_USERのパスワード>

ORACLE_DSN=host.containers.internal:1521/FREEPDB1

ORACLE_CONFIG_DIR=/app/api/storage/wallet

ORACLE_WALLET_LOCATION=/app/api/storage/wallet

ORACLE_WALLET_PASSWORD=dify

ORACLE_IS_AUTONOMOUS=false 


docker-compose.yamlを開き、profilesの設定でoracleとなっている箇所をoracle-skipに変更します。

  # Oracle vector database

  oracle:

    image: container-registry.oracle.com/database/free:latest

    profiles:

      - oracle-skip

    restart: always

    volumes:

      - source: oradata

        type: volume

        target: /opt/oracle/oradata

      - ./startupscripts:/opt/oracle/scripts/startup

    environment:

      ORACLE_PWD: ${ORACLE_PWD:-Dify123456}

      ORACLE_CHARACTERSET: ${ORACLE_CHARACTERSET:-AL32UTF8}


接続先となるデータベース・ユーザーに、最低限必要な権限を与えます。

grant db_developer_role to <接続先データベース・ユーザー>;
grant execute on ctx_ddl to <接続先データベース・ユーザー>;

以下の例では、接続先データベース・ユーザーはWKSP_APEXDEVになっています。

docker % sql sys/*********@localhost/freepdb1 as sysdba



SQLcl: 月 7月 14 12:36:11 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> grant db_developer_role to wksp_apexdev;


Grantが正常に実行されました。


SQL> grant execute on ctx_ddl to wksp_apexdev;


Grantが正常に実行されました。


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04から切断されました

docker % 


接続先データベース・ユーザーで接続し、Oracle Textのレクサーをworld_lexerという名前で作成します。実際のレクサーは言語に応じて選択します。以下ではJAPANESE_LEXERを選択しています。
begin
    ctx_ddl.create_preference(
        preference_name => 'world_lexer',
        object_name => 'JAPANESE_LEXER'
    );
end;
/

docker % sql wksp_apexdev/********@localhost/freepdb1



SQLcl: 月 7月 14 12:46:02 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> begin

  2      ctx_ddl.create_preference(

  3          preference_name => 'world_lexer',

  4          object_name => 'JAPANESE_LEXER'

  5      );

  6  end;

  7* /


PL/SQLプロシージャが正常に完了しました。


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04から切断されました

docker % 


以上で必要最小限の設定ができました。

Difyの環境の作成と起動を行います。

podman compose up -d

docker % podman compose up -d

>>>> Executing external compose provider "/opt/homebrew/bin/docker-compose". Please see podman-compose(1) for how to disable this message. <<<<


[+] Running 11/11

  Network docker_default             Created                                                                  0.0s 

  Network docker_ssrf_proxy_network  Created                                                                  0.0s 

  Container docker-web-1             Started                                                                  0.2s 

  Container docker-redis-1           Started                                                                  0.2s 

  Container docker-sandbox-1         Started                                                                  0.2s 

  Container docker-db-1              Healthy                                                                  4.7s 

  Container docker-ssrf_proxy-1      Started                                                                  0.1s 

  Container docker-api-1             Started                                                                  4.7s 

  Container docker-plugin_daemon-1   Started                                                                  4.7s 

  Container docker-worker-1          Started                                                                  4.8s 

  Container docker-nginx-1           Started                                                                  4.8s 

docker % 


以上でDifyが起動しました。手元のブラウザから接続します。


初回接続時は、管理者アカウントの作成を求められます。

メールアドレスユーザー名パスワードを入力して、セットアップをクリックします。


直前に入力したメールアドレスパスワードを入力し、サインインします。


サインインできました。


これからベクトル検索ができることを確認します。

今回の作業ではチャット・モデルとしてqwen3:8bエンべディング・モデルとしてbge-m3:latestを使用します。

Ollamaでこれらのモデルをpullしておきます。

ollama pull bge-m3:latest
ollama pull qwen3:8b


 % ollama pull bge-m3:latest

pulling manifest 

pulling daec91ffb5dd: 100% ▕██████████████████▏ 1.2 GB                         

pulling a406579cd136: 100% ▕██████████████████▏ 1.1 KB                         

pulling 0c4c9c2a325f: 100% ▕██████████████████▏  337 B                         

verifying sha256 digest 

writing manifest 

success 

% ollama pull qwen3:8b

pulling manifest 

pulling a3de86cd1c13: 100% ▕██████████████████▏ 5.2 GB                         

pulling ae370d884f10: 100% ▕██████████████████▏ 1.7 KB                         

pulling d18a5cc71b84: 100% ▕██████████████████▏  11 KB                         

pulling cff3f395ef37: 100% ▕██████████████████▏  120 B                         

pulling 05a61d37b084: 100% ▕██████████████████▏  487 B                         

verifying sha256 digest 

writing manifest 

success 

% 


ユーザー名のプルダウン・メニューに含まれる設定を開きます。


モデルプロバイダーを開き、Ollamaインストールをクリックします。


Ollamaのプラグインをインストールします。


プラグインとしてOllamaが追加されます。Ollamaにモデルを追加します。


Model TypeとしてText Embeddingを選択します。Model Namebge-m3:latestBase URLは(DifyからみるとOllamaはコンテナ外のホストで動作しているため)、http://host.containers.internal:11434を指定します。

以上で保存します。


続けて、チャット・モデルを追加します。先ほどと同様にモデルを追加をクリックします。

Model TypeLLMを選択し、Model Nameとしてqwen3:8bを設定します。Base URLhttp://host.containers.internal:11434です。

Completion ModeChatを選択します。

今回はベクトル検索の確認だけを行うので、このモデルは使用しません。

以上で保存します。


システムモデル設定をクリックします。


システム推論モデルとしてqwen3:8b埋め込みモデルとしてbge-m3:latestを設定します。

以上を設定し、保存します。


モデルの設定は、以上で完了です。

ナレッジを開き、ナレッジベースを作成します。


データソースの選択としてテキストファイルからのインポートを選択し、とりあえず空のナレッジベースを作成します


ナレッジベースの名称testとします。作成をクリックします。


ナレッジベースtestが作成されます。

ファイルを追加します。


ナレッジベースに登録するファイルを選択します。

へ進みます。


Oracle Database 23ai Freeがベクトル・ストアとして使用されることを確認することが目的なので、パラメータの調整などは省きます。

チャンク設定汎用にします。インデックス・モード高品質を選択します。検索設定ベクトル検索を選択します。ベクトル・ストアやシステムモデルが設定されているため、これらはデフォルトで選択されています。

以上で保存して処理をクリックします。


ナレッジベースにドキュメントがアップロードされたことを確認し、ドキュメントに移動します。


検索テストを開きます。


ソーステキストベクトル検索と表示されていることを確認します。

ソーステキストとして適当な文章を入力し、テスト中をクリックします。

取得したチャンクが表示されることを確認します。


精度の確認はさておき、検索結果パラグラフが表示されていれば、ベクトル検索自体は成功しています。ベクトル・ストアとしてOracle Database 23ai Freeは正しく構成されています。

Difyでの確認作業は以上になります。

Oracle Database 23ai Freeに接続し、 接続先スキーマに作成されたオブジェクトを確認します。SQLclを使います。

sql <接続先データベース・ユーザー>/<パスワード>@localhost/freepdb1

docker % sql wksp_apexdev/*******@localhost/freepdb1



SQLcl: 月 7月 14 13:33:03 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> 


作成されている表を確認します。

select table_name from user_tables where table_name like '%EMBEDDING_VECTOR_INDEX%';

SQL> select table_name from user_tables where table_name like '%EMBEDDING_VECTOR_INDEX%';


TABLE_NAME                                                                        

_________________________________________________________________________________ 

DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$I    

DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$K    

DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$U    

DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$Q    

DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$C    

DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$B    

EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE                  

DR$IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE$N    


8行が選択されました。 


SQL> 


DR$で始まる表はOracle Textの全文索引を構成する表です。おそらくDifyではベクトル・ストアにオラクルを選択すると、ハイブリッド検索にOracle Text検索を使うように構成されているようです。

全文検索索引の構成を確認してみます。

select index_name, parameters from user_indexes where index_type = 'DOMAIN';

Oracle Text索引のレクサーとしてworld lexerが使用されていることが確認できます。

SQL> select index_name, parameters from user_indexes where index_type = 'DOMAIN';


INDEX_NAME                                                                   PARAMETERS                                                                             

____________________________________________________________________________ ______________________________________________________________________________________ 

IDX_DOCS_EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE    FILTER CTXSYS.NULL_FILTER SECTION GROUP CTXSYS.HTML_SECTION_GROUP LEXER world_lexer    


SQL> 


それ以外の表は列TEXTにチャンク分割された文字列、列METAにJSON形式のメタデータ、列EMBEDDINGにベクトルが保存されています。

SQL> desc EMBEDDING_VECTOR_INDEX_95FE2D6B_BFCB_460F_8269_41FD2588CBA3_NODE


名前           Nullかどうか    タイプ                  

____________ ___________ ____________________ 

ID                       VARCHAR2(100)        

TEXT         NOT NULL    CLOB                 

META                     JSON                 

EMBEDDING    NOT NULL    VECTOR(*,*,DENSE)    

SQL> 


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