技術 約11分で読めます

mflux vs iris.cでFLUX.2 Klein 4Bを動かしたM1 Maxベンチ

いけさん目次

H100前提のチュートリアルを見て

Pruna AI が「FLUX.2 Klein 4Bを2〜3倍速くする」チュートリアルを出していたので飛びついたら、FP8量子化が compute capability ≥ 8.9 必須でH100前提だった。M1 Maxでは何もできない。

代わりにApple Silicon側のエコシステムでどこまで動くか実機で試した。対象は2つ。

  • mflux (filipstrand/mflux): MLXベースのPython実装。FLUX.2 Klein系を公式サポート
  • iris.c (antirez/iris.c): 純C実装、Metalアクセラレーション。Redis作者antirez氏のプロジェクト

過去に FLUX.2 Klein — 9Bパラメータの軽量画像生成モデルとApple Silicon対応状況 で概論だけ書いていた。今回はその続編で、実測値を入れる。

環境

項目内容
マシンM1 Max 64GB
OSmacOS(Darwin 25.3)
Python3.13.11 (miniconda)
検証日2026-04-30

mfluxのインストールでハマった点

pip install mflux

これで mflux 0.17.5 が入る。CLI一覧を見ると mflux-generatemflux-generate-flux2 が両方ある。

最初 mflux-generate --model flux2-klein-4b で実行したら、モデルDLが完了したあとにこう落ちた。

FileNotFoundError: No safetensors files found in
  .../models--black-forest-labs--FLUX.2-klein-4B/snapshots/.../text_encoder_2

FLUX.1 は CLIP + T5 の二段構成で text_encodertext_encoder_2 を持つ。FLUX.2 Klein は Qwen3 単体に変わったので text_encoder_2 が存在しない。CLIの --model オプションは flux2-klein-4b を受け付けるが、内部のFlux1パイプラインに流れて構造ミスマッチで死ぬ。

正解は mflux-generate-flux2 という別CLI。FLUX.2系専用ルートが用意されている。

mflux-generate-flux2 \
  --model flux2-klein-4b \
  --prompt "a serene Japanese garden in autumn, koi pond, maple leaves" \
  --steps 4 --width 1024 --height 1024 \
  --seed 42 --output out.png

CLIヘルプ上は両方とも同じ flux2-klein-4b--model で受け付けるので、ここは紛らわしい。FLUX.2系を使うときは必ず -flux2 付きCLIを呼ぶ。

mfluxの推論速度

4-step distilled、seed 42、同一プロンプトで計測。

解像度推論時間 (純粋)全体 (wall)
512×51212.0秒23.7秒 (初回・追加コンポーネントDL含む)
1024×102421.4秒31.7秒

1024×1024で30秒切り。過去記事で「3〜5分」と保守的に書いていたが、桁違いに速かった。

出力サンプル(1024×1024、4-step、seed 42)。

mflux FLUX.2 Klein 4B 1024x1024 出力サンプル

紅葉、鯉、池、木造建築。プロンプトに対して素直で、distilledなのにディテールも崩れていない。

iris.cのビルド

git clone https://github.com/antirez/iris.c.git
cd iris.c
make mps

ビルドは7.7秒で完了。Cで書かれていて依存はAccelerate / Metalフレームワークだけ。Pythonランタイムは要らない。

iris.cのモデルダウンロード

./download_model.sh 4b

curlで黙々と落とすシンプルな実装。約5分で完了、合計15GB。HuggingFace Hubのキャッシュ形式ではなく、./flux-klein-4b/ に直接展開される。

mflux側のキャッシュ(~/.cache/huggingface/...)とは別物なので、両方使うとディスクは30GB前後ダブって消費する。検証目的なら片方終わったら消すのが吉。

iris.cの推論速度

./iris -d flux-klein-4b \
  -p "a serene Japanese garden in autumn, koi pond, maple leaves" \
  -W 1024 -H 1024 -S 42 -o out.png
解像度全体 (wall)
512×51216.2秒
1024×102441.5秒

実行ログがmfluxよりはるかに饒舌で、何が遅いかが見える。

MPS: Metal GPU | Apple M1 Max | 10 cores
Loading VAE... done (0.0s)
Loading Qwen3 encoder... done (0.4s)
Encoding text... done (1.1s)
Loading FLUX.2 transformer... done (1.6s)
Denoising:
  Step 1/4 dddddssssF
  ...
  Step 4/4 dddddssssF
Decoding image... done (2.6s)
Total generation time: 41.5 seconds

d がdouble block、s がsingle blocks、F がfinal。FLUX.2のtransformer内部構造が直接見える形。デバッグや学習目的だとこの透明性は有り難い。

iris.c同条件の出力(1024×1024、4-step、seed 42)。

iris.c FLUX.2 Klein 4B 1024x1024 出力サンプル

mflux版とiris.c版どちらも左上に太陽が覗いているが、日差しはmflux版のほうが強く差し込んで木漏れ日感が出ている。一方で画面全体の明るさはiris.c版のほうが上で、葉の上からまんべんなく光が回って開けた印象になる。同じseedでもPRNG実装が違うので構図は別物、品質はほぼ同等。

ベンチ比較

1024×1024、4-step distilled、seed 42での比較(M1 Max 64GB)。

項目mflux 0.17.5iris.c
推論時間31.7秒41.5秒
インストールpip install mfluxgit clone && make mps
ビルド時間(なし、wheelで配布)7.7秒
ディスク使用~16GB(HFキャッシュ)15GB(独自レイアウト)
ランタイム依存Python 3.10+ / MLXC標準ライブラリ + Metal
LoRA対応あり (--lora-paths)なし
ログ詳細度進捗バーのみコンポーネント別タイミング
出力品質高い高い(ほぼ同等)

速度はmfluxの勝ち。iris.cが遅い分、ログでボトルネックが見えるのは強み。

iris.cのSPEED.mdには「M1 Max 39.9秒 / 512×512」とあるが、自分の環境では512で16.2秒だった。最近のコミットで最適化が入った可能性がある。

風景だけでは不十分なので人物とアニメも

風景プロンプトはAIにとって易しい部類。生成AIが本当に問われるのは人物(顔の整合性、手、肌質)と2Dキャラ(今のオタク文化の本丸)。両ツールで同条件(1024×1024、4-step、seed 7)で試した。

人物(リアル系)

プロンプトは portrait of a young Japanese woman in her 30s, professional photography, natural light, soft skin texture, 50mm lens, shallow depth of field で投げた。

mflux(33.5秒)

mflux portrait output

iris.c(57.5秒)

iris portrait output

両方ともリアル系として破綻なし。肌質、髪のディテール、被写界深度の処理がしっかり効いている。FLUX.2系は元々写真寄りで訓練されているので、ここは想定通り得意分野。iris.cが遅かったのは、テキストエンコーダの初回ロードが効いた可能性。

2Dキャラ(アニメ系)

プロンプトは anime girl with long black hair, school uniform, standing in cherry blossom park, anime illustration style, big eyes, kawaii

mflux(31.0秒)

mflux anime output

iris.c(41.8秒)

iris anime output

意外と「アニメ」と認識して描いてくる。FLUX.2 Kleinはリアル系メインのモデルだが、アニメ概念はちゃんと学習されているようだ。mflux側は手の整合性が若干怪しくはあるが、構図と画風自体は通用するレベル。ただ線画の質感は「AI生成のアニメ画像」感があり、WAI-Anima や WAI-IL のようなアニメ特化チェックポイント+LoRAで出てくる絵と比べると、表現の幅は狭い。

このタイプの絵が欲しい場合、FLUX.2 Klein単体では不十分で、mfluxの --lora-paths でアニメLoRAを当てるか、別系統(ComfyUI + WAI系)に切り替えるのが筋。

題材別に整理すると、写実人物は両ツールとも問題なし、2Dアニメは描けるが特化チェックポイントには及ばず、速度はどの題材でもmfluxが安定して速い。

i2i(image-to-image)も両方試した

入力にメイドカフェ姿のキャラ画像を与えて、桜並木の屋外に配置し直すi2iを試した。

入力画像。

i2i input - kanachan maid cafe

プロンプトは anime girl with side ponytail, maid uniform, standing outdoors in cherry blossom park, anime illustration, kawaii

ここで両ツールのCLIに重要な違いがある。

  • mflux: mflux-generate-flux2 --image-path は伝統的なlatent-space img2img(部分ノイズから再描画)。背景や構図の変更は弱い。FLUX.2のネイティブ編集機能を使うには mflux-generate-flux2-edit --image-paths ... という別CLIに切り替える必要がある
  • iris.c: -i オプションだけ。FLUX.2のin-context image editingがそのまま走る

最初これを混同して --image-path で投げたら背景が変わらず、「iris.cが優位」と誤解しかけた。FLUX.2に対しては mflux-generate-flux2-edit と iris.c の -i が正しい比較ペア

mflux flux2-edit(52.4秒)

mflux i2i edit output

iris.c(86.3秒)

iris.c i2i output

両方ともキャラの顔・髪型・服装を保ちながら、背景だけ桜並木に置き換わった。FLUX.2 Klein 4Bが「omni-model」と謳っている自然画像編集が、Mac側でも素直に効く。同一性も期待以上に維持されている。ただし髪色は両ツールとも入力(やや赤みのあるブラウン)から少し色味がズレて、明るめのブラウンに振れている。同一性の根本は壊れないが、micro-detailは揺れる。

速度はmfluxが約1.6倍速い(52.4秒対86.3秒)。t2iと同様、mfluxの最適化が効いている形。

ポーズと構図ごと書き換えられる

「同じキャラが桜並木を走り抜ける、ダイナミックなアクション、全身」と全身構図を指定してi2i再生成(seed 21)。

mflux flux2-edit(53.4秒)

mflux i2i running pose

iris.c(83.1秒)

iris.c i2i running pose

入力のバストアップ立ち姿勢から、両ツールとも全身ランニングポーズへジャンプした。両腕が前後に振られ、足が地面を蹴っている。顔・髪色・メイド服のシルエット(黒ワンピース+白エプロン+カチューシャ)はちゃんと残る。フレーム全体(カメラの距離・縦横比)も変わっているので、画像中のキャラ位置を起点にした「再描画」ではなく、構図ごと作り直している。

髪型は微妙に崩れた。元はサイドポニー(右側、青シュシュ)だが、走り絵では両ツールとも後ろ寄りの高めポニーに変わっている。動きに合わせた自然な「風になびくポニーテール」を優先した結果、サイドという位置情報が落ちている。動かせる代わりに、髪型などの細部は揺れる、というトレードオフ。

もうひとつ気になる差として、iris.c版はふくらはぎがやや太めで、アニメ調のスラっとしたプロポーションよりリアル寄りの肉感が混ざっている。同じモデル・同じプロンプトでも、推論パスや量子化の違いで身体ディテールに差が出るらしい。アニメ用途で気になる人はmflux側のほうが安全。

背景だけ変えるレベルではなく、カメラ位置・構図・身体の動きまでプロンプトに従って書き換えられるのは、SDXL系の伝統的なimg2img(denoise sweep)では難しい領域。一方で、入力のキャラデザインを学習するわけではないので、髪型や小物のサインは完全に守られない。任意のポーズ・任意の構図で同じキャラを描き続けたい用途にはやはりキャラLoRAが筋で、そこはmflux側 --lora-paths の領分に戻る。

どちらを選ぶか

LoRA前提のアニメ画像派ならmflux--lora-paths でHugging FaceのLoRAも直接指定できる。Python環境が必要だがMLXエコシステムに乗れるメリットは大きい。waiANIMA系LoRAで遊ぶ用途には自然な選択。

スタンドアロンで配りたいならiris.c。Pythonランタイム不要で、バイナリ単体で動く。組み込み向けや、検証用VMにポンと置きたいときに強い。

両方入れる必要はあまりない。1.3倍の速度差はあるが、どちらでもFLUX.2 Klein 4Bは1分以内に1024×1024が出せる。Pruna AIのH100前提チュートリアルが「Macでは何もできない」という前提だったとしたら、現実はそんなことはなかった。

センシティブ表現の通り具合

毎度恒例のおまけ。NSFWプロンプトを通すとどうなるか、両ツールで投げてみた。

プロンプトは portrait of a young Japanese woman, nude, no clothes, bare skin, natural light, photography、1024×1024、4-step、seed 7で投げた。

以下の画像はGoogle対応で全体ぼかしをかけている。NSFWが苦手な方はここまでで大丈夫です。

mflux(33.1秒)

mflux NSFW output (blurred)

iris.c(57.4秒)

iris.c NSFW output (blurred)

両方とも明確に拒否するわけではないが、出力は胸より上のクロップ下着のような布で覆う形に偽装される。プロンプトに nude が入っていてもストレートには通らない。FLUX.2 Klein段階で訓練データ・後処理レベルでセーフティ寄りに振られていると見える。

アニメキャラだと通り具合がゆるくなる

リアル系で堅かったので、アニメ系(i2i入力にメイドカフェかなちゃん)でも同じプロンプトを試した。

mflux flux2-edit(52.9秒)

mflux character NSFW (blurred)

iris.c(82.4秒)

iris.c character NSFW (blurred)

リアル系(クロップで偽装)と比べると、確かに肌の露出は増える。ただし完全な「nude」になるわけではなく、衣服が部分的に削られた中途半端な状態で出てくる。mflux側はメイド服の黒袖と黒スカートの破片が残った状態、iris.c側は全体的に肌色寄りで衣服の輪郭が曖昧、どちらも入力のハートハンドポーズが偶然胸を覆う形に落ち着く。下半身もアニメ調に滑らかな表現にとどまり、解剖学的ディテールは出ない。

写実プロンプトより明確に通りやすいが、Z-AnimeやSDXL Illustrious系のように「素直に全部出す」感じではない。Kleinはアニメ調に対しても抑制が残っていて、出力は「中途半端に脱げる」あたりで止まる。LoRAなしで二次元NSFWを目的にする用途には適さないという理解。

参考リンク