A unified interface for local Large Language Model(LLM) models and online LLM providers.


License
MIT
Install
pip install ullm==0.5.0

Documentation

ullm

A unified interface for local Large Language Models(LLM) and online LLM providers.

ullm 希望能为本地模型以及众多在线 LLM 服务提供统一的调用方式,使得开发者能够无痛地在不同模型或 LLM 服务之间切换,而无需更改代码。

Note

本项目只专注于为不同 LLM 模型或服务的基础生成功能提供统一接口,包括通用的生成、聊天接口以及最基础的工具调用、视觉理解功能,在此之外的其他相关功能如 Finetuning、Prompt Engineering、Emebedding、RAG、Agent、TTS、ASR 本项目目前并不支持,将来也不会支持。

Warning

本项目会尽可能地遵循语义版本,但在 1.0 版本前可能会发生不兼容的接口变动。

目录

功能与特性

  • 支持 OpenAI 等 21 个在线 LLM 服务,详见「在线服务」一节
  • 支持和 OpenAI 接口兼容的自建服务
  • 支持 Ollama API
  • 配置化的使用方式,为所有不同模型及服务提供统一的初始化方式,详见「使用」一节
  • 本地模型支持
  • 归一化模型名称
  • 为所有模型支持工具调用(对原本不支持的通过自定义 prompt 模板实现)
  • 为不同模型适配对应的 tokenizer,以获得 tokens 数量解决某些 remote model 不返回 tokens 数量的问题
  • 模型配置的管理
  • 多模型路由
  • 单元测试
  • 完善文档
  • 实现流式接口

支持模型

本地模型

TBD

在线服务

平台 Provider ID 模型数量 视觉模型数量 支持工具调用的模型数量 联网模型数量
零一万物 01ai 9 1 0 2
阿里巴巴 alibaba 51 4 7 7
Anthropic anthropic 3 3 3 0
Azure OpenAI azure-openai 20 4 11 0
百川智能 baichuan 10 0 3 5
百度 baidu 51 0 28 14
Cloudflare Workers AI cloudflare 35 0 0 0
Cohere cohere 12 0 4 6
DeepSeek deepseek 2 0 0 0
Google google 13 9 2 0
Groq groq 4 0 4 0
科大讯飞 iflytek 4 0 2 0
MiniMax minimax 6 0 6 0
Moonshot moonshot 3 0 3 0
OpenAI openai 21 5 12 0
OpenRouter openrouter 162 16 162 2
Perplexity perplexity 7 0 0 2
天工 skywork 1 0 0 0
阶跃星辰 stepfun 6 2 0 0
Together AI together 59 0 59 0
智谱 zhipu 5 1 4 2
OpenAI 接口兼容的服务 openai-compatible
Ollama API ollama

安装

pip install ullm

使用

创建模型配置

示例:

model_config = {
    # required fields
    "type": 'remote',
    "model": 'gpt-3.5-turbo',
    "provider": 'openai',
    "api_key": 'sk-************************************************',

    # optional fields
    "max_tokens": 4096,
    "max_input_tokens": 1024,
    "max_output_tokens": 1024,
    "temperature": 0.8,
    "top_p": 1.0,
    "top_k": 50,
    "stop_sequences": ['stop1', 'stop2'],
    "http_proxy": 'https://example-proxy.com',
}

模型配置中必须指定这三个字段

  • type: 指定模型为本地模型(local)还是在线模型(remote),目前仅实现了 remote

  • provider: 指定模型提供方,见前面「支持模型」一节,或者你也可以通过命令行工具来或获取目前支持的在线服务提供方

    ullm list-providers

    会得到如下结果,使用其中的 name 作为配置文件中 provider 的值

    | name              |   models |   visual_models |   tool_models |   online_models |
    |-------------------|----------|-----------------|---------------|-----------------|
    | 01ai              |        3 |               1 |             0 |               0 |
    | alibaba           |       44 |               4 |             6 |               6 |
    | anthropic         |        3 |               3 |             3 |               0 |
    | azure-openai      |       20 |               4 |            11 |               0 |
    | baichuan          |        4 |               0 |             0 |               2 |
    | baidu             |       46 |               0 |            24 |              12 |
    | cohere            |       12 |               0 |             4 |               6 |
    | deepseek          |        2 |               0 |             0 |               0 |
    | google            |        3 |               2 |             2 |               0 |
    | groq              |        4 |               0 |             4 |               0 |
    | iflytek           |        4 |               0 |             2 |               0 |
    | minimax           |        5 |               0 |             5 |               0 |
    | moonshot          |        3 |               0 |             3 |               0 |
    | ollama            |          |                 |               |                 |
    | openai            |       20 |               4 |            11 |               0 |
    | openai-compatible |          |                 |               |                 |
    | openrouter        |      127 |              13 |           127 |               4 |
    | perplexity        |        7 |               0 |             0 |               2 |
    | stepfun           |        3 |               1 |             0 |               0 |
    | zhipu             |        5 |               1 |             4 |               2 |
    
  • model: 指定要使用的模型名字

除这三个字段外,各不同平台的模型可能会有各自的一些必需字段(如 api_key),这些必需字段都在每个模型类的 META 中定义,如 OpenAIModel

class OpenAIModel(OpenAICompatibleModel):
    META = RemoteLanguageModelMetaInfo(
        api_url="https://api.openai.com/v1/chat/completions",
        language_models=[
            # ......
        ],
        visual_language_models=[
            # ......
        ],
        # https://platform.openai.com/docs/guides/function-calling
        tool_models=[
            # ......
        ],
        required_config_fields=["api_key"],
    )

由于支持的平台众多,为方便起见,ullm 在命令行接口中提供了工具来生成示例代码供您修改

ullm print-example --provider openai

会得到如下输出

from ullm import LanguageModel

config = {
    # required fields
    "type": 'remote',
    "model": 'gpt-3.5-turbo',
    "provider": 'openai',
    "api_key": 'sk-************************************************',

    # optional fields
    "max_tokens": 4096,
    "max_input_tokens": 1024,
    "max_output_tokens": 1024,
    "temperature": 0.8,
    "top_p": 1.0,
    "Top_k": 50,
    "stop_sequences": ['stop1', 'stop2'],
    "http_proxy": 'https://example-proxy.com',
}
model = LanguageModel.from_config(config)
messages = [{"role": "user", "content": "Hello!"}]
res = model.chat(messages)
messages.append(res.to_message())
messages.append({"role": "user", "content": "Tell me a joke please!"})
res = model.chat(messages)

生成的示例代码中 required_fields 下方的配置项就是必须配置的。

实例化模型

所有模型的实例化统一通过 LanguageModel 这个类来进行,您不必关心不同模型的具体类名。

from ullm import LanguageModel

model = LanguageModel.from_config(model_config)

如果配置不符合要求,这个过程中可能会报错,具体来说

  • 如果配置中缺失了一些必需字段,会报错
  • 如果模型名称不在支持的模型列表里,会报错

管理模型

ullm 实现了 ModelHub 来提供简易的模型管理,使用它可以

  • 将模型实例的配置注册到 ModelHub

    from ullm import LanguageModel, ModelHub
    
    config = {
        # required fields
        "type": 'remote',
        "model": 'gpt-3.5-turbo',
        "provider": 'openai',
        "api_key": 'sk-************************************************',
    
        # optional fields
        "max_tokens": 4096,
        "max_input_tokens": 1024,
        "max_output_tokens": 1024,
        "temperature": 0.8,
        "top_p": 1.0,
        "Top_k": 50,
        "stop_sequences": ['stop1', 'stop2'],
        "http_proxy": 'https://example-proxy.com',
    }
    model = LanguageModel.from_config(config)
    
    hub = ModelHub()
    hub.register_model(model, "openai:gpt-3.5-turbo")

    或者也可以使用命令行工具来注册模型

    ullm register-model --model-id "openai:gpt-3.5-turbo" --model-config-file openai.json
  • 通过注册时分配的唯一性 Model ID 从 ModelHub 中获取一个模型实例来进行聊天

    model = hub.get_model("openai:gpt-3.5-turbo")
    model.chat([{"role": "user", "content": "Hello"}])

默认情况下 ModelHub 会生成一个 SQLite3 的数据库文件 $HOME/.ullm.db,并在这个数据库中存储已注册的模型实例配置,若希望更改数据库文件路径或使用其他数据库引擎(如 MySQLPostPostgres),可以在实例化 ModelHub 时设置数据库 URL:

  • 使用 SQLite3 并更改数据库文件路径为 /home/user/mymodels.db

    hub = ModelHub("sqlite:////home/user/my.db")
  • 使用 MySQL

    hub = ModelHub("mysql://user:passwd@ip:port/my_db")
  • 使用 Postgres

    hub = ModelHub("postgresql://postgres:my_password@localhost:5432/my_db")

设置生成参数

示例:

generate_config = {
    "temperature": 0.7,
    "max_tokens": None,
    "max_input_tokens": None,
    "max_output_tokens": 1024,
    "top_p": None,
    "top_k": None,
    "stop_sequences": ["stop1", "stop2"],
    "frequency_penalty": None,
    "presence_penalty": None,
    "repetition_penalty": None,
    "tools": None,
    "tool_choice": None,
}

ullm 支持在生成时指定部分生成参数以覆盖模型初始化时指定的一些生成参数,目前的生成参数支持这些

  • temperature: 指定模型使用温度采样生成方法,并控制生成随机程度
  • max_tokens: 指定模型单次计算时支持的最大窗口(输入与输出之和)长度,目前并不生效
  • max_input_tokens: 指定模型支持的最大输入长度,目前仅 cohereollama 支持
  • max_output_tokens: 指定模型生成结果的最大长度
  • top_p: 指定模型采样方法为 Nucleus 采样,并指定采样百分位,与 temperature 冲突
  • top_k: 指定模型生成时采样概率最高的 k 个 token,对部分 LLM 服务如 OpenAI 不生效
  • stop_sequences: 指定模型生成的停止标识
  • frequency_penalty/presence_penalty/repetition_penalty: 用于对模型生成中一些重复行为的惩罚的设置,各家实现并不一致,若需使用请查阅对应 LLM 服务文档
  • tools/tool_choice: 指定模型要调用的工具,目前工具方面的支持还不完善,暂不建议使用

生成参数共有三层,从上到下分别是:运行时生成参数、模型配置指定的参数、LLM 服务自身的默认参数。一个参数若运行时不指定,那么会尝试从模型配置中获取,如果模型配置中也未设置则将使用服务自身的默认值(由外部 LLM API 自身决定)。

生成文本

示例:

model.generate(""补全句子白日依山尽", config=generate_config)

会得到如下结果

GenerationResult(
    model='qwen-turbo',
    stop_reason='stop',
    content='黄河入海流。',
    tool_calls=None,
    input_tokens=29,
    output_tokens=5,
    total_tokens=34,
    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"}'
)

聊天

示例:

system = "你是孙悟空,我是叫作小钻风的小妖怪,现在请你按照以上设定和我进行对话。"
messages = [{"role": "user", "content": "大王叫我来巡山啊,巡完南山巡北山啊"}]
model.chat(messages, system=system, config=generate_config)

会得到如下结果

GenerationResult(
    model='qwen-turbo',
    stop_reason='stop',
    content='嘿,小钻风,你这巡山的勤快劲儿倒也不赖。不过咱们这花果山水帘洞,可不比寻常山头,有啥新鲜事儿没?别告诉我你只找找有没有偷吃桃子的家伙。',
    tool_calls=None,
    input_tokens=50,
    output_tokens=55,
    total_tokens=105,
    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"}'
)

如果想继续对话下去,可以将结果转换为 message 对象加入到 messages 里去

response = model.chat(messages, system=system, config=generate_config)
messages.append(response.to_message())

messages.append({"role": "user", "content": "啊!孙悟空打上门啦!"})
model.chat(messages, system=system, config=generate_config)

会得到如下结果

GenerationResult(
    model='qwen-turbo',
    stop_reason='stop',
    content='哈哈,你这消息还挺灵通的嘛,小钻风。孙悟空那猴子,本事大得很,来找茬儿肯定是为了些过节。你准备好迎战了吗?咱们花果山的兄弟们可不能示弱,得让他见识见识我们妖族的厉害!',
    tool_calls=None,
    input_tokens=122,
    output_tokens=60,
    total_tokens=182,
    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"}'
)

命令行

list-providers

Usage: ullm list-providers [OPTIONS]

  List all remote LLM providers

Options:
  -h, --help  Show this message and exit.

list-supported-models

Usage: ullm list-supported-models [OPTIONS]

  List all remote models

Options:
  --providers TEXT  List models of these providers, separate multi providers
                    with commas
  --only-visual
  --only-online
  --only-tool
  -h, --help        Show this message and exit.

print-example

Usage: ullm print-example [OPTIONS]

  Print code example for a specified remote LLM provider

Options:
  --provider TEXT  [required]
  -h, --help       Show this message and exit.

chat

Usage: ullm chat [OPTIONS]

  A simple chat demo

Options:
  --model TEXT                 Model ID registered in hub, or a model config
                               file  [required]
  --model-hub-db-url TEXT      Model hub database url
  --system TEXT
  --temperature FLOAT
  --max-output-tokens INTEGER
  --keep-turns-num INTEGER
  -h, --help                   Show this message and exit.

register-model

Usage: ullm register-model [OPTIONS]

  Register a new model to hub

Options:
  --db-url TEXT             Model hub database url
  --model-id TEXT           [required]
  --model-config-file TEXT  [required]
  -h, --help                Show this message and exit.

list-models

Usage: ullm list-models [OPTIONS]

  List all registered models

Options:
  --db-url TEXT  Model hub database url
  -h, --help     Show this message and exit.