提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
最近在研究deepspeed相关内容,但使用命令方式无法单步调式调用代码的问题,若直接离线看代码,在一定程度上降低效率。同时,使用deepspeed方式debug代码内容较少。为此,我特意在少有信息中和代码实验验证完成基于vscode对deepspeed进行debug方法。特别的,该方式不仅适合deepspeed命令debug,也适用torchrun命令debug,更能延伸其它命令debug模式。本文内容分为三部分,第一部分介绍如何使用vscode传递参数debug;第二部分介绍如何使用deepspeed进行debug;第三部分介绍vscode通用命令方式进行debug。
源码路径:点击这里
验证python文件的argparse参数传递,或者是命令使用–param的参数传递方式,第一个列子使用常规python调用,我将写一个简单py文件,然后在说明vscode如何配置launch.json文件。
代码很简单,大家可直接查看,文件名为test_py.py,如下:
import argparse
def parse_opt():
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default='yolov5l.pt', help='initial weights path')
parser.add_argument('--epochs', type=int, default=300)
# opt = parser.parse_args(args=[])
opt = parser.parse_args()
return opt
def main(opt) :
print('opt.weights:',opt.weights)
print('opt.epochs:',opt.epochs)
value=opt.epochs+90000
print('value:',value)
if __name__ == '__main__':
opt = parse_opt()
main(opt)
如果使用命令修改参数调用需要执行:
python test_py.py --weights yolos --epchs 600
此方式直接按F5即可执行,该方式指定运行python解释器,也在program指定了运行py文件为test_py.py路径。
{
"version": "0.2.0",
"configurations": [
{
"name": "test_py",
"type": "python",
"request": "launch",
"python": "/home/ubuntu/miniconda3/envs/dp/bin/python", // 指定python解释器
"program": "/home/ubuntu/vscode-main/test_py.py", //"${file}",
"console": "integratedTerminal",
"justMyCode": true, //为true表示只debug自己代码,为false表示可debug库中文件
"args": [ //这里配置参数
"--weights","model_yolov5s",//"--weights=model_yolov5s" 字符串也可以使用这种方式,能自动解析
"--epochs=600", //"--epochs", "600", 整形也可以使用这种方式,能自动解析
]
}
]
}
说明:args配置有2种方式都已在代码注释中
此方式需打开对应test_py.py文件(当前页面是这个),按F5即可执行,与上区别在于未指定了运行py文件test_py.py路径,其它都一样。
{
"version": "0.2.0",
"configurations": [
{
"name": "test_py2",
"type": "python",
"request": "launch",
"python": "/home/ubuntu/miniconda3/envs/dp/bin/python", // 指定python解释器
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true, //为true表示只debug自己代码,为false表示可debug库中文件
"args": [ //这里配置参数
"--weights","model_yolov5s",//"--weights=model_yolov5s" 字符串也可以使用这种方式,能自动解析
"--epochs=200", //"--epochs", "600", 整形也可以使用这种方式,能自动解析
]
}
]
}
至于代码模块不是本文重点内容,我将不在介绍,直接给出代码,如下:
import torch
import os
from datetime import datetime
from transformers import HfArgumentParser
from dataclasses import dataclass, field
from typing import Optional
import sys
from transformers import TrainingArguments
@dataclass
class ModelArguments:
"""
Arguments pertaining to which model/config/tokenizer we are going to fine-tune from.
"""
model_name_or_path: str = field(
metadata={
"help": "Path to pretrained model or model identifier from huggingface.co/models"}
)
def gen_data():
x = torch.randn(10, 10).to('cuda')
return x
def main() -> int:
parser = HfArgumentParser((ModelArguments, TrainingArguments))
if len(sys.argv) == 2 and sys.argv[1].endswith(".json"):
# If we pass only one argument to the script and it's the path to a json file,
# let's parse it to get our arguments.
model_args, train_args = parser.parse_json_file(
json_file=os.path.abspath(sys.argv[1]))
else:
model_args, train_args = parser.parse_args_into_dataclasses()
print(model_args)
print(train_args)
gen_data()
local_rank = int(os.environ["LOCAL_RANK"])
world_size = int(os.environ["WORLD_SIZE"])
cur_dateime = datetime.now()
print("*" * 80)
value = torch.cuda.device_count()
print(
f"----> cur_datetime: {cur_dateime},world size: {world_size}, local_rank: {local_rank}, gpu count: {value}")
return value
if __name__ == '__main__':
main()
你也可以直接使用命令,也可使用sh脚本调用,如下:
deepspeed --num_nodes=1 --num_gpus=2 \
deepspeed_test.py \
--deepspeed "./config/default_offlload_zero2.json" \
--model_name_or_path my_model \
--output_dir "./save_dir"
同样调用deepspeed在vscode一样是配置launch.json文件,如下配置:
{
"version": "0.2.0",
"configurations": [
{
"name": "ds_zero2",
"type": "python",
"request": "launch",
"program": "/home/ubuntu/miniconda3/envs/cogvlm/bin/deepspeed", //"${file}",
"console": "integratedTerminal",
"justMyCode": true,
"args": [
"--num_nodes",
"1",
"--num_gpus",
"2",
"${file}", //这个就是当前界面运行文件
"--deepspeed",
"./config/default_offlload_zero2.json",
"--model_name_or_path",
"my_model",
"--output_dir",
"./out_dir"
],
"env": {
"CUDA_VISIBLE_DEVICES": "0",
"PYDEVD_DISABLE_FILE_VALIDATION": "1",
}
}
]
}
使用vscode执行命令方式最大优势能进行debug模式,而原有命令debug非常困难或无法debug(除利用其它工具),
都可将sh命令在vscode中转换,我已多次实验,总结下要点。
justMyCode:是否允许库文件设置断点进行debug,fasle表示允许,true表示不允许
env:环境变量,特别是cuda显卡设置
program:设定执行程序路径,很重要
args:类似sh给执行程序参数设定,与program配置使用
直接给列子,若执行 python test.py --weights yolov5s.pt --epochs 20
在launch.json文件需配置python解释器路径,有单独参数“python”,也需要配置执行文件,配置如下:
"python": "/home/ubuntu/miniconda3/envs/yolo/bin/python", // 指定python解释器
"program":"${file}" //可以理解为相对执行py文件路径
# "program": "/home/ubuntu/vscode-main/test_py.py", //相对给定一个绝对执行路径
上面的program配置是二选一都可以,相当于已经写了sh命令写好:python test_py.py,但还缺参数,使用args配置如下::
"args": [
"--weights",“yolov5s.pt”
"--epochs=600",
]
相当于在python test_py.py命令跟上了 --weights yolov5s.pt --epochs 600参数,代码合起来为命令参数且可debug,如下:
python test_py.py --weights yolov5s.pt --epochs 600
这个是使用deepspeed命令运行,无需配置python解释器,在launch.json文件需配置deepspeed执行路径,需给program,配置如下:
"program": "/home/ubuntu/miniconda3/envs/cogvlm/bin/deepspeed",
上面的program配置相当于已经写了sh命令写好:deepspeed,仍需配置参数(注意位置),使用args配置如下::
"args": [
"--num_nodes","1",
"--num_gpus","2",
"${file}", //这个就是当前界面运行文件
"--deepspeed",
"./config/default_offlload_zero2.json",
"--model_name_or_path", "my_model",
"--output_dir", "./out_dir"
]
其中"${file}"表示运行文件,上面相当于在deepspeed后面添加
--num_nodes=1 --num_gpus=2 \
deepspeed_test.py \
--deepspeed "./config/default_offlload_zero2.json" \
--model_name_or_path my_model \
--output_dir "./save_dir"
最终实现类似sh的命令执行,如下完整命令代码:
deepspeed --num_nodes=1 --num_gpus=2 \
deepspeed_test.py \
--deepspeed "./config/default_offlload_zero2.json" \
--model_name_or_path my_model \
--output_dir "./save_dir"
注:需要注意args配置的位置
deepspeed是vscode进行debug方式使用方法,也适用于torchrun使用方法,我个人觉得只要类似sh脚本命令,理论都可使用。
推荐视屏:点击这里