1 points par GN⁺ 2026-01-19 | 1 commentaires | Partager sur WhatsApp
  • 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 -t contrôle l’intensité de la transformation : 0.0 conserve l’original, 1.0 régénère entièrement l’image

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’erreur
    • flux_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

 
GN⁺ 2026-01-19
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

    • Super. Le point clé, c’est une spécification vivante, mise à jour en continu
      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
    • Avec Beads de Steve Yegge, on peut réduire les parties inutiles des fichiers Markdown
      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
    • Je me demande si vous comptez aussi rédiger un billet sur les autres leçons mentionnées dans le README
      En tant que fan de longue date, j’aimerais entendre votre point de vue sur l’usage de ce type d’outils
    • Je me demande si vous pouvez partager autre chose que les logs de prompts ou les notes d’implémentation
      J’aimerais apprendre de votre processus de travail
    • Il existe aussi, avec Claude ou d’autres LLM, des solutions permettant de définir le travail, d’ajouter des notes d’implémentation et de gérer les sous-tâches et dépendances
      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

    • Cette fois, j’ai rédigé une spec plutôt qu’un prompt, mais il a ensuite fallu ajuster le modèle pendant des heures
      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

    • Ça dépend du contexte. Ici, le travail s’est fait uniquement à partir du code de référence fourni par Black Forest Labs pour Flux
      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
    • J’utilise un ensemble de prompts du type « audite les modifications actuelles du code sous l’angle des erreurs logiques »
      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

    • Je me demande combien de temps antirez aurait mis sans Opus
  • 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 version PyTorch utilise le GPU (Metal Performance Shaders), tandis que la version C n’utilise qu’un seul cœur CPU
      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
    • J’ai déjà écrit des kernels CUDA et des optimiseurs 8 bits, et les LLM sont plutôt doués pour l’optimisation des performances
      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 m’intéresse à l’IA depuis longtemps. Par exemple, j’ai créé gguf-tools
      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

    • C’est étrange qu’un kernel GGML écrit par IA ait été rejeté parce qu’il était non optimisé
      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

    • Le code de référence montre uniquement la configuration du pipeline d’inférence, sans inclure la véritable implémentation cœur (kernels, transformeur, etc.)
    • Si on demandait à Claude de réimplémenter l’inférence en C/C++ et qu’on y apposait une licence MIT, ce serait vraiment impressionnant
      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

    • Après un rapide survol du code, ce n’est pas du niveau amateur, et même si ce n’est pas du niveau entreprise, c’est plutôt solide
    • Ce jugement est daté. Avec Opus 4.5 et des règles claires dans CLAUDE.md, on obtient un code assez tolérant et propre
      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