🐯

Genmojiみたいなモデル「sdxl-emoji」をM2 Pro Mac miniで動かしてみた

2024/11/20に公開

はじめに

iOS 18.2から使える予定のApple Intelligenceの機能にGenmojiがあります。
実はGenmojiと同じように絵文字を生成できるモデルがHugging Face🤗にあります。この記事では、sdxl-emojiをM2 ProのMac miniで動かしてみたときにつまづいたところをメモしていきます。

sdxl-emojiについて

sdxl-emojiは、Stable Diffusion XLをAppleスタイルの絵文字でファインチューニングしたものです。

サンプルコードそのままでは動かない

sdxl-emojiのページにあるサンプルコードで、"cuda"となっている部分を"mps"に変えるだけでは、うまく動きませんでした。

import torch
from huggingface_hub import hf_hub_download
from diffusers import DiffusionPipeline
from cog_sdxl.dataset_and_utils import TokenEmbeddingsHandler
from diffusers.models import AutoencoderKL

pipe = DiffusionPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        torch_dtype=torch.float16,
        variant="fp16",
).to("mps") # <- "cuda"から"mps"に変更

pipe.load_lora_weights("fofr/sdxl-emoji", weight_name="lora.safetensors")

text_encoders = [pipe.text_encoder, pipe.text_encoder_2]
tokenizers = [pipe.tokenizer, pipe.tokenizer_2]

embedding_path = hf_hub_download(repo_id="fofr/sdxl-emoji", filename="embeddings.pti", repo_type="model")
embhandler = TokenEmbeddingsHandler(text_encoders, tokenizers)
embhandler.load_embeddings(embedding_path) # <- ここでエラーになる
prompt="A <s0><s1> emoji of a man"
images = pipe(
    prompt,
    cross_attention_kwargs={"scale": 0.8},
).images
#your output image
images[0]

つまづきポイント1: パッケージ不足

サンプルコードのページでは、必要なパッケージのインストールは以下のように書かれていました。

pip install diffusers transformers accelerate safetensors huggingface_hub

ですが、上記のパッケージをインストールしただけでは以下のエラーで動きません。

ValueError: PEFT backend is required for this method.

なので、以下のようにライブラリも追加でインストールする必要がありました。

pip install peft

つまづきポイント2: MPSでbfloat16を扱えない

Metal Performance Shader (MPS)を使っているPyTorchはbfloat16を扱えないので、torch.float16を使う必要があります。ですが、DiffusionPipeline.from_pretrained()torch_dtype=torch.float16を指定しても

TypeError: BFloat16 is not supported on MPS

とエラーが出てしまいます。エラーが出ている箇所は、上記のサンプルコードの# <- ここでエラーになると書いてある部分です。

Hugging Faceにあるサンプルコードのページでは必要なライブラリのインストールのほかに、cog-sdxlTokenEmbeddingsHandlerが必要と書かれていました。
ですが、エラーになる箇所がTokenEmbeddingsHandlerなので、試しにコメントアウトしてみたところ、絵文字の生成ができました。

動いたコード

以下が、M2 Mac miniで動いたコードです。
実際に動かしたときのコードはGitHubにあります。: Shakshi3104/hugmoji-supplementary

import torch

from diffusers import DiffusionPipeline
from diffusers.models import AutoencoderKL

pipe = DiffusionPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        torch_dtype=torch.float16,
).to("mps")

pipe.load_lora_weights("fofr/sdxl-emoji", weight_name="lora.safetensors")

prompt="A <s0><s1> emoji of a man"
images = pipe(
    prompt,
    cross_attention_kwargs={"scale": 0.8},
).images
#your output image
images[0]

生成した絵文字の例

プロンプトを「baby tiger with tiramisu」としたら、以下の絵文字ができました。
結構Appleの絵文字っぽい画像が生成できると思います。

絵文字生成にかかる時間

初回の実行時はモデルのダウンロードがあるので時間がかかりますが、以降は3分くらいで絵文字が生成されました。
今回使用しているMac miniのスペックは以下の通りです。

  • Apple M2 Pro
    • CPU: E-core: 4 / P-core: 8
    • GPU: 19-core
    • Nerual Engine: 16-core
  • RAM: 32GB

おわりに

GenmojiみたいなStable Diffusionモデル sdxl-emojiを動かしてみました。サンプルコードがそのまま動くと思っていましたが、意外とつまづきポイントがあって手こずりました。
2024年11月時点では、iOS 18.2がDeveloper betaなので、Genmojiはまだ完全に使える状態ではありません。Genmojiの前に、sdx-emojiでオリジナルの絵文字を作ってみるのもいいと思います。Genmojiがリリースされたら、生成させる絵文字の比較もしてみたいです。

参考

Discussion