1 pontos por GN⁺ 2026-01-19 | 1 comentários | Compartilhar no WhatsApp
  • Implementação em C puro que gera imagens a partir de texto ou imagem usando o modelo FLUX.2-klein-4B
  • Funciona sem dependências externas e, opcionalmente, pode ter aceleração com BLAS ou Metal, com ganho de velocidade de até 30x
  • O encoder de texto Qwen3-4B já vem integrado, sem necessidade de etapa separada de cálculo de embeddings
  • Suporta tanto texto para imagem quanto imagem para imagem, com interface de linha de comando e API de biblioteca em C
  • Pode ser executado sem runtime Python ou PyTorch, o que é relevante para ambientes leves de inferência e para ampliar o acesso a IA open source

Visão geral do projeto

  • FLUX.2-klein-4B é um modelo de geração de imagens da Black Forest Labs que recebe prompts de texto ou imagens existentes como entrada para criar novas imagens
  • Todo o código foi escrito apenas com a biblioteca padrão de C, com suporte opcional a aceleração por MPS (Apple Metal) e BLAS (OpenBLAS)
  • O modelo pode ser baixado do HuggingFace com cerca de 16GB, e seus componentes incluem VAE (300MB), Transformer (4GB), encoder Qwen3-4B (8GB) e Tokenizer

Principais recursos

  • Zero dependencies: pode ser executado de forma independente, sem bibliotecas externas
    • Ao usar BLAS, há ganho de cerca de 30x em velocidade; no macOS é possível usar Apple Accelerate e, no Linux, OpenBLAS
  • Metal GPU acceleration: ativada automaticamente em ambientes Apple Silicon
  • Text-to-image: gera imagens a partir de prompts de texto
  • Image-to-image: transforma imagens existentes de acordo com o prompt
  • Integrated text encoder: encoder Qwen3-4B integrado, sem embeddings externos
  • Memory efficient: após a codificação, a memória do encoder é liberada automaticamente, economizando cerca de 8GB

Exemplos de uso

  • Geração de imagem a partir de texto
    ./flux -d flux-klein-model -p "A fluffy orange cat sitting on a windowsill" -o cat.png
    
  • Transformação de imagem
    ./flux -d flux-klein-model -i photo.png -o painting.png -p "oil painting style" -t 0.7
    
    • O valor de -t controla a intensidade da transformação: 0.0 mantém o original, 1.0 recria completamente

Arquitetura do modelo e desempenho

  • Transformer: 5 blocos duplos e 20 blocos simples, dimensão oculta de 3072, 24 cabeças de atenção
  • VAE: AutoencoderKL, 128 canais latentes, compressão espacial de 8x
  • Text Encoder: Qwen3-4B, 36 camadas, dimensão oculta de 2560
  • Etapas de inferência: amostragem em 4 etapas para gerar resultados de alta qualidade
  • Requisitos de memória
    • Codificação de texto: cerca de 8GB
    • Difusão: cerca de 8GB
    • Pico máximo: 16GB (antes da liberação do encoder)
  • Benchmark de desempenho (Apple M3 Max, 128GB RAM)
    • 512×512: MPS 49,6 s, BLAS 51,9 s, PyTorch MPS 5,4 s
    • 256×256: MPS 32,4 s, BLAS 29,7 s, PyTorch MPS 3,0 s
    • 64×64: MPS 25,0 s, BLAS 23,5 s, PyTorch MPS 2,2 s
    • O backend em C puro é muito lento e é adequado apenas para testes

Build e execução

  • Seleção de backend
    • make mps: macOS Apple Silicon (mais rápido)
    • make blas: Intel Mac ou Linux (requer OpenBLAS)
    • make generic: C puro, sem dependências (lento)
  • Download do modelo
    pip install huggingface_hub
    python download_model.py
    
  • A resolução de saída vai até 1024×1024, com mínimo de 64×64; recomenda-se múltiplos de 16

API da biblioteca C

  • Carregamento e liberação do modelo
    • flux_load_dir(path) / flux_free(ctx)
  • Geração e transformação de imagem
    • flux_generate(ctx, prompt, params)
    • flux_img2img(ctx, prompt, input, params)
  • Entrada e saída de imagem
    • flux_image_load(path) / flux_image_save(img, path)
  • Utilitários
    • flux_set_seed(seed) para garantir reprodutibilidade
    • flux_get_error() para verificar mensagens de erro
    • flux_release_text_encoder(ctx) permite liberar memória manualmente

Licença e outras informações

  • Publicado sob a licença MIT
  • Composição de linguagens do repositório: C 93.9%, Objective-C 3.5%, Makefile 1.7%, Python 0.9%
  • 446 estrelas e 20 forks, mostrando forte interesse da comunidade

1 comentários

 
GN⁺ 2026-01-19
Comentários no Hacker News
  • Este projeto só foi possível porque foi dito ao Opus para obrigatoriamente usar o arquivo IMPLEMENTATION_NOTES.md
    Tudo o que era descoberto durante o desenvolvimento era acumulado nesse arquivo, que era sempre mantido atualizado, e foi especificado que ele deveria ser tratado imediatamente após a compressão de contexto
    Graças a esse método, foi possível conduzir um grande trabalho de programação com eficiência sem perder o fio da meada
    Para mais detalhes, veja o arquivo IMPLEMENTATION_NOTES.md no GitHub

    • Muito bom. O ponto-chave é ter uma especificação (spec) em atualização contínua
      Eu tratei dessa abordagem no texto sobre vibe-speccing
      Também foi útil colocar um “log de experimentos” no fim da especificação, para registrar sempre que surgisse alguma mudança inesperada
    • Com o Beads do Steve Yegge, dá para reduzir partes desnecessárias dos arquivos Markdown
      Fiquei curioso se você chegou a rodar benchmarks. Também seria interessante saber se a stack em Python é mais rápida ou mais lenta que a ferramenta de inferência em C
    • Fiquei curioso se você pretende escrever também sobre outras lições mencionadas no README
      Como fã de longa data, eu gostaria de ouvir sua perspectiva sobre o uso desse tipo de ferramenta
    • Gostaria de saber se você pode compartilhar materiais além do log de prompts ou das notas de implementação
      Quero aprender com o seu processo de trabalho
    • Também existem soluções no Claude e em outros LLMs para definir tarefas, adicionar notas de implementação e fazer gerenciamento de subtarefas e dependências
      Eu uso o Beads, e a qualidade dos resultados melhora claramente, especialmente em projetos grandes
  • Achei interessante ler a motivação no README
    Eu também estou tentando incluir um arquivo PROMPTS.md de forma parecida
    Para fins de compartilhamento e ensino, é útil mostrar que tipo de abordagem um desenvolvedor experiente usa
    Dá para manter isso deterministicamente usando hooks do Claude. No AGENTS.md, eu especifiquei que ele só pode ser lido
    Isso também foi útil para transmitir o contexto da tarefa ao alternar entre LLMs

    • Desta vez, em vez de prompts, eu escrevi uma especificação, mas depois precisei ajustar o modelo por várias horas
      No fim, os prompts são a soma total desse tipo de interação, então é muito difícil reconstruí-los de forma significativa
  • Sobre o experimento de usar LLM para transpilar para outra linguagem, fiquei curioso sobre como foi o resultado e o processo
    Num gargalo de um projeto recente, eu pedi ao Claude para “reescrever isso em Rust”, e o desempenho melhorou bastante
    Mas o resultado ainda não era confiável o suficiente para uso fora do laboratório

    • Depende da situação. Desta vez, o trabalho foi feito apenas com o código de referência fornecido pela Black Forest Labs para o Flux
      O ponto central é que o agente precisa conseguir entender, por meio do feedback, se está avançando, e conseguir depurar comparando com a implementação de referência
      Todo o código foi escrito com base em dicas de implementação que explicitavam o resultado que eu queria
      Hoje alguém portou para Swift minha implementação de vector set HNSW, e fiquei feliz porque a licença é a mesma
    • Eu uso um conjunto de prompts do tipo “audite as mudanças atuais no código do ponto de vista de erros lógicos
      Eu reinspeciono o código gerado pelo Claude com o GPT-5.x-Codex
      O Opus 4.5 ainda comete erros como off-by-one, então usar outro modelo como revisor técnico é eficaz
      Minha ordem de validação é: lint → test → outro modelo → eu
  • O modelo FLUX.2 [klein] original e o código em Python só foram publicados há 3 dias
    Veja a discussão relacionada aqui

    • Fico imaginando quanto tempo o antirez teria levado sem o Opus
  • Só porque foi escrito em C não quer dizer que necessariamente tenha desempenho de nível C
    Pelos benchmarks, é 8 vezes mais lento que PyTorch. LLMs ainda têm limitações para gerar código de altíssimo desempenho nesse nível

    • A versão em PyTorch usa GPU (Metal Performance Shaders), mas a versão em C usa apenas um único núcleo de CPU
      A razão da lentidão não é a qualidade do código do LLM, e sim a diferença de hardware
      As operações centrais de fato chamam a mesma biblioteca de kernels do PyTorch
    • Eu já escrevi kernels CUDA e otimizadores de 8 bits, e LLMs são até bastante capazes em otimização de velocidade
      Repetindo várias tentativas e benchmarks, eles conseguem melhorar rápido e, em alguns casos, já superaram até o forte baseline do torch
  • Pelo que sei, esse é o primeiro projeto OSS do Salvatore na área de ML, então fiquei curioso sobre como ele construiu o conhecimento de base necessário
    Também queria saber se o Claude ajudou a fornecer especialização no domínio

    • Eu já gosto de mexer com IA há bastante tempo. Por exemplo, já fiz o gguf-tools
      Também mantenho um canal de YouTube sobre IA em italiano, onde leio artigos e faço explicações
      Em 2003, fiz minha primeira implementação de rede neural, e depois continuei experimentando com pequenos modelos GPT em PyTorch ou C
      Ao trabalhar com Redis Vector Sets, lidei com vários modelos de embedding
      O Claude acelerou a implementação, mas eu já conhecia os conceitos básicos
      Mesmo alguém com só experiência em programação e quase nenhuma vivência em IA provavelmente conseguiria, mas exigiria mais idas e vindas de feedback
  • No mês passado, fiz um experimento parecido portando o Qwen 3 Omni para o llama.cpp
    Implementei a conversão para GGUF, quantização e modalidades de entrada/saída em uma semana, mas o PR foi rejeitado
    Links relacionados: PR #18404, modelo no Hugging Face

    • É estranho que kernels GGML escritos por IA tenham sido rejeitados por estarem não otimizados
      Uma pessoa que escreva os kernels manualmente pode obter ótimos resultados se souber orientar bem o modelo
      Se essa tendência continuar, vão aparecer forks do llama.cpp mais rápidos e melhores
  • É interessante que OpenBLAS e MPS tenham velocidades quase iguais
    No README, está dito que só o MPS usa GPU

  • Fico curioso se, ao pedir ao Claude para fazer o mesmo trabalho, eu poderia colocar meu nome e uma licença MIT
    Para referência, o Flux2 usa a Apache License
    Não é uma diferença enorme, mas esse tipo de detalhe de licença me chama atenção

    • O código de referência só mostra a configuração do pipeline de inferência, e não inclui a implementação central real (kernels, transformer etc.)
    • Seria realmente impressionante mandar o Claude reimplementar a inferência em C/C++ e colocar uma licença MIT
      Mas, claro, isso só teria valor se de fato funcionasse corretamente
  • Eu não conheço bem C e trabalho mais com análise baseada em SQL, então fiquei curioso se esse código é nível produção
    Ouço com frequência que código feito por LLM é difícil de manter

    • Dei uma passada pelo código, e não parece nível amador; não é nível corporativo, mas está bem razoável
    • Essa avaliação está ultrapassada. Com o Opus 4.5 e regras claras no CLAUDE.md, sai um código bem compreensível e limpo
      Em trabalhos de ciência de dados, o desempenho ainda varia bastante, mas se você definir bem o problema e fornecer entradas claras, dá para obter bons resultados