はじめに
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 とチャットできるようになります。
- OCI 仮想マシンにログインし、作業用ディレクトリと環境変数を設定
- Private AI Services Container イメージ(large-cpu-avx512-infer-26.2.1.0.0)をダウンロード
- セットアップスクリプトを実行し、コンテナをインストール・起動・確認
- 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 用の既定のベクトル埋め込みモデル
- ロードされている LLM は Mistral.ai の 30 億パラメータモデル
実行例)
$ 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 を検討しているインフラ担当者にとって、参考になる内容です。