Loading...

2024-06-07(金) 15:00

🤖 Ollamaを使ってLlama3やPhi3をサーバとして動かしてAPIで操作する

AILlamaOllamaUbuntu
Ollamaを使ってLlamaやPhi3をUbuneu上でサーバとして動かし、curlコマンドを使ってHTTPリクエストで質問を送信し、その結果を確認するまでの手順を解説します。

目次

前提と注意事項

この記事では以下を前提としています。

  • Ubuntu 22.04
  • Ollama の実行環境は構築済みとします。
  • Ollama のバージョンは 0.1.41 です。

本記事では、以下の Ollama の公式リポジトリに記載されている内容を参考にしています。

ollama/ollama

Get up and running with large language models.

github.com

この記事のゴール

以下のようなcurlコマンドで Llama3 に質問を送信し、その結果を確認することをゴールとします。

curlでPhi3に質問を送信する
$ curl http://localhost:11434/api/chat -d '{
  "model": "phi3:mini",
  "stream": false,
  "messages": [
    { "role": "user", "content": "なぜ空はあおいの?" }
  ]
}'

上記を実行すると、回答の正確さや自然さは別として以下のように回答が返ってきます。

curlでPhi3に質問を送信する
{
  "model":"phi3:mini",
  "created_at":"2024-06-07T06:06:36.259965418Z",
  "message":{
    "role":"assistant",
    "content":" 日本語での回答として、「空は青いのから、大気中に雲や雨滴が含まれているためです。それぞれの微粒子は光を反射し、観測者にとって見えない青色を伝えます。」\n\n日本語でのステップバイステップで説明する場合:\n\n1. 空は何かが含まれていることから青い色に見えるのです。\n2. 空中に雲や水を含んだ液体があり、その分子が光の波長を変化させます。\n3. 大気中の物質は光の波長を微小な範囲で遮断し、青色が見えるように散乱します。\n4. この現象は人間や他の生物からは直接観察することができないため、青色を知る方法として、光学的な解析や理論モデルを用います。"
  },
  "done_reason":"stop",
  "done":true,
  "total_duration":55640212015,
  "load_duration":1168323,
  "prompt_eval_duration":444553000,
  "eval_count":319,
  "eval_duration":55059956000
}

Ubuntu で Ollama の環境を構築する手順については、以下にまとめています。必要な方は見てみてください。

🐧 UbuntuにOllamaをインストールしてPhi3を動かすまでの手順

UbuntuにOllamaをインストールしてMicrosoft社のSLMであるPhi3を動かすまでの手順を解説します。

ritaiz.com

Ollama の状態を確認する

公式ドキュメントに記載されているスクリプト(こちら)を実行して Ollama を Ubuntu にインストールした場合、Ubuntu のサービスとして Ollama が自動起動するように設定されています。試しに以下のコマンドを実行して Ollama の状態を確認してみてください。

Ollamaの状態を確認する
$ sudo systemctl status ollama

以下のように表示されます。

Ollamaの状態を確認する
$ sudo systemctl status ollama
● ollama.service - Ollama Service
     Loaded: loaded (/etc/systemd/system/ollama.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2024-06-07 10:16:06 JST; 4min 19s ago
   Main PID: 588934 (ollama)
      Tasks: 31 (limit: 19087)
     Memory: 3.8G
        CPU: 1min 155ms
     CGroup: /system.slice/ollama.service
             └─588934 /usr/local/bin/ollama serve
 
# 省略

上記を見ると、Active: active(running)となっており、Ollama が起動していることを確認できます。

もし Ollama を停止したい場合は、他のサービスを停止したい場合と同様に以下のようにsystemctl stopコマンドを使って停止できます。

Ollamaを停止する
$ sudo systemctl stop ollama

起動したい場合はstartを使用します。

Ollamaを起動する
$ sudo systemctl start ollama

以降は Ollama が起動している状態で進めていきます。

Ollama で使用できるモデルを確認する

Ollama が起動している状態で以下のコマンドを使って Ollama で使用できるモデルを確認します。

Ollamaで使用できるモデルを確認する
$ ollama list
NAME            ID              SIZE    MODIFIED
phi3:mini       64c1188f2485    2.4 GB  8 days ago
phi3:medium     1e67dff39209    7.9 GB  8 days ago

上記から、phi3:miniとphi3:mediumのモデルが使用できることがわかります。 もし他のモデル、例えば Llama3 を使用したい場合は、以下を実行して Llama3 をダウンロードします。4.7GB ほどのサイズがあるため、ダウンロードには時間がかかります。

Llama3をダウンロードする
$ ollama pull llama3
pulling manifest
pulling 6a0746a1ec1a... 100% ▕████████████████████████████████████████▏ 4.7 GB
pulling 4fa551d4f938... 100% ▕████████████████████████████████████████▏  12 KB
pulling 8ab4849b038c... 100% ▕████████████████████████████████████████▏  254 B
pulling 577073ffcc6c... 100% ▕████████████████████████████████████████▏  110 B
pulling 3f8eb4da87fa... 100% ▕████████████████████████████████████████▏  485 B
verifying sha256 digest
writing manifest
removing any unused layers
success

上記のようにsuccessと表示されていれば、Llama3 のダウンロードが完了しています。 以下で再度確認すると、llama3が追加されていることがわかります。

Ollamaで使用できるモデルを確認する
$ ollama list
NAME            ID              SIZE    MODIFIED
llama3:latest   365c0bd3c000    4.7 GB  5 minutes ago
phi3:mini       64c1188f2485    2.4 GB  8 days ago
phi3:medium     1e67dff39209    7.9 GB  8 days ago

これで Phi3 や Llama3 を使用する準備が整いました。

API 経由でリクエストを送信する

systemctl statusで確認したように、Ollama が起動している状態であれば以下のコマンドを同じ Ubuntu 上で実行することで、Ollama に質問を送信し、その結果を確認することができます。以下のように、modelで使用したいモデルを指定することができます。

curlでphi3に質問を送信する
$ curl http://localhost:11434/api/chat -d '{
  "model": "phi3:mini",
  "messages": [
    { "role": "user", "content": "なぜ空はあおいの?" }
  ]
}'

上記を実行すると、以下のように 回答が1文字づつ返ってきます。

curlでphi3に質問を送信する
$ curl http://localhost:11434/api/chat -d '{
  "model": "phi3:mini",
  "messages": [
    { "role": "user", "content": "なぜ空はあおいの?" }
  ]
}'
{"model":"phi3:mini","created_at":"2024-06-07T06:04:50.710600764Z","message":{"role":"assistant","content":" "},"done":false}
{"model":"phi3:mini","created_at":"2024-06-07T06:04:50.835076269Z","message":{"role":"assistant","content":"「"},"done":false}
{"model":"phi3:mini","created_at":"2024-06-07T06:04:51.152210923Z","message":{"role":"assistant","content":"空"},"done":false}
{"model":"phi3:mini","created_at":"2024-06-07T06:04:51.272242582Z","message":{"role":"assistant","content":"」"},"done":false}
{"model":"phi3:mini","created_at":"2024-06-07T06:04:51.405790738Z","message":{"role":"assistant","content":"と"},"done":false}
# 省略

チャットアプリとして使いたい場合は良いですが、回答を 1 文字づつ返却したくない場合は以下のようにstreamオプションをfalseとすることで回答全てを一度に返却することができます。

curl質問を送信する
$ curl http://localhost:11434/api/chat -d '{
  "model": "phi3:mini",
  "stream": false,
  "messages": [
    { "role": "user", "content": "なぜ空はあおいの?" }
  ]
}'

上記を実行すると以下のように表示されます。

curlで質問を送信する
$ curl http://localhost:11434/api/chat -d '{
  "model": "phi3:mini",
  "stream": false,
  "messages": [
    { "role": "user", "content": "なぜ空はあおいの?" }
  ]
}'
{
  "model":"phi3:mini",
  "created_at":"2024-06-07T06:06:36.259965418Z",
  "message":{
    "role":"assistant",
    "content":" 日本語での回答として、「空は青いのから、大気中に雲や雨滴が含まれているためです。それぞれの微粒子は光を反射し、観測者にとって見えない青色を伝えます。」\n\n日本語でのステップバイステップで説明する場合:\n\n1. 空は何かが含まれていることから青い色に見えるのです。\n2. 空中に雲や水を含んだ液体があり、その分子が光の波長を変化させます。\n3. 大気中の物質は光の波長を微小な範囲で遮断し、青色が見えるように散乱します。\n4. この現象は人間や他の生物からは直接観察することができないため、青色を知る方法として、光学的な解析や理論モデルを用います。"
  },
  "done_reason":"stop",
  "done":true,
  "total_duration":55640212015,
  "load_duration":1168323,
  "prompt_eval_duration":444553000,
  "eval_count":319,
  "eval_duration":55059956000
}

なお、このままだと Ollama が起動している Ubuntu からしか API へのリクエストを受け付けできません。 他のマシンからもリクエストを受け付けるようにするには、/etc/systemd/system/ollama.serviceファイルを編集して反映させる必要があります。次で説明します。

Ollama をローカルマシン以外からもアクセスできるようにする

以下のように、/etc/systemd/system/ollama.serviceにEnvironment="OLLAMA_HOST=0.0.0.0"を追記します。

/etc/systemd/system/ollama.service
[Unit]
Description=Ollama Service
After=network-online.target
 
[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/hisui/.nvm/versions/node/v20.9.0/bin:/home/hisui/.local/share/pnpm:/home/hisui/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin:/usr/local/go/bin"
Environment="OLLAMA_HOST=0.0.0.0"
 
[Install]
WantedBy=default.target
 

上記を編集後、以下のコマンドを実行して変更を反映して Ollama を再起動します。

Ollamaに変更を反映して再起動する
$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama

上記のようにすることで、他のマシンからも Ollama にリクエストを送信できるようになります。

例えば、Ollama が動いている Ubuntu の IP アドレスが192.168.1.100である場合に、同じネットワーク内にある別の端末から以下のcurlを実行すれば、回答が返ってきます。

ローカルマシン以外から質問を送信する
$ curl http://192.168.1.100:11434/api/chat -d '{
  "model": "phi3:mini",
  "stream": false,
  "messages": [
    { "role": "user", "content": "なぜ空はあおいの?" }
  ]
}'

もし上記を実行して以下のようなエラーが表示される場合は、Ollama が動作していないか、IP アドレスやポート番号が間違っている可能性があります。もしくはファイアウォールの設定によって接続がブロックされている可能性もありますので確認してみてください。

Ollamaに接続できない場合のエラー
curl: (7) Failed to connect to 192.168.1.100 port 11434 after 26 ms: Couldnt connect to server

なお、OLLAMA_HOST以外に指定できる環境変数としては、以下の公式リポジトリの内容が参考になると思います。

ollama/envconfig/config.go

package envconfig

github.com

デフォルトのポート番号 11434 以外のポート番号を使用する

以下のようにすることでデフォルトのポート番号である11434以外のポート番号を指定することもできます。以下は11435を指定している例です。

/etc/systemd/system/ollama.service
# 省略
Environment="OLLAMA_HOST=0.0.0.0:11435"
# 省略

上記を保存して前節で説明したように反映して再起動すれば、指定したポート番号で Ollama が起動します。

ただし、注意点があり、ポート番号をデフォルトの11434以外に設定した場合、ollama listやその他のコマンドがそのままでは動作しくなります。試しに実行してみると、以下のように Ollama に接続できないとエラーが表示されます。

ollamaに接続できない時のエラー
$ ollama list
Error: could not connect to ollama app, is it running?

もし異なるポート番号で動いている Ollama に対してollama listや他のコマンドを実行したい場合は、以下のようにOLLAMA_HOSTを指定します。

任意のポート番号を指定してollamaコマンドを実行する
$ OLLAMA_HOST="127.0.0.1:11435" ollama list
NAME            ID              SIZE    MODIFIED
llama3:latest   365c0bd3c000    4.7 GB  4 hours ago
phi3:mini       64c1188f2485    2.4 GB  8 days ago
phi3:medium     1e67dff39209    7.9 GB  8 days ago

ollama listだけでなく、他のコマンドについても同様です。

ollama serve コマンドについて

公式ドキュメントにも記載されていますが、 Ollama をサーバとして起動するためにollama serveコマンドを使用することもできます。Ubuntu では、Ollama 公式のスクリプトを実行してインストールした時点でサービスとして登録されるため(内部でollama serveを実行しています)、基本的にこのollama serveは使わなくても問題ありません。インストールした時点で Ollama が起動しており、それ以降はサービスとして動作しているためです。 もしサービスとして動いている Ollama がある状態でollama serveを実行すると、以下のようにエラーが表示されます。

すでに使用しているポート番号を指定した場合のエラー
$ ollama serve
Error: listen tcp 0.0.0.0:11434: bind: address already in use

すでにポートが使用されている場合は、以下のようにlsofコマンドを使ってどのプロセスがポートを使用しているか確認できます。

すでに使用しているポート番号を確認する
$ sudo lsof -i:11434
COMMAND     PID   USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
ollama  2094564 ollama    3u  IPv4 890723407      0t0  TCP localhost:11434 (LISTEN)

したがって、Ubuntu や他の Linux では基本的にサービスとして動いているため、冒頭に記載したようにsystemctlなどを使って起動、停止を行います。

なお、systemctl stop ollama.serviceで Ubuntu のサービスとして動いている Ollama を停止して、ollama serveを実行すると以下のように正常に動作してリクエストの待ち受け状態となります。

ollama serveコマンドを実行する
$ ollama serve
2024/06/07 11:41:29 routes.go:1028: INFO server config env="map[OLLAMA_DEBUG:false OLLAMA_FLASH_ATTENTION:false OLLAMA_HOST: OLLAMA_KEEP_ALIVE: OLLAMA_LLM_LIBRARY: OLLAMA_MAX_LOADED_MODELS:1 OLLAMA_MAX_QUEUE:512 OLLAMA_MAX_VRAM:0 OLLAMA_MODELS: OLLAMA_NOHISTORY:false OLLAMA_NOPRUNE:false OLLAMA_NUM_PARALLEL:1 OLLAMA_ORIGINS:[http://localhost https://localhost http://localhost:* https://localhost:* http://127.0.0.1 https://127.0.0.1 http://127.0.0.1:* https://127.0.0.1:* http://0.0.0.0 https://0.0.0.0 http://0.0.0.0:* https://0.0.0.0:*] OLLAMA_RUNNERS_DIR: OLLAMA_TMPDIR:]"
time=2024-06-07T11:41:29.174+09:00 level=INFO source=images.go:729 msg="total blobs: 5"
time=2024-06-07T11:41:29.176+09:00 level=INFO source=images.go:736 msg="total unused blobs removed: 0"
time=2024-06-07T11:41:29.176+09:00 level=INFO source=routes.go:1074 msg="Listening on 127.0.0.1:11434 (version 0.1.39)"
time=2024-06-07T11:41:29.177+09:00 level=INFO source=payload.go:30 msg="extracting embedded files" dir=/tmp/ollama1580340421/runners
time=2024-06-07T11:41:32.332+09:00 level=INFO source=payload.go:44 msg="Dynamic LLM libraries [cpu cpu_avx cpu_avx2 cuda_v11 rocm_v60002]"
time=2024-06-07T11:41:32.344+09:00 level=INFO source=types.go:71 msg="inference compute" id=0 library=cpu compute="" driver=0.0 name="" total="15.6 GiB" available="479.7 MiB"

試しにcurlコマンドで質問をしてみると、以下のような出力が追加表示されると思います。

curlで質問を受けた時のログ
[GIN] 2024/06/07 - 11:45:18 | 200 | 17.488916719s |       127.0.0.1 | POST     "/api/generate"
 

上記のようにログをリアルタイムに確認できるため、デバッグなどに便利です。

もし異なるポート番号で動かしたい場合は、以下のようにOLLAMA_HOSTを指定します。

任意のポート番号を指定してollama serveコマンドを実行する
$ OLLAMA_HOST=0.0.0.0:11435 ollama serve

API で指定できるオプションについて

以下の公式リポジトリ内のドキュメントに、streamやその他の色々なオプションが記載されています。また、API として用意されているエンドポイントも記載されています。

API

Ollama api

github.com

一つの例として、同じ質問に対して毎回同じ回答が欲しい場合は、以下のようにseedを指定し、さらにtemperatureを0に設定することで同じ回答が返ってくるようになります。temperatureは回答の創造性と厳密性を左右するオプションです。

seedを指定して質問を送信する
$ curl http://192.168.1.100:11434/api/chat -d '{
  "model": "phi3:mini",
  "stream": false,
  "messages": [
    { "role": "user", "content": "なぜ空はあおいの?" }
  ],
  "options": {
    "seed": 100,
    "temperature": 0
  }
}'
 

上記を実行すると、冒頭に記載したものとは異なる回答が返ってきますが、再度実行しても同じ回答になります。

seedを指定して質問を送信する
{
  "model":"phi3:mini",
  "created_at":"2024-06-07T06:22:43.585726991Z",
  "message":{
    "role":"assistant",
    "content":" 空が「あおい」と呼ばれる理由は、その物質や特性に基づいています。空は大気を含む無重力の状態であり、大気中には水素酸化炭素(CO2)が含まれており、このガスが光合成を行う植物や海藻などから放出されるためです。その結果として、空は水素酸化炭素を含んでいるため、水素酸化炭素が大気中に存在することから「あおい」と見なされます。\n\nしかし、空自体が「水」の一部ではなく、空気を含む液体ではありません。空気は窒素酸化物(NOx)や他の有機分子を含んでおり、これらが水によって変化するため、空と水は異なる性質を持っています。\n\nしたがって、空が「あおい」と言われるのは、その大気中に含まれる水素酸化炭素とその物理的な特性からです。"
    },
    "done_reason":"stop",
    "done":true,"
    total_duration":65730704614,
    "load_duration":1461885502,
    "prompt_eval_count":16,
    "prompt_eval_duration":855754000,
    "eval_count":359,
    "eval_duration":63319975000
}

Ollama を更新する

Ollama をインストールするためのコマンドを再度実行することで Ollama を更新することができます。

Ollamaを更新する
$ curl -fsSL https://ollama.com/install.sh | sh

上記を実行すると以下のように表示されます。

Ollamaを更新する
$ curl -fsSL https://ollama.com/install.sh | sh
>>> Downloading ollama...
######################################################################## 100.0%##O#-#                   ######################################################################## 100.0%
>>> Installing ollama to /usr/local/bin...
>>> Adding ollama user to render group...
>>> Adding ollama user to video group...
>>> Adding current user to ollama group...
>>> Creating ollama systemd service...
>>> Enabling and starting ollama service...
>>> The Ollama API is now available at 127.0.0.1:11434.
>>> Install complete. Run "ollama" from the command line.
WARNING: No NVIDIA/AMD GPU detected. Ollama will run in CPU-only mode.

上記で Ollama の更新が完了し、最新のバージョンがインストールされます。

まとめ

Ollama をサーバとして動かして API で操作する手順について解説しました。今回はcurlコマンドを使って API にリクエストを送信しましたが、実際にはモバイルアプリや Web アプリから API リクエストを送ることで、Llama3 や Phi3 などの生成 AI を活用するアプリを作ることができます。

弊社では、ChatGPT をはじめとした生成 AI を活用した業務システムやアプリケーションの開発を行っています。ご興味がある方は、お気軽にお問い合わせください。

お問い合わせ