93 lines
3.2 KiB
Markdown
93 lines
3.2 KiB
Markdown
# Analog Gauge Server
|
||
|
||
本目录把 [ethz-asl/analog_gauge_reader](https://github.com/ethz-asl/analog_gauge_reader)
|
||
作为被动调用模型接入统一 URL `POST /v1/inference`:
|
||
|
||
- category:`gauge.analog`
|
||
- model ID:`ethz-analog-gauge-reader@1`
|
||
- 输入:一张 JPEG 或 PNG
|
||
- 输出:`scalar` 读数与可选单位
|
||
- artifact:`original`、`annotated`、`diagnostics`
|
||
|
||
客户端只选择 category;Python 版本、项目路径、三个模型路径和超时全部由
|
||
[configs/server_gauge.yaml](../../configs/server_gauge.yaml) 的服务端配置控制。
|
||
|
||
服务端默认限制输入图像不超过 25,000,000 像素。worker 直接从 JPEG/PNG 头读取宽高,
|
||
在 Pillow/OpenCV 解码或模型推理之前拒绝超限图像;部署时可通过 `max_pixels` 在
|
||
1 到 250,000,000 之间调整。该限制与 HTTP 请求字节限制分别控制解压后尺寸和传输体积。
|
||
|
||
## 一次性准备
|
||
|
||
1. 确认上游项目和 Git LFS 模型文件已经完整:
|
||
|
||
```bash
|
||
git -C /home/xtkuang/Projects/cmvr/changan_robot/analog_gauge_reader lfs pull
|
||
```
|
||
|
||
2. 创建隔离的 Python 3.8 worker 环境:
|
||
|
||
```bash
|
||
bash server/gauge/worker/bootstrap.sh
|
||
```
|
||
|
||
3. 若仓库位置不同,修改配置中的 `python_executable` 和 `project_root`。三个模型路径可用
|
||
相对于 `project_root` 的路径。
|
||
|
||
## 校验与启动
|
||
|
||
根项目 HTTP 服务仍运行在 Python 3.10 环境;不要把 MMOCR/MMCV 安装到根 `.venv`:
|
||
|
||
```bash
|
||
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 发给统一入口:
|
||
|
||
```bash
|
||
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 的
|
||
模型权重。
|