किस सेवा की सीमाएँ हैं
नामों में भ्रम हो सकता है। Groq एक कंपनी है जो अपने हार्डवेयर पर मॉडल होस्ट करती है। Grok xAI से मॉडल परिवार है। यह साइट न Groq है, न Grok: यह एक ओपन-वेट मॉडल (मॉडल ID uncensored) के लिए एक OpenAI-कम्पैटिबल API है, जो एक स्वतंत्र प्रदाता द्वारा चलाया जाता है। इसलिए groq api रेट लिमिट के बारे में, जैसे किसी दिए गए प्लान पर प्रति मिनट अनुरोध या टोकन, Groq की कंसोल या दस्तावेज़ खोलें और अपने खाते के लिए संख्याएँ पढ़ें। वे बदलते रहते हैं, और मैं अनुमान नहीं लगाऊँगा।
जो आगे है वह हमारी API के लिए सटीक है, और आदतें किसी भी प्रदाता पर लागू होती हैं: सीमा हेडर का सम्मान करें, केवल सही त्रुटियों पर पुनः प्रयास करें, और सर्वर के लिए इसे करने से पहले अपनी कन्करेंसी को सीमित करें। यदि आप Grok NSFW सेटअप के लिए आए हैं, तो हमारी इंटीग्रेशन गाइड आसपास की त्रुटियों को भी कवर करती है।
सीमाएँ एक नज़र में
| सीमा | पूर्ण कुंजी | ट्रायल कुंजी |
|---|---|---|
| समानांतर अनुरोध | 8 | 2 |
| प्रति मिनट अनुरोध | 300 | 60 |
| अनुरोध बॉडी | 8 MB | 8 MB |
| कॉन्टेक्स्ट विंडो (प्रॉम्प्ट और प्रतिक्रिया) | 100,000 टोकन | 100,000 टोकन |
इनमें से दो दर सीमाएँ (rate limits) हैं, प्रति मिनट अनुरोध और समानांतर अनुरोध। शेष दो एकल अनुरोध के आकार की सीमाएँ हैं, जो दर सीमाओं से स्वतंत्र हैं। 90,000-टोकन वाले प्रॉम्प्ट वाला एक अनुरोध 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 पढ़ता है, और अन्यथा थोड़े जिटर (jitter) के साथ बैकऑफ करता है। यह आधिकारिक 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 लंबित प्रॉमिसेस की अनुमति देता है, और नीचे curl जाँच सीमा हेडर प्रिंट करती है ताकि आप अपनी कुंजी की ऊपरी सीमाओं की पुष्टि कर सकें:
curl -s -D - -o /dev/null https://api.groknsfw.top/v1/models \
-H "Authorization: Bearer YOUR_KEY" | grep -i "x-"स्ट्रीमिंग, लंबे प्रॉम्प्ट और कॉन्टेक्स्ट
stream: true वाले स्ट्रीम किए गए अनुरोध में समानांतर अनुरोध का स्लॉट अंतिम घटना (event) आने तक बना रहता है। इसका अर्थ है कि एक धीमी रीडर आपके खिलाफ गिना जाता है: यदि आपका कोड प्रत्येक चंक को संभालते समय रुक जाता है, तो स्लॉट व्यस्त रहता है। स्ट्रीम को शीघ्रता से पढ़ें।
लंबे प्रॉम्प्ट सीमाओं के साथ दो तरीकों से प्रभाव डालते हैं। पहला, उन्हें प्रोसेस करने में अधिक समय लगता है, इसलिए वे ऊपर दिए गए सूत्र द्वारा आपकी थ्रूपुट को कम करते हैं। दूसरा, उन्हें प्रतिक्रिया के साथ मिलकर 100,000-टोकन विंडो में फिट होना चाहिए, इसलिए एक सुरक्षा मार्जिन बनाए रखें। पुराने संवाद के टर्न्स को काटने से दोनों समस्याओं में मदद मिलती है, और उसी कटौती से आपका बिल भी कम होता है: 1M इनपुट टोकन प्रति $0.15 पर, 20,000-टोकन का इतिहास हर बार भेजने पर $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 रिप्लाइज पूरा कर सकते हैं।
बैच जॉब्स के लिए, अपने कॉन्करेंसी लिमिट के बराबर एक फिक्स्ड वर्कर पूल चलाएं और रेट्राइ लॉजिक को कभी-कभी ओवरलोड हैंडल करने दें। सीमाओं के आसपास काम करने के बजाय, क्यू बनाएं: यह आपको भविष्यवाणी योग्य व्यवहार देता है और आपको अपने उपयोगकर्ताओं को वास्तविक इंतज़ार समय दिखाने की अनुमति देता है।
