ハクソク

世界を動かす技術を、日本語で。

Flux 2 Kleinの純粋C推論

概要

  • FLUX.2-klein-4BはBlack Forest Labsによる、完全C言語実装のテキスト→画像生成モデル
  • 外部依存ゼロ(標準Cのみ)、MPSやBLASによる高速化も可能
  • テキストから画像/画像から画像生成に対応、Qwen3-4Bエンコーダー内蔵
  • モデル変換・量子化不要、safetensors形式をそのまま利用
  • Cライブラリとして統合可能、CLIツールも同梱

FLUX.2-klein-4B Pure C 実装の特徴

  • 完全C言語実装、外部依存なし(C標準ライブラリのみ)
  • MPS(Apple Silicon)やBLASによる高速化が可能
  • テキストから画像生成(text-to-image)機能
  • 画像から画像生成(image-to-image)機能
  • Qwen3-4Bエンコーダー内蔵、外部で埋め込み計算不要
  • モデル変換不要、safetensors形式のままfloatで利用
  • 量子化なし、精度維持
  • メモリ効率化:エンコーダー利用後に自動解放(約8GB節約)
  • CLIツールおよびCライブラリとして利用可能

開発背景

  • AIによるコード生成の実験として週末プロジェクトで開発
  • **Claude Code(Claude Maxプラン)**を活用し、全コードをAIで生成
  • Pythonスタック非依存の推論システムでAIの普及を目指す
  • **既存のC/C++実装(GGMLベース)**に対し、より簡潔な新規実装に挑戦

クイックスタート

  • ビルド方法(バックエンド選択)
    • make mps:Apple Silicon(最速)
    • make blas:Intel Mac/Linux(OpenBLAS必須)
    • make generic:純C(依存なし、遅い)
  • モデルダウンロード
    • pip install huggingface_hub
    • python download_model.py(約16GB)
  • 画像生成例
    • ./flux -d flux-klein-model -p "A woman wearing sunglasses" -o output.png
  • Python, PyTorch, CUDA不要で推論可能

主な機能

  • ゼロ依存:純C実装、スタンドアロン動作
  • BLAS高速化:最大約30倍高速化(Apple Accelerate, OpenBLAS)
  • Metal GPU自動対応:Apple Silicon Macで自動利用
  • テキスト→画像生成
  • 画像→画像生成(プロンプトで変換)
  • 統合テキストエンコーダー:Qwen3-4B内蔵
  • メモリ効率:自動エンコーダー解放

コマンドラインオプション

  • 必須
    • -d, --dir PATH:モデルディレクトリ
    • -p, --prompt TEXT:生成プロンプト
    • -o, --output PATH:出力画像パス(.png/.ppm)
  • 生成関連
    • -W, --width N:幅(デフォルト256)
    • -H, --height N:高さ(デフォルト256)
    • -s, --steps N:サンプリングステップ(デフォルト4)
    • -S, --seed N:ランダムシード
  • 画像→画像関連
    • -i, --input PATH:入力画像
    • -t, --strength N:変換強度(0.0-1.0、デフォルト0.75)
  • 出力・その他
    • -q, --quiet:静音モード
    • -v, --verbose:詳細表示
    • -e, --embeddings PATH:事前計算済み埋め込み利用
    • -h, --help:ヘルプ表示

再現性・シード管理

  • 生成時のシードは常にstderrに出力
  • 同じシードを指定すれば完全再現可能

ビルド方法

  • バックエンド選択
    • make:利用可能なバックエンド表示
    • make generic:純C(遅い)
    • make blas:BLAS高速化
    • make mps:Apple Silicon Metal GPU
  • 推奨環境
    • macOS Apple Silicon:make mps
    • macOS Intel/Linux(OpenBLAS):make blas
    • Linux(OpenBLASなし):make generic
  • OpenBLASインストール例
    • Ubuntu/Debian:sudo apt install libopenblas-dev
    • Fedora:sudo dnf install openblas-devel
  • その他
    • make clean:ビルド成果物削除
    • make info:バックエンド情報表示
    • make test:リファレンス画像テスト

モデルダウンロード内容

  • HuggingFace経由で約16GB
    • VAE(約300MB)
    • Transformer(約4GB)
    • Qwen3-4B Text Encoder(約8GB)
    • Tokenizer

技術詳細

  • モデル構成
    • Transformer:5ダブルブロック+20シングルブロック、3072隠れ次元、24ヘッド
    • VAE:AutoencoderKL、128チャネル、8倍圧縮
    • Text Encoder:Qwen3-4B、36層、2560隠れ次元
  • 推論ステップ:4ステップで高品質画像生成
  • メモリ要件
    • テキストエンコード時:約8GB
    • Diffusion時:約8GB(トランスフォーマー+VAE+アクティベーション)
    • ピーク時:約16GB
  • エンコーダーは自動解放、複数プロンプト時は自動再ロード

ベンチマーク

  • Apple M3 Max(128GB RAM)での生成速度
    • 512x512:C(MPS) 49.6s、C(BLAS) 51.9s、PyTorch(MPS) 5.4s
    • 256x256:C(MPS) 32.4s、C(BLAS) 29.7s、PyTorch(MPS) 3.0s
    • 64x64:C(MPS) 25.0s、C(BLAS) 23.5s、C(Generic) 605.6s、PyTorch(MPS) 2.2s
  • 解像度制限
    • 最大:1024x1024ピクセル
    • 最小:64x64ピクセル(16の倍数必須)

CライブラリAPI

  • libflux.aをリンク、flux.hをインクルード
  • 主な関数
    • flux_ctx *flux_load_dir(const char *model_dir);:モデル読み込み
    • void flux_free(flux_ctx *ctx);:リソース解放
    • flux_image *flux_generate(flux_ctx *ctx, const char *prompt, const flux_params *params);:テキスト→画像生成
    • flux_image *flux_img2img(flux_ctx *ctx, const char *prompt, const flux_image *input, const flux_params *params);:画像→画像生成
    • flux_image *flux_image_load(const char *path);:画像読み込み(PNG/PPM)
    • int flux_image_save(const flux_image *img, const char *path);:画像保存
    • flux_image *flux_image_resize(const flux_image *img, int new_w, int new_h);:リサイズ
    • void flux_image_free(flux_image *img);:画像解放
    • void flux_set_seed(int64_t seed);:シード設定
    • const char *flux_get_error(void);:エラー取得
    • void flux_release_text_encoder(flux_ctx *ctx);:エンコーダー手動解放
  • パラメータ構造体
    • width:画像幅
    • height:画像高さ
    • num_steps:ステップ数
    • guidance_scale:CFGスケール
    • seed:シード
    • strength:img2img用強度

利用例(プログラム断片)

  • テキスト→画像生成
    • モデルロード、パラメータ設定、画像生成、保存、解放
  • 画像→画像変換
    • 入力画像ロード、プロンプト指定、強度設定、変換、保存
  • 複数画像生成
    • 同一プロンプト・異なるシードで繰り返し生成

エラーハンドリング

  • 失敗時はNULL返却、flux_get_error()で詳細取得

この内容により、FLUX.2-klein-4Bの特徴・使い方・技術的背景が把握可能。C言語での高速・省依存AI画像生成に興味がある開発者・研究者に最適なプロジェクト。

Hackerたちの意見

LLMを使って別の言語にトランスパイルするメタ実験について、結果やプロセスについてどう感じた?今後も同じプロセスをやるつもり?最近、自分のプロジェクトでボトルネックを解消するために、プロジェクトの一部を「Rustで書き直して」ってClaudeに頼んだら、すごいスピードアップがあったんだ。最近は動画復元プログラムなんかもやったけど、でもその出力物は自分のホムラボ以外ではちょっと自信を持って勧められないな。
状況によるかな。今回はエージェントがFluxのBlack Forest Labsが提供したリファレンスコードだけを使って動いてたんだけど、基本的にはショーケースとして実装されたパイプラインなんだ。このプロセスが機能するためには、エージェントが本当に進展しているかどうかを理解するためのフィードバックが必要で、リファレンス実装に対して失敗をデバッグする必要があるんだ。でも、すべてのコードは、私が得たいものについての多くの実装ヒントを含んでいて、他の最小限の推論ライブラリやカーネルのリファレンスはなしに実装されてた。だから、これはTransformersの推論がどう機能するかについての既知の事実と、最終ユーザーに対してソフトウェアがどう見えるべきかという高レベルのアイデアを組み合わせた結果だと思う。ちなみに、今日、誰かが私のHNSW実装をベクターセット用にSwiftに翻訳してくれたんだ(https://github.com/jkrukowski/swift-hnsw)。それについては全然気にしてないし、AIで得られた結果かどうかも気にしないよ。ただ、実装がCのものとすごく似てるから、ターゲットライセンスが同じなのはいいね。
私は基本的に「現在のコード変更を論理エラーのために監査する」っていうプロンプトのセットを持ってて(あと、リントやテストも含めて、テスト条件を再確認することもね)、それをClaudeが生成したコードに対してGPT-5.x-Codexを使って実行してる。Opus 4.5でも、オフバイワンや論理境界のようなことでつまずくことが多いから、別のモデル(できれば新しいセッションのやつ)がとても効果的なピアレビューをしてくれるんだ。だから、私のチェックは通常、リント→テスト→他のモデル→私、って感じで、シンプルなコードではあまり多くのことが私のところに来ないよ。でも、複雑な論理や数学に関しては、全部私がやらないといけない。
このスレッドの読者にとって興味深いかもしれないこと: このプロジェクトは、Opusにすべての実装ノートを含むファイルを取る必要があるって言い始めてから可能になったんだ。それに、開発プロセス中に発見したことを蓄積することもね。それに、そのファイルには更新するための明確な指示があって、コンテキスト圧縮の後にすぐに処理されるべきだって書いてあった。これによって、Opusが合理的な時間内に大きなコーディングタスクをこなすことができたんだ。詳しくはGitHubリポジトリのIMPLEMENTATION_NOTES.mdをチェックしてみて。
すごくクールだね!そう、常に更新される仕様が鍵だよ。ここに書いたことがあるよ: https://lukebechtel.com/blog/vibe-speccing 原本の仕様の下部に「実験ログ」を持たせるのも役立つし、別のドキュメントにすることもできる。何かが「驚くべき展開」を見せたときには必ず更新する必要があるんだ。
サルバトーレ、これいいね。スティーブ・イェッジのビーズを使うのが好きなんだ。Markdownファイルの無駄がかなり減るから。ベンチマークはやった?Pythonのスタックが純粋なCの推論ツールより速いのか遅いのか、ちょっと気になる。
確立されたパラダイムを再発見する人たちを見るのは面白いね。突然みんながソフトウェア設計ドキュメントを再作成してる。[0] LLMが知性や能力を減らすって言う人もいるけど、明らかに人々はもっと整理されて、ドキュメントをしっかり作り、制約を守り、高度なパターンで考えるようになってきてる。形式的検証への関心も高まってるしね。LLMは、スキルのある雇用可能なエンジニアに、これらのツールで競争力を維持するために、最初からメンテナビリティと生産性の両方を追求させるだろうね。少なくとも、ロボットが完全に私たちを置き換えるまでの間は。[0] https://www.atlassian.com/work-management/knowledge-sharing/...
この開発作業サイクルのパターンは、Antigravityにぴったりだよ。これ、ほぼ80%はそのままでできちゃうし、ちょっとしたヒントで残りもできるようになるんだ。
LLMは自分の作業の正確さを確認するためにビジョン機能を使ってたの?もしそうなら、その確認方法はどうやってあなたが導いたの?
Claudeや他のLLMには、タスクを定義したり、実装ノートを追加したり(特に重要なのは)サブタスクや依存関係を追加できる複数のタスクソリューションがあるよ。私はBeads(https://github.com/steveyegge/beads)を使ってるけど、これが結果をかなり改善してくれると思う。特に大きなプロジェクトにはね。
じゃあCodexは、通常の仕様でそのタスクをやって、再圧縮なしでできるってこと?
READMEで言ってた他の学びについても書く予定ある?あなたのソフトウェアと文章の大ファンだから、これらのツールを使ったあなたの視点をぜひ聞きたいな!
すごいですね!どんなプロンプトを使ったのか、実装ノート以外のログを共有してもらえませんか?あなたの経験やステップから学びたいです。ありがとう!
> 推論時にPythonランタイム、PyTorch、CUDAツールキットは不要です。すごいですね、サルヴァトーレ!もう少しここに時間をかけて、私たちをCUDAツールキットとPythonから解放してください。
Claudeに同じことを頼んだら、MITライセンスを自分の名前で付けてもいいの? https://github.com/black-forest-labs/flux2はApacheライセンスみたいだけど。そんなに重要じゃないのは分かってるし、許可されていてオープンに利用できれば人々は気にしないけど、やっぱりちょっと気になる。
リファレンスコードは推論パイプラインのセットアップ方法を示してるけど、Cコードの99%は実装してないんだよね。つまり、推論カーネルやトランスフォーマーとかそういうの。
ClaudeにC/C++で推論を再実装するよう指示する時間を取ってくれたら嬉しいな。MITライセンスを付ければ大きなことになるけど、実際に動くならの話ね。
共有してくれてありがとう!READMEの中のモチベーションに感謝してるよ。ひとつ提案があって、私もやろうとしてるんだけど、PROMPTS.mdファイルを含めること。あなたの目的が共有と教育なら、経験豊富な開発者がどんなアプローチを使っているかを他の人が見るのに役立つと思う。たとえあなたがまだ試行錯誤中でもね。Claudeのフックを使って、これを決定論的に維持することができるよ。AGENTS.mdには、読むことはできるけど書くことはできないって指示してる。これがLLM間を行き来するのにも役立ってるし、あなたがやってきたことの背景を与えるのにいいんだ。
この場合、プロンプトの代わりに仕様を書いたんだけど、後でモデルを何時間も誘導しなきゃいけなかった。要するに、プロンプトはそういうやり取りの合計なんだ。意味のあるものに再構築するのは信じられないくらい難しい。
Cでコードを書かない人間で、もっと分析的な仕事(SQL)をしてるんだけど、ここで生成されたコードは「プロダクショングレード」なの?LLMについての主要な批判の一つは、メンテナンスしたくないようなコードを生成する傾向があるってことなんだけど、ここでもそうなのかな?
悪くないね。コードをざっと見た感じ、エンタープライズ品質ではないけど、アマチュアの使い捨てプロジェクトよりは確実にマシだよ。
その発言はほとんど古いし、エージェント最適化されてないLLMの症状みたいなもんだね。私の経験では、Opus 4.5はCLAUDE.mdの明確なルールに従って、慣用的なベストプラクティスをうまく守ってる。ただ、データサイエンスの仕事に関してはエージェントのパフォーマンスには賛否あるけど、問題を解決するために必要な情報をきちんと与えれば、いい仕事してくれるよ(例えば、SQLの場合はテーブルスキーマやサンプルデータね)。
先月、似たような実験をやってQwen 3 Omniをllama cppに移植したんだ。GGUF変換や量子化、入力と出力のモダリティを一週間もかからずに動かせるようにできたよ。作業をコードベースにPRとして提出したけど、当然のことながら却下された。 https://github.com/ggml-org/llama.cpp/pull/18404 https://huggingface.co/TrevorJS/Qwen3-Omni-30B-A3B-GGUF
AIが最適でないGGMLカーネルを書くことが多いから拒否されたっていうのは、ちょっと変に思える。手動でGGMLカーネルを書く人が、モデルを上手く誘導して優れたカーネルを書くのは簡単だし、エージェント用のドキュメントも素晴らしい仕事をするための指示を含めて作成できる。もしこのまま続けるなら、llama.cppのフォークがすぐに出てきて、もっと早く、もしかしたらさらに良いものが開発されるだろうね。これは避けられない。
経験からの提案だけど、画像のシードを印刷するだけじゃなくて、画像ファイルにメタデータとして追加した方がいいよ。そうしないと、私みたいに失くしちゃうから。
Comfyuiはそれを自動でやってくれるよ。
これって私の接続の問題?それともhuggingfaceのダウンローダーが完全に壊れてるの?進展が全くないのに、私のインターネット接続を圧迫してた。追記: https://github.com/bodaay/HuggingFaceModelDownloader は進展してるみたい。
サルヴァトーレ、どうやってこのテーマに必要な知識を身につけたの?確か、これがML分野での初めてのOSSプロジェクトだったよね。Claudeがこのエンジンを作るのにどれだけ役立ったのか、ちょっと気になって。
こんにちは、私は昔からAIで遊ぶのが好きでした。これを少し前に書いたんだけど、例として見せたくて:https://github.com/antirez/gguf-tools それと、主にAIについてのYouTubeチャンネルも持っていて(イタリア語で)、定期的に動画を投稿したり、論文を読んで解説したりしています。AIには長い間情熱を持っていて、2003年に初めてNNの実装を書いたんです(ここで使われた、ずいぶん前にRedisモジュールのショーケースとして:https://github.com/antirez/neural-redis)。それ以来、楽しみで小さなGPTモデルとかをPyTorchやCを使って実装し続けています。最近はRedis Vector Setsでの仕事を通じて、さまざまなモデル(特にテキスト埋め込みモデルなど)を扱う機会が増えました。Claudeのおかげで実装は早く進んだけど、各段階で何が起こっているのかを理解するための背景は持っていました。この種の作業がプログラミングの背景があってAIの知識がほとんどない状態でもできるのか、すごく興味深い質問だと思います。私の感覚では、もっと時間がかかるし、行ったり来たりが必要かもしれないけど、エージェントにもっと例を与えれば、最終的には何か動くものができると思います。
いいね!これがwasmで動いたらどれくらい遅くなるんだろう。夢の世界ではWebGPUも使えたらいいけど、それはもっと大変だね。