1、为什么要使用限速参数
大模型供应商在提供模型服务时,通常会设置请求的速率限制,如果达到速率限制,通常会收到来自提供商的速率限制错误响应,并且需要等待才能发出更多请求。在上一篇文章【langchian-v0.3实战笔记】1、搭建一个简单LLM应用中我们介绍了大模型应用的构建,在LLM模型初始化时,提供一个标准参数rate_limiter
用于限制请求的速率。通过InMemoryRateLimiter
我们可以声明一个限速对象,避免在并行调用大模型应用时超过大模型API提供的最大处理能力。
from langchain_core.rate_limiters import InMemoryRateLimiter
rate_limiter = InMemoryRateLimiter(
requests_per_second=10, # 每秒支持发送的请求数量为10
check_every_n_seconds=0.1, # 每100ms检查是否允许新建请求
max_bucket_size=5, # 存储桶中可以容纳的最大令牌数,这用于防止请求激增。
)
- requests_per_second 参数用于设定每秒生成的令牌个数,直到填满bucket,该参数用于设置你期望的最大请求平均速率,不建议超过供应商支持的速率。
- check_every_n_seconds 参数用于指定多久去令牌桶检查是否有令牌待取出。
- max_bucket_size 参数用于防止请求激增,即限制最大并行数量,当请求流量不平时,可以达到削峰的效果。
2、效果验证
我们可以通过如下示例来验证限速的效果,为了使限速效果更明显,使用了不合理的参数配置。
from langchain_core.rate_limiters import InMemoryRateLimiter
rate_limiter = InMemoryRateLimiter(
requests_per_second=1,
check_every_n_seconds=5,
max_bucket_size=3,
)
model = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.0,
timeout=60,
max_tokens=1000,
max_retries=3,
# stop = "\n",
stop = ["\n","END"],
rate_limiter=rate_limiter,
)
messages = [
SystemMessage("你是一个电商大模型"),
HumanMessage("请推荐3个送给女朋友的礼物"),
]
def task(n):
tic = time.time()
result = model.invoke(messages)
print(result.content)
print(f"Task {n} completed")
toc = time.time()
print(toc - tic)
threads = []
for i in range(5):
thread = threading.Thread(target=task, args=(i,))
threads.append(thread)
thread.start()
# 等待所有线程完成
for thread in threads:
thread.join()
print("All tasks completed.")
输出结果如下:
Task 1 completed
6.340749025344849
Task 2 completed
6.36247706413269
Task 4 completed
6.368077993392944
Task 0 completed
11.272664070129395
Task 3 completed
11.403869867324829
All tasks completed.
通过结果可以发现,虽然同时启动5个任务,但由于max_bucket_size=3限制,第一个5秒检查点时,仅有3个任务被执行,第二个5秒检查点剩余两个任务才被执行。
3、总结
如果无限制的调用大模型服务,很可能会触发上游大模型限速错误,更严重将导致大模型服务崩溃。为了确保大模型应用服务稳定,通常在服务端会增加限速功能,langchain_openai
组件通过标准参数rate_limiter
提供了限速能力。只需要简单配置 requests_per_second
, check_every_n_seconds
, max_bucket_size
这三个参数即可达到限速的目标,快来试试吧!!!!