掘金 后端 ( ) • 2024-04-24 09:35

最近在和算法工程师一起搞自动标注的事情,我需要帮他们把代码build成镜像,然后推到镜像仓库,供k8s集群中的一些任务流,比如argo workflow调用。

遇到的问题

在把算法工程师项目中的cuda版本,pytorch版本,各种python package版本一一梳理清楚后,最后遇到一个比较难搞的问题。

在docker中明明已经成功安装了mmcv,但是基于该镜像的容器在实际运行代码时会报RuntimeError: Not compiled with GPU support:

File "/opt/conda/lib/python3.8/site-packages/mmdet3d/models/layers/box3d_nms.py", line 271, in nms_bev keep = nms_rotated(boxes, scores, thresh)[1] File "/opt/conda/lib/python3.8/site-packages/mmcv/ops/nms.py", line 444, in nms_rotated keep_inds = ext_module.nms_rotated(dets_wl, scores, order, dets_sorted, RuntimeError: Not compiled with GPU support

环境及安装方式

我们项目使用的环境如下:

  • cuda: 11.2
  • pytorch: 1.9.0
  • python: 3.8
  • mmcv: 2.0.1

安装方式为:

pip install --no-cache-dir mmcv==2.0.1 -f https://download.openmmlab.com/mmcv/dist/cu116/torch1.9.0/index.html

尝试过的方法

找了很多网上的办法,比如重新安装cuda,重新安装pytorch,或者使用mmcv-full等等,没一个能用的。

截止目前唯一有效的办法就是等容器运行起来后在线安装mmcv,然后再运行业务代码。 但是因为mmcv安装过程需要基于cuda进行一些编译工作,所以整个环境准备过程非常耗时,我们云端用的又是虚拟gpu,在满足最低显存的前提下,各个硬件配置不一,有的任务执行时只是安装mmcv就已经耗时90分钟以上,太浪费时间和金钱了。

运行时安装mmcv这个方法可行,但不是长久之计。

基于运行时容器提交新的镜像

后来一次饭局咨询了一位有多年算法工程经验的前同事,他说可以尝试下在容器中安装好mmcv后,再基于该容器commit一个新的镜像。

我随后马上做了相应的尝试,发现并没有什么卵用。 尝试过程如下:

  1. 基于已有镜像运行容器,假设容器id为contianer-1
docker run -it --gpus all image:origin
  1. 在容器中安装mmcv
pip install --no-cache-dir mmcv==2.0.1 -f https://download.openmmlab.com/mmcv/dist/cu116/torch1.9.0/index.html
  1. 基于容器提交一个新的镜像
docker commit contianer-1 image:new

最后在image:new中运行业务代码,发现依然报RuntimeError: Not compiled with GPU support 的错误

解决方案

先说结论: mmcv安装时,对应的cuda路径版本必须大于运行时宿主机cuda版本,例如 云上运行容器的宿主机cuda版本为11.4,则docker build时安装的mmcv应该这样写

pip install --no-cache-dir mmcv==2.0.1 -f https://download.openmmlab.com/mmcv/dist/cu114/torch1.9.0/index.html

-f 参数后面的url中的 dist/cu<cuda_version> 处,cu后面跟的是cuda版本,这个地方的版本号必须大于等于114(注:openmmlab此处的路径忽略了小数点,所以11.4就是114,11.6就是116)

转机

经过多次痛苦又耗时的尝试后,发现mmcv是否可用主要和容器所在宿主机的cuda版本有关,和docker image中设置的cuda版本无关

我们的base image设置如下,之前一直陷入一个误区,以为mmcv必须要和base image的cuda版本一致:

ARG PYTORCH="1.9.0"
ARG CUDA="11.2"
ARG CUDNN="8"

FROM nvcr.io/nvidia/pytorch:21.03-py3

# install system dependencies
RUN apt-get update -y && apt-get install -y \
libglib2.0-0 \
libxrender1 \
libsm6 \
libxext6 \
libgl1

CMD ["/bin/bash"]

在dockerFile中修改了mmcv的 -f 参数对应的安装路径后,终于可以在容器中直接使用mmcv了,不用再在线安装了mmcv这个巨大的包了。

至此,问题圆满解决。

剩下的就是处理一些docker build加速以及镜像拉取加速的小问题了,大家有相关的问题也可以在评论区留言讨论咨询,我看到后会一一解答