ullm 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.
ullm-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,424 @@
1
+ Metadata-Version: 2.1
2
+ Name: ullm
3
+ Version: 0.1.0
4
+ Summary: A unified interface for local Large Language Model(LLM) models and online LLM providers.
5
+ Author-email: Linusp <linusp1024@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/monsternlp/ullm
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: pydantic
14
+ Requires-Dist: arrow
15
+ Requires-Dist: websocket-client
16
+ Requires-Dist: requests
17
+ Requires-Dist: python-magic
18
+ Requires-Dist: click
19
+ Provides-Extra: test
20
+ Requires-Dist: pytest; extra == "test"
21
+ Requires-Dist: pytest-cov; extra == "test"
22
+
23
+ <h1 align="center">ullm</h1>
24
+ <p align="center">A unified interface for local Large Language Model(LLM) models and online LLM providers.</p>
25
+ <h4 align="center">
26
+ <a href="https://pypi.org/project/ullm/" target="_blank">
27
+ <img src="https://shields.io/pypi/v/ullm.svg" alt="PyPI Version">
28
+ </a>
29
+ <a href="https://github.com/monsternlp/ullm/actions/workflows/pre-commit.yaml" target="_blank">
30
+ <img src="https://shields.io/github/actions/workflow/status/monsternlp/ullm/pre-commit.yaml?label=pre-commit" alt="Pre-commit status">
31
+ </a>
32
+ <a href="https://github.com/monsternlp/ullm/actions/workflows/publish.yaml" target="_blank">
33
+ <img src="https://shields.io/github/actions/workflow/status/monsternlp/ullm/publish.yaml" alt="Build status">
34
+ </a>
35
+ </h4>
36
+
37
+ ullm 希望能为本地模型以及众多在线 LLM 服务提供统一的调用方式,使得开发者能够无痛地在不同模型或 LLM 服务之间切换,而无需更改代码。
38
+
39
+ > [!NOTE]
40
+ > 本项目只专注于为不同 LLM 模型或服务的基础生成功能提供统一接口,包括通用的生成、聊天接口以及最基础的工具调用、视觉理解功能,在此之外的其他相关功能如 Finetuning、Prompt Engineering、Emebedding、RAG、Agent、TTS、ASR 本项目目前并不支持,将来也不会支持。
41
+
42
+ > [!WARNING]
43
+ > 本项目会尽可能地遵循语义版本,但在 1.0 版本前可能会发生不兼容的接口变动。
44
+
45
+ ## 目录
46
+
47
+ <!-- TOC -->
48
+
49
+ - [功能与特性](#功能与特性)
50
+ - [支持模型](#支持模型)
51
+ - [本地模型](#本地模型)
52
+ - [在线服务](#在线服务)
53
+ - [安装](#安装)
54
+ - [使用](#使用)
55
+ - [创建模型配置](#创建模型配置)
56
+ - [实例化模型](#实例化模型)
57
+ - [设置生成参数](#设置生成参数)
58
+ - [生成文本](#生成文本)
59
+ - [聊天](#聊天)
60
+ - [命令行](#命令行)
61
+ - [list-providers](#list-providers)
62
+ - [list-models](#list-models)
63
+ - [print-example](#print-example)
64
+ - [chat](#chat)
65
+
66
+ <!-- /TOC -->
67
+
68
+ ## 功能与特性
69
+
70
+ - 支持 OpenAI 等 18 个在线 LLM 服务,详见「[在线服务](#在线服务)」一节
71
+ - 支持和 OpenAI 接口兼容的自建服务
72
+ - 支持 Ollama API
73
+ - 配置化的使用方式,为所有不同模型及服务提供统一的初始化方式,详见「[使用](#使用)」一节
74
+ - [ ] 本地模型支持
75
+ - [ ] 为所有模型支持工具调用(对原本不支持的通过自定义 prompt 模板实现)
76
+ - [ ] 模型配置的管理
77
+ - [ ] 多模型路由
78
+ - [ ] 单元测试
79
+ - [ ] 完善文档
80
+ - [ ] 实现流式接口
81
+
82
+ ## 支持模型
83
+
84
+ ### 本地模型
85
+
86
+ TBD
87
+
88
+ ### 在线服务
89
+
90
+ | 平台 | Provider ID | 模型数量 | 视觉模型数量 | 支持工具调用的模型数量 | 联网模型数量 |
91
+ |------|-------------------|----------|--------------|------------------------|--------------|
92
+ | [零一万物](https://platform.lingyiwanwu.com/docs) | 01ai | 3 | 1 | 0 | 0 |
93
+ | [阿里巴巴](https://help.aliyun.com/zh/dashscope/developer-reference/model-square/?spm=a2c4g.11186623.0.0.1cca23edHYSGqT) | alibaba | 44 | 4 | 6 | 6 |
94
+ | [Anthropic](https://docs.anthropic.com/claude/reference/getting-started-with-the-api) | anthropic | 3 | 3 | 3 | 0 |
95
+ | [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions) | azure-openai | 20 | 4 | 11 | 0 |
96
+ | [百川智能](https://platform.baichuan-ai.com/docs/api) | baichuan | 4 | 0 | 0 | 2 |
97
+ | [百度](https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Nlks5zkzu) | baidu | 46 | 0 | 24 | 12 |
98
+ | [Cohere](https://docs.cohere.com/reference/about) | cohere | 12 | 0 | 4 | 6 |
99
+ | [DeepSeek](https://platform.deepseek.com/docs) | deepseek | 2 | 0 | 0 | 0 |
100
+ | [Google](https://ai.google.dev/gemini-api/docs) | google | 3 | 2 | 2 | 0 |
101
+ | [Groq](https://console.groq.com/docs/quickstart) | groq | 4 | 0 | 4 | 0 |
102
+ | [科大讯飞](https://www.xfyun.cn/doc/spark/%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E.html) | iflytek | 4 | 0 | 2 | 0 |
103
+ | [MiniMax](https://www.minimaxi.com/document/algorithm-concept?id=6433f37594878d408fc8295d) | minimax | 5 | 0 | 5 | 0 |
104
+ | [Moonshot](https://platform.moonshot.cn/docs/api/chat#%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF) | moonshot | 3 | 0 | 3 | 0 |
105
+ | [OpenAI](https://platform.openai.com/docs/api-reference/chat) | openai | 20 | 4 | 11 | 0 |
106
+ | [OpenRouter](https://openrouter.ai/docs) | openrouter | 127 | 13 | 127 | 4 |
107
+ | [Perplexity](https://docs.perplexity.ai/docs/getting-started) | perplexity | 7 | 0 | 0 | 2 |
108
+ | [阶跃星辰](https://platform.stepfun.com/docs/Chat/chat-completion-create) | stepfun | 3 | 1 | 0 | 0 |
109
+ | [智谱](https://open.bigmodel.cn/dev/api) | zhipu | 5 | 1 | 4 | 2 |
110
+ | OpenAI 接口兼容的服务 | openai-compatible | | | | |
111
+ | Ollama API | ollama | | | | |
112
+
113
+
114
+ ## 安装
115
+
116
+ ```shell
117
+ pip install ullm
118
+ ```
119
+
120
+ ## 使用
121
+
122
+ ### 创建模型配置
123
+
124
+ 示例:
125
+
126
+ ```python
127
+ model_config = {
128
+ # required fields
129
+ "type": 'remote',
130
+ "model": 'gpt-3.5-turbo',
131
+ "provider": 'openai',
132
+ "api_key": 'sk-************************************************',
133
+
134
+ # optional fields
135
+ "max_tokens": 4096,
136
+ "max_input_tokens": 1024,
137
+ "max_output_tokens": 1024,
138
+ "temperature": 0.8,
139
+ "top_p": 1.0,
140
+ "top_k": 50,
141
+ "stop_sequences": ['stop1', 'stop2'],
142
+ "http_proxy": 'https://example-proxy.com',
143
+ }
144
+
145
+ ```
146
+
147
+ 模型配置中必须指定这三个字段
148
+
149
+ - type: 指定模型为本地模型(`local`)还是在线模型(`remote`),目前仅实现了 remote
150
+ - provider: 指定模型提供方,见前面「[支持模型](#支持模型)」一节,或者你也可以通过命令行工具来或获取目前支持的在线服务提供方
151
+
152
+ ```shell
153
+ ullm list-providers
154
+ ```
155
+
156
+ 会得到如下结果,使用其中的 name 作为配置文件中 `provider` 的值
157
+
158
+ ```
159
+ | name | models | visual_models | tool_models | online_models |
160
+ |-------------------|----------|-----------------|---------------|-----------------|
161
+ | 01ai | 3 | 1 | 0 | 0 |
162
+ | alibaba | 44 | 4 | 6 | 6 |
163
+ | anthropic | 3 | 3 | 3 | 0 |
164
+ | azure-openai | 20 | 4 | 11 | 0 |
165
+ | baichuan | 4 | 0 | 0 | 2 |
166
+ | baidu | 46 | 0 | 24 | 12 |
167
+ | cohere | 12 | 0 | 4 | 6 |
168
+ | deepseek | 2 | 0 | 0 | 0 |
169
+ | google | 3 | 2 | 2 | 0 |
170
+ | groq | 4 | 0 | 4 | 0 |
171
+ | iflytek | 4 | 0 | 2 | 0 |
172
+ | minimax | 5 | 0 | 5 | 0 |
173
+ | moonshot | 3 | 0 | 3 | 0 |
174
+ | ollama | | | | |
175
+ | openai | 20 | 4 | 11 | 0 |
176
+ | openai-compatible | | | | |
177
+ | openrouter | 127 | 13 | 127 | 4 |
178
+ | perplexity | 7 | 0 | 0 | 2 |
179
+ | stepfun | 3 | 1 | 0 | 0 |
180
+ | zhipu | 5 | 1 | 4 | 2 |
181
+ ```
182
+
183
+ - `model`: 指定要使用的模型名字
184
+
185
+ 除这三个字段外,各不同平台的模型可能会有各自的一些必需字段(如 `api_key`),这些必需字段都在每个模型类的 META 中定义,如 `OpenAIModel`
186
+
187
+ ```python
188
+ class OpenAIModel(OpenAICompatibleModel):
189
+ META = RemoteLanguageModelMetaInfo(
190
+ api_url="https://api.openai.com/v1/chat/completions",
191
+ language_models=[
192
+ # ......
193
+ ],
194
+ visual_language_models=[
195
+ # ......
196
+ ],
197
+ # https://platform.openai.com/docs/guides/function-calling
198
+ tool_models=[
199
+ # ......
200
+ ],
201
+ required_config_fields=["api_key"],
202
+ )
203
+ ```
204
+
205
+ 由于支持的平台众多,为方便起见,ullm 在命令行接口中提供了工具来生成示例代码供您修改
206
+
207
+ ```shell
208
+ ullm print-example --provider openai
209
+ ```
210
+
211
+ 会得到如下输出
212
+
213
+ ```
214
+ from ullm import LanguageModel
215
+
216
+ config = {
217
+ # required fields
218
+ "type": 'remote',
219
+ "model": 'gpt-3.5-turbo',
220
+ "provider": 'openai',
221
+ "api_key": 'sk-************************************************',
222
+
223
+ # optional fields
224
+ "max_tokens": 4096,
225
+ "max_input_tokens": 1024,
226
+ "max_output_tokens": 1024,
227
+ "temperature": 0.8,
228
+ "top_p": 1.0,
229
+ "Top_k": 50,
230
+ "stop_sequences": ['stop1', 'stop2'],
231
+ "http_proxy": 'https://example-proxy.com',
232
+ }
233
+ model = LanguageModel.from_config(config)
234
+ messages = [{"role": "user", "content": "Hello!"}]
235
+ res = model.chat(messages)
236
+ messages.append(res.to_message())
237
+ messages.append({"role": "user", "content": "Tell me a joke please!"})
238
+ res = model.chat(messages)
239
+ ```
240
+
241
+ 生成的示例代码中 `required_fields` 下方的配置项就是必须配置的。
242
+
243
+ ### 实例化模型
244
+
245
+ 所有模型的实例化统一通过 `LanguageModel` 这个类来进行,您不必关心不同模型的具体类名。
246
+
247
+ ```python
248
+ from ullm import LanguageModel
249
+
250
+ model = LanguageModel.from_config(model_config)
251
+ ```
252
+
253
+ 如果配置不符合要求,这个过程中可能会报错,具体来说
254
+
255
+ - 如果配置中缺失了一些必需字段,会报错
256
+ - 如果模型名称不在支持的模型列表里,会报错
257
+
258
+ ### 设置生成参数
259
+
260
+ 示例:
261
+
262
+ ```python
263
+ generate_config = {
264
+ "temperature": 0.7,
265
+ "max_tokens": None,
266
+ "max_input_tokens": None,
267
+ "max_output_tokens": 1024,
268
+ "top_p": None,
269
+ "top_k": None,
270
+ "stop_sequences": ["stop1", "stop2"],
271
+ "frequency_penalty": None,
272
+ "presence_penalty": None,
273
+ "repetition_penalty": None,
274
+ "tools": None,
275
+ "tool_choice": None,
276
+ }
277
+ ```
278
+
279
+
280
+ ullm 支持在生成时指定部分生成参数以覆盖模型初始化时指定的一些生成参数,目前的生成参数支持这些
281
+
282
+ - `temperature`: 指定模型使用温度采样生成方法,并控制生成随机程度
283
+ - `max_tokens`: 指定模型单次计算时支持的最大窗口(输入与输出之和)长度,目前并不生效
284
+ - `max_input_tokens`: 指定模型支持的最大输入长度,目前仅 `cohere` 和 `ollama` 支持
285
+ - `max_output_tokens`: 指定模型生成结果的最大长度
286
+ - `top_p`: 指定模型采样方法为 Nucleus 采样,并指定采样百分位,与 `temperature` 冲突
287
+ - `top_k`: 指定模型生成时采样概率最高的 k 个 token,对部分 LLM 服务如 `OpenAI` 不生效
288
+ - `stop_sequences`: 指定模型生成的停止标识
289
+ - `frequency_penalty`/`presence_penalty`/`repetition_penalty`: 用于对模型生成中一些重复行为的惩罚的设置,各家实现并不一致,若需使用请查阅对应 LLM 服务文档
290
+ - `tools`/`tool_choice`: 指定模型要调用的工具,目前工具方面的支持还不完善,暂不建议使用
291
+
292
+ 生成参数共有三层,从上到下分别是:运行时生成参数、模型配置指定的参数、LLM 服务自身的默认参数。一个参数若运行时不指定,那么会尝试从模型配置中获取,如果模型配置中也未设置则将使用服务自身的默认值(由外部 LLM API 自身决定)。
293
+
294
+ ### 生成文本
295
+
296
+ 示例:
297
+
298
+ ```python
299
+ model.generate(""补全句子:白日依山尽", config=generate_config)
300
+ ```
301
+
302
+ 会得到如下结果
303
+
304
+ ```python
305
+ GenerationResult(
306
+ model='qwen-turbo',
307
+ stop_reason='stop',
308
+ content='黄河入海流。',
309
+ tool_calls=None,
310
+ input_tokens=29,
311
+ output_tokens=5,
312
+ total_tokens=34,
313
+ original_result='{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":"黄河入海流。"}}]},"usage":{"total_tokens":34,"output_tokens":5,"input_tokens":29},"request_id":"00ccdb48-74a3-9873-851c-79dbfb4b5a8c"}'
314
+ )
315
+ ```
316
+
317
+ ### 聊天
318
+
319
+ 示例:
320
+
321
+ ```python
322
+ system = "你是孙悟空,我是叫作小钻风的小妖怪,现在请你按照以上设定和我进行对话。"
323
+ messages = [{"role": "user", "content": "大王叫我来巡山啊,巡完南山巡北山啊"}]
324
+ model.chat(messages, system=system, config=generate_config)
325
+ ```
326
+
327
+ 会得到如下结果
328
+
329
+ ```python
330
+ GenerationResult(
331
+ model='qwen-turbo',
332
+ stop_reason='stop',
333
+ content='嘿,小钻风,你这巡山的勤快劲儿倒也不赖。不过咱们这花果山水帘洞,可不比寻常山头,有啥新鲜事儿没?别告诉我你只找找有没有偷吃桃子的家伙。',
334
+ tool_calls=None,
335
+ input_tokens=50,
336
+ output_tokens=55,
337
+ total_tokens=105,
338
+ original_result='{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":"嘿,小钻风,你这巡山的勤快劲儿倒也不赖。不过咱们这花果山水帘洞,可不比寻常山头,有啥新鲜事儿没?别告诉我你只找找有没有偷吃桃子的家伙。"}}]},"usage":{"total_tokens":105,"output_tokens":55,"input_tokens":50},"request_id":"774dcfa1-27be-955a-872a-94d8c0eeca2c"}'
339
+ )
340
+ ```
341
+
342
+ 如果想继续对话下去,可以将结果转换为 message 对象加入到 `messages` 里去
343
+
344
+ ```python
345
+ response = model.chat(messages, system=system, config=generate_config)
346
+ messages.append(response.to_message())
347
+
348
+ messages.append({"role": "user", "content": "啊!孙悟空打上门啦!"})
349
+ model.chat(messages, system=system, config=generate_config)
350
+ ```
351
+
352
+ 会得到如下结果
353
+
354
+ ```python
355
+ GenerationResult(
356
+ model='qwen-turbo',
357
+ stop_reason='stop',
358
+ content='哈哈,你这消息还挺灵通的嘛,小钻风。孙悟空那猴子,本事大得很,来找茬儿肯定是为了些过节。你准备好迎战了吗?咱们花果山的兄弟们可不能示弱,得让他见识见识我们妖族的厉害!',
359
+ tool_calls=None,
360
+ input_tokens=122,
361
+ output_tokens=60,
362
+ total_tokens=182,
363
+ original_result='{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":"哈哈,你这消息还挺灵通的嘛,小钻风。孙悟空那猴子,本事大得很,来找茬儿肯定是为了些过节。你准备好迎战了吗?咱们花果山的兄弟们可不能示弱,得让他见识见识我们妖族的厉害!"}}]},"usage":{"total_tokens":182,"output_tokens":60,"input_tokens":122},"request_id":"3de256d0-23bd-93a5-93a6-7bb6e859f9d9"}'
364
+ )
365
+ ```
366
+
367
+ ## 命令行
368
+
369
+ ### `list-providers`
370
+
371
+ ```shell
372
+ Usage: ullm list-providers [OPTIONS]
373
+
374
+ List all remote LLM providers
375
+
376
+ Options:
377
+ -h, --help Show this message and exit.
378
+ ```
379
+
380
+ ### `list-models`
381
+
382
+
383
+ ```
384
+ Usage: ullm list-models [OPTIONS]
385
+
386
+ List all remote models
387
+
388
+ Options:
389
+ --providers TEXT List models of these providers, separate multi providers
390
+ with commas
391
+ --only-visual
392
+ --only-online
393
+ --only-tool
394
+ -h, --help Show this message and exit.
395
+ ```
396
+
397
+ ### `print-example`
398
+
399
+
400
+ ```shell
401
+ Usage: ullm print-example [OPTIONS]
402
+
403
+ Print code example for a specified remote LLM provider
404
+
405
+ Options:
406
+ --provider TEXT [required]
407
+ -h, --help Show this message and exit.
408
+ ```
409
+
410
+ ### `chat`
411
+
412
+ ```shell
413
+ Usage: ullm chat [OPTIONS]
414
+
415
+ A simple chat demo
416
+
417
+ Options:
418
+ -c, --config-file TEXT [required]
419
+ --system TEXT
420
+ --temperature FLOAT
421
+ --max-output-tokens INTEGER
422
+ --keep-turns-num INTEGER
423
+ -h, --help Show this message and exit.
424
+ ```