跳到主要内容

PyCharm 远程开发

远程开发主要基于将开发环境(包括代码编辑、编译、运行等)从本地机器转移到远程服务器上,这个过程涉及几个关键组件和概念:

1.远程服务器

远程服务器是托管远程开发环境的中心,可以是一个物理服务器,也可以是云中的虚拟机,比如在 GPUGEEK 平台,远程服务器为平台的 实例,服务器需要配置可以运行代码的环境。

2.网络连接

远程开发重依赖于网络连接,允许开发者的本地电脑与远程服务器进行通信,这包括文件传输、命令执行、结果返回等。

3.开发工具和IDE

开发者在本地电脑上使用的集成开发环境(Pychrm、VS Code或者其它IDE)通常具有连接远程服务器并在远程环境中执行任务的能力。

在 GPUGEEK 平台使用远程开发的适用场景如下:

  1. 本地电脑没有GPU或本地电脑硬件配置无法运行当前项目。
  2. 本地安装环境较为复杂,不想折腾调试本地环境。
  3. 本地调试后再上传到GPU服务器麻烦,不如在服务器上调试后直接 run。
  4. 统一开发环境,防止本地调试完成可以正常 run 后,代码上传到实例中却报一堆错误。
提示

远程开发非常依赖网络稳定性,在 GPUGEEK 平台使用 IDE 工具进行远程开发,网络连接方式为:本地电脑 IDE - GPUGEEK 平台网络转发服务器 - GPUGEEK平台实例,以下情况可能会发生本地 IDE 与实例服务器网络断开连接。

  1. 本地电脑睡眠、本地电脑 Wifi 连接网络出现断连。
  2. 本地网络出现波动,与 GPUGEEK 网络转发服务器断开连接。
  3. GPUGEEK 网络转发服务器流量过载主动断开连接。
  4. 实例所在机房流量过载导致网络延迟、网络波动、从而中断连接。

综上所述:通过开发工具IDE连接实例进行远程开发仅适合调试代码,如有长时间训练需求,如连续 N 个小时或 N 天,请通过 ssh 登录到实例终端,配合 tmux、screen、nohup 等工具将训练进程放到后台运行,以免因网络中断而导致训练进程异常关闭。

使用 PyCharm IDE 工具进行连接 GPUGEEK 平台实例进行远程开发。

  1. 确保您的 Pycharm 为专业版,社区版无远程开发功能。
  2. 在 PyCharm 中进行数据集同步非常慢,仅适合代码文件进行同步到服务器端。
  3. 本次文档中演示 PyCharm 版本为 2023.3 (Professional Edition),内部版本号#PY-233.11799.259,已安装汉化插件。
  4. 该文档使用macOS版本进行演示,Windows版本与macOS版本可能有少许差距

1. 新建项目

在 PyCharm 中新建一个项目,如果您的项目已经在本地电脑存在,则绕过该步骤;我这里为了演示代码同步,所以需要准备一个项目,我从 GitHub 拉取了 Yolov5 的项目来进行演示,并且使用本地解释器打印了一个测试页面。

2. 配置远程连接到实例及Python解释器

1. macOS 点击 PyCharm - Settings

2. 项目 - Python解释器 - 添加解释器 - SSH

3. 到 GPUGEEK 控制台 - 个人空间 - 实例管理,找到对应实例的 登录,然后复制 登录指令登录密码

复制后粘贴到任意文件中,内容如下

登录指令:ssh -p 11111 root@xxxxxxxx.gpugeek.com
登录密码:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

命令拆解如下:
实例SSH主机:xxxxxxxx.gpugeek.com
实例SSH端口:11111
实例登录用户名:root
实例登录密码:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
然后把以上对应信息复制到下图中对应框中
  1. 1号标记填入您实例对应SSH主机
  2. 2号标记填入您实例对应的SSH端口
  3. 3号标记填入您实例对应的用户名

然后点击4号标记进行下一步

4. 然后把对应的实例登录密码输入进去,然后点击下一步

5. 这一步会检测通过SSH登录目标实例和Python环境,检测完成后点击下一步

6. 配置远程服务器实例上的Python解释器

根据下图标记操作:
  1. 1号标记选择 Conda 环境,因为平台的官方镜像中默认已安装 Conda 以及在 base 环境中安装了 框架、CUDA、Python。
  2. 2号标记,默认情况下PyCharm会先进行检测 Conda 可执行文件,如果检测不到,可以直接输入该路径 /usr/local/miniconda3/bin/conda
  3. 3号标记,点击加载环境,PyCharm会加载目标实例的 Conda 环境。
  4. 4号标记,使用现有环境,如果现有的 base 环境中的框架、python等不符合您的要求,可以点击创建新环境,不过创建新环境里默认没有框架和Python,需要您后续自行安装。
  5. 5号标记,选择现有环境。
  6. 6号标记,选择要同步到远程服务器实例中的文件目录(具体请看下张图片)。
  7. 同时需要选中自动上传项目文件到服务器
配置本地代码同步到远程服务器实例中的路径
  1. 1号标记为本地电脑项目路径,需要把该目录中的所有代码文件同步到远程服务器实例中 (本地电脑代码项目所在的目录中,比如我本地的 /opt/yolov5 目录中,一定不能存在数据集,该代码文件建议控制在 50MB 以内,否则本地电脑通过 PyCharm 同步该目录到实例中时间会无限长以及超时问题的发生)
  2. 2号标记为本地电脑项目路径同步到实例中的路径,选择同步到实例中所存储的位置,我这里把项目文件同步到实例中的 /gz-data/yolov5 文件中。
  3. 选择完成后,点击确定

7. 然后点击创建 -> 完成

PyCharm会自动同步 /opt/yolov5 目录中的数据到实例的 /gz-data/yolov5 目录下

8. 在本地电脑 PyCharm 中运行代码,可以看到输出使用的是远程服务器实例中的解释器

9. 通过 PyCharm 终端登录实例

  1. 点击左下角终端
  2. 选择创建的 SSH 服务器

3. 测试运行项目

展示测试运行 yolov5 过程

直接 python 训练 yolov5 会去判断当前环境是否满足,然后从 github 以及 images.cocodataset.org 拉取数据集。 如果数据集拉取失败则无法开始训练,可以使用网络加速来解决 https://gpugeek.com/docs/best-practice/network_turbo

(base) root@492132307857413:/gz-data/yolov5# apt-get update -y
(base) root@492132307857413:/gz-data/yolov5# apt-get install libgl1-mesa-glx ca-certificates -y
(base) root@492132307857413:/gz-data/yolov5# pip install -r requirements.txt
(base) root@492132307857413:/gz-data/yolov5# python train.py --data coco.yaml --epochs 300 --weights '' --cfg yolov5n.yaml --batch-size 128
train: weights=, cfg=yolov5n.yaml, data=coco.yaml, hyp=data/hyps/hyp.scratch-low.yaml, epochs=300, batch_size=128, imgsz=640, rect=False, resume=False, nosave=False, noval=False, noautoanchor=False, noplots=False, evolve=None, bucket=, cache=None, image_weights=False, device=, multi_scale=False, single_cls=False, optimizer=SGD, sync_bn=False, workers=8, project=runs/train, name=exp, exist_ok=False, quad=False, cos_lr=False, label_smoothing=0.0, patience=100, freeze=[0], save_period=-1, seed=0, local_rank=-1, entity=None, upload_dataset=False, bbox_interval=-1, artifact_alias=latest
github: skipping check (not a git repository), for updates see https://github.com/ultralytics/yolov5
YOLOv5 🚀 2023-12-12 Python-3.10.10 torch-1.13.1+cu117 CUDA:0 (NVIDIA GeForce RTX 3090, 24260MiB)

hyperparameters: lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0
Comet: run 'pip install comet_ml' to automatically track and visualize YOLOv5 🚀 runs in Comet
TensorBoard: Start with 'tensorboard --logdir runs/train', view at http://localhost:6006/

Dataset not found ⚠️, missing paths ['/gz-data/datasets/coco/val2017.txt']
Downloading https://github.com/ultralytics/yolov5/releases/download/v1.0/coco2017labels.zip to /gz-data/datasets/coco2017labels.zip...
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 46.4M/46.4M [00:04<00:00, 11.9MB/s]
Unzipping /gz-data/datasets/coco2017labels.zip...
Downloading http://images.cocodataset.org/zips/test2017.zip to /gz-data/datasets/coco/images/test2017.zip...
Downloading http://images.cocodataset.org/zips/val2017.zip to /gz-data/datasets/coco/images/val2017.zip...
Downloading http://images.cocodataset.org/zips/train2017.zip to /gz-data/datasets/coco/images/train2017.zip...
Unzipping /gz-data/datasets/coco/images/val2017.zip...

Unzipping /gz-data/datasets/coco/images/test2017.zip...
Unzipping /gz-data/datasets/coco/images/train2017.zip...
Dataset download success ✅ (1428.5s), saved to /gz-data/datasets
Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf...
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 755k/755k [00:00<00:00, 1.18MB/s]

from n params module arguments
0 -1 1 1760 models.common.Conv [3, 16, 6, 2, 2]
1 -1 1 4672 models.common.Conv [16, 32, 3, 2]
2 -1 1 4800 models.common.C3 [32, 32, 1]
3 -1 1 18560 models.common.Conv [32, 64, 3, 2]
4 -1 2 29184 models.common.C3 [64, 64, 2]
5 -1 1 73984 models.common.Conv [64, 128, 3, 2]
6 -1 3 156928 models.common.C3 [128, 128, 3]
7 -1 1 295424 models.common.Conv [128, 256, 3, 2]
8 -1 1 296448 models.common.C3 [256, 256, 1]
9 -1 1 164608 models.common.SPPF [256, 256, 5]
10 -1 1 33024 models.common.Conv [256, 128, 1, 1]
11 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
12 [-1, 6] 1 0 models.common.Concat [1]
13 -1 1 90880 models.common.C3 [256, 128, 1, False]
14 -1 1 8320 models.common.Conv [128, 64, 1, 1]
15 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
16 [-1, 4] 1 0 models.common.Concat [1]
17 -1 1 22912 models.common.C3 [128, 64, 1, False]
18 -1 1 36992 models.common.Conv [64, 64, 3, 2]
19 [-1, 14] 1 0 models.common.Concat [1]
20 -1 1 74496 models.common.C3 [128, 128, 1, False]
21 -1 1 147712 models.common.Conv [128, 128, 3, 2]
22 [-1, 10] 1 0 models.common.Concat [1]
23 -1 1 296448 models.common.C3 [256, 256, 1, False]
24 [17, 20, 23] 1 115005 models.yolo.Detect [80, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [64, 128, 256]]
YOLOv5n summary: 214 layers, 1872157 parameters, 1872157 gradients, 4.6 GFLOPs

AMP: checks passed ✅
optimizer: SGD(lr=0.01) with parameter groups 57 weight(decay=0.0), 60 weight(decay=0.001), 60 bias
train: Scanning /gz-data/datasets/coco/train2017... 117266 images, 1021 backgrounds, 0 corrupt: 100%|██████████| 118287/118287 [00:12<00:00, 9333.47it/s]
train: WARNING ⚠️ /gz-data/datasets/coco/images/train2017/000000099844.jpg: 2 duplicate labels removed
train: WARNING ⚠️ /gz-data/datasets/coco/images/train2017/000000201706.jpg: 1 duplicate labels removed
train: WARNING ⚠️ /gz-data/datasets/coco/images/train2017/000000214087.jpg: 1 duplicate labels removed
train: WARNING ⚠️ /gz-data/datasets/coco/images/train2017/000000522365.jpg: 1 duplicate labels removed
train: New cache created: /gz-data/datasets/coco/train2017.cache
val: Scanning /gz-data/datasets/coco/val2017... 4952 images, 48 backgrounds, 0 corrupt: 100%|██████████| 5000/5000 [00:01<00:00, 4461.27it/s]
val: New cache created: /gz-data/datasets/coco/val2017.cache

AutoAnchor: 4.45 anchors/target, 0.995 Best Possible Recall (BPR). Current anchors are a good fit to dataset ✅
Plotting labels to runs/train/exp5/labels.jpg...
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs/train/exp5
Starting training for 300 epochs...

Epoch GPU_mem box_loss obj_loss cls_loss Instances Size
0/299 14.9G 0.09918 0.08274 0.08872 1793 640: 55%|█████▌ | 513/925 [05:39<02:40, 2.57it/s]
0/299 14.9G 0.09399 0.08324 0.08538 166 640: 100%|██████████| 925/925 [10:16<00:00, 1.50it/s]
Class Images Instances P R mAP50 mAP50-95: 100%|██████████| 20/20 [00:46<00:00, 2.31s/it]
all 5000 36335 0.00279 0.0515 0.00313 0.00101

Epoch GPU_mem box_loss obj_loss cls_loss Instances Size
1/299 23.1G 0.07863 0.08435 0.07822 1657 640: 62%|██████▏ | 570/925 [05:58<02:41, 2.20it/s]

查看 GPU 利用率

(base) root@492132307857413:~# nvidia-smi 
Tue Dec 12 19:48:41 2023
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.23.08 Driver Version: 545.23.08 CUDA Version: 12.3 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA GeForce RTX 3090 On | 00000000:21:00.0 Off | N/A |
| 50% 50C P2 162W / 350W | 22807MiB / 24576MiB | 88% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
+---------------------------------------------------------------------------------------+