如何在使用交互式会话时,通过VS Code在远程计算机上运行代码的调试会话?

21
我正在使用一个类似于slurm的condor集群,并希望使用VS code(特别是其调试器)和remote sync extension运行我的代码。
我尝试在VS code中使用调试器来运行它,但结果并不如预期。
首先,像往常一样使用VS code和远程同步登录到集群,这个操作正常工作。然后,我使用以下命令获取交互作业:
condor_submit -i request_cpus=4 request_gpus=1

然后成功分配了一个节点/GPU。

一旦我拥有它,我尝试运行调试器,但某种方式它会将我从远程会话中注销(并且从打印语句中看起来好像它会转到头节点)。这不是我想要的。我想在分配给我的节点/GPU的交互式会话中运行作业。为什么VS Code在错误的位置运行它?我如何在正确的位置运行它?


一些来自集成终端的输出:

source /home/miranda9/miniconda3/envs/automl-meta-learning/bin/activate
/home/miranda9/miniconda3/envs/automl-meta-learning/bin/python /home/miranda9/.vscode-server/extensions/ms-python.python-2020.2.60897-dev/pythonFiles/lib/python/new_ptvsd/wheels/ptvsd/launcher /home/miranda9/automl-meta-learning/automl/automl/meta_optimizers/differentiable_SGD.py 
conda activate base
(automl-meta-learning) miranda9~/automl-meta-learning $ source /home/miranda9/miniconda3/envs/automl-meta-learning/bin/activate
(automl-meta-learning) miranda9~/automl-meta-learning $ /home/miranda9/miniconda3/envs/automl-meta-learning/bin/python /home/miranda9/.vscode-server/extensions/ms-python.python-2020.2.60897-dev/pythonFiles/lib/python/new_ptvsd/wheels/ptvsd/launcher /home/miranda9/automl-meta-learning/automl/automl/meta_optimizers/differentiable_SGD.py 
--> main in differentiable SGD
hello world torch_utils!
vision-sched.cs.illinois.edu
Files already downloaded and verified
Files already downloaded and verified
Files already downloaded and verified
-> initialization of DiMO done!

---> i = 0, iteration/it 1 about to start
lp_norms(mdl) = 18.43514633178711
lp_norms(meta_optimized mdl) = 18.43514633178711
[e=0,it=1], train_loss: 2.304989814758301, train error: -1, test loss: -1, test error: -1

---> i = 1, iteration/it 2 about to start
lp_norms(mdl) = 18.470401763916016
lp_norms(meta_optimized mdl) = 18.470401763916016
[e=0,it=2], train_loss: 2.3068909645080566, train error: -1, test loss: -1, test error: -1

---> i = 2, iteration/it 3 about to start
lp_norms(mdl) = 18.548133850097656
lp_norms(meta_optimized mdl) = 18.548133850097656
[e=0,it=3], train_loss: 2.3019633293151855, train error: -1, test loss: -1, test error: -1

---> i = 0, iteration/it 1 about to start
lp_norms(mdl) = 18.65604019165039
lp_norms(meta_optimized mdl) = 18.65604019165039
[e=1,it=1], train_loss: 2.308889150619507, train error: -1, test loss: -1, test error: -1

---> i = 1, iteration/it 2 about to start
lp_norms(mdl) = 18.441967010498047
lp_norms(meta_optimized mdl) = 18.441967010498047
[e=1,it=2], train_loss: 2.300947666168213, train error: -1, test loss: -1, test error: -1

---> i = 2, iteration/it 3 about to start
lp_norms(mdl) = 18.545459747314453
lp_norms(meta_optimized mdl) = 18.545459747314453
[e=1,it=3], train_loss: 2.30662202835083, train error: -1, test loss: -1, test error: -1
-> DiMO done training!
--> Done with Main
(automl-meta-learning) miranda9~/automl-meta-learning $ conda activate base
(automl-meta-learning) miranda9~/automl-meta-learning $ hostname vision-sched.cs.illinois.edu

没有调试模式无法运行

问题比我想象的更严重。我不能在交互式会话中运行调试器,但是我甚至不能“不带调试运行”,因为它会自动切换到Python Debug Console。这意味着我必须手动运行python main.py,但这将导致我无法使用变量窗格...这是一个很大的损失!

我正在将终端切换到conoder_ssh_to_job,然后单击按钮Run Without Debugging(或^F5Control + fn + f5),尽管我确保在我的集成窗口底部处于交互式会话状态,但它仍会自动转到Python Debugger窗口/窗格,这与我从集群请求的交互式会话没有连接...


相关:

3个回答

13

最近我遇到了一个相关问题(我想在计算节点上使用VsCode的交互式Python能力),之前提到的方法都不起作用,但是这个方法解决了问题:

  1. ssh连接到远程集群:ssh cluster
  2. 在远程集群内,将我的公钥添加到authorizedkeys中,通常是将~/.ssh/id_rsa.pub(本地机器)的内容附加到.ssh/authorized_keys(远程集群)
  3. 在集群内分配一些资源(这个特定集群使用slurm而不是condor,所以在这种情况下我使用类似于srun --pty bash的命令)
  4. 获取计算节点的名称,通常可以在命令行中看到:username@nodename。为了方便起见,我们假设我得到了一个通用名称node001
  5. 为了简化操作,修改本地机器上的~/.ssh/config文件,并将其编辑为:
Host cluster
   # stuff written

Host node*
    HostName %h
    ProxyJump cluster
    User $USERNAME

现在我可以从本地机器ssh到它(只要计算节点正在运行),命令是ssh node001

在VsCode中,操作如下:

  1. CTRL+P > Remote-SSH: Connect to Host...
  2. 输入节点名称,在此处为node001
  3. 连接到节点后,您运行的每个交互式Python程序(包括jupyter和jupytext)都将访问您分配的资源

我不知道这个解决方案有多通用,但希望至少能帮助某些人!


12

您可以尝试颠倒操作顺序:首先提交作业,获取分配给您的计算节点的名称,然后指示 VSCode 连接到计算节点而不是登录节点。

因此,首先要做的是

condor_submit -i request_cpus=4 request_gpus=1

并注意计算节点的名称。以下假设为 node001

然后,在您的笔记本电脑上打开VSCode,单击远程开发扩展图标,并选择“Remote SSH: Connect to Host...”。选择“+ Add new SSH host...”。在“输入SSH命令”框中添加以下内容:

ssh -J vision-sched.cs.illinois.edu miranda9@node001

在VSCode中,它会询问您应该更新哪个SSH配置文件。确保检查配置:如果需要,请指定SSH密钥,用户名等。还要确保在该文件中正确配置了vision-sched.cs.illinois.edu

然后您可以选择连接到该主机。 VSCode将在计算节点上执行,并在分配完成时断开连接。


1
“-J”选项是什么?为什么需要它,它似乎是额外的东西(评论以使答案更自包含)? - Charlie Parker
2
“-J”选项是使用代理。由于计算节点未连接到公共互联网,因此必须通过登录节点访问它。 - damienfrancois
尝试先让 ssh -J ... 部分正常工作。最好的方法是在您的 .ssh/config 文件中配置连接。创建 SSH 密钥对并将它们安装在您的集群中。还要检查您的集群文档,看看是否有有关 SSH 连接到计算节点的信息。 - damienfrancois
@damienfrancois,首先感谢您提供的解决方案。我已经为我的交互式slurm作业分配了2个GPU,但是当我打开一个ssh会话到计算节点时,所有GPU都暴露给了VS code。我该如何避免这种情况?您能否详细说明一下您如何使用SLURM进行测试?谢谢。 - arash
这在只允许对主目录文件系统进行只读访问的计算节点上会失败。 - dbrane
显示剩余5条评论

6

下面是一个更简单的解决方法:

  1. 在远程服务器上创建一个名为 bash 的文件,放在某个位置,例如 /home/myuser/pathto/bash
  2. 使用 chmod +x bash 命令使其可执行
  3. bash 文件中写入 salloc [您所需的交互式任务选项]
  4. 在 vscode 设置中搜索 Automation Shell: Linux 并点击 "Edit in settings.js"
  5. 更改以下一行代码:"terminal.integrated.automationShell.linux": "/home/myuser/pathto/bash" 并保存它(使用绝对路径。例如 ~/pathto/bash 在我的情况下无效)
  6. 完成 :)

现在每次运行调试器时,都会先询问交互式任务,然后调试器将在该任务上运行。但请注意,此操作也适用于在 tasks.json 中运行的任务。
您还可以使用 srun 代替 salloc。例如:srun --pty -t 2:00:00 --mem=8G bash


我正在尝试使用这种方法调试C程序时遇到了问题。当我在VSCode上启动调试会话时,它会在登录节点的/tmp目录下创建一些随机文件,然后在计算节点的/tmp目录下找不到这些文件时失败。有什么办法可以解决这个问题吗? - Seralpa
很遗憾,我认为这种方法只适用于登录节点和计算节点相同的情况。 - asalimih

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接