先说说我为啥要用Docker。搞过CV的都知道,OpenCV、TensorFlow、PyTorch这些库的版本兼容性特别烦人。比如我们项目需要TensorFlow 2.4,但服务器上装的是2.6,就这么一点版本差异,代码就跑不起来了。更别说还有CUDA toolkit、cuDNN这些深度学习依赖,版本搭配更是让人头疼。Docker就能把这些环境全部打包成一个镜像,随时随地都能部署,再也不用担心环境不一致的问题了。
下面直接上干货。首先得准备Dockerfile,这个文件就是用来定义镜像内容的。我通常从NVIDIA官方的基础镜像开始,因为他们已经集成了CUDA和cuDNN,省去了很多配置的麻烦。比如这样:
这个Dockerfile做了几件事:基于CUDA环境的基础镜像,安装Python和pip,然后把项目依赖文件拷进去安装,最后设置工作目录。requirements.txt里面就是项目需要的所有Python包,像opencv-python、tensorflow-gpu、pillow这些。
构建镜像的命令很简单:
但这里有个坑要注意,如果用的不是NVIDIA Docker,GPU加速是用不了的。所以运行时得加上--gpus参数:
在实际项目中,我还遇到了摄像头和图形界面显示的问题。如果是做实时目标检测,需要访问主机摄像头,得加上--device参数:
要是想在容器里运行GUI程序并显示在主机上,还要挂载X11 socket:
数据持久化也是个重要问题。训练数据总不能每次都拷进容器吧?可以用数据卷或者直接挂载主机目录:
说到生产环境部署,Docker Compose就派上用场了。特别是微服务架构的CV应用,比如一个服务做图像预处理,一个服务跑模型推理,用docker-compose.yml可以轻松管理多个容器:
最后分享几个实践中的小技巧。一是镜像要尽量小,可以用.dockerignore文件排除不必要的文件,比如数据集、日志这些。二是多阶段构建,把编译环境和运行环境分开,最终镜像只包含运行必需的内容。三是善用镜像缓存,把不经常变动的层放在Dockerfile前面,这样可以加速构建过程。
说实话,刚开始用Docker的时候觉得挺麻烦的,又要写Dockerfile,又要学各种命令。但用熟练之后发现真能省下不少时间,特别是在团队协作和持续集成场景下。现在我们的CV项目从开发到部署都用Docker,再也没出现过"在我机器上好好的"这种问题。
当然Docker也不是万能的,比如对GPU资源的管理就比较基础,如果需要更细粒度的资源控制,可能还得上Kubernetes。但对于大多数计算机视觉项目来说,Docker已经足够好用了。希望这些经验对正在被环境问题困扰的小伙伴有所帮助。