Flux 2 Klein : inférence en pur C
(github.com/antirez)- Implémentation en pur C permettant de générer des images à partir de texte ou d’images avec le modèle FLUX.2-klein-4B
- Fonctionne sans dépendances externes, avec en option une accélération BLAS ou Metal pouvant offrir jusqu’à 30× plus de vitesse
- Encodeur de texte Qwen3-4B intégré, sans besoin de calcul d’embeddings séparé
- Prend en charge à la fois le text-to-image et la transformation image-to-image, avec une interface en ligne de commande et une API de bibliothèque C
- Peut s’exécuter sans runtime Python ni PyTorch, ce qui est significatif pour les environnements d’inférence légers et l’élargissement de l’accessibilité de l’IA open source
Aperçu du projet
- FLUX.2-klein-4B est un modèle de génération d’images de Black Forest Labs, capable de créer de nouvelles images à partir de prompts textuels ou d’images existantes
- L’ensemble du code est écrit uniquement avec la bibliothèque standard C, avec prise en charge optionnelle de l’accélération MPS (Apple Metal) et BLAS (OpenBLAS)
- Le modèle peut être téléchargé depuis HuggingFace pour environ 16GB et se compose de VAE (300MB), Transformer (4GB), encodeur Qwen3-4B (8GB) et Tokenizer
Principales fonctionnalités
- Zero dependencies : exécution autonome sans bibliothèques externes
- Avec BLAS, environ 30× d’accélération, avec Apple Accelerate sur macOS et OpenBLAS sur Linux
- Metal GPU acceleration : activée automatiquement sur Apple Silicon
- Text-to-image : génération d’images à partir de prompts textuels
- Image-to-image : transformation d’images existantes selon un prompt
- Integrated text encoder : encodeur Qwen3-4B intégré, sans embeddings externes
- Memory efficient : libération automatique de la mémoire de l’encodeur après l’encodage, soit environ 8GB économisés
Exemples d’utilisation
- Génération d’image à partir de texte
./flux -d flux-klein-model -p "A fluffy orange cat sitting on a windowsill" -o cat.png - Transformation d’image
./flux -d flux-klein-model -i photo.png -o painting.png -p "oil painting style" -t 0.7- La valeur
-tcontrôle l’intensité de la transformation : 0.0 conserve l’original, 1.0 régénère entièrement l’image
- La valeur
Architecture du modèle et performances
- Transformer : 5 double blocks et 20 single blocks, dimension cachée de 3072, 24 têtes d’attention
- VAE : AutoencoderKL, 128 canaux latents, compression spatiale ×8
- Text Encoder : Qwen3-4B, 36 couches, dimension cachée de 2560
- Étapes d’inférence : échantillonnage en 4 étapes pour produire des résultats de haute qualité
- Exigences mémoire
- Encodage du texte : environ 8GB
- Diffusion : environ 8GB
- Pic maximal : 16GB (avant libération de l’encodeur)
- Benchmarks de performance (Apple M3 Max, 128GB RAM)
- 512×512 : MPS 49.6s, BLAS 51.9s, PyTorch MPS 5.4s
- 256×256 : MPS 32.4s, BLAS 29.7s, PyTorch MPS 3.0s
- 64×64 : MPS 25.0s, BLAS 23.5s, PyTorch MPS 2.2s
- Le backend en pur C est très lent et convient uniquement aux tests
Compilation et exécution
- Choix du backend
make mps: macOS Apple Silicon (le plus rapide)make blas: Intel Mac ou Linux (OpenBLAS requis)make generic: pur C, sans dépendances (lent)
- Téléchargement du modèle
pip install huggingface_hub python download_model.py - La résolution de sortie va jusqu’à 1024×1024, avec un minimum de 64×64 et des multiples de 16 recommandés
API de bibliothèque C
- Chargement et libération du modèle
flux_load_dir(path)/flux_free(ctx)
- Génération et transformation d’image
flux_generate(ctx, prompt, params)flux_img2img(ctx, prompt, input, params)
- Entrée/sortie d’image
flux_image_load(path)/flux_image_save(img, path)
- Utilitaires
flux_set_seed(seed)pour assurer la reproductibilitéflux_get_error()pour consulter les messages d’erreurflux_release_text_encoder(ctx)pour libérer manuellement la mémoire
Licence et autres informations
- Publié sous licence MIT
- Répartition des langages du dépôt : C 93.9%, Objective-C 3.5%, Makefile 1.7%, Python 0.9%
- 446 étoiles et 20 forks, signe d’un fort intérêt de la communauté
1 commentaires
Commentaires sur Hacker News
Ce projet a été possible parce qu’on a demandé à Opus d’utiliser impérativement le fichier IMPLEMENTATION_NOTES.md
Toutes les découvertes faites pendant le développement y étaient accumulées, le fichier était toujours maintenu à jour, et il était précisé qu’il fallait le traiter immédiatement après la compression du contexte
Cette méthode a permis de mener efficacement un gros travail de développement sans perdre le fil
Voir le fichier IMPLEMENTATION_NOTES.md sur GitHub pour plus de détails
J’ai abordé cette approche dans mon article sur le vibe-speccing
Il a aussi été utile d’ajouter un « journal d’expérimentation » en bas de la spec pour y consigner chaque changement inattendu
Je me demande si des benchmarks ont été faits. Ce serait aussi intéressant de savoir si la stack Python est plus rapide ou plus lente qu’un outil d’inférence en C
En tant que fan de longue date, j’aimerais entendre votre point de vue sur l’usage de ce type d’outils
J’aimerais apprendre de votre processus de travail
J’utilise Beads, et la qualité des résultats s’améliore nettement, surtout sur les gros projets
J’ai trouvé la motivation expliquée dans le README intéressante
Moi aussi, j’essaie d’inclure un fichier PROMPTS.md
À des fins de partage et de pédagogie, il est utile de montrer quelle approche un développeur expérimenté adopte
Avec un hook Claude, on peut garder cela déterministe. J’ai indiqué dans AGENTS.md qu’il devait être en lecture seule
C’était aussi utile pour transmettre le contexte de travail lors d’un passage d’un LLM à un autre
Au final, un prompt est la somme de ce type d’interactions, donc il est très difficile de le reconstituer de manière pertinente
Concernant les expériences de transpilation vers un autre langage avec un LLM, je serais curieux de connaître les résultats et le processus
Moi aussi, j’ai récemment demandé à Claude de « le réécrire en Rust » sur un goulet d’étranglement d’un projet, et les performances se sont nettement améliorées
En revanche, le résultat n’était pas suffisamment fiable pour un usage hors laboratoire
L’essentiel, c’est que l’agent puisse comprendre sa progression via le feedback, déboguer en comparant à l’implémentation de référence
Tout le code a été écrit à partir d’indices d’implémentation précisant le résultat que je voulais obtenir
Aujourd’hui, quelqu’un a porté en Swift mon implémentation de vector set HNSW, et ça fait plaisir car la licence est la même
Je fais ensuite revérifier le code généré par Claude avec GPT-5.x-Codex
Même Opus 4.5 continue à faire des erreurs de type off-by-one, donc utiliser un autre modèle comme relecteur pair est efficace
Mon ordre de validation est : lint → test → autre modèle → moi
Le modèle FLUX.2 [klein] original et le code Python n’ont été publiés qu’il y a 3 jours
Voir la discussion associée ici
Le fait que ce soit écrit en C ne veut pas forcément dire que ça offre des performances de niveau C
D’après les benchmarks, c’est 8 fois plus lent que PyTorch. Les LLM ont encore des limites pour générer ce niveau de code très haute performance
La lenteur vient donc de la différence de matériel, pas de la qualité du code produit par le LLM
Les opérations cœur appellent en réalité la même bibliothèque de kernels que PyTorch
Ils itèrent vite en répétant essais et benchmarks, et ils ont même parfois dépassé la solide baseline de torch
Sauf erreur, c’est le premier projet OSS de Salvatore dans le domaine du ML, donc je suis curieux de savoir comment il a acquis les connaissances de base nécessaires
J’aimerais aussi savoir si Claude a aidé en apportant une expertise métier
Je tiens aussi une chaîne YouTube sur l’IA en italien, où je lis et explique des articles de recherche
En 2003, j’ai réalisé ma première implémentation de réseau de neurones, et depuis je continue à expérimenter avec de petits modèles GPT en PyTorch ou en C
En travaillant sur Redis Vector Sets, j’ai manipulé divers modèles d’embeddings
Claude m’a permis d’aller plus vite dans l’implémentation, mais je connaissais déjà les concepts de base
Ce serait sans doute possible aussi avec seulement un bagage en programmation et très peu d’expérience en IA, mais il faudrait probablement davantage d’allers-retours de feedback
Le mois dernier, j’ai fait une expérience similaire en portant Qwen 3 Omni vers llama.cpp
J’ai implémenté la conversion GGUF, la quantification et les modalités d’entrée/sortie en une semaine, mais la PR a été refusée
Liens associés : PR #18404, modèle Hugging Face
Quelqu’un qui écrit les kernels manuellement peut obtenir d’excellents résultats s’il guide bien le modèle
Si cette tendance se poursuit, on verra apparaître des forks de llama.cpp plus rapides et meilleurs
Je trouve intéressant qu’OpenBLAS et MPS aient quasiment la même vitesse
Le README dit que seul MPS utilise le GPU
Je me demande si, en demandant la même tâche à Claude, on peut mettre mon nom dessus sous licence MIT
À noter que Flux2 utilise la licence Apache License
La différence est faible, mais ce genre de détails de licence m’interpelle
Encore faut-il que ça fonctionne réellement
Je ne connais pas bien le C et je fais surtout de l’analyse basée sur SQL, donc je me demande si ce code est de niveau production
J’entends souvent dire que le code produit par les LLM est difficile à maintenir
En data science, les performances restent irrégulières, mais si l’on définit clairement le problème et les entrées, on peut obtenir de bons résultats