Supershipの名畑です。逃げ上手の若君はジャンプでも読んでいるのですが、アニメもOPとEDまでを含め期待を上回る出来で毎週楽しみに見ています。余談ですがEDを歌っているぼっちぼろまるさんのタンタカタンタンタンタンメンは昔から好きです。
はじめに
Black Forest Labsのニュースが話題になっています。
画像生成AIの「Stable Diffusion」などの開発に携わったAI研究者が、新しいAI開発企業の「Black Forest Labs」を立ち上げました。さらに、Black Forest Labsはパラメーターサイズが120億のオープンソース画像生成AIモデル「Flux」も発表しています。
参考:Stable Diffusionのオリジナル開発陣がAI企業「Black Forest Labs」を立ち上げ独自の画像生成AIモデル「Flux」をリリース - GIGAZINE
画像生成AIモデル「Stable Diffusion」の共同開発者たちによって設立されたベンチャー企業「Black Forest Labs(BFL)」は8月1日(現地時間)、高品質な画像生成能力と多様な出力が特徴の最新の画像生成AIモデル「FLUX.1」を発表した。
参考:ASCII.jp:「Stable Diffusion」開発者たちが新たな画像生成AI「FLUX.1」を発表 迷走するStability AIと対照的な展開に
ということで、画像生成AIモデルであるFLUX.1を手元のMacBook(M2)で動かした過程を記事に残します。
コードはすべてPythonです。
FLUX.1について
詳しくは公式アナウンスである「Announcing Black Forest Labs - Black Forest Labs」をご覧いただければと思いますが、以下の3つのモデルがあります。
-
FLUX.1 [pro]
- 最先端のパフォーマンスを持つ画像生成モデルで、API経由でアクセス可能。
-
FLUX.1 [dev]
- 非商用アプリケーション向けのモデルで、Hugging Faceで入手可能で、商用利用の場合は問い合わせが必要。
-
FLUX.1 [schnell]
- ローカル開発や個人使用向けの高速モデルで、Apache2.0ライセンスの下で公開されている。Hugging Faceで入手でき、推論コードはGitHubおよびHugging FaceのDiffusersで見つけることができる。ComfyUIとの統合もサポートしている。
本当は FLUX.1 [pro] を試したかったのですが、APIは現時点(2024.8.5)ではまだ「Accounts are only activated for selected partners.」ということで招待制です。
ReplicateやFal.aiを経由すれば呼べるのでしょうが、今回はローカルで生成できる最も高品質なモデルである FLUX.1 [dev] を用いることにします。
記事の最後に FLUX.1 [schnell] での生成例も載せます。
「とりあえずどんな画像が生成されるかだけ自分で試してみたい」という方は以下のリンク先にてWeb上で生成可能です。有料なものもありますのでご注意ください。
- FLUX.1 [pro]
- FLUX.1 [dev]
- FLUX.1 [schnell]
私の環境
MacBook Pro(Apple M2 Proチップ / メモリ16GB)です。
OSはmacOS 14 Sonomaです。
パッケージとしてはdiffusers、sentencepiece、t5、torch、transformersが必要です。diffusersについては公式の手順に従い、githubからのインストールとします。
まとめると以下コマンドです。torchは後述の理由でバージョンを絞っています。
$ pip install sentencepiece torch==2.3.1 transformers git+https://github.com/huggingface/diffusers.git
私の環境でのバージョンはそれぞれ以下です。
$ pip list | grep -e diffusers -e sentencepiece -e t5 -e torch -e transformers
diffusers 0.30.0.dev0
sentencepiece 0.2.0
t5 0.9.4
torch 2.3.1
transformers 4.43.3
torchは現時点(2024.8.5)の最新は2.4.0なのですが、2.3.1にダウングレードしました。
最初は2.4.0で進めていたのですが、生成画像のノイズがひどく、なぜか検索してみるとダウングレードでうまくいったという情報が見つかったためです。因果関係は調べきれていませんが、解決はしています。
ちなみにノイズがひどい画像というのは以下のようなものです。
アクセス権の取得
今回はHugging Face経由でモデルを入手して実行します。
そのためにまずはHugging Faceのアカウントを作成します。
アカウントを作成してログイン後FLUX.1-devのページに行くと規約への同意が求められます。
規約を読んで納得した上でAgree and access repositoryを押します。
以下のようにアクセス権が得られたことが確認できます。
アクセストークンの作成
モデルをダウンロードする際のユーザー認証のため、Hugging Faceのアクセストークンを作成します。
Hugging FaceでSettingsに移動し、さらにAccess Tokensに移動します。
ここでCreate new Access Tokenを押します。
読み取り権限があればいいのでReadを選び、好きな名前を指定して生成してください。
ハードコーディングを避けるため、環境変数にセットします。
まず設定ファイルを開きます。私の環境ではzshrcです。
$ open ~/.zshrc
生成したアクセストークンの値を記録します。
私はHUGGING_FACE_TOKENという名前にしました。
export HUGGING_FACE_TOKEN=ここにアクセストークンの値を書く
PYTORCH_MPS_HIGH_WATERMARK_RATIOの指定
メモリ16GBマシンなので当たり前ではありますが、私の環境ではメモリが不充分なためか、そのまま実行すると以下のエラーが出ました。
RuntimeError: MPS backend out of memory
Use PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0 to disable upper limit for memory allocations (may cause system failure).
MacBookのGPUであるMPSの容量不足です。
指示通り、環境変数として以下の指定をしました。こうすることでMPSの使用上限がなくなります。
export PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0
ただし、メモリ使用のリミットをはずすことでメモリ枯渇によるPC停止もありえますのでご注意ください。
最初は0.0ではない値にしようかと思ったのですが、以下のエラーが出るので断念して0.0としました。
RuntimeError: invalid low watermark ratio 1.4
torch.mps.empty_cache()でMPSのキャッシュをクリアできますので、こちらを適宜呼ぶことでメモリ容量の不足を回避することができるのであれば、その方が良いですね。
transformer_flux.pyの修正
このまま実行すると、まだエラーが発生します。
scale = torch.arange(0, dim, 2, dtype=torch.float64, device=pos.device) / dim
TypeError: Cannot convert a MPS Tensor to float64 dtype as the MPS framework doesn't support float64. Please use float32 instead.
float64の代わりにfloat32を使うようにというエラーです。transformer_flux.pyの該当箇所を以下のように変更すれば回避できます。
# scale = torch.arange(0, dim, 2, dtype=torch.float64, device=pos.device) / dim
scale = torch.arange(0, dim, 2, dtype=torch.get_default_dtype(), device=pos.device) / dim
GitHubのissueでも「flux does not work on MPS devices」として上がっていますので、近いうちに対応される可能性はあります。
ComfyUIでも「FLUX Issue | MPS framework doesn't support float64 」というissueがありました。
コード
公式のサンプルコードのままでは動かないため、以下を変更しています。
- アクセストークンの指定
- MacBookのGPUを使用するためにdeviceとしてmpsを指定
-
enable_model_cpu_offloadの呼び出しを削除
- 呼び出すとCUDA前提の処理が流れるため「AssertionError: Torch not compiled with CUDA enabled」が起こります。
コードは以下です。公式サンプルコードからの変更箇所はコメントに記載済みです。
import torch
from diffusers import FluxPipeline
import os # 環境変数読み込みのために追加
hf_token = os.getenv("HUGGING_FACE_TOKEN") # Hugging Faceのトークンを取得
pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-dev",
torch_dtype=torch.bfloat16,
token=hf_token # Hugging Faceのトークンを指定
)
pipe.to(torch.device("mps")) # deviceとしてMPSを指定する
# pipe.enable_model_cpu_offload() # 呼び出し削除
prompt = "A cat holding a sign that says hello world"
image = pipe(
prompt,
height=1024,
width=1024,
guidance_scale=3.5,
output_type="pil",
num_inference_steps=50,
max_sequence_length=512,
generator=torch.Generator("cpu").manual_seed(0)
).images[0]
image.save("flux-dev.png")
品質は後回しでとりあえず生成を試すだけなら、時間を短縮するためにnum_inference_stepsを小さくする方がいいかもしれません。
シード値の調整はgeneratorで行えます。
呼び出し時のパラメータについて詳しくはapi referenceをご覧ください。
モデルに対して「A cat holding a sign that says hello world」というプロンプトで画像を生成しています。
訳すと「hello worldという看板を持った猫」ですね。
初回はモデル等のダウンロードが必要となります。30GB以上あるので、環境によってはかなり時間がかかるかと思います。
結果
気になるところはあれど、かなり綺麗で、そして「Hello World」という文字もきっちり示せています。プロンプトを忠実に再現していますね。
また、せっかくなので別プロンプトでも試してみました。
prompt = "anime style, Japanese moe heroine"
「anime style, Japanese moe heroine」なので、訳すと「アニメスタイル、日本の萌えヒロイン」です。
その結果は以下でした。
なにを以て萌えとするかはここでは論じませんが、こちらもプロンプトを忠実に再現した高品質な画像と感じます。
ちなみに過去記事の際に同一プロンプトを用いてStable Image Ultraで生成した画像は以下でした。
比較してみると、FLUX.1の方が萌えヒロインという言葉に近い、かな?
FLUX.1 [schnell]でも試してみた
高速モデル、つまり少ないステップ数で画像の生成が可能である FLUX.1 [schnell] においても公式のサンプルコードを元にして画像生成をしてみました。
import torch
from diffusers import FluxPipeline
import os # 環境変数読み込みのために追加
hf_token = os.getenv("HUGGING_FACE_TOKEN") # Hugging Faceのトークンを取得
pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-schnell",
torch_dtype=torch.bfloat16,
token=hf_token # Hugging Faceのトークンを指定
)
pipe.to(torch.device("mps")) # deviceとしてMPSを指定する
# pipe.enable_model_cpu_offload() # 呼び出し削除
prompt = "A cat holding a sign that says hello world"
image = pipe(
prompt,
guidance_scale=0.0,
output_type="pil",
num_inference_steps=4,
max_sequence_length=256,
generator=torch.Generator("cpu").manual_seed(0)
).images[0]
image.save("flux-schnell.png")
こちらも初回は30GB以上あるモデル等のダウンロードが行われますので時間がかかります。
結果は以下となります。
「anime style, Japanese moe heroine」だと以下です。
さすがに FLUX.1 [dev] と比べて落ちる感はあれど、両方ともプロンプトをきちんと汲んだ綺麗な画像ですね。
ちなみに、少ないステップ数で生成できるため、本記事のコードであれば FLUX.1 [dev] と比べて時間は数分の一です。
最後に
早くAPIも使いたい。
Today we release the FLUX.1 text-to-image model suite. With their strong creative capabilities, these models serve as a powerful foundation for our upcoming suite of competitive generative text-to-video systems. Our video models will unlock precise creation and editing at high definition and unprecedented speed. We are committed to continue pioneering the future of generative media.
動画生成も可能になるとのことで、本当に今後が楽しみです。
宣伝
SupershipのQiita Organizationを合わせてご覧いただけますと嬉しいです。他のメンバーの記事も多数あります。
Supershipではプロダクト開発やサービス開発に関わる方を絶賛募集しております。
興味がある方はSupership株式会社 採用サイトよりご確認ください。