버리고 간 무료 모델 호출은 공짜가 아닙니다. 이미 큐(queue)를 소모했고, 소켓을 끊기 전 서버가 방출한 토큰도 이미 소모했습니다. 재시도하기 전에 이 부분 사용량(partial)을 비용 처리하세요. 그렇지 않으면, 절약하는 것처럼 보이지만 실제로는 몇 분 동안 청구되는 루프를 돌리게 됩니다.
이 문제는 공유 무료 서버가 느리고 클라이언트가 낙관적일 때 발생합니다. 첫 번째 시도는 수백 개의 토큰을 스트리밍하고, 그러다 약속했던 마감 시간이 지나서 취소하고 동일한 프롬프트를 다시 보냅니다. 두 번째 시도는 실제로 풀(pool)에서 가져오지 않은 작업 뒤에 대기하게 됩니다. 소켓을 닫는다고 해서 토큰 미터기의 '0원' 가격이 그 큐를 되돌려주지는 않습니다.
그것은 단지 여전히 무료라고 표시되는 대시보드 안에서 기다림을 숨길 뿐입니다. 재시도 문제는 개발자 논의에서 다시 활발하게 다루어지고 있습니다. 이것을 HTTP 클라이언트가 처한 '기분' 문제가 아니라, 장부(ledger) 문제로 취급해야 합니다.
무료로 야간 작업을 받는 인쇄소를 상상해 보세요. 당신이 한 챕터를 제출하면, 그들은 세 페이지에 맞춰 활자를 세팅합니다. 그러다 수령 시간이 변경되어 당신이 취소합니다. 그 페이지들은 작업대 위에 남아 있습니다. 챕터를 다시 제출하는 것은 첫 번째 작업 뒤에 두 번째 작업을 추가할 뿐입니다.
기록해야 할 것들
작업마다 세 가지 숫자를 유지하고, 매번 시도 후 업데이트하세요. spent_s는 이미 기다린 큐와 생성량(generation)을 합친 것입니다. spent_tokens는 부분 사용량을 포함하여 돌아온 모든 토큰입니다. ceiling_tokens는 공급업체의 할당량이 아니라 이 작업에 대해 당신이 설정한 상한선입니다.
상한선은 무료 레인이 당신의 프로세스 내부에서 무한 루프를 의미할 수 없도록 존재합니다. 해당 레인에서의 재시도는 다음 시도가 남은 마감 시간 내에 완료될 수 있고, 소모된 토큰과 최악의 경우 예상치를 더해도 상한선을 초과하지 않을 때만 허용됩니다. 그렇지 않으면 깨끗한 한 번의 시도를 위해 유료 레인으로 전환하거나, 멈추고 가지고 있는 것을 반환해야 합니다.
중단(Stopping)은 결과입니다. 또 다른 희망적인 enqueue는 그렇지 않습니다. 첫 번째 호출 시 빈 시도 목록을 전달하여, 부분적인 상태가 되기 전에 해당 함수가 허용하거나 거부하도록 하고 두 가지 정책을 유지하지 않도록 하세요.
여기서 제시된 수치들은 이번 주에 측정한 타이밍으로 대체해야 하는 자리 표시자입니다. 여기의 어떤 것도 공개 풀(public pool)의 측정값, 가격 목록, 또는 다음 월요일에도 여전히 유효할 제한 사항이 아닙니다. 만약 숫자가 마지막 샘플보다 오래되었다면, 이미 잘못된 입력 값입니다.
실행 가능한 원장 (A ledger you can run)
스크립트를 book_partial.py로 저장하세요. 이것은 특정 공급업체의 클라이언트가 아니라 로컬 의사 결정 도우미이며 소켓을 열지 않습니다. 여기에 히스토리를 입력하면 액션(action)을 반환합니다.
#!/usr/bin/env python3
"""재시도하기 전에 부분적인 무료 슬롯 시도를 기록하세요."""
...
첫 번째 예시는 넓은 시간 창을 가진 야간 작업(night job)입니다. 부분적인 결과가 하나 나왔고, 배포된 것은 없으며, 스스로 설정한 상한선 아래에 여전히 공간이 있습니다.
python3 book_partial.py <<'EOF'
{
"attempts": [
...
retry_free가 표시되는 것을 볼 수 있을 것입니다. 소모된 시간은 44초이고, 남은 창(window)은 넓으며, 220에 추정치인 800을 더해도 4000 이하를 유지합니다. 달러 필드는 그림자 가격(shadow price)이므로 부분적인 상태가 기록에 계속 표시됩니다. 이것은 청구서(invoice)가 아니며, 이 비율(rate)은 반드시 대체해야 하는 임시 값입니다.
현재 지불된 요율을 모른다면, paid_usd_per_1k를 0으로 설정하고 시간과 토큰만으로 결정하세요. 오래된 스레드에서 복사한 진부한 가격(stale price)은 증거처럼 보이기 때문에 0보다 더 나쁩니다.
이제 대화형 사례입니다. 동일한 부분적인 결과, 60초의 마감 시간, 그리고 동일한 다음 추정치입니다. 야간 작업과 인라인 작업(inline job)은 프롬프트가 공유되더라도 같은 베팅이 아닙니다.
python3 book_partial.py <<'EOF'
{
"attempts": [
...
남은 시간은 16초입니다. 다음 무료 시도는 47을 요구합니다. 유료 시도는 14를 요구하며, 이는 여전히 적합하므로 액션은 cut_over입니다. 무료 서버는 해당 브랜치에서 나쁜 제품이 되지 않았습니다. 남은 클럭이 더 이상 당신이 앉게 될 대기열과 일치하지 않을 뿐입니다.
프로젝션 아래의 천장을 낮추면, 마감 기한(deadline)이 충분히 넓더라도 같은 함수는 재시도하는 대신 멈춥니다. 세 번째 테스트 케이스를 실행하고 그것에 대해 논쟁하기 전에 액션을 읽어보세요.
python3 book_partial.py <<'EOF'
{
"attempts": [
...
브랜치 고정하기 (Pin the branches)
세 개의 브랜치가 수식을 편집하는 동안 표류하지 않도록 작은 단언(assertion)을 연결하세요. 이것은 로컬 테스트입니다. 네트워크에 영향을 주지 않으며, 예상되는 액션을 업데이트하지 않고 검사 순서를 재배열하면 실패합니다.
python3 - <<'PY'
import importlib.util
...
파일을 저장한 디렉토리에서 그것을 실행한 다음, cut-over 케이스 옆에 있는 마지막 단언을 읽어보세요. 빡빡한 마감 기한과 터진 천장 모두 멈추고, 천장 검사가 먼저 실행되기 때문에 cut-over보다 멈춤(stop)이 우세합니다. 무료 경로가 이미 부분 사용량을 소모했다면 한 번 비용을 지불하는 것을 선호한다면, 해당 브랜치를 교체하고 실제로 원하는 정책과 일치할 때까지 테스트를 다시 실행하세요. 스스로 재시도하는 클라이언트는 어느 순서도 준수하지 않으므로, 그것을 끄거나 루프가 이미 실행된 후에 당신이 이야기하는 원장(ledger)으로 만드세요.
앉게 될 대기열 샘플링하기 (Sample the queue you will sit in)
next_queue_s를 신뢰하기 전에, 실제로 실행할 시간대에 샘플을 받아보세요. 무료 레인에서 짧고 고정된 프롬프트를 보내 첫 토큰까지의 시간을 대기열(queue)로 기록하고, 나머지를 생성(generation)으로 기록하세요. 이것을 세 번 수행하여 최악의 대기열 시간을 유지하고 프로브 텍스트는 버리세요. 만약 프로브가 실패하면, 그 레인은 이번 시간대에 적격하지 않습니다.
프로브가 괜찮다고 느껴질 때까지 재시도하지 마세요. 이 루프가 원장이 멈추도록 의도된 것입니다. 아래 명령어는 벤치마크나 공급업체 호출이 아닌 임시 타이머입니다. sleep을 자체 클라이언트로 교체한 다음, 최악의 샘플을 정책에 넣으세요.
여전히 무료로 사용할 수 있는 공간
공개: 이 글은 MonkeyCode의 제품 홍보의 일환으로 작성되었습니다. MonkeyCode는 이 워크플로우에서 오직 넘치는 공간(spill lane)으로서만 속합니다. 즉, 이미 원장(ledger)이 retry_free로 표시한 작업을 위해 제공되는 무료 모델 접근 및 무료 서버 옵션입니다. 이 페이지는 모델 이름, 토큰 할당량, 하드웨어 또는 각 옵션의 지속 기간을 명시하지 않는데, 이러한 사실들은 변하기 때문에 게시물에 고정할 수 없기 때문입니다. 여전히 그 넘치는 공간이 필요하다면, 실시간 제한 사항을 읽고 의존하게 될 값들을 ceiling_tokens와 next_queue_s에 복사한 다음, 샘플이 변경될 때마다 이 단언(assertion)을 다시 실행하십시오.
개방된 용량은 사람이 답변에서 막혔거나, 포기할 시도가 멱등적이지 않거나 (not idempotent), 또는 큐 대기 시간(queue time)을 샘플링할 수 없어 next_queue_s에 소망을 입력해야 할 때 잘못된 베팅입니다. 또한 재시도할 경우 부작용을 두 배로 적용할 수 있으므로 잘못된 베팅이기도 합니다. 왜냐하면 토큰 예약은 두 번째 쓰기(write)를 취소하지 못하기 때문입니다. 첫 호출 전에 작업에 자체 멱등성 키(idempotency key)를 찍으십시오. shipped: true를 최종적인 것으로 간주하여, 나중에 오는 무료 응답이 이미 반환한 유료 답변을 덮어쓰지 못하게 하십시오.
이것이 빠뜨리는 것들
이 함수는 사용자의 샘플을 신뢰합니다. 조용한 오후 한때가 일주일은 아니므로, 만약 큐가 변동한다면 실행하는 시간의 최악의 샘플을 유지하고 그 숫자를 next_queue_s에 넣으십시오. 또한 방출되는 모든 토큰을 소모된 것으로 간주하는데, 이는 최고치(ceiling)에는 올바른 편향이지만 품질 점수(quality score)에는 잘못된 편향입니다. 재개할 수 있는 부분적인 결과물은 버려야 하는 부분적인 결과물과 같은 모양이 아닙니다.
클라이언트가 연속 사용을 지원하는 경우, 누락된 간격만 투영에 추가한 다음, 새로운 편향(bias)이 테스트했던 것이 되도록 단언문을 다시 실행하세요. 결제, 접근 제어 또는 '중지'가 허용 가능한 결과가 아니며 계약된 대체 경로가 없는 모든 경로는 여기에 사용하지 마세요. 팀의 용량 예측으로도 사용하지 마세요. 이 기능은 하나의 작업 기록만 남기므로, 한 시간 정각에 무료 서버가 모두를 수용할 수 있을지 알려주지는 않을 것입니다.
대시보드가 호출이 무료였고 부분적인 양이 적어 보였다는 이유로 쓰기 취소(write-off) 단계를 건너뛰고 싶을 겁니다. 그래도 기록하세요. 다음 재시도 과정이야말로 무료 통행료가 끝없이 이어지는 대기열로 변하는 곳입니다.