WSL中Snakemake执行简单测试Snakefile耗时90秒的排查求助
Snakemake Python规则耗时过长(90秒vs1秒)问题排查
背景
在Windows 10的WSL2中独立环境安装了Snakemake,用于探索数据分析DAG的可复现性。测试流程:
- 用shell规则将3个两列数字的txt文件复制为csv到
intermediate文件夹 - 用Python脚本读取中间文件,用matplotlib绘图,希望可在独立conda环境运行
问题
DAG可正常输出文件,但涉及Python的规则耗时约90秒,远慢于命令行直接执行的1秒左右。
已尝试方案
- 将项目从挂载的C盘迁移到WSL主目录,排除磁盘速度问题
- 创建独立conda环境(含numpy、matplotlib),通过
--use-conda可运行,但仍耗时久,推测环境激活耗时 - 复用Snakemake环境安装依赖,注释conda配置后执行速度依旧缓慢
代码示例
workflow/snakefile
samples = "first_data,second_data,third_data" rule all: input: expand("graphs/{file}.png", file=samples.split(",")), rule make_intermediate: input: "data/{file}.txt", output: "intermediate/{file}_shell.csv", shell: "cp {input[0]} {output[0]}" rule make_graph: input: "intermediate/{file}_shell.csv", output: "graphs/{file}.png", # conda: # "../envs/data_env.yaml" script: "../scripts/a_script.py"
scripts/a_script.py
import matplotlib.pyplot as plt import numpy as np def make_graph(filename_in, filename_out): data = np.loadtxt(filename_in, delimiter=',') plt.figure() plt.title(filename_in) plt.plot(data[:, 0], data[:, 1]) plt.savefig(filename_out) plt.close() make_graph(snakemake.input[0], snakemake.output[0])
执行日志(无独立conda环境,命令snakemake -c 4)
Select jobs to execute... Execute 3 jobs... [Wed Jan 17 19:58:26 2024] localrule make_graph: input: intermediate/second_data_shell.csv output: graphs/second_data.png jobid: 3 reason: Missing output files: graphs/second_data.png wildcards: file=second_data resources: tmpdir=/tmp [Wed Jan 17 19:58:26 2024] localrule make_graph: input: intermediate/first_data_shell.csv output: graphs/first_data.png jobid: 1 reason: Missing output files: graphs/first_data.png wildcards: file=first_data resources: tmpdir=/tmp [Wed Jan 17 19:58:26 2024] localrule make_graph: input: intermediate/third_data_shell.csv output: graphs/third_data.png jobid: 5 reason: Missing output files: graphs/third_data.png wildcards: file=third_data resources: tmpdir=/tmp [Wed Jan 17 20:00:39 2024] Finished job 1. 1 of 4 steps (25%) done [Wed Jan 17 20:00:39 2024] Finished job 3. 2 of 4 steps (50%) done [Wed Jan 17 20:00:39 2024] Finished job 5. 3 of 4 steps (75%) done Select jobs to execute... Execute 1 jobs...
解答
核心原因
耗时过长的根本原因是Matplotlib在WSL2无图形界面环境下的后端初始化阻塞。默认情况下Matplotlib会尝试使用交互式后端(如TkAgg),但WSL2没有X11显示服务支持,导致进程长时间等待超时,最终才 fallback 到非交互式后端。
解决方案
1. 强制指定非交互式后端
修改a_script.py,在导入Matplotlib前添加后端配置,跳过交互式后端的尝试:
import matplotlib matplotlib.use('Agg') # 强制使用无需图形界面的非交互式后端 import matplotlib.pyplot as plt import numpy as np def make_graph(filename_in, filename_out): data = np.loadtxt(filename_in, delimiter=',') plt.figure() plt.title(filename_in) plt.plot(data[:, 0], data[:, 1]) plt.savefig(filename_out) plt.close() make_graph(snakemake.input[0], snakemake.output[0])
2. 优化conda环境使用(若后续需要)
如果之后恢复使用独立conda环境仍觉得激活耗时:
- 提前用
conda env create -f ../envs/data_env.yaml预创建环境,避免Snakemake每次检查环境的额外开销 - 使用
--conda-frontend mamba替代默认conda,加速环境创建与依赖解析(需先在Snakemake环境中安装mamba)
3. 其他辅助优化
- 检查WSL2内存分配:默认内存可能偏低,可在Windows用户目录下创建
.wslconfig文件调整,示例:[wsl2] memory=4GB - 确保所有文件都在WSL本地磁盘,避免跨系统磁盘的IO开销
验证效果
修改脚本后重新运行snakemake -c 4,每个make_graph任务的耗时会降到和命令行直接执行一致的1秒左右。
内容的提问来源于stack exchange,提问作者andwerb
相关产品推荐
相关产品推荐

