使用vscode进行服务器python代码调试/以及使用debugpy进行复杂代码调试
使用vscode进行代码调试/以及使用debugpy进行复杂代码调试
- 前言:
- 方法一:使用ipdb对程序进行调试
- 1.1 直接命令行运行ipdb:(不建议直接命令行运行,建议代码中插入)
- 1.2 直接在代码片段中插入ipdb(推荐使用这个方法):
- 1.3 ipdb命令行调试的一些常用指令:
- 方法二:VScode中的python调试
- 2.1 简单调试
- 2.2 复杂命令调试(命令行调试)
- 2.21 debugpy直接插入代码里:
- 2.22 如何修改复杂命令?
- 参考文档
前言:
大家首先要会使用vscode连接服务器,之后再考虑调试,连接服务器。可以参考下面这个帖子:
ssh使用vscode连接linux服务器【autodl服务器】,并调出命令行运行代码【允许python代码跳转】
笔者已经提前在服务器上安装了Python
和Python Debugger
插件。大家也提前安装一下。
方法一:使用ipdb对程序进行调试
1.1 直接命令行运行ipdb:(不建议直接命令行运行,建议代码中插入)
首先需要安装 ipdb:
pip install ipdb
之后我们可以试着创建一个代码文件,就叫它test.py
吧。
class Book:
def __init__(self, title, author, year):
self.title = title
self.author = author
self.year = year
def __str__(self):
return f"'{self.title}' by {self.author} ({self.year})"
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
def remove_book(self, title):
self.books = [book for book in self.books if book.title != title]
def find_books_by_author(self, author):
return [book for book in self.books if book.author == author]
def list_books(self):
for book in self.books:
print(book)
def main():
library = Library()
# 添加书籍
library.add_book(Book("1984", "George Orwell", 1949))
library.add_book(Book("To Kill a Mockingbird", "Harper Lee", 1960))
library.add_book(Book("The Great Gatsby", "F. Scott Fitzgerald", 1925))
library.add_book(Book("Brave New World", "Aldous Huxley", 1932))
# 列出所有书籍
print("All books in the library:")
library.list_books()
print()
# 查找某个作者的书籍
author = "George Orwell"
print(f"Books by {author}:")
books_by_author = library.find_books_by_author(author)
for book in books_by_author:
print(book)
print()
# 删除书籍
library.remove_book("1984")
print("After removing '1984':")
library.list_books()
# 使用循环进行一些复杂操作
print("
Books published before 1950:")
for book in library.books:
if book.year < 1950:
print(book)
if __name__ == "__main__":
main()
在终端上输入
python -m ipdb test.py
就可以从程序开头一行一行的调试了:
1.2 直接在代码片段中插入ipdb(推荐使用这个方法):
但是直接在代码中运行ipdb
的话,可能不能直接命中我们需要调试的片段,特别是如果我们跑一个非常大的项目的时候,只希望在项目中的某一个代码文件的某一片段检查一下,我们需要在那个需要中断的地方插入上如下代码。
import ipdb;ipdb.set_trace();
程序跑的时候就会在你设置断点的位置停下来。
我们在#删除书籍
上面插入了import ipdb;ipdb.set_trace();
程序也刚好运行到这里停了下来。如果是大项目中的某一个代码文件,这样插入也有用。
1.3 ipdb命令行调试的一些常用指令:
h
:帮助命令(help)s
:(step into)进入函数内部n
:(next)执行下一行b
: (break)b line_number
对某行号打断点cl
: (clear)清除断点c
: (continue)一直执行到断点r
: (return)从当前函数返回j
: (jump)j line_number
,跳过代码片段,直接执行指定行号所在的代码l
: (list)列出上下文代码a
: (argument)列出传入函数所有的参数值p/pp
: print 和 pretty print 打印出变量值r
: (restart)重启调试器q
: (quit)退出调试,清除所有信息
方法二:VScode中的python调试
2.1 简单调试
我们现在仍然使用上面创建的test.p
y文件作为案例来讲解。
从服务器文件中点开test.py
,同时打上断点
(小红点)。
之后,从左侧“运行
”选项卡访问调试程序。点击“运行和调试
”之后,在上方选择调试器处,我选择了“Python Debugger
”调试器。(因为我想调试的是python代码,如果是其他的代码,比如Node.js
,也要更换相应的调试工具。)
之后选择当前python文件
(第一条,也就是我们现在点开的test.py
文件)
然后程序运行到断点就停下来了。
至于调试的按钮,大家有过调试经验的,尝试一下就知道了,就不细说了。
当然也可以直接从vscode
程序的右上角,进行python
代码运行和调试。
2.2 复杂命令调试(命令行调试)
在vsocde中,有两种核心调试模式:Launch
和Attach
。我通常使用Attach
模式进行复杂命令的调试。
有的时候,我不是只跑一个文件,而是跑一个非常大的项目,同时项目的执行命令非常复杂,这个时候如何调试呢?
比如我现在想调试scene graph generation benchmark
项目。
其运行命令如下:
CUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.launch --master_port 10026 --nproc_per_node=2 tools/relation_train_net.py --config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp
这种情况,没有办法直接通过调试按钮进行运行。不过幸运的是,如果在您的 Python
环境中安装了debugpy
,调试器也可以从命令行运行。
调试器命令行语法如下:
python -m debugpy
--listen | --connect
[<host>:]<port>
[--wait-for-client]
[--configure-<name> <value>]...
[--log-to <path>] [--log-to-stderr]
<filename> | -m <module> | -c <code> | --pid <pid>
[<arg>]...
接下来我会解释如何使用命令行调试功能。
- 安装debugpy:
pip install debugpy
- 点击创建
launch.json
文件。
- 我们选择
Python Debugger
。并且继续选择当前python文件
。打开launch.json
文件。
刚才是没有进入调试器时的操作,如果你已经进入了调试器,可以直接点击添加配置
。打开launch.json
文件。
4… 修改launch.json
文件。
初始时的launch.json
文件是这样的:
launch.json
中可选的调试方式有两种,一种是launch
,一种是attach
,之后我们把request修改成attach
的模式。即如下:(注意,端口号要选择自己服务器的端口号
。我是用的autodl服务器,这个服务器可选的端口号是6006
(如果使用的商业服务器比如autodl,可能连接的时候不能翻墙))
{
"version": "0.2.0",
"configurations": [
{
"name": "Python 调试程序: 当前文件",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 6006
}
}
]
}
之后我们在命令行运行如下命令(因为wait-for-client
服务器端开始受到调试指令,并等待客户端的进一步命令):
python -m debugpy --listen 6006 --wait-for-client ./test.py
接着我们点击F5
。和远程服务器成功连接,并且可以从我们打断点的地方开始调试:
运行大项目的时候,使用attach
调试模式会非常方便。
2.21 debugpy直接插入代码里:
实际上可以直接把debugpy放在代码里运行(这个方法不用修改命令行的命令,可能会简单一点?):
在代码入口放入:
import debugpy
debugpy.listen(("localhost", 5678))
print("Waiting for debugger attach...")
debugpy.wait_for_client()
# debugpy.breakpoint()
print("Debugger attached.")
# 你的程序代码
之后本地运行你的Python脚本,点击F5
:
python your_script.py
(我一步直接修改命令,这个方法没有尝试过)
2.22 如何修改复杂命令?
比如我们运行的程序命令如下,如何修改成attach
可以识别并调试的命令呢?
CUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.launch --master_port 10026 --nproc_per_node=2 tools/relation_train_net.py --config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp
方法一: 在项目入口代码里直接放上debugpy,就不用修改复杂命令了。
方法二:交给gpt就好啦。让GPT去修改。
我问gpt:
我现在想要使用vscode的debugpy调试一个项目,项目的运行命令如下:
CUDA_VISIBLE_DEVICES=0,1 python -m torch.distributed.launch --master_port 10026 --nproc_per_node=2 tools/relation_train_net.py --config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp我现在想要使用vscode的attach调试功能,使用6006端口号,像运行这个小文件一样运行这个项目:
python -m debugpy --listen 6006 --wait-for-client ./test.py那我应该如何修改这个项目的运行指令呢?我说的不是在文件中添加debugpy代码,而是命令行直接运行并调试。
gpt回答:
gpt回答:
CUDA_VISIBLE_DEVICES=0,1 python -m debugpy --listen 6006 --wait-for-client -m torch.distributed.launch --master_port 10026 --nproc_per_node=2 tools/relation_train_net.py --config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL False MODEL.ROI_RELATION_HEAD.PREDICTOR CausalAnalysisPredictor MODEL.ROI_RELATION_HEAD.CAUSAL.EFFECT_TYPE none MODEL.ROI_RELATION_HEAD.CAUSAL.FUSION_TYPE sum MODEL.ROI_RELATION_HEAD.CAUSAL.CONTEXT_LAYER motifs SOLVER.IMS_PER_BATCH 12 TEST.IMS_PER_BATCH 2 DTYPE “float16” SOLVER.MAX_ITER 50000 SOLVER.VAL_PERIOD 2000 SOLVER.CHECKPOINT_PERIOD 2000 GLOVE_DIR /home/kaihua/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/kaihua/checkpoints/pretrained_faster_rcnn/model_final.pth OUTPUT_DIR /home/kaihua/checkpoints/causal-motifs-sgcls-exmp
之后我们再对master_port的端口号做一些修改,比如修改成6006这样,稍微改一改,复杂命令的项目就能成功运行啦。
我在这里贴一下我的源命令
和修改过后的命令
,方便大家参考(这里去掉了master_port 和 nproc_per_node ,实际上我觉得修改过就可以了,重新加上也可以,可能是我当时跑的时候线程不够用了。):
原命令:
CUDA_VISIBLE_DEVICES=0 python -m torch.distributed.launch --master_port 10027 --nproc_per_node=1 tools/relation_test_net.py --config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL True MODEL.ROI_RELATION_HEAD.PREDICTOR TransformerPredictor TEST.IMS_PER_BATCH 1 DTYPE “float16” GLOVE_DIR /home/Scene-Graph-Benchmark.pytorch/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp OUTPUT_DIR /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp
修改后的命令:
CUDA_VISIBLE_DEVICES=1 python -m debugpy --listen 45396 --wait-for-client tools/relation_test_net.py --config-file “configs/e2e_relation_X_101_32_8_FPN_1x.yaml” MODEL.ROI_RELATION_HEAD.USE_GT_BOX True MODEL.ROI_RELATION_HEAD.USE_GT_OBJECT_LABEL True MODEL.ROI_RELATION_HEAD.PREDICTOR TransformerPredictor TEST.IMS_PER_BATCH 1 DTYPE “float16” GLOVE_DIR /home/Scene-Graph-Benchmark.pytorch/glove MODEL.PRETRAINED_DETECTOR_CKPT /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp OUTPUT_DIR /home/Scene-Graph-Benchmark.pytorch/checkpoints/rtpb-precls-exmp
参考文档
- VS Code 中的 Python 调试
- VS Code 中的 Python 调试
- 在 VS Code 中开始使用 Python
命令行可选项(可以咨询gpt分别都是什么意思):