了解如何使用 OpenAI 的批处理 API 成组发送异步请求,将成本降低 50%,使用独立且显著更高的速率限额,并在明确的 24 小时时限内获得结果。这项服务非常适合处理不需要即时响应的作业。您也可以在此直接查看 API 参考。
概览
虽然 OpenAI 平台的某些使用场景要求您发送同步请求,但在许多情况下,请求并不需要即时响应,或者速率限制使您无法快速执行大量查询。批处理作业通常适用于以下场景:
- 运行评估
- 对大型数据集进行分类
- 为内容库生成嵌入向量
- 将大型离线视频渲染作业加入队列
批处理 API 提供了一组简单易用的端点,您可以将一组请求汇集到单个文件中,启动批处理作业来执行这些请求,在请求执行期间查询批次状态,并在批次完成后获取汇总结果。
与直接使用标准端点相比,批处理 API 具有以下优势:
- 成本更低: 与同步 API 相比,成本降低 50%
- 速率限制更高: 与同步 API 相比,可用限额大幅增加
- 完成速度快: 每个批次均在 24 小时内完成,通常用时更短
入门
1. 准备批处理文件
批处理首先需要一个 .jsonl 文件,其中每一行都包含一个 API 请求的详细信息。目前可用的端点包括:
/v1/responses(Responses API)/v1/chat/completions(Chat Completions API)/v1/embeddings(嵌入向量 API)/v1/completions(Completions API)/v1/moderations(内容审核指南)/v1/images/generations(图像 API)/v1/images/edits(图像 API)/v1/videos(视频生成指南)
对于给定的输入文件,每一行的 body 字段中的参数都与对应端点的参数相同。每个请求都必须包含唯一的 custom_id 值,您可以在处理完成后用它来关联结果。下面是一个包含 2 个请求的输入文件示例。请注意,每个输入文件只能包含针对同一个模型的请求。
使用批处理生成视频时:
- 批处理目前仅支持
POST /v1/videos。 - 视频批处理请求必须使用 JSON,不能使用 multipart 格式。
- 请提前上传素材,并在请求体中传入受支持的素材引用,不要使用 multipart 上传。
- 在批处理中进行图像引导的生成时,请使用
input_reference。在 JSON 请求中,将input_reference作为包含file_id或image_url的对象传入。 - 批处理不支持通过 multipart 上传
input_reference,包括视频参考输入。 - 批处理生成的视频在批次完成后最多可供下载
24小时。
请求 /v1/moderations 时,请在每个请求体中包含 input 字段。使用 omni-moderation-latest 时,批处理接受纯文本输入,以及包含文本或图像输入的内容数组。批处理工作进程会拒绝设置了 stream=true 的请求,这与同步内容审核端点的行为一致。
{"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo-0125", "messages": [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Hello world!"}],"max_tokens": 1000}}
{"custom_id": "request-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo-0125", "messages": [{"role": "system", "content": "You are an unhelpful assistant."},{"role": "user", "content": "Hello world!"}],"max_tokens": 1000}}
内容审核输入示例
纯文本请求:
{
"custom_id": "moderation-text-1",
"method": "POST",
"url": "/v1/moderations",
"body": {
"model": "omni-moderation-latest",
"input": "This is a harmless test sentence."
}
}
包含文本和图像输入的请求:
{
"custom_id": "moderation-mm-1",
"method": "POST",
"url": "/v1/moderations",
"body": {
"model": "omni-moderation-latest",
"input": [
{
"type": "text",
"text": "Describe this image"
},
{
"type": "image_url",
"image_url": {
"url": "https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg"
}
}
]
}
}
建议使用 image_url 引用远程素材,而不是使用 base64 数据块,
使您的 .jsonl 文件大小保持在远低于批处理 200 MB 上传限制的水平,
对于多模态内容审核请求尤其如此。
2. 上传批处理输入文件
与我们的微调 API 类似,您必须先上传输入文件,才能在启动批处理时正确引用它。请使用文件 API 上传您的 .jsonl 文件。
import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const file = await openai.files.create({
file: fs.createReadStream("fixtures/batchinput.jsonl"),
purpose: "batch",
});
console.log(file);3. 创建批次
成功上传输入文件后,您可以使用输入文件对应的 File 对象的 ID 创建批次。在本例中,假设文件 ID 为 file-abc123。目前,完成时限只能设置为 24h。您还可以通过可选的 metadata 参数提供自定义元数据。
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.create({
input_file_id: "file-abc123",
endpoint: "/v1/chat/completions",
completion_window: "24h",
});
console.log(batch);此请求将返回一个 Batch 对象,其中包含该批次的元数据:
{
"id": "batch_abc123",
"object": "batch",
"endpoint": "/v1/chat/completions",
"errors": null,
"input_file_id": "file-abc123",
"completion_window": "24h",
"status": "validating",
"output_file_id": null,
"error_file_id": null,
"created_at": 1714508499,
"in_progress_at": null,
"expires_at": 1714536634,
"completed_at": null,
"failed_at": null,
"expired_at": null,
"request_counts": {
"total": 0,
"completed": 0,
"failed": 0
},
"metadata": null
}
4. 查看批次状态
您可以随时查看批次状态,此操作也会返回一个 Batch 对象。
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.retrieve("batch_abc123");
console.log(batch);Batch 对象的状态可以是以下任意一种:
| 状态 | 说明 |
|---|---|
validating | 正在验证输入文件,验证通过后才能开始批处理 |
failed | 输入文件未通过验证 |
in_progress | 输入文件已通过验证,批处理正在运行 |
finalizing | 批处理已完成,正在准备结果 |
completed | 批处理已完成,结果已就绪 |
expired | 批处理未能在 24 小时时限内完成 |
cancelling | 正在取消批处理任务(最多可能需要 10 分钟) |
cancelled | 批处理任务已取消 |
5. 获取结果
批处理任务完成后,您可以使用 Batch 对象中的 output_file_id 字段向 Files API 发起请求,下载输出并写入本机文件,本例中为 batch_output.jsonl。
import OpenAI from "openai";
const openai = new OpenAI();
const fileResponse = await openai.files.content("file-xyz123");
const fileContents = await fileResponse.text();
console.log(fileContents);输出的 .jsonl 文件会为输入文件中每条成功的请求提供一行响应。批处理任务中所有失败请求的错误信息都会写入错误文件,您可以通过该批处理任务的 error_file_id 找到此文件。
对于 /v1/videos,已完成的批处理结果包含的视频对象均已处于 completed、failed 或 expired 等终止状态。批处理任务结束后,您可以立即使用返回的视频 ID 下载最终资源。
请注意,输出行的顺序 可能与输入行的顺序不一致 。 处理结果时,请使用 custom_id 字段,而不要依赖行的顺序。 输出文件的每一行都包含此字段,您可以用它 将输入中的请求与输出中的结果对应起来。
{"id": "batch_req_123", "custom_id": "request-2", "response": {"status_code": 200, "request_id": "req_123", "body": {"id": "chatcmpl-123", "object": "chat.completion", "created": 1711652795, "model": "gpt-3.5-turbo-0125", "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello."}, "logprobs": null, "finish_reason": "stop"}], "usage": {"prompt_tokens": 22, "completion_tokens": 2, "total_tokens": 24}, "system_fingerprint": "fp_123"}}, "error": null}
{"id": "batch_req_456", "custom_id": "request-1", "response": {"status_code": 200, "request_id": "req_789", "body": {"id": "chatcmpl-abc", "object": "chat.completion", "created": 1711652789, "model": "gpt-3.5-turbo-0125", "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello! How can I assist you today?"}, "logprobs": null, "finish_reason": "stop"}], "usage": {"prompt_tokens": 20, "completion_tokens": 9, "total_tokens": 29}, "system_fingerprint": "fp_3ba"}}, "error": null}
输出文件会在批处理任务完成 30 天后自动删除。
6. 取消批处理任务
如有需要,您可以取消正在运行的批处理任务。任务状态将变为 cancelling,直到正在处理的请求完成(最多需要 10 分钟),随后状态将变为 cancelled。
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.cancel("batch_abc123");
console.log(batch);7. 获取所有批处理任务的列表
您随时都可以查看自己的所有批处理任务。如果任务较多,可以使用 limit 和 after 参数对结果进行分页。
import OpenAI from "openai";
const openai = new OpenAI();
const list = await openai.batches.list();
for await (const batch of list) {
console.log(batch);
}模型支持情况
我们的大多数模型都支持批处理 API,但并非全部。请参阅模型参考文档,确认您使用的模型支持批处理 API。
速率限制
批处理 API 的速率限制独立于现有的各模型速率限制。批处理 API 有以下三类速率限制:
- 单个批处理任务的限制: 单个批处理任务最多可包含 50,000 个请求,批处理输入文件的大小上限为 200 MB。请注意,
/v1/embeddings批处理任务还有一项限制:任务内所有请求的嵌入输入总数不得超过 50,000。 - 每个模型的排队提示 Token 数: 每个模型对可排队等待批处理的提示 Token 总数都有上限。您可以在平台设置页面查看这些限制。
- 批处理任务创建速率限制: 您每小时最多可以创建 2,000 个批处理任务。如果需要提交更多请求,请增加每个批处理任务中的请求数量。
批处理 API 目前没有输出 Token 限制。由于批处理 API 使用一套新增的独立速率限额, 使用批处理 API 不会占用各模型标准速率限额中的 Token 配额,因此您可以方便地增加调用我们 API 时的请求数量和可处理的 Token 数量。
批处理任务过期
未能按时完成的批处理任务最终会进入 expired 状态;该任务中未完成的请求将被取消,已完成请求的响应则可通过批处理任务的输出文件获取。所有已完成请求消耗的 Token 均会计费。
过期请求将写入错误文件,并附带如下所示的消息。您可以使用 custom_id 获取过期请求的请求数据。
{"id": "batch_req_123", "custom_id": "request-3", "response": null, "error": {"code": "batch_expired", "message": "This request could not be executed before the completion window expired."}}
{"id": "batch_req_123", "custom_id": "request-7", "response": null, "error": {"code": "batch_expired", "message": "This request could not be executed before the completion window expired."}}