Both FLUX.1 57,408 open models are 12-billion-parameter rectified-flow transformers from Black Forest Labs 57,408 , each a 23.8 GB download. [schnell] ("fast" in German) is distilled to draw an image in 1 to 4 steps and is Apache 2.0. [dev], "trained using guidance distillation," is "second only to" the paid FLUX.1 [pro] and uses about 50 steps. Its license lets you "use Output for any purpose (including for commercial purposes)," but forbids running the weights for revenue-generating activity or in products that reach end users without a license from Black Forest Labs. FLUX.2 [klein] 4B (January 2026, Apache 2.0, 7.8 GB) is the newer permissive choice.
Neither was run here: their 16-bit weights alone need about 24 GB, six times this machine's GPU memory. Offloading layers to system RAM and 4- or 8-bit quantized builds help, but on a 4 GB card SD 1.5 is the model that runs.
<!doctype html>
<style>
body { margin: 0; padding: 8px; background: #fafaf7; font: 11px system-ui, sans-serif; color: #263238; }
svg { width: 100%; max-width: 600px; display: block; }
</style>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<p>Your GPU memory: <select id="gpu"><option value="4">4 GB (GTX 1650)</option><option value="8">8 GB</option><option value="12">12 GB</option><option value="24">24 GB</option></select>
· weights: <select id="bits"><option value="16">16-bit</option><option value="8">8-bit quantized</option><option value="4">4-bit quantized</option></select></p>
<svg viewBox="0 0 600 270" font-size="11"></svg>
<script>
// params in billions; steps per image; licence
const MODELS = [
{ name: 'FLUX.1 [schnell]', params: 12, steps: 4, lic: 'Apache 2.0', color: '#3f7d3a' },
{ name: 'FLUX.1 [dev]', params: 12, steps: 50, lic: 'Non-Commercial (outputs OK)', color: '#e09a10' },
{ name: 'FLUX.2 [klein] 4B', params: 4, steps: 4, lic: 'Apache 2.0', color: '#2a9d8f' },
{ name: 'SD 1.5', params: 0.86, steps: 20, lic: 'OpenRAIL-M', color: '#1f5f8b' },
];
const svg = d3.select('svg');
const y = d3.scaleBand(MODELS.map(m => m.name), [30, 120]).padding(0.2);
const x = d3.scaleLinear([0, 26], [130, 580]);
svg.append('text').attr('x', 130).attr('y', 18).attr('font-weight', 'bold').text('memory for the weights alone (GB)');
const gx = svg.append('g').attr('transform', 'translate(0,120)');
const row = svg.selectAll('g.m').data(MODELS).join('g').attr('class', 'm').attr('transform', m => `translate(0,${y(m.name)})`);
row.append('text').attr('x', 124).attr('y', y.bandwidth() / 2).attr('dy', '0.35em').attr('text-anchor', 'end').text(m => m.name);
const bar = row.append('rect').attr('x', 130).attr('height', y.bandwidth()).attr('fill', m => m.color);
const lab = row.append('text').attr('y', y.bandwidth() / 2).attr('dy', '0.35em');
const gpuLine = svg.append('line').attr('y1', 26).attr('y2', 124).attr('stroke', '#b5452f').attr('stroke-width', 2);
const gpuText = svg.append('text').attr('y', 138).attr('fill', '#b5452f');
// Steps per image, as dots
svg.append('text').attr('x', 130).attr('y', 168).attr('font-weight', 'bold').text('denoising steps per image');
MODELS.forEach((m, i) => {
svg.append('text').attr('x', 124).attr('y', 186 + i * 20).attr('text-anchor', 'end').text(m.name);
svg.selectAll(null).data(d3.range(m.steps)).join('circle').attr('r', 3.2).attr('cx', k => 136 + k * 8.8).attr('cy', 182 + i * 20).attr('fill', m.color);
svg.append('text').attr('x', 140 + m.steps * 8.8).attr('y', 186 + i * 20).text(`${m.steps} · ${m.lic}`);
});
function draw() {
const gpu = +document.getElementById('gpu').value, bits = +document.getElementById('bits').value;
gx.call(d3.axisBottom(x).ticks(6));
bar.transition().attr('width', m => x(m.params * bits / 8) - 130);
lab.transition().attr('x', m => x(m.params * bits / 8) + 5)
.text(m => `${(m.params * bits / 8).toFixed(1)} GB ${m.params * bits / 8 <= gpu ? '✔ fits' : '✘ too big (offload or quantize)'}`);
gpuLine.transition().attr('x1', x(gpu)).attr('x2', x(gpu));
gpuText.transition().attr('x', x(gpu) + 4).text(`${gpu} GB GPU`);
}
document.querySelectorAll('select').forEach(e => e.addEventListener('input', draw));
draw();
</script>