cmvr_edge_ai/server/gauge/README.md

3.2 KiB
Raw Blame History

Analog Gauge Server

本目录把 ethz-asl/analog_gauge_reader 作为被动调用模型接入统一 URL POST /v1/inference

  • categorygauge.analog
  • model IDethz-analog-gauge-reader@1
  • 输入:一张 JPEG 或 PNG
  • 输出:scalar 读数与可选单位
  • artifactoriginalannotateddiagnostics

客户端只选择 categoryPython 版本、项目路径、三个模型路径和超时全部由 configs/server_gauge.yaml 的服务端配置控制。

服务端默认限制输入图像不超过 25,000,000 像素。worker 直接从 JPEG/PNG 头读取宽高, 在 Pillow/OpenCV 解码或模型推理之前拒绝超限图像;部署时可通过 max_pixels 在 1 到 250,000,000 之间调整。该限制与 HTTP 请求字节限制分别控制解压后尺寸和传输体积。

一次性准备

  1. 确认上游项目和 Git LFS 模型文件已经完整:
git -C /home/xtkuang/Projects/cmvr/changan_robot/analog_gauge_reader lfs pull
  1. 创建隔离的 Python 3.8 worker 环境:
bash server/gauge/worker/bootstrap.sh
  1. 若仓库位置不同,修改配置中的 python_executableproject_root。三个模型路径可用 相对于 project_root 的路径。

校验与启动

根项目 HTTP 服务仍运行在 Python 3.10 环境;不要把 MMOCR/MMCV 安装到根 .venv

uv sync --locked --extra server --group dev
uv run --no-sync cmvr-edge-ai validate \
  --config configs/server_gauge.yaml
uv run --no-sync cmvr-edge-ai serve \
  --config configs/server_gauge.yaml \
  --log-level INFO \
  --log-format text

默认队列容量为 1同一个 worker 串行处理请求,不让上游模型的可变状态并发执行。 请求超时为 300 秒HTTP 超时为 360 秒,给首次加载 DINO/MMOCR 权重留出空间。 若服务监听非 loopback 地址,必须配置 Bearer token并默认使用 TLS只有受信隔离网络 可显式设置 allow_insecure_remote: true。远程请求需要携带 Authorization: Bearer <token>,健康探针不需要认证。 没有检测到仪表、刻度数字或指针时返回 no_result;模型 checkpoint、依赖或部署故障 返回 failed,不会伪装成“没有识别结果”。

请求示例

下面的脚本只把图像和稳定业务 category 发给统一入口:

python - <<'PY'
import base64
import json
from pathlib import Path
from urllib.request import Request, urlopen

path = Path("/path/to/gauge.jpg")
payload = {
    "schema_version": "cmvr.inference-request/v1",
    "category": "gauge.analog",
    "inputs": [{
        "kind": "image",
        "name": "image",
        "media_type": "image/jpeg",
        "encoding": "base64",
        "data": base64.b64encode(path.read_bytes()).decode("ascii"),
    }],
    "requested_artifact_roles": ["annotated", "diagnostics"],
}
request = Request(
    "http://127.0.0.1:8081/v1/inference",
    data=json.dumps(payload).encode("utf-8"),
    headers={"Content-Type": "application/json"},
)
print(urlopen(request, timeout=360).read().decode("utf-8"))
PY

真实模型首次请求可能较慢;轻量协议测试使用 fake upstream project不加载约 1.2 GB 的 模型权重。