☰
BentoML 模板参数(Template Arguments)完全指南:用 use_arguments() 让同一份 Service 适配任意模型与配置
2026/9/25 3:21:33 网站建设 项目流程
  • 模型推理服务
  • 人工智能
  • 后端
  • 大模型
  • MLOps
  • LLMOps

【免费下载链接】BentoML

The easiest way to serve AI apps and models - Build Model Inference APIs, Job queues, LLM apps, Multi-model pipelines, and more!

项目地址:https://gitcode.com/gh_mirrors/be/BentoML
点击查看免费下载

从 BentoML v1.4.8 起,你可以通过use_arguments()API 为 Service 定义模板参数(template arguments),在serve、build、deploy时传入动态且经过校验的参数。本文将完整覆盖参数 schema 的定义(Pydantic 与无校验两种模式)、CLI 传参方式(--arg与--arg-file)、缺参报错行为,并结合仓库源码剖析参数如何经由依赖注入容器流入 Service 代码。读完本文,你能把一份固定的service.py改造为可复用的"模型模板",例如同一份代码分别构建 Llama、DeepSeek 等不同模型的多卡推理 Bento,而无需维护多份几乎相同的源码。

为什么需要模板参数

在真实生产中,同一个推理服务的代码往往是相同的,不同的只是模型名、GPU 数量与 GPU 型号。以往的做法是复制多份service.py或用环境变量层层透传。模板参数把"哪些值是每次构建/部署时才确定的"从代码中显式剥离出来:这些参数在 Python 代码里就是普通变量,可以直接用在service.py的任何位置——包括条件分支、循环和其他动态逻辑中。

对应文档入口为 Configure template arguments,其前置概念(Service 本身)见 Services。

用 Pydantic 定义参数 schema(带默认值与校验)

推荐做法是用pydantic.BaseModel声明参数结构:可以为参数设置默认值,并获得 Pydantic 的类型校验能力。示例如下:

from pydantic import BaseModel import bentoml class BentoArgs(BaseModel): model_name: str gpu: int = 8 gpu_type: str = "nvidia-h200-141gb" args = bentoml.use_arguments(BentoArgs)

要点:

  • model_name没有默认值,是必填参数;
  • gpu默认 8,gpu_type默认nvidia-h200-141gb,均可在 CLI 覆盖;
  • 声明后即可像普通 Python 变量一样引用args,例如:
import bentoml @bentoml.service( resources={ "gpu": args.gpu, "gpu_type": args.gpu_type } ) class LLM: model = bentoml.models.HuggingFaceModel(args.model_name) ...

这里@bentoml.service(resources=...)声明的 GPU 资源数和型号、HuggingFaceModel加载的模型仓库名,都直接来自运行时注入的参数——同一份代码构建出的不同 Bento 会携带不同的资源配置和模型。

从源码看,use_arguments()接收一个可选的 Pydantic 模型参数:传入模型时用model(**arguments)构造实例并触发 Pydantic 校验;校验失败会被包装为带提示信息的InvalidArgument异常(提示通过--arg修正参数)。见 use_arguments 实现:

@inject def use_arguments( model: type[Model] | None = None, *, arguments: dict[str, Any] = Provide[BentoMLContainer.bento_arguments], ) -> Model | types.SimpleNamespace: ... if model is None: return types.SimpleNamespace(**arguments) try: return model(**arguments) except ValidationError as e: raise InvalidArgument( f"Argument error. Please provide correct arguments via --arg option: {e}" ) from e

注意实现中的两个细节:

  1. 函数带有@inject装饰器,arguments通过simple_di从BentoMLContainer.bento_arguments这一静态 provider 中解析——该 provider 在 configuration 容器 中初始化为空字典{};
  2. 类型重载(@overload)区分了两种签名:传入type[Model]返回Model,不传则返回types.SimpleNamespace,静态类型检查可以据此推断属性访问。

不用 Pydantic 定义参数:SimpleNamespace 模式

use_arguments()也可以完全不传 schema 直接调用:

import bentoml args = bentoml.use_arguments() @bentoml.service(resources={"gpu": int(args.gpu)}) class LLM: model = bentoml.models.HuggingFaceModel(args.model_name) ...

此时返回一个包含所有参数值的types.SimpleNamespace对象(对应源码中types.SimpleNamespace(**arguments)分支,见 args.py)。需要明确两个取舍:

  • 没有校验:CLI 传入的所有值都保持字符串类型,因此示例中int(args.gpu)需要手动转换;
  • 没有默认值:schema 模式里由 Pydantic 字段默认值兜底的逻辑在此不可用,缺参时属性访问会直接抛AttributeError。

仓库的单测 fixture 就采用了这种无 schema 用法,测试用 service 把参数直接放进labels:

import bentoml args = bentoml.use_arguments() @bentoml.service(labels={"foo": args.label}) class MyService: pass

这说明模板参数不仅能驱动资源与模型加载,也可以写入labels等元数据,用于后续检索与区分构建产物。

通过 CLI 提供参数值

声明好模板参数后,在以下命令中都可以动态供给参数值:bentoml serve、bentoml build、bentoml deploy(传入 Bento 路径时)、以及bentoml code:

bentoml build --arg model_name=meta-llama/Llama-3.3-70B-Instruct --arg gpu=4 bentoml serve --arg model_name=deepseek-ai/DeepSeek-V3 bentoml deploy --arg model_name=deepseek-ai/DeepSeek-V3 bentoml deployment update <deployment_name> --arg model_tag=$MODEL_TAG --bento ./project/directory # 也可以在 YAML 文件中定义参数并传入 bentoml build --arg-file bento_args.yaml

从源码看,--arg与--arg-file由统一的装饰器build_args_option挂到各命令上,见 build_args_option。该装饰器被bentoml build(bentos.py)、bentoml serve(serve.py)以及deploy相关命令(deployment.py 中create、update、code等命令共 5 处)复用,与文档描述的命令覆盖范围一致。

两个选项的解析行为值得注意:

--arg KEY=VALUE可以重复指定多次(multiple=True)。回调 set_build_args 对每项执行item.partition("=")拆分,若格式不是key=value会直接抛click.BadParameter报错;解析出的键值对最终调用set_arguments(arguments, override=False)写入依赖注入容器。

--arg-file <path>指向一个 YAML 文件(click.Path(exists=True, dir_okay=False)保证文件存在且不是目录)。回调 set_build_args_from_file 用yaml.safe_load读取,YAML 解析失败时抛出Invalid YAML file错误。示例文件格式即普通的键值对:

model_name: deepseek-ai/DeepSeek-V3 gpu: 4

参数合并语义:文件兜底,命令行覆盖

set_arguments的实现揭示了两种来源的合并规则,见 set_arguments:

def set_arguments(arguments: dict[str, Any], override: bool = True) -> None: if not override: arguments |= BentoMLContainer.bento_arguments.get() BentoMLContainer.bento_arguments.set(arguments)

--arg与--arg-file都以override=False调用:新传入的键值与容器内已有值做并集(|=),新传入的值对同名键具有更高优先级。因此若bento_args.yaml与--arg同时指定了同名参数,命令行--arg的值生效——这与 CI/CD 场景中"配置文件提供基线、流水线注入覆盖值"的用法天然契合。

参数如何流转到 Bento 与运行期

写入容器后,参数沿两条路径生效:

  1. Service 定义期:模块顶层的args = bentoml.use_arguments(...)在构建/加载service.py时执行,从BentoMLContainer.bento_arguments取到当前 CLI 注入的值,因此@bentoml.service(resources=...)、HuggingFaceModel(args.model_name)等装饰与初始化代码拿到的就是本次运行传入的值;
  2. Bento 元数据:构建产物会把参数固化进 Bento 对象,Bento 类 的args字段即以BentoMLContainer.bento_arguments.get()作为默认工厂——这使得bentoml deploy --bento <path>这类基于已构建 Bento 的操作也能复用其中固化的参数,而不是重新要求传一遍。

运行期服务侧同样读取该容器:serving 实现 在拉起服务进程前取bento_args参与进程编排。

缺省必填参数时的报错行为

官方文档明确提示:如果缺少必填参数,BentoML 会在执行命令时报错。具体行为因模式而异:

  • Pydantic 模式:model(**arguments)触发ValidationError,被包装为InvalidArgument,错误信息中会提示 "Please provide correct arguments via--argoption"(见 args.py);
  • SimpleNamespace 模式:无默认值兜底,args.某必填字段在属性访问时抛AttributeError;
  • CLI 层:--arg值格式非法(缺=)或--arg-file指向不存在/非法 YAML 时,在参数解析阶段即被 Click 拦截报错。

因此建议优先使用 Pydantic schema:它把"参数是否齐全、类型是否正确"的检查前移到服务加载之前,错误信息也更可读。

典型应用:一份模板构建多个模型部署

把上述能力组合起来,一个典型的"模型工厂"工作流是:

  1. 维护一份模板化的service.py,其中BentoArgs声明model_name(必填)、gpu、gpu_type(带默认值);
  2. 每次需要部署新模型时,仅通过 CLI 传参构建:
# 构建 Llama 3.3 70B 的 4 卡版本 bentoml build --arg model_name=meta-llama/Llama-3.3-70B-Instruct --arg gpu=4 # 构建 DeepSeek-V3 版本(走 YAML 文件) bentoml build --arg-file deepseek_args.yaml # 本地验证 bentoml serve --arg model_name=deepseek-ai/DeepSeek-V3 # 部署并滚动更新既有部署 bentoml deployment update <deployment_name> --arg model_tag=$MODEL_TAG --bento ./project/directory
  1. 由于参数被固化在 Bento 元数据中,bentoml deploy等后续操作可直接基于构建产物工作,无需重复声明参数。

小结

模板参数把"每次部署才确定的值"从 Service 代码中解耦出来:use_arguments(BentoArgs)提供带默认值和 Pydantic 校验的强类型参数,use_arguments()提供轻量的无校验SimpleNamespace;--arg与--arg-file分别支持命令行逐项传参与 YAML 批量传参,且同名键以命令行优先覆盖;参数经BentoMLContainer.bento_arguments依赖注入容器分发,并固化进 Bento 元数据供部署阶段复用。核心实现可进一步阅读 use_arguments 源码、CLI 选项定义 与 测试 fixture。适用前提:该功能自 BentoML v1.4.8 起可用,本文示例均以当前仓库(v1.4.x 开发线)的源码为准。

  • 模型推理服务
  • 人工智能
  • 后端
  • 大模型
  • MLOps
  • LLMOps

【免费下载链接】BentoML

The easiest way to serve AI apps and models - Build Model Inference APIs, Job queues, LLM apps, Multi-model pipelines, and more!

项目地址:https://gitcode.com/gh_mirrors/be/BentoML
点击查看免费下载
上一篇:Go Micro 的 Model 包:让每个服务都拥有类型化数据层(Client、Server、Model 三位一体)
下一篇:Instatic与Web Components服务:企业开发的终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询