ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

用 Label Studio ML SDK 从零创建最简机器学习后端(Dummy Model 实战教程)

2026/9/11 18:41:36 拓冰建站 浏览量
用 Label Studio ML SDK 从零创建最简机器学习后端(Dummy Model 实战教程) 用 Label Studio ML SDK 从零创建最简机器学习后端Dummy Model 实战教程【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studioLabel Studio 的 ML Backend 机制允许你把自己训练好的模型包装成独立的 Web 服务与标注平台联动实现自动预标注、交互式标注与模型持续训练。本教程以dummy_model.md文档为核心使用一个只产生随机预测的哑模型Dummy Model串起 ML Backend 的完整生命周期从编写model.py、初始化后端目录、启动开发/生产服务器到连接 Label Studio 项目并获取预测与触发训练。读完本文你将掌握 Label Studio ML SDK 的核心抽象predict()/fit()两个方法以及底层 HTTP 通信协议能够照葫芦画瓢写出自己的第一个可用 ML Backend。为什么需要一个最简单的 ML 后端Label Studio 的 ML Backend 本质上是一个独立运行的 Web 服务Label Studio 平台通过 HTTP 请求向它询问预测结果它返回符合 Label Studio 预测 JSON 格式的应答。其核心价值在于预标注Pre-annotation模型自动为任务生成标签人工标注员只需复核修正交互式标注模型根据标注员的实时操作如圈选、高亮给出建议结果模型评估与微调标注结果反向喂给模型形成标注 → 训练 → 再标注的闭环。本教程的 Dummy Model 虽然不做真实推理但它完整覆盖了上述机制的所有关键环节且不依赖任何第三方深度学习框架——任何分类任务例如使用Choices标签的项目都可以直接复用。它让你先跑通整条链路再把真实模型逻辑替换进去是理解 ML Backend 架构的最佳切入点。适用场景与标注配置示例Dummy Model 对任意分类任务都兼容典型如Choices单选/多选标注。教程文档中给出的图像二分类示例波音 vs 空客如下View Image nameimage value$image/ Choices namechoice toNameimage showInLinetrue Choice valueBoeing backgroundblue/ Choice valueAirbus backgroundgreen / /Choices /View该配置的核心结构是ImageObject 标签声明输入数据nameimage、value$image指向任务 JSON 中的图片字段ChoicesControl 标签定义分类选项toNameimage与 Object 绑定showInLinetrue让选项水平排列Choice是具体的类别值background控制选项在编辑器中的颜色。Dummy Model 在__init__中通过self.parsed_label_config解析这套配置自动提取出from_name这里即choice、to_name即image与labels即[Boeing, Airbus]从而让预测结果与任意标签配置自动对齐——这正是它通吃分类任务的秘诀。编写 model.py继承与两个核心方法创建 ML Backend 的核心工作就是编写一个model.py脚本。文档强调使用 Label Studio 的 ML SDK即label-studio-ml包时脚本必须做到两点模型类继承自label_studio_ml.LabelStudioMLBase重写两个方法predict()接收输入任务Task列表输出 Label Studio JSON 格式的预测结果fit()接收标注Annotation可迭代对象返回包含创建的链接与资源的字典该字典会被保存到self.train_output字段供后续加载模型使用。完整代码清单在./my_backend所在目录下创建文件model.py内容如下from label_studio_ml.model import LabelStudioMLBase class DummyModel(LabelStudioMLBase): def __init__(self, **kwargs): # dont forget to call base class constructor super(DummyModel, self).__init__(**kwargs) # you can preinitialize variables with keys needed to extract info from tasks and annotations and form predictions from_name, schema list(self.parsed_label_config.items())[0] self.from_name from_name self.to_name schema[to_name][0] self.labels schema[labels] def predict(self, tasks, **kwargs): This is where inference happens: model returns the list of predictions based on input list of tasks predictions [] for task in tasks: predictions.append({ score: 0.987, # prediction overall score, visible in the data manager columns model_version: delorean-20151021, # all predictions will be differentiated by model version result: [{ from_name: self.from_name, to_name: self.to_name, type: choices, score: 0.5, # per-region score, visible in the editor value: { choices: [self.labels[0]] } }] }) return predictions def fit(self, annotations, **kwargs): This is where training happens: train your model given list of annotations, then returns dict with created links and resources return {path/to/created/model: my/model.bin}逐段解读__init__构造器必须调用父类构造函数super(DummyModel, self).__init__(**kwargs)。随后利用基类提供的self.parsed_label_config属性解析当前项目的标注配置list(...)[0]取出第一个控制标签如choiceschema[to_name][0]得到其绑定的 Object 标签名如imageschema[labels]得到全部候选类别。把这三个值缓存为实例属性之后predict就能直接使用。predict(self, tasks, **kwargs)这是推理发生的入口。Label Studio 会通过 HTTP 把任务列表 POST 给 ML BackendSDK 把请求体解析成tasks参数传给此方法。每个任务返回一个预测字典score该预测的整体得分0~1会显示在 Data Manager 的预测列中可用于排序与筛选model_version预测对应的模型版本标识Label Studio 用它区分不同模型/不同轮次训练产生的预测本例故意使用一个科幻风格的版本号delorean-20151021展示其自由格式result符合 Label Studio 标注结果格式的列表其中from_name/to_name必须与标签配置一致type: choices对应Choices标签类型value.choices为选中的类别数组内层score是单个区域的置信度显示在标注编辑器内。注意predict必须为每个输入任务返回一个对应的预测条目返回的列表长度与任务数一致否则 Label Studio 会回退到逐任务单发模式甚至判定响应无效详见下文源码分析。fit(self, annotations, **kwargs)训练入口。Label Studio 将带有标注的任务数据序列化后的annotations列表发送给后端。方法体可以执行任意训练逻辑最后返回一个字典描述训练产物如模型文件的链接与路径SDK 会把这个返回值存入self.train_output方便后续predict阶段读取已训练的模型。Dummy Model 只是象征性地返回{path/to/created/model: my/model.bin}。初始化 ML Backend一行命令生成全部配置文档特别指出Label Studio 可以自动生成运行 ML Backend 所需的全部配置与脚本。给后端起名my_backend在命令行执行label-studio-ml init my_backend该命令会读取同级目录下的./model.py并在同一层级创建./my_backend目录把开发模式与生产模式启动所需的配置和脚本一并复制进去。提示可以通过--script参数指定模型脚本的其他位置例如label-studio-ml init my_backend --script /path/to/my/script.py生成的my_backend/目录结构由 ml_create.md 文档可印证大致包含Dockerfile、docker-compose.yml、model.py、_wsgi.pyDocker 启动辅助文件、requirements*.txtPython 依赖清单与test_api.py模型接口测试等。也就是说init命令把写模型逻辑与搭服务运行环境两件事解耦你只需维护model.py其余脚手架由 SDK 代劳。启动 ML Backend 服务器ML Backend 提供两种运行模式取舍的核心在于训练期间是否阻塞预测服务。开发模式单进程、训练期间阻塞在开发模式下训练与推理在同一个进程中完成因此模型训练期间服务器不会响应预测请求。执行label-studio-ml start my_backend服务器默认监听http://localhost:9090日志直接输出到控制台。这种模式适合快速调试model.py逻辑由于无需 Docker 与 Redis也是本地验证的首选对应的无 Docker 启动方式参见 ml_create.md。生产模式Redis RQ 后台训练生产模式由Redis 服务器 RQ 任务队列驱动训练在后台异步执行因此你可以一边启动训练一边继续从当前模型状态获取预测训练结束后新模型版本会自动生效。使用前提是系统已安装 Docker 与 docker-composecd my_backend/ docker-compose up容器启动后运行时日志位于my_backend/logs/uwsgi.logRQ 训练日志位于my_backend/logs/rq.log便于排查训练失败等问题。这种训练不阻塞推理 自动切换模型版本的机制正是支撑主动学习Active Learning闭环的基础设施。将 ML Backend 接入 Label Studio 项目新建一个 Label Studio 项目并直接绑定刚启动的后端label-studio start my_project --init --ml-backends http://localhost:9090其中--init表示创建新项目--ml-backends传入后端服务地址。之后在项目的Settings Machine Learning页面可以看到该后端的连接状态。查看预测结果绑定成功后打开标注界面即可看到模型预测。完整的行为说明参见 Set up machine learning with Label Studio。预测会以预标注形式加载进编辑器标注员可直接采纳或修改。触发模型训练训练有两种触发方式界面操作进入项目设置的 Machine Learning 页面点击Start training按钮API 调用curl -X POST http://localhost:8080/api/models/train源码视角Label Studio 如何与 ML Backend 通信ML Backend 协议并非黑盒在本仓库中即可看到完整的服务端实现下面按调用链梳理。HTTP 端点协议Label Studio 侧通过 api_connector.py 中的MLApi类与后端通信约定的端点相对 ML Backend 根 URL包括端点方法用途/healthGET健康检查连接时探测后端是否存活/setupPOST首次连接时把项目 label config、access token 等发送给后端让 SDK 完成配置解析/predictPOST批量发送任务并取回预测结果/trainPOST发送带标注的任务数据触发训练/validate、/versions、/job_status、/webhook等—配置校验、版本查询、训练任务状态查询、标注事件回调各请求默认超时时间也集中在 api_connector.py预测/训练请求体超时默认 100 秒健康检查仅 1 秒setup 为 3 秒均可用ML_TIMEOUT_*系列环境变量调整。predict 响应校验逻辑当 Label Studio 调用predict后models.py 中的_get_predictions_from_ml_backend会对响应做严格校验响应必须是包含results字段的 dict且results为非空列表若results数量与输入任务数不一致当只返回 1 条时会自动降级为逐任务串行请求兼容不支持批处理的旧后端否则判定失败并返回空预测每个预测条目必须包含result字段score与model_version可选缺省时回落到后端当前版本。这与 Dummy Model 中为每个 task 生成一个 prediction的写法一一对应解释了为什么响应格式必须严格遵守。后端状态机与训练任务models.py 定义了后端状态枚举CONNECTED、DISCONNECTED、ERROR、TRAINING、PREDICTING。Label Studio 会周期性调用/health与/setup刷新状态见update_state()train()被调用后状态切换为TRAINING并登记MLBackendTrainJob通过/job_status轮询训练是否完成。MLBackendTrainAPIapi.py则直接对应上文curl -X POST /api/models/train的入口——注意实际路由为 urls.py 中的POST /api/ml/pk/train。测试用例佐证仓库中的 test_predict.py 验证了完整链路先以TextChoices配置建项目通过POST /api/ml/注册后端再请求/api/projects/{id}/next获取下一任务断言任务携带预测且value.choices[0] label_A、model_version与注册标题一致。这意味着只要你的predict()返回结构正确from_name/to_name/type/value.choices预测就会自动出现在标注界面——Dummy Model 的写法与测试预期完全吻合。常见问题与排障思路后端显示 Disconnected / Error先确认后端进程存活开发模式看控制台日志生产模式看logs/uwsgi.log再检查/health端点是否 200update_state()中健康检查失败会直接置为DISCONNECTED/setup失败则置为ERROR并记录error_message见 models.py。预测为空或数量不匹配检查predict()是否为每个任务返回了含result字段的条目参考上文响应校验规则。训练按钮点击后无反应查看logs/rq.log生产模式与后端控制台日志确认fit()是否抛异常训练任务状态可通过/job_status端点查询。Docker 内访问 localhost若 Label Studio 与 ML Backend 都跑在容器里localhost指向的是容器自身应改用http://host.docker.internal:9090访问宿主机服务。从 Dummy Model 到真实模型跑通 Dummy Model 后把它升级为真实模型只需三步在__init__中加载预训练权重例如借助self.train_output读取fit阶段的产物重写predict()用真实推理替换self.labels[0]的随机选取在fit()中写入真正的训练逻辑并返回模型资源字典。SDK 提供的其他可用属性还包括self.label_interface完整标注配置对象与self.model_version当前模型版本详见 ml_create.md。此外若模型需要访问存储在 Label Studio 或云存储中的数据需配置LABEL_STUDIO_URL与LABEL_STUDIO_API_KEY环境变量。更多进阶主题——包括交互式预标注、Webhook 触发训练、以及 HuggingFace、OpenAI、LangChain 等框架的现成示例——可继续阅读 ml_tutorials 系列文档。【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考