模型简介
模型特点
模型能力
使用案例
license: apache-2.0 library_name: diffusers pipeline_tag: text-to-image
LibreFLUX:一款自由解蒸馏的FLUX模型
LibreFLUX是FLUX.1-schnell的Apache 2.0版本,提供完整T5上下文长度,采用注意力掩码机制,恢复了分类器自由引导功能,并移除了大部分FLUX美学微调/DPO内容。这意味着它比基础FLUX模型"丑"得多,但更容易针对新数据分布进行微调。它秉承开源软件的核心原则:应当比专有方案更难使用、更慢更笨拙,并保留21世纪初的审美趣味。

图中男子自信站立,身着印有幽默标语的基础款T恤,文字写道:"我把FLUX schnell解蒸馏成又慢又丑的模型,只换来这件蠢T恤"。他混合着骄傲与讽刺的表情,暗示理解语句背后的复杂性,又对这份寒酸回报感到好笑。中性背景突显人物与T恤,戏谑地浓缩了技术流程中常见挫败与虎头蛇尾的本质。
目录
使用指南
推理
通过diffusers调用定制流程,当前适配diffusers==0.30.3
。CFG尺度建议2.0-5.0,若出现模糊或异常阴影可降低CFG值(diffusers中为guidance_scale
),或在前几步禁用CFG(定制流程中no_cfg_until_timestep=2
)。
# ! pip install diffusers==0.30.3
import torch
from diffusers import DiffusionPipeline
pipe = DiffusionPipeline.from_pretrained(
"jimmycarter/LibreFLUX",
custom_pipeline="jimmycarter/LibreFLUX",
use_safetensors=True,
torch_dtype=torch.bfloat16,
trust_remote_code=True,
)
# 高显存配置
prompt = "黑板照片,上书:'我想假装自己是聋哑人'"
negative_prompt = "模糊"
images = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
return_dict=False,
# guidance_scale=3.5,
# num_inference_steps=28,
# generator=torch.Generator().manual_seed(42),
# no_cfg_until_timestep=0,
)
images[0][0].save('chalkboard.png')
# ≤24GB显存方案:
# ! pip install optimum-quanto
from optimum.quanto import freeze, quantize, qint8
# 量化冻结需耐心等待
quantize(
pipe.transformer,
weights=qint8,
exclude=[
"*.norm", "*.norm1", "*.norm2", "*.norm2_context",
"proj_out", "x_embedder", "norm_out", "context_embedder",
],
)
freeze(pipe.transformer)
pipe.enable_model_cpu_offload()
images = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
device=None,
return_dict=False,
do_batch_cfg=False, # https://github.com/huggingface/optimum-quanto/issues/327
# guidance_scale=3.5,
# num_inference_steps=28,
# generator=torch.Generator().manual_seed(42),
# no_cfg_until_timestep=0,
)
images[0][0].save('chalkboard.png')
ComfyUI用户可使用单变压器文件,但注意当前ComfyUI不支持注意力掩码可能导致画质下降。
微调
推荐使用SimpleTuner配合--flux_attention_masked_training
选项及jimmycarter/LibreFlux-SimpleTuner模型进行微调。该版本移除了干扰SimpleTuner的定制流程。SimpleTuner支持LyCORIS参数高效微调与全参数微调,推理时请使用本仓库定制流程按示例加载LyCORIS权重。
from lycoris import create_lycoris_from_weights
pipe = DiffusionPipeline.from_pretrained(
"jimmycarter/LibreFLUX",
custom_pipeline="jimmycarter/LibreFLUX",
use_safetensors=True,
torch_dtype=torch.bfloat16,
trust_remote_code=True,
)
lycoris_safetensors_path = 'pytorch_lora_weights.safetensors'
wrapper, _ = create_lycoris_from_weights(1.0, lycoris_safetensors_path, pipe.transformer)
wrapper.merge_to()
del wrapper
prompt = "黑板照片,上书:'我想假装自己是聋哑人'"
negative_prompt = "模糊"
images = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
return_dict=False,
)
images[0][0].save('chalkboard.png')
# 可选:保存融合LyCORIS的完整流程
# pipe.save_pretrained('/path/to/output/pipeline')
Schnell解蒸馏非技术报告
本报告以极不科学的方式,在有限资源下记录FLUX.1-schnell解蒸馏过程。不宣称模型优秀,但确实完成了训练,消耗约1,500 H100等效小时。

人人都是艺术家机器学习研究员。
动机
FLUX是优秀文生图模型,但现有版本均为蒸馏版。FLUX.1-dev通过蒸馏免去CFG(分类器自由引导),FLUX.1-schnell(德语"快速")进一步蒸馏至仅需4步生成。schnell采用Apache-2.0许可可自由商用,但直接使用CFG时效果欠佳,需跳过初始步骤。
蒸馏模型通过对抗网络等技术训练学生模型模仿教师模型。解蒸馏后生成耗时约翻倍(需计算条件/非条件样本),但优势在于自由商用、更易训练及潜在创造力。
恢复原始训练目标
简单采用流匹配目标与MSE损失即可重新学习。但LibreFLUX与OpenFLUX.1均未完全解蒸馏,表现为CFG>4.0时出现异常阴影或模糊。相较原始模型假设的50-200万H100小时训练量,我们的训练时长不足为奇。
FLUX与注意力掩码
FLUX使用T5-XXL文本编码器,将文本填充至256(schnell)或512(dev)标记。填充段被模型用于存储信息,注意力图可视化显示首尾各10-40个填充标记含关键信息。长提示因此性能下降。
通过注意力掩码可避免此问题。BFL未采用可能因现有实现已足够且加速训练考虑。我已实现掩码机制,使512标记全长度可用。虽然小规模微调会损伤模型,但解蒸馏本身需大幅调整,故加入此机制。
加速解蒸馏与小显存适配
全程避免全参数微调,采用quantoint8精度与6亿参数LoKr(比LoRA更接近全参数效果)。初始损失下降缓慢,通过以下噪声注入函数加速:
def approximate_normal_tensor(inp, target, scale=1.0):
tensor = torch.randn_like(target)
desired_norm = inp.norm()
desired_mean = inp.mean()
desired_std = inp.std()
current_norm = tensor.norm()
tensor = tensor * (desired_norm / current_norm)
current_std = tensor.std()
tensor = tensor * (desired_std / current_std)
tensor = tensor - tensor.mean() + desired_mean
tensor.mul_(scale)
target.copy_(tensor)
def init_lokr_network_with_perturbed_normal(lycoris, scale=1e-3):
with torch.no_grad():
for lora in lycoris.loras:
lora.lokr_w1.fill_(1.0)
approximate_normal_tensor(lora.org_weight, lora.lokr_w2, scale=scale)
此非标准PEFT,会轻微扰动所有权重。测试未发现性能下降且损失下降速度翻倍,故采用scale=1e-3
。配合adamw_bf16
优化器进行bfloat16训练。
LoKr层选择优化
FLUX的"norm"层含非线性变换,微调时变化显著。变压器模型主要工作由首尾层完成,故重点微调这些层。通过余弦相似度分析确认此现象后,向LyCORIS提交PR实现分层系数设置功能。
Beta时间步调度与分层
扩散模型存在多任务问题(不同时间步对应不同任务),梯度形态与损失量级各异。大批量时可平滑处理,针对schnell高噪时间步失真问题,采取两项措施:
- 实现近似原始sigmoid采样的Beta调度,侧重高噪时间步(类似SD3论文方法但更温和)
- 多层级分层采样,类似增大批量效果标准化梯度
from scipy.stats import beta as sp_beta
alpha = 2.0
beta = 1.6
num_processes = self.accelerator.num_processes
process_index = self.accelerator.process_index
total_bsz = num_processes * bsz
start_idx = process_index * bsz
end_idx = (process_index + 1) * bsz
indices = torch.arange(start_idx, end_idx, dtype=torch.float64)
u = torch.rand(bsz)
p = (indices + u) / total_bsz
sigmas = torch.from_numpy(
sp_beta.ppf(p.numpy(), a=alpha, b=beta)
).to(device=self.accelerator.device)
数据集
使用网络开源数据集,每图2-3条VLM生成描述(含长短版本)。数据集多样且未经过美学筛选,有助于摆脱文生图模型的过度优化倾向。共训练约50万张高分辨率图像,含随机方形与长宽比裁剪。
训练过程
初始在5x3090上训练月余,500,000图像,批量1(DDP等效5)。后意外获得RunWare7xH100资源,合并PEFT模型后改用32亿参数LoKr,批量6(DDP等效42)。H100训练时因SimpleTuner漏洞未使用初始化技巧,且分层采样进一步抑制梯度,导致1e-5
学习率下进展缓慢。
事后指数移动平均
懒于实现完整EDM2式EMA,改为保存所有检查点后按不同alpha值迭代LERP融合。评估不同CFG尺度后选定alpha=0.9。多数EMA模型在"极小值点游走"特性上差异不大。
结果分析
图1. LibreFLUX与OpenFLUX.1对比样本(diffusers生成,LibreFLUX使用512标记+注意力掩码,OpenFLUX使用256标记,35步采样,共用"模糊"负提示,int8量化)
OpenFLUX通过schnell输出解蒸馏,可能解释其文本能力较弱但保留FLUX超美学特征。文生图模型缺乏有效评估指标,在突破"混沌度"与个位数FID后,审美判断成为关键。
结语
若重来会提高H100训练的学习率。H100资源夜间突然到位,准备不足。解蒸馏schnell可能需要远超1,500 H100小时。期待参数更少效果更好的模型,如同LLaMA 3.1 8B媲美GPT3.5 175B的小规模优质模型。
对FLUX"开源"的看法:当前大量模型为VC融资造势,a16z挖角Stability.ai整个SD3团队后领域愈发浮躁。但相信个人与研究机构将持续推动开放权重发展。本项目零收益,ML领域至今零收益,但愿持续贡献。

感谢RunWare提供H100资源。
联系与资助
通过模型讨论区issue联系。如需资助继续训练或提供可复现研究条件,请留邮箱。
引用格式
@misc{libreflux,
author = {James Carter},
title = {LibreFLUX: A free, de-distilled FLUX model},
year = {2024},
publisher = {Huggingface},
journal = {Huggingface repository},
howpublished = {\url{https://huggingface.co/datasets/jimmycarter/libreflux}},
}









