- 模型推理服务
- 人工智能
- 后端
- 大模型
- 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!
从 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注意实现中的两个细节:
- 函数带有
@inject装饰器,arguments通过simple_di从BentoMLContainer.bento_arguments这一静态 provider 中解析——该 provider 在 configuration 容器 中初始化为空字典{}; - 类型重载(
@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 与运行期
写入容器后,参数沿两条路径生效:
- Service 定义期:模块顶层的
args = bentoml.use_arguments(...)在构建/加载service.py时执行,从BentoMLContainer.bento_arguments取到当前 CLI 注入的值,因此@bentoml.service(resources=...)、HuggingFaceModel(args.model_name)等装饰与初始化代码拿到的就是本次运行传入的值; - 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:它把"参数是否齐全、类型是否正确"的检查前移到服务加载之前,错误信息也更可读。
典型应用:一份模板构建多个模型部署
把上述能力组合起来,一个典型的"模型工厂"工作流是:
- 维护一份模板化的
service.py,其中BentoArgs声明model_name(必填)、gpu、gpu_type(带默认值); - 每次需要部署新模型时,仅通过 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- 由于参数被固化在 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!
相关推荐
解锁AHKActionSheet自定义潜能:3种按钮类型与UIAppearance高级技巧
解锁AHKActionSheet自定义潜能:3种按钮类型与UIAppearance高级技巧 AHKActionSheet是一款受Spotify应用启发的UIAc
移动开发WeChatFerry 安装教程:3 步跑通 Python 微信机器人
WeChatFerry 安装教程:3 步跑通 Python 微信机器人 WeChatFerry 是一个通过 hook PC 版微信客户端来运行微信机器人的开源微
txtai Agent 配置完全指南:模型、工具集、指令、模板与记忆参数详解
txtai Agent 配置完全指南:模型、工具集、指令、模板与记忆参数详解 txtai 的 Agent 框架是一个"自动编排"智能体:它接收一个 LLM 与一
人工智能大模型RAGAI Agent向量数据库NLP本地部署
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考