09:12 — 토큰 미터는 0을 가리키지만, 마감 시간은 그렇지 않다
09:12에 무료 레인에 요약 작업(summarization jobs) 40개를 예약합니다.
09:14에도 토큰 미터는 여전히 0을 가리킵니다. 비용 대시보드는 완벽해 보입니다.
09:41에야 작업 37이 마침내 완료됩니다. 배치 마감 시간(batch deadline)은 09:30이었습니다.
이 간극은 토큰 문제가 아닙니다. 슬롯 문제입니다.
이것은 고객의 사고가 아니라 종합적인 시뮬레이션입니다. 아래의 모든 숫자는 하나의 Python 파일과 고정된 시드 값으로 로컬에서 재현되므로, 저와 논쟁하는 대신 이 데이터로 논쟁할 수 있습니다.
토큰 카운터는 작업량을 측정할 뿐, 비용을 측정하지 않는다
카운터는 작업이 완료될 때만 움직입니다. 대기 시간은 그것에게 보이지 않습니다.
슬롯 2개와 작업 40개라는 것은 대기 시간이 다른 모든 것을 지배한다는 의미입니다. 실제로 소비하는 통화는 방출되는 토큰(tokens)이 아니라 점유된 슬롯 초(slot-seconds)입니다.
재시도(Retry)는 피해를 두 배로 만듭니다. 재시는 단순히 토큰을 두 번 사용하는 것뿐만 아니라, 동시성 슬롯(concurrency slot)을 두 번 점유하게 합니다.
선언된 테스트 조건
아래의 내용은 공급업체로부터 온 것이 아닙니다. 이것들은 로컬 시뮬레이션의 선언된 입력값입니다.
- 동시성(Concurrency): 2 슬롯, FIFO 방식 입실.
- 기본 지연 시간(Base latency): 시도당 6.0초. 제공업체와 비교하여 측정된 것이 아닌 선언된 값입니다.
- 지터(Jitter): 가우시안 분포, 표준 편차(sigma) 2.0초, 시도당 최소 0.5초.
- 재시도 확률(Retry probability): 시도당 0.18, 최대 3회 시도.
- 배치 크기(Batch size): 작업 40개, 시드 112, 단일 프로세스, 네트워크 호출 없음.
- 출력: JSONL 원장 하나, 요약 블록 하나, 그리고 차단기 결정(breaker decision).
작업이 아닌 '시도'를 기록하라
시도당 하나의 원장 라인(ledger line)이 최소한으로 유용한 세분성입니다. 나중에 작업을 기준으로 집계할 수 있습니다.
- 식별자(Identity):
job_id, attempt, lane.
- 타이밍(Timing):
enqueued_at, dispatched_at, finished_at.
- 점유 시간(Occupancy):
slot_seconds, attempt_seconds.
- 결과(Result):
outcome, prompt_tokens, completion_tokens, breaker_state.
slot_seconds는 대부분의 팀이 저장하지 않는 필드입니다. 또한 비용 질문에 답하는 유일한 필드이기도 합니다.
시뮬레이션을 로컬에서 실행하라
이것을 slot_ledger.py로 저장하고 실행하세요. 표준 라이브러리를 넘어서는 의존성이 필요하지 않습니다.
#!/usr/bin/env python3
# 2 슬롯 무료 레인에 대한 결정론적 슬롯 시간 회계 드릴.
import json
...
시드 112에서의 예상 출력 형태
이 값들은 선언된 입력에 대한 예시입니다. 정확한 숫자는 사용자의 Python 빌드에 따라 달라지므로, 마지막 소수점 대신 모양과 비율을 비교하세요.
jobs 40
success_rate 0.875
slot_seconds_total 291.4
...
p90_wait_seconds를 확인해 보세요. 이는 시도당 작업 시간이 6.0초인 레인에서 129.7초입니다. 경과 시간의 거의 모든 부분이 줄을 서서 기다리는 데 사용되었습니다.
평균값 하나가 아닌 네 가지 임계치
평균값은 마감 시간을 놓치는 꼬리 부분(tail)을 숨깁니다. 대신 이 네 가지에 게이트를 설정하세요.
success_rate가 0.95 미만: 다른 어떤 것보다 먼저 멱등성(idempotency) 문제를 해결하세요. 비-멱등적 쓰기 작업(non-idempotent write)을 재시도하는 것이 중복 데이터를 만드는 방법입니다.
slot_seconds_per_success가 BASE_LATENCY_S보다 30% 이상 높음: 재시도는 아무것도 사주지 못합니다.
retry_slot_overhead_pct가 25%를 초과함: 새로운 무료 레인 유입을 동결하세요. 모든 새로운 작업은 모두의 대기 시간을 늘립니다.
p90_wait_seconds가 마감 시간 여유분의 절반을 초과함: 이 배치(batch)에 이 레인은 적절한 선택이 아닙니다.
p90_wait_seconds를 인큐(enqueue) 분별로 슬라이스하세요. 빠르게 시작하여 10분 만에 성능이 저하되는 배치는 모델 문제가 아니라 대기열(queue) 문제입니다.
입고 게이트 (The admission gate)
무작정 허용하는 대기열은 고칠 수 없습니다. 디스패처 앞에 게이트를 두세요.
HEADROOM = 0.5 # 무료 레인은 최대 여유분의 절반만 소비할 수 있음
MAX_RETRY_SLOT_OVERHEAD = 25.0 # 백분율
...
왜 여유분의 절반일까요? 나머지 절반은 재시도, 아티팩트 쓰기(artifact writes), 그리고 출력을 읽는 검토자에게 필요하기 때문입니다.
슬롯으로 표현된 재시도 증폭 (Retry amplification)
시도당 실패율(per-attempt failure rate) $p$가 0.18일 때, 성공당 예상 시도 횟수는 $1 / (1 - p)$로 약 1.22입니다. 이는 대장(ledger) 오버헤드 약 22%와 일치합니다.
검토에서 주장할 수 있는 공식은 간단합니다. 성공당 슬롯 비용은 기본 시도 시간을 (1 - p)로 나눈 값과 같습니다. 작업을 더 크게 만들어 p를 높이면, 토큰과 점유된 슬롯 모두에서 두 배의 비용을 지불하게 됩니다.
무료 옵션이 실제로 적합한 경우
수집기(collector)와 브레이커 루프(breaker loop)를 작고 항상 켜져 있는 호스트에서 실행하고, 위험도가 낮은 분류 단계는 무료 모델 액세스를 통해 전송합니다. 무료 서버 옵션과 무료 모델 액세스는 운영자 자체 설명에 따라 사용 가능하며, 이것이 제가 여기서 하는 유일한 가용성 주장입니다.
고지 사항: 이 문서는 MonkeyCode의 제품 홍보 활동의 일환으로 작성되었습니다.
테스트는 정직하게 유지하세요: 이 기사의 원장(ledger)은 로컬이며 시뮬레이션된 것입니다. 시뮬레이터를 실제 디스패처로 교체하고 동일한 네 가지 임계값(thresholds)을 유지하면, 의견 대신 측정값을 얻게 됩니다.
장애 처리 및 롤백 (Rollback)
- 단계 1, 섀도우(shadow): 메트릭을 계산하고
lane_mode를 기록하며, 아무것도 변경하지 않습니다.
- 단계 2, 게이트(gate): 오직
split만 강제합니다. 절대 freeze로 시작하지 마십시오.
- 단계 3, 프리즈(freeze): 새로운 입력을 거부하고, 대기열을 비우고, 배치 소유자에게 알립니다.
- 롤백(Rollback): 게이트 플래그를 해제하고, 이전 디스패처 이미지를 복원하며, 사후 분석(postmortem)을 위해 JSONL 파일을 보관합니다.
- 정리(Cleanup):
slot_ledger.jsonl을 매일 순환시키고, 7일보다 오래된 라인을 삭제하며, 실제 원장이 도착하면 테스트 파일을 삭제합니다.
환경 변수 하나를 일종의 '킬 스위치(kill switch)'로 사용하십시오. 오전 3시에 찾을 수 없는 킬 스위치는 진정한 킬 스위치가 아닙니다.
이 방식으로 작업을 라우팅해서는 안 되는 경우
- 계약상 p99가 엄격한 서비스 수준 목표(SLO)를 가진 팀. 대기열 시간은 협상의 여지가 없습니다.
- 컴퓨트 호스트에서 데이터 거주지 또는 감사 추적(audit-trail) 요구 사항이 있는 워크로드.
- 대규모 아티팩트 외부 전송(egress)이 발생하는 배치. 슬롯 회계가 대역폭 문제로부터 당신을 구해주지 못할 것입니다.
- Idempotent하게 만들 수 없는 작업. 먼저 쓰기 경로(write path)를 수정하거나, 재시도(retries)가 기록을 중복 생성할 것입니다.
마감 기한 여유 시간이 관찰된 p90 대기 시간의 2배 미만이라면, 무료 용량은 단순히 잘못된 선택입니다. 레인에 비용을 지불하거나, 배치를 축소하십시오.
마이그레이션부터가 아니라 원장(ledger)부터 시작하세요. 이 실습을 처음부터 끝까지 실행하고 싶다면, 무료 모델 접근과 무료 서버 옵션만으로도 첫 40개 행을 수집하기에 충분합니다.