1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Oracle Cloud] 仮想マシンで構築するPrivate Large Language Model Service:Private AI Services Container 26.2.1 を試してみた (2026/08/16)

1
Posted at

はじめに

Oracleが提供する Private AI Services Container 上で動作する、自前運用型の LLM 推論サービスPrivate Large Language Model Service(Private LLM Service)。バックエンドには llama.cpp と vLLM という 2 つの推論ランタイムが使われており、これらのランタイムが Private LLM Service を支えています。

このサービスは、オンプレミス環境、エアギャップ(インターネット非接続)環境、パブリッククラウドのいずれでも稼働させることができ、外部の LLM API にデータを送信することなく、自社のインフラ内で LLM 推論を完結させたい、というニーズに応える機能といえます。
Private AI Services Container 26.2.1 で提供される、CPU 向けのコンテナイメージを使って OCI(Oracle Cloud Infrastructure)の仮想マシン上に LLM 推論環境を構築してみました。

Private LLM Service で扱う LLM は、パラメータ数によって大まかに 3 つの規模に分類され、それぞれ適したユースケースが異なります。

パラメータ規模 主なユースケース
〜100億(10B)以下 Chat、RAG(Retrieval Augmented Generation)、Tool calling agents
100億〜700億(10B〜70B) Chat、RAG、Tool calling agents、Coding Agents
700億(70B)超 「思考」や推論を要する最も難易度の高いタスク

また、LLM を CPU で動かす際に必要となるリソースは、次のように整理されています。

リソース 何によって決まるか
CPU メモリ(RAM) モデルサイズにほぼ比例。量子化、コンテキスト長、同時実行数、ランタイムによって実際の必要量は変動
CPU コア数 推論のレイテンシとスループットに影響。コア数を増やすと応答速度・処理能力が向上する傾向
ディスク容量 ダウンロードした LLM の数とサイズに比例

本記事執筆時点では GPU デプロイメントや他クラウドでのデプロイメントは対象外です。

作業ステップ

以下のような操作フローで Private AI Services Container のセットアップし、LLM とチャットできるようになります。

  1. OCI 仮想マシンにログインし、作業用ディレクトリと環境変数を設定
  2. Private AI Services Container イメージ(large-cpu-avx512-infer-26.2.1.0.0)をダウンロード
  3. セットアップスクリプトを実行し、コンテナをインストール・起動・確認
  4. curl で /v1/chat/completions エンドポイントに POST し、LLM とチャットする(OpenAI API 互換のリクエスト/レスポンス)

Oracle Private Agent Factory や Open WebUI、AnythingLLM のような高機能な LLM クライアントも利用できますが、今回は cURL コマンドのみを使って動作確認を行います。

前提条件

  • OCI 仮想マシン
    • シェイプ: VM.Standard.E6.Flex
    • OS: Oracle Linux 9
    • OCPU数: 8 OCPU
    • メモリ: 64 GB RAM
    • ストレージ: カスタムのブート・ボリューム・サイズ 150 GB
    • Linux シェルで opc ユーザーとして操作できる権限(sudo 実行権限を含む)
    • jq コマンド(Oracle Linux 9 にはデフォルトでインストール済み)

8 OCPU はパフォーマンスとコストのトレードオフとして選択されたシェイプです。想定するモデルサイズや性能要件に応じて調整してください。

  • Oracle Container Registry(container-registry.oracle.com)にログインするための認証トークンおよび権限

Oracle Container Registry の認証トークン発行手順は、以下のブログが参考になります。
Getting Started with Private AI Services Container

手順

Step 1: 仮想マシンを作成

1〜200億パラメータ程度の LLM を利用できるように、以下のスペックで OCI 上に仮想マシンを作成します。

項目
OS Oracle Linux 9
シェイプ VM.Standard.E6.Flex
CPU 8 OCPU
メモリ 64 GB RAM
ストレージ カスタムのブート・ボリューム・サイズ 150 GB

仮想マシンのサイジングを検討する際は、以下の観点を確認してください。

  • 使いたいユースケースに対して LLM が十分な性能を持つか
  • ユースケースを満たす最小の LLM サイズはどれか
  • LLM が利用可能なメモリ(RAM)に収まるか
  • レイテンシ・スループットの観点で許容できる推論性能か
  • CPU コア数を増やすとレイテンシ・スループットは改善するが、ハードウェアコストも増加する
  • ダウンロードする全 LLM を格納できる十分なディスク容量があるか

Step 2: ブート・ボリュームを拡張する

仮想マシンを作成してログインしたら、OCI のブート・ボリュームを拡張してディスク容量を全て使えるようにします。

opc ユーザーの Linux シェルで以下を実行します。

sudo /usr/libexec/oci-growfs -y
df -h

実行後、ブート・ボリュームには約 123 GB の空き容量が確認できました。

実行例)

$ sudo /usr/libexec/oci-growfs -y
Volume Group: ocivolume
Volume Path: /dev/ocivolume/root
Mountpoint Data
---------------
          mountpoint: /
              source: /dev/mapper/ocivolume-root
     filesystem type: xfs
         source size: 29.4G
                type: lvm
                size: 29.5G
    physical devices: ['/dev/sda3']
    physical volumes: ['/dev/sda', '/dev/sda']
    partition number: ['3']
   volume group name: ocivolume
   volume group path: /dev/ocivolume/root

Partition dry run expansion "/dev/sda3" succeeded.
CHANGE: partition=3 start=4401152 old: size=93325312 end=97726463 new: size=310171615 end=314572766

Expanding partition /dev/sda3: Confirm?  Partition expand expansion "/dev/sda3" succeeded.
update-partition set to true
FLOCK: try exec open fd 9, on failure exec exits this program
FLOCK: /dev/sda: obtained exclusive lock
resizing 3 on /dev/sda using resize_sfdisk_gpt
314572800 sectors of 512. total size=161061273600 bytes
## sfdisk --unit=S --dump /dev/sda
label: gpt
label-id: B09F8120-4C25-4FDD-BAF9-F48ED5FDC6E0
device: /dev/sda
unit: sectors
first-lba: 34
last-lba: 97727250
sector-size: 512

/dev/sda1 : start=        2048, size=      204800, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=31299AB3-A07A-4F4E-A32F-98864683D426, name="EFI System Partition"
/dev/sda2 : start=      206848, size=     4194304, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=5D1C94EE-CB85-409C-BA68-F900136B30D7
/dev/sda3 : start=     4401152, size=    93325312, type=E6D6D379-F507-44C2-A23C-238F2A3DF928, uuid=FC568597-2B73-498F-A3D8-F2DAC325EEEF
padding 33 sectors for gpt secondary header
max_end=314572766 tot=314572800 pt_end=97726463 pt_start=4401152 pt_size=93325312
resize of /dev/sda returned 0.
FLOCK: /dev/sda: releasing exclusive lock

CHANGED: partition=3 start=4401152 old: size=93325312 end=97726463 new: size=310171615 end=314572766

Extending /dev/sda3 succeeded.
Device /dev/sda3 extended successfully.
Logical volume /dev/ocivolume/root extended successfully.

$ df -h
Filesystem                  Size  Used Avail Use% Mounted on
devtmpfs                    4.0M     0  4.0M   0% /dev
tmpfs                       5.2G     0  5.2G   0% /dev/shm
tmpfs                       2.1G  8.9M  2.1G   1% /run
efivarfs                    256K   17K  235K   7% /sys/firmware/efi/efivars
/dev/mapper/ocivolume-root  133G   11G  123G   8% /
/dev/mapper/ocivolume-oled   15G  144M   15G   1% /var/oled
/dev/sda2                   2.0G  453M  1.5G  23% /boot
/dev/sda1                   100M  7.7M   93M   8% /boot/efi
tmpfs                       1.1G     0  1.1G   0% /run/user/988
tmpfs                       1.1G     0  1.1G   0% /run/user/1000

Step 3: OS環境をセットアップ

Private AI Services Container のインストール・設定・実行に必要なディレクトリと環境変数を用意します。

mkdir -p /home/opc/privateai
mkdir -p /home/opc/config
mkdir -p /home/opc/models
mkdir -p /home/opc/secrets
export PRIVATE_DIR=/home/opc/privateai
export SECRETS_DIR=/home/opc/secrets
export CONFIG_DIR=/home/opc/config
export HOST=$(hostname -f); echo $HOST

Step 4: コンテナをダウンロード

使用するコンテナ・イメージを選択

Private AI Services Container は 7 種類の特化型コンテナイメージを含む単一プロダクトです。今回は以下のイメージを使用します。

  • large-cpu-avx512-infer-26.2.1.0.0

このコンテナには既定の LLM が含まれており、AVX-512 アーキテクチャの CPU 上で Private Large Language Model Service を有効化します。

Oracle Container Registry へログインし、コンテナをダウンロード

以下のコマンドで、Podman のインストール、Oracle Container Registry からのコンテナイメージのダウンロード、ZIP ファイルの取り出し、インストールスクリプトを含む ZIP の展開を行います。

sudo dnf install -y container-tools
podman login container-registry.oracle.com
IMAGEID=`podman create container-registry.oracle.com/database/private-ai:large-cpu-avx512-infer-26.2.1.0.0`
podman cp $IMAGEID:/privateai/scripts/privateai-setup-large-cpu-avx512-infer-26.2.1.0.0.zip .
unzip privateai-setup-large-cpu-avx512-infer-26.2.1.0.0.zip

実行例)

$ sudo dnf install -y container-tools
Ksplice for Oracle Linux 9 (x86_64)
Oracle Linux 9 OCI Included Packages (x86_64)
Oracle Linux 9 BaseOS Latest (x86_64)
Oracle Linux 9 Application Stream Packages (x86_64)
Oracle Linux 9 Addons (x86_64)
Oracle Linux 9 UEK Release 8 (x86_64)
Last metadata expiration check: 0:00:01 ago on Fri 14 Aug 2026 00:00:16 AM GMT.
Dependencies resolved.


Complete!

$ podman login container-registry.oracle.com
Username: Username@XXXX.com
Password: <Your Secret>

Login Succeeded!

$ IMAGEID=`podman create container-registry.oracle.com/database/private-ai:large-cpu-avx512-infer-26.2.1.0.0`
Trying to pull container-registry.oracle.com/database/private-ai:large-cpu-avx512-infer-26.2.1.0.0...
Getting image source signatures
Copying blob 62c44988cb34 done   |
Copying blob 53ba487209f7 done   |
Copying blob 8f848b427924 done   |
Copying blob 4dc22ee7b222 done   |
Copying blob 862a5f1397ff done   |
Copying blob 99f1b4dcaf22 done   |
Copying blob 0635847550c5 done   |
Copying blob be76aa0a298d done   |
Copying blob 7d4d900b061d done   |
Copying blob d3358fe5c691 done   |
Copying blob b6543c05667b done   |
Copying blob 24809fca92d8 done   |
Copying blob 9c573bd95e55 done   |
Copying config cd1635e829 done   |
Writing manifest to image destination


$ unzip privateai-setup-large-cpu-avx512-infer-26.2.1.0.0.zip
Archive:  privateai-setup-large-cpu-avx512-infer-26.2.1.0.0.zip
   creating: setup/
  inflating: setup/quickStart.sh
  inflating: setup/containerSetup.sh
  inflating: setup/SETUP_README.md
  inflating: setup/util.sh
  inflating: setup/configSetup.sh
  inflating: setup/secretsSetup.sh

Step 5: コンテナをインストール・起動・確認

以下のコマンドで、コンテナをインストールして起動します。
この例では、コンテナは HTTP プロトコル・既定の TCP ポート 8080 で動作するように設定しています。

cd /home/opc/setup
./secretsSetup.sh -s $SECRETS_DIR
./configSetup.sh -d $PRIVATE_DIR -s $SECRETS_DIR
./containerSetup.sh -d $PRIVATE_DIR --http

実行例)

$ cd /home/opc/setup
$ ./secretsSetup.sh -s $SECRETS_DIR
Enter keystore password:
Confirm keystore password:
  SUCC: Generated security directory at /home/opc/secrets
$ ./configSetup.sh -d $PRIVATE_DIR -s $SECRETS_DIR
  SUCC: Container UID 2001 maps to Host UID 102000

  SUCC: Copied PrivateAI security directory

  SUCC: Generated PrivateAI logs directory
$ ./containerSetup.sh -d $PRIVATE_DIR --http
Using image version large-cpu-avx512-infer-26.2.1.0.0
HTTPS connection enabled: false
  WARN: Low memory
        Recommended at least 16G of system memory

  SUCC: Container started

$

コンテナの起動には複数のフェーズがあり、既定の LLM が初回利用時に使える状態になるまで最大 3 分程度かかることがあります。

コンテナの起動状態を確認

コンテナが起動しているかを確認します。

podman ps

LLM がディスクからロードされている間は starting ステータスになります。コンテナがメモリに完全にロードされると unhealthy になり、リクエストを処理できる状態になると最終的に healthy になります。

実行例)

$ podman ps
CONTAINER ID  IMAGE                                                                                COMMAND     CREATED         STATUS                    PORTS                   NAMES
658b94afb557  container-registry.oracle.com/database/private-ai:large-cpu-avx512-infer-26.2.1.0.0              27 seconds ago  Up 27 seconds (starting)  0.0.0.0:8080->8080/tcp  privateai

コンテナのヘルスチェック

/health REST エンドポイントを確認します。

curl -i http://localhost:8080/health

有効な HTTP レスポンスが返ってくればコンテナはリクエストを処理できる状態です。エラーが返る場合は、まだ準備ができていません。

実行エラーの例)

$ curl -i http://localhost:8080/health
curl: (56) Recv failure: Connection reset by peer

実行例)

$ curl -i http://localhost:8080/health
HTTP/1.1 200 OK
date: Sun, 16 Aug 2026 05:34:49 GMT
x-server-id: dee9c798-494d-4918-ba4e-a96462677ce8
x-ratelimit-global-limit-requests: 30000
x-ratelimit-global-remaining-requests: 29999
x-ratelimit-global-reset-requests: 1
x-ratelimit-limit-requests: 30000
x-ratelimit-remaining-requests: 29999
x-ratelimit-reset-requests: 1
content-length: 0

ロード済みモデルを確認

以下のコマンドでロード済みモデルを確認します。

curl http://localhost:8080/v1/models | jq
  • large-cpu-avx512-infer-26.2.1.0.0 コンテナは、追加設定なしで LLM 推論とベクトル生成の両方が行える状態になっています
    • ロードされている LLM は Mistral.ai の 30 億パラメータモデル Ministral-3-3B-Reasoning-2512-Q8_0
    • ロードされているのは ONNX Runtime 用の既定のベクトル埋め込みモデル

実行例)

$ curl http://localhost:8080/v1/models | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1039  100  1039    0     0  86583      0 --:--:-- --:--:-- --:--:-- 86583
{
  "data": [
    {
      "id": "clip-vit-base-patch32-img",
      "modelDeployedTime": "2026-08-16T05:15:59.348809613Z",
      "modelSize": "335.37M",
      "modelCapabilities": [
        "IMAGE_EMBEDDINGS"
      ]
    },
    {
      "id": "Ministral-3-3B-Reasoning-2512-Q8_0",
      "modelDeployedTime": "2026-08-16T05:15:59.354852448Z",
      "modelSize": "3.40G",
      "modelCapabilities": [
        "TEXT_GENERATION"
      ]
    },
    {
      "id": "clip-vit-base-patch32-txt",
      "modelDeployedTime": "2026-08-16T05:15:59.349638173Z",
      "modelSize": "243.57M",
      "modelCapabilities": [
        "TEXT_EMBEDDINGS"
      ]
    },
    {
      "id": "multilingual-e5-large",
      "modelDeployedTime": "2026-08-16T05:15:59.351777649Z",
      "modelSize": "2.09G",
      "modelCapabilities": [
        "TEXT_EMBEDDINGS"
      ]
    },
    {
      "id": "all-minilm-l12-v2",
      "modelDeployedTime": "2026-08-16T05:15:59.346445503Z",
      "modelSize": "127.13M",
      "modelCapabilities": [
        "TEXT_EMBEDDINGS"
      ]
    },
    {
      "id": "multilingual-e5-base",
      "modelDeployedTime": "2026-08-16T05:15:59.350882358Z",
      "modelSize": "1.04G",
      "modelCapabilities": [
        "TEXT_EMBEDDINGS"
      ]
    },
    {
      "id": "all-mpnet-base-v2",
      "modelDeployedTime": "2026-08-16T05:15:59.347809482Z",
      "modelSize": "415.82M",
      "modelCapabilities": [
        "TEXT_EMBEDDINGS"
      ]
    }
  ]
}

Step 6: LLM とチャット

この記事では cURL ユーティリティを使用して LLM とチャットします。

Private AI Services Container は、/v1/chat/completions エンドポイントで OpenAI API 互換の REST インターフェースを実装しています。リクエストには以下の情報を指定します。

  • 使用する LLM モデル名
  • LLM に送信するメッセージ(プロンプト)
  • Private AI Services Container の URL

以下の例では localhost を使用していますが、コンテナが稼働するホストの IP アドレスや完全修飾ドメイン名を指定することも可能です。これにより、ローカル・リモートいずれの Private AI Services Container に対しても同じ cURL コマンドで操作できます。

curl --noproxy '*' -X POST --header 'Content-Type: application/json' --header "Authorization: Bearer $API_KEY" --cacert $SECRETS_DIR/cert.pem  --data '{
        "model": "Ministral-3-3B-Reasoning-2512-Q8_0",
        "messages":[
                {"role": "user", "content": "こんにちは"}
        ],
        "max_tokens": 256,
        "temperature": 0.7,
        "stream": false
}' http://localhost:8080/v1/chat/completions | jq

実行例)

$ curl --noproxy '*' -X POST --header 'Content-Type: application/json' --header "Authorization: Bearer $API_KEY" --cacert $SECRETS_DIR/cert.pem  --data '{
        "model": "Ministral-3-3B-Reasoning-2512-Q8_0",
        "messages":[{"role": "user", "content": "こんにちは"}],
        "max_tokens": 256,
        "temperature": 0.7,
        "stream": false
}' http://localhost:8080/v1/chat/completions | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1712  100  1506  100   206     46      6  0:00:34  0:00:32  0:00:02   364
{
  "id": "chatcmpl-qXoAsAuQBG4YTDBhvGVkMOF9i0BTITTa",
  "object": "chat.completion",
  "created": 1786859719,
  "model": "Ministral-3-3B-Reasoning-2512-Q8_0",
  "choices": [
    {
      "index": 0,
      "message": {
        "reasoning_content": "Okay, the user says \"こんにちは\" which is a Japanese greeting. They might be asking how to say \"hello\" in Japanese or perhaps are just greeting me. Since the user is in Japanese, I should respond in Japanese as well.\n\nFirst, I should confirm that I understand the greeting. \"こんにちは\" is indeed a common way to say \"hello\" in Japanese, especially in the morning or afternoon.\n\nNow, what should I say back? A common response is \"こんに ちは\" again, but perhaps I can add something like \"How are you?\" or \"Nice to meet you.\"\n\nBut to keep it simple and friendly, maybe I can just say \"こん にちは\" and perhaps add a smiley to make it friendly.\n\nAlternatively, if the user is just saying hello, I can respond with a similar greeting and maybe ask how they are doing.\n\nLet me draft a response.\n\nPossible responses:\n1. \"こんにちは! How are you?\"\n2. \"こんにちは! この天気、楽しいですか?\" (Hello! Is the weather nice today?)\n3. \"こんにちは! 幸せな日を!\" (Hello! May you have a happy day!)\n\nI think the first one is straightforward and polite.\n\nBut to be a bit more personal, maybe",
        "content": "",
        "role": "assistant"
      },
      "finish_reason": "length"
    }
  ],
  "usage": {
    "prompt_tokens": 127,
    "total_tokens": 383,
    "completion_tokens": 256
  }
}

応答時間・結果は、
モデル、設定、プロンプト、ワークロード、利用可能な計算リソースによって変動します。大きな LLM ほど応答に時間がかかる傾向があり、CPU リソースを増やすことで応答時間を短縮できる場合があります。

クリーンアップ

検証で作成したリソースが不要になった場合は、以下の手順で削除します。

# 稼働中のコンテナを確認する
podman ps -a

# コンテナを停止・削除する
podman stop <確認したコンテナID>
podman rm <確認したコンテナID>

# ダウンロードしたイメージを削除する(任意)
podman rmi container-registry.oracle.com/database/private-ai:large-cpu-avx512-infer-26.2.1.0.0

# セットアップ用に作成したディレクトリ・ファイルを削除する(任意)
rm -rf /home/opc/privateai /home/opc/config /home/opc/models /home/opc/secrets /home/opc/setup
rm -f privateai-setup-large-cpu-avx512-infer-26.2.1.0.0.zip

仮想マシン 自体が不要な場合は、OCI コンソールから該当のコンピュート・インスタンスを終了(Terminate)してください。

おわりに

今回の検証を通じて、以下のポイントを確認しました。

  • OCI 上に CPU ベースの 仮想マシン(VM.Standard.E6.Flex、8 OCPU、64 GB RAM)を用意し、Private AI Services Container 26.2.1 をダウンロード・インストールするまでの一連の流れ
  • podman ps によるコンテナ起動状態の遷移(starting → unhealthy → healthy)と、/health エンドポイントによるヘルスチェックの方法
  • /v1/models エンドポイントで、コンテナに既定でロードされている LLM(Ministral-3-3B-Reasoning-2512-Q8_0)と埋め込みモデルを確認できること
  • /v1/chat/completions エンドポイントが OpenAI API 互換のインターフェースを提供しており、cURL のみでも LLM とのチャットが行えること
  • 追加のクライアントツールをインストールしなくても、cURL だけで Private LLM Service の動作検証が完結すること

社内データを外部に出さずに LLM 推論基盤を自前で構築・検証したいエンジニアや、Oracle Cloud Infrastructure 上でのプライベート AI 基盤の PoC を検討しているインフラ担当者にとって、参考になる内容です。

参考情報

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?