GPT-Image-2 老是生成失败 / 超时?5 个真根因和能直接抄走的修复代码

GPT-Image-2 老是生成失败 / 超时?5 个真根因和能直接抄走的修复代码

TL;DR — GPT-Image-2 本身就慢,高质量 1024px 调用真实耗时 145-280 秒。大部分”生成失败”根本不是模型挂了,是你链路上某一层(CDN / 反代 / SDK)先于 OpenAI 把连接掐了。剩下四类根因:双层 moderation、第三方客户端参数不兼容、3 并发以上的限流、卡在 OpenAI 组织验证。每一个都有一两行能直接抄的修复代码。

30 秒对症

你看到的现象八成是这个根因跳到
504、连接被掐、卡 60s / 180s超时链路1
moderation_blockedYour request was rejected双层内容过滤2
Unknown parameterInvalid request,但 curl 直调没事客户端参数不兼容3
429 Too Many Requests,2 并发 OK,3-5 并发开始挂限流4
Your organization must be verifiedOpenAI 组织验证墙5
我就想要张图,不想写代码用网页版非开发者出口

1. 超时(这个最大头)

OpenAI 开发者论坛上贴出来的”GPT-Image-2 挂了”,大概三分之二是这个。不是 bug,是你的网关比 OpenAI 先放弃。

实测耗时(直接调 gpt-image-2):

  • 最小请求,1024×1024 medium,无参考图:约 80 秒
  • 1024×1024 high,无参考图:中位 195 秒,p95 接近 280 秒
  • 1536×1024 high + input_fidelity="high" + 小参考图:约 130 秒(反而更快,模型早期就锁定方向)
  • 1024×1024 medium + 两张 JPG 参考图:约 44 秒

然后看一下从你代码到 OpenAI 的典型超时链:

你的代码              ── OpenAI Python SDK 默认 600s

你的反代 / 网关        ── NGINX 默认 60s,Azure SDK 默认 180s,Express 120s

你的 CDN 边缘          ── Cloudflare Free 100s,Vercel Hobby 60s

OpenAI 上游            ── 195 秒后返回

谁最低谁说了算。Vercel Hobby 跑 GPT-Image-2 高质量 = 必坏,60 秒后用户看到 504,但 OpenAI 还在生成一张永远没人会收到的图。

修复优先级

(a) 开 streaming + partial_images。 单条修复收益最大,但绝大多数代码没开:

stream = client.images.generate(
    model="openai/gpt-image-2",
    prompt="深夜两点的拉面店,霓虹灯在湿漉漉的路面上反光",
    size="1024x1024",
    stream=True,
    partial_images=2,
)
for event in stream:
    if event.type == "image_generation.partial_image":
        push_to_client(event.b64_json, index=event.partial_image_index)
    elif event.type == "image_generation.completed":
        final = event.b64_json

首字节耗时从 195 秒压到 5-15 秒。用户能看到进度,网关也能持续看到响应,60 秒切断这条线就不会触发。代价是每张 partial 多 100 image output tokens,开 2 张够用。

(b) 不能 stream 就走异步。 立即返回 task ID,后台 worker 慢慢算,完了用 webhook 推给前端或者前端轮询。前端隔着 100 秒硬切的 CDN 时这是唯一可行的模式——而且客户端断了不浪费这次生成,worker 照算完存起来。

(c) 把 quality 降下来。 很多 prompt 根本不需要 quality="high"。换成 medium 直接省 60-120 秒。需要延迟低的话输出 JPEG,比 PNG 编码序列化快。

绝对不要做的: 一超时就立刻原 prompt 重试。OpenAI 还在算!你这一下钱算两次,紧接着自己把自己打成 429。

2. moderation_blocked

第二大根因。OpenAI 跑两遍安全过滤——进去时扫 prompt 和参考图,出来时再扫生成结果。文案不一样:

  • Your request was rejected by the safety system → 输入过滤抓的。改 prompt 用词。
  • Generated image was filtered → 输出过滤抓的。prompt 看着干净,但生成出来的图过滤器不喜欢。改整个场景,不是改几个词。

同一个 prompt 重试完全没用。 过滤器是确定性的,输入一样会被同样地拦,连续重试只会把请求烧光。

输出过滤特别警惕的内容(哪怕 prompt 写得很婉转):

  • 任何可能被读成未成年的形象,包括卡通化的
  • 真实公众人物(政客、明星、运动员)
  • 知名 IP 角色(迪士尼、任天堂、漫威)
  • 真实的医疗、手术、伤害场景
  • 像证件、真实货币、注册商标 logo 的东西

务实的修法是在你这一侧加一层 prompt 预校验——简单正则扫一遍明星名、品牌名、高危词就能拦住大多数。免得在 OpenAI 那边烧 200 秒最后被拒。

3. 第三方客户端参数不兼容

如果你是通过 Cherry Studio 之类的桌面客户端调 GPT-Image-2,那大概率是这个问题。chat-completions 和 image-generations 两个接口的参数结构压根不一样,但客户端按 chat 的样子拼参数发过来,图像接口直接拒。

当前已知的参数坑:

  • response_format —— gpt-image-2 不接受,必须去掉
  • messages: [...] 数组发给 /v1/images/generations —— 端点都用错了
  • n>1 —— 能用,但每张独立计入限流,并发预算要按张算

最干净的最小请求:

curl https://api.ofox.ai/v1/images/generations \
  -H "Authorization: Bearer $OFOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-image-2",
    "prompt": "深夜两点的拉面店,霓虹灯在湿漉漉的路面上反光",
    "size": "1024x1024"
  }'

客户端报错但 curl 直调没事,那就是客户端多发了参数。大多数客户端的”高级参数”面板里能关 response_format,关掉就好。

4. 限流

图像的限流不等于文字的限流。同一把 Key,文字模型 50 RPM 平稳,图像并发上 10 立刻 429。

实测的并发预算:

  • 3 并发 + 每批之间 2 秒间隔:稳
  • 5 并发:高峰偶尔 429
  • 10 并发:基本必挨打

call site 加 semaphore 是最便宜的修法:

import asyncio

sem = asyncio.Semaphore(3)

async def generate(prompt: str):
    async with sem:
        result = await client.images.generate(
            model="openai/gpt-image-2",
            prompt=prompt,
            size="1024x1024",
        )
        await asyncio.sleep(2)
        return result

配合指数退避,看 429 响应里的 Retry-After 头决定下次重试时间。注意:超时不要重试。 见第 1 节。

5. 组织验证卡住

OpenAI 把 GPT-Image-2 锁在组织验证后面,走 Persona 做身份核验。常见卡死姿势:

  • 国家不在白名单(白名单 OpenAI 没公开)
  • 90 天内已经成功验证过一次,被锁不能重验
  • Persona 链接 session 过期了——必须从 OpenAI 控制台重开,不要点 Persona 那封邮件里的链接
  • 验证通过了但模型权限要 6-24 小时才同步过来

如果你卡在”Your organization must be verified”又不想等,通过已经验证过的聚合方调用 GPT-Image-2 能完全跳过这步。下一节有一行代码的 SDK 切换示例。

选对工具:你在搭什么决定走哪条路

GPT-Image-2 的失败姿势大多发生在最糟糕的请求形态——你的笔记本直连 OpenAI 美东边缘、用默认超时、走一条不稳的网络。两条更干净的路,按你在干的事选:

写代码、要集成进系统 → 走 Ofox 的 OpenAI 兼容端点

from openai import OpenAI

client = OpenAI(
    api_key="ofox-...",
    base_url="https://api.ofox.ai/v1",
)

stream = client.images.generate(
    model="openai/gpt-image-2",
    prompt="...",
    size="1024x1024",
    stream=True,
    partial_images=2,
)

每次调用大头的耗时都在 OpenAI 服务端的生成上,这部分谁也快不了。能变的是你的客户端到 OpenAI 边缘之间的网络。亚太直连 OpenAI 美东节点本身就是几百毫秒的延迟加上偶发丢包和 TLS 握手重试——文字调用快进快出无所谓,但是 100-200 秒的流式连接上,任何一次抖动都直接干掉整次生成(也就是第 1 节里那种 504)。Ofox 给亚太流量保留了一条优化好的稳定路径,整段 streaming 时间窗里字节流能正常流到客户端。顺带的好处:第 5 节那道组织验证墙在 Ofox 这边已经过了,同样的模型 ID 不需要再走一遍 Persona。

OpenAI SDK 不变,模型 ID openai/gpt-image-2 不变,streaming / partial_images / 参考图 / input_fidelity 全支持。只改一行 base_url。

临时用一下,不是要集成 → 用 gptimage2.plus

gptimage2.plus 是 GPT-Image-2 的网页版包装。超时和重试它在后端帮你顶住,你输入 prompt 直接拿 2K 图。注册送 5 积分,不登录每天免费 1 次,优惠码 LAUNCH50 当前可用,首月 5 折。

适合你如果:

  • 不写代码、就想要几张图
  • ChatGPT 网页今天又抽风生不出来
  • 想用预设场景(产品图、证件照、老照片修复)而不是自己琢磨 prompt

如果是要在管线里批量、或者集成进自家产品里——上 API。

走 API 的话,最短的”不再失败”路径

  1. 把 streaming 打开,partial_images=2。性价比最高的一招。
  2. semaphore 限制并发到 3,退避要看 Retry-After
  3. prompt 预校验,提前拦掉明显会被 moderation 拒的内容。
  4. 超时不要重试,让原请求跑完,或者把整个调用改成异步任务模式。
  5. 在国内 / 日韩 / 东南亚的话,或者卡在组织验证的话,换成亚太稳定的聚合方 base_url。

模型本身是当前 Arena 文生图榜的第一名,失败的几种姿势都是有边界的,每一种都有一两行代码能改掉。