本文中出现的 FPI 统一指代 F-PolyImage 产品(https://geocommunity.vip)
面向读者:如果你正在尝试快速部署视觉大模型,将 AI 图像生成能力接入自己的产品,或者希望后续通过 LoRA 微调让模型更贴合具体业务场景,那么这篇文章会比较适合你。本文以 F-PolyImage 产品为例,记录我如何在云 GPU 上完成视觉模型的部署与微调,并借助 ComfyUI 工作流和 API 接口,让前端产品能够真正调用模型生成图片。相比单纯介绍某个工具,本文更关注一个完整的工程实践问题:如何把一个视觉大模型从“能跑起来”,进一步推进到“能被产品稳定调用”。
一、为什么现阶段FPI选择租用服务器来做模型微调,而不直接自建算力或只用第三方 API?
目前产品上线时间较短,用户体量尚小,同时我们存在自研部署模型的业务需求。通过自主完成模型微调与参数定制,能够打造产品差异化竞争力,摆脱单纯依赖第三方大模型 API 调用的被动局面。基于现阶段实际情况,我们选择以服务器租赁方式开展模型微调及参数优化工作。
二、我们的服务器是在哪里租用的?并简单介绍GPU、CPU、ComfyUI。
我们的服务器租用自 Onething AI,管理后台地址:https://console.onethingai.com。创建实例,选择合适于需求的镜像和显卡规格即可。我们的如下:

ComfyUI 是一个用来运行 AI 绘图/图像生成工作流的可视化工具。
GPU 的全称是 Graphics Processing Unit,中文常叫 图形处理器 / 显卡。主攻:图像渲染、AI 计算、大量并行运算
CPU 的全称是 Central Processing Unit,中文叫 中央处理器。负责运行系统、调度程序、处理通用计算任务。
其实我们在 OneThing AI 租用的是一个完整的云服务器实例,只不过它和之前用来部署网站的腾讯云服务器不太一样:它配备了高性能 GPU,因此更适合视觉模型、AI 绘图、模型推理、部署和调参等任务。
三、云服务器在模型部署方面有哪些操作上的优势?模型部署到底部署的是什么?
OneThing AI 提供的是一个已经部署好的 GPU + ComfyUI 环境,模型如果已内置就可以直接选用;如果没有内置,则需要先上传或下载模型,再在对应工作流中调用。模型部署不是从零安装服务器环境那一步,而是把模型文件准备好,并让 ComfyUI 能够调用它的过程。如果自己部署:准备硬件 → 安装系统 → 安装 GPU 驱动 → 安装 CUDA / PyTorch 环境 → 安装 ComfyUI → 下载模型 → 放到正确目录 → 安装自定义节点 → 启动服务 → 测试工作流 → 对外访问或接入业务系统。可以看到很复杂,但是部署原理都一样。
四、FLUX.2 klein 4B + ComfyUI 部署命令教程
我们租用的服务器支持 FLUX2 模型的快速部署,因此当前目标是完成官方工作流的配置与导入,具体步骤如下:
- 下载官方工作流 JSON
- 复制到 ComfyUI/output
- 从 OneThingAI 的「输出目录」下载到本地
- 再把这个 JSON 拖进 ComfyUI 画布
详细部署过程:
首先进入命令行界面。

(点击”日志/终端”)

1、确认环境
nvidia-smi
确认能看到:
NVIDIA GeForce RTX 4090
找到 ComfyUI 目录:
find / -maxdepth 3 -type d -name "ComfyUI" 2>/dev/null
你当时得到的是:
/root/ComfyUI
确认云存储:
ls /root/onethingai-fs
df -h | grep onethingai
2、创建模型目录并软链接到 ComfyUI
mkdir -p /root/onethingai-fs/mymodels/flux2/diffusion_models
mkdir -p /root/onethingai-fs/mymodels/flux2/text_encoders
mkdir -p /root/onethingai-fs/mymodels/flux2/vae
把 ComfyUI 的模型目录链接到云存储:
cd /root/ComfyUI
rm -rf /root/ComfyUI/models/diffusion_models
ln -s /root/onethingai-fs/mymodels/flux2/diffusion_models /root/ComfyUI/models/diffusion_models
rm -rf /root/ComfyUI/models/text_encoders
ln -s /root/onethingai-fs/mymodels/flux2/text_encoders /root/ComfyUI/models/text_encoders
rm -rf /root/ComfyUI/models/vae
ln -s /root/onethingai-fs/mymodels/flux2/vae /root/ComfyUI/models/vae
检查:
ls -l /root/ComfyUI/models | grep -E "diffusion_models|text_encoders|vae"
3、安装下载工具
python -m pip install -U modelscope
python -m pip install -U "huggingface_hub>=0.34.0,<1.0"
如果没有 aria2c,安装:
apt update && apt install -y aria2
4、克隆 FLUX.2 klein 工作流包
你当时下载的是这个包,里面有官方工作流和下载链接:
cd /root/onethingai-fs/mymodels
git clone https://cnb.cool/fuyaotingyu/ComfyUI/ComfyUI-FLUX.2-klein.git flux2_klein_pack
进入目录:
cd /root/onethingai-fs/mymodels/flux2_klein_pack
查看里面的文件:
find /root/onethingai-fs/mymodels/flux2_klein_pack -maxdepth 3 -type f | sort
当时里面有这个工作流:
workflows/FLUX.2 klein 蒸馏版文生图.json
5、下载 qwen_3_4b.safetensors
这是文本编码器,必须是单文件版,不能用 model-00001-of-00002.safetensors 那种分片文件。
aria2c \
-x 16 \
-s 16 \
--continue=true \
--file-allocation=none \
-d /root/ComfyUI/models/text_encoders \
-o qwen_3_4b.safetensors \
"https://cnb.cool/ai-models/Comfy-Org/flux2-klein-4B/-/lfs/6c671498573ac2f7a5501502ccce8d2b08ea6ca2f661c458e708f36b36edfc5a?name=qwen_3_4b.safetensors"
检查:
ls -lh /root/ComfyUI/models/text_encoders/qwen_3_4b.safetensors
6、下载 FLUX.2 klein 4B FP8 主模型
这是后来解决显存问题的关键文件:
cd /root/ComfyUI/models/diffusion_models
aria2c -x 16 -s 16 -c \
-o flux-2-klein-4b-fp8.safetensors \
"https://cnb.cool/ai-models/black-forest-labs/FLUX.2-klein-4b-fp8/-/lfs/97ed34fe0567e436200f2faee3939b88f2b5d99f8af2a4dc16532c4245c0ccb6?name=flux-2-klein-4b-fp8.safetensors"
检查:
ls -lh /root/ComfyUI/models/diffusion_models/flux-2-klein-4b-fp8.safetensors
你当时检查到:
3.8G flux-2-klein-4b-fp8.safetensors
7、下载或准备 VAE
你当时已经有了:
flux2-vae.safetensors
如果是从 ModelScope 下载,可以这样:
modelscope download --model black-forest-labs/FLUX.2-klein-4B --include "*.safetensors" --local_dir /root/onethingai-fs/mymodels/flux2_test
然后复制 VAE:
cp /root/onethingai-fs/mymodels/flux2_test/vae/diffusion_pytorch_model.safetensors /root/ComfyUI/models/vae/flux2-vae.safetensors
检查:
ls -lh /root/ComfyUI/models/vae/flux2-vae.safetensors
8、把官方工作流复制到 ComfyUI 输出目录
cp "/root/onethingai-fs/mymodels/flux2_klein_pack/workflows/FLUX.2 klein 蒸馏版文生图.json" /root/ComfyUI/output/flux2_official_t2i.json
检查:
ls -lh /root/ComfyUI/output/flux2_official_t2i.json
你当时得到:
-rw-r--r-- 1 root root 18K ... /root/ComfyUI/output/flux2_official_t2i.json
然后去 OneThingAI 页面:
输出目录 -> 下载 flux2_official_t2i.json 到本地
再把这个文件:
flux2_official_t2i.json
拖进 ComfyUI 画布,就会自动生成如下截图的节点。

9、启动或重启 ComfyUI
cd /root/ComfyUI
pkill -f "python.*main.py" || true
sleep 2
nohup python main.py --listen 0.0.0.0 --port 8188 > /root/comfyui.log 2>&1 &
sleep 5
ss -lntp | grep 8188
当然,也可以快捷重启:

然后根据自身需求进行调参即可。所有工作完成之后,点击启动按钮,测试图片生成。
五、工作流介绍

1、简单介绍
一套 FLUX.2 klein 蒸馏版文生图工作流。
它的作用很简单:输入一段文字提示词,让模型根据提示词生成一张图片。
比如这里的提示词是:一辆超级跑车。
整个流程可以理解为:文字提示词 → 模型理解文字 → 在潜空间(Latent)生成图像 → 解码成真实图片 → 保存输出
2、详参介绍
| 模块 | 当前配置(根据需求设置) | 教学解释 |
|---|---|---|
| 工作流类型 | FLUX.2 klein 文生图 | 根据文字生成图片 |
| 提示词 | 一辆超级跑车 | 生成内容 |
| 图片尺寸 | 512×512 | 生成正方形图片 |
| 主模型 | flux-2-klein-4b-fp8 | 负责图像生成 |
| 文本编码器 | qwen_3_4b.safetensors | 负责理解提示词 |
| VAE | flux2-vae.safetensors | 负责解码图像 |
| Seed | randomize | 每次生成不同结果 |
| 采样器 | euler | 快速稳定的采样算法 |
| 步数 | 4 | 蒸馏模型快速出图 |
| CFG | 1.0 | 提示词引导较自然 |
| batch size | 1 | 一次生成一张 |
| 输出前缀 | F-PolyImage | 保存图片名称前缀 |
如果想换更强的模型,比如更大参数、更高精度、画质更好的 FLUX 模型,本质上就是:把 UNet 加载器里的模型文件换成另一个模型文件。但前提是:这个模型文件必须已经在服务器的对应模型目录里。
如果需求是图生图或者局部重绘,那么就不能只使用当前这套文生图工作流,而应该切换到对应的 Img2Img 图生图工作流 或 Inpainting 局部重绘工作流。(详情问GPT,这里主要是想告诉大家:不同的生成需求,对应的是不同类型的工作流。比如文生图用 Text-to-Image 工作流,图生图用 Img2Img 工作流,局部重绘用 Inpainting 工作流。在实际使用中,效率最高的方式通常不是从零开始搭建节点,而是优先选择官方已经提供好的工作流模板,然后在这个基础上调整提示词、模型、尺寸、步数、CFG、去噪强度等关键参数。这样既能减少搭建节点时出错的概率,也能帮助我们更快地跑通流程、验证效果,并把主要精力放在模型效果和参数调优上。)
六、本地跑通文生图工作流后,我是如何放在产品中用的?
1、导出工作流为API格式的json文件

2、查看 ComfyUI 实际运行端口
3、用本机地址验证 ComfyUI 是否正常
4、在平台页面添加真实运行端口的公网映射


我查到的端口是7860,添加7860端口,把URL地址复制给AI就行了。后面就是让AI根据API.json的格式向该URL请求图像生成,并且返回图像到本地,显示在产品前端。
七、ComfyUI 工作流和基于 API JSON 格式通过 URL 请求图像生成的实现原理与区别
在 ComfyUI 网页端测试生成时,在页面上看到的工作流其实就是一个可视化配置器。点“运行”后,前端会把当前工作流里的节点参数,比如提示词、宽度、高度、seed、steps、模型节点连接关系等,提交给服务器端的 ComfyUI 后端;ComfyUI 后端再按这个工作流去调用 GPU 上的 FLUX 模型完成推理生成。现在的 API 文件里也能看到这些节点。
而在本地代码测试时,本质上是跳过了ComfyUI的网页界面,直接把导出的 API.json 当作“工作流请求体模板”,由代码修改里面的参数,然后通过 URL 请求远程 ComfyUI 的接口,例如 /prompt。ComfyUI 收到这个 JSON 后,执行的还是同一套模型推理逻辑。
区别是:网页端是“可视化界面帮你提交工作流”,代码端是“你自己把 API 工作流 JSON 提交给服务器”。
八、截止2026/5/15,产品调用Flux2模型遇到的问题。以及后期的模型微调。
问题:产品在本地localhost测试模型Flux2模型完全没问题。但是,部署到公网后,虽然能够正常生成图片,但是拿不回图片返回到产品前端。
模型微调分为两类:
- 推理参数调优
- 模型训练 / LoRA 微调
第一类,推理参数调优,不重新训练模型,只调整生成过程里的参数,让出图更稳定、更符合产品需求。
第二类,进行真正的微调,大概思路:
- 收集 30~50 张统一风格活动海报,清洗掉低质量和文字过多的图
- 每张图写英文 caption,统一加触发词 fpoly poster style
- 先用 512/768 分辨率、rank 4/8、500~1000 steps 跑通
- 固定 10 条测试 prompt,对比原模型和 LoRA 模型
- 把 LoRA 加入工作流,调 LoRA 权重 0.6、0.8、1.0
- 导出 ImageFlux_Poster_API.json,接入产品
- 前端增加“活动海报”风格入口,后端自动使用海报 LoRA 工作流
九、问题解决
之前能生成,但是前端不显示是由于ComfyUI 云实例到部署产品的服务器的网络极差,即使在ComfyUI生成了,但是下载到服务器本地很慢,只有下载成功,才返回到前端显示。然后我改了一个策略,ComfyUI生成成功,立即借助生成图片的URL显示在前端,后端静默下载图片进行服务器本地存储。
十、图生图工作流拓展
在前面的文章中,我主要记录了 F-PolyImage 产品如何通过云 GPU 部署 FLUX.2 Klein 文生图工作流,并通过 ComfyUI 的 API JSON 接入产品后端。后续实验中,我继续测试了 FLUX.2 Klein 的图生图能力,也就是基于用户上传的参考图,再结合提示词生成新的图片。
图生图和文生图的底层逻辑有很多相似之处:二者都运行在同一个云 GPU 服务器上的 ComfyUI 服务中,都通过 ComfyUI 的 /prompt 接口提交工作流任务,也都可以通过 /history 和 /view 获取生成结果。不同点在于,图生图在提交任务之前,需要先把用户上传的图片传到 ComfyUI,然后在 API JSON 中把 LoadImage 节点的图片名称替换成用户实际上传的文件名。
1、下载官方图生图工作流
我当前的服务器终端位置是:
(base) root@instance:~#
首先确认 ComfyUI 是否存在:
ls -lh /root
如果看到:
ComfyUI
说明 ComfyUI 目录存在。然后进入 ComfyUI 目录:
cd /root/ComfyUI
pwd
正常输出应该是:
/root/ComfyUI
接着创建一个专门存放 FLUX.2 Klein 工作流 JSON 的目录:
mkdir -p workflows/flux2-klein
下载官方图生图 / 图像编辑 Base 工作流:
curl -L -o workflows/flux2-klein/image_flux2_klein_image_edit_4b_base.json https://raw.githubusercontent.com/Comfy-Org/workflow_templates/refs/heads/main/templates/image_flux2_klein_image_edit_4b_base.json
再下载 Distilled 快速版图生图工作流:
curl -L -o workflows/flux2-klein/image_flux2_klein_image_edit_4b_distilled.json https://raw.githubusercontent.com/Comfy-Org/workflow_templates/refs/heads/main/templates/image_flux2_klein_image_edit_4b_distilled.json
下载完成后检查:
ls -lh workflows/flux2-klein
如果看到:
image_flux2_klein_image_edit_4b_base.json
image_flux2_klein_image_edit_4b_distilled.json
说明官方图生图工作流已经下载成功。
2、确认模型文件是否齐全
我的 ComfyUI 模型目录是软链接到云盘的:
models/diffusion_models -> /root/onethingai-fs/mymodels/flux2/diffusion_models
models/text_encoders -> /root/onethingai-fs/mymodels/flux2/text_encoders
models/vae -> /root/onethingai-fs/mymodels/flux2/vae
因此要查看真实模型目录中的文件:
ls -lh /root/onethingai-fs/mymodels/flux2/diffusion_models
ls -lh /root/onethingai-fs/mymodels/flux2/text_encoders
ls -lh /root/onethingai-fs/mymodels/flux2/vae
图生图工作流主要需要这些模型文件:
flux-2-klein-4b-fp8.safetensors
qwen_3_4b.safetensors
flux2-vae.safetensors
如果使用部分 Base 图像编辑工作流,可能还需要:
flux-2-klein-base-4b-fp8.safetensors
full_encoder_small_decoder.safetensors
如果缺少 Base 主模型,可以下载:
wget -c -O /root/onethingai-fs/mymodels/flux2/diffusion_models/flux-2-klein-base-4b-fp8.safetensors "https://huggingface.co/black-forest-labs/FLUX.2-klein-base-4b-fp8/resolve/main/flux-2-klein-base-4b-fp8.safetensors"
如果缺少图像编辑 VAE,可以下载:
wget -c -O /root/onethingai-fs/mymodels/flux2/vae/full_encoder_small_decoder.safetensors "https://huggingface.co/black-forest-labs/FLUX.2-small-decoder/resolve/main/full_encoder_small_decoder.safetensors"
下载后再次检查:
ls -lh /root/onethingai-fs/mymodels/flux2/vae
如果看到:
flux2-vae.safetensors
full_encoder_small_decoder.safetensors
说明 VAE 文件准备完成。
3、把图生图工作流 JSON 下载到本地电脑
ComfyUI 的工作流 JSON 文件虽然已经下载到了服务器上,但如果要拖入浏览器里的 ComfyUI 画布,还需要把 JSON 文件下载到本地电脑。
可以在服务器上临时开启一个 HTTP 下载服务:
cd /root/ComfyUI/workflows/flux2-klein
python3 -m http.server 8899
终端出现类似:
Serving HTTP on 0.0.0.0 port 8899 ...
说明临时文件服务已经启动。
然后在本地浏览器访问:
http://你的服务器公网IP:8899/
如果 8899 端口打不开,说明还没有做公网映射。可以到云 GPU 平台的实例控制台中添加 8899 端口的公网映射。
进入页面后下载:
image_flux2_klein_image_edit_4b_base.json
image_flux2_klein_image_edit_4b_distilled.json
下载到本地电脑后,打开 ComfyUI 网页,把 JSON 文件直接拖到 ComfyUI 画布里即可。
4、后续接入产品后端时,依然导出为API文件,然后基于API文件的格式进行传参生图。
十一、截至2026/5/22,初步完成对lora微调:从 15 张电脑电商海报开始:训练一个 FLUX.2 Klein LoRA 的完整实践记录。

(流程图)
最近我尝试用自己的电脑电商海报数据集,训练一个可以在 ComfyUI 工作流中使用的 LoRA。整个过程并不是简单地“上传图片、点训练”就结束,而是完整经历了数据集准备、训练器安装、模型路径确认、VAE 适配、LoRA 注入修复、正式训练和 ComfyUI 加载测试。
最终,我成功训练出了一个适用于 FLUX.2 Klein 4B 的电脑电商海报风格 LoRA,并在 ComfyUI 中成功加载出图。
1、最终目标
我的目标很明确:
用 15 张电脑电商海报图,训练一个 LoRA,让模型在生成图片时更容易生成类似的视觉风格。
我希望 LoRA 学到的不是具体某一张图,而是:
电脑产品居中展示
电商广告海报构图
科技感背景
高光、屏幕光、边缘光
大标题区域
商业产品摄影氛围
训练完成后,我希望在 ComfyUI 的 FLUX.2 Klein 文生图工作流中,通过触发词调用这个风格。
最终使用的触发词是:
fpoly_computer_poster_style
2、整体路线选择
一开始,我的 ComfyUI 工作流使用的是:
flux-2-klein-4b-fp8.safetensors
这是 FLUX.2 Klein 的 fp8 推理模型。
但 fp8 模型更适合推理,不适合作为训练底模。因此训练时,我选择了非 fp8 版本:
/root/onethingai-fs/mymodels/flux2/diffusion_models/flux-2-klein-4b.safetensors
最终路线是:
FLUX.2 Klein 4B 非 fp8 模型训练 LoRA
↓
导出 LoRA
↓
复制到 ComfyUI
↓
在 FLUX.2 Klein fp8 工作流中加载使用
没有走 SDXL LoRA,也没有走 FLUX.1-dev LoRA,而是直接打通了 FLUX.2 Klein 4B LoRA 训练路线。
3、训练集准备
我的训练集一共有 15 张图片,每张图片都有一个对应的英文描述 txt。
最终目录是:
/root/ComfyUI/input/computer_poster_lora
文件结构如下:
001.jpg
001.txt
002.jpg
002.txt
003.jpg
003.txt
...
015.jpg
015.txt
每个 .txt 文件都使用同一个触发词开头,例如:
fpoly_computer_poster_style, computer e-commerce promotional poster, modern laptop computer, center composition with three-quarter front view, dark gradient background with subtle blue glow, dramatic rim lighting and screen glow, large text area at top, professional commercial advertising photography
我先检查了数据集数量:
cd /root/ComfyUI/input/computer_poster_lora
echo "图片数量:"
ls *.jpg *.png *.jpeg 2>/dev/null | wc -l
echo "txt数量:"
ls *.txt 2>/dev/null | wc -l
结果是:
图片数量:15
txt数量:15
然后检查触发词是否统一:
grep -l "^fpoly_computer_poster_style" *.txt | wc -l
grep -L "^fpoly_computer_poster_style" *.txt
结果 15 个 txt 都包含触发词,数据集准备完成。
4、训练工具:Ostris AI Toolkit
我使用的是:
Ostris AI Toolkit
安装路径:
/root/ai-toolkit
安装命令:
cd /root
git clone https://github.com/ostris/ai-toolkit.git
cd /root/ai-toolkit
pip install -r requirements.txt
安装后检查:
python run.py --help
正常显示帮助信息,说明训练器可以运行。
5、硬件环境
我的训练环境是:
GPU:NVIDIA GeForce RTX 4090
显存:23.53GB
PyTorch:2.7.1+cu126
CUDA:可用
检查命令:
python - <<'PY'
import torch
print("torch:", torch.__version__)
print("cuda available:", torch.cuda.is_available())
if torch.cuda.is_available():
print("gpu:", torch.cuda.get_device_name(0))
print("vram GB:", round(torch.cuda.get_device_properties(0).total_memory / 1024**3, 2))
PY
因为是 4090 24GB 级别显存,所以训练参数采用保守方案:
batch_size: 1
LoRA rank: 16
learning rate: 8e-5
dtype: bf16
quantize: true
low_vram: true
6、确认 FLUX.2 Klein 模型文件
我先查找了本地模型:
find /root/ComfyUI/models /root/onethingai-fs/mymodels -iname "*flux*klein*" -o -iname "*flux-2*"
确认存在这些文件:
/root/onethingai-fs/mymodels/flux2/diffusion_models/flux-2-klein-4b.safetensors
/root/onethingai-fs/mymodels/flux2/diffusion_models/flux-2-klein-4b-fp8.safetensors
/root/onethingai-fs/mymodels/flux2/diffusion_models/flux-2-klein-base-4b-fp8.safetensors
最终训练使用:
/root/onethingai-fs/mymodels/flux2/diffusion_models/flux-2-klein-4b.safetensors
ComfyUI 推理工作流继续使用:
flux-2-klein-4b-fp8.safetensors
7、训练配置文件
我先复制了 ai-toolkit 的 FLUX LoRA 模板:
cd /root/ai-toolkit
cp config/examples/train_lora_flux_24gb.yaml config/computer_poster_lora.yaml
之后逐步修改配置。
最终关键配置如下:
name: "computer_poster_lora_flux2_klein_test"
trigger_word: "fpoly_computer_poster_style"
network:
type: "lora"
linear: 16
linear_alpha: 16
network_kwargs:
target_lin_modules:
- "Flux2"
datasets:
- folder_path: "/root/ComfyUI/input/computer_poster_lora"
caption_ext: "txt"
caption_dropout_rate: 0.05
resolution: [512, 768, 1024]
train:
batch_size: 1
steps: 600
gradient_accumulation_steps: 1
train_unet: true
train_text_encoder: false
gradient_checkpointing: true
noise_scheduler: "flowmatch"
optimizer: "adamw8bit"
lr: 8e-5
dtype: bf16
disable_sampling: true
model:
name_or_path: "/root/onethingai-fs/mymodels/flux2/diffusion_models/flux-2-klein-4b.safetensors"
arch: "flux2_klein_4b"
quantize: true
flux2_klein_te_path: "/root/onethingai-fs/mymodels/flux2_test/text_encoder"
vae_path: "/root/onethingai-fs/mymodels/flux2/vae/full_encoder_small_decoder.safetensors"
low_vram: true
其中最关键的三点是:
arch: "flux2_klein_4b"
network_kwargs:
target_lin_modules:
- "Flux2"
vae_path: "/root/onethingai-fs/mymodels/flux2/vae/full_encoder_small_decoder.safetensors"
8、踩坑一:VAE 不匹配
第一次测试训练时,模型主体和 Qwen3 文本编码器都加载成功了,但 VAE 报错:
KeyError: 'decoder.up.0.block.0.conv1.bias'
最开始我尝试过:
/root/onethingai-fs/mymodels/flux2_test/vae/diffusion_pytorch_model.safetensors
以及:
/root/onethingai-fs/mymodels/flux2/vae/flux2-vae.safetensors
都失败了。
于是我检查了几个 VAE 文件的 key:
python - <<'PY'
from safetensors.torch import safe_open
vae_files = [
"/root/onethingai-fs/mymodels/flux2/vae/flux2-vae.safetensors",
"/root/onethingai-fs/mymodels/flux2/vae/full_encoder_small_decoder.safetensors",
"/root/onethingai-fs/mymodels/flux2_test/vae/diffusion_pytorch_model.safetensors",
]
for path in vae_files:
print("\n===", path, "===")
with safe_open(path, framework="pt", device="cpu") as f:
keys = list(f.keys())
target = "decoder.up.0.block.0.conv1.bias"
print("has target key:", target in keys)
PY
结果只有这个文件包含目标 key:
/root/onethingai-fs/mymodels/flux2/vae/full_encoder_small_decoder.safetensors
所以最终使用它作为 VAE。
这个问题解决后,日志成功走到:
Model Loaded
9、踩坑二:LoRA 没有挂载到模型
解决 VAE 后,又遇到新的问题:
create LoRA for U-Net: 0 modules.
There are not any lora modules in this network.
这说明模型加载成功了,但 LoRA 没有挂载到任何模块。
我继续查看 ai-toolkit 的代码,发现 FLUX.2 的目标模块是:
Flux2
于是配置里加入:
network_kwargs:
target_lin_modules:
- "Flux2"
但第一次加入后仍然失败。原因是配置里还保留了:
is_flux: true
这会让 ai-toolkit 把目标模块强制覆盖成 FLUX.1 的:
FluxTransformer2DModel
而 FLUX.2 Klein 不是这个模块名,所以 LoRA 仍然挂不上。
最终解决方案是:
删除 is_flux: true
保留 arch: "flux2_klein_4b"
手动指定 target_lin_modules: ["Flux2"]
修复后,日志显示:
create LoRA for U-Net: 80 modules.
这说明 LoRA 成功挂载。
10、先做 20 步测试训练
正式训练前,我先把步数设为:
steps: 20
测试训练成功后,日志中出现:
create LoRA for U-Net: 80 modules.
Found 15 images
Caching latents to disk
Saved checkpoint
这说明训练链路已经打通:
模型能加载
Qwen3 能加载
VAE 能加载
LoRA 能挂载
训练集能读取
训练能跑
权重能保存
11、正式训练 600 步
测试成功后,我把步数改成:
steps: 600
正式训练命令:
cd /root/ai-toolkit
python run.py config/computer_poster_lora.yaml
训练过程中保存了中间版本:
computer_poster_lora_flux2_klein_test_000000250.safetensors
computer_poster_lora_flux2_klein_test_000000500.safetensors
最终保存:
/root/ai-toolkit/output/computer_poster_lora_flux2_klein_test/computer_poster_lora_flux2_klein_test.safetensors
日志中关键结果是:
Saved checkpoint to output/computer_poster_lora_flux2_klein_test/computer_poster_lora_flux2_klein_test.safetensors
说明正式训练成功。
12、复制 LoRA 到 ComfyUI
训练完成后,我把最终 LoRA 复制到 ComfyUI 的 LoRA 目录:
mkdir -p /root/ComfyUI/models/loras
cp /root/ai-toolkit/output/computer_poster_lora_flux2_klein_test/computer_poster_lora_flux2_klein_test.safetensors \
/root/ComfyUI/models/loras/computer_poster_lora_flux2_klein_v1.safetensors
最终 LoRA 文件:
/root/ComfyUI/models/loras/computer_poster_lora_flux2_klein_v1.safetensors
13、ComfyUI 工作流接线
在 ComfyUI 里,我添加了:
LoRA 加载器(仅模型)
Lora LoaderModelOnly
因为我没有训练文本编码器,所以只需要模型版 LoRA 加载器。
最终接线是:
UNet加载器
↓
LoRA加载器(仅模型)
↓
CFG引导器
↓
采样器
↓
VAE解码
↓
保存图片
也就是把 LoRA 插在:
UNet加载器 和 CFG引导器 之间
LoRA 强度初始设置为:
0.70

14、提示词测试
测试时提示词必须包含触发词:
fpoly_computer_poster_style
例如:
fpoly_computer_poster_style, modern laptop e-commerce promotional poster, product centered, dark blue technology background, dramatic rim lighting, glowing screen, clean premium commercial layout, large headline area, professional product advertising design
最终 ComfyUI 成功出图,画面已经有明显的电脑电商海报风格。
15、最终成果
最终我得到的 LoRA 文件是:
computer_poster_lora_flux2_klein_v1.safetensors
它可以在我的 FLUX.2 Klein 文生图工作流中使用,用来生成电脑电商广告海报风格图片。
这次完整完成了:
训练集准备
触发词设计
ai-toolkit 安装
FLUX.2 Klein 模型适配
VAE 修复
LoRA target 修复
20 步测试训练
600 步正式训练
ComfyUI 加载 LoRA
成功出图
17、后续优化方向
这次训练只用了 15 张图,已经能看到风格效果。后续可以继续优化。
如果风格不够明显,可以尝试:
LoRA 强度提高到 0.8 - 1.0
或者继续训练到:
800 - 1000 steps
如果画面变形、过拟合或者电脑结构不稳定,可以降低 LoRA 强度:
0.45 - 0.6
也可以测试中间版本:
computer_poster_lora_flux2_klein_test_000000500.safetensors
有时 500 步比最终 600 步更自然。
另外,LoRA 不适合精准生成海报文字。
它更适合学习构图、风格、光影和商业设计氛围。海报中文字最好后期用设计软件、局部重绘或专门的文字控制流程处理。
十二、后续扩展:如果训练集增加到 1000 张,如何快速重新训练?
1. 新建 1000 张训练集目录
我建议不要覆盖原来的 15 张小数据集,而是新建一个目录:
mkdir -p /root/ComfyUI/input/computer_poster_lora_1000
然后把 1000 张图片和 1000 个同名 txt 放进去,结构仍然保持:
0001.jpg
0001.txt
0002.jpg
0002.txt
...
1000.jpg
1000.txt
每个 txt 仍然建议保留同一个触发词:
fpoly_computer_poster_style
例如:
fpoly_computer_poster_style, modern laptop e-commerce promotional poster, product centered, premium technology background, dramatic commercial lighting, clean advertising layout
2. 检查数据数量
上传完成后,先检查图片和 txt 数量:
cd /root/ComfyUI/input/computer_poster_lora_1000
echo "图片数量:"
ls *.jpg *.png *.jpeg 2>/dev/null | wc -l
echo "txt数量:"
ls *.txt 2>/dev/null | wc -l
理想结果:
图片数量:
1000
txt数量:
1000
再检查触发词:
echo "包含触发词的 txt 数量:"
grep -l "^fpoly_computer_poster_style" *.txt | wc -l
echo "没有触发词的 txt:"
grep -L "^fpoly_computer_poster_style" *.txt
理想结果是:
包含触发词的 txt 数量:
1000
没有触发词的 txt:
如果第二部分没有文件名输出,就说明触发词统一。
3. 复制一份新的训练配置
不要直接覆盖之前的 15 张图训练配置,可以复制一份新配置:
cd /root/ai-toolkit
cp config/computer_poster_lora.yaml config/computer_poster_lora_1000.yaml
然后修改配置里的名字、数据集路径和训练步数:
sed -i 's|computer_poster_lora_flux2_klein_test|computer_poster_lora_flux2_klein_1000_v1|g' config/computer_poster_lora_1000.yaml
sed -i 's|/root/ComfyUI/input/computer_poster_lora|/root/ComfyUI/input/computer_poster_lora_1000|g' config/computer_poster_lora_1000.yaml
4. 1000 张图建议训练多少步?
如果还是训练“风格类 LoRA”,1000 张数据不建议只跑 600 步。
可以先从:
steps: 3000
开始测试。
修改命令:
sed -i 's|steps: 600|steps: 3000|g' config/computer_poster_lora_1000.yaml
如果原配置里还是 steps: 20,则运行:
sed -i 's|steps: 20|steps: 3000|g' config/computer_poster_lora_1000.yaml
也可以更稳妥地手动检查:
grep -E 'name:|folder_path:|steps:|lr:|linear:|linear_alpha:|arch:|target_lin_modules:|vae_path:' config/computer_poster_lora_1000.yaml
我建议 1000 张图第一版保持这些参数不变:
linear: 16
linear_alpha: 16
lr: 8e-5
batch_size: 1
train_text_encoder: false
arch: "flux2_klein_4b"
target_lin_modules:
- "Flux2"
先不要一上来改 rank、学习率和 text encoder。数据量变大后,先验证稳定性更重要。
5. 重新训练命令
正式重新训练只需要运行:
cd /root/ai-toolkit
python run.py config/computer_poster_lora_1000.yaml
训练完成后,输出目录会变成:
/root/ai-toolkit/output/computer_poster_lora_flux2_klein_1000_v1/
最终 LoRA 大概率在:
/root/ai-toolkit/output/computer_poster_lora_flux2_klein_1000_v1/computer_poster_lora_flux2_klein_1000_v1.safetensors
6. 复制新 LoRA 到 ComfyUI
训练完成后,把新 LoRA 复制到 ComfyUI 的 loras 目录:
cp /root/ai-toolkit/output/computer_poster_lora_flux2_klein_1000_v1/computer_poster_lora_flux2_klein_1000_v1.safetensors \
/root/ComfyUI/models/loras/computer_poster_lora_flux2_klein_1000_v1.safetensors
然后刷新 ComfyUI,在 LoRA 加载器里选择:
computer_poster_lora_flux2_klein_1000_v1.safetensors
初始强度仍然建议:
0.6 - 0.8
7. 一个完整的快速重训命令合集
如果 1000 张图片和 txt 已经放好了,可以直接按下面流程执行:
cd /root/ComfyUI/input/computer_poster_lora_1000
echo "图片数量:"
ls *.jpg *.png *.jpeg 2>/dev/null | wc -l
echo "txt数量:"
ls *.txt 2>/dev/null | wc -l
echo "包含触发词的 txt 数量:"
grep -l "^fpoly_computer_poster_style" *.txt | wc -l
echo "没有触发词的 txt:"
grep -L "^fpoly_computer_poster_style" *.txt
确认无误后:
cd /root/ai-toolkit
cp config/computer_poster_lora.yaml config/computer_poster_lora_1000.yaml
sed -i 's|computer_poster_lora_flux2_klein_test|computer_poster_lora_flux2_klein_1000_v1|g' config/computer_poster_lora_1000.yaml
sed -i 's|/root/ComfyUI/input/computer_poster_lora|/root/ComfyUI/input/computer_poster_lora_1000|g' config/computer_poster_lora_1000.yaml
sed -i 's|steps: 600|steps: 3000|g' config/computer_poster_lora_1000.yaml
sed -i 's|steps: 20|steps: 3000|g' config/computer_poster_lora_1000.yaml
grep -E 'name:|folder_path:|steps:|lr:|linear:|linear_alpha:|arch:|target_lin_modules:|vae_path:' config/computer_poster_lora_1000.yaml
python run.py config/computer_poster_lora_1000.yaml
训练完成后:
cp /root/ai-toolkit/output/computer_poster_lora_flux2_klein_1000_v1/computer_poster_lora_flux2_klein_1000_v1.safetensors \
/root/ComfyUI/models/loras/computer_poster_lora_flux2_klein_1000_v1.safetensors
8. 1000 张数据时的注意事项
数据量增加后,最重要的不是盲目增加训练步数,而是保证数据质量。
我会特别注意这几点:
1. 图片风格要统一,不要混入太多无关风格
2. 每张图片都要有对应 txt
3. txt 描述要准确,不要所有图片都写完全一样
4. 触发词必须统一
5. 先跑 3000 步,不要一上来跑太久
6. 训练完成后测试 0.6、0.8、1.0 三个 LoRA 强度
如果 3000 步后风格不够明显,可以继续训练到:
5000 - 6000 steps
如果出现过拟合,比如画面总是重复同一种构图、产品形态僵硬、背景过于固定,则降低步数或使用中间 checkpoint。
9. 推荐版本命名方式
为了后续管理,建议这样命名:
computer_poster_lora_flux2_klein_v1_15imgs_600steps.safetensors
computer_poster_lora_flux2_klein_v2_1000imgs_3000steps.safetensors
computer_poster_lora_flux2_klein_v3_1000imgs_5000steps.safetensors
这样以后可以清楚知道每个 LoRA 是用多少数据、多少步训练出来的。
十三、进阶落地:当 LoRA / 模型训练成熟后,如何接入网页生图产品?
当训练流程打通以后,模型接入网页产品的核心思路并不复杂:先在 ComfyUI 中调通工作流,再导出 API 版 JSON,后端把它作为推理模板,根据前端传入的商品信息动态修改提示词、尺寸、LoRA 和其他参数,然后通过 HTTP 调用云端推理服务完成生成。
十四、LoRA 微调部分常见参数的功能汇总表
| 参数 / 文件 | 含义 | 主要功能 | 调大 / 调小的影响 |
|---|---|---|---|
computer_poster_lora_flux2_klein_v1.safetensors | LoRA 训练产物 | 保存“电脑电商海报风格”的微调权重,推理时叠加到底模上使用 | 不是参数,不能单独出图,必须配合 FLUX.2 Klein 底模 |
flux-2-klein-4b.safetensors | 训练用底模 | LoRA 微调时依附的基础生图模型 | 底模决定 LoRA 适配对象,换底模可能不兼容 |
flux-2-klein-4b-fp8.safetensors | 推理用底模 | 在 ComfyUI 文生图工作流里加载 LoRA 后实际出图 | fp8 更省显存,适合部署推理 |
vae / full_encoder_small_decoder.safetensors | VAE 模型 | 把图片压缩到 latent 潜空间,或把 latent 解码成真实图片 | VAE 不匹配可能导致训练报错、出图异常或颜色/细节不对 |
text_encoder / qwen_3_4b.safetensors | 文本编码器 | 把 prompt / caption 转换成模型能理解的语义向量 | 决定模型如何理解文字描述 |
train_text_encoder: false | 是否训练文本编码器 | 表示只训练图像生成模型相关 LoRA,不训练文字理解部分 | false 更省显存、更稳定;true 可增强特定词理解,但更耗资源 |
trigger word / fpoly_computer_poster_style | 触发词 | 训练和推理时用于唤起特定 LoRA 风格 | 推理时不写触发词,LoRA 风格可能不明显 |
caption | 图片说明文本 | 告诉模型每张训练图包含什么内容和风格 | caption 越准确,LoRA 越容易学到正确风格 |
resolution | 训练分辨率 | 控制训练图片缩放后的尺寸 | 分辨率越高,细节越好,但显存消耗越大 |
batch_size: 1 | 批大小 | 每一步训练送入模型的图片数量 | 越大越吃显存;小 batch 更容易在 24GB 显卡上跑通 |
steps | 训练步数 | 控制 LoRA 总共训练多少次迭代 | 太少学不到风格;太多可能过拟合 |
learning rate / lr: 8e-5 | 学习率 | 控制每一步权重更新幅度 | 太高容易学崩;太低学习慢、风格不明显 |
rank / linear: 16 | LoRA 秩 / 容量 | 决定 LoRA 能存储多少风格信息 | rank 越大表达能力越强,但更吃显存、更易过拟合 |
dtype: bf16 | 训练数值精度 | 用 bfloat16 降低显存占用并保持训练稳定 | 比 fp32 省显存;通常比 fp16 更稳定 |
quantize: true | 量化加载 | 用更省显存的方式加载模型 | 节省显存,但可能略微影响精度或速度 |
low_vram: true | 低显存模式 | 尽量降低训练时显存占用 | 更容易跑通训练,但训练速度可能变慢 |
lora strength | LoRA 强度 | 推理时控制 LoRA 对最终图像的影响程度 | 太低风格不明显;太高可能变形、过拟合感强 |
save_every / checkpoint 间隔 | 中间权重保存频率 | 训练过程中定期保存 LoRA 检查点 | 方便对比不同步数效果,也便于训练中断恢复 |
optimizer | 优化器 | 决定训练时如何更新 LoRA 权重 | 不同优化器影响收敛速度、稳定性和显存占用 |
dataset | 训练数据集 | LoRA 学习风格的图片和 caption 来源 | 数据质量比数量更重要;图片风格越统一,LoRA 越容易学到目标风格 |