【免费生图】Qwen Image 3.0 Pro 接入指南:限量真相与 429 应对(2026)
Qwen Image 3.0 Pro 在 ofox 上 $0 且不按张收费,但限时又限量:连着调必 429。3 分钟接入、真实限制,以及降级要花多少钱。
阿里在 2026-07-21 发布了 Qwen Image 3.0 Pro,上架 ofox 的价格是 $0。不是「token 免费、底下藏一笔按张的钱」——ofox 上多数生图模型恰恰是那么定价的——它连按张的费用也没有。是真的零,不是那种会悄悄扣完的试用额度。
但它也不是那种你这周就该拿去做产品的免费。理由写在模型页的中文描述里,英文报道基本都略过了:本版本为限时免费体验版,目前为限量体验阶段。限时和限量是两条独立的约束,而真正会打断你一下午的是后面那条。
下面是这个免费档位给了什么、拿走了什么,以及三个会让你从 gpt-image-2 教程抄来的代码直接崩掉的接入细节。本文所有配图都是模型的真实输出,2026-07-23 生成。
接完能做什么,不能做什么
| 能做 | 通过 OpenAI 兼容端点以 $0 出图(token 和按张都是 0),文生图,尺寸任意 |
| 需要多久 | 已有 ofox key 的话大约 3 分钟 |
| 需要什么 | 一个 ofox API Key、Python 3.8+ 或 Node 18+,以及你大概率已经装了的 openai SDK |
| 不能做 | 跑批量。按公布的配额做产能规划。假设下个月还是这个价。拿到 base64。用参考图(见下文) |
什么时候该用,什么时候别用
该用的场景:
- 你在选生图模型,想先拿自己的 prompt 试试它的文字渲染,再决定钱花在哪。
- 你是偶发、交互式地出图,一小时几张,429 只是让你重试一次而不是让任务失败。
- 你需要图里有正确的中文,而现有模型总是写成鬼画符。这是 Qwen 真正拉开差距的能力,而且验证它不要钱。
别用的场景:
- 你要跑批量。限量阶段让吞吐变得不可预测,而批处理里不可预测的吞吐比明确的价格更糟。
- 你有延迟要求。这里 429 的退避是几十秒量级,不是几百毫秒。
- 你在写一个三个月内没人会去看、但必须一直能跑的东西。免费这个档位是明确写了有期限的。
可以停的地方: 如果你只是想知道文字渲染那个说法是不是真的,看完下面四张测试图就可以关掉本文了。结论是写词成立、写序列不成立,知道这一条你不用接入任何东西就已经赚了。
环境准备
- 一个 ofox API Key,去 ofox 控制台 拿。
- Python 3.8 及以上装
openai>=1.0,或者 Node 18+ 装openai。不需要阿里云账号,不需要 DashScope key,不需要单独配区域。 - 一个能写文件的地方。这个端点给你的是 URL 不是字节流,而那个链接活不了太久。
三分钟接入
第 1 步:把 SDK 指向 ofox
from openai import OpenAI
client = OpenAI(
base_url="https://api.ofox.ai/v1",
api_key="YOUR_OFOX_KEY",
)
预期结果:没有任何输出。import 失败的话跑 pip install -U openai 升级。
第 2 步:调模型
resp = client.images.generate(
model="bailian/qwen-image-3.0-pro:free",
prompt="A ceramic mug on a linen cloth, morning light, shallow depth of field",
size="1024x1024",
n=1,
)
print(resp.data[0].url)
预期结果:标准输出打印一个 https://dashscope-*.oss-accelerate.aliyuncs.com/... 的链接。
Node 版本:
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.ofox.ai/v1",
apiKey: process.env.OFOX_API_KEY,
});
const r = await client.images.generate({
model: "bailian/qwen-image-3.0-pro:free",
prompt: "A ceramic mug on a linen cloth, morning light",
size: "1024x1024",
n: 1,
});
console.log(r.data[0].url);
第 3 步:趁链接还没过期把字节抓下来
import urllib.request
urllib.request.urlretrieve(resp.data[0].url, "out.png")
预期结果:磁盘上出现 out.png,1024x1024 大约 1 到 1.5 MB。
这一步不是可有可无的收尾。把链接写进数据库之前,先读完下一节。
三个会让抄来的代码崩掉的细节
一、返回的是 URL,不是 base64
外面流传的生图教程大多是照着 gpt-image-2 写的,那个返回 b64_json。Qwen 3.0 Pro 在这个端点上返回 url,b64_json 是空的。这样写会挂:
raw = base64.b64decode(resp.data[0].b64_json) # Qwen 上直接 TypeError
如果你的代码要在多个模型之间路由,两种形态都得兼容:
item = resp.data[0]
raw = (base64.b64decode(item.b64_json) if item.b64_json
else urllib.request.urlopen(item.url).read())
那个 URL 指向阿里的 OSS,带签名且会过期。一定要把字节落盘。存进数据库的链接,过一阵就是一张裂图。
二、免费的配额是「按时刻」而不是「按天」
官方没有公布 RPM 数值,所以我们只能测能观察到的部分。连着发请求,第二个立刻返回 429 Requests rate limit exceeded。开两个生成进程并行跑,两个都 429,而且谁都不往前走,直到杀掉其中一个。单个串行 worker、退避从 45 秒起往上加,则每个请求都跑完了。
| 调用形态 | 结果 |
|---|---|
| 连着发两个请求 | 第二个立刻 429 |
| 同一个 key 开两个进程并行 | 两个都 429,杀掉一个之前谁都不动 |
| 单 worker、退避 45s、任务间隔 20s | 全部跑完 |
| 同样形态连跑四个任务 | 四个全过,第一次清空之后没再 429 |
这种形态——只要有并发就立刻 429、严格串行就相当宽松——正是限量体验阶段从外面看到的样子。它不是故障,而且越用力重试越糟。
import time, openai
def generate(prompt, size="1024x1024", tries=6):
for i in range(tries):
try:
r = client.images.generate(
model="bailian/qwen-image-3.0-pro:free",
prompt=prompt, size=size, n=1)
return r.data[0].url
except openai.RateLimitError:
time.sleep(45 * (i + 1))
raise RuntimeError("配额始终没放开")
# 走 OpenAI SDK 时,429 抛的是 openai.RateLimitError。
# 只有直接打 HTTP 端点,接到的才是 urllib 的 HTTPError(429)。
三、尺寸没有枚举限制
不少生图端点只认一份固定的尺寸清单,别的一律拒绝——所以那么多生图代码里都带着一张「宽屏」映射到某个厂商钦定字符串的对照表。这个端点看起来不是那样。
| 传入尺寸 | 返回 | 用途 |
|---|---|---|
1024x1024 | 原样 | 默认方图 |
1024x1536 | 原样 | 竖版,海报和规格卡 |
1664x928 | 原样 | 宽屏,接近 16:9 |
我们传什么就返回什么分辨率。如果你在生成固定比例的博客头图或社交卡片,可以直接要最终尺寸,不用先出方图再裁——少一个把构图切掉脑袋的环节。
需要注意这是实测行为不是文档承诺。拿回来的图还是要校验尺寸,尤其当它会被塞进一个比例不对就会崩的版式里。
参考图:我们没能让它生效
模型页把参考图输入和文生图并列写着。我们没能在这个端点上让它工作,而且失败的方式值得记一笔,因为它是无声的。
拿 Test 1 那张咖啡机海报做源图,prompt 要求改成墨线手绘风但保留版式和规格数值,试了三种写法:
| 尝试 | 结果 |
|---|---|
images.generate(..., image="data:image/png;base64,...") | HTTP 200,出图了,参考图被完全忽略 |
images.generate(..., image_url="data:image/png;base64,...") | HTTP 200,出图了,但没复现参考图内容 |
POST /images/edits | HTTP 400 You must provide a model parameter,而 body 里有 model |
第一种最清楚:给它一张写实风的咖啡机海报,返回的是一张植物精华广告。风格对,主体完全不相干,参考图里什么都没留下。
第二种乍看更接近,细看更说明问题:源海报写的是锅炉 1.6 L、重量 12.4 kg,新图写成了 2.0 L 和 28 kg,四行表格变成八格网格,实拍产品变成带引线标注的剖面图,保修那行消失了。唯一对上的 9 bar 是所有意式咖啡机的标准压力,说明不了任何问题。
换句话说,模型是照着 prompt 文字重新画了一张,压根没读参考图。第三种比前两种更麻烦:一个抱怨缺少 model 参数、而该参数明明存在的 400,够你去查自己的序列化查二十分钟。
能确定地说的是:这个模型文档上有参考图能力,而我们没有找到能在 ofox 的 OpenAI 兼容生图端点上把它送进去的参数写法。也许阿里原生的 DashScope API 可以,也许正确的参数名是我们没试到的。但它不会大声报错,所以你要真拿它做东西,请核对输出确实反映了输入,别看到 200 就当成功。
文字渲染那个说法立得住吗
阿里给这一代的卖点是排版:小字保持可读、长 prompt 保持连贯、多种文字同框。这些都可验证,所以我们验了。下面每张图都是给定尺寸下的原始输出,没有修图,也没有在多次尝试里挑好的。
测试一:规格表里的小字。 prompt 要求四行带确切数值的表格,外加底部一行细字流水号。

每个数值都落对了:Pressure 9 bar、Boiler 1.6 L、Weight 12.4 kg、Warranty 24 months。底部那行是 Serial AT-2026-0731 / Made in Suzhou,连斜杠和带连字符的流水号都准确。在 1024x1536 下这行细字大约相当于 8pt。没有掉字、没有生造字符、小字号上也没有糊成一团——而生图模型通常正是在这里露馅的。
测试二:两种文字同框。 同一块指示牌上英文和中文各占一行,共用一组数字。

两种文字都正确。开发者专场 和 注册签到 是结构完整的汉字,不是多数生图模型产出的那种「汉字形状的噪声」。拉丁字和中文的字重一致,两行的 09:00 也对得上。
试过用西方生图模型做中文海报的人会明白这一张的分量。这是全文最有意思的结果,而且你自己零成本就能复现。
测试三:多标注的技术示意图。 这类通常是要崩的。prompt 点名了五个必须出现的字串(CLIENT、GATEWAY、MODEL、RESPONSE,以及 auth / route / inference 三项图例),每个方块下面的说明文字则没有指定内容。

五个指定字串全部渲染正确、位置也对。更值得注意的是它自己补的部分:加了标题,把箭头编成 1. Request / 2. Forward / 3. Output,说明文字写得技术上通顺而不是凑数的占位文(网关下面写的是「Validates authentication / Routes to endpoint」)。全图拼写没有出错。
这让它有资格用来出文档示意图的初稿。但不等于可靠——它补的那些说明是它对你架构的猜测,猜错的时候它一样写得理直气壮。
测试四:它在哪儿真的崩。 我们要一张代码编辑器截图,带文件树、语法高亮的 Python,以及可见的 1 到 14 行号。

外壳几乎完美。文件名正确且图标匹配,状态栏一字不差地写着 UTF-8 CRLF Python 3.12 Ln 8, Col 22 Spaces: 4,菜单栏合理,语法高亮给关键字、字符串和函数名分配的颜色也说得通。
然后看行号那一列:1, 3, 3, 4, 6, 7, 9, 8, 0, 8, 11, 11, 12, 13, 14。没有 2、没有 5、没有 10,好几个重复,还冒出一个 0。再看代码最后一行:if __name__ = "__main__":,Python 需要两个等号的地方只有一个。
这就是这个模型能力的诚实边界。词——包括小字和中文——它写得对;序列它写不对。 行号那一列是对单调计数最纯粹的考验,而它交出的东西远看像在计数,凑近就散了。那个该是 == 的 = 是同一个毛病的另一种表现。
实用结论:凡是读者把文字当语言读的地方都可以用;凡是读者会把内容当字面真值的代码截图,或者坐标轴标签必须是真实序列的图表,都不要用。这不是换个 prompt 能修好的问题,这就是模型当前不擅长的事。
接入常见报错
| 报错 | 含义 | 解决 |
|---|---|---|
429 Requests rate limit exceeded | 免费档位的限量,不是故障 | 串行化请求,退避 45 秒起往上加。不要并行 |
b64_json 上 TypeError: expected str, got None | 你抄了 gpt-image-2 的代码 | 读 data[0].url 再去抓 |
| 图片链接过一阵变 403 | OSS 签名链接过期 | 生成时立刻下载,保存字节而不是链接 |
model_not_found | 少了 :free 后缀 | 完整 ID 是 bailian/qwen-image-3.0-pro:free,冒号也要 |
data 数组为空 | prompt 命中内容过滤 | 换个说法。这个端点不总是给出明确的拒绝原因 |
团队协作时的配置
限量这件事对团队的影响比对个人大得多:你的同事会互相限流。两个人同时对着同一个免费模型调 prompt,正是那个稳定触发 429 的并发场景。
三种处理方式,按投入从小到大:
- 一个 key,一条队列。 把出图放到单 worker 的任务队列后面,而不是让每个人的电脑直接打端点。这是真正能解决问题的那一步。
- 按模型分流,而不是按 key 分流。 Qwen 是 ofox 上唯一免费的生图模型,所以这条实际意思是把批量工作挪到付费模型上,把 Qwen 留给它真正占优的排版场景。Seedream 5.0 Lite 每张 $0.035,是放批量的最便宜去处。
- 自动降级。 捕获 429 之后重试到有真实吞吐的付费模型。每张 $0.035 到 $0.05,几张图被放行的成本远低于一个工程师干等着。
因为这些都在同一个 base URL、同一个 key 后面,第三条只是换一个 model 字符串,不是再做一次接入。
CHAIN = [
"bailian/qwen-image-3.0-pro:free", # $0,但限量
"volcengine/doubao-seedream-5.0-lite", # 每张 $0.035
"openai/gpt-image-2", # 输入 $4/M,输出 $24/M
]
def generate_with_failover(prompt, size="1024x1024"):
for model in CHAIN:
try:
r = client.images.generate(
model=model, prompt=prompt, size=size, n=1)
return model, r.data[0]
except Exception as e:
if "429" not in str(e):
raise
raise RuntimeError("所有 provider 都被限流了")
把模型名跟图一起返回。等哪天你发现某一批图的风格跟另一批不一样,知道每张究竟是谁出的,能省你一个小时。
为免费窗口关闭那天做准备
「限时」加上没有截止日,本质是个排期问题伪装成了定价说明。真正的故障不是你收到一张账单,而是某天早上 model ID 不再解析,或者解析到了一个付费变体,然后你接进去的那个东西不工作了,而团队里没人记得为什么。
三条便宜的预防措施,每条都不比接入本身更花时间:
- 把 model ID 放进配置。 一个环境变量里的字符串,而不是散在六个调用点。对多数团队来说这一条就是全部缓解措施。
- 记录每张图是哪个模型出的。 输出质量变化时,你需要先知道是不是模型在你脚下换了,再去怀疑自己的 prompt。
- 提前知道降级目标的价格。 下面那张表就是为了让你在 429 变成常态之前,决定已经做好了。
如果你会归档生成的图,这一条比听起来更重要。签名 OSS 链接按它自己的节奏过期,所以一张你免费生成、但只存了链接没存文件的图,无论定价怎么变都是一张迟早会裂的图。
Qwen 被限流时的替代选择
| 模型 | ofox 价格 | 说明 |
|---|---|---|
bailian/qwen-image-3.0-pro:free | $0,按张也不收 | 唯一真免费的。限量,且有时限 |
volcengine/doubao-seedream-5.0-lite | 每张 $0.035 | 按张计费里最便宜的。按张不按 token |
volcengine/doubao-seedream-4.5 | 每张 $0.04 | 同系列上一代 |
volcengine/doubao-seedream-5.0-pro | 每张 $0.05 | Seedream 最高档。想继续用国产模型的话是自然的第一跳 |
google/gemini-3.1-flash-lite-image | 输入 $0.25/M,输出 $1.50/M | 按 token 计费,吞吐可预期 |
google/gemini-3.1-flash-image | 输入 $0.50/M,输出 $3.00/M | 按 token 计费,更大一档 |
openai/gpt-image-2 | 输入 $4/M,输出 $24/M(缓存 $1/M) | 最可预期的一个 |
这张表要仔细读,因为定价页很容易看错,我们自己第一遍就看错了。生图模型的计费方式并不统一。 Seedream 那几行 token 两列都写着 $0/M,看起来是免费,其实不是:它们按生成的图张数计费,Per Image 那一行才是会进你账单的数字。生图模型上的 $0/$0 token 行什么都说明不了。
于是 Qwen Image 3.0 Pro 成了 ofox 上目前唯一完全不收费的生图模型,无论按 token 还是按张。这也戳破了这个故事里让人舒服的那个版本:没有免费的降级选项。 被限量卡住的时候,替代方案是要花钱的,便宜的那头每张 $0.035 到 $0.05。数目不大,但不是零,而一条按「免费」设计的流水线需要知道自己到底属于哪种。
Seedream 依然是最自然的第一跳。同一个 base URL、同一个 key、换一个字符串。但它们是另一个系列,我们也没有拿同样的四组排版测试去测过它们,所以把它们当成 Qwen 文字渲染能力的等价替代是一种假设,不是一项结论。
价格是 2026-07-23 逐个抓 ofox 模型页确认的。核对时踩到一点:gpt-image-2 在 /v1/models 接口上对我们这把 key 返回的是 $5/M 和 $30/M,正是模型页上被划掉的那列牌价,旁边 ofox 的折后价是 $4/M 和 $24/M。我们只在一把 key 上测过,所以把它当成「该读页面而不是读接口」的理由,而不是一条有文档依据的规则。
想看付费档位的深入对比,我们单独写过 Seedream 4.5 图像 API 教程 和 Flux 2 Max API 指南,另外 GPT-Image-2 生成失败排查 讲了生成变慢和 504 通常意味着什么。
我们没能验证的部分
把没验到的地方讲清楚,因为这次发布的报道里很多都没讲:
- 没有 benchmark。 阿里这一代没有放技术报告,也没有公开评测数字。你看到的任何 Qwen Image 3.0 Pro 的排名都是某个人的主观感受,包括我们的。
- 没有开源权重。 早几代 Qwen-Image 有可下载的权重,这一代没有,所以自托管不是绕开限量的出口。
- 没有公布速率限制。 上面那些数字是一把 key 在一个下午的观察结果,不是文档化的限制。你的可能不同,阿里也可以随时改而不通知任何人。
- 免费定价没有截止日。「限时」而不给日期,就是全部的披露内容。
- 长 prompt 的说法没测。 阿里宣传的 prompt 处理能力在数千 token 量级。我们的测试 prompt 每条只有几十个词,这说明不了一段 4,000 token 的场景描述能不能保持连贯。限量让一次性做完压力测试不现实,我们不打算假装做过。
- 样本量只有四。 四个 prompt、每个一次、不重试也不挑选。足以证明小字渲染可行、数字序列会崩,但不足以给任何一项标上百分比。
之所以要写清楚:这次发布的多数报道把阿里的能力清单当成了测量结果来复述。能力清单是一项声明。上面四张图是四个数据点,比声明多,比 benchmark 少得多。


