初心者でもできる!HuggingFaceモデルをGGUF形式に変換しOllamaで使う手順

最近、AIのことは一応触ってはいますが、ちっともわからない状況です🫠

先日までOllamaを使用していたのでローカルLLMについてはなんとなく分かってきた様でもありという状況ですが、OllamaGGUF形式のモデルが使えるとはいえ、すべてのモデルがGUFF形式で公開されているというわけはありません。

リポジトリ内には拡張子が無いモデルのファイルがあって…これ何?って感じです。なんとなく分かってきたのはHuggingFaceにで公開されているモデルはHFって呼ばれるモデルのようですが…。どこかに名言されてるんでしょうか🙇

ということで、HuggingFaceに公開されているHFモデルをなんとかしてOllamaでも使用可能なGGUF形式に変換できないかという内容でチャレンジしてみたいと思います。

(2024.09.11)Ollamaに作成したGGUF形式のモデルをpullする方法のリンクを追記

【参考】

tech.takuyakobayashi.jp

qiita.com

動作の前提

今回はWindows11(WSL)Ubuntu24.04 LTS環境で行っていますが、ピュアなUbuntu24.04 LTSでも動作を確認しています。

今回はUbuntuのバイナリのビルドがあるので、念の為に以下のパッケージをインストールしておきます。また、Pythonvenvpipもデフォルトではインストールされていないこともあるので動作を確認しておいてください。

$ sudo apt update

# pipとvenvのインストール(もしなければ)
$ sudo apt install python3-pip python3-venv

# バイナリのビルドツールとgit関連のインストール
$ sudo apt install build-essential git git-lfs 

git-lftHuggingFaceでも使用されている大容量ファイルを扱うためのものになります。Windows版のGitにはこの機能が含まれているそうです。

GGUF形式のモデルへの変換方法の調査

調べてみると、Hugginfaceで公開されているモデルを積極的にGGUFモデルに変換されている7shiさんがQiitaにエントリで書かれていました。

再掲

qiita.com

これを元に自分でもチャレンジしてみます。張り切って車輪の再発明しますよ🤩🤩🤩

記事の中ではllama.cppが必要のようです。Ollamaは内部的にllama.cpp(のサーバ機能)を利用しているもののようで、ローカルLLMといえば、これっていうもののようです。ただ、cppとの記載がある通り、C++ソースコードのビルドが必要となります。

Port of Facebook's LLaMA model in C/C++GitHub - ggerganov/llama.cpp: LLM inference in C/C++

また、llama.cppにはその他に使用できるツールも同梱されており、ただローカルLLMを使用するだけというものでは無いようです。今回の変換ツールも、このllama.cppに同梱(ビルドで生成されるものを含む)されています。

llama.cppを使用するための準備

llama.cppの取得とビルド

まずはllama.cppGitHubから取得します。llama.cppは以下のリポジトリにあるので、CLIでCloneを行います。

github.com

$ git clone https://github.com/ggerganov/llama.cpp

git cloneコマンドで取できたら、続いてllama.cppのビルドを行っていこうと思います。

llama.cppに含まれるPythonの実行ファイルのための準備

クローンしたllama.cppソースコードにはPythonの実行ファイルも含まれています。そちらはビルドしなくても動作させることができます。ただ、Python用のライブラリを準備(インストール)する必要があるので、その作業を事前に行っておきます。

# クローンディレクトリの移動
$ cd ~/llama.cpp

# llama.cpp用の仮想環境の準備(今回は**.llama.cpp**として、llama.cppのクローンディレクトリの中に作成します。)
$ python -m venv .llama.cpp
$ source ./.llama.cpp/bin/activate
(.llama.cpp) $ pip install -r requirements.txt

(注意)pythonやpipは必要であればpython3やpip3に置き換えてください。

こちらでPythonプログラムの準備は完了です。

llama.cppのビルド

続いてはllama.cppのビルドを行っていきます。以下のリンクを参考にビルドを行っていきましょう。

【参考】llama.cppバイナリビルド説明 github.com

# クローンディレクトリへの移動
$ cd llama.cpp

# バイナリのビルド
make

# 成功したらホームディレクトリに戻る
cd ~

成功すればllama.cppのバイナリ構築は完了です。 これでHFファイルGGUF形式に変換するプログラムの準備は整いました。

GGUFモデルへの変換

変換準備ができたのでGGUF形式のモデルに変換するHFモデルを取得します。今回はDataPilot/ArrowPro-7B-KillerWhaleHuggingFaceからダウンロードします。すでにGGUF形式のモデルはHuggingFace上に存在しますが、参照先と同じことをしてみます。

huggingface.co

今回は、Gitを使用する方法とPythonを使用する方法の2つの方法を紹介します。基本的にはどちらを使用しても可能処理は可能ですが、どちらも一長一短があるかもしれません。

(その1)GitのコマンドでのLLMモデルの取得(一般的な方法)

まずはGitを使用してモデルのリポジトリのファイルを取得する方法です。Git Cloneコマンドを使用してリポジトリを取得する方法は大きく変わりません。

# LLMのダウンロード(SafetensorsモデルというかHFモデル)
# Hugginfaceのリポジトリからgit cloneコマンドで取得
$ git clone https://huggingface.co/DataPilot/ArrowPro-7B-KillerWhale

このままでいいはずなのですが、Git Cloneの処理の途中で停止してしまいました。

そんなときには【Ctrl+C】を押下して、以下のようにコマンドを実行します。HuggingFaceではサイズの大きなモデルはLFSという仕組みによって保存されているので、このようなファイルがある場合にはgit lfsコマンドでダウンロードします。

# クローンしたディレクトリへ移動
$ cd ArrowPro-7B-KillerWhale/
$ git lfs pull

HuggingFaceリポジトリLFSとかかれているファイルがその対象になります。

これで問題なくダウンロードされるはずですが、それでもだめなときもあります。そんなときはwgetコマンドで取得するのも手です。リポジトリのファイルのリンクをwgetコマンドの引数にして実行してください。最初からwgetコマンドで取得するのも手なのかもしれないのですが🫠

(その2)LLMモデルの取得(専用スクリプトを使用する方法)

こちらは2つ目の方法になります。

7shiさんのサイトではHuggingFaceのページにあるPythonのサンプルコードを修正することで対応できるという風に書いてあったので、それを修正してコマンドライン実行できるものをつくってみました。

【該当箇所】

https://qiita.com/7shi/items/14d24a25aa26dcf97d2d#clone

(注意)このPythonではライブラリにtransformersが必要なるので以下を実行してライブラリをインストールをしてください。

ライブラリのインストール

$ pip install transformer

LLM取得アプリのソースコード

以下のプログラムを実行します。引数にはモデル名を入れてください。例えばDataPilot/ArrowPro-7B-KillerWhaleというような形式です。

実行後でダウンロードされたmodeltokenizer"~/.cache/huggingface/hub/"に格納されますが、指定する場合には環境変数HUGGINGFACE_HUB_CACHEにパスを設定してください。

HuggingFaceからLLMモデルを取得するアプリ

HuggingFaceからmodelとtokenizerをダウンロードするコード

実行の様子

取得されたファイル

~/.cache/huggingface/hub/models--DataPilot--ArrowPro-7B-KillerWhale/snapshots/ 以下にモデルの実体があります

上記2つのどちらかの手法でファイルが取得できたら、GGUF形式モデルに変換する処理に移ります。

GGUF形式のモデルへの変換

手順としては

  1. BFloat16GGUF形式モデルに変換
  2. Q4_K_M量子化(Q4_K_M量子化の手法で、4bitの量子化となります)

という手順を行います。量子化を行うことでサイズも小さくできるのでメモリが足りない場合などでも効果があるのではないでしょうか。

1. BFloat16GGUF形式モデルに変換

(その1)Git Cloneでモデルの取得を行った場合

# BFloat16(bf16)へ一旦変換
$ python ~/llama.cpp/convert_hf_to_gguf.py --outfile ArrowPro-7B-KillerWhale-bf16.gguf --outtype bf16 ArrowPro-7B-KillerWhale

(その2)掲載のPythonプログラムでモデルの取得を行った場合

※モデルパスに注意

今回は~/.cache/huggingface/hub/models--DataPilot--ArrowPro-7B-KillerWhale/snapshots/ 以下にモデルの実体があります

# BFloat16(bf16)へ一旦変換
# モデルパスに注意
# モデルの実体は以下に格納されています
# ```~/.cache/huggingface/hub/models--DataPilot--ArrowPro-7B-KillerWhale/snapshots/``` 

$ python ~/llama.cpp/convert_hf_to_gguf.py --outfile ArrowPro-7B-KillerWhale-bf16.gguf --outtype bf16 ~/.cache/huggingface/hub/models--DataPilot--ArrowPro-7B-KillerWhale/snapshots/63a8746d41285207538662a8eb052a7461f79d22

変換し、BFloat16(bf16)GGUF形式のモデルが作成されました。

2. Q4_K_M量子化

さらに、Q4_K_M量子化を行います。(ここからは同じ作業になります。)

# Q4_K_Mへ変換
$ ./llama.cpp/llama-quantize ArrowPro-7B-KillerWhale-bf16.gguf ArrowPro-7B-KillerWhale-Q4_K_M.gguf Q4_K_M

作成されたモデルのファイルサイズも圧倒的に小さくなっています。

これでGGUF形式のLLMモデルが生成できました。最後にこちらをOllamaでロードしてみたいと思います。

生成したGGUF形式のモデルOllamaで使用してみる

以前のエントリ同様にOllamaを使用していきます。

【参考】OllamaGGUF形式のLLMを使用する

uepon.hatenadiary.com

モデルの設定ファイルを例えば以下のように作成し

Modelfile_ArrowPro-7B-KillerWhale-Q4_K_M

FROM /ollama/ArrowPro-7B-KillerWhale-Q4_K_M.gguf

別途、Dockerなどでモデルを設定します。先程はWSL上でGGUF形式のモデルを作成していましたが、このモデルファイルは別の処理系に持っていっても問題なく使用することができます。では、モデル設定をします。

以下はWindowsDocker上で動作を行っています。以下のようにあらかじめ作成していたコンテナを起動し、

PS> docker start ollama

以下のように実行します。今回はArrowPro-7B-KillerWhale-Q4_K_Mと設定しています。

※モデルファイルはDocker側から参照できるパスにしておきましょう。(Dockerコンテナ側のパスになるため、PowerShellからのパス補完は行われません。)

PS > docker exec -it ollama ollama create ArrowPro-7B-KillerWhale-Q4_K_M -f /ollama/Modelfile_ArrowPro-7B-KillerWhale-Q4_K_M

うまくモデル設定ができたので、つづいて実行を行います。

PS> docker exec -it ollama ollama run ArrowPro-7B-KillerWhale-Q4_K_M

無事起動できたのでプロンプトを入れてテストをしてみます。

問題なさそうですね。唐揚げのレシピについて聞いてみると

若干怪しい記述もありますが、問題なく使用できています。

おわりに

HuggingFaceに公開されているLLMモデルを取得・変換し、GGUF形式への変換とともに量子化し、Ollamaで動作できるように設定を行いました。

これで公開されていほぼほとんどのモデルのテストができるようになったかな?🤩🤩🤩

追記

※コメントでOllamaに作成したGGUF形式のモデルをpullする方法を教えていただいたので追記いたします。(2024.09.11)

note.com

【参考】

tech.takuyakobayashi.jp

github.com

【過去記事】

uepon.hatenadiary.com

uepon.hatenadiary.com

/* -----codeの行番号----- */