自定义模型接入

介绍

供应商集成完成后,接下来为供应商下模型的接入,为了帮助理解整个接入过程,我们以Xinference为例,逐步完成一个完整的供应商接入。

需要注意的是,对于自定义模型,每一个模型的接入都需要填写一个完整的供应商凭据。

而不同于预定义模型,自定义供应商接入时永远会拥有如下两个参数,不需要在供应商 yaml 中定义。

在前文中,我们已经知道了供应商无需实现validate_provider_credential,Runtime会自行根据用户在此选择的模型类型和模型名称调用对应的模型层的validate_credentials来进行验证。

编写供应商 yaml

我们首先要确定,接入的这个供应商支持哪些类型的模型。

当前支持模型类型如下:

  • llm 文本生成模型

  • text_embedding 文本 Embedding 模型

  • rerank Rerank 模型

  • speech2text 语音转文字

  • tts 文字转语音

  • moderation 审查

Xinference支持LLMText EmbeddingRerank,那么我们开始编写xinference.yaml

随后,我们需要思考在 Xinference 中定义一个模型需要哪些凭据

  • 它支持三种不同的模型,因此,我们需要有model_type来指定这个模型的类型,它有三种类型,所以我们这么编写

  • 每一个模型都有自己的名称model_name,因此需要在这里定义

  • 填写 Xinference 本地部署的地址

  • 每个模型都有唯一的 model_uid,因此需要在这里定义

现在,我们就完成了供应商的基础定义。

编写模型代码

然后我们以llm类型为例,编写xinference.llm.llm.py

llm.py 中创建一个 Xinference LLM 类,我们取名为 XinferenceAILargeLanguageModel(随意),继承 __base.large_language_model.LargeLanguageModel 基类,实现以下几个方法:

  • LLM 调用

    实现 LLM 调用的核心方法,可同时支持流式和同步返回。

    在实现时,需要注意使用两个函数来返回数据,分别用于处理同步返回和流式返回,因为Python会将函数中包含 yield 关键字的函数识别为生成器函数,返回的数据类型固定为 Generator,因此同步和流式返回需要分别实现,就像下面这样(注意下面例子使用了简化参数,实际实现时需要按照上面的参数列表进行实现):

  • 预计算输入 tokens

    若模型未提供预计算 tokens 接口,可直接返回 0。

    有时候,也许你不需要直接返回0,所以你可以使用self._get_num_tokens_by_gpt2(text: str)来获取预计算的tokens,这个方法位于AIModel基类中,它会使用GPT2的Tokenizer进行计算,但是只能作为替代方法,并不完全准确。

  • 模型凭据校验

    与供应商凭据校验类似,这里针对单个模型进行校验。

  • 模型参数 Schema

    与自定义类型不同,由于没有在 yaml 文件中定义一个模型支持哪些参数,因此,我们需要动态实现模型参数的Schema。

    如Xinference支持max_tokens temperature top_p 这三个模型参数。

    但是有的供应商根据不同的模型支持不同的参数,如供应商OpenLLM支持top_k,但是并不是这个供应商提供的所有模型都支持top_k,我们这里举例 A 模型支持top_k,B模型不支持top_k,那么我们需要在这里动态生成模型参数的 Schema,如下所示:

  • 调用异常错误映射表

    当模型调用异常时需要映射到 Runtime 指定的 InvokeError 类型,方便 Dify 针对不同错误做不同后续处理。

    Runtime Errors:

    • InvokeConnectionError 调用连接错误

    • InvokeServerUnavailableError 调用服务方不可用

    • InvokeRateLimitError 调用达到限额

    • InvokeAuthorizationError 调用鉴权失败

    • InvokeBadRequestError 调用传参有误

接口方法说明见:Interfaces,具体实现可参考:llm.py

Last updated