RouteLLM 是一个用于服务与评估大语言模型(LLM)路由器的框架。
我们的核心功能包括:
通过 PyPI 安装
pip install "routellm[serve,eval]"
从源码安装
git clone https://github.com/lm-sys/RouteLLM.git
cd RouteLLM
pip install -e .[serve,eval]
让我们通过一个示例,将现有的 OpenAI 客户端替换为在多个 LLM 之间路由查询,而不是只使用单一模型。
mf 路由器初始化 RouteLLM 控制器来替换 OpenAI 客户端。默认情况下,RouteLLM 将使用性能最佳的配置:import os
from routellm.controller import Controller
os.environ["OPENAI_API_KEY"] = "sk-XXXXXX"
# 替换为你的模型提供商,这里我们使用 Anyscale 的 Mixtral。
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 作为强模型,anyscale/mistralai/Mixtral-8x7B-Instruct-v0.1 作为弱模型,并相应设置了 API 密钥。你可以通过更新模型名称来路由到不同的模型对或提供商,详见模型支持。
想路由到本地模型?请查看路由到本地模型。
> python -m routellm.calibrate_threshold --routers mf --strong-model-pct 0.5 --config config.example.yaml
对于 mf 路由器,要达到 50.0% 的强模型调用率,阈值 = 0.11593
这意味着我们希望使用 0.11593 作为阈值,这样大约 50% 的查询(那些最需要 GPT-4 的)将被路由到它(详见阈值校准)。
model 字段,以指定要使用的路由器和阈值:response = client.chat.completions.create(
# 这告诉 RouteLLM 使用 MF 路由器,成本阈值为 0.11593
model="router-mf-0.11593",
messages=[
{"role": "user", "content": "Hello!"}
]
)
就是这样!现在,请求将根据需求在强模型和弱模型之间路由,在保持高质量响应的同时节省成本。
根据你的使用场景,你可能需要考虑使用不同的模型对、修改配置,或根据接收到的查询类型校准阈值以提高性能。
除了使用 Python SDK,你还可以启动一个 OpenAI 兼容的服务器,该服务器可与任何现有的 OpenAI 客户端配合使用,步骤类似:
> 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)
服务器启动后,你可以启动一个本地路由聊天机器人,查看不同消息如何被路由。
python -m examples.router_chat --router mf --threshold 0.11593
在上述示例中,GPT-4 和 Mixtral 8x7B 被用作模型对,但你可以使用 strong-model 和 weak-model 参数进行修改。
我们利用 LiteLLM 来支持来自广泛开源和闭源模型的聊天补全。通常,你需要设置 API 密钥,并使用适当的模型名称指向提供商。或者,你也可以通过为模型名称添加 openai/ 前缀并设置 --base-url 和 --api-key 标志来使用任何 OpenAI 兼容的端点。
请注意,无论使用何种模型对,目前 mf 和 sw_ranking 路由器生成嵌入向量时仍需要 OPENAI_API_KEY。
为流行提供商设置 API 密钥的说明:
- 使用 Ollama 的本地模型:参见本指南
- Anthropic
- Gemini - Google AI Studio
- Amazon Bedrock
- Together AI
- Anyscale Endpoints
对于其他模型提供商,请在此处查找说明此处或提出 issue。
不同 LLM 的成本和能力差异巨大,这在部署时带来了一个两难选择:将所有查询路由到能力最强的模型可以获得最高质量的响应,但成本可能非常高昂;而将查询路由到较小的模型可以节省成本,但可能导致响应质量下降。
LLM 路由为此提供了一个解决方案。我们引入了一个路由器,它查看查询并将简单的查询路由到更小、更便宜的模型,从而在保持质量的同时节省成本。我们专注于在两个模型之间进行路由:一个更强但更贵的模型,以及一个更便宜但更弱的模型。每个请求还与一个成本阈值相关联,该阈值决定了该请求的成本-质量权衡——更高的成本阈值导致更低的成本,但可能导致响应质量下降。
本仓库中的研究是与 Anyscale 合作进行的,我们感谢他们的帮助和支持。
RouteLLM 提供了一个轻量级的 OpenAI 兼容服务器,用于基于不同路由策略路由请求:
python -m routellm.openai_server --routers mf --config config.example.yaml
--routers 指定服务器可用的路由器列表。例如,这里服务器启动时有一个可用的路由器:mf(路由器列表见下文)。--config 指定路由器配置文件的路径。如果未指定,服务器将默认使用我们性能最佳的配置(详情见配置)。对于大多数用例,我们推荐使用 mf 路由器,因为我们评估发现它非常强大且轻量。
向服务器发出请求时,客户端使用 model 字段指定每个请求要使用的路由器和成本阈值,格式为 router-[路由器名称]-[阈值]。例如,使用 model 值为 router-mf-0.5 表示请求应使用 mf 路由器,阈值为 0.5。
用于路由的阈值控制着成本-质量权衡。有意义的阈值范围因路由器类型和接收到的查询而异。因此,我们建议使用传入查询的样本以及你希望路由到强模型的查询百分比来校准阈值。
默认情况下,我们支持基于公开的 Chatbot Arena 数据集校准阈值。例如,为 mf 路由器校准阈值,使得 50% 的调用被路由到强模型:
> python -m routellm.calibrate_threshold --task calibrate --routers mf --strong-model-pct 0.5 --config config.example.yaml
对于 mf 路由器,要达到 50.0% 的强模型调用率,阈值 = 0.11593
这意味着对于 mf 路由器,阈值应设置为 0.1881,以便大约 50% 的调用被路由到强模型,即使用 model 字段值为 router-mf-0.1159。
但是请注意,由于我们是基于现有数据集校准阈值,实际接收到的查询路由到每个模型的百分比会有所不同。因此,我们建议在与接收到的查询类型密切相关的数据集上进行校准。
RouteLLM 还包含一个评估框架,用于衡量不同路由策略在基准测试上的性能。
要在基准测试上评估路由器,可以使用以下命令:
python -m routellm.evals.evaluate --routers random sw_ranking bert --benchmark gsm8k --config config.example.yaml
--routers 指定要评估的路由器列表,例如本例中的 random 和 bert。--benchmark 指定要评估路由器的具体基准测试。目前我们支持:mmlu、gsm8k 和 mt-bench。评估结果将打印到控制台。路由器性能图也会在当前目录生成(可使用 --output 覆盖路径)。为避免重复计算,默认情况下,路由器在给定基准测试上的结果会被缓存。可以通过使用 --overwrite-cache 标志来覆盖此行为,该标志接受一个要覆盖缓存的路由器列表。
我们所有基准测试的结果都已缓存。对于 MT Bench,我们使用预计算的针对所需模型对的判断结果。对于 MMLU 和 GSM8K,我们使用 SGLang 计算了所需模型对的结果——如果你想评估不同的模型对,可以在基准测试目录中找到完整的代码。
默认情况下,评估使用 GPT-4 和 Mixtral 作为模型对。要修改使用的模型对,请使用 --strong-model 和 --weak-model 标志进行设置。
开箱即用,RouteLLM 支持 4 个在 gpt-4-1106-preview 和 mixtral-8x7b-instruct-v0.1 模型对上训练的路由器。
完整路由器列表:
1. mf:使用在偏好数据上训练的矩阵分解模型(推荐)。
2. sw_ranking:使用加权 Elo 计算进行路由,其中每个投票的权重根据其与用户提示的相似度确定。
3. bert:使用在偏好数据上训练的 BERT 分类器。
4. causal_llm:使用在偏好数据上调优的基于 LLM 的分类器。
5. random:随机路由到任一模型。
虽然这些路由器是在 gpt-4-1106-preview 和 mixtral-8x7b-instruct-v0.1 模型对上训练的,但我们发现这些路由器也能很好地泛化到其他强-弱模型对。因此,你可以替换用于路由的模型对,而无需重新训练这些模型!
我们还提供了关于如何训练基于 LLM 的分类器的详细说明,请参见以下笔记本。
完整细节请参阅我们的论文。
路由器的配置通过 Controller 的 config 参数指定,或通过使用 --config 标志传入 YAML 文件路径来指定。它是一个从路由器名称到路由器初始化关键字参数的顶级映射。
config.example.yaml 文件中提供了一个示例配置——它提供了在 Arena 数据上训练的路由器的配置,这些数据使用 GPT-4 作为评判员进行了增强。使用的模型和数据集都托管在 Hugging Face 上,属于 RouteLLM 和 LMSYS 组织。
我们欢迎贡献!如果你有任何建议或改进,请随时提出 issue 或 pull request。
要向 RouteLLM 添加新路由器,请在 routers.py 中实现抽象的 Router 类,并将新路由器添加到 ROUTER_CLS 字典中。然后,你可以立即在服务器或评估框架中使用新路由器。
只需实现一个方法:calculate_strong_win_rate,它接收用户提示并返回强模型在该给定提示下的胜率——如果此胜率大于用户指定的成本阈值,则请求被路由到强模型。否则,路由到弱模型。
要向 RouteLLM 添加新基准测试,请在 benchmarks.py 中实现抽象的 Benchmark 类,并更新 evaluate.py 模块以正确初始化新的基准测试类。理想情况下,基准测试的结果应预先计算,以避免每次评估运行都重新生成结果——请参阅现有基准测试以获取示例。
本仓库中的代码基于论文中的研究。如果你觉得本仓库有帮助,请引用。
@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},
}