Linux Python pdb调试(附带例子解释)


刚读研的时候看到老师用pdb debug觉得很酷,不知道怎么用,下来后自己试了试,我感觉很好用!(1、可能是因为debug的文件夹都比较熟悉了所以觉得pdb好用,建议还是可以用vscode调试;2、亲身体验在Linux使用pdb调试打印model时显示不完整,不利于查看,在vscode的终端pdb调试能完整的看到model)

1、应用场景

用于Linux系统下Python文件的debug。

  • 直接调试Python文件(此时我们的文件夹就全是Python文件,需要调试的Python文件不在一些执行脚本里面)。
  • shell脚本里带有Python文件时(我们实现一些功能的时候,会写一个shell脚本即.sh文件,里面可能包括一些变量、路径之类的,也包括我们要运行的Python文件。运行的时候我们运行.sh文件,如果脚本里有运行Python文件的命令,那自然而然里面的Python文件也被运行到了)。

2、两种方式调试

  • 非侵入式方法
    python -m pdb xxx.py 如果还有后续的参数,直接加在它后面。
    如果是要调试Pytorch的神经网络,如下命令:
    torchrun -m pdb xxx.py : 注意调试的时候使用一个GPU, 一个线程来调试最好。
  • 侵入式方法
    需要在运行的文件中增加一行
    import pdb;pdb.set_trace()

3、基本操作

  • 查看源代码:l 查看当前位置前后11行。ll,查看当前函数的所有代码
  • 运行下一行:n 就是往下运行一行
  • 添加断点:b /mnt/database/xxx.py:100 在/mnt/database/xxx.py路径下的xxx.py文件的第100行打断点
  • 清除断点:cl
  • 打印变量值:p A 打印变量名为A的值(若是想打印这个A的shape之类的属性值都可以,即p A.shape,就会把A的shape打印出来,打印其他属性操作是一样的)
  • 进入函数:s 如果我们运行到某一行,这一行调用了一个函数,我们就可以使用s,然后就可以跳到那个函数里面去
  • 执行下一行:r如果在函数中,直接运行到函数返回处
  • 直接跳转到指定行:j 100 跳到第100行
  • 跳到断点处:c 先使用b打断点,然后使用c就可以直接跳到断点处
  • 持续执行直到运行到指定行:unt 100假如我现在在第20行,使用该命令我可以一直往下执行到第100行
  • 在函数中时打印函数的参数和参数的值:a
  • 退出pdb调试:q
  • 如果要重新开始下一次调试:(即保留断点设置和debugger设置):restart

4、例子解释

  • 我使用的是wenet中写好的run.sh脚本(wenet是一个做语音识别的开源工具),对网络训练的时候进行debug
  • shell脚本内容(看下我代码里的注释)
#!/bin/bash
. ./path.sh || exit 1;

export CUDA_VISIBLE_DEVICES="0"
export NCCL_DEBUG=INFO

num_nodes=1

node_rank=0

data=/mnt/database/luody/wenet-main/examples/aishell/s0/data1
data_url=www.openslr.org/resources/33

nj=16
dict=data/dict/lang_char.txt
data_type=raw
num_utts_per_shard=1000

train_set=train
train_config=/mnt/database/luody/wenet-main/examples/aishell/s0/conf/train_conformer.yaml
cmvn=true
dir=/mnt/database/luody/wenet-main/examples/aishell/s0/exp/conformer_auto_weight
checkpoint=
average_checkpoint=true
decode_checkpoint=$dir/final.pt
average_num=1

. tools/parse_options.sh || exit 1;

  mkdir -p $dir
  INIT_FILE=$dir/ddp_init
  init_method=file://$(readlink -f $INIT_FILE)
  echo "$0: init method is $init_method"
  num_gpus=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}')
  # Use "nccl" if it works, otherwise use "gloo"
  dist_backend="gloo"
  world_size=`expr $num_gpus \* $num_nodes`
  echo "total gpus is: $world_size"
  cmvn_opts=
  $cmvn && cp data/${train_set}/global_cmvn $dir
  $cmvn && cmvn_opts="--cmvn ${dir}/global_cmvn"
    i=0
    gpu_id=$(echo $CUDA_VISIBLE_DEVICES | cut -d',' -f$[$i+1])
  
    rank=`expr $node_rank \* $num_gpus + $i`
    ##################################################
    #  注意看这里,原本脚本是运行python文件,即直接python wenet/bin/train.py,但是我们想要调试它,就应该是 python -m pdb wenet/bin/train.py
    ########################################################3
    python -m pdb wenet/bin/train.py --gpu $gpu_id \
      --config $train_config \
      --data_type $data_type \
      --symbol_table $dict \
      --train_data /mnt/database/luody/wenet-main/examples/aishell/s0/data/$train_set/data.list \
      --cv_data /mnt/database/luody/wenet-main/examples/aishell/s0/data/dev/data.list \
      ${checkpoint:+--checkpoint $checkpoint} \
      --model_dir $dir \
      --ddp.init_method $init_method \
      --ddp.world_size $world_size \
      --ddp.rank $rank \
      --ddp.dist_backend $dist_backend \
      --num_workers 1 \
      $cmvn_opts \
      --pin_memory

现在我们直接copy上面的代码到终端即可,终端会自动给我们运行
粘贴到终端后的界面如下
在这里插入图片描述

接下来就可以开始调试啦
l:显示当前所在位置的上下文代码
在这里插入图片描述
n:运行一行
在这里插入图片描述
b:打断点(在/mnt/database/luody/wenet_kd_test/wenet/bin/train.py文件的第126行打断点)
在这里插入图片描述
c:跳到断点处(跳到了第126行)
在这里插入图片描述
s:进入函数(train.py文件中有一个函数,我们要进入这个函数用ss后可以看到跳到了executor.py文件的train函数部分)
在这里插入图片描述
p:打印参数以及参数的一些属性(打印参数的shape)
在这里插入图片描述

在这里插入图片描述
q:退出调试
在这里插入图片描述

5、总结

熟能生巧、多用

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值