見出し画像

Paperspaceでdiffusers形式のFLUXモデルをダウンロードしてGGUF化する話@ComfyUI

前回記事にしたスクリプトを組み込んで、paperspaceでダウンロードできるようにしました。
後半はGGUF化する際の注意点を記載しています。

※基本的に、FLUXのモデルをそのままダウンロードした方が早いです。Diffusers形式のものしか無い場合に有効となります。

使用方法は、Pony系のダウンロードと同じような感じにしました。

以下のスクリプトをnotebooksディレクトリにアップロードしておきます。

また、現段階では必要なものとして、以下のjsonファイルをアップロードします。
これを「index.json」フォルダを作成し、その中に配置します。
(いくつかjsonファイルがありますが、スクリプトで使用するのは以下のひとつだけ)

以下のスクリプトをセルコマンドで実行します。

# モデルのURLとローカルパスのリスト
models = [
    {
        "base_url": "https://huggingface.co/AlekseyCalvin/RealisticLeoFluxV1_byLeoNguyen_Diffusers/resolve/main",
        "base_path": "/tmp/ComfyUI/models/unet/RealisticLeoFluxV1"
    }
]

# 各モデルについてスクリプトを実行
for model in models:
    base_url = model["base_url"]
    base_path = model["base_path"]
    print(f"Downloading model from {base_url} to {base_path}")
    # シェルコマンドを適切に実行
    !python3 /notebooks/FLUXmodeldownload_from_hugginface.py "{base_url}" "{base_path}"

セルコマンド内で修正しておく部分は、以前のものと同様です。
base_urlのところにhuggingfaceのurlを入れる
base_pathのところにダウンロードしたいComfyUIのディレクトリをしています。基本は、上の「unet」です。
実行すると以下の様にログが出ます。

ファイルを確認するコマンドでも、結合したsafetensorsファイルが確認出来ました。

<GGUF化する場合>
convert.pyを公開されているサイトで以下のような警告があります。

これは、今回のようなunet部分のみだと、GGUF変換はうまくいかないよという警告で、実際に試してみても、unet部分だけで処理するとエラーが出ました。

①テキストエンコーダーとVAEと組み合わせたsafetensorsを作成する

以下に保存されます。

これをGGUF化します。
①モデルの場所と名前を変えます

import os

MODEL_DIR = "/tmp/ComfyUI/output/checkpoints"
MODEL_NAME = "RealisticFlux_00001_.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}")

③GGUF化します

import subprocess

CONVERT_SCRIPT = "/usr/src/app/safetensors_convert_GGUF.py"  
QUANT_METHOD = "Q4_K_M"  # You can change this to the desired quantization method.

# FP16モデルへの変換と量子化処理
try:
    result = subprocess.run(
        ["python3", CONVERT_SCRIPT, "--src", MODEL_NAME, "--model_dir", MODEL_DIR, "--temp_dir", TEMP_DIR, "--quant_method", QUANT_METHOD],
        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}")

④ファイルをunetに移動します:ログで成功と出てから

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}")

取り合えず成功しました。

モデルのサイズも小さくなっている。

基本的なフローで画像生成が出来ました。

個人的にはFLUXのGGUF化はそれほど数をこなしていなかったので、「unetモデル単独はダメ」ということを認識していませんでした。

LocalでunetモデルをGGUF化する際も、clipとvaeをまとめるひと手間が必要な様です。

Paperspaceからダウンロードするのは時間がかかりますので、Localで使用する場合はLocalで作業するのが良さそうです。多分。

いいなと思ったら応援しよう!