如何解决Alphafold2软件no space left on device问题


        在Linux系统上(以下称宿主机)使用Google DeepMind团队的Alphafold2软件预测蛋白3D结构,当预测某些蛋白混合物的结构时出现no space left on device的错误,当把这个问题解决后又出现No such file or directory的新Bug,两个问题Debug的时间加起来差不多四五天,今天就来记录一下问题解决过程和解决方法。

1 软件运行出现图1的报错,程序停止运行

Alt

图1. 软件运行出现“no space left on device”报错

1.1 原因分析

        在运行Jackhmmer环节的时候,会产生一些临时文件,遇到氨基酸数量较多的蛋白,临时文件就会偏大,导致存放临时文件的目录空间不足

1.2 解决方法

         针对临时文件目录空间不足问题,提出两个解决方法,一是修改临时文件目录,二是将宿主机空间较多的目录挂载到容器中的/tmp目录

1.2.1 修改临时文件目录

        既然是存放临时文件的目录空间不足,那就将存放临时文件的目录修改为空间更大的目录。于是,就将软件的源代码扒出来,通过网上一些问答贴(如师弟提供的https://github.com/prehensilecode/alphafold_singularity/issues/24)将设置临时文件存放目录的代码定位到alphafold/alphafold/data/tools/utils.py脚本第25行,将None改为空间更大的路径,例如"/mnt/output",因为源代码的设定是存在根目录下的tmp文件夹,而我用的服务器该目录总共就只分配了50G,还有其它文件占据空间,可用空间就只有七八个G,造成空间不足问题。具体操作如下:

  1. 在宿主机上alphafold镜像中运行一个容器,就是按照正常流程运行Alphafold2。
python3 run_docker.py --fasta_paths=f1.fasta,f2.fasta --max_template_date=2023-10-01 --model_preset=multimer --data_dir=/home/admin/data/data3/alphafold/database --output_dir=/home/admin/data/data2/minirose/alphafold 
  1. 查看正在运行的容器。
docker ps

Alt

图2. 查看服务器上正在运行的容器

3) 进入自己运行的容器,如果是共用账号,注意不要进错容器了。
docker exec -it serene_allen /bin/bash #-it表示以交互模式进入容器,serene_allen是要进入的容器名,/bin/bash表示进入容器进行的操作

Alt

图3. 进入容器

  1. 查看容器磁盘空间。在容器中命令的使用方式与在宿主机中是一样的,查看结果显示/mnt/output的剩余空间还很多,于是就将/mnt/output定为临时文件存放目录。
    注:其实这个目录当时选的不太好,根据源代码可以知道output是软件运行时新建的目录,这也可能是后面运行一段时间出错的原因之一,但也不是很确定,暂时用这个也可以。
df -h #查看所有磁盘空间大小,-h表示以人易于看懂的方式显示空间大小

Alt

图4. 查看容器中的磁盘使用情况

  1. 在容器中创建tpm目录。因为/mnt/output虽然空间多,但还有其它文件,为了避免文件的交叉太乱,所以就在/mnt/output中创建了一个tmp文件。容器中本身是不能直接创建目录,但是output里面的文件是从宿主机映射过来的,看了下源代码,output下存放的是结果文件,也就是需要在宿主机你存放结果文件的地方创建tmp目录。
    注:这一步我觉得可以省略,最后应该也能运行成功,但没有试过。创建tmp目录时,记得对该目录开放全部权限。
  2. 修改脚本。在Linux中找到alphafold/alphafold/data/tools/utils.py脚本,修改第25行,将None改为空间更大的路径,例如"/mnt/output/tmp",这个目录一定要是容器中的目录,不然报错。
    注:tmp是我在宿主机上创建的,软件运行时会将它映射到容器中的/mnt/output目录下。
vim utils.py #编辑utils.py,将25行的None改为“/mnt/output/tmp”

改完了记得保存,vim的使用这里就不详述了。
Alt

图5. 将utils.py中的None修改为/mnt/output/tmp

  1. 将utils.py脚本复制到容器中的对应路径下。不在容器中直接修改是因为容器中没有现成的编辑器,只能通过这种方式来修改。
docker cp /home/admin/.gp/alphafold/alphafold/data/tools/utils.py serene_allen:/app/alphafold/alphafold/data/tools #serene_allen是容器名
  1. 复制后一定要记住将你对容器的修改更新到镜像中,不然原始的镜像是不会保留你的更改的。
docker commit serene_allen alphafold #serene_allen是容器名,alphafold是镜像名

查看服务器中所有镜像

docker images

Alt

图6. 查看服务中的镜像

  1. 最后再重新运行Alphafold2就不会报错了,程序会将临时文件保存到你新设定的目录。

1.2.2 将宿主机空间较多的目录挂载到容器中的/tmp目录

        这里的灵感是来自于软件开发者将宿主机上的fasta文件、数据库文件、输出目录进行挂载的做法。具体操作如下:

  1. 查看宿主机文件目录空间大小。选择/home进行挂载
    Alt
图7. 查看宿主机的磁盘使用情况

  1. 文件目录挂载。这里是通过修改软件源代码alphafold/docker/ run_docker.py脚本,让程序运行的时候自动将宿主机的/home挂载在容器中的/tmp目录上,让/tmp的实际大小为/home的大小。
vim run_docker.py
##在脚本中添加以下两行代码,/home/tmp为宿主机上的目录,/tmp为容器中的目录
home_tmp_mount = types.Mount(target="/tmp", source="/home/tmp", type="bind")
mounts.append(home_tmp_mount)

注:/home/tmp目录最好是开放全部权限

chmod 777 /home/tmp #777表示设置/home/tmp目录具有所有人可读、可写、可执行的权限

Alt

图8. 在run_docker.py中添加挂载目录的代码

  1. 后面无需再做任何操作,直接运行就不会报错了,这个方法比较简单。

2 软件运行出现图9中的报错,程序停止运行。

Alt

图9. 软件运行出现“No such file or directory”的报错

2.1 原因分析

        对于这个问题的原因其实我也很迷糊,起初修改临时文件目录后,我这边可以正常运行了,和我同用一个账号的师弟出现了图9中的问题,报错其实就是显示之前设置的临时文件路径找不到,我设想了一些原因给师弟调试了一下,但是没有用,于是就给他换了一个服务器连接的终端,居然奇迹般地就可以正常运行了,但并没有找出来问题的根本原因是啥。但是,滑稽的是过了几天,我这边再次运行时,我也出现了图9的问题。各种办法试过了,无果。晚上试着随便翻翻Docker的书籍,看完镜像内部结构,我突然有了解决思路。

2.2 解决方法

        解决办法有两个,一是重新构建镜像,二是基于原有的镜像重新构建镜像。

2.2.1 重新构建镜像

        这个方法比较耗时,过程中还可能会遇到一堆Bug,例如某个目录内存不足、网络不稳定问题,具体操作方法就不详述了,参照github上的官方方法:https://github.com/google-deepmind/alphafold。

2.2.2 基于原有的镜像重新构建镜像

        这个方法就比较快,思路就是基于原有的alphafold镜像重新构建镜像,再将原有镜像中的utils.py脚本恢复为原来的样子,这样软件就能基于新的镜像重新运行啦。具体操作如下:

  1. 编写Dockerfile文件。打开alphafold/docker/Dockerfile文件,写入两行代码。
vim Dockerfile #编辑Dockerfile文件
##在Dockerfile中写入以下两行代码
FROM alphafold #表示以alphafold为基础镜像,相当于复制了alphafold镜像
COPY utils.py /app/alphafold/alphafold/data/tools #表示将宿主机中的utils.py复制到/app/alphafold/alphafold/data/tools

Alt

图10. 编写Dockerfile文件

  1. 构建镜像。-f表示以文件方式构建镜像,-t表示新的镜像名称,.表示在当前路径下构建镜像。
    注:运行该命令时,一定要进入utils.py文件同级目录下,不然构建镜像时找不到该文件。
docker build -f /home/admin/.gp/alphafold/docker/Dockerfile -t alphafold-tmpnone .
  1. 修改alphafold/docker/run_docker.py脚本源代码,该步骤的run_docker.py脚本是1.2.2中的2)修改后得到的脚本。将脚本中镜像名从原来的“alphafold”改为我们的新镜像名“alphafold-tmpnone”后保存。一定要修改镜像名,不然运行的时候是基于原来的旧镜像
    Alt
图11. 修改run_docker.py中的镜像名称

  1. 修改完毕再重新运行就可以了。

3 总结

        两个问题中,问题1大家遇到的可能性更大一些,如果遇到问题1建议直接使用第二种方法进行解决,即使用目录挂载的方式,将宿主机中空间较多的目录直接通过代码或其它方式挂载到容器中的/tmp上,这样不会造成临时文件目录的更改,也不会引发问题2。如果不幸遇到问题2建议使用第二种方法进行解决,即基于旧的镜像构建新镜像,并将旧镜像中更改的文件覆盖掉,这样就可以使用新的镜像,避免了之前乱七八糟的环境冲突。

        还有一点就是尽量不要多个人同时在不同地方使用同一个Linux账号,大多数情况下是没有问题的,但一些特殊情况下会出现一些很奇怪的bug,无法进行精准排除。

        最后一点是个人教训,吃了不懂Docker的亏,其实本来问题也没有很复杂,但是由于最初不懂Docker的运行原理,所以只能一点一点地去排除问题原因,一点一点去靠近问题的本质。还是前天晚上实在没有解决问题的灵感了,感觉能试的角度和方法都试了,便无意地在微信读书找了本Docker的书看起来,看完镜像的内部结构,思维突然打开了,半夜爬起来解决了问题2,顺带想到了问题1的方法二。由此可见理论知识的重要性,“有道无术,术尚可求也,有术无道,止于术”,这也是为什么社会在判断一个人的学术能力时,在不知道这些人真实水平的情况下,更倾向于选择本硕博专业对口的人吧。

更多关于R语言和Python编程的文章可关注图片中的水印。

  • 31
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值