限制屬於哪個服務
名稱容易混淆。Groq 是一家在其自有硬體上託管模型的公司。Grok 是 xAI 的模型系列。此網站兩者皆非:它是單一開放權重模型(模型 ID 為 uncensored)的 OpenAI 相容 API,由獨立供應商運行。因此,若要了解 groq api rate limit(例如每分鐘請求數或 token 數),請開啟 Groq 控制台或文件查看您帳戶的數字。這些數字會變動,我不會猜測。
以下內容完全適用於我們的 API,且這些習慣可套用於任何供應商:尊重限制標頭、僅在正確錯誤時重試,並在伺服器強制執行前限制您自己的並行請求數。如果您是來尋找 Grok NSFW 設定,我們的 整合指南也涵蓋了相關錯誤。
限制一覽
| 限制 | 完整金鑰 | 試用金鑰 |
|---|---|---|
| 並行請求 | 8 | 2 |
| 每分鐘請求數 | 300 | 60 |
| 請求主體 | 8 MB | 8 MB |
| 上下文視窗(提示詞加補全) | 100,000 token | 100,000 token |
其中有兩項是嚴格意義上的速率限制,即每分鐘請求數與並行請求數。另外兩項則是單一請求的大小限制,且與速率限制獨立。一個帶有 90,000 token 提示詞的請求,在每分鐘 300 次的限制下僅計為一個請求,與單行提示詞相同,但處理時間較長且佔用槽位較久。
$0.50 的試用額度可在註冊後於 API 金鑰頁面 一鍵領取,並使用試用限制。完整金鑰的限制在您完成儲值後適用。
三種 429 錯誤
所有限制錯誤均以 HTTP 429 形式出現,但含義不同,需採取不同應對措施。
rate_limited:你發送的請求超過了每分鐘的配額。放慢速度;視窗為一分鐘,因此均勻間隔請求比長時間暫停更有效。concurrency:同時進行中的請求過多。請等待較早的請求完成。這在串流輸出中很常見,因為每個請求會持續到整個生成過程結束。- 暫時過載:也是 429,帶有
Retry-After: 5標頭。這不是您的錯,也不與您金鑰的限制相關。等待指定的 5 秒後重試。
失敗的請求不會計費,因此重試迴圈的成本僅是最終成功的那個請求。回應也會包含 X-RateLimit-Limit-Requests 和 X-RateLimit-Limit-Concurrency,讓你的客戶端能讀取自身的限制上限,而非硬編碼這些值,此外還有 X-Balance-USD 顯示剩餘額度,以及 X-Request-Id,你應該將其記錄下來,並在聯繫 技術支援 時提供。
吞吐量計算:為何每分鐘 300 次難以達到
這兩個限制會相互影響。擁有 8 個並行槽位時,每分鐘最多可完成的請求數為 8 x 60 除以請求平均持續時間(秒)。要實際達到每分鐘 300 次請求,您需要請求的平均完成時間為 8 x 60 / 300 = 1.6 秒。較慢的請求會先受到並行限制。
| 平均請求時間 | 完整金鑰每分鐘最大數量(8 個槽位) | 試用金鑰每分鐘最大數量(2 個槽位) |
|---|---|---|
| 2 秒 | 240 | 60 |
| 10 秒 | 48 | 12 |
| 20 秒 | 24 | 6 |
這些是針對假想請求耗時的算術上限,並非對我們服務的測量;請測量你自己的請求。重點在於,使用完整金鑰進行 20 秒的長篇創作生成,每分鐘最多只能發送 24 個請求,遠低於允許的 300 個。如果你需要更高的吞吐量,請使用 max_tokens 縮短回覆,或在每次呼叫時要求較少的文字,而不是期望提高請求限制。
處理所有三種情況的客戶端
此 Python 客戶端使用訊號量限制其並行請求數,讀取 Retry-After(若存在),否則以微小抖動退避。它使用官方的 openai 套件。
import random
import threading
import time
from concurrent.futures import ThreadPoolExecutor
from openai import OpenAI, RateLimitError
client = OpenAI(
base_url="https://api.groknsfw.top/v1",
api_key="YOUR_KEY",
max_retries=0, # we handle retries ourselves
)
slots = threading.BoundedSemaphore(8) # use 2 on the trial key
def ask(prompt, tries=6):
for attempt in range(tries):
with slots:
try:
r = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": prompt}],
max_tokens=400,
)
return r.choices[0].message.content
except RateLimitError as e:
wait = e.response.headers.get("retry-after")
body = e.response.text
# sleep outside the slot so others can proceed
delay = float(wait) if wait else min(2 ** attempt, 30)
if "rate_limited" in body:
delay = max(delay, 5)
time.sleep(delay + random.random())
raise RuntimeError("still rate limited after retries")
with ThreadPoolExecutor(max_workers=8) as pool:
results = list(pool.map(ask, ["Write one line about the sea."] * 20))
print(len(results))
Node 中的相同概念是一個小型佇列,最多允許 8 個待處理的 promise,下方的 curl 檢查會列印限制標頭,以便你確認金鑰的上限:
curl -s -D - -o /dev/null https://api.groknsfw.top/v1/models \
-H "Authorization: Bearer YOUR_KEY" | grep -i "x-"串流輸出、長提示詞與上下文
帶有 stream: true 的串流請求會保留其並行槽位,直到最後一個事件到達。這意味著慢速讀取者會佔用你的資源:如果你的程式碼在處理每個區塊時暫停,該槽位就會保持忙碌。請盡快消耗串流。
長提示詞會以兩種方式與限制產生交互作用。首先,它們處理時間較長,因此會透過上述公式降低你的吞吐量。其次,它們必須與回覆一起放入 100,000 token 的上下文視窗中,因此請保留餘裕。修剪舊的對話輪次有助於解決這兩個問題,同時也能減少你的帳單:每 1M 個輸入 token 費用為 $0.15,20,000 token 的歷史記錄每次重傳時費用為 $0.003。
向您的用戶顯示限制
速率限制也是一項產品決策。如果您的應用程式位於最終用戶與 API 之間,原始的 429 錯誤不應直接顯示給他們。請事先決定他們看到的內容。
- 對於聊天應用程式,顯示短暫的「正在撰寫」狀態並排隊訊息。如果螢幕上有動作,幾秒鐘的等待對大多數用戶來說是不可見的。
- 對於批次工具,以已完成項目的計數顯示進度,讓作業在背景運行。重試是內部行為,不應顯示為錯誤。
- 對於共享部署,在您的程式碼中為每個用戶分配少量每人配額,以防止單一重度用戶佔用所有 8 個槽位。
針對每次失敗記錄三件事:X-Request-Id、錯誤代碼,以及當時你的應用程式有多少請求正在執行中。有了這些資訊,你可以在幾分鐘內區分是客戶端行為異常還是真正的流量負載。如果問題看起來是伺服器端造成的,請求 ID 就是 技術支援 會首先要求提供的資訊。
最後,故意測試失敗路徑。以故意低的訊號量運行您的客戶端,然後以高的訊號量運行,並觀察日誌顯示的內容。從未觸發的重試迴圈是一個您無法信任的重試迴圈。試用金鑰是進行此測試的方便場所,因為僅有 2 個並行請求,使用短腳本很容易觸發 concurrency 錯誤,並觀察程式碼的反應,每次請求成本僅幾分之一美分。
常見錯誤
少數幾種模式導致了大多數人報告的 429 問題。
- 立即重試。 一個在每次失敗時都重傳的迴圈,會將一次超限時的情況變成風暴。請等待、加入抖動(jitter),並限制重試次數。
- 重試所有請求。 只有 429 和暫時性伺服器錯誤值得重試。格式錯誤的請求或錯誤的金鑰每次都會以相同的方式失敗。
- 忘記將串流輸出計入數量。 完整金鑰上的十個開啟的聊天視窗可能是十個串流輸出,這比 8 個槽位多兩個。
- 未設定超時。 掛起的連接會佔用槽位。請在您的 HTTP 客戶端中為每個請求設定合理的超時時間。
- 以平均值為規模。 流量以突發形式出現。請為最繁忙的一分鐘做規劃,而非每日平均值。
在發布前規劃容量
從你的峰值倒推。如果你預期有 30 個使用者同時聊天,且每個回覆串流輸出約需 15 秒,則在他們同時發送時你需要 30 個槽位,而完整金鑰僅有 8 個。將其餘請求在你的應用程式中排隊,顯示短暫等待,並在槽位釋放時處理它們。擁有 8 個槽位和 15 秒的回覆,你每分鐘可以完成 8 x 60 / 15 = 32 個回覆。
對於批次作業,運行等於您的並行限制的固定工作池,讓重試邏輯處理偶爾的過載。與其繞過限制,不如建立佇列:這會提供可預測的行為,並讓您向用戶顯示實際等待時間。
