生成一张美女在水下潜水的图七步流程,环环相扣
image-gen 的核心是一条七步流程,把一句自然语言变成高质量图片:
自然语言 → 意图澄清(Step 0) → 意图识别(LLM) → 知识图谱查询 → Prompt 组装 → ComfyUI 出图 → 评估迭代 → 经验积累
每一步都有对应模块。下面一个一个来聊。
核心引擎:零外部依赖
这是 image-gen 最"轴"的一个决定:整个引擎只用 Python 标准库。
不依赖 torch、transformers、requests,甚至连 PIL 都是可选的。所有 HTTP 请求用 urllib,数据序列化用 json,路径处理用 pathlib,字符串匹配用 re,全是 Python 自带的。
为什么不调云端出图 API?因为 image-gen 走的是本地出图路线:模型跑在你自己的 GPU 上,图片不经过任何第三方服务器,数据完全留在本地。好处很直接,不限次数、不计费、不出网、隐私安全,而且可以随时切换模型和工作流,不受平台锁定。
# comfyui.py — 完全用 urllib 实现 ComfyUI 客户端import urllib.requestimport jsondef check_connection(cfg): try: url = f"http://{cfg['comfyui_host']}:{cfg['comfyui_port']}/system_stats" with urllib.request.urlopen(url, timeout=5) as resp: return resp.status == 200 except Exception: return False
clone 下来就能跑,不用 pip install 任何东西(ComfyUI 本身当然要装)。对于不想折腾 Python 环境的人来说,这是真正的零负担。
Step 0:先搞清楚你要什么
这是整个流程的第一步,也是最容易被忽略的一步。
大多数用户说话是模糊的。"画个猫",什么风格?什么光影?什么构图?什么色调?这些维度如果都不指定,后面的知识图谱再聪明,也只能猜。
Step 0 的职责就是在流程启动之前,先把用户没说清楚的东西问明白。
具体怎么做的?系统会对照八个关键维度,风格、氛围、光照、构图、色调、背景、用途、宽高比,逐一检查用户描述里有没有覆盖。如果用户的话已经足够详细(比如"写实摄影风格,金色黄昏光影,特写构图,暖色调的猫"),会直接跳过这步。
如果描述比较简短,系统就会挑出影响最大的 2-4 个维度,一次只问一个问题,给 3-5 个具体选项:
你希望什么风格?(写实摄影 / 油画 / 水彩 / 数字插画 / 其他)→ 水彩光影偏好?(自然光 / 金色黄昏 / 棚拍灯光 / 阴天柔光 / 其他)→ 自然光构图呢?(特写 / 半身 / 全身 / 场景全景 / 其他)→ 特写
问完之后,把答案合并进原始描述,形成增强版 prompt:
原始:一只猫增强:一只猫,水彩风格,自然光,特写构图
这一步看着简单,效果很实际,它让后面所有环节都有了更明确的输入,而不是靠猜。
Step 1:用大模型理解你的话
意图澄清之后,就进入实体识别环节。image-gen 接了一个 OpenAI 兼容的 LLM 来做意图解析。它会读取知识图谱里所有已知实体,带着这些背景知识去理解用户的话,然后输出结构化的标签列表。
# intent.py — LLM 驱动的意图识别def extract_seed_entities_llm(user_intent, cfg): catalog_preview = _build_catalog_preview() # 带上已知实体作为参考 system_prompt = _SYSTEM_PROMPT.format(catalog=catalog_preview) response = _call_chat_api(full_prompt, cfg) # 解析 JSON 数组 → ["subject:cat", "style:watercolor"]
举个例子,用户说"给我画一只趴在窗台上的慵懒猫咪,水彩风格,暖色调",系统能拆解出:
- •
style:watercolor — 水彩风格
关键是,即使遇到知识图谱里没有的词,比如用户说"赛博朋克猫",模型也不会忽略它,照样会构造一个 subject:cyberpunk_cat 标签传下去,后续由知识图谱自动接纳。
万一大模型调不通,还有关键词兜底,不会彻底挂掉。
Step 2:知识图谱,用系统的"记忆"生成图片骨干
PromptKG 是整条流程里最有"灵魂"的部分。它不是一个静态词典,而是一个会生长的知识图谱,记录了三个维度的信息:
实体字典:覆盖 12 个分类(主体、风格、情绪、构图、光照、背景、色调、颜色、类型、技法、纹理、主题),每个实体都有中英文双语标注和出现频次统计。
共现关系:记录哪些实体经常一起出现。"水彩"和"温暖"共现了 52 次,"水彩"和"冷色调"只有 3 次,下次你选了水彩,系统就知道优先推荐温暖,而不是冷色调。
模板索引:保存历史上成功的实体组合,可以直接复用。
你输入"一只猫",KG 会一口气补全你没说到的东西:
用户不需要想得面面俱到,系统帮你填上那些你"应该要但没想到"的细节。
而且,知识图谱还支持自动扩展。当 LLM 识别出一个新实体(比如 subject:cyberpunk_cat),KG 会自动把它加进字典,并且在后台异步调用 LLM 把中文名翻译好。下次再出现类似请求,这个新实体就正式成为系统的一部分了。
Step 3:14 维结构化 Prompt
这个阶段,image-gen 不写"一大坨"文字 prompt,而是用 14 维的 JSON 结构来控制画面的每个方面:
| | |
|---|
| | |
| | |
| | |
| | |
| | "natural light from window" |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
结构化的好处是每个维度可以独立调整。你只想把光照从"日落"换成"日出"?改 lighting 字段就行,主体、风格、色调都不用动。
特别值得一提的两个设计:
中文排版 DSL:控制图片中文字的大小、颜色、渐变、排版方向,适合做海报、封面。
对比构图:用户说"猫 vs 狗",系统会自动识别对比意图,构造左右分屏的构图 prompt。
prompt_assembly 模块负责把这些维度组装起来:它会先填 KG 已知的实体,再补上 LLM 发现但 KG 不认识的新实体,最后用推荐填满剩余维度。一条全自动的 prompt 装配线。
Step 4:ComfyUI 本地出图
Prompt 准备好了,接下来就是让 ComfyUI 在本地机器上生成图片。
ComfyUI 是跑在你自己电脑上的 Stable Diffusion 工作流引擎,图片生成完全在本地 GPU 完成,不调用任何云服务。系统先检查本地 ComfyUI 是否在跑(默认监听 127.0.0.1:8188),连接正常后,把组装好的正向和负向 prompt 注入到工作流 JSON 里,提交给本地 ComfyUI,轮询等待图片生成完毕,最后保存到本地输出目录。
工作流注入逻辑相当健壮:自动找到 CLIPTextEncode 节点,第一个注入正向 prompt,第二个注入负向 prompt;找不到第二个就顺着 KSampler 的 negative 输入追溯;KSampler 的 seed 每次也会随机化,避免生成完全相同的图。
系统默认加载 ernie_image_gguf.json 工作流,也支持自定义,把从 ComfyUI 界面导出的 API 格式 JSON 放到 workflows/ 目录下,配置里改一行就能切换。
Step 5:评估迭代,让模型给自己打分
这是 image-gen 的核心亮点。图片生成之后,不是直接丢给用户,而是先过一道评估关。
系统用视觉模型从六个维度给图片打分:
六个分数加权平均,低于阈值(默认 8 分)就触发迭代:
- 1. 视觉模型分析图片的不足(比如"猫的姿势不够自然,水彩笔触感不足")
最多迭代 3 轮,直到达标为止。
--- Iteration 1/3 --- Score: 6.5/8 Weaknesses: 猫的姿势不够自然,水彩笔触感不足 Refining prompt...--- Iteration 2/3 --- Score: 8.2/8 Passed threshold! Stopping.
迭代之间有一个容易忽略但很重要的细节:显存管理。ComfyUI 连续出图几次后,GPU 显存累积状态会导致浮点精度漂移,图片质量莫名下降,多余肢体、细节模糊、画面扭曲都可能出现。image-gen 在每轮迭代结束时主动调用 ComfyUI 的 /free 接口释放显存,可选是否完全卸载模型。这个小细节,实际跑起来效果很明显,第 1 张和第 5 张图的质量几乎没有差距。
Step 6:经验回写,越用越聪明
评分达标的生成结果,系统会自动回写到知识图谱:
- • 注册新实体:LLM 识别出的未知实体,写入字典
- • 异步翻译:后台启动进程,把新实体的中文名翻译好
写入是原子操作,先写临时文件,再 os.replace 替换,避免并发读写出问题。
def update_kg(used_entities, positive_prompt, score, threshold=8): # 1. 更新共现 for e1, e2 in combinations(used_entities, 2): graph["co_occurrence"][e1][e2] += 1 # 2. 新模板入索引 graph["prompt_index"].append(new_entry) # 3. 原子写入 _atomic_json_save(GRAPH_PATH, graph)
结果就是:你用得越多,推荐越准。第一次"赛博朋克猫"可能要迭代 3 轮才达标,成功之后共现计数上去了,下次类似的组合可能 1 轮就过。
两个 CLI,精细控制随你选
image-gen 提供两个命令行入口:
快速入口image-gen.py — 一行命令跑完全流程:
python scripts/image-gen.py "a cat on windowsill, watercolor style"
精细控制image-gen-cli.py — 十几个子命令,按需组合:
# 完整流程python scripts/image-gen-cli.py pipeline --prompt "画一只水彩猫"# 单步调试:只提取意图python scripts/image-gen-cli.py intent --text "水彩猫"# 单步评估:给已有图片打分python scripts/image-gen-cli.py evaluate --image result.png --intent "水彩猫"# 看看图片分析结果python scripts/image-gen-cli.py describe --image result.png --prompt "描述这张图"# 释放显存python scripts/image-gen-cli.py free-memory --unload
所有子命令都输出 JSON 格式,方便脚本调用或接入其他流程。
配置很简单
本地 ComfyUI 的地址和视觉模型 API,一个 config.json 搞定一切:
{ "comfyui_host": "127.0.0.1", "comfyui_port": 8188, "output_dir": "~/image-gen-output", "vision_api_url": "https://your-api/v1", "vision_model": "qwen3.6-plus", "vision_api_key": "", "max_iterations": 3, "score_threshold": 8, "default_workflow": "workflows/ernie_image_gguf"}
API 密钥推荐通过环境变量 VISION_API_KEY 设置,不要直接写在配置文件里。
视觉模型用的是 OpenAI 兼容协议,想换成其他兼容OpenAI协议的模型,只需改 vision_api_url 和 vision_model 就能切换。
这个视觉模型承担了两个重要角色:理解意图和评估质量。一个模型两份工作,整条流程的智能就靠它驱动。
总结
总得来说 image-gen 做的事情就是:
- 1. 完整流程:七步流程,从一句自然语言到一张高质量图片,中间环节全自动。Step 0 先澄清意图,后面每一步都建立在更准确的输入之上
- 2. 本地出图:模型跑在你自己的 GPU 上,图片不出网、不计费、不限次数,如果配合本地的LLM模型,隐私安全更有保障
- 3. 零依赖:核心引擎只用 Python 标准库,clone 就能跑
- 4. LLM 驱动:意图识别和图片评估都由大语言模型完成,比关键词匹配聪明得多
- 5. 知识图谱:PromptKG 基于共现统计做智能推荐,解决"用户描述太简单"的老问题
- 6. 自动迭代:六维度加权评估,不达标的图不出手,自动优化重试
- 7. 经验积累:成功组合回写 KG,系统越用越精准
- 8. 中文友好:支持中文实体识别、中英文双语标注、中文排版 DSL、汉字渲染
对了,安装文档在项目的 docs/install-guide.md 里,包括 ComfyUI 部署、GGUF 量化模型下载(8GB 显存就能跑)、配置说明、常见问题等。
项目地址:https://github.com/xsyl06/image-gen
最后,还要感谢B站UP主 小天fotos ,本项目的kg推荐模块等流程就是从他的一人公司项目获取的灵感。
这里贴上他的一人公司项目地址:https://github.com/xiaotianfotos/OPC