Docker+PyCharm+Miniconda实现深度学习代码远程调试和环境隔离
本文详细介绍了如何在局域网环境下,利用Docker、PyCharm和Miniconda构建一个高效的深度学习远程调试平台。首先在服务器(server)上,通过Docker构建包含不同CUDA环境的镜像,以运行容器并实现环境的隔离。通过位于主机(host)的PyCharm,将项目代码deploy至容器中,从而实现远程debug或代码运行。为了处理容器内产生的大量数据文件,这些文件将被挂载到服务器的存储设备上。此外,通过在服务器(Windows系统)上设置文件分享,与主机建立连接,便于用户在主机上访问和浏览由深度学习应用产生的数据。这种配置确保Host内的项目代码只能在Host上被修改,而server上的数据文件只能在host上被预览且不可更改,从而最大程度上保障了数据的安全性和完整性。
环境说明
- Windows 11 23H2
- Docker Desktop 4.34.2(Windows)
- Docker Engine v27.2.0
- PyCharm 2024.2.1
- GeForce 3060Ti
路由配置
WAN口接入互联网,LAN口接host和servers,为LAN口配置静态ip(例如本文主图的静态ip配置)。
关于路由:我选用的是水星(Mercury)MR100GP-AC 商用5口千兆有线路由-250元。
Docker设置(Windows系统)
以Windows上Docker Desktop 4.34.2 (167172)为例。
环境配置
docker图标右键,switch to Linux containers
切换至Linux container!如果显示switch to Windows containers
说明已经在Linux container环境了,跳过该步骤即可。
设置里builders把desktop-Linux设置为default builder.
网络配置
设置里general->expose daemon on tcp://localhost:2375选项开启。(让其他软件可以调用docker的daemon接口)
that only can be accessed via tcp://127.0.0.1, My inner IP address 192.168.3.9 doesn’t work. The document said to edit the C:\ProgramData\Docker\config\daemon.json and add “hosts”: [“tcp://0.0.0.0:2375”], but it’s doesn’t work for any IP address, I’m very sure I did it as the document.
不要尝试上述方案,因为不起作用。请按下述方式进行。
管理员身份运行Windows powershell,运行(监听+防火墙):
netsh interface portproxy add v4tov4 listenport=2375 connectaddress=127.0.0.1 connectport=2375 listenaddress=192.168.1.3 protocol=tcp
netsh advfirewall firewall add rule name="docker_daemon" dir=in action=allow protocol=TCP localport=2375
listenaddress=192.168.1.3
是我server的静态ip,你应当修改为你的server的实际地址。
设置docker的proxy才能拉取镜像,或者换源(大部分镜像最近都失效了或者只能在校园/公司网内部使用)。
注意,上述ip和port应当改成你自己局域网内的proxy地址。
连接测试
pycharm(2024.2): settings->build,execution,deployment->docker
通过TCP socket连接server’s docker,若virtual machine path那个框内有项目,可以先把里面的项目删掉。看是否显示connection successful
.
然后你可以在pycharm里远程控制docker on the server.(找到侧边栏services或快捷键alt+8)。你可以自行探索一下pycharm的远程docker控制功能有哪些。
构建image
直接pull image
我构建好的镜像已上传my docker hub,可以直接pull,避免手动构建失败:
- GeForce 3060Ti适用
- 此镜像从nvidia官方镜像
nvidia/cuda:11.3.1-cudnn8-runtime-ubuntu20.04
构建
docker pull sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04
image push命令:
docker push sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04 # The push refers to repository [docker.io/sylvanding/my-cuda]
从Dockerfile手动构建
我的server使用GeForce 3060Ti(以此为例),我们从nvidia官方镜像nvidia/cuda:11.3.1-cudnn8-runtime-ubuntu20.04
开始构建dockerfile:
- 继承官方cuda和cudnn runtime环境
- 安装工具包(最重要的是openssh-server将用于pycharm远程连接)
- 修改root用户登录密码
- 修改openssh配置文件,允许远程连接
- 安装
nvidia-container-toolkit
(会根据当前容器环境自动选择合适的版本),从而使nvidia-smi
等命令可以运行 - 安装miniconda
- 设置工作目录和暴露接口
上述dockerfile文件如下:
FROM nvidia/cuda:11.3.1-cudnn8-runtime-ubuntu20.04LABEL maintainer="sylvanding@qq.com"# set env
# https://stackoverflow.com/questions/61388002/how-to-avoid-question-during-the-docker-build
ENV TZ=Asia/Shanghai \DEBIAN_FRONTEND=noninteractiveRUN apt-get update && apt-get install -y \wget \curl \git \bzip2 \vim \openssh-server \&& rm -rf /var/lib/apt/lists/*# change root pwd
ARG USERPWD=123456
RUN echo "root:${USERPWD}" | chpasswd# openssh config
RUN mkdir /var/run/sshd
RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config.d/ssh_config.conf \&& echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config.d/ssh_config.conf
RUN service ssh restart# install nvidia-container-toolkit
# https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
## configure the production repository
RUN curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o \/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
## update the packages list from the repository
RUN apt-get update
## install the NVIDIA Container Toolkit packages
RUN apt-get install -y nvidia-container-toolkit# install Miniconda
# https://docs.anaconda.com/miniconda/#quick-command-line-install
RUN mkdir -p ~/miniconda3
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
RUN bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
RUN rm ~/miniconda3/miniconda.sh
## initialize newly-installed Miniconda
RUN ~/miniconda3/bin/conda init bashWORKDIR /reposEXPOSE 22 8080
各个组件的版本选择:显卡驱动 → CUDA → CUDA Toolkit → cuDNN → Pytorch
通过命令构建image
docker build --build-arg HTTP_PROXY=http://192.168.1.2:10811 -f ./path/to/your/Dockerfile -t sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04 .
注意:修改你的http_proxy才能顺利构建环境(国内)。
在pycharm里构建image
打开编写的dockerfile,edit
设置build image的配置:
name是你这个run configuration的名称,server选择你刚刚添加的docker服务器接口,注意:在build args中添加http_proxy才能顺利构建环境(国内)。之前设置的proxy只是docker desktop的proxy,这里构建镜像时要再次指定! 最后,apply和run。
创建容器
pycharm里选中image右键create container.
docker run配置:
- server: 设置为之前配置的网络docker
- bind ports: 将container 22端口映射到server的2222端口
- bind mounts: 将container的
/repos
工作路径挂载到server的E:\repos
,方便以后直接在server(Windows)里设置E:\repos
文件夹网络共享文件 - env variables: 为container设置proxy,记得更换为你自己的
- run options:
--gpus all
docker run -p 2222:22 -v E:\repos:/repos --env http_proxy=http://192.168.1.2:10811 --env https_proxy=http://192.168.1.2:10811 --name cuda113-cudnn8-ubuntu20 --pull missing --restart always --gpus all sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04
☑️ container创建成功:
PyCharm项目部署和远程同步(基于Windows文件共享)
pycharm项目部署
settings->deployment->new SFTP
新建ssh连接
❌ 若test connection提示:Cannot connect to remote host: net.schmizz.sshj.transport.TransportException: Server closed connection during identification exchange,首先尝试重启ssh服务
docker exec cuda113-cudnn8-ubuntu20 service ssh restart
. 若依然无法连接,检查/etc/ssh/sshd_config.d/*.conf
和/etc/ssh/sshd_config
等ssh配置文件和防火墙配置,修改正确后重启ssh服务再次进行test connection.
root path设置为工作目录;Rsync可根据个人需求选择是否开启。
设置项目mapping路径:local path是本地项目路径 --mapping>>
deployment path是server上相对于root path的远程项目路径。
向server的development path推送项目:选中需要推送的项目(比如我的project是DBlink),工具栏tools->deployment->upload…,建议开启automatic upload.
⚠️ 不推荐使用Deployment中的 Mapping 设置,为记录的完整性在此列出相关操作。更推荐在配置远程interpreter时直接设置项目同步(见下一节),原因如下:
- Deployment 功能主要用于将本地开发环境中的文件部署到远程服务器上。这包括将代码文件、资源和相关配置文件传输到线上环境或开发测试服务器中。
- SSH 连接解释器中的 Sync Folders 设置,主要用于同步本地和远程解释器环境中的文件,以便在远程服务器上运行和测试代码,同时保持本地和远程环境的代码一致性。非常适合于远程开发场景,可以在本地编辑代码并直接在远程环境下运行和调试。
Deployment 主要用于部署,而 Sync Folders 更侧重于持续的开发和实时调试。如果是开发过程中频繁需要测试代码,即利用远程资源和环境,则使用 SSH 解释器的 Sync Folders 更为合适;如果主要是将更新推送到生产或测试环境,使用 Deployment 功能会更直接有效。 ——generated by GPT
推送成功结果查看:
pycharm远程miniconda环境解释器配置
通过ssh连接远程container,调用miniconda,获取miniconda中的所有虚拟python环境。设置双向文件同步。
settings->project->python interpreter->add interpreter ->on ssh
⚠️ 这里并非创建基于docker的interpreter,因为我的之前run的container cuda环境在多个项目中是可以复用的,因此我们在container中用miniconda创建虚拟环境是一种更好的选择。
自动读取远程环境配置…
选择conda environment,设置conda虚拟环境。sync folders填写工作路径/repos/your project name
,勾选自动上传到服务器。
查看interpreter配置结果:
查看同步情况:
查看从container->server的挂载是否成功:
Windows文件共享
⚠️ 测试发现,pycharm可以实现本地文件的Automatic upload,但无法实现服务器端文件更新后传回本地。事实上,在深度学习模型训练、测试过程中产生的大量数据文件也不需要传回本地,可以使用Windows的文件共享实现在server端共享挂载的文件夹,在本地预览server上的文件,选择需要的数据文件进行下载,降低本地存储大小。
在host和server(均为Windows操作系统)上开启网络共享。
server
server: 在局域网上共享container挂载的E:\repos:/repos
.
server上也可以管理共享或查看所有共享:
host
Host: 在host上挂载server共享的repos文件夹:
这样,数据文件存放在远端电脑,而host可以通过文件共享的方式预览文件(并不会下载文件到本地)。
Windows通过SSH连接实现远程显存监控
Server(Windows)
Windows开启SSH-server服务
检查 OpenSSH 的可用性
管理员身份打开powershell并运行:
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
如果任何 SSH 客户端或服务器功能不可用,请根据 PowerShell (Admin) 中的要求使用以下命令。
安装 OpenSSH 服务器
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
再次检查可用性。
修改ssh-server配置文件
默认情况下,OpenSSH 客户端和 OpenSSH 服务器位于以下目录:C:\Windows\System32\OpenSSH
. 管理员身份打开记事本,再在记事本里打开配置文件sshd_config_default
.
修改如下部分:
- PermitRootLogin yes
- PasswordAuthentication yes
保存。搜索service服务:
找到openssh ssh server
服务,修改启动方式为“自动”,点“启动”。然后apply and ok.
Host(-)
Host通过ssh服务测试连接server(Windows ssh):
ssh admin@192.168.1.3
显卡状态监控:
nvidia-smi -l 5
测试pytorch能否正常使用显卡
参考官方文档安装pytorch后,尝试运行下述代码:
import torchprint(torch.cuda.is_available())
输出true,则pytorch cuda版运行正常。
原创声明:©️ 本文为博主原创文章,转载需注明出处——https://blog.csdn.net/IYXUAN