如何使用furrr::future_map并行运行tesseract::ocr?
解决
furrr::future_map与tesseract::ocr的兼容问题 问题背景
使用furrr::future_map并行调用tesseract::ocr时触发错误:
Detected a non-exportable reference (‘externalptr’ of class ‘tesseract’)
该错误源于tesseract引擎的外部指针(externalptr)无法被future框架序列化并传递给子进程,但相同逻辑用parallel包可以正常运行。
核心原因
tesseract("eng")创建的OCR引擎是外部指针对象,这类对象无法跨进程序列化传递。parallel::parLapply通过clusterEvalQ在每个子进程单独加载tesseract并初始化引擎,避免了跨进程传递指针;而furrr默认会扫描全局环境中的依赖,尝试将tesseract相关的外部指针传递给子进程,因此触发错误。
解决方案
方案1:在并行任务内部初始化tesseract引擎(推荐)
修改OCR函数,让每个并行任务单独创建tesseract引擎,避免跨进程传递外部指针:
library(tesseract) library(furrr) library(tidyverse) # 测试链接 links <- rep("http://jeroen.github.io/images/testocr.png", 10) # 修改后的OCR处理函数 f.ocr_save <- function(url){ out <- tryCatch( { # 每个任务内部独立初始化引擎 eng <- tesseract("eng") out <- tesseract::ocr(url, engine = eng) }, error=function(cond) { message(paste("URL处理出错:")) message(cond) return("URL处理错误") }, warning=function(cond) { message(paste("URL处理有警告:")) message(cond) return(NULL) } ) return(out) } # 设置并行策略(multisession适合Windows/macOS) plan(multisession, workers = 2) # 正常执行并行OCR future_map(links, f.ocr_save)
方案2:禁用全局变量检查(应急用,不推荐)
通过furrr_options禁用全局变量自动传递,强制子进程自行处理依赖,但需确保子进程能加载所需库:
plan(multisession, workers = 2) # 禁用全局变量检查,需确保子进程已加载tesseract future_map(links, f.ocr_save, .options = furrr_options(globals = FALSE))
此方法可能引发其他依赖问题,仅作为临时应急方案。
验证效果
修改后的代码可以像parallel包一样正常返回OCR结果,且不会触发外部指针序列化错误。
内容的提问来源于stack exchange,提问作者ava
相关产品推荐
相关产品推荐

