Desenhos para colorir com IA local: do prompt ao arquivo que imprime bem
Gerar a imagem é a parte fácil, e é onde todo tutorial para. O que decide se a criança consegue pintar é o que vem depois: binarizar, vetorizar e imprimir sem serrilhado.
Com pressa? Peça o TL;DR ao Claude — ele lê a página e resume.
Minha filha pediu um desenho de dinossauro para pintar. Fui procurar na internet e achei o de sempre: PNG de seiscentos pixels com marca d’água no meio, três anúncios em volta, e uma linha que vira escadinha assim que sai da impressora.
Tenho seis máquinas aqui rodando modelo local. Achei que resolveria em dez minutos.
Levou uma tarde, e o problema não estava onde eu imaginava. A imagem sai fácil. O que dá trabalho é fazer ela chegar no papel de um jeito que uma criança de cinco anos consiga pintar.
Qual modelo, e por que não o mais famoso
black-forest-labs/FLUX.2-klein-4B
- Parâmetros
- 4 B
- Licença
- Apache 2.0
- Transformer
- 7,75 GB (BF16)
- Codificador de texto
- 8,04 GB (BF16)
- VAE
- 0,17 GB
- Total em disco
- 15,96 GB
Quase todo tutorial usa o FLUX.1 dev, que é o mais conhecido. Eu comecei por ele também, até parar para ler a licença: é não comercial.
Para desenho da minha filha, tanto faz. Só que aí a professora dela viu e pediu cópias para a turma inteira, e a conversa muda. Não sou advogado e não vou fingir que sei onde exatamente fica a linha entre uso pessoal e distribuição, mas achei mais simples usar um modelo em que essa pergunta não existe.
O klein de 4B é Apache 2.0. O que sai dele é seu, sem asterisco.
Quanto de VRAM
| Precisão | Transformer | Texto | VAE | Total |
|---|---|---|---|---|
| BF16 (como publicado) | 7,75 | 8,04 | 0,17 | 15,96 |
| FP8 | 3,88 | 4,02 | 0,17 | 8,06 |
| Q4 (~31%) | 2,40 | 2,49 | 0,17 | 5,06 |
Tem um detalhe que muda bastante a conta em placa pequena. O codificador de texto só trabalha enquanto o prompt está sendo lido. Depois disso ele pode sair da memória, e o transformer termina o serviço sozinho.
| Estratégia | Pico em BF16 | Pico em FP8 |
|---|---|---|
| Tudo carregado junto | 15,96 | 8,06 |
| Codificador descarregado após o prompt | 8,04 | 4,04 |
Em FP8 com descarregamento o pico teórico cai para 4 GB. Isso muda quem consegue brincar disso: cabe até em placa de 8 GB.
Cabe nas minhas placas?
| Máquina | Memória (GB) | BF16 completo | FP8 | FP8 + descarregamento |
|---|---|---|---|---|
| RTX 5070 · 12 GiB | 12,9 | não | cabe | sobra |
| RTX 5070 Ti · 16 GiB | 17,2 | apertado | sobra | sobra |
| RTX 4090 · 24 GiB | 25,8 | cabe | sobra | sobra |
| RTX 5090 · 32 GiB | 34,4 | sobra | sobra | sobra |
| MacBook Pro M4 Max · 48 GiB | 51,5 | cabe | sobra | sobra |
| Mini PC · 96 GiB unificados | 103,1 | sobra | sobra | sobra |
A 5070 de 12 GB é o caso interessante. Nos posts sobre LLM ela vive ficando de fora: não carrega um 27B, não carrega um 32B, fica sempre olhando os outros. Aqui ela roda tudo com folga em FP8. Geração de imagem é bem mais amigável com placa modesta do que texto, e ninguém comenta isso.
No Mac, com MLX
O caminho no Mac não é o mesmo. CUDA não existe ali, e usar PyTorch com backend MPS funciona mas é o pior dos mundos.
O que se usa é o mflux, uma reimplementação do Flux em MLX, o framework da Apple. Ele já suporta a família klein, tem quantização de 4 e 8 bits embutida e uma flag --low-ram para máquina apertada.
uv tool install mflux
mflux-generate \
--model klein \
--quantize 8 \
--steps 4 \
--height 1440 --width 1024 \
--prompt "coloring book page, thick black outlines, white background, a friendly dinosaur wearing rain boots" \
--output dino.png
Funciona bem. Só é mais devagar, e vale entender por quê.
Por que o Mac demora mais
Isso me incomodou por um tempo, porque nos testes com LLM o Mac costuma se sair bem. Um M4 Max acompanha placa boa gerando texto. Aí você manda ele gerar imagem e a diferença é gritante.
Não é contradição. Os dois problemas travam em lugares diferentes.
Gerar texto, na parte de decodificação, é basicamente ler os pesos inteiros da memória a cada token gerado. A conta em si é pequena; o gargalo é o transporte. Quem manda é largura de banda, e é exatamente aí que memória unificada compete de igual para igual.
Gerar imagem é outro problema. O modelo passa vinte, trinta vezes pelo mesmo latente, e cada passada é multiplicação de matriz grande. Os pesos já estão carregados e ficam parados; o que roda sem parar é cálculo. Aí quem manda é FLOPS.
| Máquina | TFLOPS | Onde isso pesa |
|---|---|---|
| RTX 4090 | 82,6 | geração de imagem |
| Apple M4 Max | 18,4 | geração de imagem |
Quatro vezes e meia de diferença em cálculo bruto. Some a isso o fato de que kernel de difusão vem sendo otimizado para CUDA há anos e para MLX há bem menos tempo, e o resultado é o que se vê.
Ordem de grandeza para calibrar expectativa: relatos públicos colocam o klein 4B em 30 a 40 segundos por imagem de 1024px num M1 Max. Não medi no meu M4 Max ainda, e não vou fingir que medi.
A conclusão prática é chata mas útil: se você tem placa NVIDIA e um Mac, gere no PC e edite no Mac. E se só tem Mac, o klein de 4B é a escolha certa justamente por ser pequeno.
O prompt
Página de colorir não é desenho bonito. É um desenho com um monte de restrição:
coloring book page for young children, black and white line art,
thick clean bold outlines, uniform line weight, pure white background,
no shading, no hatching, no gray tones, no texture,
large simple closed shapes, centered composition, generous margins
Cada pedaço ali está consertando alguma coisa que deu errado antes.
Linha fina some na impressora doméstica e a criança não vê onde parar, daí o thick bold outlines. Sombreado vira chuvisco de pontinhos no papel e ninguém consegue pintar em cima, daí o no shading, no gray tones. Região aberta faz o giz vazar, e região miúda demais é frustração pura para mão de cinco anos, daí o large simple closed shapes. E generous margins porque impressora de casa não imprime até a borda, o que eu descobri do jeito difícil.
Depois disso vem o tema, e aí sim vale caprichar: a friendly dinosaur wearing rain boots, standing next to a puddle.
Deixe a criança escolher. É a melhor parte, e também onde o processo emperra, porque pedido de criança sempre tem um detalhe que o modelo ignora ou entende ao contrário. Eu gero quatro de uma vez e deixo ela apontar. Sai mais rápido que tentar acertar de primeira, e escolher já é metade da diversão.
A parte que os tutoriais não contam
Aqui é onde os vídeos terminam: geraram o PNG, mandaram imprimir, acabou.
Só que o PNG é o formato errado para isso. Uma imagem de 1024×1024 impressa numa folha A4 dá uns 90 DPI. Impressora doméstica trabalha entre 300 e 600. O resultado é linha com degrau visível, que é exatamente o problema dos desenhos de banco de imagem que me fez começar tudo isso.
Gerar em resolução maior ajuda pouco e custa caro. A saída é outra: traço preto em fundo branco não deveria ser pixel, deveria ser vetor.
São duas operações. Primeiro binarizar, jogando tudo para preto ou branco puro, o que de quebra limpa os cinzas que o modelo insiste em deixar. Depois vetorizar, convertendo os contornos em curvas.
# 1. Binarizar: cinza vira preto ou branco, sem meio-termo
magick desenho.png -colorspace Gray -threshold 62% -type bilevel desenho.pbm
# 2. Vetorizar: contornos viram curvas
# --turdsize descarta manchinha solta (sujeira da geração)
# --alphamax controla o quanto os cantos são suavizados
potrace desenho.pbm --svg --turdsize 12 --alphamax 1.0 -o desenho.svg
# 3. PDF em A4, pronto para imprimir em qualquer tamanho
magick -density 300 desenho.svg -page A4 -gravity center -extent 2480x3508 desenho.pdf
O --threshold 62% é o número que você vai ficar ajustando. Baixo demais engorda a linha e fecha os detalhes. Alto demais quebra o traço e abre região, que é o pior dos dois, porque giz de cera vaza por buraco de um pixel só.
Depois do SVG o tamanho da impressão para de ser problema. O mesmo arquivo imprime nítido em A4 ou num painel de metro e meio para a parede do quarto. E fica com algumas dezenas de KB em vez de megabytes, o que importa na hora de mandar no grupo de pais da escola.
O teste que realmente vale
Nenhum número aqui responde se a página presta. O teste é dar giz de cera para uma criança e olhar.
Ela enxerga onde a linha fecha? As regiões cabem na mão dela? O desenho aguenta ser pintado por cima sem virar borrão?
Joguei fora umas quantas que ficaram lindas na tela e não funcionaram no papel. Linha elegante, fina demais. Detalhe que exigia precisão de adulto. O modelo não tem como saber disso, e nenhum prompt conserta.
O que ainda não medi
Segundos por imagem em cada máquina da bancada, incluindo o M4 Max. Quantas gerações costumam ser necessárias até sair uma página aproveitável, que na minha tarde foi coisa de uma em cinco. E se o klein de 4B perde para o irmão de 9B justamente em arte de linha, onde eu desconfio que modelo menor vá melhor, porque a restrição aqui é simplicidade e não riqueza de detalhe.
Essa última é a comparação que eu quero fazer. Fica para o próximo.
Fontes: FLUX.2-klein-4B no Hugging Face · mflux · potrace