使用foreach做reticulate并行调用时运行报错该如何解决?
问题解决方案
foreach完全可以和reticulate搭配使用,你遇到的报错是PSOCK集群的工作机制导致的,和两个包的兼容性无关。
报错原因
- PSOCK类型的集群会为每个核心启动独立的全新R进程,所有主进程里加载的包、创建的变量(包括你
import得到的wandb对象)默认不会同步到子进程中。 - reticulate封装的Python对象无法跨R进程序列化传递,也不能通过
.export参数从主进程导出到子进程。 - 子进程找不到
wandb对象,调用wandb$init自然会触发「尝试应用非函数」的报错。
修正方案
你只需要把reticulate加载、Python包导入的逻辑放到%dopar%的代码块内部,让每个子进程单独完成初始化即可,示例代码如下:
library(doParallel) library(foreach) library(parallel) # 初始化集群 cl <- makeCluster(detectCores(), type = 'PSOCK') registerDoParallel(cl) foreach(i = 1:5) %dopar% { # 每个子进程单独完成reticulate和Python包初始化 library(reticulate) # 如有自定义Python环境可取消下行注释指定路径,避免子进程调用到未装wandb的Python # use_python("/usr/bin/python3", required = TRUE) wandb <- import("wandb") # 建议给不同进程的run加区分标识,避免wandb后台日志冲突 wandb$init(project = "test", name = paste0("parallel_run_", i)) } # 运行结束后关闭集群 stopCluster(cl)
额外注意事项
- 如果你使用Linux/macOS系统,也可以把集群类型改成
FORK,fork模式会复制主进程的内存空间,不需要在子进程内重复导入,但仍推荐单独初始化避免Python全局状态冲突。 - 并行场景下调用wandb要注意避免多个进程同时写入同一份日志文件,建议每个进程的run配置独立的存储路径。
内容的提问来源于stack exchange,提问作者brucezepplin
相关产品推荐
相关产品推荐

