ComfyUI 接入 wylon 生图模型
wylon 新云提供兼容 OpenAI Images 的同步生图接口。ComfyUI 可以通过支持自定义 api_base 的第三方节点调用该接口,本文以 comfyui-gpt-image 为例。
warning
需要调整第三方节点的尺寸选项
该节点最初面向 OpenAI
gpt-image-1,默认尺寸与 wylon 当前示例模型不一致。完成安装后,需要按本文修改节点源码并重启 ComfyUI。
前置准备
- 已安装并可正常启动 ComfyUI。
- 具有安装第三方自定义节点和编辑节点文件的权限。
- 已在 wylon 控制台创建 API Key。
- 已确认要使用的图片模型 ID,本文示例为
Qwen/Qwen-Image-2512。
1. 安装 comfyui-gpt-image
节点源码位于 lceric/comfyui-gpt-image。在 ComfyUI 中按以下路径安装:
- 打开 ComfyUI 菜单,进入管理扩展功能。
- 选择全部扩展,将筛选类型切换为节点包。
- 搜索
comfyui-gpt-image,安装并启用节点包。 - 安装完成后重启 ComfyUI。
info
这是第三方节点
节点并非由 wylon 官方维护。升级 ComfyUI 或节点前,建议先备份本地工作流和修改过的节点文件。
2. 确认模型参数
GET /v1/models 当前用于确认模型 ID 和可用状态,不提供完整的模型参数契约。尺寸、数量和输出格式请以对应 API 文档中的模型能力说明为准。
本文使用的 Qwen/Qwen-Image-2512 当前支持以下参数:
| 参数 | 支持值 | 说明 |
|---|---|---|
size | 1328x1328、1664x928、928x1664、1104x1472、1584x1056 | 默认使用 1664x928 |
n | 1 | 每次生成一张图片 |
output_format | png | 输出 PNG 图片 |
negative_prompt | 支持 | 描述不希望出现的内容 |
完整参数语义和最新限制见同步生图 API 文档。inference_steps 当前不是正式 OpenAPI 请求字段,请勿自行添加。
3. 修改节点的 size 选项
comfyui-gpt-image 的 size 使用固定下拉选项。编辑以下文件:
ComfyUI/custom_nodes/comfyui-gpt-image/nodes_api.py
找到 size 的 options,在保留原有选项的基础上加入 wylon 示例模型支持的尺寸:
"options": [
"auto", "1024x1024", "1024x1536", "1536x1024",
"1328x1328", "1664x928", "928x1664", "1104x1472", "1584x1056"
],
保存文件并重启 ComfyUI,使新的下拉选项生效。
update
节点更新可能覆盖本地修改
更新
comfyui-gpt-image 后,请重新检查 nodes_api.py 中的尺寸选项。
4. 配置并运行节点
在工作流中添加 Ports OpenAI GPT Image 1 节点,并按下表填写:
| 字段 | 填写内容 |
|---|---|
prompt | 期望生成的图片描述,不能留空 |
api_base | https://api.wylon.cn/v1/,必须保留末尾斜杠 |
auth_token | 你的 wylon API Key |
model | 完整模型 ID,例如 Qwen/Qwen-Image-2512 |
size | 选择目标模型支持的尺寸 |
n | 当前示例模型填写 1 |
quality、background、moderation | 保持默认值,实际支持情况由所选模型决定 |
link
api_base 必须以斜杠结尾
节点使用
urljoin 拼接请求路径。如果省略末尾斜杠,/v1 可能在拼接时被替换,最终请求会返回 404。
将节点的图像输出连接到保存图像或预览图像,然后运行工作流。
key
分享工作流前移除密钥
auth_token 可能随工作流配置一起保存。导出、上传或分享工作流前,请移除 API Key,并确认文件中没有密钥明文。
5. 可选:增强图片下载稳定性
节点收到图片 URL 后还需要发起一次下载请求。网络不稳定时,可以修改 nodes_api.py 中的 validate_and_cast_response(),为下载增加超时、完整性检查和有限重试。
先在文件顶部加入:
import time
再将原有的单次下载逻辑替换为:
last_err = None
for attempt in range(4):
try:
with requests.get(image_url, stream=True, timeout=(10, 60)) as response:
if response.status_code != 200:
raise Exception("HTTP %s" % response.status_code)
buffer = io.BytesIO()
for chunk in response.iter_content(65536):
if chunk:
buffer.write(chunk)
expected = response.headers.get("Content-Length")
if expected and buffer.tell() < int(expected):
raise Exception("Truncated: %d/%s" % (buffer.tell(), expected))
buffer.seek(0)
img = Image.open(buffer)
img.load()
break
except Exception as error:
last_err = error
time.sleep(2 * (attempt + 1))
else:
raise Exception("Failed to download the image: %s" % last_err)
这段修改只重试结果下载,不会重新发送图片生成请求。生成请求已被受理后,不要因下载失败直接重复运行整个工作流,以免创建新的计费请求。