paint-brush
ओपनएआई की दर सीमा: एलएलएम मूल्यांकन के लिए घातीय बैकऑफ़ के लिए एक गाइडद्वारा@abram
2,068 रीडिंग
2,068 रीडिंग

ओपनएआई की दर सीमा: एलएलएम मूल्यांकन के लिए घातीय बैकऑफ़ के लिए एक गाइड

द्वारा Abram11m2024/01/29
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

यह आलेख आपको सिखाएगा कि खतरनाक "ओपनएआई रेट लिमिट" अपवाद के आगे झुके बिना किसी भी एलएलएम मॉडल का उपयोग करके मूल्यांकन कैसे चलाया जाए। हम इससे शुरुआत करेंगे: - परिभाषित करना कि दर-सीमा का क्या अर्थ है और एक सादृश्य का उपयोग करना - यह समझना कि OpenAI दर-सीमाएँ क्या हैं - यह समझाते हुए कि दर-सीमा प्रक्रिया कैसे विकसित की गई - संहिता कार्यान्वयन की व्याख्या करना
featured image - ओपनएआई की दर सीमा: एलएलएम मूल्यांकन के लिए घातीय बैकऑफ़ के लिए एक गाइड
Abram HackerNoon profile picture
0-item
1-item


परिचय

यह आलेख आपको सिखाएगा कि खतरनाक "ओपनएआई रेट लिमिट" अपवाद के आगे झुके बिना किसी भी एलएलएम मॉडल का उपयोग करके मूल्यांकन कैसे चलाया जाए। हम इससे शुरुआत करेंगे:


  • यह परिभाषित करना कि दर-सीमा का क्या अर्थ है और एक सादृश्य का उपयोग करना
  • यह समझना कि OpenAI दर-सीमाएँ क्या हैं
  • यह समझाते हुए कि दर-सीमा प्रक्रिया कैसे विकसित की गई
  • संहिता कार्यान्वयन की व्याख्या करना
  • संहिता कार्यान्वयन में प्रयुक्त रणनीति का सारांश


दर-सीमित (और सादृश्य स्पष्टीकरण) क्या है?

अब तक, क्लाउडफ़ेयर स्पष्टीकरण सबसे अच्छा है जो मैंने देखा है: दर-सीमित करना नेटवर्क ट्रैफ़िक को सीमित करने की एक रणनीति है। यह इस पर एक सीमा लगाता है कि कोई व्यक्ति एक निश्चित समय-सीमा के भीतर कितनी बार किसी कार्रवाई को दोहरा सकता है - उदाहरण के लिए, किसी खाते में लॉग इन करने का प्रयास करना।


सीधे शब्दों में कहें तो, ऐसे चार बच्चों की माँ होने की कल्पना करें जिन्हें शहद बहुत पसंद है। पिछली बार, शहद उम्मीद से जल्दी ख़त्म हो गया। अब, आपने दस हजार तक गिनती करने के लिए एक टाइमर सेट कर दिया है और प्रत्येक बच्चे को कुछ शहद लेने की बारी दी है। टाइमर दर-सीमा का प्रतिनिधित्व करता है, क्योंकि यह अधिक शहद प्राप्त करने से पहले एक विशिष्ट प्रतीक्षा समय लागू करता है।


अवधारणा को समझाने के बाद, आइए ओपनएआई दर-सीमा को समझें और चर्चा करें कि मैंने पायथन का उपयोग करके ओपनएआई के आर/टीपीएम (प्रति मिनट अनुरोध/टोकन) को प्रबंधित करने के लिए दर-सीमा तर्क कैसे लागू किया।


OpenAI दर सीमा को समझना

ओपनएआई ने एक मिनट के भीतर अपने एआई मॉडल के लिए किए जा सकने वाले अनुरोधों की संख्या पर कुछ प्रतिबंध लगाए हैं। OpenAI द्वारा प्रदान किए गए प्रत्येक AI मॉडल के लिए ये सीमाएँ अलग-अलग हैं।


मुफ़्त संस्करण के लिए:

  • जीपीटी-3.5-टर्बो मॉडल के लिए, उपयोगकर्ता प्रति दिन 40,000 टोकन अनुरोध या प्रति मिनट 3 एपीआई कॉल कर सकते हैं।


टियर 1 के लिए:

  • जीपीटी-3.5-टर्बो मॉडल के लिए, उपयोगकर्ताओं को प्रति मिनट 60,000 टोकन अनुरोध या 3,500 एपीआई कॉल की अनुमति है।
  • जीपीटी-4 मॉडल के लिए, सीमा 10,000 टोकन अनुरोध या 500 एपीआई कॉल प्रति मिनट है।
  • जीपीटी-4-टर्बो-पूर्वावलोकन के लिए, उपयोगकर्ता प्रति मिनट 150,000 टोकन अनुरोध या 500 एपीआई कॉल कर सकते हैं।
  • जीपीटी-4-विज़न-पूर्वावलोकन के लिए, उपयोगकर्ता प्रति मिनट 10,000 टोकन अनुरोध और/या 500 एपीआई कॉल कर सकते हैं।


अन्य स्तरों की दर-सीमाओं के बारे में अधिक जानकारी के लिए दस्तावेज़ देखें..


इन प्रतिबंधों के कारणों में शामिल हैं:

  1. यह सुनिश्चित करना कि सेवाएँ सुचारू और प्रतिक्रियात्मक रूप से चलें, क्योंकि एआई मॉडल द्वारा किए जाने वाले जटिल कार्यों के लिए पर्याप्त संसाधनों की आवश्यकता होती है।
  2. सभी उपयोगकर्ताओं की मांग को प्रबंधित करना और यह सुनिश्चित करना कि उपलब्ध बुनियादी ढांचा, जैसे कि उनके सर्वर और जीपीयू, अतिभारित हुए बिना अनुरोधों को संभाल सकें।
  3. उपयोग में वृद्धि के लिए तैयारी करना और उच्च मांग के तहत कुशल संचालन बनाए रखना।


निकट भविष्य में इन सीमाओं के सुसंगत बने रहने की उम्मीद है।


दर-सीमा प्रक्रिया की व्याख्या करना

प्रक्रिया (नीचे छवि देखें) में उपयोगकर्ताओं को यूआई से एलएलएम मूल्यांकन चलाने और तर्क लिखने की आवश्यकता के बिना अपने एलएलएम ऐप्स के लिए दर-सीमा पैरामीटर कॉन्फ़िगर करने में सक्षम बनाना शामिल है।


यह एक फ़ंक्शन के माध्यम से हासिल किया जाता है जो बैच को तैयार करता है और आमंत्रित करता है। बैच में प्रत्येक कॉल run_with_retry फ़ंक्शन को आमंत्रित करती है, जो बदले में पुनः प्रयास तंत्र के साथ अंतिम फ़ंक्शन ( invoke_app ) को आमंत्रित करती है।


Agenta.ai पर बैच बैकऑफ़ घातीय रणनीति का उपयोग करके एलएलएम मूल्यांकन के मूल्यांकन के लिए दर-सीमा प्रक्रिया


मुझे विश्वास है कि उपरोक्त प्रक्रिया को देखने के बाद आप अपनी पसंद की किसी भी भाषा में कोड-लॉजिक लिख सकते हैं। बहरहाल, मैं तुम्हें दिखाऊंगा कि मैंने अपना काम कैसे किया। अधिक पृष्ठभूमि और संदर्भ के लिए, मैं मुख्य रूप से एजेंटा में बैकएंड सॉफ्टवेयर इंजीनियर के रूप में काम करता हूं।


एजेंटा एक ओपन-सोर्स एंड-टू-एंड एलएलएम डेवलपर प्लेटफ़ॉर्म है जो आपको त्वरित इंजीनियरिंग और प्रबंधन, ⚖️ मूल्यांकन, मानव एनोटेशन और 🚀 परिनियोजन के लिए उपकरण प्रदान करता है। यह सब आपकी पसंद की रूपरेखा, लाइब्रेरी या मॉडल पर कोई प्रतिबंध लगाए बिना। एजेंटा डेवलपर्स और उत्पाद टीमों को कम समय में उत्पादन-ग्रेड एलएलएम-संचालित अनुप्रयोगों के निर्माण में सहयोग करने की अनुमति देता है।


हम उपयोगकर्ताओं को यूआई से अपने एलएलएम मूल्यांकन दर-सीमित कॉन्फ़िगरेशन को कॉन्फ़िगर करने की क्षमता देना चाहते थे ताकि वे अपने एलएलएम प्रदाता दर-सीमित अपवाद को बायपास कर सकें।

Agenta.ai पर नया मूल्यांकन बनाने के लिए यूआई (उपयोगकर्ता-इंटरफ़ेस)।


प्रक्रिया आरेख को देखते हुए, लागू करने वाली पहली चीज़ बैच (एलएलएम कॉल के) को तैयार करने और लागू करने का तर्क है। एलएलएम रन रेट सीमा को परिभाषित करने के लिए दर सीमा कॉन्फ़िगरेशन को सत्यापित करना और डेटा सत्यापन मॉडल का उपयोग करना महत्वपूर्ण है। नीचे दिया गया मॉडल बैच के कार्य करने के लिए आवश्यक rate_limit_config पैरामीटर को संभालता है।


 from pydantic import BaseModel, Field class LLMRunRateLimit(BaseModel): batch_size: int = Field(default=10) max_retries: int = Field(default=3) retry_delay: int = Field(default=3) delay_between_batches: int = Field(default=5)


batch_invoke फ़ंक्शन निम्नलिखित पैरामीटर लेता है:

  • यूरी: आपके एलएलएम आवेदन का यूआरएल।
  • testset_data: वह टेस्टसेट डेटा जिसे आपके LLM एप्लिकेशन को संसाधित करने की आवश्यकता है।
  • पैरामीटर: आपके एलएलएम आवेदन के लिए पैरामीटर।
  • रेट_लिमिट_कॉन्फिग: दर सीमा कॉन्फ़िगरेशन (जैसा कि नया मूल्यांकन बनाने के लिए उपरोक्त इंटरफ़ेस में देखा गया है)।


 async def batch_invoke( uri: str, testset_data: List[Dict], parameters: Dict, rate_limit_config: Dict ) -> List[AppOutput]: """ Invokes the LLm app in batches, processing the testset data. Args: uri (str): The URI of the LLm app. testset_data (List[Dict]): The testset data to be processed. parameters (Dict): The parameters for the LLm app. rate_limit_config (Dict): The rate limit configuration. Returns: List[AppOutput]: The list of app outputs after running all batches. """ batch_size = rate_limit_config[ "batch_size" ] # Number of testset to make in each batch max_retries = rate_limit_config[ "max_retries" ] # Maximum number of times to retry the failed llm call retry_delay = rate_limit_config[ "retry_delay" ] # Delay before retrying the failed llm call (in seconds) delay_between_batches = rate_limit_config[ "delay_between_batches" ] # Delay between batches (in seconds) list_of_app_outputs: List[AppOutput] = [] # Outputs after running all batches openapi_parameters = await get_parameters_from_openapi(uri + "/openapi.json") async def run_batch(start_idx: int): print(f"Preparing {start_idx} batch...") end_idx = min(start_idx + batch_size, len(testset_data)) for index in range(start_idx, end_idx): try: batch_output: AppOutput = await run_with_retry( uri, testset_data[index], parameters, max_retries, retry_delay, openapi_parameters, ) list_of_app_outputs.append(batch_output) print(f"Adding outputs to batch {start_idx}") except Exception as exc: import traceback traceback.print_exc() print( f"Error processing batch[{start_idx}]:[{end_idx}] ==> {str(exc)}" ) # Schedule the next batch with a delay next_batch_start_idx = end_idx if next_batch_start_idx < len(testset_data): await asyncio.sleep(delay_between_batches) await run_batch(next_batch_start_idx) # Start the first batch await run_batch(0) return list_of_app_outputs


बैच को तैयार करने और लागू करने के बाद, अगले चरण में run_with_retry तर्क को निष्पादित करना शामिल है। इस कस्टम कार्यान्वयन में दर-सीमित कार्यक्षमता शामिल है और एलएलएम ऐप के आह्वान का प्रबंधन करता है, सेट विलंब तक पहुंचने के बाद पुनः प्रयास करता है। एक्सपोनेंशियल बैकऑफ़, एक ऐसी तकनीक जो तेजी से बढ़ते प्रतीक्षा-समय के साथ एक ऑपरेशन का पुन: प्रयास करती है, अधिकतम पुनर्प्रयास गिनती तक पहुंचने तक नियोजित होती है।


 async def run_with_retry( uri: str, input_data: Any, parameters: Dict, max_retry_count: int, retry_delay: int, openapi_parameters: List[Dict], ) -> AppOutput: """ Runs the specified app with retry mechanism. Args: uri (str): The URI of the app. input_data (Any): The input data for the app. parameters (Dict): The parameters for the app. max_retry_count (int): The maximum number of retries. retry_delay (int): The delay between retries in seconds. openapi_parameters (List[Dict]): The OpenAPI parameters for the app. Returns: AppOutput: The output of the app. """ retries = 0 last_exception = None while retries < max_retry_count: try: result = await invoke_app(uri, input_data, parameters, openapi_parameters) return result except (httpx.TimeoutException, httpx.ConnectTimeout, httpx.ConnectError) as e: last_exception = e print(f"Error in evaluation. Retrying in {retry_delay} seconds:", e) await asyncio.sleep(retry_delay) retries += 1 # If max retries reached, return the last exception return AppOutput(output=None, status=str(last_exception))


AppOutput का उपयोग: अधिकतम पुनर्प्रयास का उपयोग करने के बाद भी अपवाद को संभालना महत्वपूर्ण है। इस तरह, आप उस सभी डेटा को चलाने की अनुमति देते हैं जिसे आप संसाधित करने का प्रयास कर रहे हैं, और फिर आप यह निर्धारित कर सकते हैं कि क्या विफल हुआ और क्या पारित हुआ।


अंतिम चरण ऐप को इनवॉइस करना है, एलएलएम ऐप के openapi_parameters का उपयोग करके यह निर्धारित करना है कि इसे एकल डेटापॉइंट के साथ कैसे इनवॉइस किया जाए।


मेक_पेलोड फ़ंक्शन से आपको चिंतित नहीं होना चाहिए। यह अपने ओपनएपीआई मापदंडों के आधार पर एलएलएम ऐप को लागू करने के लिए पेलोड का निर्माण करता है।


 async def invoke_app( uri: str, datapoint: Any, parameters: Dict, openapi_parameters: List[Dict] ) -> AppOutput: """ Invokes an app for one datapoint using the openapi_parameters to determine how to invoke the app. Args: uri (str): The URI of the app to invoke. datapoint (Any): The data to be sent to the app. parameters (Dict): The parameters required by the app taken from the db. openapi_parameters (List[Dict]): The OpenAPI parameters of the app. Returns: AppOutput: The output of the app. Raises: httpx.HTTPError: If the POST request fails. """ url = f"{uri}/generate" payload = await make_payload(datapoint, parameters, openapi_parameters) async with httpx.AsyncClient() as client: try: logger.debug(f"Invoking app {uri} with payload {payload}") response = await client.post( url, json=payload, timeout=httpx.Timeout(timeout=5, read=None, write=5) ) response.raise_for_status() llm_app_response = response.json() app_output = ( llm_app_response["message"] if isinstance(llm_app_response, dict) else llm_app_response ) return AppOutput(output=app_output, status="success") except: return AppOutput(output="Error", status="error")


और इससे प्रक्रिया पूरी हो जाती है।


सारांश

कोड में बैकऑफ़ घातीय रणनीति निम्नानुसार काम करती है:


  • बैच प्रोसेसिंग: बैच_इनवोक फ़ंक्शन टेस्टसेट डेटा को कॉन्फ़िगर करने योग्य आकार के साथ छोटे बैचों में विभाजित करता है। प्रत्येक बैच को क्रमिक रूप से संसाधित किया जाता है।


  • पुनः प्रयास के साथ व्यक्तिगत आह्वान: प्रत्येक बैच के भीतर, प्रत्येक डेटा बिंदु को run_with_retry फ़ंक्शन द्वारा संसाधित किया जाता है। यह फ़ंक्शन डेटा बिंदु के लिए ऐप को इनवॉइस करने का प्रयास करता है। यदि विशिष्ट नेटवर्क त्रुटियों (टाइमआउट, कनेक्शन समस्याएं) के कारण आमंत्रण विफल हो जाता है, तो फ़ंक्शन देरी से पुनः प्रयास करता है। यह विलंब प्रारंभ में एक कॉन्फ़िगर करने योग्य मान ( retry_delay ) पर सेट किया गया है और उसी बैच के भीतर प्रत्येक बाद के पुनः प्रयास प्रयास के लिए दोगुना कर दिया गया है।


यह दृष्टिकोण विफलता के बाद बार-बार अनुरोधों के साथ ऐप सर्वर पर ओवरलोडिंग से बचने में मदद करता है। यह सर्वर को पुनर्प्राप्त करने का समय देता है और पुन: प्रयास करने से पहले लंबित अनुरोधों की कतार को साफ़ करने की अनुमति देता है।


रणनीति में अनंत लूप को रोकने के लिए प्रति डेटा बिंदु पर कॉन्फ़िगर करने योग्य अधिकतम संख्या में पुनः प्रयास भी शामिल हैं। ऐप सर्वर द्वारा निर्धारित दर सीमा से अधिक होने से बचने के लिए बैचों के बीच देरी ( delay_between_batches ) भी शामिल है।


मुझे आशा है कि यह आज के लेख में आपने जो कुछ भी सीखा है उसका सारांश प्रस्तुत करता है। यदि आपके कोई सवाल हैं तो कृपया मुझे बताएं!