[베타] 분리된 ITPM / OTPM 레이트 리밋
[베타] 분리된 ITPM / OTPM 레이트 리밋
라우터 배포에서 분당 입력 토큰(ITPM)과 분당 출력 토큰(OTPM)을 별도로 강제해요.
프로바이더가 단일 결합 TPM 대신 분리된 입력/출력 처리량 제한을 게시할 때(예: Bedrock Mantle 모델 카드) 사용해요.
이는 결합 TPM/RPM 강제와 동일한 enforce_model_rate_limits 사전 호출 검사를 사용해요. 배포에 tpm/rpm 대신 itpm/otpm을 설정해요.
출처: 문서
본문
빠른 시작 (Quick Start)
model_list:
- model_name: gpt-oss-120b
litellm_params:
model: bedrock_mantle/openai.gpt-oss-120b
aws_region_name: us-east-1
itpm: 500000 # 500K input tokens per minute
otpm: 100000 # 100K output tokens per minute
router_settings:
optional_pre_call_checks:
- enforce_model_rate_limits
프록시 시작:
litellm --config /path/to/config.yaml
itpm/otpm을 프로바이더 할당량 또는 모델 카드의 값(Service Quotas 콘솔 또는 내부 용량 계획)으로 설정해요.
Mantle 스타일 예약 (Mantle-style reservation)
LiteLLM은 Bedrock Mantle 엔드포인트와 동일한 예약 모델을 따라요. 토큰 제한이 업스트림 호출 전에 강제되고 응답 후에 조정돼요.
사전 호출 (승인, Pre-call/admission)
요청이 프로바이더로 보내지기 전에:
- 요청 본문(
messages,prompt, 또는 Responsesinput)에서 입력 토큰을 추정. - 할당량 검사 시
max_tokens를 대신할 유효 출력 상한(effective output cap)을 결정:
| 우선순위 | 출처 | 예시 (openai.gpt-oss-120b) |
|---|---|---|
| 1 | 요청 max_tokens 또는 max_completion_tokens |
클라이언트가 max_tokens: 1024 전송 → 1024 사용 |
| 2 | 모델 맵 max_output_tokens (대체 max_tokens) |
클라이언트 상한 없음 → 모델 카드의 32768 사용 |
| 3 | 하드 기본값 | 알 수 없는 모델 → 4096 |
- ITPM 검사: 배포 ITPM 제한에 대해
estimated_input + effective_output_cap을 예약. 승인 시도가 제한을 초과하면429로 차단. - OTPM 검사:
current_otpm + effective_output_cap이 OTPM 제한에 들어맞는지 확인. OTPM을 초과하면 ITPM 예약을 롤백하고429를 반환.
이는 Mantle을 반영해요. 클라이언트가 max_tokens를 생략하면 LiteLLM은 입력 컨텍스트 창이 아니라 모델의 최대 출력 용량을 가정해요. 그래서 큰 모델에서 max_tokens가 없으면 많은 ITPM/OTPM 헤드룸이 예약될 수 있어요.
팁: max_tokens(Responses에서는 max_output_tokens)를 예상 완성 크기에 가깝게 설정하세요. Mantle과 LiteLLM 모두 응답 후 조정하지만, 높은 기본 상한은 호출이 끝날 때까지 동시 요청을 여전히 차단해요.
사후 호출 (조정, Post-call/reconciliation)
성공적인 응답 후:
| 카운터 | 기록되는 것 |
|---|---|
| ITPM | 사전 호출 예약을 billable_input + completion_tokens으로 교체. 여기서 billable_input = prompt_tokens - cached_tokens |
| OTPM | 실제 completion_tokens 추가 |
요청이 완성 전에 실패하면 ITPM 예약은 환불되고 OTPM은 청구되지 않아요.
작업 예시 (Worked example)
bedrock_mantle/openai.gpt-oss-120b(max_output_tokens: 32768, itpm: 500000)에 대해 max_tokens 없는 요청:
| 단계 | 계산 | ITPM 사용량 |
|---|---|---|
| 사전 호출 예약 | 입력 추정 12 + 출력 상한 32768 | 32780 예약 |
| 응답 | prompt_tokens=10, completion_tokens=150, 캐시 없음 |
— |
| 사후 호출 조정 | 10 + 150 | 160 최종 |
명시적 max_tokens 없이는 사전 호출 보류가 최종 청구보다 훨씬 큽니다. 이는 Mantle이 할당량 예약에 대해 문서화한 것과 같은 동작이에요.
동작 방식 (How It Works)
| 단계 | ITPM | OTPM |
|---|---|---|
| 사전 호출 | estimated_input + effective_output_cap 예약 |
current_otpm + effective_output_cap 검사 |
| 사후 호출 | billable_input + completion_tokens으로 조정 |
실제 completion_tokens 추가 |
| 실패 | ITPM 예약 환불 | OTPM 청구 없음 |
캐시된 프롬프트 토큰(prompt_tokens_details.cached_tokens)은 응답 후 ITPM 청구에서 제외돼요.
응답 헤더 (Response Headers)
모델 그룹에 itpm 또는 otpm이 구성되면 LiteLLM이 반환해요.
| 헤더 | 설명 |
|---|---|
| x-ratelimit-limit-input-tokens | 모델 그룹의 ITPM 제한 |
| x-ratelimit-remaining-input-tokens | 이번 분의 남은 ITPM 용량 |
| x-ratelimit-reset-input-tokens | 분 창이 재설정될 때까지 초 |
| x-ratelimit-limit-output-tokens | 모델 그룹의 OTPM 제한 |
| x-ratelimit-remaining-output-tokens | 이번 분의 남은 OTPM 용량 |
| x-ratelimit-reset-output-tokens | 분 창이 재설정될 때까지 초 |
오류 응답 (Error Response)
업스트림 호출 전에 제한이 초과되면:
{
"error": {
"message": "Model rate limit exceeded. ITPM limit=500000, current usage=500120",
"type": "rate_limit_error",
"code": 429
}
}
응답에는 retry-after 헤더(현재 분 창이 재설정될 때까지 초)가 포함돼요.
프로젝트 수준 제한 (Project-Level Limits)
프록시에서 프로젝트의 모델별 ITPM/OTPM 할당량을 강제해요. 프로젝트를 만들거나 업데이트할 때 model_itpm_limit과 model_otpm_limit을 설정해요. 각각 모델 이름(클라이언트가 요청하는 model_name)을 분당 토큰 제한으로 매핑해요.
curl -X POST 'http://localhost:4000/project/new' \
-H "Authorization: Bearer $LITEL..._KEY" \
-H 'Content-Type: application/json' \
-d '{
"project_alias": "my-project",
"team_id": "<team-id>",
"models": ["claude-fable-5"],
"model_itpm_limit": {"claude-fable-5": 300000},
"model_otpm_limit": {"claude-fable-5": 100000}
}'
프로젝트의 키로 만든 요청은 이 제한에 집계돼요. 강제는 배포 제한과 동일한 예약 모델을 따릅니다. LiteLLM은 업스트림 호출 전에 입력 추정과 유효 출력 상한을 예약한 뒤 응답 후 실제 사용량으로 조정해요. 라우터 설정은 필요 없어요. 프록시의 레이트 리미터가 프로젝트 메타데이터를 자동으로 강제해요. 프로젝트가 프록시 DB에 살므로 데이터베이스가 필요해요.
프로젝트 응답 헤더
프로젝트 제한이 있는 모델의 성공적인 응답에는 다음이 포함돼요.
| 헤더 | 설명 |
|---|---|
| x-ratelimit-model_per_project_itpm-limit-tokens | 모델의 프로젝트 ITPM 제한 |
| x-ratelimit-model_per_project_itpm-remaining-tokens | 이번 분의 남은 프로젝트 ITPM |
| x-ratelimit-model_per_project_otpm-limit-tokens | 모델의 프로젝트 OTPM 제한 |
| x-ratelimit-model_per_project_otpm-remaining-tokens | 이번 분의 남은 프로젝트 OTPM |
프로젝트 오류 응답
프로젝트 제한을 초과할 요청은 업스트림 호출 전에 429로 차단돼요.
{
"error": {
"message": "Rate limit exceeded for model_per_project_itpm: <project-id>:claude-fable-5. Limit type: tokens. Current limit: 300000, Remaining: 300000. Limit resets at: 2026-08-18 14:48:49 UTC",
"type": "throttling_error",
"code": "429"
}
}
ITPM 대 TPM
| 설정 | 제한하는 것 | 사용 시점 |
|---|---|---|
| tpm | 총 토큰/분 (단일 카운터) | 레거시 결합 처리량 제한 |
| itpm + otpm | 입력·출력 분리 | 별도 입력/출력 TPM을 제공하는 프로바이더 문서 (Bedrock Mantle) |
같은 배포에 두 모드를 모두 설정하지 마세요. itpm 또는 otpm이 있으면 LiteLLM은 ITPM/OTPM 경로를 사용하고 해당 배포의 결합 TPM 추적을 무시해요.
다중 인스턴스 배포 (Multi-Instance Deployment)
Redis로 프록시 복제본 간에 카운터를 공유해요.
router_settings:
optional_pre_call_checks:
- enforce_model_rate_limits
redis_host: redis.example.com
redis_port: 6379
redis_password: your-password
SDK 사용법 (SDK Usage)
from litellm import Router
router = Router(
model_list=[
{
"model_name": "gpt-oss-120b",
"litellm_params": {
"model": "bedrock_mantle/openai.gpt-oss-120b",
"itpm": 500_000,
"otpm": 100_000,
},
}
],
optional_pre_call_checks=["enforce_model_rate_limits"],
)
response = await router.acompletion(
model="gpt-oss-120b",
messages=[{"role": "user", "content": "Hello"}],
max_tokens=1024, # explicit cap avoids over-reserving model max_output_tokens
)