llmrouter-lib 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. llmrouter_lib-0.1.0/LICENSE +21 -0
  2. llmrouter_lib-0.1.0/PKG-INFO +595 -0
  3. llmrouter_lib-0.1.0/README.md +527 -0
  4. llmrouter_lib-0.1.0/llmrouter/__init__.py +6 -0
  5. llmrouter_lib-0.1.0/llmrouter/cli/__init__.py +0 -0
  6. llmrouter_lib-0.1.0/llmrouter/cli/router_chat.py +1053 -0
  7. llmrouter_lib-0.1.0/llmrouter/cli/router_inference.py +664 -0
  8. llmrouter_lib-0.1.0/llmrouter/cli/router_main.py +503 -0
  9. llmrouter_lib-0.1.0/llmrouter/cli/router_train.py +354 -0
  10. llmrouter_lib-0.1.0/llmrouter/data/__init__.py +39 -0
  11. llmrouter_lib-0.1.0/llmrouter/data/api_calling_evaluation.py +722 -0
  12. llmrouter_lib-0.1.0/llmrouter/data/data.py +456 -0
  13. llmrouter_lib-0.1.0/llmrouter/data/data_generation.py +545 -0
  14. llmrouter_lib-0.1.0/llmrouter/data/data_loader.py +54 -0
  15. llmrouter_lib-0.1.0/llmrouter/data/generate_llm_embeddings.py +145 -0
  16. llmrouter_lib-0.1.0/llmrouter/evaluation/__init__.py +24 -0
  17. llmrouter_lib-0.1.0/llmrouter/evaluation/batch_evaluator.py +251 -0
  18. llmrouter_lib-0.1.0/llmrouter/evaluation/example.py +128 -0
  19. llmrouter_lib-0.1.0/llmrouter/models/__init__.py +97 -0
  20. llmrouter_lib-0.1.0/llmrouter/models/automix/__init__.py +13 -0
  21. llmrouter_lib-0.1.0/llmrouter/models/automix/data_pipeline.py +1087 -0
  22. llmrouter_lib-0.1.0/llmrouter/models/automix/main_automix.py +235 -0
  23. llmrouter_lib-0.1.0/llmrouter/models/automix/methods.py +597 -0
  24. llmrouter_lib-0.1.0/llmrouter/models/automix/model.py +409 -0
  25. llmrouter_lib-0.1.0/llmrouter/models/automix/router.py +687 -0
  26. llmrouter_lib-0.1.0/llmrouter/models/automix/trainer.py +99 -0
  27. llmrouter_lib-0.1.0/llmrouter/models/base_trainer.py +69 -0
  28. llmrouter_lib-0.1.0/llmrouter/models/causallm_router/__init__.py +4 -0
  29. llmrouter_lib-0.1.0/llmrouter/models/causallm_router/router.py +338 -0
  30. llmrouter_lib-0.1.0/llmrouter/models/causallm_router/trainer.py +189 -0
  31. llmrouter_lib-0.1.0/llmrouter/models/elorouter/__init__.py +4 -0
  32. llmrouter_lib-0.1.0/llmrouter/models/elorouter/router.py +213 -0
  33. llmrouter_lib-0.1.0/llmrouter/models/elorouter/trainer.py +111 -0
  34. llmrouter_lib-0.1.0/llmrouter/models/gmtrouter/__init__.py +8 -0
  35. llmrouter_lib-0.1.0/llmrouter/models/gmtrouter/data_loader.py +486 -0
  36. llmrouter_lib-0.1.0/llmrouter/models/gmtrouter/models.py +370 -0
  37. llmrouter_lib-0.1.0/llmrouter/models/gmtrouter/router.py +337 -0
  38. llmrouter_lib-0.1.0/llmrouter/models/gmtrouter/trainer.py +419 -0
  39. llmrouter_lib-0.1.0/llmrouter/models/graphrouter/__init__.py +4 -0
  40. llmrouter_lib-0.1.0/llmrouter/models/graphrouter/graph_nn.py +229 -0
  41. llmrouter_lib-0.1.0/llmrouter/models/graphrouter/router.py +538 -0
  42. llmrouter_lib-0.1.0/llmrouter/models/graphrouter/trainer.py +87 -0
  43. llmrouter_lib-0.1.0/llmrouter/models/hybrid_llm/__init__.py +4 -0
  44. llmrouter_lib-0.1.0/llmrouter/models/hybrid_llm/router.py +349 -0
  45. llmrouter_lib-0.1.0/llmrouter/models/hybrid_llm/trainer.py +43 -0
  46. llmrouter_lib-0.1.0/llmrouter/models/knnmultiroundrouter/__init__.py +5 -0
  47. llmrouter_lib-0.1.0/llmrouter/models/knnmultiroundrouter/router.py +510 -0
  48. llmrouter_lib-0.1.0/llmrouter/models/knnmultiroundrouter/trainer.py +70 -0
  49. llmrouter_lib-0.1.0/llmrouter/models/knnrouter/__init__.py +4 -0
  50. llmrouter_lib-0.1.0/llmrouter/models/knnrouter/router.py +245 -0
  51. llmrouter_lib-0.1.0/llmrouter/models/knnrouter/trainer.py +42 -0
  52. llmrouter_lib-0.1.0/llmrouter/models/largest_llm/__init__.py +3 -0
  53. llmrouter_lib-0.1.0/llmrouter/models/largest_llm/router.py +269 -0
  54. llmrouter_lib-0.1.0/llmrouter/models/llmmultiroundrouter/__init__.py +3 -0
  55. llmrouter_lib-0.1.0/llmrouter/models/llmmultiroundrouter/router.py +635 -0
  56. llmrouter_lib-0.1.0/llmrouter/models/meta_router.py +154 -0
  57. llmrouter_lib-0.1.0/llmrouter/models/mfrouter/__init__.py +5 -0
  58. llmrouter_lib-0.1.0/llmrouter/models/mfrouter/router.py +280 -0
  59. llmrouter_lib-0.1.0/llmrouter/models/mfrouter/trainer.py +157 -0
  60. llmrouter_lib-0.1.0/llmrouter/models/mlprouter/__init__.py +4 -0
  61. llmrouter_lib-0.1.0/llmrouter/models/mlprouter/router.py +332 -0
  62. llmrouter_lib-0.1.0/llmrouter/models/mlprouter/trainer.py +139 -0
  63. llmrouter_lib-0.1.0/llmrouter/models/router_r1/__init__.py +3 -0
  64. llmrouter_lib-0.1.0/llmrouter/models/router_r1/prompt_pool.py +141 -0
  65. llmrouter_lib-0.1.0/llmrouter/models/router_r1/route_service.py +188 -0
  66. llmrouter_lib-0.1.0/llmrouter/models/router_r1/router.py +418 -0
  67. llmrouter_lib-0.1.0/llmrouter/models/routerdc/__init__.py +9 -0
  68. llmrouter_lib-0.1.0/llmrouter/models/routerdc/dcdata_utils.py +185 -0
  69. llmrouter_lib-0.1.0/llmrouter/models/routerdc/dcdataset.py +162 -0
  70. llmrouter_lib-0.1.0/llmrouter/models/routerdc/dcmodel.py +285 -0
  71. llmrouter_lib-0.1.0/llmrouter/models/routerdc/dcutils.py +114 -0
  72. llmrouter_lib-0.1.0/llmrouter/models/routerdc/router.py +585 -0
  73. llmrouter_lib-0.1.0/llmrouter/models/routerdc/trainer.py +361 -0
  74. llmrouter_lib-0.1.0/llmrouter/models/smallest_llm/__init__.py +3 -0
  75. llmrouter_lib-0.1.0/llmrouter/models/smallest_llm/router.py +269 -0
  76. llmrouter_lib-0.1.0/llmrouter/models/svmrouter/__init__.py +4 -0
  77. llmrouter_lib-0.1.0/llmrouter/models/svmrouter/router.py +227 -0
  78. llmrouter_lib-0.1.0/llmrouter/models/svmrouter/trainer.py +40 -0
  79. llmrouter_lib-0.1.0/llmrouter/plugin_system.py +337 -0
  80. llmrouter_lib-0.1.0/llmrouter/prompts/__init__.py +109 -0
  81. llmrouter_lib-0.1.0/llmrouter/utils/__init__.py +84 -0
  82. llmrouter_lib-0.1.0/llmrouter/utils/api_calling.py +279 -0
  83. llmrouter_lib-0.1.0/llmrouter/utils/arena_conversation.py +188 -0
  84. llmrouter_lib-0.1.0/llmrouter/utils/constants.py +41 -0
  85. llmrouter_lib-0.1.0/llmrouter/utils/conversation.py +187 -0
  86. llmrouter_lib-0.1.0/llmrouter/utils/data_convert.py +584 -0
  87. llmrouter_lib-0.1.0/llmrouter/utils/data_loader.py +68 -0
  88. llmrouter_lib-0.1.0/llmrouter/utils/data_processing.py +293 -0
  89. llmrouter_lib-0.1.0/llmrouter/utils/dataframe_utils.py +16 -0
  90. llmrouter_lib-0.1.0/llmrouter/utils/embeddings.py +133 -0
  91. llmrouter_lib-0.1.0/llmrouter/utils/evaluation.py +690 -0
  92. llmrouter_lib-0.1.0/llmrouter/utils/model_loader.py +106 -0
  93. llmrouter_lib-0.1.0/llmrouter/utils/progress.py +43 -0
  94. llmrouter_lib-0.1.0/llmrouter/utils/prompting.py +155 -0
  95. llmrouter_lib-0.1.0/llmrouter/utils/router_helpers.py +53 -0
  96. llmrouter_lib-0.1.0/llmrouter/utils/setup.py +16 -0
  97. llmrouter_lib-0.1.0/llmrouter/utils/tensor_utils.py +18 -0
  98. llmrouter_lib-0.1.0/llmrouter_lib.egg-info/PKG-INFO +595 -0
  99. llmrouter_lib-0.1.0/llmrouter_lib.egg-info/SOURCES.txt +104 -0
  100. llmrouter_lib-0.1.0/llmrouter_lib.egg-info/dependency_links.txt +1 -0
  101. llmrouter_lib-0.1.0/llmrouter_lib.egg-info/entry_points.txt +2 -0
  102. llmrouter_lib-0.1.0/llmrouter_lib.egg-info/requires.txt +26 -0
  103. llmrouter_lib-0.1.0/llmrouter_lib.egg-info/top_level.txt +1 -0
  104. llmrouter_lib-0.1.0/pyproject.toml +70 -0
  105. llmrouter_lib-0.1.0/setup.cfg +4 -0
  106. llmrouter_lib-0.1.0/tests/test_plugin_system.py +149 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 U Lab @UIUC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,595 @@
1
+ Metadata-Version: 2.4
2
+ Name: llmrouter-lib
3
+ Version: 0.1.0
4
+ Summary: A unified framework for LLM routing and evaluation.
5
+ Author-email: Tao Feng <taofeng2@illinois.edu>, Haozhen Zhang <wazhz14@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 U Lab @UIUC
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/ulab-uiuc/LLMRouter
29
+ Project-URL: Source, https://github.com/ulab-uiuc/LLMRouter
30
+ Project-URL: Bug Tracker, https://github.com/ulab-uiuc/LLMRouter/issues
31
+ Classifier: Programming Language :: Python :: 3
32
+ Classifier: Programming Language :: Python :: 3.10
33
+ Classifier: Programming Language :: Python :: 3.11
34
+ Classifier: License :: OSI Approved :: MIT License
35
+ Classifier: Operating System :: OS Independent
36
+ Classifier: Development Status :: 3 - Alpha
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: Intended Audience :: Science/Research
39
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
40
+ Requires-Python: >=3.10
41
+ Description-Content-Type: text/markdown
42
+ License-File: LICENSE
43
+ Requires-Dist: torch>=2.0
44
+ Requires-Dist: transformers>=4.40
45
+ Requires-Dist: sentencepiece>=0.1.99
46
+ Requires-Dist: numpy>=1.21
47
+ Requires-Dist: pandas>=1.5
48
+ Requires-Dist: scikit-learn>=1.2
49
+ Requires-Dist: pyyaml>=6.0
50
+ Requires-Dist: tqdm>=4.65
51
+ Requires-Dist: datasets>=2.14
52
+ Requires-Dist: pydantic>=2.0
53
+ Requires-Dist: gradio>=4.0
54
+ Requires-Dist: litellm>=1.0
55
+ Requires-Dist: peft>=0.7
56
+ Requires-Dist: torch-geometric>=2.3
57
+ Requires-Dist: scipy>=1.10
58
+ Requires-Dist: protobuf>=3.20
59
+ Provides-Extra: router-r1
60
+ Requires-Dist: vllm==0.6.3; extra == "router-r1"
61
+ Requires-Dist: torch==2.4.0; extra == "router-r1"
62
+ Requires-Dist: openai>=1.0; extra == "router-r1"
63
+ Provides-Extra: all
64
+ Requires-Dist: vllm==0.6.3; extra == "all"
65
+ Requires-Dist: torch==2.4.0; extra == "all"
66
+ Requires-Dist: openai>=1.0; extra == "all"
67
+ Dynamic: license-file
68
+
69
+ <div align="center">
70
+ <img src="assets/logo.png" alt="LLMRouter Logo" width="200">
71
+ </div>
72
+
73
+ <h1 align="center">πŸš€ LLMRouter: An Open-Source Library for LLM Routing</h1>
74
+
75
+
76
+ <div align="center">
77
+ <p>
78
+ <a href="https://www.python.org/downloads/release/python-3109/"><img src="https://img.shields.io/badge/PYTHON-3.10-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="Python"></a>
79
+ <a href="https://github.com/ulab-uiuc/LLMRouter/pulls"><img src="https://img.shields.io/badge/PRS-WELCOME-orange?style=for-the-badge" alt="PRs"></a>
80
+ <a href="https://join.slack.com/t/llmrouteropen-ri04588/shared_invite/zt-3jz3cc6d1-ncwKEHvvWe0OczHx7K5c0g"><img src="https://img.shields.io/badge/SLACK-JOIN%20US-4A154B?style=for-the-badge&logo=slack&logoColor=white" alt="Slack"></a>
81
+ <a href="https://ulab-uiuc.github.io/LLMRouter/" style="text-decoration:none;"><img src="https://img.shields.io/badge/DOCS-ONLINE-0A9EDC?style=for-the-badge&logo=readthedocs&logoColor=white" alt="Docs"></a>
82
+ <!-- <a href="" style="text-decoration:none;"><img src="https://img.shields.io/badge/TWITTER-ANNOUNCEMENTS-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white" alt="Twitter"></a> -->
83
+ <a href="LICENSE"><img src="https://img.shields.io/badge/LICENSE-MIT-2EA44F?style=for-the-badge" alt="License"></a>
84
+ </p>
85
+ </div>
86
+
87
+
88
+
89
+
90
+
91
+
92
+ ## ✨ Introduction
93
+
94
+ <div align="center">
95
+ <img src="assets/llmrouter_.png" alt="LLMRouter Overview" style="width: 100%; max-width: 1000px;">
96
+ </div>
97
+
98
+
99
+ **LLMRouter** is an intelligent routing system designed to optimize LLM inference by dynamically selecting the most suitable model for each query. To achieve intelligent routing, it defines:
100
+
101
+ 1. πŸš€ *Smart Routing*: Automatically routes queries to the optimal LLM based on task complexity, cost, and performance requirements.
102
+ 2. πŸ“Š *Multiple Router Models*: Support for **over 16 routing models**, organized into four major categoriesβ€”**single-round routers, multi-round routers, agentic routers, and personalized routers**β€”covering a wide range of strategies such as KNN, SVM, MLP, Matrix Factorization, Elo Rating, graph-based routing, BERT-based routing, hybrid probabilistic methods, transformed-score routers, and more.
103
+ 3. πŸ› οΈ *Unified CLI*: Complete command-line interface for training, inference, and interactive chat with Gradio-based UI.
104
+ 4. πŸ“ˆ *Data Generation Pipeline*: Complete pipeline for generating training data from 11 benchmark datasets with automatic API calling and evaluation.
105
+
106
+ ## πŸ“° News
107
+
108
+ - πŸš€ **[2025-12]**: **LLMRouter** is officially released - ship smarter 🧠, cost-aware πŸ’Έ LLM routing with 16+ routers 🧭, a unified `llmrouter` CLI πŸ› οΈ, and a plugin workflow for custom routers 🧩.
109
+
110
+ ## πŸ”— Links
111
+
112
+ - [Supported Routers](#-supported-routers)
113
+ - [Installation](#installation)
114
+ - [Use Your Own Dataset](#-preparing-training-data)
115
+ - [Training a Router](#training-a-router)
116
+ - [Running Inference via a Router](#running-inference)
117
+ - [Interactive Chat Interface with a Router](#interactive-chat-interface)
118
+ - [Creating Your Own Routers](#-creating-custom-routers)
119
+ - [Acknowledgments](#-acknowledgments)
120
+ - [Citation](#-citation)
121
+
122
+ ## 🧭 Supported Routers
123
+
124
+ ### Single-Round Routers
125
+ | Router | Training | Inference | Description | Tutorial |
126
+ |--------|:--------:|:---------:|-------------|:--------:|
127
+ | `knnrouter` | βœ… | βœ… | K-Nearest Neighbors based routing | [πŸ“–](llmrouter/models/knnrouter/README.md) |
128
+ | `svmrouter` | βœ… | βœ… | Support Vector Machine based routing | [πŸ“–](llmrouter/models/svmrouter/README.md) |
129
+ | `mlprouter` | βœ… | βœ… | Multi-Layer Perceptron based routing | [πŸ“–](llmrouter/models/mlprouter/README.md) |
130
+ | `mfrouter` | βœ… | βœ… | Matrix Factorization based routing | [πŸ“–](llmrouter/models/mfrouter/README.md) |
131
+ | `elorouter` | βœ… | βœ… | Elo Rating based routing | [πŸ“–](llmrouter/models/elorouter/README.md) |
132
+ | `routerdc` | βœ… | βœ… | Dual Contrastive learning based routing | [πŸ“–](llmrouter/models/routerdc/README.md) |
133
+ | `automix` | βœ… | βœ… | Automatic model mixing | [πŸ“–](llmrouter/models/automix/README.md) |
134
+ | `hybrid_llm` | βœ… | βœ… | Hybrid LLM routing strategy | [πŸ“–](llmrouter/models/hybrid_llm/README.md) |
135
+ | `graphrouter` | βœ… | βœ… | Graph-based routing | [πŸ“–](llmrouter/models/graphrouter/README.md) |
136
+ | `causallm_router` | βœ… | βœ… | Causal Language Model router | [πŸ“–](llmrouter/models/causallm_router/README.md) |
137
+ | `smallest_llm` | N/A | βœ… | Always routes to smallest model | [πŸ“–](llmrouter/models/smallest_llm/README.md) |
138
+ | `largest_llm` | N/A | βœ… | Always routes to largest model | [πŸ“–](llmrouter/models/largest_llm/README.md) |
139
+
140
+ ### Multi-Round Routers
141
+ | Router | Training | Inference | Description | Tutorial |
142
+ |--------|:--------:|:---------:|-------------|:--------:|
143
+ | `router_r1` | [LINK](https://github.com/ulab-uiuc/Router-R1) | βœ… | Pre-trained Router-R1 model for multi-turn conversations | [πŸ“–](llmrouter/models/router_r1/README.md) |
144
+
145
+ ### Personalized Routers
146
+ | Router | Training | Inference | Description | Tutorial |
147
+ |--------|:--------:|:---------:|-------------|:--------:|
148
+ | `gmtrouter` | βœ… | βœ… | Graph-based personalized router with user preference learning | [πŸ“–](llmrouter/models/gmtrouter/README.md) |
149
+
150
+ ### Agentic Routers
151
+ | Router | Training | Inference | Description | Tutorial |
152
+ |--------|:--------:|:---------:|-------------|:--------:|
153
+ | `knnmultiroundrouter` | βœ… | βœ… | KNN-based agentic router for complex tasks | [πŸ“–](llmrouter/models/knnmultiroundrouter/README.md) |
154
+ | `llmmultiroundrouter` | N/A | βœ… | LLM-based agentic router for complex tasks | [πŸ“–](llmrouter/models/llmmultiroundrouter/README.md) |
155
+
156
+ ## πŸš€ Get Started
157
+
158
+ ### Installation
159
+
160
+ #### Install from source
161
+
162
+ Clone the repository and install in editable mode using a virtual environment (e.g., with anaconda3):
163
+
164
+ ```bash
165
+ # Clone the repository
166
+ git clone https://github.com/ulab-uiuc/LLMRouter.git
167
+ cd LLMRouter
168
+
169
+ # Create and activate virtual environment
170
+ conda create -n llmrouter python=3.10
171
+ conda activate llmrouter
172
+
173
+ # Install the package (base installation)
174
+ pip install -e .
175
+
176
+ # Optional: Install with RouterR1 support (requires GPU)
177
+ # RouterR1 is tested with vllm==0.6.3 (torch==2.4.0); the extra pins these versions.
178
+ pip install -e ".[router-r1]"
179
+
180
+ # Optional: Install all optional dependencies
181
+ pip install -e ".[all]"
182
+ ```
183
+
184
+ #### Install from PyPI
185
+
186
+ ```bash
187
+ pip install llmrouter-lib
188
+ ```
189
+
190
+ ### πŸ”‘ Setting Up API Keys
191
+
192
+ LLMRouter requires API keys to make LLM API calls for inference, chat, and data generation. Set the `API_KEYS` environment variable using one of the following formats:
193
+
194
+ **JSON Array Format** (recommended for multiple keys):
195
+ ```bash
196
+ export API_KEYS='["your-key-1", "your-key-2", "your-key-3"]'
197
+ ```
198
+
199
+ **Comma-Separated Format** (alternative for multiple keys):
200
+ ```bash
201
+ export API_KEYS='key1,key2,key3'
202
+ ```
203
+
204
+ **Single Key** (for one API key):
205
+ ```bash
206
+ export API_KEYS='your-api-key'
207
+ ```
208
+
209
+ **Note**:
210
+ - API keys are used for **inference**, **chat interface**, and **data generation** (Step 3 of the pipeline)
211
+ - Multiple keys enable automatic load balancing across API calls
212
+ - The environment variable must be set before running inference, chat, or data generation commands
213
+ - For persistent setup, add the export command to your shell profile (e.g., `~/.bashrc` or `~/.zshrc`)
214
+
215
+ ### 🌐 Configuring API Endpoints
216
+
217
+ API endpoints can be specified at two levels (resolved in priority order):
218
+
219
+ 1. **Per-Model** (highest priority): `api_endpoint` field in LLM candidate JSON (`default_llm.json`)
220
+ 2. **Router-Level** (fallback): `api_endpoint` field in router YAML config
221
+ 3. **Error**: Raises descriptive error if neither is specified
222
+
223
+ **LLM Candidate JSON** (per-model endpoints):
224
+ ```json
225
+ {
226
+ "qwen2.5-7b-instruct": {
227
+ "model": "qwen/qwen2.5-7b-instruct",
228
+ "api_endpoint": "https://integrate.api.nvidia.com/v1",
229
+ ...
230
+ },
231
+ "custom-model": {
232
+ "model": "custom/model-name",
233
+ "api_endpoint": "https://api.customprovider.com/v1",
234
+ ...
235
+ }
236
+ }
237
+ ```
238
+
239
+ **Router YAML** (default endpoint):
240
+ ```yaml
241
+ api_endpoint: 'https://integrate.api.nvidia.com/v1' # Fallback for all models
242
+ ```
243
+
244
+ **Benefits**: Different models can use different providers; easy migration; backward compatible with router configs.
245
+
246
+ For details, see [Data Generation Pipeline documentation](llmrouter/data/README.md#llm-data-json-default_llmjson).
247
+
248
+ ### πŸ“Š Preparing Training Data
249
+
250
+ LLMRouter includes a complete data generation pipeline that transforms raw benchmark datasets into formatted routing data with embeddings. The pipeline supports 11 diverse benchmark datasets including Natural QA, Trivia QA, MMLU, GPQA, MBPP, HumanEval, GSM8K, CommonsenseQA, MATH, OpenbookQA, and ARC-Challenge.
251
+
252
+ #### Pipeline Overview
253
+
254
+ The data generation pipeline consists of three main steps:
255
+
256
+ 1. **Generate Query Data** - Extract queries from benchmark datasets and create train/test split JSONL files
257
+ 2. **Generate LLM Embeddings** - Create embeddings for LLM candidates from their metadata
258
+ 3. **API Calling & Evaluation** - Call LLM APIs, evaluate responses, and generate unified embeddings + routing data
259
+
260
+ #### Quick Start
261
+
262
+ Start with the sample configuration file:
263
+
264
+ ```bash
265
+ # Step 1: Generate query data
266
+ python llmrouter/data/data_generation.py --config llmrouter/data/sample_config.yaml
267
+
268
+ # Step 2: Generate LLM embeddings
269
+ python llmrouter/data/generate_llm_embeddings.py --config llmrouter/data/sample_config.yaml
270
+
271
+ # Step 3: API calling & evaluation (requires API_KEYS - see "Setting Up API Keys" section above)
272
+ python llmrouter/data/api_calling_evaluation.py --config llmrouter/data/sample_config.yaml --workers 100
273
+ ```
274
+
275
+ #### Output Files
276
+
277
+ The pipeline generates the following files:
278
+
279
+ - **Query Data** (JSONL): `query_data_train.jsonl` and `query_data_test.jsonl` - Query data with train/test split
280
+ - **LLM Embeddings** (JSON): `default_llm_embeddings.json` - LLM metadata with embeddings
281
+ - **Query Embeddings** (PyTorch): `query_embeddings_longformer.pt` - Unified embeddings for all queries
282
+ - **Routing Data** (JSONL): `default_routing_train_data.jsonl` and `default_routing_test_data.jsonl` - Complete routing data with model responses, performance scores, and token usage
283
+
284
+ **Example routing data entry:**
285
+ ```json
286
+ {
287
+ "task_name": "gsm8k",
288
+ "query": "Janet has 4 apples. She gives 2 to Bob. How many does she have left?",
289
+ "ground_truth": "2",
290
+ "metric": "GSM8K",
291
+ "model_name": "llama3-chatqa-1.5-8b",
292
+ "response": "Janet has 4 apples and gives 2 to Bob, so she has 4 - 2 = 2 apples left.",
293
+ "performance": 1.0,
294
+ "embedding_id": 42,
295
+ "token_num": 453
296
+ }
297
+ ```
298
+
299
+ #### Configuration
300
+
301
+ All paths and parameters are controlled via YAML configuration. The sample config file (`llmrouter/data/sample_config.yaml`) references the example data directory and can be used as-is or customized for your setup.
302
+
303
+ **Note**: Step 3 requires API keys for calling LLM services. See the [Setting Up API Keys](#-setting-up-api-keys) section above for configuration details.
304
+
305
+ For complete documentation including detailed file formats, embedding mapping system, configuration options, and troubleshooting, see **[llmrouter/data/README.md](llmrouter/data/README.md)**.
306
+
307
+ ### Training a Router
308
+
309
+ Before training, ensure you have prepared your data using the [Data Generation Pipeline](#-preparing-training-data) or use the example data in `data/example_data/`.
310
+
311
+ Train various router models with your configuration:
312
+ ```bash
313
+ # Train KNN router
314
+ llmrouter train --router knnrouter --config configs/model_config_train/knnrouter.yaml
315
+
316
+ # Train MLP router with GPU
317
+ CUDA_VISIBLE_DEVICES=2 llmrouter train --router mlprouter --config configs/model_config_train/mlprouter.yaml --device cuda
318
+
319
+ # Train MF router quietly
320
+ CUDA_VISIBLE_DEVICES=1 llmrouter train --router mfrouter --config configs/model_config_train/mfrouter.yaml --device cuda --quiet
321
+ ```
322
+
323
+ ### Running Inference
324
+
325
+ Perform inference with trained routers (requires API keys - see [Setting Up API Keys](#-setting-up-api-keys) section):
326
+ ```bash
327
+ # Single query inference
328
+ llmrouter infer --router knnrouter --config config.yaml --query "What is machine learning?"
329
+
330
+ # Batch inference from file
331
+ llmrouter infer --router knnrouter --config config.yaml --input queries.txt --output results.json
332
+
333
+ # Route only (without calling LLM API - no API keys needed)
334
+ llmrouter infer --router knnrouter --config config.yaml --query "Hello" --route-only
335
+
336
+ # Custom generation parameters
337
+ llmrouter infer --router knnrouter --config config.yaml --query "Explain AI" --temp 0.7 --max-tokens 2048 --verbose
338
+ ```
339
+
340
+ Input file formats supported: `.txt` (one query per line), `.json` (list of strings or objects with `"query"` field), `.jsonl` (one JSON object per line).
341
+
342
+ ### Interactive Chat Interface
343
+
344
+ <div style="text-align:center;">
345
+ <img src="assets/llmrouter_chat.gif" style="width: 100%; height: auto;">
346
+ </div>
347
+
348
+ <p align="center">
349
+ <strong>πŸ“± Quick Preview:</strong> Animated overview of the LLMRouter chat interface showing real-time routing and model selection.
350
+ </p>
351
+
352
+ <div style="text-align:center;">
353
+ <video width="100%" controls style="max-width: 800px; height: auto;">
354
+ <source src="assets/llmrouter_chat_demo.mov" type="video/quicktime">
355
+ Your browser does not support the video tag.
356
+ </video>
357
+ </div>
358
+
359
+ Launch the chat interface (requires API keys - see [Setting Up API Keys](#-setting-up-api-keys) section):
360
+
361
+ ```bash
362
+ # Basic chat interface
363
+ llmrouter chat --router knnrouter --config config.yaml
364
+
365
+ # Custom host and port
366
+ llmrouter chat --router knnrouter --config config.yaml --host 0.0.0.0 --port 7860
367
+
368
+ # With public sharing link
369
+ llmrouter chat --router knnrouter --config config.yaml --share
370
+
371
+ # Specify query mode
372
+ llmrouter chat --router knnrouter --config config.yaml --mode full_context --top_k 5
373
+ ```
374
+
375
+ Query Modes:
376
+ - `current_only`: Routes based on current query only (default)
377
+ - `full_context`: Combines all chat history with current query
378
+ - `retrieval`: Retrieves top-k similar historical queries for context
379
+
380
+ ### Direct Script Execution
381
+
382
+ You can also run the CLI scripts directly:
383
+ ```bash
384
+ # Training
385
+ python -m llmrouter.cli.router_train --router knnrouter --config config.yaml
386
+
387
+ # Inference
388
+ python -m llmrouter.cli.router_inference --router knnrouter --config config.yaml --query "Hello"
389
+
390
+ # Chat
391
+ python -m llmrouter.cli.router_chat --router knnrouter --config config.yaml
392
+ ```
393
+
394
+ ## πŸ”§ Creating Custom Routers
395
+
396
+ LLMRouter supports a **plugin system** that allows you to add custom router implementations without modifying the core codebase. This makes it easy to experiment with new routing strategies or domain-specific routers.
397
+
398
+ ### Quick Start
399
+
400
+ **1. Create your router directory:**
401
+ ```bash
402
+ mkdir -p custom_routers/my_router
403
+ ```
404
+
405
+ **2. Implement your router** (`custom_routers/my_router/router.py`):
406
+ ```python
407
+ from llmrouter.models.meta_router import MetaRouter
408
+ import torch.nn as nn
409
+
410
+ class MyRouter(MetaRouter):
411
+ """Your custom router implementation."""
412
+
413
+ def __init__(self, yaml_path: str):
414
+ # Initialize with a model (can be nn.Identity() for simple routers)
415
+ model = nn.Identity()
416
+ super().__init__(model=model, yaml_path=yaml_path)
417
+
418
+ # Get available LLM names from config
419
+ self.llm_names = list(self.llm_data.keys())
420
+
421
+ def route_single(self, query_input: dict) -> dict:
422
+ """Route a single query to the best LLM."""
423
+ query = query_input['query']
424
+
425
+ # Your custom routing logic here
426
+ # Example: route based on query length
427
+ selected_llm = (self.llm_names[0] if len(query) < 50
428
+ else self.llm_names[-1])
429
+
430
+ return {
431
+ "query": query,
432
+ "model_name": selected_llm,
433
+ "predicted_llm": selected_llm,
434
+ }
435
+
436
+ def route_batch(self, batch: list) -> list:
437
+ """Route multiple queries."""
438
+ return [self.route_single(q) for q in batch]
439
+ ```
440
+
441
+ **3. Create configuration** (`custom_routers/my_router/config.yaml`):
442
+ ```yaml
443
+ data_path:
444
+ llm_data: 'data/example_data/llm_candidates/default_llm.json'
445
+
446
+ hparam:
447
+ # Your hyperparameters here
448
+
449
+ # Optional: Default API endpoint (used as fallback if models don't specify their own)
450
+ # Individual models can override this by specifying api_endpoint in the llm_data JSON file
451
+ api_endpoint: 'https://integrate.api.nvidia.com/v1'
452
+ ```
453
+
454
+ **4. Use your custom router** (same as built-in routers!):
455
+ ```bash
456
+ # Inference
457
+ llmrouter infer --router my_router \
458
+ --config custom_routers/my_router/config.yaml \
459
+ --query "What is machine learning?"
460
+
461
+ # List all routers (including custom ones)
462
+ llmrouter list-routers
463
+ ```
464
+
465
+ ### Plugin Discovery
466
+
467
+ Custom routers are automatically discovered from:
468
+ - `./custom_routers/` (recommended - project directory)
469
+ - `~/.llmrouter/plugins/` (user home directory)
470
+ - `$LLMROUTER_PLUGINS` environment variable (colon-separated paths)
471
+
472
+ ### Example Routers
473
+
474
+ LLMRouter includes example custom routers you can learn from:
475
+
476
+ **RandomRouter** - Simple baseline that randomly selects an LLM
477
+ ```bash
478
+ llmrouter infer --router randomrouter \
479
+ --config custom_routers/randomrouter/config.yaml \
480
+ --query "Hello world"
481
+ ```
482
+
483
+ **ThresholdRouter** - Advanced trainable router with difficulty estimation
484
+ ```bash
485
+ # Train the router
486
+ llmrouter train --router thresholdrouter \
487
+ --config custom_routers/thresholdrouter/config.yaml
488
+
489
+ # Use for inference
490
+ llmrouter infer --router thresholdrouter \
491
+ --config custom_routers/thresholdrouter/config.yaml \
492
+ --query "Explain quantum computing"
493
+ ```
494
+
495
+ ### Documentation
496
+
497
+ For detailed guides on creating custom routers:
498
+ - πŸ“– **Quick Start**: [custom_routers/README.md](custom_routers/README.md)
499
+ - πŸ“– **Implementation Summary**: [CUSTOM_ROUTER_SUMMARY.md](CUSTOM_ROUTER_SUMMARY.md)
500
+
501
+ ### Common Routing Patterns
502
+
503
+ **Rule-based routing:**
504
+ ```python
505
+ def route_single(self, query_input):
506
+ query = query_input['query'].lower()
507
+ if 'code' in query:
508
+ return {"model_name": "code-specialist"}
509
+ elif len(query) < 50:
510
+ return {"model_name": "small-fast-model"}
511
+ else:
512
+ return {"model_name": "large-capable-model"}
513
+ ```
514
+
515
+ **Embedding-based routing:**
516
+ ```python
517
+ from llmrouter.utils import get_longformer_embedding
518
+
519
+ def route_single(self, query_input):
520
+ embedding = get_longformer_embedding(query_input['query'])
521
+ # Use embedding similarity to select best model
522
+ selected = self._find_best_model(embedding)
523
+ return {"model_name": selected}
524
+ ```
525
+
526
+ **Cost-optimized routing:**
527
+ ```python
528
+ def route_single(self, query_input):
529
+ difficulty = self._estimate_difficulty(query_input)
530
+ # Select cheapest model that can handle the difficulty
531
+ for model_name, info in sorted(self.llm_data.items(),
532
+ key=lambda x: x[1]['cost']):
533
+ if info['capability'] >= difficulty:
534
+ return {"model_name": model_name}
535
+ ```
536
+
537
+ <!-- ## Star History
538
+
539
+ [![Star History Chart](https://api.star-history.com/svg?repos=ulab-uiuc/LLMRouter&type=date&legend=top-left)](https://www.star-history.com/#ulab-uiuc/LLMRouter&type=date&legend=top-left) -->
540
+
541
+
542
+ ## πŸ—ΊοΈ TODO
543
+
544
+ - [ ] Improve personalized routers: stronger user profiling, cold-start strategies, and online feedback updates.
545
+ - [ ] Integrate a multimodal router: support image/audio inputs and route by modality + task type to the right multimodal model.
546
+ - [ ] Add continual/online learning to adapt routers to domain drift (e.g., periodic re-training + feedback loops).
547
+
548
+
549
+
550
+ ## πŸ™ Acknowledgments
551
+
552
+ LLMRouter builds upon the excellent research from the community. We gratefully acknowledge the following works that inspired our router implementations:
553
+
554
+ - [**RouteLLM**](https://arxiv.org/abs/2406.18665) - Learning to Route LLMs with Preference Data (ICLR 2025)
555
+ - [**RouterDC**](https://arxiv.org/abs/2409.19886) - Query-Based Router by Dual Contrastive Learning (NeurIPS 2024)
556
+ - [**AutoMix**](https://arxiv.org/abs/2310.12963) - Automatically Mixing Language Models (NeurIPS 2024)
557
+ - [**Hybrid LLM**](https://arxiv.org/abs/2404.14618) - Cost-Efficient and Quality-Aware Query Routing (ICLR 2024)
558
+ - [**GraphRouter**](https://arxiv.org/abs/2410.03834) - A Graph-based Router for LLM Selections (ICLR 2025)
559
+ - [**GMTRouter**](https://arxiv.org/abs/2511.08590) - Personalized LLM Router over Multi-turn User Interactions
560
+ - [**Router-R1**](https://arxiv.org/abs/2506.09033) - Teaching LLMs Multi-Round Routing and Aggregation via RL (NeurIPS 2025)
561
+ - [**FusionFactory**](https://arxiv.org/abs/2507.10540) - Fusing LLM Capabilities with Multi-LLM Log Data
562
+
563
+ We warmly welcome contributions from the community! A powerful open-source router framework requires the collective effort of everyone. If you have developed a new routing method, please consider submitting a PR to add it to LLMRouter. Together, we can build the most comprehensive LLM routing library!
564
+
565
+
566
+
567
+ ## 🀝 Contribution
568
+
569
+ **We warmly welcome new contributors and sincerely thank all current contributors for their valuable contributions.**
570
+
571
+
572
+ </br>
573
+
574
+ <div align="center">
575
+ <a href="https://github.com/ulab-uiuc/LLMRouter/graphs/contributors">
576
+ <img src="https://contrib.rocks/image?repo=ulab-uiuc/LLMRouter" style="border-radius: 15px; box-shadow: 0 0 20px rgba(0, 217, 255, 0.3);" />
577
+ </a>
578
+ </div>
579
+
580
+
581
+
582
+
583
+ ## πŸ“š Citation
584
+
585
+ If you find LLMRouter useful for your research or projects, please cite it as:
586
+
587
+ ```bibtex
588
+ @misc{llmrouter2025,
589
+ title = {LLMRouter: An Open-Source Library for LLM Routing},
590
+ author = {Tao Feng and Haozhen Zhang and Zijie Lei and Haodong Yue and Chongshan Lin and Jiaxuan You},
591
+ year = {2025},
592
+ howpublished = {\url{https://github.com/ulab-uiuc/LLMRouter}},
593
+ note = {GitHub repository}
594
+ }
595
+ ```