Senna模型基于ModelArts Lite Server适配PyTorch NPU训练指导
方案概览
本方案介绍了在ModelArts Lite Server上使用昇腾计算资源 Ascend Snt9B23或Ascend Snt9B开展Senna模型的训练过程。
Senna是一种结合了大型视觉语言系统(Senna-VLM)和端到端模型(Senna-E2E)的自动驾驶系统。端到端模型虽然有着强大的规划能力,但是在面对复杂场景的规划表现不佳,大型视觉-语言模型(LVLM)在场景理解和推理方面表现出色,但是不适合精确的数值预测。Senna结合两者优点,扬长避短,将高级规划与低级轨迹预测分离,以自然语言生成规划决策,以端到端模型预测精确轨迹。
Senna-VLM采用多图像编码方法和多视图提示来高效理解场景,还引入了面向规划的问答和三步训练策略,在保留常识的同时,提升Senna-VLM的规划性能。在两个数据集上的大量实验显示,Senna达到了最先进的规划性能,其跨场景泛化能力和迁移能力对于实现完全自动驾驶至关重要。
资源规格要求
推荐使用“西南-贵阳一”Region上的Lite Server资源和 Ascend Snt9B23或Ascend Snt9B单机。
名称 |
版本 |
---|---|
Driver |
24.1.0.6(Snt9B) 24.1.RC3.5(Snt9B23) |
PyTorch |
pytorch_2.1.0 |
获取软件和镜像
分类 |
名称 |
获取路径 |
---|---|---|
插件代码包 |
AscendCloud-ACD-6.5.905-xxx.zip 文件名中的xxx表示具体的时间戳,以包名发布的实际时间为准。 |
获取路径:Support-E,在此路径中查找下载ModelArts 6.5.905版本。
说明:
如果上述软件获取路径打开后未显示相应的软件信息,说明您没有下载权限,请联系您所在企业的华为方技术支持下载获取。 |
Snt9B 基础镜像包 |
swr.cn-southwest-2.myhuaweicloud.com/atelier/pytorch_2_1_ascend:pytorch_2.1.0-cann_8.0.0-py_3.10-hce_2.0.2412-aarch64-snt9b-20250216120941-8c7dfdd |
SWR上拉取。 |
Snt9B23 基础镜像包 |
swr.cn-southwest-2.myhuaweicloud.com/atelier/pytorch_2_1_ascend:pytorch_2.1.0-cann_8.0.rc3-py_3.10-hce_2.0.2412-aarch64-snt9b23-20250315172739-f66f096 |
SWR上拉取 |
约束限制
- 本文档适配昇腾云ModelArts 6.5.905版本,请参考表2 获取软件和镜像获取配套版本的软件包和镜像,请严格遵照版本配套关系使用本文档。
- 确保容器可以访问公网。
步骤一:检查环境
- 请参考Lite Server资源开通,购买Lite Server资源,并确保机器已开通,密码已获取,能通过SSH登录,不同机器之间网络互通。
购买Lite Server资源时如果无可选资源规格,需要联系华为云技术支持申请开通。
当容器需要提供服务给多个用户,或者多个用户共享使用该容器时,应限制容器访问Openstack的管理地址(169.254.169.254),以防止容器获取宿主机的元数据。具体操作请参见禁止容器获取宿主机元数据。
- SSH登录机器后,检查NPU卡状态。运行如下命令,返回NPU设备信息。
npu-smi info # 在每个实例节点上运行此命令可以看到NPU卡状态
如出现错误,可能是机器上的NPU设备没有正常安装,或者NPU镜像被其他容器挂载。请先正常安装固件和驱动,或释放被挂载的NPU。
- 检查是否安装docker。
docker -v #检查docker是否安装
如尚未安装,运行以下命令安装docker。
yum install -y docker-engine.aarch64 docker-engine-selinux.noarch docker-runc.aarch64
- 配置IP转发,用于容器内的网络访问。执行以下命令查看net.ipv4.ip_forward配置项的值,如果为1,可跳过此步骤。
sysctl -p | grep net.ipv4.ip_forward
如果net.ipv4.ip_forward配置项的值不为1,执行以下命令配置IP转发。sed -i 's/net\.ipv4\.ip_forward=0/net\.ipv4\.ip_forward=1/g' /etc/sysctl.conf sysctl -p | grep net.ipv4.ip_forward
步骤二:启动容器
- 获取基础镜像。建议使用官方提供的镜像部署推理服务。镜像地址{image_url}参见表2 获取软件和镜像。
docker pull {image_url}
- 启动容器镜像。启动前请先按照参数说明修改${}中的参数。可以根据实际需要增加修改参数。
export work_dir="自定义挂载的工作目录" export container_work_dir="自定义挂载到容器内的工作目录" export container_name="自定义容器名称" export image_id="镜像名称或ID" export datasets_dir="存放已有数据集的位置" docker run -itd \ -u root \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci8 \ --device=/dev/davinci9 \ --device=/dev/davinci10 \ --device=/dev/davinci11 \ --device=/dev/davinci12 \ --device=/dev/davinci13 \ --device=/dev/davinci14 \ --device=/dev/davinci15 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ --shm-size 1024g \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /etc/ascend_install.info:/etc/ascend_install.info \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /usr/bin/hccn_tool:/usr/bin/hccn_tool \ -v /etc/hccn.conf:/etc/hccn.conf \ -v ${work_dir}:${container_work_dir} \ -v ${datasets_dir}:${datasets_dir} \ --net=host \ --name ${container_name}\ ${image_id} \ /bin/bash
参数说明:
- --device=/dev/davinci0 :挂载对应卡到容器,当需要挂载多卡,请依次添加多项该配置,示例为16卡,最小卡数为8卡。
- -v ${work_dir}:${container_work_dir}:代表需要在容器中挂载宿主机的目录。宿主机和容器使用不同的文件系统。work_dir为宿主机中工作目录,目录下可存放项目所需代码、数据等文件。container_work_dir为要挂载到的容器中的目录。为方便两个地址可以相同。
- -v ${datasets_dir}:${datasets_dir}:容器中挂载宿主机中存放数据集的目录,若宿主机中存在数据集,可以添加该参数,在容器中通过软连接将数据集连接到项目对应的数据集中,若打算重新下载数据集或宿主机中没有数据集,可以不添加该参数。为方便两个地址可以相同。
- --name ${container_name} 容器名称,进入容器时会用到,此处可以自己定义一个容器名称,例如senna。
- ${image_id}:镜像的ID
- 进入容器。需要将${container_name}替换为实际的容器名称。
docker exec -it ${container_name} bash
步骤三:上传模型代码及安装依赖
- 安装插件代码包。将获取到的插件代码包 AscendCloud-ACD-6.5.905-xxx.zip 文件上传到容器的 {container_work_dir} 目录下,并解压。
cd {container_work_dir} unzip AscendCloud-ACD-6.5.905-xxx.zip #解压
Senna 模型训练所需的代码存放在解压后得到的文件夹中的 models\Senna 目录下,Senna 目录里有如下结构:Senna ├── test/ ├── ├── train_8p.sh ├── ├── train_performance.sh ├── bitsandbytes.patch ├── Senna.patch ├── README.md
后面将根据需要,拷贝对应的文件到指定文件夹。
- 代码部署。
- 在容器工作目录 {container_work_dir} 下新建项目目录 senna。
cd {container_work_dir} mkdir senna && cd senna
- 下载代码,切换分支。
git clone https://github.com/hustvl/Senna.git cd Senna git checkout 5f202ce84dc4fe52949934ab0921e287d733ff8f
- 将 Senna.patch 文件移动到模型源码目录 {container_work_dir}/senna/Senna,并应用 patch。
git apply Senna.patch
- 在容器工作目录 {container_work_dir} 下新建项目目录 senna。
- 安装模型相关依赖。
cd {container_work_dir}/senna/Senna pip install -r requirements.txt
- 安装npu适配的bitsandbytes。
- 拉取 bitsandbytes 仓中 multi-backend-refactor-npu 分支的代码。
# 进入senna项目文件夹(注意不是Senna源码文件夹) cd {container_work_dir}/senna git clone https://github.com/SlightwindSec/bitsandbytes.git -b multi-backend-refactor-npu cd bitsandbytes
- 将 bitsandbytes.patch 拷贝到 bitsandbytes 源码目录下,应用patch文件。
cd {container_work_dir}/senna/bitsandbytes git apply bitsandbytes.patch
- 在构建之前,查看 cmake 版本,确保版本在 3.22.1 之上,推荐使用下面命令进行安装和环境设置。
pip install cmake==3.29.2 export PATH=$PATH:/home/ma-user/.local/bin export CMAKE_ROOT=/home/ma-user/.local/share/cmake-3.29 cmake --version
- 在 {container_work_dir}/senna/bitsandbytes 目录下,执行下面命令构建并安装。
cmake -DCOMPUTE_BACKEND=npu -S . make pip install -e .
- 拉取 bitsandbytes 仓中 multi-backend-refactor-npu 分支的代码。
步骤四:准备训练所需数据
- 准备预训练权重。
- 进入 {container_work_dir}/senna/Senna 代码目录。
下载 vicuna-7b-v1.5权重:vicuna-7b-v1.5 权重下载
下载 clip-vit-large-patch14-336权重:clip-vit-large-patch14-336 权重下载
- 目录结构如下:
Senna ├── assets/ ├── data_tools/ ├── eval_tools/ ├── llava-v1.6-34b/ ├── llava_output/ ├── llaVa-Pretrain/ ├── vicuna-7b-v1.5/ ├── clip-vit-large-patch14-336/
- 修改权重 clip-vit-large-patch14-336 中的 config.js 文件。
// 第2行:"_name_or_path": "openai/clip-vit-large-patch14-336" 改成实际的位置 "_name_or_path": "{container_work_dir}/senna/Senna/clip-vit-large-patch14-336"
- 进入 {container_work_dir}/senna/Senna 代码目录。
- 准备生成QA数据集。
- 在 {container_work_dir}/senna/Senna 源码目录下创建文件夹 llavaout,存放生成的 QA 数据。
cd {container_work_dir}/senna/Senna mkdir llava_output
- 进入到 {container_work_dir}/senna/Senna 目录下,下载 LLaVA-v1.6-34b 模型,用于生成 QA 数据。
下载 LLaVA-v1.6-34b 模型:LLaVA-v1.6-34b 模型下载
目录结构:Senna ├── assets/ ├── data_tools/ ├── eval_tools/ ├── llava-v1.6-34b/ ├── llava_output/
- 下载完成后,修改 LLaVA-v1.6-34b 模型内的 config.json 文件。
// 将"mm_vision_tower": "openai/clip-vit-large-patch14-336" 修改为实际存储的路径,例如 "mm_vision_tower": "{container_work_dir}/senna/Senna/clip-vit-large-patch14-336"
- 在 Senna/data_tools/senna_nusc_data_converter.py 中,修改相关配置。
# 302行修改代码 pretrained = "...",将路径改成模型实际的位置 # load vlm model and generate def _fill_trainval_infos(nusc, nusc_can_bus, ......): ...... from llava_next.llava.model.builder import load_pretrained_model pretrained = "{container_work_dir}/senna/Senna/llava-v1.6-34b" model_name = "llava-v1.6-34b" device_map = "auto"
- 在 Senna 文件夹下,创建文件夹 data,并在此文件夹中自行官网下载或软连接已有 nuscenes v1.0 数据集和 canbus。
# 示例为软连接已有的数据集到该目录下,也可以在该目录下下载全量数据集 # 本示例以及代码中,canbus 放在 nuscenes 数据集目录下:nuscenes/can_bus mkdir data && cd data ln -s {datasets_dir}/datasets/nuscenes_v1.0/nuscenes . cd ..
下载 nuscenes v1.0 全量数据集(mini、Trainval、Test)以及 can_bus:下载nuscenes数据集链接
- 在 Senna/data_tools/senna_nusc_converter.sh 中,参照下面给出的示例进行文件路径的修改。
# 根据自己的文件位置修改一些路径 export PYTHONPATH={container_work_dir}/senna/Senna:$PYTHONPATH # 模型源码的路径 echo "Start generating dataset..." /home/ma-user/anaconda3/envs/PyTorch-2.1.0/bin/python \ # 修改为 python 解释器位置,可以使用 which python 命令查看 data_tools/senna_nusc_data_converter.py \ nuscenes \ --root-path {container_work_dir}/senna/Senna/data/nuscenes \ # nuscenes 数据集的位置,数据集在该文件夹下(mini、trainval、test) --out-dir {container_work_dir}/senna/Senna/llava_output \ # 修改为 QA 数据要输出的目标文件夹,命名为 llava_output --extra-tag senna_nusc \ --version v1.0 \ # 数据集版本 --canbus {container_work_dir}/senna/Senna/data/nuscenes # can_bus 的位置,can_bus 放在 nuscenes 文件夹下
- 执行命令安装数据生成所需依赖。
# 安装 pyquaternion pip install pyquaternion # 安装 nuscenes pip install nuscenes-devkit # 安装数据生成所需的 4.51.3 版本transformers pip install transformers==4.51.3
- 执行数据生成脚本。
sh data_tools/senna_nusc_converter.sh
- 在 {container_work_dir}/senna/Senna 源码目录下创建文件夹 llavaout,存放生成的 QA 数据。
- 准备 LLaVA-Pretrain 数据集。
- 进入 {container_work_dir}/senna/Senna 代码目录,下载 LLaVA 数据集。
下载 LLaVA 训练数据集:LLaVA-Pretrain 数据集下载
- 目录结构如下:
Senna ├── assets/ ├── data_tools/ ├── eval_tools/ ├── llava-v1.6-34b/ ├── llava_output/ ├── LLaVA-Pretrain/
- 进入 {container_work_dir}/senna/Senna 代码目录,下载 LLaVA 数据集。
步骤五:配置训练前路径
- 创建保存训练结果的文件夹。
- 修改pretrain_senna_llava.sh文件配置 Stage1 训练路径。
将 Senna 模型所在目录记作 {Senna_dir},即 {container_work_dir}/senna/Senna。
在 train_tools/pretrain_senna_llava.sh 文件中。
- 第 3-6 行,更换文件路径。
MODEL="{Senna_dir}/vicuna-7b-v1.5/" DATA="{Senna_dir}/LLaVA-Pretrain/blip_laion_cc_sbu_558k.json" IMAGE_DATA="{Senna_dir}/LLaVA-Pretrain" OUT_DIR="{Senna_dir}/test/output1/" # stage1训练结果的保存位置
- 第 16 行,修改 python 路径,可以使用 which python 命令查看。
# specify the python path export PATH=/home/ma-user/anaconda3/envs/PyTorch-2.1.0/bin:$PATH
- 第 18 行,修改成 Senna 实际保存的路径。
# 修改成下面的目录 cd {container_work_dir}/senna/Senna
- 第 27 行,修改成实际保存的路径。
# --vision_tower /path/to/clip-vit-large-patch14-336/ --vision_tower {Senna_dir}/clip-vit-large-patch14-336/
- 第 3-6 行,更换文件路径。
- 修改train_senna_llava.sh文件配置 Stage2 训练路径。
在 train_tools/train_senna_llava.sh 文件中。
- 第 3-5 行,更换文件路径,Senna_dir 例如 /home/xxxx/senna/Senna。
MODEL="{Senna_dir}/test/output1/" DATA="{Senna_dir}/llava_output/senna_nusc_train.json" OUT_DIR="{Senna_dir}/test/output2/"
- 第 13 行,修改 python 路径,可以使用 which python 命令查看。
# specify the python path export PATH=/home/ma-user/anaconda3/envs/PyTorch-2.1.0/bin:$PATH
- 第 15 行,修改成 Senna 模型实际的位置。
cd {container_work_dir}/senna/Senna
- 第 23 行,修改成权重实际存放的位置,例如 /home/xxx/senna/Senna/clip-vit-large-patch14-336。
# --vision_tower /path/to/clip-vit-large-patch14-336/ --vision_tower {Senna_dir}/clip-vit-large-patch14-336/
- 第 3-5 行,更换文件路径,Senna_dir 例如 /home/xxxx/senna/Senna。
- 配置评估路径。
- 在 eval_tools/senna_plan_cmd_eval_multi_img.sh 中,参照下面示例进行修改,改为用户自定义的路径。
export PYTHONPATH={container_work_dir}/senna/Senna:$PYTHONPATH # 配置Senna源码路径 export PATH=/home/ma-user/anaconda3/envs/PyTorch-2.1.0/bin:$PATH # 配置Python路径 python eval_tools/senna_plan_cmd_eval_multi_img.py # 配置评估脚本路径
- 在 eval_tools/senna_plan_cmd_eval_multi_img.py 中,参照下面示例进行修改,改为用户自定义的路径。
eval_data_path = '{Senna_dir}/llava_output/senna_nusc_train.json' # 指向评估数据的路径,包含了用于评估的数据 model_plan = '{Senna_dir}/test/output2' # 指向预训练的模型 save_path = '{Senna_dir}/eval_result/result/eval_result.json' # 定义评估结果的保存路径,只保留一个 save_path 即可
- 在 Senna 文件夹下创建文件 eval_result/result/eval_result.json,用于保存评估结果。
mkdir -p eval_result/result touch eval_result/result/eval_result.json
- 在 eval_tools/senna_plan_cmd_eval_multi_img.sh 中,参照下面示例进行修改,改为用户自定义的路径。
- 训练前,安装特定版本 transformers。
pip install transformers==4.31.0
步骤六:训练及评估
将训练脚本 train_8p.sh 和 train_performance.sh 拷贝到 {container_work_dir}/senna/Senna/test 文件夹下。
- 训练前准备。
导入配置。
export ASCEND_SLOG_PRINT_TO_STDOUT=0 export ASCEND_GLOBAL_LOG_LEVEL=3 export ASCEND_GLOBAL_EVENT_ENABLE=0 export HCCL_WHITELIST_DISABLE=1 export HCCL_IF_IP=$(hostname -I |awk '{print $1}') export HCCL_CONNECT_TIMEOUT=1200 export CPU_AFFINITY_CONF=1 export COMBINED_ENABLE=1 export PYTHONPATH=$PYTHONPATH:{container_work_dir}/senna/Senna
设置使用前 8 卡训练。export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
- 精度训练与评估。
开始训练。
# stage1 混合预训练 sh train_tools/pretrain_senna_llava.sh # stage2 微调和规划微调(全参数微调) sh train_tools/train_senna_llava.sh # 评估 senna 的准确性 sh eval_tools/senna_plan_cmd_eval_multi_img.sh
在导入配置后,也可以使用提供的脚本进行训练和评估。bash test/train_8p.sh
精度训练完成后,stage1 训练结果保存在 Senna/test/output1 文件夹下,stage2 训练结果保存在 Senna/test/output2 文件夹下,评估结果保存在 Senna/test/output 文件夹下;其中 output/0 文件夹保存评估的日志及关键信息,output1/0 文件夹保存 stage1 训练的日志,output2/0 文件夹保存 stage2 训练的日志。
- 性能训练与评估。
使用 16 卡进行性能训练与评估。
在 test/train_performance.sh 文件中做如下修改。################基础配置参数,需要模型审视修改################## # 网络名称,同目录名称 Network="Senna" WORLD_SIZE=16 # 将 WORLD_SIZE=8 修改为 16 ...... # 设置 device 侧日志登记为 error msnpureport -g error -d 0 --docker msnpureport -g error -d 1 --docker msnpureport -g error -d 2 --docker msnpureport -g error -d 3 --docker msnpureport -g error -d 4 --docker msnpureport -g error -d 5 --docker msnpureport -g error -d 6 --docker msnpureport -g error -d 7 --docker # 添加剩余的 8 张卡日志配置 msnpureport -g error -d 8 --docker msnpureport -g error -d 9 --docker msnpureport -g error -d 10 --docker ...... msnpureport -g error -d 14 --docker msnpureport -g error -d 15 --docker
执行训练指令。# 设置使用 16 卡训练 export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 # 执行训练脚本 bash test/train_performance.sh
性能训练完成后,Stage1训练结果保存在Senna/test/output1文件夹下,Stage2 训练结果保存在Senna/test/output2文件夹下;其中 output/0 文件夹下保存着 Stage2训练的日志以及关键信息,output1/0 文件夹下保存着Stage1的训练日志以及关键信息。