fix: 修复两个OCR问题
1. 修复_clean_ocr_prefix误删登录关键词导致答非所问 - 噪声前缀后必须跟标点/空格或字符串结束,不能紧跟中文字符 - 登录插件,哪里可以下载到?不再被清理为插件,哪里可以下载到? 2. 修复EasyOCR静默原生崩溃检测 - 父进程:空stderr+空crash log也计入CUDA崩溃计数,2次后强制CPU - Worker:添加CUDA驱动DLL预检,加载失败时强制CPU模式
This commit is contained in:
@@ -137,6 +137,21 @@ try:
|
||||
os.environ.setdefault("OMP_NUM_THREADS", "1")
|
||||
os.environ.setdefault("MKL_NUM_THREADS", "1")
|
||||
|
||||
# ── CUDA 驱动预检:在 import torch 之前探测 CUDA 驱动是否可用 ──
|
||||
# 防止 CUDA 驱动损坏导致 import torch 时原生崩溃(crash log 为空的静默崩溃)
|
||||
if os.environ.get("EASYOCR_FORCE_CPU") != "1":
|
||||
try:
|
||||
import ctypes
|
||||
ctypes.windll.nvcuda # 尝试加载 CUDA 驱动 DLL
|
||||
sys.stderr.write("[easyocr_worker] CUDA 驱动 DLL 加载成功\n")
|
||||
sys.stderr.flush()
|
||||
except Exception as _cuda_drv_err:
|
||||
os.environ["EASYOCR_FORCE_CPU"] = "1"
|
||||
os.environ["CUDA_VISIBLE_DEVICES"] = ""
|
||||
sys.stderr.write(f"[easyocr_worker] ⚠️ CUDA 驱动加载失败({_cuda_drv_err}),强制 CPU 模式\n")
|
||||
sys.stderr.flush()
|
||||
_write_crash_log(f"{datetime.now()} [easyocr_worker] CUDA 驱动预检失败: {_cuda_drv_err}")
|
||||
|
||||
# ── 预检:物理内存+虚拟内存是否足够加载 CUDA 库 ──
|
||||
_vm = _get_virtual_memory_info()
|
||||
# ⭐ 统一使用 GlobalMemoryStatusEx(与 monitor.py / Task Manager 一致)
|
||||
|
||||
+9
-4
@@ -1856,10 +1856,13 @@ class MessageMonitor:
|
||||
if crash:
|
||||
detail = (detail + "\n[ocr] worker 崩溃日志(easyocr_crash.log):\n" + crash).strip()
|
||||
logger.error(f"[ocr] EasyOCR worker 启动即崩溃: {detail}")
|
||||
# ⭐ 检测 CUDA 相关崩溃(access violation / torch 错误)→ 增加 OOM 计数,下次强制 CPU
|
||||
if crash and ("access violation" in crash.lower() or "torch" in crash.lower()):
|
||||
# ⭐ 检测 CUDA 相关崩溃(access violation / torch 错误 / 静默原生崩溃)→ 增加 OOM 计数,下次强制 CPU
|
||||
_is_cuda_crash = (crash and ("access violation" in crash.lower() or "torch" in crash.lower()))
|
||||
_is_silent_native_crash = (not err.strip() and not crash.strip()) # 无stderr无crash log = 原生层崩溃
|
||||
if _is_cuda_crash or _is_silent_native_crash:
|
||||
self._easyocr_cuda_oom_count += 1
|
||||
logger.warning(f"[ocr] 检测到 CUDA 崩溃,累计{self._easyocr_cuda_oom_count}次,下次可能强制 CPU")
|
||||
logger.warning(f"[ocr] 检测到{'CUDA崩溃' if _is_cuda_crash else '静默原生崩溃(无日志)'}, "
|
||||
f"累计{self._easyocr_cuda_oom_count}次,下次可能强制 CPU")
|
||||
# ⭐ 检测页面文件不足(WinError 1455)→ 长期冷却,不反复重试
|
||||
_is_pagefile_error = "页面文件" in str(detail) or "1455" in str(detail)
|
||||
if _is_pagefile_error:
|
||||
@@ -4810,6 +4813,8 @@ class MessageMonitor:
|
||||
|
||||
# ⭐ OCR噪声前缀清理:去除UI按钮标签等OCR误识别的前缀
|
||||
# 如"必选,运营方有哪些权利和义务?" → "运营方有哪些权利和义务?"
|
||||
# 注意:前缀后必须跟标点/空格或字符串结束,不能紧跟中文字符
|
||||
# 否则会误删"登录插件"中的"登录"
|
||||
_OCR_NOISE_PREFIXES = re.compile(
|
||||
r'^(?:必选|必填|可选|请输入|搜索|查找|查询|发送|取消|确认|确定|提交|保存|删除|编辑| '
|
||||
r'|添加|新建|创建|设置|修改|返回|关闭|展开|收起|更多|选项|操作|'
|
||||
@@ -4817,7 +4822,7 @@ class MessageMonitor:
|
||||
r'同意|拒绝|同意并|下一步|上一步|完成|跳过|继续|登录|注册|退出|'
|
||||
r'开启|关闭|启用|禁用|暂停|恢复|开始|停止|运行|'
|
||||
r'是|否|有|无|对|错|真|假|好|坏|新|旧|已|未)'
|
||||
r'[,,::\s]*'
|
||||
r'[,,::\s]+|$'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user