错误缓解方案
千帆ModelBuilder为不同的服务设定了不同的调用频率限制策略,以保障服务稳定性和为开发者提供最佳性能和较优的开发体验。本文介绍了千帆ModelBuilder提供的具体调用频率限制策略,以及遇到限制时的一些处理方法。
调用频率限制介绍
开发者在调用API服务时,调用次数/消耗tokens数有一定的限制。调用频率限制介绍、限制策略等,请参考速率限制说明文档。
触发限制后的响应
以ERNIE 3.5为例进行说明
- 默认RPM=300,如果客户在1分钟之内发送310个请求,只会有300个请求成功,剩余10个请求直接失败。请求失败错误码为336501,错误描述为Rate limit reached for RPM。
- 默认TPM=300,000,如果客户在1分钟内消耗的token数量超过300,000 ,则超过300,000tokens以后的请求都会失败。请求失败错误码为336502,错误描述为Rate limit reached for TPM。
示例如下:
HTTP/1.1 200
Content-Type: application/json
X-Ratelimit-Limit-Requests: 300 //一分钟内允许的最大请求次数
X-Ratelimit-Limit-Tokens: 300000 //一分钟内允许的最大tokens消耗,包含输入tokens和输出tokens
X-Ratelimit-Remaining-Requests: xx //达到RPM速率限制前,剩余可发送的请求数配额,如果配额用完,将会在0-60s后刷新
X-Ratelimit-Remaining-Tokens: xxx // 达到TPM速率限制前,剩余可消耗的tokens数配额,如果配额用完,将会在0-60s后刷新
{
"code": 336501,
"msg": "Rate limit reached for RPM"
}
如何处理限制
为最大限度地减少服务出现问题后带来的影响,千帆ModelBuilder提供了多种机制,在调用错误时进行重试等,避免出现频率极高的错误,提升用户使用体验。
重试机制
SDK 提供了多种方式,在遇到错误时自动进行重试,以及在重试间进行退避避免触发流控。
基于指数回避重试机制,重试的等待时间会以某种策略化的计算,以规避请求风暴等问题,更多详细介绍请参考退避回避算法。简单可以总结为:
重试等待时间=min(backoff_factor×(2^重试次数)+random(0, jitter), max_wait_interval)
- retry_count:重试次数。
- backoff_factor:退避因子。
- jitter:抖动系数,对退避时间做一个“抖动”,以具有一定的随机性。
- max_wait_interval:最大重试间隔,以避免无限长的等待时间。
- timeout:本次请求超时时间(秒)。
SDK目前提供2种方式设置重试机制,分别通过环境变量设置、通过参数设置。不同方式实现效果相同,设置方式及参数名不同,开发者可以选择任一方式,具体使用请参考示例。
- 方式一:通过环境变量设置
环境变量设置对整个程序生效。
说明 | 设置环境变量项 |
---|---|
超时时间(秒) | QIANFAN_LLM_API_RETRY_TIMEOUT |
重试次数 | QIANFAN_LLM_API_RETRY_COUNT |
退避因子 | QIANFAN_LLM_API_RETRY_BACKOFF_FACTOR |
抖动系数 | QIANFAN_LLM_API_RETRY_JITTER |
最大重试间隔 | QIANFAN_LLM_API_RETRY_MAX_WAIT_INTERVAL |
以ERNIE-3.5-8K调用为例,如下。
import os
import qianfan
## 超时时间(秒)
os.environ["QIANFAN_LLM_API_RETRY_TIMEOUT"] = "300"
# 重试次数(模型推理相关操作)
os.environ["QIANFAN_LLM_API_RETRY_COUNT"] = "3"
## 退避因子
os.environ["QIANFAN_LLM_API_RETRY_BACKOFF_FACTOR"] = "1"
## 抖动系数
os.environ["QIANFAN_LLM_API_RETRY_JITTER"] = "3"
## 最大重试间隔
os.environ["QIANFAN_LLM_API_RETRY_MAX_WAIT_INTERVAL"] = "120"
#【推荐】使用安全认证AK/SK鉴权,通过环境变量初始化认证信息
# 替换下列示例中参数,安全认证Access Key替换your_iam_ak,Secret Key替换your_iam_sk
os.environ["QIANFAN_ACCESS_KEY"] = "your_iam_ak"
os.environ["QIANFAN_SECRET_KEY"] = "your_iam_sk"
chat_comp = qianfan.ChatCompletion()
# 指定特定模型
resp = chat_comp.do(model="ERNIE-3.5-8K", messages=[{
"role": "user",
"content": "你好"
}])
print(resp["body"])
- 方式二:通过参数设置
参数设置仅对该请求生效。
说明 | 参数名称 | 类型 |
---|---|---|
重试次数 | retry_count | int |
超时时间(秒) | request_timeout | float |
退避因子 | backoff_factor | float |
抖动系数 | retry_jitter | float |
自定义重试API错误码 | retry_err_codes | set[int] |
最大重试间隔 | retry_max_wait_interval | float |
以ERNIE-3.5-8K调用为例如下。
import os
import qianfan
#【推荐】使用安全认证AK/SK鉴权,通过环境变量初始化认证信息
# 替换下列示例中参数,安全认证Access Key替换your_iam_ak,Secret Key替换your_iam_sk
os.environ["QIANFAN_ACCESS_KEY"] = "your_iam_ak"
os.environ["QIANFAN_SECRET_KEY"] = "your_iam_sk"
chat = qianfan.ChatCompletion()
resp = chat.do(
model="ERNIE-3.5-8K",
messages=[{
"role": "user",
"content": "你好"
}],
# 重试次数
retry_count=3,
# 超时时间(秒)
request_timeout=300,
# 退避因子
backoff_factor=2,
# 抖动系数
retry_jitter=2,
# 最大重试间隔
retry_max_wait_interval=120,
# 自定义需要重试的API错误码
retry_err_codes={2, 336100, 15, 18, 336501, 336502},
)
print(resp["body"])
限流机制
为防止超额请求带来的潜在问题,千帆ModelBuilder SDK对用户接口的请求进行限流。限流策略及配置以下:
类别 | 维度 | 描述 |
请求频率类 | QPS 限制 | 设置 QPS 限制,为正浮点数。注意: (1)QPS限制和RPM不能同时设置,只能设置其中一个 (2)如果是ERNIE 系列模型,SDK 会自动从平台获取限流配置,且和用户自己指定的配置对比,SDK 会取两者中较小的值 (3)如果是第三方模型,则需要用户自行配置限流 |
RPM 限制 | 设置RPM 限制,会限制每分钟请求的次数,为正浮点数。注意: (1)QPS限制和RPM不能同时设置,只能设置其中一个 (2)如果是ERNIE 系列模型,SDK 会自动从平台获取限流配置,且和用户自己指定的配置对比,SDK 会取两者中较小的值 (3)如果是第三方模型,则需要用户自行配置限流。 |
|
token/字符类 | TPM 限制 | 设置TPM 限制,代表每分钟内可以消耗的 Token 总数,为正整数。注意: (1)如果是ERNIE 系列模型,SDK 会自动从平台获取限流配置,且和用户自己指定的配置对比,SDK 会取两者中较小的值 (2)如果是第三方模型,则需要用户自行配置限流。 |
开发者可以通过以下2种方式配置限流,通过调整设定的限流值,避免出现频率极高的错误。
- 方式一:通过系统环境变量配置
以ERNIE-3.5-8K为例说明
import os
import qianfan
# 设置QPS限制,为正浮点数,QPS限制和RPM不能同时设置,只能设置其中一个
os.environ["QIANFAN_QPS_LIMIT"] = "1"
# 设置RPM限制,限制每分钟请求的次数,为正浮点数;QPS限制和RPM不能同时设置,只能设置其中一个
# os.environ["QIANFAN_RPM_LIMIT"] = "300"
# 设置TPM限制,代表每分钟内可以消耗的 Token 总数,为正整数
os.environ["QIANFAN_TPM_LIMIT"] = "30000"
# 使用安全认证AK/SK鉴权,通过环境变量方式初始化;替换下列示例中参数,安全认证Access Key替换your_iam_ak,Secret Key替换your_iam_sk
os.environ["QIANFAN_ACCESS_KEY"] = "your_iam_ak"
os.environ["QIANFAN_SECRET_KEY"] = "your_iam_sk"
chat_comp=qianfan.ChatCompletion()
# 指定特定模型
resp = chat_comp.do(model="ERNIE-3.5-8K", messages=[{
"role": "user",
"content": "你好"
}])
print(resp.body)
- 方式二:通过参数配置
在创建相关请求对象时,传入相关参数进行配置限流,以ERNIE-3.5-8K为例说明。
import os
import qianfan
# 使用安全认证AK/SK鉴权,通过环境变量方式初始化;替换下列示例中参数,安全认证Access Key替换your_iam_ak,Secret Key替换your_iam_sk
os.environ["QIANFAN_ACCESS_KEY"] = "your_iam_ak"
os.environ["QIANFAN_SECRET_KEY"] = "your_iam_sk"
# 创建相关请求对象时,通过参数配置限流
chat_comp=qianfan.ChatCompletion(
# 设置QPS限制,为正浮点数,QPS限制和RPM不能同时设置,只能设置其中一个
request_per_minute=300,
# 设置RPM限制,限制每分钟请求的次数,为正浮点数;QPS限制和RPM不能同时设置,只能设置其中一个
#request_per_minute
# 设置TPM限制,代表每分钟内可以消耗的 Token 总数,为正整数
token_per_minute=300000,
)
# 指定特定模型
resp = chat_comp.do(model="ERNIE-3.5-8K", messages=[{
"role": "user",
"content": "你好"
}])
print(resp.body)
自动截断机制
当调用API,输入大模型内容过长,超过限制时,接口会返回336103或336007错误。可以通过以下任一方式解决:
· 通过适当缩短prompt,即减少输入长度,避免请求内容超过限制
· 通过使用SDK调用相关API,当输入大模型内容过长时,SDK会自动截断输入
如何提升调用频率限制
如果用户使用的服务RPM和TPM速率限制较低,无法满足业务要求,可以通过购买TPM实现扩容。具体请查看如何提升速率限制。