Files
EVEngine/tools/vision-prefilter
西风逍遥游 811eff1c3a ci(quality): warnings-as-errors gate, sanitizers, smoke, Python lint/tests
- EVENGINE_ENABLE_STRICT_WARNINGS option: MSVC /W4 /WX, GCC/Clang
  -Wall -Wextra -Werror, with documented noise suppressions and
  -isystem/-external:I for third-party headers; enabled on the
  Windows/Linux debug CI jobs.
- Fix warnings across engine, modules and tests exposed by the gate,
  including real bugs (incomplete-type deletes, Timespan microsecond
  overflow, overload hiding, enum switch gaps, dead code).
- Add Linux ASan+UBSan job, example smoke step, python-tools test
  job, ruff config (scripts+tools), weekly Linux coverage job and a
  CodeQL workflow.
2026-08-22 02:27:37 +08:00
..

EVEngine vision-prefilter

本地轻量视觉预筛选服务 —— 低成本前置视觉过滤器。

基于 llama.cpp llama-server 对 Qwen2-VL-2B GGUF Q4_K_M 量化 推理封装,批量评估 「渲染快照 + 精简几何文本快照」,输出结构化风险评级。过滤无问题视角,把 「高价高精度 VLM」的调用量压到最低:只有 need_high_precision_review == true 的场景才值得继续走昂贵模型。

为什么不用 PyTorch

本服务不依赖 torch / transformers / bitsandbytes(避免几十 GB 依赖、CUDA 匹配 地狱、脆弱性)。推理交给 llama.cpp llama-server(纯 C/C++ 单二进制 + 一个 GGUF 模型文件),本服务只是它前面的一个薄 FastAPI 网关。

llama.cpp 的 JSON Schema 约束在 token 采样层强制输出,从根上杜绝模型吐出自由 文本或 markdown —— 这比 prompt 约束硬得多,正好满足「只输出标准 JSON」的硬需求。

定位

渲染快照 + 几何文本快照 ──► [vision-prefilter 网关] ──► [llama-server (Qwen2-VL-2B GGUF)]
                                  │
                    risk_score 0~3 / has_problem / problem_regions
                                  │
                 需要高精度复查? ──否──► 通过(无需再花大模型钱)
                                  │是
                                  ▼
                        高价高精度 VLM
  • 独立、可后台运行(bin/start_vision_prefilter.* 同时拉起 llama-server + 网关)。
  • 标准化输入输出协议(见下)。
  • 批量推理接口 POST /v1/prefilter/batch。
  • 内置业务判定规则:道路遮挡=高风险、植被扎堆=中风险、布局均衡=无风险。

目录结构

vision-prefilter/
├── README.md
├── requirements.txt
├── vision_prefilter/
│   ├── __init__.py        # 常量 / 元信息
│   ├── protocol.py        # 标准化输入输出 schema(pydantic)+ 校验
│   ├── grammar.py         # JSON Schema:token 采样层强制标准 JSON
│   ├── rules.py           # 内置业务判定规则(道路/植被/均衡)
│   ├── model.py           # llama-server OpenAI 兼容 API 客户端 + 解析
│   ├── server.py          # FastAPI HTTP 网关
│   └── __main__.py        # CLI 入口
├── bin/
│   ├── start_vision_prefilter.sh    # Linux/macOS 后台启动整套
│   └── start_vision_prefilter.bat   # Windows 后台启动整套
├── scripts/
│   ├── client_batch.py    # 批量客户端示例
│   └── download_model.sh  # 下载 Qwen2-VL-2B Q4_K_M GGUF
└── test/
    └── test_core.py       # 规则 + JSON 解析单测

安装

Python 3.10+(仅网关用),并安装 llama.cpp:

# 1) 安装 llama.cpp(单二进制;Windows 从 releases 下载 llama-server.exe,
#    Linux/macOS 见 https://github.com/ggml-org/llama.cpp 或 brew/包管理器)
#   确保 llama-server 在 PATH。

# 2) 下载 GGUF 模型(Q4_K_M 约 1.6GB)
./scripts/download_model.sh          # 或按需换别的 Qwen2-VL-2B GGUF

# 3) 安装网关依赖(轻量,无 torch)
cd tools/vision-prefilter
python -m venv .venv
# Windows: .venv\Scripts\activate   Linux/macOS: source .venv/bin/activate
pip install -r requirements.txt

启动(后台)

Linux / macOS:

./bin/start_vision_prefilter.sh models/qwen2-vl-2b-instruct-q4_k_m.gguf

Windows:

bin\start_vision_prefilter.bat models\qwen2-vl-2b-instruct-q4_k_m.gguf

脚本会拉起 llama-server(默认 :8080,-ngl 99 尽可能 GPU 卸载)再拉起网关 (默认 :8531),各写 llama-server.log / vision-prefilter.log + .pid,可后台运行。

前台手动启动(供调试):

# 终端 1:llama-server
llama-server -m models/qwen2-vl-2b-instruct-q4_k_m.gguf --host 127.0.0.1 --port 8080 -ngl 99

# 终端 2:网关
python -m vision_prefilter --host 127.0.0.1 --port 8531 --backend http://127.0.0.1:8080

环境变量:VISION_PREFILTER_HOST / VISION_PREFILTER_PORT / VISION_PREFILTER_BACKEND (默认 http://127.0.0.1:8080,即 llama-server)/ VISION_PREFILTER_GGUF。

HTTP API

GET /health

{ "service": "eve.vision.prefilter", "status": "ok",
  "backend": "http://127.0.0.1:8080", "backend_ready": true }

GET /protocol

返回当前输入/输出的 JSON Schema,调用方可按此对接。

POST /v1/prefilter/batch

批量推理。输入(每张快照):

{
  "protocol_version": "1.0",
  "scenes": [
    {
      "id": "view-001",
      "image": "data:image/png;base64,iVBORw0KGgo...",
      "geometry": "road=(0,0)->(100,0)\ntreeCluster N=6@(10,10)",
      "prompt": null
    }
  ]
}

字段:

字段 必填 说明
id 是 调用方场景标识,原样回显
image 是 渲染快照,PNG/JPEG 的 base64(data:...;base64,... 或裸 base64)
geometry 否 精简几何文本快照(如道路线段、植被簇位置)
prompt 否 覆盖固定任务 Prompt

输出(每个场景一个):

{
  "protocol_version": "1.0",
  "service": "eve.vision.prefilter",
  "results": [
    {
      "id": "view-001",
      "ok": true,
      "result": {
        "risk_score": 3,
        "has_problem": true,
        "problem_regions": [
          { "bbox": [120, 40, 300, 210], "type": "道路遮挡", "note": "..." }
        ],
        "need_high_precision_review": true
      },
      "error": null
    }
  ]
}

单场景失败不会影响整批:ok=false 且 error 为结构化消息(不包含模型原文)。

输出契约(模型侧)

JSON Schema(grammar.py)在 token 采样层强制模型只输出该 JSON,禁止自由文本:

{
  "risk_score": 0,                // 0~3
  "has_problem": false,
  "problem_regions": [            // bbox 为像素坐标
    { "bbox": [x1,y1,x2,y2], "type": "遮挡|过密|空旷|穿插|道路遮挡|植被扎堆", "note": "..." }
  ],
  "need_high_precision_review": false
}

内置业务规则(rules.py)

模型负责感知画面内容,判定走确定性规则,结果可解释:

判定 风险 高精度复查
道路遮挡(几何提示含 road / 模型检出道路遮挡/遮挡) 3 是
植被扎堆 / 过密 / 穿插 2 否
布局均衡(无问题) 0 否

need_high_precision_review == true 才触发高价高精度 VLM。

测试

无需后端即可跑核心逻辑单测(规则 + JSON 解析):

pip install pytest
cd tools/vision-prefilter
python -m pytest test -q

调用方示例

python scripts/client_batch.py --image build/.../shot.png --geometry geom.txt --id view-001