SafetensorsモデルのGGUF化@paperspaceでも出来る編
ここに記事にしたものをpaperspaceで行うために修正したコマンドになります。ちなみに最近の文字を入れた画像はDALLE3に作成してもらっています。
前回記事に記載漏れていましたが、パッチを当てるところまでの処理は、llama.cppを削除しない限り残っているため、実際にGGUF化するのは、2回のコンバートコマンドをするだけになります。
さて、paperspaceの方に移ります。
このGGUF化にはllama.cppが必要になりますので、その分の容量が追加で必要になります(60MB)
<初回操作>
①llama.cppのインストール
%cd /notebooks
!git clone https://github.com/ggerganov/llama.cpp
②llama.cppからGGUFモジュールのインストール
(これはインスタンスごとに必要)
%cd /notebooks/llama.cpp
!pip install llama.cpp/gguf-py
③llama.cppのバージョン修正とパッチ
%cd llama.cpp
!git checkout tags/b3600
!git apply ..\lcpp.patch
④patchをnotebooksディレクトリに配置した場合のコマンド
%cd /notebooks
!git clone https://github.com/ggerganov/llama.cpp
%cd /notebooks/llama.cpp
!pip install ./gguf-py
%cd /notebooks/llama.cpp
!git checkout tags/b3600
!git apply /notebooks/lcpp.patch
⑤CMAKEのインストールコマンド
!sudo apt-get update
!sudo apt-get install -y cmake
⑥コンパイルコマンド
# 1. ビルド用ディレクトリの作成と移動
!mkdir -p /notebooks/llama.cpp/build
%cd /notebooks/llama.cpp/build
# 2. CMakeによるビルドファイルの生成
!cmake ..
# 3. llama-quantizeバイナリのビルド
!cmake --build . --config Debug -j10 --target llama-quantize
# 4. 作業ディレクトリを元に戻す
%cd /notebooks/llama.cpp
⑦convert.pyとread_tensors.pyをnotebookディレクトリに配置する
⑧セルコマンドの内容を編集して実行
以下のセルコマンドは、以下の様に記載します(python3.10)。
最初にモデルが配置されているディレクトリを記載します。
モデル名は、変換したいモデル名を記載します。
モデルの配置先のディレクトリを記載します。
convert.pyに量子化はQ4_K_Mに指定しています。
# 1. モデルが配置されているディレクトリ、モデル名、移動先ディレクトリを指定
import os
import shutil
MODEL_DIR = "/tmp/ComfyUI/models/checkpoints"
MODEL_NAME = "your_model_name.safetensors" # ここにモデル名を入力
FINAL_DIR = "/tmp/ComfyUI/models/unet" # 移動先のディレクトリ
# 2. モデルが配置されているディレクトリ内に一時ディレクトリを作成
TEMP_DIR = os.path.join(MODEL_DIR, "temp_model")
os.makedirs(TEMP_DIR, exist_ok=True)
# 3. FP16モデルに変換し、量子化して、FP16モデルを削除
!python3 /notebooks/convert.py --src $MODEL_NAME --model_dir $MODEL_DIR --temp_dir $TEMP_DIR
# 4. 量子化されたモデルファイルを別のディレクトリに移動
MODEL_BASE_NAME = os.path.splitext(MODEL_NAME)[0] # 拡張子を除去
QUANTIZED_MODEL = f"{MODEL_BASE_NAME}.gguf"
shutil.move(os.path.join(MODEL_DIR, QUANTIZED_MODEL), os.path.join(FINAL_DIR, QUANTIZED_MODEL))
# 5. 一時ディレクトリを削除(不要な場合)
shutil.rmtree(TEMP_DIR)
convert.pyは以下です。前回記事と内容は異なりますので、ご注意ください。
コマンド実行後の状態です。
wai-cute-v5-sdxl.safetensorsを変換したものです。
量子化されたのが分かります。Diffusionモデル部分はもともと5GBぐらいなのが、1.5GBに!
ただ、この状態だとCLIPがそのままなので、合計は3GBぐらいだったりします。
これは、配置先を間違えたものですが、実際に使用するにはunetに配置する必要がありますので、そのようにセルコマンドは設定しています。
<2回目操作(インスタンスを改めて立ち上げた場合)>
①llama.cppからGGUFモジュールのインストール
(連続して使用する際は不要)
%cd /notebooks/llama.cpp
!pip install llama.cpp/gguf-py
②セルコマンドの内容を編集して実行
# 1. モデルが配置されているディレクトリ、モデル名、移動先ディレクトリを指定
import os
import shutil
MODEL_DIR = "/tmp/ComfyUI/models/checkpoints"
MODEL_NAME = "your_model_name.safetensors" # ここにモデル名を入力
FINAL_DIR = "/tmp/ComfyUI/models/unet" # 移動先のディレクトリ
# 2. モデルが配置されているディレクトリ内に一時ディレクトリを作成
TEMP_DIR = os.path.join(MODEL_DIR, "temp_model")
os.makedirs(TEMP_DIR, exist_ok=True)
# 3. FP16モデルに変換し、量子化して、FP16モデルを削除
!python3 /notebooks/convert.py --src $MODEL_NAME --model_dir $MODEL_DIR --temp_dir $TEMP_DIR
# 4. 量子化されたモデルファイルを別のディレクトリに移動
MODEL_BASE_NAME = os.path.splitext(MODEL_NAME)[0] # 拡張子を除去
QUANTIZED_MODEL = f"{MODEL_BASE_NAME}.gguf"
shutil.move(os.path.join(MODEL_DIR, QUANTIZED_MODEL), os.path.join(FINAL_DIR, QUANTIZED_MODEL))
# 5. 一時ディレクトリを削除(不要な場合)
shutil.rmtree(TEMP_DIR)
こういう感じでGGUFファイルを使用して画像生成が出来ました。
注意点
生成時間に関してですが、GGUFの方が長かったです。
これは私の使用方法が悪いのか、今後改善されていくのかわかりません。
参考までに時間を提示します。2回目以降の生成時間です。
1024x1024で、A4000
GGUF:12秒/枚
通常/7-8秒/枚
fp8:7-8秒/枚
このあたりは、今後の課題になるのでしょうか?
<追記>
提示したセルコマンドですが、一つにまとめてしまっているため、どこかで間違っている際に分かりにくくなる可能性があります。
それぞれのセルコマンドに分けたものを提示します。
ディレクトリの場所などは任意に変えてください。
<2回目>
①llama.cppからGGUFモジュールのインストール
%cd /notebooks/llama.cpp
!pip install llama.cpp/gguf-py
②モデルディレクトリやファイルのチェック
import os
MODEL_DIR = "/tmp/ComfyUI/models/checkpoints"
MODEL_NAME = "openflux1-v0.1.0-fp8.safetensors" # ここにモデル名を入力
FINAL_DIR = "/tmp/ComfyUI/models/unet" # 移動先のディレクトリ
TEMP_DIR = os.path.join(MODEL_DIR, "temp_model")
# モデルディレクトリとファイルの存在確認
if not os.path.exists(MODEL_DIR):
raise FileNotFoundError(f"モデルディレクトリが見つかりません: {MODEL_DIR}")
if not os.path.exists(os.path.join(MODEL_DIR, MODEL_NAME)):
raise FileNotFoundError(f"モデルファイルが見つかりません: {MODEL_NAME}")
print("モデルディレクトリとファイルの確認が完了しました。")
③一時ディレクトリの作成
import os
# 一時ディレクトリの作成
TEMP_DIR = os.path.join(MODEL_DIR, "temp_model")
try:
os.makedirs(TEMP_DIR, exist_ok=True)
print(f"一時ディレクトリを作成しました: {TEMP_DIR}")
except Exception as e:
raise RuntimeError(f"一時ディレクトリの作成に失敗しました: {e}")
④FP16モデルへの変換および量子化処理の実行
import subprocess
CONVERT_SCRIPT = "/notebooks/convert.py" # convert.pyのパス
# FP16モデルへの変換と量子化処理
try:
result = subprocess.run(
["python3", CONVERT_SCRIPT, "--src", MODEL_NAME, "--model_dir", MODEL_DIR, "--temp_dir", TEMP_DIR],
capture_output=True,
text=True
)
if result.returncode != 0:
raise RuntimeError(f"変換スクリプトの実行に失敗しました: {result.stderr}")
print(f"変換スクリプトの実行が完了しました: {result.stdout}")
except Exception as e:
raise RuntimeError(f"変換スクリプトの実行に失敗しました: {e}")
⑤量子化されたモデルファイルの移動
import os
import shutil
MODEL_BASE_NAME = os.path.splitext(MODEL_NAME)[0] # 拡張子を除去
QUANTIZED_MODEL = f"{MODEL_BASE_NAME}.gguf"
# 量子化モデルの移動
try:
source_path = os.path.join(MODEL_DIR, QUANTIZED_MODEL)
destination_path = os.path.join(FINAL_DIR, QUANTIZED_MODEL)
if not os.path.exists(source_path):
raise FileNotFoundError(f"量子化されたモデルが見つかりません: {source_path}")
shutil.move(source_path, destination_path)
print(f"モデルを移動しました: {destination_path}")
except Exception as e:
raise RuntimeError(f"モデルの移動に失敗しました: {e}")
⑥一時ディレクトリの削除
import shutil
import os
# 一時ディレクトリの削除
try:
shutil.rmtree(TEMP_DIR)
print(f"一時ディレクトリを削除しました: {TEMP_DIR}")
except Exception as e:
raise RuntimeError(f"一時ディレクトリの削除に失敗しました: {e}")