この記事は Zenn に公開した記事の再掲です(原文・最新版: https://zenn.dev/acs_developer/articles/apple-silicon-mps-float8-e4m3fn-workaround )。
Apple Silicon Mac(MPSバックエンド)でFP8量子化された画像生成モデルをロードすると、次のエラーで止まることがあります。
Undefined type Float8_e4m3fn
筆者は32GBユニファイドメモリのApple Silicon機(M5)+ ComfyUI系環境で、FLUX.2とKrea 2 Turboの2つのモデルで別々にこのエラーに遭遇し、それぞれ別の方法で回避して実測まで取りました。本記事はその記録です。
- ケース1(FLUX.2): 本体だけBF16版へ差し替えて解決
- ケース2(Krea 2 Turbo): BF16の現実的な選択肢がなくGGUF量子化版へ切り替えて解決(+ローダーのアーキタグ問題のパッチ)
何が起きているか
FP8(float8_e4m3fn)はNVIDIA GPU向けの量子化フォーマットとして配布されることが多く、MPSバックエンドではこの型の演算がサポートされていません。筆者の環境では、FLUX.2公式FP8版(flux-2-klein-4b.safetensors・約4.07GB)をロードした際、最初のlinear層に入った瞬間にUndefined type Float8_e4m3fnで停止しました。
ポイントは、これは「メモリ不足」ではなく「型の非対応」だということです。解像度を下げてもステップ数を減らしても解決しません。ファイルサイズが小さくて魅力的に見えるFP8版は、Macではそもそも動かない前提で構成を考える必要があります。
ケース1: 本体だけBF16へ差し替える(FLUX.2)
FLUX.2はBF16版が公式配布されているため、diffusion本体だけをBF16版へ差し替えました。差し替えたのは1ファイルだけで、他はそのまま流用しています。
| 役割 | ファイル | サイズ |
|---|---|---|
| diffusion本体 |
flux-2-klein-4b.safetensors(BF16版) |
約7.75GB |
| テキストエンコーダ | qwen3vl_4b_fp8_scaled.safetensors |
約5.24GB |
| VAE | flux2-vae.safetensors |
約0.34GB |
興味深いのは、テキストエンコーダのfp8_scaled版はMPSでもそのまま動いたことです。「FP8」と名の付くファイルが全滅するわけではなく、落ちるのはfloat8_e4m3fn型のまま演算に入る箇所です。エラーメッセージがどの層で出ているかを見て、差し替え対象を最小限にするのが容量的にも得策でした(失敗したFP8本体は削除して約4GBを回収)。
BF16差し替え後の実測(32GB機・MPS)
| 内容 | 解像度 | 実測時間 | 推定ピークメモリ |
|---|---|---|---|
| t2i単体生成 | 512×512 | 20.2秒 | 約25.1GiB |
| 参照画像1枚つき編集 | 512×512 | 30.3秒 | ─ |
| 参照画像2枚つき生成 | 800×1408 | 90.2秒 | 約27.2GiB |
BF16はFP8の約2倍のファイルサイズになりますが、32GBユニファイドメモリなら800×1408の参照つき生成までピーク約27GiBで収まりました。16GB機ではこの構成は厳しいとみてください(その場合は次のGGUF案が本命になります)。
ケース2: GGUF量子化版へ切り替える(Krea 2 Turbo)
Krea 2 TurboのFP8版も同じFloat8_e4m3fnエラーで動きませんでした。こちらはBF16をそのまま載せる選択肢が重かったため、**GGUF量子化版(Q6_K・10.6GB)**へ切り替えたところ、MPSで安定動作しました。
GGUFはLLM由来の量子化フォーマットですが、ComfyUI-GGUF経由で画像生成モデルにも使えます。FP8が使えないMacにとっては「ファイルサイズを抑えつつ動く」現実的な代替です。
落とし穴: GGUFのアーキテクチャタグ不一致
コミュニティ配布のGGUF(例: krea2_raw_bf16-Q5_1.gguf)では、GGUF内部のアーキテクチャタグが独自値(krea2)になっていて、ComfyUI-GGUFのローダーが未知アーキテクチャとして拒否する問題に当たりました。
筆者はComfyUI-GGUF/loader.pyのアーキテクチャ判定部にエイリアスを1行足すローカルパッチで解決しています(krea2を互換アーキテクチャ名として扱わせる)。考え方はこうです。
# loader.py のアーキテクチャ判定付近(概念コード)
if arch == "krea2":
arch = "qwen_image" # 互換アーキテクチャへ別名解決
注意点が2つあります。
-
git pullで更新するとパッチが消えます。カスタムノード更新後に「昨日まで動いていたGGUFが急に読めない」となったら、まずここを疑ってください - タグ偽装はあくまで「実体が互換アーキテクチャである」場合の対処です。中身が本当に別物なら当然壊れます
判断の指針まとめ
-
Undefined type Float8_e4m3fnは型の非対応。解像度・ステップ調整では直らない - 公式BF16版があるなら、エラーが出る本体だけBF16へ差し替えるのが最短(周辺ファイルは案外そのまま動く)
- BF16がメモリ的に重いならGGUF量子化版が現実解。Q6_Kクラスなら品質面の実用性も確認できた
- GGUFがローダーに拒否されたらアーキテクチャタグを確認。パッチは更新で消える前提で管理する
同じ問題の切り分け手順を、モデルを問わない一般形(エラーの4分類・保存すべき情報・判断表)としてまとめた記事もACS Developerで公開しています: Apple SiliconのFP8モデルエラーとBF16代替の実測