开源框架用于构建和评估 LLM 路由器,优化多模型推理的成本-效果权衡,对成本敏感的场景有用。
RouteLLM 是一个用于提供和评估 LLM router 的框架。
它的核心功能包括:
可直接替代 OpenAI client(也可以启动兼容 OpenAI 的 server),将较简单的查询路由到成本更低的模型。
框架开箱即用地提供了训练好的 router。我们已经证明,在 MT Bench 等广泛使用的 benchmark 上,这些 router 能够在维持 GPT-4 95% 性能的同时,将成本最多降低 85%。
Benchmark 还表明,这些 router 能达到与商业产品相同的性能,同时成本低 40% 以上。
你可以轻松扩展这个框架,加入新的 router,并在多个 benchmark 上比较不同 router 的性能。
pip install "routellm[serve,eval]"
git clone https://github.com/lm-sys/RouteLLM.git
cd RouteLLM
pip install -e .[serve,eval]
下面让我们逐步了解如何替换现有的 OpenAI client,在多个 LLM 之间路由查询,而不是只使用单一模型。
首先,我们使用 mf router 初始化 RouteLLM controller,以此替换 OpenAI client。默认情况下,RouteLLM 会使用性能最好的配置:
import os
from routellm.controller import Controller
os.environ["OPENAI_API_KEY"] = "sk-XXXXXX"
# Replace with your model provider, we use Anyscale's Mixtral here.
os.environ["ANYSCALE_API_KEY"] = "esecret_XXXXXX"
client = Controller(
routers=["mf"],
strong_model="gpt-4-1106-preview",
weak_model="anyscale/mistralai/Mixtral-8x7B-Instruct-v0.1",
)
在上面的示例中,我们选择 gpt-4-1106-preview 作为 strong model,选择 anyscale/mistralai/Mixtral-8x7B-Instruct-v0.1 作为 weak model,并相应设置 API key。你可以按照“模型支持”中的说明更新模型名称,在不同模型组合或 provider 之间进行路由。
想路由到本地模型?请查看“路由到本地模型”。
每个路由请求都有一个成本阈值,用于控制成本与质量之间的权衡。我们应该根据收到的查询类型校准这个阈值,从而最大限度提升路由性能。下面以 Chatbot Arena 的数据为例,将阈值校准为让 50% 的请求调用 GPT-4。
> python -m routellm.calibrate_threshold --routers mf --strong-model-pct 0.5 --config config.example.yaml
For 50.0% strong model calls for mf, threshold = 0.11593
这意味着我们应该使用 0.11593 作为阈值,使大约 50% 的查询,也就是最需要 GPT-4 的那部分查询,被路由到 GPT-4(详情参见“阈值校准”)。
现在,让我们在生成 completion 时更新 model 字段,指定要使用的 router 和阈值:
response = client.chat.completions.create(
# This tells RouteLLM to use the MF router with a cost threshold of 0.11593
model="router-mf-0.11593",
messages=[
{"role": "user", "content": "Hello!"}
]
)
就是这样!现在,请求会根据实际需求被路由到 strong model 或 weak model,从而在保持高质量响应的同时节省成本。
根据具体使用场景,你可能需要考虑使用不同的模型组合、修改配置,或者按照收到的查询类型校准阈值,以提升性能。
除了使用 Python SDK,你还可以按照类似步骤启动一个兼容 OpenAI 的 server。它能与任何现有的 OpenAI client 配合使用:
> export OPENAI_API_KEY=sk-XXXXXX
> export ANYSCALE_API_KEY=esecret_XXXXXX
> python -m routellm.openai_server --routers mf --strong-model gpt-4-1106-preview --weak-model anyscale/mistralai/Mixtral-8x7B-Instruct-v0.1
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:6060 (Press CTRL+C to quit)
server 启动后,你可以运行本地 router 聊天机器人,查看不同消息是如何被路由的。
python -m examples.router_chat --router mf --threshold 0.11593
上面的示例使用 GPT-4 和 Mixtral 8x7B 作为模型组合,但你可以通过 strong-model 和 weak-model 参数修改它。
我们利用 LiteLLM 支持来自众多开源及闭源模型的 chat completion。通常,你需要设置 API key,并使用恰当的模型名称指向对应的 provider。你也可以使用任意兼容 OpenAI 的 endpoint:只需在模型名称前添加 openai/ 前缀,并设置 --base-url 和 --api-key flag。
需要注意的是,无论使用哪种模型组合,目前 mf 和 sw_ranking router 生成 embedding 时仍然需要 OPENAI_API_KEY。
常用 provider 的 API key 设置说明:
使用 Ollama 运行本地模型:请参阅这份指南。
Gemini:Google AI Studio。
对于其他模型 provider,请在此查找说明或提交 issue。
不同 LLM 的成本和能力差异很大,这给模型部署带来了两难选择:把所有查询都路由到能力最强的模型,可以获得最高质量的响应,但成本可能非常高;把查询路由到较小的模型可以节省成本,却可能导致响应质量下降。
LLM routing 为这个问题提供了解决方案。我们引入了一个 router,它会分析查询,并把较简单的查询路由到更小、更便宜的模型,从而在保持质量的同时节省成本。我们重点研究两个模型之间的路由:一个能力更强、成本更高的模型,以及一个更便宜但能力较弱的模型。每个请求还会关联一个成本阈值,用来决定该请求在成本与质量之间的权衡——成本阈值越高,成本越低,但响应质量也可能随之下降。
本仓库中的研究由我们与 Anyscale 合作完成,感谢他们提供的帮助与支持。
RouteLLM 提供了一个轻量级、兼容 OpenAI 的 server,可以根据不同的路由策略处理请求:
python -m routellm.openai_server --routers mf --config config.example.yaml
--routers 指定 server 可用的 router 列表。例如,这里启动的 server 提供了一个 router:mf(router 完整列表见下文)。
--config 指定 router 配置文件的路径。如果没有指定,server 默认使用性能最好的配置(详情参见“配置”)。
对于大多数使用场景,我们推荐使用 mf router,因为评估结果表明,它不仅性能很强,而且十分轻量。
向 server 发起请求时,client 需要通过 model 字段,按照 router-[ROUTER NAME]-[THRESHOLD] 格式指定每个请求使用的 router 和成本阈值。例如,将 model 设置为 router-mf-0.5,表示该请求应使用阈值为 0.5 的 mf router 进行路由。
路由使用的阈值控制着成本与质量之间的权衡。有效阈值的范围会因 router 类型和收到的查询而异。因此,我们建议使用一部分传入查询作为样本,并结合你希望路由到 strong model 的查询比例来校准阈值。
默认情况下,我们支持基于公开的 Chatbot Arena 数据集校准阈值。例如,可以通过以下方式校准 mf router 的阈值,使 50% 的调用被路由到 strong model:
> python -m routellm.calibrate_threshold --task calibrate --routers mf --strong-model-pct 0.5 --config config.example.yaml
For 50.0% strong model calls for mf, threshold = 0.11593
这意味着 mf router 的阈值应设置为 0.1881,以便将大约 50% 的调用路由到 strong model,也就是使用值为 router-mf-0.1159 的 model 字段。
不过需要注意,由于阈值是基于现有数据集校准的,实际路由到各个模型的调用比例会因收到的真实查询而异。因此,我们建议使用与实际查询类型高度相似的数据集进行校准。
RouteLLM 还包含一个评估框架,用于衡量不同路由策略在 benchmark 上的性能。
要在某个 benchmark 上评估 router,可以使用以下命令:
python -m routellm.evals.evaluate --routers random sw_ranking bert --benchmark gsm8k --config config.example.yaml
--routers 指定要评估的 router 列表,例如这里的 random 和 bert。
--benchmark 指定用来评估 router 的具体 benchmark。当前支持:mmlu、gsm8k 和 mt-bench。
评估结果会打印到控制台,同时还会在当前目录中生成 router 性能图表,你可以使用 --output 覆盖输出路径。为了避免重复计算,默认情况下,router 在给定 benchmark 上的结果会被缓存。你可以使用 --overwrite-cache flag 覆盖这一行为,该 flag 接收一个 router 列表,指定要覆盖哪些 router 的缓存。
我们所有 benchmark 的结果都已缓存。对于 MT Bench,我们使用目标模型组合的预计算评判结果。对于 MMLU 和 GSM8K,我们使用 SGLang 计算目标模型组合的结果。如果你希望评估不同的模型组合,可以在 benchmark 目录中找到完整代码。
默认情况下,评估使用 GPT-4 和 Mixtral 作为模型组合。要修改使用的模型组合,可以通过 --strong-model 和 --weak-model flag 进行设置。
RouteLLM 开箱即用地支持 4 个基于 gpt-4-1106-preview 和 mixtral-8x7b-instruct-v0.1 模型组合训练的 router。
router 完整列表如下:
mf:使用基于偏好数据训练的矩阵分解模型(推荐)。
sw_ranking:使用加权 Elo 计算进行路由,每张选票会根据它与用户 prompt 的相似程度进行加权。
bert:使用基于偏好数据训练的 BERT classifier。
causal_llm:使用基于偏好数据调优的 LLM classifier。
random:随机路由到其中一个模型。
虽然这些 router 是基于 gpt-4-1106-preview 和 mixtral-8x7b-instruct-v0.1 模型组合训练的,但我们发现,它们同样能很好地泛化到其他 strong model 与 weak model 的组合。因此,你可以替换路由使用的模型组合,而无须重新训练这些模型!
我们还在下面的 notebook 中提供了如何训练 LLM classifier 的详细说明。
完整细节请参阅我们的论文。
router 的配置可以通过 Controller 的 config 参数指定,也可以使用 --config flag 传入 YAML 文件路径。它是一个顶层映射,从 router 名称映射到初始化 router 时使用的 keyword argument。
config.example.yaml 文件中提供了配置示例,其中包含基于 Arena 数据训练的 router 配置,这些数据使用 GPT-4 作为 judge 进行了增强。使用的所有模型和数据集都托管在 Hugging Face 的 RouteLLM 和 LMSYS 组织下。
欢迎贡献!如果你有任何建议或改进,请随时提交 issue 或 pull request。
要向 RouteLLM 添加新的 router,请实现 routers.py 中的抽象 Router 类,并把新 router 添加到 ROUTER_CLS 字典中。完成后,你便可以立即在 server 或评估框架中使用这个新 router。
只需要实现一个方法:calculate_strong_win_rate。它接收用户 prompt,并返回 strong model 在给定 prompt 条件下的胜率。如果该胜率大于用户指定的成本阈值,请求就会被路由到 strong model;否则,请求会被路由到 weak model。
要向 RouteLLM 添加新的 benchmark,请实现 benchmarks.py 中的抽象 Benchmark 类,并更新 evaluate.py module,以正确初始化新的 benchmark 类。理想情况下,应当预先计算 benchmark 结果,以避免每次运行评估时重新生成结果——有关具体实现方式,请参考现有 benchmark。
本仓库中的代码基于论文中的研究成果。如果你觉得这个仓库对你有帮助,请引用我们的论文。
@misc{ong2024routellmlearningroutellms,
title={RouteLLM: Learning to Route LLMs with Preference Data},
author={Isaac Ong and Amjad Almahairi and Vincent Wu and Wei-Lin Chiang and Tianhao Wu and Joseph E. Gonzalez and M Waleed Kadous and Ion Stoica},
year={2024},
eprint={2406.18665},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2406.18665},
}