Ubuntu Weekly Recipe

第825回ローカルLLMの実行ツールであるOllamaをUbuntuで動かす

ChatGPTをはじめとした生成AIにおけるここ数年の勃興は語るまでもありません。特にユーザーからの自然言語による対話をもとに文章を生成する仕組みは、すでに趣味や研究の範囲を超えて各分野の業務でも広く使われるようになりつつあります。その自然言語の理解と文章の生成に貢献している概念のひとつが、LLM(Large Language Model:大規模言語モデル)です。現在ではChatGPTで使われているGPTシリーズだけでなく、GoogleのGeminiやAnthropicのClaudeなど、規模の大小、目的問わずさまざまなLLMが登場しています。

今回はそんなLLMのうち個人でも利用可能で軽量なモデルの入門として、まずはUbuntu上で動かす方法について紹介しましょう。

図1 ollamaとOpen WebUIを使えばChatGPTっぽいUIからローカルLLMを使える

ローカルLLMの実行環境として定番のOllama

ChatGPTにしろGeminiにしろ、これらはいずれも「インターネット上のサービス」として提供されています。つまりウェブブラウザーから操作したり、APIを呼び出す際に、インターネットへの接続が必要です。当然その質問内容はインターネットを経由して、各サービスのサーバーに渡されます。さらにサービスによっては、その質問・生成内容自体を学習データとして使われるかもしれません。事の是非はともかく、インターネットに質問文としての情報を流すことや、それが学習にも使われるかもしれないこと自体が「セキュリティリスクである」と捉えられる環境もあることでしょう。また、可能であればインターネットなしにLLMを使いたいケースもありますし、言語モデル自体を自分たちが持っている情報で補強したいこともあります。

そこで出てくる手段のひとつがローカルLLMです。つまり任意の言語モデルを、ローカルマシンの性能だけで動かし、インターネットや対外サービスに依存せずに生成系AIを使えるようにします。とは言え、いわゆる「大規模」な言語モデルを動かすには、それなりのハードウェアリソースや電力に時間とお金が必要になります。しかしながら言語モデルによってはご家庭にあるGPUでも十分に動く規模のものもありますし、規模が小さいとRaspberry Pi 5で動かすことも可能だったりします。

現在LLMの実行環境として広く使われているものに、Go言語で作られたOllamaがあります。任意の「言語モデル」をロードすることで、さまざまな言語モデルを同じインターフェースから使えるようになります。さらにAPIも用意しているため、バックエンドはOllamaに任せてフロントエンドを作り込めば、自由に対話型のようなウェブサービスやチャットボットも作れます。

Ollamaのインストール自体はシンプルです。もともとGo言語で作られた単一ファイルのバイナリが配布されているために、libc以外には依存関係もなく、それを取り込めば良いだけです。公式にインストールスクリプトが配布されており、それを使えばNVIDIAやAMDのドライバ等も合わせてインストールできます。もちろんコンテナ等に閉じ込めてしまうのもひとつの手でしょう。

$ curl -fsSL https://ollama.com/install.sh -O
もしくは
$ wget https://ollama.com/install.sh

公式サイトの説明ではダウンロードしたスクリプトをそのままshコマンドに渡していますが、一般的には中身も確認せずにスクリプトを実行するのは危険です。一度内容を精査した上で、実行することを心がけてください。ちなみに、sudo等でスクリプト全体を管理者権限で実行するのではなく、必要に応じてsudoコマンドを使う作りになっているあたりは良心的な作りです。

なお、install.shでやっていること自体はシンプルです。

  • CPUアーキテクチャーやLinuxディストリビューション、WSL2かどうかなどの環境を確認する
  • Ollamaの実行バイナリをダウンロードし/usr/local/bin/ollamaとして配置する
  • ollamaユーザーとグループを作成し、ollamaユーザーをrenderグループとvideoグループに、スクリプトの実行ユーザーをollamaグループに所属させる
  • /etc/systemd/system/ollama.serviceを作成し、起動時にOllamaをデーモンとして起動するよう設定する
  • AMDもしくはNVIDIAのGPUを探す
  • AMDのGPUが見つかりROCmもインストールされていたら、ROCm版のOllamaバイナリに差し替える
  • NVIDIAのGPUが見つかり、nvidia-smiがインストールされていなかったら、NVIDIAのドライバーやツールキットをインストールする

最低限必要なのは/usr/local/bin/ollamaだけです。これだけあればCPUでもLLMは動きます。もちろんAMD ROCmやNVIDIA CUDAがあれば高速化できますし、GPUメモリが少なくても一番小さい規模のLLMなら動くことが多いです。

ちなみにNVIDIAのドライバーやツールキットはUbuntuの公式パッケージでもNVIDIAのサードパーティのバイナリパッケージでもかまいません。Ubuntuの公式パッケージを使いたいならあらかじめ次のようにインストールして、一度再起動しておいてください。

Ubuntuデスクトップで、デスクトップ向けのGPUとして使いたい場合:
$ sudo ubuntu-drivers install
もしくは
$ sudo apt install nvidia-driver-XXX

画面の描画等はせずに、純粋にGPGPUとして使いたい場合:
$ sudo ubuntu-drivers install --gpgpu
もしくは
$ sudo apt install nvidia-driver-XXX-server

基本的にはubuntu-driversコマンドが自動検知して、適切なパッケージをインストールしてくれます。ただし新しいGPUや通常とDevice ID等が異なるGPUだと、ubuntu-driversがうまく検知できないかもしれません。その場合は後者のaptコマンドを使って直接インストールする方法を試してください。

ここでXXXはバージョン番号になります。基本的にsudo apt install nvidia-driver-と入力したあとにTabキーを2回押したら表示されるバージョンのうち、一番新しいものを指定しておけば良いでしょう。セキュアブートの環境だとインストール後に、セキュアブートの設定が始まります。これについては画面の指示に従って、ワンタイムパスワードの設定を行い、再起動しください。

GUIからインストールしたければ第817回の参考書を片手にUbuntuでもStable Diffusion WebUIを動作させ、画像を生成するが、AMD ROCmなら第742回のAMD RadeonとROCmでBlenderを高速化するが参考になることでしょう。

それではinstall.shを実行しましょう。内部でcurlコマンドも使っているため、先にそれをインストールしています。

$ sudo apt install curl
$ bash install.sh
>>> Downloading ollama...
(中略)
>>> Installing ollama to /usr/local/bin...
[sudo] shibata のパスワード:
>>> Creating ollama user...
>>> 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...
Created symlink /etc/systemd/system/default.target.wants/ollama.service → /etc/systemd/system/ollama.service.
>>> NVIDIA GPU installed.

サービスファイルが自動的に有効化され、起動しているためにOllamaのバックエンドも起動しています。

$ command -v ollama
/usr/local/bin/ollama

$ ollama --version
ollama version is 0.3.3

$ systemctl status ollama.service
● ollama.service - Ollama Service
     Loaded: loaded (/etc/systemd/system/ollama.service; enabled; preset: enabled)
     Active: active (running) since Sun 2024-08-04 16:19:27 JST; 50s ago
   Main PID: 3326 (ollama)
      Tasks: 18 (limit: 76734)
     Memory: 1.2G (peak: 1.2G)
        CPU: 7.990s
     CGroup: /system.slice/ollama.service
             └─3326 /usr/local/bin/ollama serve
             (後略)

Llama 3.1モデルを試してみる

無事にOllamaをインストールできたら、さっそく言語モデルを試してみましょう。Ollamaでは、いくつかのメジャーな言語モデルをかんたんにインストールできます。使えるモデルはOllamaサイトのモデル一覧から確認できます。

このうちMetaが開発するLlamaは、高性能で使い勝手がよく、さらに軽量なモデルも用意されているために広く使われているモデルです。今回は最新のLlama 3.1のパラメーターサイズ8Bのものを使います。

$ ollama run llama3.1
pulling manifest
(中略)
verifying sha256 digest
writing manifest
removing any unused layers
success
>>> Send a message (/? for help)

初めてモデルを実行する場合は、/usr/share/ollama/.ollama/models/以下にモデルファイルをダウンロードする必要があります[1]。Llama 3.1の8Bだと4.7GiBぐらいのファイルをダウンロードすることになるようです。

ちなみに「8B(80 billion=80億⁠⁠」というのはパラメーター数を意味し、一般的に数字が大きいほど精度が良くなり、必要な計算リソースは増えます。特にメモリ使用量は、このパラメーター数に比例して大きくなる傾向があります。今回のケースだと、NVIDIA RTX A1000 8GiBのGPUで8Bのモデルを使ったところおおよそ7GiB強のGPUメモリを消費していました。

あとはプロンプトに質問を入力していくだけです。単一行ならそのまま入力してエンターキーを押したら回答の生成を開始してくれます。試しにUbuntuについて質問してみましょう。

図2 さすがにUbuntuなら常識の範囲ですし簡単に答えられますよね

上図で質問する際に、最初に/set verboseしているのは生成時間を表示したかったからです。次にUbuntuについて聞いて……デビッド・ヘイタビーって誰!? すみません、取り乱しました。もちろんUbuntuの創設者は「マーク・シャトルワース」です。英語で質問するとLinuxディストリビューションとしてのUbuntuを回答する時は毎回「Mark Shuttleworth」が登場します。日本語で質問すると半分ぐらいの頻度で「マーク・シャトルワース」以外の人が創設者として登場しました。

これくらいの質問なら4秒弱で結果を返してくれます。結果自体も4秒待ってから表示されると言うよりは、すぐに表示を開始しほぼ4秒の間ずっと文字を表示し続けるため、ほとんど「すぐに回答してくれている」と感じます。

ちなみにスラッシュで始まるコマンドによって、いくつかの操作を行えます。

>>> /?
Available Commands:
  /set            Set session variables
  /show           Show model information
  /load <model>   Load a session or model
  /save <model>   Save your current session
  /clear          Clear session context
  /bye            Exit
  /?, /help       Help for a command
  /? shortcuts    Help for keyboard shortcuts

/show infoで現在使っているモデル情報が表示されます。

>>> /show info
  Model
        arch                    llama
        parameters              8.0B
        quantization            Q4_0
        context length          131072
        embedding length        4096

  Parameters
        stop    "<|start_header_id|>"
        stop    "<|end_header_id|>"
        stop    "<|eot_id|>"

  License
        LLAMA 3.1 COMMUNITY LICENSE AGREEMENT
        Llama 3.1 Version Release Date: July 23, 2024

複数行を入力したい場合は"""でくくってください。

また、OllamaではChatGPTと同じように前回の回答に続けて文章を入力すると、そのコンテキストを維持して回答します。一度コンテキストをクリアしたい場合は/clearコマンドを実行しましょう。

終了したい場合は/byeです。うっかりexitとかquitとか入力すると、これまでのコンテキストをもとにそれっぽい回答を考え出してくれます。

Open WebUIでChatGPTっぽくする

CLIはCLIで便利なのですが、前の回答・コンテキストを保持したり、複数行の入力等を考えるとWeb UIのほうが便利なことも多々あります。Ollamaの場合、Open WebUIというまさにChatGPTのようなウェブアプリケーションが存在します。これを使えば、複数のモデル間の切り替え、質問履歴の保存、コンテキストの保持、アカウントの管理などが単一のWeb UIで実現できます。

Open WebUIはDockerで動かすのがおそらく一番簡単でしょう。ただしDockerからNVIDIAのGPUリソースを使うためには、NVIDIA Container Toolkitをホストマシンにインストールしなくてはなりません。

このツールキットはDebianパッケージ化されていないため、NVIDIAの公式サイトの手順に従ってインストールすることにします。

$ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
$ sudo apt update
$ sudo apt install nvidia-container-toolkit

さらにDockerとgitをインストールします。ここではUbuntuの公式リポジトリ版を使っていますが、Dockerが提供するパッケージをインストールする形でもかまいません。もしNVIDIA Container Toolkitより先にDockerをインストールしている場合は、2番目のコマンドのようにDockerデーモンを再起動しておくと良いでしょう。これによりDocker側でツールキットの存在を検知して、適切な対応を行ってくれます。

$ sudo apt install docker.io git
$ sudo systemctl restart docker.service

さらにOllamaの設定を変更します。Ollamaは初期設定だと、127.0.0.1:11434でのみAPI呼び出しを待ち受けています。

$ ss -ltn | grep 11434
LISTEN 0      4096       127.0.0.1:11434      0.0.0.0:*

しかしながらUbuntu 24.04 LTSだと、Dockerインスタンスの中からこのAPIは叩けません。次のようなエラーが表示されてしまいます。

ERROR [apps.ollama.main] Connection error: Cannot connect to host host.docker.internal:11434 ssl:default [Connection refused]

そこで0.0.0.0:11434で待ち受けるように変更します。ただしこの変更は、インターネットからアクセスできる環境で設定すると、誰でも外部からOllamaを操作できてしまうために危険です。閉じられたネットワーク内部にとどめておきましょう。より良い方法は、たとえばdocker0インターフェースに割り当てられているIPアドレスを指定して、ホスト上のDockerインスタンスからのみアクセスするよう限定することです。

まずはollama.serviceのDrop-inファイルを編集できるようにします。

$ sudo systemctl edit ollama.service

ファイルエディタが起動しますので、次の2行を入力します。

[Service]
Environment="OLLAMA_HOST=0.0.0.0"

あとは設定を反映し、ollama.serviceを再起動するだけです。

$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama.service
$ ss -ltn | grep 11434
LISTEN 0      4096               *:11434            *:*

無事に0.0.0.0:11434で待ち受けるようになりました。

あとはOpen WebUIのリポジトリをクローンし、サービスを起動します。

$ git clone https://github.com/open-webui/open-webui.git
$ cd open-webui
$ sudo docker run -d -p 3000:8080 --gpus all \
  --add-host=host.docker.internal:host-gateway \
  -v open-webui:/app/backend/data --name open-webui --restart always \
  ghcr.io/open-webui/open-webui:cuda

ここではNVIDIA GPU用のイメージを使っているためopen-webui:cudaを指定していますが、NVIDIAでなければ:mainタグを指定すれば良いでしょう。

あとはhttp://ホストマシンのIPアドレス:3000にアクセスすれば次の手順でアカウント作成、ログインが可能です。

図3 まずはログインが求められるために、⁠サインアップ」を選ぶ
図4 名前とメールアドレス、パスワードを入力。メールアドレスは外部には渡されず、ログイン時にのみ使うことになっているので適当でもOK
図5 作成してログインすると、見慣れたWeb UIが表示される
図6 まずは画面左上からモデルを選択する。⁠ollama run」もしくは「ollama pull」したモデルのみが表示される

モデルはollama側で保持したモデルが表示されます。ollama run モデル名すると自動的にモデルをダウンロード・実行しますし、ollama pull モデル名とすればダウンロードだけを実行します。もし何も表示されない場合は、ホスト上のollamaサービスとの接続がうまくいっていない可能性があります。Dockerインスタンスのログなどにエラーが残っていないか確認しましょう。

これまではLlama3.1を使っていましたが、今回はあらかじめ以下も実行していました。

$ ollama pull gemma2

GemmaはGoogleが公開しているLLMです。Geminiで使っているモデルというわけではなく、⁠同じ研究とテクノロジーに基づいて」構築されたモデルとのことです。Llamaに比べると若干テンションの高い印象があります。

図7 Ubuntu Weekly Recipeの記事から面白いと思うものをピックアップ

誰かこの連載で豆腐ステーキの記事を書いていましたっけ。食べ物に関しては、からあげの記事しか記憶にありません。まぁ、16年間800回以上続く連載なので、そういう記事もあったかもしれませんね、たぶん。いや、ないか。

Llamaも含めて海外で作られたモデルはどうしても、英語などの言語のデータセットが主体となり、日本語の情報や日本語の解釈は性能が落ちてしまいます。特に7Bや8Bといった軽量なモデルだと、さらに精度が落ちてしまうでしょう。日本語をメインに使いたいのであれば、日本語LLMなどと呼ばれる、日本語のデータセットで学習したモデルの利用をおすすめします。

英語で質問して英語で回答を得る形であれば、Llama 3.1でも結構な精度で回答を得られるようです。また、次のように、すでにある情報を元に翻訳してもらうという手もあります。

図8 Ubuntuは今年で20週年を迎えるため、そういうセッションを想定した概要を翻訳してもらった

コンテキストを使って、翻訳してくれました。原文の日本語のニュアンスを良くも悪くも読み取った翻訳になっているのではないでしょうか。

日本語向けにチューニングしたLLMも

Llama3.1やGemma2も、軽量モデルであればそこそこのGPUで軽快に動きますし、比較的自由に使えるライセンスモデルですので、いろいろと遊びがいはありそうです。ただしやはり日本語のやりとりには不安があります。このあたりは日本語向けにチューニングしたLLMに軍配があがることでしょう。

最近は日本語LLMについても様々なモデルがリリースされています。Llamaベースにしたものも多く、それなりに軽量なモデルも出ている状態です。残念ながらOllamaからすぐに使えるものはありませんが、少しの手間でモデル化すれば導入できるため、日本語で試したいのであればそこから調べてみると良いでしょう。

図9 Gemmaさんに町田市に質問してみたところ、やはり(高い確率で)神奈川県とのこと。領土問題を解決するためにも、日本語LLMが必要になりそう

おすすめ記事

記事・ニュース一覧