⚙️

ollamaで自分のようなbotを作る_2. カスタムモデルを作るにはどうするか調べてみる

2024/04/23に公開

前回はDockerでollamaを起動して、モデルとやり取りすることができた。

前回の記事
ollamaで自分のようなbotを作る_1.Dockerの公式イメージを動かしてみる
https://zenn.dev/machbike/articles/fae7b7727b9cb8

本記事では自分のようなレスポンスをするモデルを作るにはどうすれば良いか調べていく。

モデルをカスタマイズする方法を調べる

README.mdからモデルのカスタムに関するところを読む。

モデルをカスタマイズする
GGUF からインポート
Ollama は、Modelfile での GGUF モデルのインポートをサポートしています。
https://github.com/ollama/ollama?tab=readme-ov-file

モデルのインポート: モデルをインポートするには、Modelfileという名前のファイルを作成し、その中にFROM命令とインポートしたいモデルへのローカルパスを記述します。その後、ollama create example -f Modelfile と ollama run example を実行します。https://opensource.devtheworld.jp/blog/Ollama

→モデルを作って、それをインポートすれば良いのか?

自分のモデルを作りたい

カスタムモデルを作る場合はかなりの工数がかかるっぽい。以下のようなサイトで作り方を学べそう。

https://www.freecodecamp.org/news/how-to-build-a-large-language-model-from-scratch-using-python/

他に方法が無いか調べたところ、ファインチューニングという方法が出てきた。

既存のモデルをファインチューニングすることで、特定のデータセットに対するモデルの理解を深めることができます。このアプローチでは、モデルの基本構造を保持しつつ、特定のデータセットやタスクに特化したパフォーマンスを向上させるために、モデルのパラメータを微調整します。
ChatGPTより

そこで、ollamaで使えるモデルから今回の用途に適したモデルを聞いたところ「Orca Mini」や「DeepSeek-LLM」が良いとのこと。

日本語のテキストデータでファインチューニングを考えている場合、「Orca Mini」や「DeepSeek-LLM」のような多言語対応モデルを検討すると良いでしょう。これらのモデルは、多様な言語のデータに基づいて訓練されており、日本語を含む複数の言語での性能が期待できます。
ChatGPTより

ファインチューニングの手順を聞くと以下のサイトが出てきたので、こちらのサイトを見てみた。
しかし、大まかな手順は書かれているが、具体的にどうするかが書かれていない。

Training and Fine-Tuning Orca: Step-by-Step Process
https://webonecreation.com/ai-tools/training-and-fine-tuning-orca-step-by-step-process/

ファインチューニングとは?どんなことをする?などの情報は以下のサイトに分かりやすく書いてある。
https://qiita.com/ksonoda/items/b9fd3e709aeae79629ff

その後も調べたが、orca miniのファインチューニングの方法は見つからなかった。

現時点でOrca Miniをファインチューニングする際の具体的な方法を詳細に説明する公式サイトやドキュメントは見つかりませんでした。ファインチューニング大規模言語モデルのプロセスは一般的には似ていますが、Orca Miniのような特定のモデルに関する詳細なガイドラインが必要な場合は、そのモデルを提供するプラットフォームやコミュニティのサポートフォーラム、または関連する技術文書を直接参照することをお勧めします。

以下に一致するモデルは無いとのことだった。

以下に一致するモデルはありますか?
・具体的なファインチューニングの方法が記載されたサイトがある
・ollamaで使えるモデルである

現在のところ、Ollamaで使用可能なモデルの中で、具体的なファインチューニング方法が詳細に記載された公式なガイドが見つかるモデルは限られています。一般的に、ファインチューニングに関する情報は、大規模言語モデル全般に適用可能なガイドラインやチュートリアルとして提供されることが多いです。特定のモデルに適したファインチューニングの方法を探す場合は、そのモデルの公式ドキュメントや、技術的なフォーラム、コミュニティでの議論を参照するのが最適です。また、Hugging FaceのTransformersライブラリなどのリソースを利用して、異なるモデルのファインチューニングに関する一般的なアプローチを理解することも有効です。
ChatGPTより

ファインチューニングは難しそう。
ここでふと、プロンプトを与えることでどれだけ応答に違いがあるのか? ということが気になった。

ファインチューニングはできないが、プロンプトを与えることでそれなりに応答の精度をあげることができる。
「プロンプトを与えない VS プロンプトを与える」 でどれだけ応答性能に差があるかやってみることにした。

さくさく動く環境を作りたい

前回、モデルを動かした時に返答にかなりの時間がかかった。
そこでさくさくレスポンスしてくれる環境を作る。

どのモデルを使うか?

日本語でトレーニングされているモデルが良いのでは。
「Orca Mini」や「DeepSeek-LLM」のどちらか。

どの環境で実行するか

複数の起動方法がある。「CPUのみ」「Nvidia GPU」「AMD GPU」の3つ。

  • CPU:リソース要件が最も低く、設定も簡単ですが、処理速度はGPUを使用する場合に比べて遅い
  • Nvidea:高速化されるが、セットアップが必要。
  • AMD GPU:Nvidia GPUに匹敵するパフォーマンスだが、セットアップがやや複雑

Nvidia環境を構築してみる

docを参考に実行。いきなり詰まった。

tee: /etc/yum.repos.d/nvidia-container-toolkit.repo: No such file or directory

確認すると確かにこのディレクトリは存在しない。
そもそも、私の環境はMacOSであり、Unixベースなので、aptもyumも使えない。

AMD GPU環境を構築してみる

doc通りにやってみる

$ docker run -d --device /dev/kfd --device /dev/dri -v ollama:/root/.ollama -p 11434:11434 --name ollama_amd ollama/ollama:rocm
Unable to find image 'ollama/ollama:rocm' locally
rocm: Pulling from ollama/ollama
2d473b07cdd5: Extracting [=================>                                 ]  26.74MB/76.1MB
4f4eb3eed7c6: Download complete 
4e682e6173ef: Downloading [=================================>                 ]  55.44MB/82.77MB
a49b9456537c: Downloading [===========>                                       ]  55.79MB/236.1MB
97a62ce7a828: Downloading [==========>                                        ]     14MB/67.47MB
7bca3865cb92: Waiting 
7cffa5a2e049: Waiting 
0880b9c1cfe6: Waiting 

動き出した。完了したところでrunしようとしたが、エラーになった。
そもそもこのコマンドは何してるのか分解してみる。

docker run -d 
--device /dev/kfd : AMD GPUにアクセスするためのデバイスファイルをコンテナに接続する。
--device /dev/dri : AMD GPUにアクセスするためのデバイスファイルをコンテナに接続する。
-v ollama:/root/.ollama
-p 11434:11434
--name ollama 
ollama/ollama:rocm

そもそもMacOSではAMD GPUを使った方法もできないらしい。(Linuxならできる)
ということで、CPUを使ったやり方で進める。

CPUのみの構築方法を試す

改めて確認すると、モデルによって必要なメモリが異なる。
PC自体のメモリは16GBだが、dockerに割り当てているのは現在2GB。
そのため、現状の設定だと動かせるモデルがない。
docker割り当てメモリを一時的にでも8GBにする必要がある。
余裕を持たせて9GBにしてみる。

README.md

dockerのCPU使用可能量を増やしたからか、前と同じ質問を投げても10秒後には返答が始まった。どうやらCPUの値を変更する必要があったっぽい。

>>> 空はなぜ青い?

空 (くう) is a noun in Japanese that refers to the sky or atmosphere. It can be translated as "blue" in English, but it's important to note that the word "空" has multiple meanings and connotations in Japanese 
culture.

In Japan, the color blue is often associated with calmness, serenity, and tranquility, which are qualities that are highly valued in Japanese culture. The blue sky is seen as a symbol of these virtues, and is 
often used in art and literature to represent peacefulness and harmony.

So, why is the sky blue? In simple terms, the Earth's atmosphere scatters sunlight in all directions, and this scattering effect gives the sky its blue color. The shorter wavelengths of light, such as blue and 
violet, are scattered more than the longer wavelengths, such as red and orange, which is why the sky appears blue.

In Japanese culture, the blue sky is often used as a metaphor for the infinite and the unknown, representing the vastness and mystery of the universe. The blue color is also associated with the idea of "yūgen," or
the profound and mysterious beauty of the world.

So, while the scientific explanation for why the sky is blue is based on the way light interacts with the Earth's atmosphere, the cultural and symbolic significance of blue in Japanese culture goes beyond just a 
physical phenomenon, and represents a deeper appreciation for the beauty and mystery of the world around us.

一部を抜粋して翻訳してみる。

So, why is the sky blue? In simple terms, the Earth's atmosphere scatters sunlight in all directions, and this scattering effect gives the sky its blue color. The shorter wavelengths of light, such as blue and 
violet, are scattered more than the longer wavelengths, such as red and orange, which is why the sky appears blue.

では、なぜ空は青いのでしょうか? 簡単に言うと、地球の大気は太陽光をあらゆる方向に散乱させ、この散乱効果が空に青い色を与えます。 青色や青色などの波長の短い光は、
紫は、赤やオレンジなどの長い波長よりも多く散乱されるため、空が青く見えます。

それっぽい返答である。

とりあえず、前に「小規模で動作する」「多言語でトレーニングされている」とあった「Orca mini」のモデルを試してみる。

>>> 空はなぜ青い?日本語で。
The phrase "The sky is blue" in English is commonly used to describe the color of the sky. However, the Japanese language has a different word for this color, which is "senbei".

訳
英語では「空は青い」というフレーズが空の色を表すのによく使われます。 しかし、日本語にはこの色を表す別の言葉があり、それは「せんべい」です。

あれ?支離滅裂、日本語じゃない。
もう一回「日本語で」の指定を消して実行してみる。

あの文での英検は「The sky is blue」という交響的な文です。彼らの形から表現されてもあり、外部からでも古きっかなように使い捨てこのままに。

This is a translation of the English phrase "The sky is blue" in Japanese. The word used for "senbei" is

何故かせんべいが出てしまう。
使い物にならなさそうなので、Llama2で進めてみる。

プロンプトでのカスタマイズを試す

README.mdの「Customize a prompt」を参考に実行する。

まず、Modefileを作成。今回はollama_dockerディレクトリ配下に作成した。
READMEではコンテナに対してコマンド実行していたが、私はコンテナに入ってからコマンド実行したかったので、ローカルのディレクトリとコンテナ内のディレクトリをマウントした。
-v ollama:/root/.ollama --mount type=bind,src=$(pwd),dst=/appの部分。

// コンテナを起動
$ docker run -d -v ollama:/root/.ollama --mount type=bind,src=$(pwd),dst=/app -p 11434:11434 --name ollama_cpu ollama/ollama
b3cca0b3ca6bbc5a0577c68e07f90d31cf71f6f845359f0d8dfdd201374c0a4f
// 起動確認
$ docker ps
CONTAINER ID   IMAGE           COMMAND               CREATED         STATUS         PORTS                                           NAMES
b3cca0b3ca6b   ollama/ollama   "/bin/ollama serve"   4 seconds ago   Up 3 seconds   0.0.0.0:11434->11434/tcp, :::11434->11434/tcp   ollama_cpu
// コンテナに入る
$ dexec b3cca0b3ca6b bash 
// ファイルがあるか確認
root@b3cca0b3ca6b:/# ls app/
Modelfile

READMEのプロンプトをModefileに記載後、create/runする。
早速テキストを投げてみる。

>>> Hi! What's your name?
Woah there, it's-a me, Mario! *adjusts cap* Great to meet you, buddy! My name is, of course, Mario. It's-a nice to have someone to talk to-a here. What brings you to this-a place? *munches on some mushrooms*

翻訳
わあ、それは私だ、マリオだ! *キャップを調整します* 
初めまして、相棒! 私の名前はもちろんマリオです。 
ここで話し相手がいるのは嬉しいことです。 
何があなたをこの場所に連れてきたのですか? *キノコをむしゃむしゃ食べる*

「キャップ」「キノコ」「it's-a me, Mario!」というレスポンスはマリオっぽい返答である。
良い感じ。

Discussion