OpenAI API 速率限制

2023-03-17 17:23 更新

概述

什么是速率限制?

速率限制是 API 對(duì)用戶或客戶端在指定時(shí)間段內(nèi)可以訪問(wèn)服務(wù)器的次數(shù)施加的限制。

為什么我們有速率限制?

速率限制是 API 的常見(jiàn)做法,它們的實(shí)施有幾個(gè)不同的原因:

  • 它們有助于防止濫用或誤用 API。例如,惡意行為者可能會(huì)向 API 發(fā)送大量請(qǐng)求,以試圖使其過(guò)載或?qū)е路?wù)中斷。通過(guò)設(shè)置速率限制,OpenAI 可以防止此類活動(dòng)。

  • 速率限制有助于確保每個(gè)人都能公平地訪問(wèn) API。如果一個(gè)人或組織發(fā)出過(guò)多的請(qǐng)求,可能會(huì)使其他人的 API 陷入困境。通過(guò)限制單個(gè)用戶可以發(fā)出的請(qǐng)求數(shù)量,OpenAI 確保大多數(shù)人有機(jī)會(huì)使用 API 而不會(huì)遇到速度下降的情況。

  • 速率限制可以幫助 OpenAI 管理其基礎(chǔ)設(shè)施上的聚合負(fù)載。如果對(duì) API 的請(qǐng)求急劇增加,可能會(huì)對(duì)服務(wù)器造成負(fù)擔(dān)并導(dǎo)致性能問(wèn)題。通過(guò)設(shè)置速率限制,OpenAI 可以幫助為所有用戶保持流暢和一致的體驗(yàn)。

請(qǐng)完整閱讀本文檔,以更好地了解 OpenAI 的速率限制系統(tǒng)的工作原理。我們包括代碼示例和可能的解決方案來(lái)處理常見(jiàn)問(wèn)題。建議在填寫(xiě)速率限制增加請(qǐng)求表之前遵循此指南,并在最后一部分中詳細(xì)說(shuō)明如何填寫(xiě)。

我們的 API 有哪些速率限制?

我們根據(jù)使用的特定端點(diǎn)以及您擁有的帳戶類型,在組織級(jí)別而非用戶級(jí)別實(shí)施速率限制。速率限制以兩種方式衡量:RPM(每分鐘請(qǐng)求數(shù))和 TPM(每分鐘令牌數(shù))。下表突出顯示了我們 API 的默認(rèn)速率限制,但在填寫(xiě)速率限制增加請(qǐng)求表后,可以根據(jù)您的用例增加這些限制。

TPM(每分鐘令牌數(shù))單位因型號(hào)而異:

類型 1 TPM 等于
davinci 每分鐘 1 個(gè)令牌
curie 每分鐘 25 個(gè)令牌
babbage 每分鐘 100 個(gè)令牌
ada 每分鐘 200 個(gè)令牌

實(shí)際上,這意味著與 davinci 模型相比,您每分鐘可以向 ada 模型發(fā)送大約 200 倍的令牌。

文本和嵌入 聊天 編碼 編輯 圖像 音頻
免費(fèi)試用用戶 ?20 RPM
?150,000 TPM
?20 RPM
?40,000 TPM
?20 RPM
?40,000 TPM
?20 RPM
?150,000 TPM
50 images / min 50 RPM
按需付費(fèi)用戶(前 48 小時(shí)) ?60 RPM
?250,000 TPM*
?60 RPM
?60,000 TPM*
?20 RPM
?40,000 TPM
?20 RPM
?150,000 TPM
50 images / min 50 RPM
按量付費(fèi)用戶(48小時(shí)后) ?3,500 RPM
?350,000 TPM*
?3,500 RPM
?90,000 TPM*
?20 RPM
?40,000 TPM
?20 RPM
?150,000 TPM
50 images / min 50 RPM

重要的是要注意,根據(jù)首先發(fā)生的情況,任一選項(xiàng)都可能達(dá)到速率限制。例如,您可能會(huì)向 Codex 端點(diǎn)發(fā)送僅包含 100 個(gè)令牌的 20 個(gè)請(qǐng)求,這將達(dá)到您的限制,即使您沒(méi)有在這 20 個(gè)請(qǐng)求中發(fā)送 40k 個(gè)令牌。

GPT-4 速率限制

在 GPT-4 推出期間,該模型將有更嚴(yán)格的速率限制以滿足需求。 gpt-4/gpt-4-0314 的默認(rèn)速率限制為 40k TPM 和 200 RPM。 gpt-4-32k/gpt-4-32k-0314 的默認(rèn)速率限制為 80k PRM 和 400 RPM。聯(lián)系我們請(qǐng)求提高速率限制訂購(gòu)專用容量;請(qǐng)注意,我們可能無(wú)法方便地滿足所有請(qǐng)求。

速率限制如何工作?

如果您的速率限制是每分鐘 60 個(gè)請(qǐng)求和每分鐘 150k davinci 令牌,您將受到限制,要么達(dá)到請(qǐng)求/分鐘上限,要么用完令牌——以先發(fā)生者為準(zhǔn)。例如,如果您的最大請(qǐng)求數(shù)/分鐘為 60,則您應(yīng)該能夠每秒發(fā)送 1 個(gè)請(qǐng)求。如果您每 800 毫秒發(fā)送 1 個(gè)請(qǐng)求,一旦達(dá)到速率限制,您只需讓程序休眠 200 毫秒即可再發(fā)送一個(gè)請(qǐng)求,否則后續(xù)請(qǐng)求將失敗。默認(rèn)值為 3,000 個(gè)請(qǐng)求/分鐘,客戶可以有效地每 20 毫秒或每 .02 秒發(fā)送 1 個(gè)請(qǐng)求。

如果我遇到速率限制錯(cuò)誤會(huì)怎樣?

速率限制錯(cuò)誤如下所示:

Rate limit reached for default-text-davinci-002 in organization org-{id} on requests per min. Limit: 20.000000 / min. Current: 24.000000 / min.

如果您達(dá)到速率限制,這意味著您在短時(shí)間內(nèi)發(fā)出了太多請(qǐng)求,并且 API 將拒絕滿足進(jìn)一步的請(qǐng)求,直到經(jīng)過(guò)指定的時(shí)間量。

Rate limits vs max_tokens

我們提供的每個(gè)模型都有有限數(shù)量的令牌,可以在發(fā)出請(qǐng)求時(shí)作為輸入傳遞。您不能增加模型接收的最大令牌數(shù)。例如,如果您使用的是 text-ada-001,則可以向該模型發(fā)送的最大令牌數(shù)是每個(gè)請(qǐng)求 2,048 個(gè)令牌。

錯(cuò)誤緩解

我可以采取哪些措施來(lái)緩解這種情況?

OpenAI Cookbook 有一個(gè) python notebook,詳細(xì)解釋了如何避免速率限制錯(cuò)誤。

在提供編程訪問(wèn)、批量處理功能和自動(dòng)社交媒體發(fā)布時(shí),您還應(yīng)該謹(jǐn)慎行事 - 考慮只為受信任的客戶啟用這些功能。

為防止自動(dòng)和大量濫用,請(qǐng)?jiān)谥付〞r(shí)間范圍內(nèi)(每天、每周或每月)為單個(gè)用戶設(shè)置使用限制??紤]對(duì)超出限制的用戶實(shí)施硬上限或人工審查流程。

使用指數(shù)退避重試

避免速率限制錯(cuò)誤的一種簡(jiǎn)單方法是使用隨機(jī)指數(shù)退避自動(dòng)重試請(qǐng)求。使用指數(shù)退避重試意味著在遇到速率限制錯(cuò)誤時(shí)執(zhí)行短暫的休眠,然后重試不成功的請(qǐng)求。如果請(qǐng)求仍然不成功,則增加睡眠時(shí)間并重復(fù)該過(guò)程。這一直持續(xù)到請(qǐng)求成功或達(dá)到最大重試次數(shù)為止。這種方法有很多好處:

  • 自動(dòng)重試意味著您可以從速率限制錯(cuò)誤中恢復(fù)而不會(huì)崩潰或丟失數(shù)據(jù)

  • 指數(shù)退避意味著您可以快速嘗試第一次重試,同時(shí)如果您的前幾次重試失敗,仍然可以從更長(zhǎng)的延遲中獲益

  • 將隨機(jī)抖動(dòng)添加到延遲有助于重試所有同時(shí)命中。

請(qǐng)注意,不成功的請(qǐng)求會(huì)影響您的每分鐘限制,因此不斷重新發(fā)送請(qǐng)求將不起作用。

下面是一些使用指數(shù)退避算法的 Python 示例解決方案。

  • 示例 #1:使用 Tenacity 庫(kù)

  • Tenacity 是一個(gè) Apache 2.0 許可的通用重試庫(kù),用 Python 編寫(xiě),用于簡(jiǎn)化將重試行為添加到幾乎所有內(nèi)容的任務(wù)。要為您的請(qǐng)求添加指數(shù)退避,您可以使用 tenacity.retry 裝飾器。下面的示例使用 tenacity.wait_random_exponential 函數(shù)向請(qǐng)求添加隨機(jī)指數(shù)退避。

    import openai
    from tenacity import (
        retry,
        stop_after_attempt,
        wait_random_exponential,
    )  # for exponential backoff
     
    @retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
    def completion_with_backoff(**kwargs):
        return openai.Completion.create(**kwargs)
     
    completion_with_backoff(model="text-davinci-003", prompt="Once upon a time,")

    請(qǐng)注意,Tenacity 庫(kù)是第三方工具,OpenAI 不保證其可靠性或安全性。

  • 示例 #2:使用退避庫(kù)

  • 另一個(gè)提供退步和重試的函數(shù)裝飾器的python庫(kù)是 backoff。

    import backoff 
    import openai 
    @backoff.on_exception(backoff.expo, openai.error.RateLimitError)
    def completions_with_backoff(**kwargs):
        return openai.Completion.create(**kwargs)
     
    completions_with_backoff(model="text-davinci-003", prompt="Once upon a time,")

    與 Tenacity 一樣,退避庫(kù)是第三方工具,OpenAI 不保證其可靠性或安全性。

  • 示例 3:手動(dòng)退避實(shí)現(xiàn)

  • 如果你不想使用第三方庫(kù),你可以按照這個(gè)例子實(shí)現(xiàn)你自己的退避邏輯:

    # imports
    import random
    import time
     
    import openai
     
    # define a retry decorator
    def retry_with_exponential_backoff(
        func,
        initial_delay: float = 1,
        exponential_base: float = 2,
        jitter: bool = True,
        max_retries: int = 10,
        errors: tuple = (openai.error.RateLimitError,),
    ):
        """Retry a function with exponential backoff."""
     
        def wrapper(*args, **kwargs):
            # Initialize variables
            num_retries = 0
            delay = initial_delay
     
            # Loop until a successful response or max_retries is hit or an exception is raised
            while True:
                try:
                    return func(*args, **kwargs)
     
                # Retry on specific errors
                except errors as e:
                    # Increment retries
                    num_retries += 1
     
                    # Check if max retries has been reached
                    if num_retries > max_retries:
                        raise Exception(
                            f"Maximum number of retries ({max_retries}) exceeded."
                        )
     
                    # Increment the delay
                    delay *= exponential_base * (1 + jitter * random.random())
     
                    # Sleep for the delay
                    time.sleep(delay)
     
                # Raise exceptions for any errors not specified
                except Exception as e:
                    raise e
     
        return wrapper
        
    @retry_with_exponential_backoff
    def completions_with_backoff(**kwargs):
        return openai.Completion.create(**kwargs)

    同樣,OpenAI 不保證此解決方案的安全性或效率,但它可以作為您自己的解決方案的良好起點(diǎn)。

批處理請(qǐng)求

OpenAI API 對(duì)每分鐘的請(qǐng)求數(shù)和每分鐘的令牌數(shù)有單獨(dú)的限制。

如果您達(dá)到每分鐘請(qǐng)求的限制,但每分鐘有可用的令牌容量,您可以通過(guò)將多個(gè)任務(wù)分批處理到每個(gè)請(qǐng)求中來(lái)提高吞吐量。這將使您每分鐘可以處理更多的令牌,尤其是對(duì)于我們較小的模型。

發(fā)送一批提示與普通的 API 調(diào)用完全相同,只是您將字符串列表而不是單個(gè)字符串傳遞給提示參數(shù)。

  • 沒(méi)有批處理的例子

  • import openai
     
    num_stories = 10
    prompt = "Once upon a time,"
     
    # serial example, with one story completion per request
    for _ in range(num_stories):
        response = openai.Completion.create(
            model="curie",
            prompt=prompt,
            max_tokens=20,
        )
        # print story
        print(prompt + response.choices[0].text)
  • 使用批處理的例子

  • import openai  # for making OpenAI API requests
     
     
    num_stories = 10
    prompts = ["Once upon a time,"] * num_stories
     
    # batched example, with 10 story completions per request
    response = openai.Completion.create(
        model="curie",
        prompt=prompts,
        max_tokens=20,
    )
     
    # match completions to prompts by index
    stories = [""] * len(prompts)
    for choice in response.choices:
        stories[choice.index] = prompts[choice.index] + choice.text
     
    # print stories
    for story in stories:
        print(story)

警告:響應(yīng)對(duì)象可能不會(huì)按照提示的順序返回完成,因此請(qǐng)始終記住使用索引字段將響應(yīng)匹配回提示。

請(qǐng)求增加

我什么時(shí)候應(yīng)該考慮申請(qǐng)?zhí)岣呃氏拗疲?/p>

我們的默認(rèn)速率限制幫助我們最大限度地提高穩(wěn)定性并防止濫用我們的 API。我們?cè)黾酉拗埔詥⒂酶吡髁繎?yīng)用程序,因此申請(qǐng)?zhí)岣咚俾氏拗频淖罴褧r(shí)間是當(dāng)您認(rèn)為您擁有必要的流量數(shù)據(jù)來(lái)支持提高速率限制的有力案例時(shí)。沒(méi)有支持?jǐn)?shù)據(jù)的大型速率限制增加請(qǐng)求不太可能獲得批準(zhǔn)。如果您正在為產(chǎn)品發(fā)布做準(zhǔn)備,請(qǐng)通過(guò)10天以上的階段性發(fā)布獲取相關(guān)數(shù)據(jù)。

請(qǐng)記住,速率限制的增加有時(shí)可能需要 7-10 天,因此如果有數(shù)據(jù)支持您將達(dá)到您當(dāng)前的增長(zhǎng)數(shù)字,那么嘗試提前計(jì)劃并盡早提交是有意義的。

我的速率限制提高請(qǐng)求會(huì)被拒絕嗎?

速率限制增加請(qǐng)求通常被拒絕,因?yàn)樗狈ψC明增加的合理性所需的數(shù)據(jù)。我們?cè)谙旅嫣峁┝藬?shù)字示例,展示了如何最好地支持提高速率限制的請(qǐng)求,并盡力批準(zhǔn)符合我們的安全政策并顯示支持?jǐn)?shù)據(jù)的所有請(qǐng)求。我們致力于使開(kāi)發(fā)人員能夠擴(kuò)展我們的 API 并取得成功。

我已經(jīng)為我的文本/代碼 API 實(shí)現(xiàn)了指數(shù)退避,但我仍然遇到這個(gè)錯(cuò)誤。如何提高速率限制?

目前,我們不支持增加我們的免費(fèi)測(cè)試端點(diǎn),例如編輯端點(diǎn)。我們也不會(huì)提高 ChatGPT 速率限制,但您可以加入 ChatGPT Professional 訪問(wèn)的候補(bǔ)名單。

我們理解有限的速率限制可能導(dǎo)致的挫敗感,我們很樂(lè)意為每個(gè)人提高默認(rèn)值。但是,由于共享容量限制,我們只能批準(zhǔn)通過(guò)我們的速率限制增加請(qǐng)求表證明有需求的付費(fèi)客戶增加速率限制。為了幫助我們正確評(píng)估您的需求,我們要求您在表格的“分享需求證據(jù)”部分提供您當(dāng)前使用情況的統(tǒng)計(jì)數(shù)據(jù)或基于歷史用戶活動(dòng)的預(yù)測(cè)。如果此信息不可用,我們建議采用分階段發(fā)布方法。首先按照您當(dāng)前的速率限制向部分用戶發(fā)布服務(wù),收集 10 個(gè)工作日的使用數(shù)據(jù),然后根據(jù)該數(shù)據(jù)提交正式的速率限制提高請(qǐng)求,以供我們審核和批準(zhǔn)。

我們將審核您的請(qǐng)求,如果獲得批準(zhǔn),我們將在 7-10 個(gè)工作日內(nèi)通知您批準(zhǔn)情況。

以下是您可以如何填寫(xiě)此表格的一些示例:

  • DALL-E API 示例

  • 模型 估計(jì)代幣/分鐘 估計(jì)請(qǐng)求/分鐘 # 用戶 需要的證據(jù) 1 小時(shí)最大吞吐量成本
    DALL-E API N/A 50 1000 我們的應(yīng)用程序目前正在生產(chǎn)中,根據(jù)我們過(guò)去的流量,我們每分鐘發(fā)出大約 10 個(gè)請(qǐng)求。 $60
    DALL-E API N/A 150 10,000 我們的應(yīng)用程序在 App Store 中越來(lái)越受歡迎,我們開(kāi)始達(dá)到速率限制。我們能否獲得默認(rèn)限制 50 img/min 的三倍?如果我們需要更多,我們將提交一份新表格。謝謝! $180
  • 語(yǔ)言模型示例

  • 模型 估計(jì)代幣/分鐘 估計(jì)請(qǐng)求/分鐘 # 用戶 需要的證據(jù) 1 小時(shí)最大吞吐量成本
    text-davinci-003 325,000 4,0000 50 我們正在向最初的一組 alpha 測(cè)試人員發(fā)布,需要更高的限制來(lái)適應(yīng)他們的初始使用。我們?cè)谶@里有一個(gè)指向我們的谷歌驅(qū)動(dòng)器的鏈接,它顯示了分析和 api 使用情況。 $390
    text-davinci-002 750,000 10,000 10,000 我們的應(yīng)用程序受到了很多關(guān)注;我們的候補(bǔ)名單上有 50,000 人。我們希望每天向 1,000 人的群組推出,直到我們達(dá)到 50,000 名用戶。請(qǐng)查看過(guò)去 30 天我們當(dāng)前令牌/分鐘流量的鏈接。這是針對(duì) 500 個(gè)用戶的,根據(jù)他們的使用情況,我們認(rèn)為 750,000 個(gè)令牌/分鐘和 10,000 個(gè)請(qǐng)求/分鐘將是一個(gè)很好的起點(diǎn)。 $900
  • 代碼模型示例

  • 模型 估計(jì)代幣/分鐘 估計(jì)請(qǐng)求/分鐘 # 用戶 需要的證據(jù) 1 小時(shí)最大吞吐量成本
    code-davinci-002 150,000 1,000 15 我們是一群研究論文的研究人員。我們估計(jì)我們需要對(duì) code-davinci-002 進(jìn)行更高的速率限制,以便在月底前完成我們的研究。這些估計(jì)基于以下計(jì)算 [...] Codex 模型目前處于免費(fèi)測(cè)試階段,因此我們可能無(wú)法為這些模型提供立即增加。

請(qǐng)注意,這些示例只是一般用例場(chǎng)景,實(shí)際使用率會(huì)因具體實(shí)施和使用情況而異。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)