推理提供商文档

如何在 Hub 上注册为推理提供商?

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

如何在 Hub 上注册为推理提供商?

想在 Hugging Face Hub 上列出为推理提供商吗?联系我们吧!

请通过社交网络或在这里联系我们

请注意,第 3 步将要求您的组织将其 Hub 帐户升级到团队或企业计划

本指南详细介绍了在 Hub 上注册为推理提供商的步骤,并提供了实施指南。

  1. 实现标准任务 API - 请遵循我们的任务 API 模式以实现兼容性(参见先决条件)。
  2. 提交 PR 以进行 JS 客户端集成 - 将您的提供商添加到huggingface.js(参见JS 客户端集成)。
  3. 注册模型映射 - 使用我们的模型映射 API 将您的模型与 Hub 模型关联(参见模型映射 API)。
  4. 实现计费端点 - 提供一个计费 API(参见计费)。
  5. 提交 PR 以进行 Python 客户端集成 - 将您的提供商添加到huggingface_hub(参见Python 客户端集成)。
  6. 在服务器端注册您的提供商并提供图标 - 请联系我们以在服务器端添加您的提供商,并提供您的 SVG 图标。
  7. 创建您自己一方的文档 - 在您自己一方添加文档并进行大量沟通。
  8. 添加文档页面 - 在此仓库(huggingface/hub-docs)中打开一个 Pull Request,以在文档中添加特定于提供商的页面。
  9. 分享,分享,再分享 - 大量宣传,以确保您的集成取得最大成功!

1. 先决条件

如果您的实现严格遵循 OpenAI API(用于 LLM 和 VLM),您可能可以跳过此部分的大部分内容。在这种情况下,只需在huggingface.js 上打开一个 PR 即可注册。

了解集成的第一步是查看位于huggingface.js 仓库内的 JS 推理客户端。

这是为我们的模型页面上的推理小部件提供动力的客户端,并且是下游(Python SDK、生成代码片段等)的蓝图实现。

什么是任务?

您会发现推理方法(textToImagechatCompletion 等)的名称与任务名称非常相似。任务,在 HF 生态系统中也称为 pipeline_tag,是模型的类型(基本上是模型具有的输入和输出类型),例如“text-generation”或“text-to-image”。它在模型页面上突出显示,如下所示:

所有可能的任务列表可以在https://huggingface.co/tasks 找到,JS 方法名称列表记录在https://github.com/huggingface/huggingface.js/tree/main/packages/inference 的 README 中。

请注意,chatCompletion 是一个例外,因为它本身不是一个 pipeline_tag。相反,它包括具有 pipeline_tag="text-generation"pipeline_tag="image-text-to-text" 的模型,这些模型被标记为“conversational”。

任务 API 模式

对于每种任务类型,我们都强制执行 API 模式,以便用户可以更轻松地互换使用不同的模型。要兼容,您的第三方 API 必须遵循我们在 HF 模型页面上为每种流水线任务类型期望的“标准”形状 API。

这对于 LLM 来说不是问题,因为所有人都已收敛到 OpenAI API,但对于“text-to-image”或“automatic-speech-recognition”等其他任务来说可能更棘手,因为这些任务不存在标准 API。

例如,您可以在此处找到文本转语音的预期模式:https://github.com/huggingface/huggingface.js/packages/src/tasks/text-to-speech/spec/input.json#L4,其他支持的任务也类似。如果您的 API 对于给定任务与 HF 的不同,那没关系:您可以调整 huggingface.js 中的代码来调用您的模型,即提供某种参数名称和输出名称的“翻译”。但是,API 规范不应特定于模型,而应特定于任务。运行 JS 代码并添加一些测试以确保它运行良好。我们可以在此步骤中提供帮助!

2. JS 客户端集成

在继续下一步之前,请确保您已实施必要的代码以集成 JS 客户端并彻底测试您的实现。以下是步骤:

实现提供商助手(JS)

packages/inference/src/providers/{provider_name}.ts 下创建一个新文件,并复制粘贴以下代码片段。

import { TaskProviderHelper } from "./providerHelper";

export class MyNewProviderTask extends TaskProviderHelper {

	constructor() {
		super("your-provider-name", "your-api-base-url", "task-name");
	}

    override prepareHeaders(params: HeaderParams, binary: boolean): Record<string, string> {
        // Override the headers to use for the request.
        return super.prepareHeaders(params, binary);
    }

	makeRoute(params: UrlParams): string {
        // Return the route to use for the request. e.g. /v1/chat/completions route is commonly use for chat completion.
		throw new Error("Needs to be implemented");
	}

	preparePayload(params: BodyParams): Record<string, unknown> {
        // Return the payload to use for the request, as a dict.
		throw new Error("Needs to be implemented");
	}

	getResponse(response: unknown, outputType?: "url" | "blob"): string | Promise<Blob>{
		// Return the response in the expected format.
        throw new Error("Needs to be implemented");
    }
}

实现需要自定义处理的方法。查看基本实现以检查默认行为。如果您不需要覆盖方法,只需删除它。您至少需要定义 makeRoutepreparePayloadgetResponse

如果提供商支持多个需要不同实现的任务,请为每个任务创建专用子类,遵循现有提供商实现的模式,例如Together AI 提供商实现

对于文本生成和对话任务,您可以分别继承 BaseTextGenerationTaskBaseConversationalTask(在providerHelper.ts 中定义),并在需要时覆盖方法。示例可以在CerebrasFireworks 提供商实现中找到。

注册提供商

转到packages/inference/src/lib/getProviderHelper.ts 并将您的提供商添加到 PROVIDERS。您还需要在packages/inference/src/types.ts 中将您的提供商添加到 INFERENCE_PROVIDERS 列表。请尽量遵守字母顺序。

更新 packages/inference 目录下的README.md,将您的提供商包含在支持的提供商列表中以及支持的模型链接列表中。

3. 模型映射 API

恭喜!您现在拥有了一个 JS 实现,可以成功地在您的基础设施上进行推理调用!是时候集成 Hub 了!

第一步是使用模型映射 API 注册支持哪些 Hub 模型。

完成第 1 步和第 2 步是此步骤的先决条件。要继续此步骤,我们必须在服务器端启用您的帐户。请确保您在 Hub 上有一个公司组织,并将其升级到团队或企业计划

注册映射项

POST /api/partners/{provider}/models

创建一个新的映射项,使用以下主体(JSON 编码):

{
    "task": "WidgetType", // required
    "hfModel": "string", // required: the name of the model on HF: namespace/model-name
    "providerModel": "string", // required: the partner's "model id" i.e. id on your side
    "status": "live" | "staging" // Optional: defaults to "staging". "staging" models are only available to members of the partner's org, then you switch them to "live" when they're ready to go live
}
  • task,在 HF 生态系统中也称为 pipeline_tag,是模型类型/API 类型(例如:“text-to-image”、“text-generation”,但对于聊天模型应使用“conversational”)
  • hfModel 是 Hub 端的模型 ID。
  • providerModel 是您方(可以相同或不同)的模型 ID。通常,我们鼓励您也在您方使用 HF 模型 ID,但这取决于您。

此路由的输出是一个映射 ID,之后您可以使用它来更新映射的状态或删除它。

认证

您需要成为提供商 Hub 组织(例如 TogetherAI 的https://huggingface.co/togethercomputer)的成员,并拥有**写入**权限才能访问此端点。

验证

该端点验证:

  • hfModel 确实是 pipeline_tag == task OR task 为“conversational”且模型兼容(即 pipeline_tag 是“text-generation”或“image-text-to-text” AND 模型被标记为“conversational”)。
  • 创建映射后(异步),我们会自动测试合作伙伴 API 是否能正确处理 Hugging Face JS 推理客户端的调用,以确保 API 规范有效。请参阅下面的自动验证部分。

使用标签过滤器将多个 Hub 模型映射到单个推理端点

我们也支持根据其tags映射 Hub 模型。使用标签过滤器,您可以自动将多个 Hub 模型映射到您方的单个推理端点。例如,任何标记为lorabase_model:adapter:black-forest-labs/FLUX.1-dev 的模型都可以映射到您的 Flux-dev LoRA 推理端点。

重要提示:确保 JS 客户端库可以处理您提供商的 LoRA 权重。有关更多详细信息,请查看fal 的实现

API 如下:

POST /api/partners/{provider}/models

创建一个新的映射项,使用以下主体(JSON 编码):

{
    "type": "tag-filter", // required
    "task": "WidgetType", // required
    "tags": ["string"], // required: any HF model with all of those tags will be mapped to providerModel
    "providerModel": "string", // required: the partner's "model id" i.e. id on your side
    "adapterType": "lora", // required: only "lora" is supported at the moment
    "status": "live" | "staging" // Optional: defaults to "staging". "staging" models are only available to members of the partner's org, then you switch them to "live" when they're ready to go live
}
  • task,在 HF 生态系统中也称为 pipeline_tag,是模型类型/API 类型(例如:“text-to-image”、“text-generation”,但对于聊天模型应使用“conversational”)
  • tags 是要匹配的模型标签集。例如,要匹配 Flux 的所有 LoRA,您可以使用:["lora", "base_model:adapter:black-forest-labs/FLUX.1-dev"]
  • providerModel 是您方(可以与 Hub 模型 ID 相同或不同)的模型 ID。
  • adapterType 是一个字面值,可帮助客户端库解释如何调用您的 API。目前唯一支持的值是 "lora"

此路由的输出是一个映射 ID,之后您可以使用它来更新映射的状态或删除它。

删除映射项

DELETE /api/partners/{provider}/models/{mapping ID}

其中 mapping ID 是创建时获得的映射的 _id 字段。您也可以从列表 API 端点中检索它。

更新映射项的状态

调用此 HTTP PUT 端点

PUT /api/partners/{provider}/models/{mapping ID}/status

使用以下主体(JSON 编码):

{
    "status": "live" | "staging" // The new status, one of "staging" or "live"
}   

其中 mapping ID 是创建时获得的映射的 _id 字段。您也可以从列表 API 端点中检索它。

列出整个映射

GET /api/partners/{provider}/models?status=staging|live

这将获取数据库中的所有映射项。为了清晰起见,输出按任务分组。

这是公开访问的。保持透明默认是有益的,并且有助于调试客户端 SDK 等。

以下是响应示例:

{
    "text-to-image": {
        "black-forest-labs/FLUX.1-Canny-dev": {
            "_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
            "providerId": "black-forest-labs/FLUX.1-canny",
            "status": "live"
        },
        "black-forest-labs/FLUX.1-Depth-dev": {
            "_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
            "providerId": "black-forest-labs/FLUX.1-depth",
            "status": "live"
        },
        "tag-filter=base_model:adapter:stabilityai/stable-diffusion-xl-base-1.0,lora": {
            "_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
            "status": "live",
            "providerId": "sdxl-lora-mutualized",
            "adapterType": "lora",
            "tags": [
                "base_model:adapter:stabilityai/stable-diffusion-xl-base-1.0",
                "lora"
            ]
        }
    },
    "conversational": {
        "deepseek-ai/DeepSeek-R1": {
            "_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
            "providerId": "deepseek-ai/DeepSeek-R1",
            "status": "live"
        }
    },
    "text-generation": {
        "meta-llama/Llama-2-70b-hf": {
            "_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
            "providerId": "meta-llama/Llama-2-70b-hf",
            "status": "live"
        },
        "mistralai/Mixtral-8x7B-v0.1": {
            "_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
            "providerId": "mistralai/Mixtral-8x7B-v0.1",
            "status": "live"
        }
    }
}

自动验证

创建映射后,Hugging Face 会定期执行自动化测试,以确保映射的端点正常工作。

每 6 小时,我们会通过向您的服务发出 API 调用来测试每个模型。如果测试成功,模型将保持激活状态并继续定期测试。但是,如果测试失败(例如,您的服务在推理请求期间返回 HTTP 错误状态),提供商将暂时从活动提供商列表中移除。

失败的映射每小时会重新测试一次。此外,更新模型映射的状态会触发即时验证测试。

验证过程检查以下内容:

  • 推理 API 可达,且 HTTP 调用成功。
  • 输出格式与 Hugging Face JavaScript Inference Client 兼容。
  • 延迟要求已满足
    • 对于对话和文本模型:小于 5 秒(流式模式下到达第一个 token 的时间)。
    • 对于其他任务:小于 30 秒。

对于大型语言模型(LLM),会进行额外的行为测试

  • 工具调用支持。
  • 结构化输出支持。

这些测试包括向模型发送特定的推理请求,并验证响应是否符合预期格式。

4. 计费

对于路由请求(参见下图),即用户通过 HF 进行身份验证时,我们的目的是让用户只支付标准的提供商 API 费率。我们不会收取额外费用,而是直接转嫁提供商的成本。有关定价结构的更多详细信息,请参阅 定价页面

我们建议一种更简单的方式来计算此成本并向用户收费,即要求您通过您自己托管的 HTTP API 提供每个请求的成本。

HTTP API 规范

我们要求您公开一个支持 HTTP POST 请求的 API。请求正文是一个 JSON 编码的对象,其中包含一个请求 ID 列表,用于请求成本。身份验证系统应与您的推理服务相同;例如,使用Bearer token。

POST {your URL here}
Authorization: {authentication info - eg "Bearer token"}
Content-Type: application/json

{
    "requestIds": [
        "deadbeef0",
        "deadbeef1",
        "deadbeef2",
        "deadbeef3"
    ]
}

响应也是 JSON 编码的。响应包含一个对象数组,指定请求的 ID 及其 nano-USD(10^-9 美元)单位的成本。

HTTP/1.1 200 OK
Content-Type: application/json

{
    "requests": [
        { "requestId": "deadbeef0", "costNanoUsd": 100 },
        { "requestId": "deadbeef1", "costNanoUsd": 100 },
        { "requestId": "deadbeef2", "costNanoUsd": 100 },
        { "requestId": "deadbeef3", "costNanoUsd": 100 }
    ]
}

我们的系统将每分钟请求一次此 API 端点,批次最多可达 10,000 个请求。

价格单位

我们要求价格是 **非负整数** 的 **nano-USD**(10^-9 美元)。

如何定义请求 ID

对于您服务的每个请求/生成,您都应该定义一个唯一的请求(或响应)ID,并将其作为响应头提供。我们将使用此 ID 作为上述计费 API 的请求 ID。

作为这些要求的一部分,请告知我们您的 Header 名称。如果您还没有,我们建议使用 Inference-Id 作为示例名称,它应该包含一个 UUID 字符字符串。

示例:在您的推理响应中定义一个 Inference-Id 头。

POST /v1/chat/completions
Content-Type: application/json
[request headers]
[request body]
------
HTTP/1.1 200 OK
Content-Type: application/json
[other request headers]
Inference-Id: unique-id-00131
[response body]

通过 OpenAI /models 路由公开定价

如果您的 API 与 OpenAI 兼容,我们希望您通过 /v1/models 端点公开 LLM 定价信息和上下文长度。

这为我们的 提供商比较表 和其他提供商选择功能(如 :cheapest(选择最便宜的提供商))提供了支持。

我们期望的格式如下

{
    {
      "id": "model-id-0",
      "object": "model",
      "created": 1686935002,
      "owned_by": "organization-owner",
      /// [...] other fields
      "pricing": {
        "input": 0.2, /// Price in US dollars per million input tokens
        "output": 2, /// Price in US dollars per million output tokens
      },
      "context_length": 200000, /// Supported context length in tokens
    },
}

5. Python 客户端集成

在将新提供商添加到 huggingface_hub Python 库之前,请确保已完成所有先前的步骤并在 Hub 上运行一切正常。Python 库中的支持是第二步。

实现提供商辅助器(Python)

src/huggingface_hub/inference/_providers/{provider_name}.py 下创建一个新文件,并复制粘贴以下代码片段。

实现需要自定义处理的方法。请查看基类实现以检查默认行为。如果您不需要覆盖某个方法,只需删除它。至少需要重写 _prepare_payload_as_dict_prepare_payload_as_bytes 中的一个。

如果提供商支持多种需要不同实现的任务,请为每个任务创建专用子类,遵循 fal_ai.py 中显示的模式。

对于文本生成和对话任务,可以分别继承 BaseTextGenerationTaskBaseConversationalTask(在 _common.py 中定义),并在需要时重写方法。示例如 fireworks_ai.py 和 together.py。

from typing import Any, Dict, Optional, Union

from ._common import TaskProviderHelper


class MyNewProviderTaskProviderHelper(TaskProviderHelper):
    def __init__(self):
        """Define high-level parameters."""
        super().__init__(provider=..., base_url=..., task=...)

    def get_response(
        self,
        response: Union[bytes, Dict],
        request_params: Optional[RequestParameters] = None,
    ) -> Any:
        """
        Return the response in the expected format.

        Override this method in subclasses for customized response handling."""
        return super().get_response(response)

    def _prepare_headers(self, headers: Dict, api_key: str) -> Dict:
        """Return the headers to use for the request.

        Override this method in subclasses for customized headers.
        """
        return super()._prepare_headers(headers, api_key)

    def _prepare_route(self, mapped_model: str, api_key: str) -> str:
        """Return the route to use for the request.

        Override this method in subclasses for customized routes.
        """
        return super()._prepare_route(mapped_model)

    def _prepare_payload_as_dict(self, inputs: Any, parameters: Dict, mapped_model: str) -> Optional[Dict]:
        """Return the payload to use for the request, as a dict.

        Override this method in subclasses for customized payloads.
        Only one of `_prepare_payload_as_dict` and `_prepare_payload_as_bytes` should return a value.
        """
        return super()._prepare_payload_as_dict(inputs, parameters, mapped_model)

    def _prepare_payload_as_bytes(
        self, inputs: Any, parameters: Dict, mapped_model: str, extra_payload: Optional[Dict]
    ) -> Optional[bytes]:
        """Return the body to use for the request, as bytes.

        Override this method in subclasses for customized body data.
        Only one of `_prepare_payload_as_dict` and `_prepare_payload_as_bytes` should return a value.
        """
        return super()._prepare_payload_as_bytes(inputs, parameters, mapped_model, extra_payload)

注册提供商

添加测试

6. 添加提供商文档

在 Hugging Face 文档中为您的提供商创建一个专门的文档页面。该页面应包含您的提供商服务的简洁描述,突出对用户的益处,设定关于性能或功能的预期,并包含任何相关细节,如定价模型或数据保留策略。基本上,提供对最终用户有价值的任何信息。

以下是添加您的文档页面的方法

  • 提供您的 Logo:您可以直接将您的 logo 文件(单独的浅色和深色模式版本)发送给我们。这通常是最简单的方法。或者,如果您愿意,可以打开一个 PR 到 huggingface/documentation-images 存储库。如果您选择打开 PR
    • Logo 必须是 .png 格式。
    • 将它们命名为 {provider-name}-light.png{provider-name}-dark.png
    • 请在 PR 中 ping @Wauplin@celinah
  • 创建文档文件
    • 使用现有的提供商页面作为模板。例如,查看 Fal AI 的模板。
    • 文件应位于 scripts/inference-providers/templates/providers/{your-provider-name}.handlebars
  • 提交文档 PR
    • 添加您新的 {provider-name}.handlebars 文件。
    • 更新 合作伙伴表 以包含您的公司或产品。
    • 更新 docs/inference-providers/ 目录中的 _toctree.yml 文件,在“提供商”部分包含您的新文档页面,并保持字母顺序。
    • 更新 scripts/inference-providers/scripts/generate.ts 文件,将您的提供商包含在 PROVIDERS_HUB_ORGSPROVIDERS_URLS 常量中,并保持字母顺序。
    • scripts/inference-providers 存储库的根目录下运行 pnpm install(如果您还没有安装),然后运行 pnpm run generate 来生成文档。
    • 提交所有更改,包括手动编辑的文件(提供商页面、_toctree.yml、合作伙伴表)以及脚本生成的文件的更改。
    • 当您打开 PR 时,请 ping @Wauplin、@SBrandeis、@julien-c 和 @hanouticelina 进行审查。如果您需要任何帮助,请随时与我们联系——我们随时为您服务!

常见问题

问题: 默认情况下,我们在设置页面上按什么顺序列出提供商?

回答: 默认排序是按 HF 在过去 7 天内路由的总请求数排序。此顺序决定了模型页面上的小部件将优先使用哪个提供商(但用户的顺序优先)。

在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.