mortred_model_server

Changelog

All notable changes to this project are documented here. The format follows Keep a Changelog; versions follow Semantic Versioning. 每个版本的条目保留英文原文,中文说明 以引用块附于同版本之下。

[Unreleased]

Fixed

发布 .sha256 只写 tarball 文件名curl -fLOsha256sum -c 才能 打出 OK(deployment §6.1)。原先 sha256sum /绝对路径 会把 runner 路径写进 校验文件。bootstrap.sh 先解析 latest tag,再下 mortred_model_server-<tag>-<profile>-linux-x64.tar.gz(没有 ...-latest-... 资产)。gpu staging 与 cpu 一样落到 opt/mortred/cp -a src/. dest/, 不是 cp -a src dest/opt/)。

write_prometheus_credentials.sh 把 scrape 密钥 chown 给真正读它的进程: compose 里 prom/prometheus 的 uid 65534,或 apt 单元的 prometheus 用户(/etc/prometheus/*)。权限仍是 600。compose 监控通过 prometheus.compose.ymlhost.docker.internal:8080(容器内 localhost 是 Prometheus 自己)。deployment 补了属主步骤和该 Docker 主机名。

Changed

入口一无 Docker 按 GitHub latest tagmortred_model_server-<version>-<profile>-linux-x64.tar.gz。Release 不挂 ...-latest-... tarball 文件名(GHCR :latest-cpu / :latest-gpu 仍是镜像 tag)。README / deployment / bootstrap.sh 不再写成「无 Docker 一定能装上」: 还没有 Release 时 WARN 并落到源码构建。verify_deployment.sh --basic 禁止 打包或下载 mortred_model_server-latest-

YOLOv5 / v6 / v7 / v8 的 min_box_area_px 统一在解码坐标系(letterbox 网络像素)里、unmap 之前过滤。原先 v5/v6 在 unmap 后的源图像像素上比 面积,v8 完全不读该键。合成解码单测覆盖这条共用阈值。

checker 按 HTTP catalog 的 [*.backend] type="tensorrt" 对照 trt_engines.json(不再找已删除的 *_TRT)。脚手架(TODO(new_model) / 不在 HTTP catalog)跳过。cpu 权重集合不再含 catalog 不服务、且不在 HF 上的 hrnet ONNX。

发布 tarball 按平铺写进文档:包根就是 install.shopt/mortred/deploy/(打包脚本和 gpu release job 本来就是这样打的)。README / 部署 / 安装脚本注释改为解到空目录,不再 cd 一个打包器不会生成的 wrapper 目录。

入口二/三与 bootstrap 改为三个 token(init-trust / supervisor.env), 与 compose 已有的 :? scrape 必填对齐。可选监控 compose 挂载 scrape credentials 文件(不由应用 compose 或发布 tarball 发明 token),并 provision Grafana 的 Prometheus 数据源。

人读文档与统一信封对齐:请求 images[],响应 {status, status_str, task_id, results[]}api-contractapi-keys 与任务教程 不再把 img_data{code, msg, data} 写成成功示例。中英监控/部署均写明 网关 /metrics 含环回也要 MORTRED_METRICS_TOKEN。README Model Zoo 区分 HTTP catalog 与 bench-only。

Fixed

ci_container_boot.sh 按统一信封断言推理结果(status / results[],含 results[0].status),不再读已删除的 codepayload.get("code", 0) 会永远 通过,HTTP 200 且 status != 0 仍会打印成功。

HTTP 扩散工人在 init 时从模型 TOML 种入采样模板(sample_size / 默认步数 / channels)。缺或空 sample_size 会 init 失败,而不再每请求 MODEL_EMPTY_INPUT_IMAGE。异步冒烟与 DDPM 示例改用 params.timesteps (不是根上 timestep)和统一结果信封。少步 CPU 出图证明: model_golden.ddpm_celeba_hq_fewstep + conf/ci/ddpm_onnx_fewstep.toml (不进 hosted;ONNX 约 143MiB)。该用例断言 HTTP adapter 走出 128x128 PNG, 不钉像素(每次 random_device 仍重新播种)。异步冒烟会设 MORTRED_AUTH_TOKEN 并在 /jobsAuthorization: Bearer(空 token 是 401;/healthz 仍公开)。

Supervisor 在磁盘上已有 mortred-gateway.out 时,若 scrape token 未设置或与 推理/管理 token 相同则拒绝 listen;spawn __gateway 使用同一谓词,失败记为 permanent 而非 backoff,避免「健康横幅 + 网关崩溃循环」。/api/v1/keys 仍是 404。

BaseAiModel::run(以及 packed BackendCvModel::run_batch)接住 run_impl / OpenCV 的抛出并返回 MODEL_RUN_SESSION_FAILED,避免 workflow go 线程 std::terminate 整进程。packed run_batch 在 catch 后还会把该错误码盖到 每一个 item_statusrun_image_batch 会先全部标 OK;不盖的话 HTTP 会谎报成功)。 扩散 DDPM/DDIM/cls-cond 后处理不再对 1/4 通道 convertTo(CV_8UC3) + COLOR_RGB2BGR(LDM latent channels=4save_raw_output);出图按通道转换,只要 raw 时跳过。

do_work 在把 worker 还回队列之前写入推理 metrics 和运行时间 EWMA (与 process_batch 相同)。析构 drain 把「worker 已入队」当作可以销毁 这些成员;enqueue 后再写会与超时请求的析构竞态。

YOLO v5/v6/v7/v8 预处理改为 Ultralytics 导出同款中心 letterbox(等比、 填充 114),框反变换用同一套 pad/scale。NanoDet / CenterFace / LibFace 仍走拉伸 GeometryScale。Fork CI 用仅 CI 的 ONNX overlay (conf/ci/yolov8_onnx_hosted.tomlyolov8s.onnx)证明 YOLOv8 decode+NMS+unmap;出厂 yolov8_config.toml 仍是 TensorRT。

Supervisor 优雅关停不再挂死。WFServerBase::stop() 本身就是阻塞的 shutdown() + wait_finish();旧代码又补了一次 wait_finish(),第二次 永久阻塞。生产上一直被 systemd TimeoutStopSec 的 SIGKILL 掩盖—— mortred-supervisor 此前从未真正优雅退出过。由本次重构的进程内 SupervisorApp 关停路径暴露。

Changed

控制面去全局化(内部重构,无行为变化):网关/supervisor 的文件级全局 状态移除,GatewayApp / SupervisorApp 持有各自状态;run() 将进程 环境映射为显式的 *InitOptions,app 对象移入新的依赖 workflow 的 control_workflow 库以便测试进程内链接。验收:两个网关与两个 supervisor 实例(不同 root/token/catalog)可同进程并存 (gateway_multiinstance_testsupervisor_multiinstance_test)。

Fixed

网关现在向模型服务器转发 raw-body 控制头 X-Mortred-Params / X-Mortred-Options / X-Request-ID,并在自身错误回复中回显 X-Request-ID。此前 raw-body 请求经网关代理后参数与关联 id 被静默丢弃 (JSON envelope 路径不受影响)。其余客户端头仍然丢弃——默认拒绝的转发 白名单就是防头注入的屏障。

Supervisor 的 process() 现在与网关/模型服务器一样把空 method 折叠为 ""。此前畸形请求行(workflow 返回 null method)会从 nullptr 构造 std::string——未定义行为,通常表现为管理面崩溃。

异步任务回复现在计入 mortred_http_requests_total:此前 202 提交回复、 200 状态/等待/结果回复以及异步错误码(404/405/409/429)在模型服务器监控 上不可见。异步回复刻意不产生 mortred_http_request_duration_ms 样本——该 直方图观测的是推理耗时,异步 HTTP 路径上没有这一耗时。

模型进程与网关的 main 在 SIGINT/SIGTERM 时会 done() WaitGroup,从而走到 stop() 和析构 drain;不再被默认信号直接杀死。Supervisor 本身原本就是这样。

Changed

POST /jobs 在准入时立即返回 202,不再等推理结束。GET …/wait 在终态或 wait 预算耗尽时返回(单位毫秒)。客户逐步验收见 async-jobs-customer-test.zh-cn.md

Removed

Changed

Changed

Fixed

Added

Removed

Changed

Fixed

Added

[0.1.0] - 2026-08-23

Added

Fixed

中文摘要:新增部署 Profile 体系(cpu/gpu 单一事实源贯穿构建、依赖、目录、 权重四层)、双轨分发(Docker 双 target + compose profiles;版本化 tarball