Files
mingxi_platform/mingxi-vision/engine/loader.py
T
ilaandClaude Sonnet 4.6 68e4f444c5 feat(vision): 实现 mingxi-vision 推理服务核心功能
- engine/defect_classes: HRIPCB 6类缺陷定义 + 4类扩展 + severity排序
- engine/base: DefectBox / DetectResult 数据类 + BaseInferenceEngine 抽象基类
- engine/ultralytics_adapter: YOLOv8 .pt 推理适配器 + warmup
- engine/annotator: 按 severity 着色的标注图生成 + base64 编码
- engine/loader: 单例管理 + asyncio.Lock 推理串行化 + 热重载支持
- config: Pydantic v1 BaseSettings,读取 .env
- schema: DetectResponse / HealthResponse / ReloadRequest 等响应模型
- api/detect: POST /api/detect,内存读图,推理锁保护
- api/health: GET /api/health
- api/model: POST /api/model/reload 热重载接口
- main: FastAPI lifespan 启动加载模型

测试通过:/api/health 200,/api/detect 空图返回 pass,标注图 base64 正常

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 21:18:34 +08:00

44 lines
1.4 KiB
Python

import asyncio
from typing import Optional
from .base import BaseInferenceEngine
_engine: Optional[BaseInferenceEngine] = None
# 懒初始化,确保在事件循环启动后创建
_inference_lock: Optional[asyncio.Lock] = None
def get_engine() -> BaseInferenceEngine:
if _engine is None:
raise RuntimeError("推理引擎未初始化,请先调用 init_engine()")
return _engine
def get_inference_lock() -> asyncio.Lock:
global _inference_lock
if _inference_lock is None:
_inference_lock = asyncio.Lock()
return _inference_lock
def init_engine(model_path: str, runtime: str = "ultralytics") -> BaseInferenceEngine:
global _engine
if runtime == "onnx":
from .onnx_adapter import OnnxRuntimeAdapter
_engine = OnnxRuntimeAdapter(model_path)
else:
from .ultralytics_adapter import UltralyticsAdapter
_engine = UltralyticsAdapter(model_path)
print(f"[mingxi-vision] 加载模型: {model_path}")
_engine.warmup()
print(f"[mingxi-vision] 引擎就绪: {_engine.__class__.__name__} · {_engine.model_version}")
return _engine
def reload_engine(model_path: str, runtime: str = "ultralytics") -> BaseInferenceEngine:
"""热重载模型,调用方必须持有推理锁"""
global _engine
_engine = None # 释放旧引用,让 GC 回收显存
return init_engine(model_path, runtime)