Aprende a usar la API de procesamiento por lotes de OpenAI para enviar grupos de solicitudes asíncronas con costos un 50 % menores, límites de solicitudes independientes y considerablemente más altos, y un plazo definido de 24 horas para obtener los resultados. El servicio es ideal para procesar trabajos que no requieren respuestas inmediatas. También puedes consultar directamente la referencia de la API aquí.
Descripción general
Aunque algunos usos de la plataforma de OpenAI requieren enviar solicitudes síncronas, en muchos casos las solicitudes no necesitan una respuesta inmediata o los límites de solicitudes impiden ejecutar una gran cantidad de consultas rápidamente. El procesamiento por lotes suele ser útil en casos de uso como:
- Ejecutar evaluaciones
- Clasificar grandes conjuntos de datos
- Generar embeddings de repositorios de contenido
- Poner en cola grandes trabajos de renderizado de video sin conexión
La API de procesamiento por lotes ofrece un conjunto sencillo de puntos de acceso que te permiten agrupar solicitudes en un solo archivo, iniciar un trabajo de procesamiento por lotes para ejecutarlas, consultar el estado del lote mientras se ejecutan las solicitudes y, finalmente, recuperar los resultados recopilados cuando se completa el lote.
En comparación con el uso directo de los puntos de acceso estándar, la API de procesamiento por lotes ofrece:
- Menores costos: un descuento del 50 % en comparación con las API síncronas
- Límites de solicitudes más altos: un margen considerablemente mayor en comparación con las API síncronas
- Plazos de finalización breves: cada lote se completa en un plazo de 24 horas (y a menudo en menos tiempo)
Primeros pasos
1. Prepara tu archivo de lote
Los lotes comienzan con un archivo .jsonl en el que cada línea contiene los detalles de una solicitud individual a la API. Por ahora, los puntos de acceso disponibles son:
/v1/responses(API Responses)/v1/chat/completions(API para completar chats)/v1/embeddings(API de embeddings)/v1/completions(API de completado)/v1/moderations(Guía de moderación)/v1/images/generations(API de imágenes)/v1/images/edits(API de imágenes)/v1/videos(Guía de generación de video)
En un archivo de entrada, los parámetros del campo body de cada línea son los mismos que los del punto de acceso correspondiente. Cada solicitud debe incluir un valor custom_id único, que puedes usar para identificar los resultados una vez completada. Aquí tienes un ejemplo de un archivo de entrada con 2 solicitudes. Ten en cuenta que cada archivo de entrada solo puede incluir solicitudes a un único modelo.
Para la generación de video mediante el procesamiento por lotes:
- Actualmente, el procesamiento por lotes solo admite
POST /v1/videos. - Las solicitudes de video por lotes deben usar JSON, no multipart.
- Carga los recursos con anticipación y pasa referencias compatibles a esos recursos en el cuerpo de la solicitud en lugar de usar cargas multipart.
- Usa
input_referencepara las generaciones guiadas por imágenes en el procesamiento por lotes. En las solicitudes JSON, pasainput_referencecomo un objeto confile_idoimage_url. - El procesamiento por lotes no admite cargas multipart de
input_reference, incluidas las entradas de video de referencia. - Los videos generados por lotes están disponibles para su descarga durante un máximo de
24horas después de que se completa el lote.
Al enviar solicitudes a /v1/moderations, incluye un campo input en el cuerpo de cada solicitud. El procesamiento por lotes acepta entradas de texto sin formato y arreglos de contenido con entradas de texto o imágenes mediante omni-moderation-latest. El proceso de ejecución de lotes rechaza las solicitudes que establecen stream=true, al igual que el punto de acceso de moderación síncrono.
{"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}}
Ejemplos de entradas de moderación
Solicitud de solo texto:
{
"custom_id": "moderation-text-1",
"method": "POST",
"url": "/v1/moderations",
"body": {
"model": "omni-moderation-latest",
"input": "This is a harmless test sentence."
}
}
Solicitud con entrada de texto e imagen:
{
"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"
}
}
]
}
}
De preferencia, usa image_url para hacer referencia a recursos remotos (en lugar de blobs en base64) para
mantener tus archivos .jsonl muy por debajo del límite de carga de 200 MB del procesamiento por lotes,
especialmente en las solicitudes de moderación multimodal.
2. Carga tu archivo de entrada del lote
Al igual que con nuestra API de ajuste fino, primero debes cargar tu archivo de entrada para poder hacer referencia a él correctamente al iniciar los lotes. Carga tu archivo .jsonl con la API de archivos.
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. Crea el lote
Una vez que hayas cargado correctamente tu archivo de entrada, puedes usar el ID del objeto File de entrada para crear un lote. En este caso, supongamos que el ID del archivo es file-abc123. Por ahora, el plazo de finalización solo se puede establecer en 24h. También puedes proporcionar metadatos personalizados mediante el parámetro opcional 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);Esta solicitud devolverá un objeto Batch con metadatos sobre tu lote:
{
"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. Consulta el estado de un lote
Puedes consultar el estado de un lote en cualquier momento; esta consulta también devolverá un objeto Batch.
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.retrieve("batch_abc123");
console.log(batch);El estado de un objeto Batch puede ser cualquiera de los siguientes:
| Estado | Descripción |
|---|---|
validating | se está validando el archivo de entrada antes de que pueda comenzar el lote |
failed | el archivo de entrada no pasó el proceso de validación |
in_progress | el archivo de entrada se validó correctamente y el lote se está ejecutando |
finalizing | el lote se completó y se están preparando los resultados |
completed | el lote se completó y los resultados están listos |
expired | no se pudo completar el lote dentro del plazo de 24 horas |
cancelling | se está cancelando el lote (puede tardar hasta 10 minutos) |
cancelled | se canceló el lote |
5. Obtener los resultados
Una vez que se complete el lote, puedes descargar los resultados haciendo una solicitud a la API de archivos con el campo output_file_id del objeto Batch y guardarlos en un archivo en tu equipo, en este caso 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);El archivo de salida .jsonl tendrá una línea de respuesta por cada línea de solicitud del archivo de entrada que se haya procesado correctamente. La información de error de las solicitudes fallidas del lote se guardará en un archivo de errores que puedes encontrar mediante el campo error_file_id del lote.
Para /v1/videos, el resultado de un lote completado contiene objetos de video que ya alcanzaron un estado final, como completed, failed o expired. Puedes usar los ID de video devueltos para descargar los archivos finales inmediatamente después de que termine el lote.
Ten en cuenta que el orden de las líneas de salida puede no coincidir con el de las líneas de entrada. En lugar de basarte en el orden para procesar los resultados, usa el campo custom_id, que estará presente en cada línea del archivo de salida y te permitirá asociar las solicitudes de entrada con los resultados de salida.
{"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}
El archivo de salida se eliminará automáticamente 30 días después de que se complete el lote.
6. Cancelar un lote
Si es necesario, puedes cancelar un lote en curso. El estado del lote cambiará a cancelling hasta que se completen las solicitudes en curso (hasta 10 minutos), tras lo cual cambiará a cancelled.
import OpenAI from "openai";
const openai = new OpenAI();
const batch = await openai.batches.cancel("batch_abc123");
console.log(batch);7. Obtener una lista de todos los lotes
Puedes ver todos tus lotes en cualquier momento. Si tienes muchos lotes, puedes usar los parámetros limit y after para paginar los resultados.
import OpenAI from "openai";
const openai = new OpenAI();
const list = await openai.batches.list();
for await (const batch of list) {
console.log(batch);
}Disponibilidad por modelo
La API de procesamiento por lotes está disponible para la mayoría de nuestros modelos, pero no para todos. Consulta la documentación de referencia de los modelos para asegurarte de que el modelo que usas sea compatible con la API de procesamiento por lotes.
Límites de solicitudes
Los límites de solicitudes de la API de procesamiento por lotes son independientes de los límites existentes por modelo. La API de procesamiento por lotes tiene tres tipos de límites de solicitudes:
- Límites por lote: un solo lote puede incluir hasta 50 000 solicitudes, y un archivo de entrada de lote puede tener un tamaño de hasta 200 MB. Ten en cuenta que los lotes de
/v1/embeddingstambién están limitados a un máximo de 50 000 entradas para embeddings entre todas las solicitudes del lote. - Tokens de prompt en cola por modelo: cada modelo tiene un número máximo de tokens de prompt que se pueden poner en cola para el procesamiento por lotes. Puedes consultar estos límites en la página de configuración de la plataforma.
- Límite de frecuencia de creación de lotes: puedes crear hasta 2000 lotes por hora. Si necesitas enviar más solicitudes, aumenta el número de solicitudes por lote.
La API de procesamiento por lotes actualmente no tiene un límite de tokens de salida. Como sus límites de solicitudes ofrecen una capacidad nueva e independiente, usar la API de procesamiento por lotes no consumirá tokens de tus límites de solicitudes estándar por modelo. Esto te ofrece una forma práctica de aumentar el número de solicitudes y de tokens procesados al consultar nuestra API.
Vencimiento de los lotes
Los lotes que no se completan a tiempo terminan pasando al estado expired; las solicitudes sin terminar de ese lote se cancelan, y las respuestas de las solicitudes completadas quedan disponibles en el archivo de salida del lote. Se te cobrarán los tokens consumidos por todas las solicitudes completadas.
Las solicitudes vencidas se registrarán en tu archivo de errores con el mensaje que se muestra a continuación. Puedes usar custom_id para obtener los datos de las solicitudes vencidas.
{"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."}}