画像生成AI FLUX.1 に Diffusers で LoRA を適用してみた♭

## このブログは何？
[画像生成AI FLUX.1 に Diffusers で LoRA を適用してみた](https://qiita.com/yuji-arakawa/items/8d065ae3df536f5cd559) の続編です。前回の記事で試した3つの LoRA のうち1つしか顕著な効果を確認できなかったのですが、X で、[まゆひらさんがご紹介されていた](https://x.com/riddi0908/status/1824753162886291716) QTCanimatedFeeling-FLUX-PAseer【Alpha】がとても良さそうでしたので Diffusers で試してみた記事となります

:::note
Diffusers での FLUX.1 による画像生成自体はこちら ↓ のブログにまとめています。
:::

https://qiita.com/yuji-arakawa/items/fd4fd0c026ecfa664d97

:::note warn
上の記事では、RTX2060 という VRAM が貧弱な GPU で動かすことを主眼にしていましたが、画像生成に FLUX.1 Dev で 40分、FLUX.1 Schnell で8分もかかってしまいました（共有VRAMへ大量に漏れ出しているためと思われますのでまだチューニング余地はありそうです）。今回の記事は クラウドで VRAM の大きな GPU仮想マシンを借りて検証していますの量子化やモデルオフローディングなどは省いています（ローカルで動作確認してクラウド実行という...不思議な感じがしなくもないですね）
:::

---
## FLUX.1 とは？

FLUX.1は、Stable Diffusionの開発者たちが設立したBlack Forest Labsの画像生成AIモデルです。プロンプトに対する高い忠実性と優れた画像品質で注目を集めています。パラメータ数は、12B（120億）です。

![QTCanimation_lora_v1-PAseer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/40523484-a6e6-5e8e-6be7-4f6a3d2f8a8d.png)



### FLUX.1 の特徴
- __高品質な画像生成__ : 人物の顔や手、指などの複雑なディテールを正確に描写することができ解剖学的な崩壊もほとんど見られない高品質な画像を生成できます
- __プロンプトへの忠実性__ : テキストプロンプトによるユーザーの指示を反映した画像を生成する高い能力を持っています
- __用途に合わせた3つのモデル__ : 最高性能でBlack Forest Labsやそのパートナー企業のAPIサービスでのみ利用可能な Pro モデル、高性能でオープンウェイト（fine-tuning modelなどの派生物の商用利用は不可）な Dev モデル、わずか 4 Step で高品質な画像を生成できる高速モデルの Schnell の 3つのモデルがあります


:::note
FLUX.1 Schnell の 4 Step 高速生成は昨年秋に流行った LCM : Latent Consistency Model（潜在一貫性モデル） によるリアルタイムお絵描きの興奮を思い出しますね！
:::

---

## Diffusers とは？
Diffusersは、Hugging Faceが開発した拡散モデル（Diffusion Model）のためのオープンソースライブラリです

### Diffusers の特徴
- __簡潔さ__ : 数行のコードで画像生成などの複雑なタスクを実行できます
- __柔軟さ__ : モデルのカスタマイズや新しいモデルの開発が容易にできます
- __豊富な事前学習済みモデル__ : Hugging Face Hub からStable Diffusion、FLUX等の多数の事前学習済みモデルを簡単にダウンロードして使用できます

---

## LoRA とは？
LoRA (Low-Rank Adaptation) は、大規模な事前学習済みモデルを効率的にファインチューニングするための技術です。特に画像生成AIの分野で元のモデルの画風を変えたり特定の種類の画像を意図したとおりに生成されやすくする目的で多く活用されています

### コード例で使う LoRA の紹介
__QTCanimatedFeeling-FLUX-PAseer【Alpha】__ を使用します。これは、アニメーションスタイルを強化するLoRAです。より複雑なドレス、より繊細な線画、より細かい目の表現などの効果がある LoRA です。

https://civitai.com/models/654875

## QTCanimatedFeeling-FLUX-PAseer【Alpha】による生成例
<table>
<tr>
<td>
FLUX.1 Dev
</td>
<td>
LoRAなし
</td>
<td>
QTCanimatedFeeling-FLUX-PAseer【Alpha】
</td>
</tr>
<tr>
<td>
</td>
<td>

![51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/ac130e0f-9000-f67d-b7d2-da86afe4bbff.png)
</td>
<td>

![53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/a05b79ec-f56b-8afc-6631-9ea39c9c6374.png)
</td>
</tr>
<tr>
<td>
プロンプト
</td>
<td colspan=2>
a cute Japanese idle singer girl, long black hair, She is singing ,holding a microphone, wearing white idle costume, standing on the stage .This is a flashy concert with 3D holograms and laser effects
</td>
<tr>
<td>
seed
</td>
<td colspan=2>
1127239343
</td>
</tr>
<tr>
<td>
</td>
<td>


![61.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/0967daa0-b636-e09e-c9be-413d32df0380.png)
</td>
<td>

![63.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/c57b99a2-3c1a-4843-5f4c-3265a8f36427.png)

</td>
</tr>
<tr>
<td>
プロンプト
</td>
<td colspan=2>
3D animation style graphics reminiscent of Pixar of a magical girl in a pink costume. She is holding a magic wand. Beside her is a white cat. Seven-colored lights, petals and butterflies are dancing around them.
<td>
</tr>
<tr>
<td>
seed
</td>
<td colspan=2>
1127239343
</td>
</tr>
<tr>
<td>
</td>
<td>


![62.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/dd0b6e8e-0af1-f02f-c256-e4a7882359a5.png)
</td>
<td>

![64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/89860895-1b0d-6fb7-69d0-d2948ca8abe2.png)
</td>
</tr>
<tr>
<td>
プロンプト
</td>
<td colspan=2>
modern anime style, a magical girl in a pink costume. She is holding a magic wand. Beside her is a white cat. Seven-colored lights, petals and butterflies are dancing around them.
<td>
</tr>
<tr>
<td>
seed
</td>
<td colspan=2>
1127239343
</td>
</tr>
</table>

「より複雑なドレス、より繊細な線画、より細かい目の表現などの効果」という開発者の説明のとおりアニメ塗りというよりはより繊細な表現を実現する効果があるようです

### コード例
#### サンプルコード取得
サンプルのノートブックはこちら ↓ から取得してください

https://github.com/kutsushitaneko/flux1-diffusers-lora

```bash:リポジトリのクローン
git clone
https://github.com/kutsushitaneko/flux1-diffusers-lora
cd flux1-diffusers-lora
```
#### セットアップ
お好みの Jupyter 環境で `setup.ipynb` を上から順に実行します

```python:PyTorchインストール
%pip install -U torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
```
CUDA対応の PyTorchをインストールしています。インストールすべきバージョンが不明な場合は、以前の記事の[CUDA 対応 PyTorch のインストール](https://qiita.com/yuji-arakawa/items/fd4fd0c026ecfa664d97#cuda-%E5%AF%BE%E5%BF%9C-pytorch-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E4%B8%8A%E3%81%AE%E7%A2%BA%E8%AA%8D%E7%B5%90%E6%9E%9C%E3%81%A7%E5%BF%85%E8%A6%81%E3%81%AA%E5%A0%B4%E5%90%88%E3%81%AE%E3%81%BF)を参考にしてみてください

```python:PyTorchバージョンの確認
%pip show torch
```
CUDA対応の PyTorch がインストールされたことを確認します。`Version` に バージョン番号に続いて +cu121 のような CUDA Toolkit バージョンが表示されていれば正しくCUDA対応の PyTorch がインストールされています。Version: 2.4.0 のように PyTorch のバージョン番号だけが表示された場合は、CUDA 対応ではありません
```python:依存ライブライのインストール
%pip install -r requirements.txt
```
requirementsファイルから必要なパッケージをインストールしています

```python:Hugging Face ログイン
from huggingface_hub import notebook_login
notebook_login()
```
FLUX.1 Dev を使う場合には、Hugging Face であらかじめ Black Forrest Labs のライセンス条件に同意していることが必要です。また、モデルにアクセスする際には、それが確認できるよう Hugging Face へのログインが必要です。Hugging Face アカウントやトークンについては以前の記事の[ライセンス条件への同意とHugging Face へログイン（Dev を使用する場合のみ）](https://qiita.com/yuji-arakawa/items/fd4fd0c026ecfa664d97#%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E6%9D%A1%E4%BB%B6%E3%81%B8%E3%81%AE%E5%90%8C%E6%84%8F%E3%81%A8hugging-face-%E3%81%B8%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3dev-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E3%81%BF)を参考にしてみてください

#### LoRA のダウンロード
[こちら](https://civitai.com/models/654875)の"Download"をクリックして safeTensor ファイルをダウンロードします。ダウンロードしたファイルは、loras フォルダ内に配置します

#### サンプルノートブック
お好みの Jupyter 環境で `FLUX1_Schnell_with_QTCanimatedFeeling_LoRA_girl.ipynb` などを先頭から実行してください。

#### コードの説明
最初のセルで必要な Python パッケージをインポートしています
```python:パッケージのインポート
import torch
from diffusers import FluxPipeline
import time
import ipywidgets
```

次のセルで Flux.1 dev をロードしています
```python: Flux.1 dev のロード
pipe = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    torch_dtype=torch.bfloat16
)
pipe.to("cuda")
```
次のセルで実際に画像を生成しています
```python:画像生成
test_case = "51"
start_time = time.time()
image = pipe(
    prompt="a cute Japanese idle singer girl, long black hair, She is singing ,holding a microphone, wearing white idle costume, standing on the stage .This is a flashy concert with 3D holograms and laser effects",
    height=1360,
    width=768,
    guidance_scale=3.5,
    output_type="pil",
    num_inference_steps=20,
    max_sequence_length=512,
    generator=torch.Generator("cpu").manual_seed(1127239343),
    joint_attention_kwargs={"scale": 1.0}
).images[0]
end_time = time.time()
print(f"画像生成時間: {end_time - start_time} 秒")
image.save(f"output/{test_case}.png")
```
プロンプトは
> a cute Japanese idle singer girl, long black hair, She is singing ,holding a microphone, wearing white idle costume, standing on the stage .This is a flashy concert with 3D holograms and laser effects

です。日本語に翻訳すると
> 黒い長髪の可愛い日本のアイドル歌手の女の子が、マイクを持って歌っています。彼女は白いアイドルのコスチュームを着て、ステージに立っています。3Dホログラムとレーザー効果を使った派手なコンサートです。

となります（翻訳は、["とにかく翻訳する青山アイさん"](https://qiita.com/yuji-arakawa/items/28f30a5434ba429f3f16)）。

次のセルは生成された画像を表示しています
```python:画像表示
image
```
次にプロンプトを少し変えて再び画像生成しています。まだ、LoRAは適用していません
```python:画像生成
test_case = "52"
start_time = time.time()
image = pipe(
    prompt="modern anime style, a cute Japanese idle singer girl, long black hair, She is singing ,holding a microphone, wearing white idle costume, standing on the stage .This is a flashy concert with 3D holograms and laser effects",
    height=1360,
    width=768,
    guidance_scale=3.5,
    output_type="pil",
    num_inference_steps=20,
    max_sequence_length=512,
    generator=torch.Generator("cpu").manual_seed(1127239343),
    joint_attention_kwargs={"scale": 1.0}
).images[0]
end_time = time.time()
print(f"画像生成時間: {end_time - start_time} 秒")
image.save(f"output/{test_case}.png")
```
今度のプロンプトは
> modern anime style, a cute Japanese idle singer girl, long black hair, She is singing ,holding a microphone, wearing white idle costume, standing on the stage .This is a flashy concert with 3D holograms and laser effects

です。これも翻訳すると
> 現代的なアニメスタイルで、可愛らしい日本のアイドル歌手の女の子です。長い黒髪で、彼女はマイクを持って歌っています。白いアイドルのコスチュームを着て、ステージに立っています。3Dホログラムとレーザー効果を使った派手なコンサートです。

となります。違いは"modern anime style"です。
そして、次のコードで生成した画像を表示しています
```python:画像表示
image
```
次のセルのコードが Diffusers の pipeline に LoRA をロードしています。このコードより上で生成されている画像は LoRA 無しで Flux.1 のオリジナルの画像です。このコードより後の生成画像が LoRA を適用したものです。
```python:LoRAのロード
pipe.load_lora_weights(
    pretrained_model_name_or_path_or_dict="loras",
    weight_name="QTCanimation_lora_v1-PAseer.safetensors"
)
```
以下のコードは LoRAを適用した Diffusers Pipeline を使って、上と同様に2種類のプロンプトで画像を生成しています。同じプロンプトの画像同士を較べてみると LoRA の効果が出ていることがわかります

<table>
<tr>
<td>
FLUX.1 Dev
</td>
<td>
LoRAなし
</td>
<td>
QTCanimatedFeeling-FLUX-PAseer【Alpha】
</td>
</tr>
<tr>
<td>
</td>
<td>

![51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/ac130e0f-9000-f67d-b7d2-da86afe4bbff.png)
</td>
<td>

![53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/a05b79ec-f56b-8afc-6631-9ea39c9c6374.png)
</td>
</tr>
<tr>
<td>
プロンプト
</td>
<td colspan=2>
a cute Japanese idle singer girl, long black hair, She is singing ,holding a microphone, wearing white idle costume, standing on the stage .This is a flashy concert with 3D holograms and laser effects
</td>
<tr>
<td>
seed
</td>
<td colspan=2>
1127239343
</td>
</tr>
<tr>
<td>
FLUX.1 Dev
</td>
<td>
LoRAなし
</td>
<td>
QTCanimatedFeeling-FLUX-PAseer【Alpha】
</td>
</tr>
<tr>
<td>
</td>
<td>

![52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/6e969f84-8d12-863f-ad60-b2f42dfce87d.jpeg)

</td>
<td>

![54.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74534/9aff5a55-94db-5b08-a1c8-a616cc097053.jpeg)

</td>
</tr>
<tr>
<td>
プロンプト
</td>
<td colspan=2>
modern anime style, a cute Japanese idle singer girl, long black hair, She is singing ,holding a microphone, wearing white idle costume, standing on the stage .This is a flashy concert with 3D holograms and laser effects
</td>
<tr>
<td>
seed
</td>
<td colspan=2>
1127239343
</td>
</tr>
</table>

## えっと、あとがきです
FLUX.1 が登場してひと月くらいですが LoRA も沢山出てきていますね。今回は Diffusers でも LoRA を適用できることを再確認しましたが ComfyUI や Forge などでも FLUX.1 対応が進んでいてこれから楽しめそうなモデルです。

ところで今回試した LoRA とは関係ないのですが FLUX.1 は、"modern anime style" というプロンプトを追加すると帽子や天使の輪、角といった被り物が出てくる確率が高いようです。面白いですね。

記事を書きかけにして2週間程放置している間に ImageFX とか出て来て本当に油断できないですね。他にもいろいろ LoRA を試してから公開と思っていましたが記事が古くなり過ぎないうちに公開します（下書きに9年前の記事が4つも残っていることに気づいたときのトラウマが忘れられない....）。

最初の FLUX.1 の記事は、自宅の RTX2060 という非力な GPU で頑張っていたのですがあまりにも時間がもったいないので今回はクラウドで GPU マシンを借りてお試ししました。あっ、止めないと課金が！ということで

終わりだよ～(o・∇・o)