自定义模型#

Xinference 提供了一种灵活而全面的方式来集成、管理和应用自定义模型。

无需注册而直接启动自定义模型#

v0.14.0 版本开始,如果你需要注册的模型的家族是 Xinference 内置支持的模型,你可以直接通过 launch 接口中的 model_path 参数来启动它,从而免去注册步骤的麻烦。现在非常推荐使用这种方式。

例如:

xinference launch --model_path <model_file_path> --model-engine <engine> -n qwen1.5-chat

上面的例子展示了当我已有 qwen1.5-chat 模型文件时,如何直接 launch 它。

对于分布式场景,将你的模型文件置于某个 worker ,然后通过 launch 接口的 worker_ipmodel_path 参数来达到直接 launch 的效果。

定义自定义大语言模型#

基于以下模板定义一个自定义大语言模型:

{
  "version": 1,
  "context_length": 2048,
  "model_name": "custom-llama-2-chat",
  "model_lang": [
    "en"
  ],
  "model_ability": [
    "chat"
  ],
  "model_family": "my-llama-2-chat",
  "model_specs": [
    {
      "model_format": "pytorch",
      "model_size_in_billions": 7,
      "quantizations": [
        "none"
      ],
      "model_uri": "file:///path/to/llama-2-chat"
    },
    {
      "model_format": "ggufv2",
      "model_size_in_billions": 7,
      "quantizations": [
        "q4_0",
        "q8_0"
      ],
      "model_file_name_template": "llama-2-chat-7b.{quantization}.gguf"
      "model_uri": "file:///path/to/gguf-file"
    }
  ],
  "chat_template": "{% if messages[0]['role'] == 'system' %}{% set system_message = '<<SYS>>\n' + messages[0]['content'] | trim + '\n<</SYS>>\n\n' %}{% set messages = messages[1:] %}{% else %}{% set system_message = '' %}{% endif %}{% for message in messages %}{% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}{{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }}{% endif %}{% if loop.index0 == 0 %}{% set content = system_message + message['content'] %}{% else %}{% set content = message['content'] %}{% endif %}{% if message['role'] == 'user' %}{{ '<s>' + '[INST] ' + content | trim + ' [/INST]' }}{% elif message['role'] == 'assistant' %}{{ ' ' + content | trim + ' ' + '</s>' }}{% endif %}{% endfor %}",
  "stop_token_ids": [2],
  "stop": []
}
  • model_name: 模型名称。名称必须以字母或数字开头,且只能包含字母、数字、下划线或短划线。

  • context_length: 一个可选的整数,模型支持的最大上下文长度,包括输入和输出长度。如果未定义,默认值为2048个token(约1,500个词)。

  • model_lang: 一个字符串列表,表示模型支持的语言。例如:[‘en’],表示该模型支持英语。

  • model_ability: 一个字符串列表,定义模型的能力。它可以包括像 ‘embed’、’generate’ 和 ‘chat’ 这样的选项。示例表示模型具有 ‘generate’ 的能力。

  • model_family: A required string representing the family of the model you want to register. This parameter must not conflict with any builtin model names.

  • model_specs: 一个包含定义模型规格的对象数组。这些规格包括:
    • model_format: 一个定义模型格式的字符串,可以是 ‘pytorch’ 或 ‘ggufv2’。

    • model_size_in_billions: 一个整数,定义模型的参数量,以十亿为单位。

    • quantizations: 一个字符串列表,定义模型的量化方式。对于 PyTorch 模型,它可以是 “4-bit”、”8-bit” 或 “none”。对于 ggufv2 模型,量化方式应与 model_file_name_template 中的值对应。

    • model_id:代表模型 id 的字符串,可以是该模型对应的 HuggingFace 仓库 id。如果 model_uri 字段缺失,Xinference 将尝试从此id指示的HuggingFace仓库下载该模型。

    • model_uri:表示模型文件位置的字符串,例如本地目录:”file:///path/to/llama-2-7b”。当 model_format 是 ggufv2 ,此字段必须是具体的模型文件路径。而当 model_format 是 pytorch 时,此字段必须是一个包含所有模型文件的目录。

    • model_file_name_template: gguf 模型所需。一个 f-string 模板,用于根据量化定义模型文件名。注意,这里不要填入文件的路径。

  • chat_template:如果 model_ability 中包含 chat ,那么此选项必须配置以生成合适的完整提示词。这是一个 Jinja 模版字符串。通常,你可以在模型目录的 tokenizer_config.json 文件中找到。

  • stop_token_ids:如果 model_ability 中包含 chat ,那么推荐配置此选项以合理控制对话的停止。这是一个包含整数的列表,你可以在模型目录的 generation_config.jsontokenizer_config.json 文件中提取相应的值。

  • stop:如果 model_ability 中包含 chat ,那么推荐配置此选项以合理控制对话的停止。这是一个包含字符串的列表,你可以在模型目录的 tokenizer_config.json 文件中找到 token 值对应的字符串。

定义自定义 embedding 模型#

基于以下模板定义一个自定义 embedding 模型:

{
    "model_name": "custom-bge-base-en",
    "dimensions": 768,
    "max_tokens": 512,
    "language": ["en"],
    "model_id": "BAAI/bge-base-en",
    "model_uri": "file:///path/to/bge-base-en"
}
  • model_name: 模型名称。名称必须以字母或数字开头,且只能包含字母、数字、下划线或短划线。

  • dimensions: 表示 embedding 维度的整型值。

  • max_tokens: 表示 embedding 模型支持的最大输入序列长度的整型值。

  • model_lang: 一个字符串列表,表示模型支持的语言。例如:[‘en’],表示该模型支持英语。

  • model_id: 一个表示模型标识的字符串,类似 HuggingFace 或 ModelScope 使用的标识符。

  • model_uri: 表示模型的 URI 的字符串,例如 “file:///path/to/llama-2-7b”。如果模型 URI 不存在,Xinference 将尝试使用 model_id 从 HuggingFace 或 ModelScope 下载模型。

定义自定义 rerank 模型#

基于以下模板定义一个自定义大语言模型:

{
    "model_name": "custom-bge-reranker-v2-m3",
    "type": "normal",
    "language": ["en", "zh", "multilingual"],
    "model_id": "BAAI/bge-reranker-v2-m3",
    "model_uri": "file:///path/to/bge-reranker-v2-m3"
}
  • model_name: 模型名称。名称必须以字母或数字开头,且只能包含字母、数字、下划线或短划线。

  • type: 表示模型的类型,可选值包括 normalLLM-basedLLM-based layerwise

  • model_lang: 一个字符串列表,表示模型支持的语言。例如:[‘en’],表示该模型支持英语。

  • model_id: 一个表示模型标识的字符串,类似 HuggingFace 或 ModelScope 使用的标识符。

  • model_uri: 表示模型的 URI 的字符串,例如 “file:///path/to/llama-2-7b”。如果模型 URI 不存在,Xinference 将尝试使用 model_id 从 HuggingFace 或 ModelScope 下载模型。

注册一个自定义模型#

以代码的方式注册自定义模型

import json
from xinference.client import Client

with open('model.json') as fd:
    model = fd.read()

# replace with real xinference endpoint
endpoint = 'http://localhost:9997'
client = Client(endpoint)
client.register_model(model_type="<model_type>", model=model, persist=False)

以命令行的方式

xinference register --model-type <model_type> --file model.json --persist

注意将以下部分的 <model_type> 替换为 LLMembeddingrerank

列举内置和自定义模型#

以代码的方式列举内置和自定义模型

registrations = client.list_model_registrations(model_type="<model_type>")

以命令行的方式

xinference registrations --model-type <model_type>

启动自定义模型#

以代码的方式启动自定义模型

uid = client.launch_model(model_name='custom-llama-2', model_format='pytorch')

以命令行的方式

xinference launch --model-name custom-llama-2 --model-format pytorch

使用自定义模型#

以代码的方式调用模型

model = client.get_model(model_uid=uid)
model.generate('What is the largest animal in the world?')

结果为:

{
   "id":"cmpl-a4a9d9fc-7703-4a44-82af-fce9e3c0e52a",
   "object":"text_completion",
   "created":1692024624,
   "model":"43e1f69a-3ab0-11ee-8f69-fa163e74fa2d",
   "choices":[
      {
         "text":"\nWhat does an octopus look like?\nHow many human hours has an octopus been watching you for?",
         "index":0,
         "logprobs":"None",
         "finish_reason":"stop"
      }
   ],
   "usage":{
      "prompt_tokens":10,
      "completion_tokens":23,
      "total_tokens":33
   }
}

或者以命令行的方式,用实际的模型 UID 替换 ${UID}

xinference generate --model-uid ${UID}

注销自定义模型#

以代码的方式注销自定义模型

model = client.unregister_model(model_type="<model_type>", model_name='custom-llama-2')

以命令行的方式

xinference unregister --model-type <model_type> --model-name custom-llama-2