Vertex Batch API
設定
在您的 config.yaml 中設定 Vertex 模型。gcs_bucket_name 是儲存批次預測檔案的 GCS bucket,這是 vertexai 用來儲存檔案的必要參數。較舊的 bucket_name litellm 參數仍受支援,並且會被視為與 gcs_bucket_name 相同。若兩者都設定在同一個部署上,gcs_bucket_name 會生效
model_list:
- model_name: vertex-batch
litellm_params:
model: vertex_ai/gemini-3.8-flash
vertex_project: my-project
vertex_location: us-central1
vertex_credentials: /path/to/service_account.json
gcs_bucket_name: my-batch-bucket # required param for vertexai to store files
model_info:
mode: batch
當模型的 litellm_params 上未設定 gcs_bucket_name(或 bucket_name)與 vertex_credentials 時,LiteLLM 會回退使用這些環境變數。GCS_BATCH_BUCKET_NAME 存在的原因是,gcs_bucket 記錄回呼 已經使用 GCS_BUCKET_NAME 作為寫入 LLM 請求記錄的 bucket,因此將 GCS_BUCKET_NAME 設為您的批次 bucket 也會把請求記錄送到那裡。批次檔案會先檢查 GCS_BATCH_BUCKET_NAME;當它未設定時,則使用 GCS_BUCKET_NAME
# GCS Bucket settings, used to store batch prediction files in
export GCS_BATCH_BUCKET_NAME="my-batch-bucket" # bucket for batch prediction files, takes precedence over GCS_BUCKET_NAME
export GCS_BUCKET_NAME="my-logging-bucket" # used for batch files only when GCS_BATCH_BUCKET_NAME is unset
export GCS_PATH_SERVICE_ACCOUNT="/path/to/service_account.json" # path to your service account json file
# Vertex /batch endpoint settings, used for LLM API requests
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service_account.json" # path to your service account json file
export VERTEXAI_LOCATION="us-central1" # can be any vertex location
export VERTEXAI_PROJECT="my-project"
用法
請依照以下完整流程:建立 JSONL 檔案 → 上傳檔案 → 建立 batch → 擷取 batch 狀態 → 取得檔案內容
1. 建立 batch 請求的 JSONL 檔案
LiteLLM 預期檔案需遵循 OpenAI 批次檔案格式。
檔案中的每個 body 都應為 OpenAI API 請求。
建立一個名為 batch_requests.jsonl 的檔案,內容放入您的請求:
{"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gemini-3.8-flash", "messages": [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Hello world!"}],"max_tokens": 10}}
{"custom_id": "request-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gemini-3.8-flash", "messages": [{"role": "system", "content": "You are an unhelpful assistant."},{"role": "user", "content": "Hello world!"}],"max_tokens": 10}}
2. 上傳檔案
上傳您的 JSONL 檔案。對於 vertex_ai,檔案會儲存在部署的 gcs_bucket_name(或 bucket_name)中,並回退使用 GCS_BATCH_BUCKET_NAME,再來是 GCS_BUCKET_NAME。
- Python
- Curl
from openai import OpenAI
oai_client = OpenAI(
api_key="sk-<your-litellm-api-key>", # litellm proxy API key
base_url="http://localhost:4000" # litellm proxy base url
)
file_obj = oai_client.files.create(
file=open("batch_requests.jsonl", "rb"),
purpose="batch",
extra_headers={"custom-llm-provider": "vertex_ai"}
)
print(f"File uploaded with ID: {file_obj.id}")
curl --request POST \
--url http://localhost:4000/v1/files \
--header 'Content-Type: multipart/form-data' \
--header 'custom-llm-provider: vertex_ai' \
--form purpose=batch \
--form file=@batch_requests.jsonl
預期回應:
{
"id": "gs://my-batch-bucket/litellm-vertex-files/publishers/google/models/gemini-3.8-flash/abc123-def4-5678-9012-34567890abcd",
"bytes": 416,
"created_at": 1758303684,
"filename": "litellm-vertex-files/publishers/google/models/gemini-3.8-flash/abc123-def4-5678-9012-34567890abcd",
"object": "file",
"purpose": "batch",
"status": "uploaded",
"expires_at": null,
"status_details": null
}
3. 建立 batch
使用已上傳的檔案 ID 建立 batch 工作。
- Python
- Curl
batch_input_file_id = file_obj.id # from step 2
create_batch_response = oai_client.batches.create(
completion_window="24h",
endpoint="/v1/chat/completions",
input_file_id=batch_input_file_id, # e.g. "gs://my-batch-bucket/litellm-vertex-files/publishers/google/models/gemini-3.8-flash/abc123-def4-5678-9012-34567890abcd"
extra_headers={"custom-llm-provider": "vertex_ai"}
)
print(f"Batch created with ID: {create_batch_response.id}")
curl --request POST \
--url http://localhost:4000/v1/batches \
--header 'Content-Type: application/json' \
--header 'custom-llm-provider: vertex_ai' \
--data '{
"input_file_id": "gs://my-batch-bucket/litellm-vertex-files/publishers/google/models/gemini-3.8-flash/abc123-def4-5678-9012-34567890abcd",
"endpoint": "/v1/chat/completions",
"completion_window": "24h"
}'
預期回應:
{
"id": "7814463557919047680",
"completion_window": "24hrs",
"created_at": 1758328011,
"endpoint": "",
"input_file_id": "gs://my-batch-bucket/litellm-vertex-files/publishers/google/models/gemini-3.8-flash/abc123-def4-5678-9012-34567890abcd",
"object": "batch",
"status": "validating",
"cancelled_at": null,
"cancelling_at": null,
"completed_at": null,
"error_file_id": null,
"errors": null,
"expired_at": null,
"expires_at": null,
"failed_at": null,
"finalizing_at": null,
"in_progress_at": null,
"metadata": null,
"output_file_id": null,
"request_counts": null,
"usage": null
}
4. 擷取 batch 狀態
檢查您的批次工作狀態。批次會依序進入這些狀態:validating → in_progress → completed。output_file_id 會保持為 null,直到批次到達 completed。
- Python
- Curl
retrieved_batch = oai_client.batches.retrieve(
batch_id=create_batch_response.id, # Created batch id, e.g. 7814463557919047680
extra_headers={"custom-llm-provider": "vertex_ai"}
)
print(f"Batch status: {retrieved_batch.status}")
if retrieved_batch.status == "completed":
print(f"Output file: {retrieved_batch.output_file_id}")
curl --request GET \
--url 'http://localhost:4000/batches/7814463557919047680?provider=vertex_ai' \
--header "Authorization: Bearer $LITELLM_API_KEY"
預期回應(完成時):
{
"id": "7814463557919047680",
"completion_window": "24hrs",
"created_at": 1758328011,
"endpoint": "",
"input_file_id": "gs://my-batch-bucket/litellm-vertex-files/publishers/google/models/gemini-3.8-flash/abc123-def4-5678-9012-34567890abcd",
"object": "batch",
"status": "completed",
"cancelled_at": null,
"cancelling_at": null,
"completed_at": null,
"error_file_id": null,
"errors": null,
"expired_at": null,
"expires_at": null,
"failed_at": null,
"finalizing_at": null,
"in_progress_at": null,
"metadata": null,
"output_file_id": "gs://my-batch-bucket/litellm-vertex-files/publishers/google/models/gemini-3.8-flash/prediction-model-2025-09-19T21:26:51.569037Z/predictions.jsonl",
"request_counts": null,
"usage": null
}
5. 取得檔案內容
batch 完成後,請使用 batch 回應中的 output_file_id 來擷取結果。
**重要:**在請求路徑中使用 output_file_id 時,必須先進行 URL 編碼。
- Python
- Curl
import urllib.parse
import json
output_file_id = retrieved_batch.output_file_id
# URL encode the file ID
encoded_file_id = urllib.parse.quote_plus(output_file_id)
# Get file content
file_content = oai_client.files.content(
file_id=encoded_file_id,
extra_headers={"custom-llm-provider": "vertex_ai"}
)
# Process the results
for line in file_content.text.strip().split('\n'):
result = json.loads(line)
print(f"Request: {result['request']}")
print(f"Response: {result['response']}")
print("---")
# Note: The file ID must be URL encoded
curl --request GET \
--url 'http://localhost:4000/files/gs%253A%252F%252Fmy-batch-bucket%252Flitellm-vertex-files%252Fpublishers%252Fgoogle%252Fmodels%252Fgemini-2.5-flash-lite%252Fprediction-model-2025-09-19T21%253A26%253A51.569037Z%252Fpredictions.jsonl/content?provider=vertex_ai' \
--header "Authorization: Bearer $LITELLM_API_KEY"
預期回應:
回應包含 JSONL 格式,每一行一個結果:
{"status":"","processed_time":"2025-09-19T21:29:47.352+00:00","request":{"contents":[{"parts":[{"text":"Hello world!"}],"role":"user"}],"generationConfig":{"max_output_tokens":10},"system_instruction":{"parts":[{"text":"You are a helpful assistant."}]}},"response":{"candidates":[{"avgLogprobs":-0.48079710006713866,"content":{"parts":[{"text":"Hello there! It's nice to meet you"}],"role":"model"},"finishReason":"MAX_TOKENS"}],"createTime":"2025-09-19T21:29:47.484619Z","modelVersion":"gemini-3.8-flash","responseId":"S8vNaIvKHdvshMIP_aOtuAg","usageMetadata":{"candidatesTokenCount":10,"candidatesTokensDetails":[{"modality":"TEXT","tokenCount":10}],"promptTokenCount":9,"promptTokensDetails":[{"modality":"TEXT","tokenCount":9}],"totalTokenCount":19,"trafficType":"ON_DEMAND"}}}
{"status":"","processed_time":"2025-09-19T21:29:47.358+00:00","request":{"contents":[{"parts":[{"text":"Hello world!"}],"role":"user"}],"generationConfig":{"max_output_tokens":10},"system_instruction":{"parts":[{"text":"You are an unhelpful assistant."}]}},"response":{"candidates":[{"avgLogprobs":-0.6168075137668185,"content":{"parts":[{"text":"I am unable to assist with this request."}],"role":"model"},"finishReason":"STOP"}],"createTime":"2025-09-19T21:29:47.470889Z","modelVersion":"gemini-3.8-flash","responseId":"S8vNaOneHISShMIP28nA8QQ","usageMetadata":{"candidatesTokenCount":9,"candidatesTokensDetails":[{"modality":"TEXT","tokenCount":9}],"promptTokenCount":9,"promptTokensDetails":[{"modality":"TEXT","tokenCount":9}],"totalTokenCount":18,"trafficType":"ON_DEMAND"}}}
原生 Vertex JSONL 直通
預設情況下,LiteLLM 在您上傳檔案時會將每一行 OpenAI 格式轉換為 Vertex GenerateContent 請求,並在您下載時將批次輸出再轉回 OpenAI chat completion 形式。在上傳時設定 passthrough=true 以略過這兩者:檔案會逐位元組原封不動地儲存在您的 GCS bucket 中,而批次輸出會以 Vertex 的原生格式回傳,包含 groundingMetadata。可用於轉換未涵蓋的 Vertex 功能,例如搭配 excludeDomains 的 googleSearch grounding,同時不需要向您的呼叫端提供 GCP 憑證。成本追蹤不變:LiteLLM 會從每一列原生輸出中讀取 usageMetadata,並以與線上 Gemini 請求相同的方式計費。
1. 建立原生 JSONL 檔案
每一行都是一個 Vertex 批次預測請求,也就是具有 request 鍵的 JSON 物件:
{"request": {"contents": [{"role": "user", "parts": [{"text": "What is the tallest building in the world?"}]}], "tools": [{"googleSearch": {"excludeDomains": ["example.com"]}}]}}
{"request": {"contents": [{"role": "user", "parts": [{"text": "Who won the last FIFA World Cup?"}]}], "tools": [{"googleSearch": {"excludeDomains": ["example.com"]}}]}}
2. 使用 passthrough=true 上傳它
原生列不包含模型,因此請指定要執行批次的 Vertex 部署:target_model_names(受管理檔案,需要資料庫)或 model 查詢參數(不需要資料庫)。LiteLLM 會將物件儲存在該模型路徑下的 litellm-vertex-files/passthrough/ 中,而批次輸出也會存放在旁邊,這就是下載步驟知道要原封不動回傳它的方式。
model_list:
- model_name: gemini-3.8-flash
litellm_params:
model: vertex_ai/gemini-3.8-flash
vertex_project: my-project
vertex_location: us-central1
gcs_bucket_name: my-batch-bucket
- Python
- Curl
- LiteLLM SDK
file_obj = oai_client.files.create(
file=open("native_batch_requests.jsonl", "rb"),
purpose="batch",
extra_body={"target_model_names": "gemini-3.8-flash", "passthrough": True},
)
print(f"File uploaded with ID: {file_obj.id}")
curl --request POST \
--url http://localhost:4000/v1/files \
--header "Authorization: Bearer $LITELLM_API_KEY" \
--form purpose=batch \
--form target_model_names=gemini-3.8-flash \
--form passthrough=true \
--form file=@native_batch_requests.jsonl
import litellm
file_obj = litellm.create_file(
file=open("native_batch_requests.jsonl", "rb"),
purpose="batch",
custom_llm_provider="vertex_ai",
model="vertex_ai/gemini-3.8-flash",
passthrough=True,
)
建立批次、輪詢,並以下載輸出,如同上述步驟 3 到 5。輸出是原始 Vertex predictions.jsonl,因此每一行都包含 request、status 和 response,而在每一列有執行 grounding 的地方則會有 candidates[].groundingMetadata。
直通會檢查什麼
purpose必須是batch,且指定的模型必須是該金鑰可使用的vertex_ai部署,否則上傳會以 400 錯誤拒絕並標示該欄位。- 每一行都必須是具有
request鍵的 JSON 物件。OpenAI 格式的行會被以 400 錯誤拒絕並標示該行,且不會上傳任何內容。 - 批次防護欄只支援 OpenAI 格式的列,因此當金鑰、團隊或請求已設定前置呼叫防護欄時,直通上傳會以 400 錯誤拒絕。
直通是逐次上傳套用。SDK 全域的 litellm.disable_vertex_batch_output_transformation 旗標仍會套用於每個 Vertex 批次輸出,但絕不會影響輸入端;passthrough 只會對您設定它的那個檔案同時涵蓋兩者。