"); //-->
高效 Backbone:HENET 系列;
动态障碍物检测:Bevformer、SparseBev 等;
通用障碍物检测:FlashOCC 等;
静态目标检测:MapTR 系列;
多模态融合:Bevfusion 等;
轨迹预测:QCNet 等。
更多场景算法持续开发和优化中,敬请关注。 参考算法的 Model Zoo:
2.快速上手2.1 算法包获取参考算法算法包的获取和使用依赖地平线 征程 6 算法工具链 OpenExplorer 开发包以及配套的 docker 开发环境,其获取方式为:
算法包 config 文件和工具脚本路径为:samples/ai_toolchain/horizon_model_train_sample/scripts,目录结构如下:
scripts/
├── configs # 模型配置文件
│ ├── bev
│ ├── classification
│ ├── detection
│ ├── disparity_pred
│ ├── keypoint
│ ├── lane_pred
│ ├── lidar_multi_task
│ ├── map
│ ├── occ
│ ├── opticalflow_pred
│ ├── segmentation
│ ├── track_pred
│ └── ...
├── examples # pointpillars模型示例脚本
└── tools # 相关工具脚本
├── calops.py # 模型计算量统计脚本
├── compile_perf_hbir.py # 模型编译和编译器预估性能脚本
├── dataset_converters # 部分模型数据准备相关脚本
├── datasets # 数据集准备相关脚本
├── export_hbir.py # 导出hbir模型脚本
├── export_onnx.py # 导出onnx模型脚本
├── gen_camera_param_nusc.py # 生成nuscenes数据集相机参数脚本
├── homography_generator.py # 生成homography矩阵脚本
├── infer_hbir.py # 推理hbir模型脚本
├── model_checker.py # 模型检查脚本
├── predict.py # 精度验证脚本
├── reference_points_generator.py # 参考点生成脚本
├── train.py # 模型训练脚本
├── validation_hbir.py # hbir模型精度验证脚本
└── ...
2.2 环境搭建2.2.1 环境要求docker 环境模型源码路径:/usr/local/lib/python3.10/dist-packages/hat
开发机配置要求参考:
依赖版本python3.1cuda11.8torch/torchvision参考OE发布包docker20.10.10
2.2.2 算法包安装算法包本地安装流程复杂,并且为了不和用户本地开发环境冲突,强烈建议用户使用 征程 6 算法工具链提供的 GPU Docker 集成开发环境
验证当前开发环境已成功安装算法包方式:
python3
>>> import hat
>>> hat.__version__
正常打印算法包版本信息即为安装成功。
2.3 数据集准备数据集使用模型准备流程ImageNetHENETNuScenesFlashOccBevformerSparseBevMapTRArgoverse 2QCNetMSCOCOFCOS
2.4 模型配置文件解读模型配置 config 文件路径:samples/ai_toolchain/horizon_model_train_sample/scripts/configs
模型配置 config 文件负责定义了模型结构、数据集加载以及整套的训练流程:
import ...
#---------------------- 基础参数配置 ----------------------
device_ids = [0, 1, 2, 3, 4, 5, 6, 7] # 指定模型训练所用的GPU列表
batch_size_per_gpu = 128
cudnn_benchmark = True # 是否打开cudnn benchmark
seed = None # 是否设置随机数种子
log_rank_zero_only = True # 简化多卡训练时的日志打印,只在第0卡上输出日志
march = March.NASH_E # 目标平台架构,March.NASH_E表示J6E平台,以此类推
convert_mode = "jit-strip" # 量化训练模式
data_rootdir = "..." # 数据集路径
meta_rootdir = "..." # meta路径
img_shape = ...
auto_augment = True # data_loader相关数据增强配置
num_queries = ... # 初始化的query数量
float_train_epochs = 300
task_name = "..."
ckpt_dir = "./tmp_models/%s" % task_name # 权重checkpoint文件保存路径
...
#---------------------- 模型结构配置 ----------------------
model = dict(
type="...",
backbone=dict(
...
), # backbone使用的结构和配置
neck=dict(
...
), # neck使用的结构和配置
head=dict(
type="...",
encoder=dict(
...
),
decoder=dict(
...
),
num_proposals=num_queries,
), # head使用的结构和配置
losses=dict(
...
), # loss/criterion计算方式与配置
post_process=dict(
...
), # 后处理配置
) # 训练阶段模型的结构和配置
deploy_model = dict(
type="...",
backbone=dict(
...
),
neck=dict(
...
),
head=dict(
type="...",
encoder=dict(
...
),
decoder=dict(
...
),
num_proposals=num_queries,
),
losses=None,
post_process=None,
) # 部署阶段模型的结构和配置,取消了loss和后处理部分
deploy_inputs = dict(
img=torch.randn((1, 3, img_shape[0], img_shape[1])),
) # 部署阶段模型模拟输入
#---------------------- 数据加载配置 ----------------------
data_loader = dict(
type=torch.utils.data.DataLoader,
dataset=dict(
type="ImageNet",
data_path=ImageNet_path + "train_lmdb/",
...
),
batch_size=batch_size_per_gpu,
num_workers=8,
...
) # 训练阶段的数据集加载流程
val_data_loader = dict(
type=torch.utils.data.DataLoader,
dataset=dict(
type="ImageNet",
data_path=ImageNet_path + "val_lmdb/",
...
),
batch_size=batch_size_per_gpu,
num_workers=4,
...
) # 验证阶段的数据集加载流程
#---------------------- 训练 & 验证流程配置 ----------------------
batch_processor = dict(
...
) # 模型在训练过程中每个迭代进行的操作,包括前向计算、梯度回传、参数更新等
val_batch_processor = dict(
...
) # 模型在验证过程中每个迭代进行的操作,只包含前向计算
metric_updater = dict(
type="MetricUpdater",
...
) # 模型训练过程中更新指标的方法
val_metric_updater = dict(
type="MetricUpdater",
...
) # 训练出来的模型在验证过程中更新指标的方法
stat_callback = dict(
...
)
ckpt_callback = dict(
...
)
trace_callback = dict(
...
)
val_callback = dict(
...
) # 提供不同阶段callbacks来动态调整训练状态
float_trainer = dict(
type="...",
...
) # 浮点模型训练流程的配置
calibration_trainer = dict(
type="...",
...
) # 模型校准流程的配置
qat_trainer = dict(
type="...",
...
) # 量化训练流程的配置
int_infer_trainer = dict(
type="...",
...
) # 不包含训练流程,只是为了验证定点模型的精度
float_predictor = dict(
type="...",
...
) # 推理浮点模型配置
calibration_predictor = dict(
type="...",
...
) # 推理校准后模型配置
qat_predictor = dict(
type="...",
...
) # 推理量化训练后模型配置
int_infer_predictor = dict(
type="...",
...
) # 推理定点hbir模型配置
#---------------------- 部署流程配置 ----------------------
compile_cfg = dict(
march=march,
name=task_name,
...
) # 编译相关配置
hbir_infer_model = dict(
type="...",
model_path=os.path.join(ckpt_dir, "quantized.bc"),
)
infer_cfg = dict(
model=hbir_infer_model,#int_infer_predictor的model
infer_inputs=dict(
imgs="./tmp_orig_data/imagenet/val/val/...",
),
process_inputs=...,
viz_func=...,
process_outputs=...,
transforms=...,
) # 单帧推理配置,使用单份输入数据推理定点hbir模型并可视化
onnx_cfg = dict(
model=deploy_model,
stage="qat",
inputs=deploy_inputs,
...
) # 导出onnx模型配置
2.5 模型训练注:所有已经提供的 config 配置,可以保证正常运行和复现精度。如果因为环境配置和训练时间等原因,需要修改配置的话,那么对应的训练策略可能也需要更改
2.5.1 浮点训练地平线参考算法提供每个阶段训练完成后的权重,在模型对应 config 文件目录下的README文件中,并指定 config 文件中ckpt_dir路径加载
完成 config 文件中参数的配置后,使用以下命令训练浮点模型:
python3 tools/train.py --config configs/{config_file} --stage float
2.5.2 校准训练完成后的浮点 ckpt 默认保存在ckpt_dir。
该步骤涉及的 QAT 校准原理请参考用户手册:
为加速 QAT 训练收敛和获得最优量化精度,建议在 QAT 之前做 calibration 校准,其过程为通过 batch_size 个样本初始化量化参数,为 QAT 的量化训练提供一个更好的初始化参数。
通过运行下面的脚本开启模型的 Calibration:
python3 tools/train.py --config configs/{config_file} --stage calibration
2.5.3 QAT 训练校准 calibration 之前,通过修改 config 文件中calibration_trainer的checkpoint_path参数来配置加载的浮点训练权重。
该步骤涉及的 QAT 量化感知训练原理请参考用户手册:
校准完成后,就可以加载校准权重开启模型的量化训练。 量化训练其实是在浮点训练和校准基础上的 fine-tune,具体配置信息在 config 的qat_trainer中定义。和浮点训练的方式一样,将checkpoint_path指定为训好的校准权重路径。 通过运行下面的脚本开启模型的量化感知训练:
python3 tools/train.py --config configs/{config_file} --stage qat2.6 模型导出2.6.1 模型检查
在将 PyTorch 模型编译为板端可部署执行的模型之前,需要先导出为编译器中间表示模型,也即 hbir 模型。在导出 hbir 模型之前,可以对模型进行编译器算子支持以及结构支持的检查,通过如下脚本执行:
python3 tools/model_checker.py --config configs/{config_file}2.6.2 导出 HBIR 模型
当校准或量化训练阶段的模型精度满足预期后,可以使用如下命令导出伪量化 hbir 和定点 hbir 模型:
python3 tools/export_hbir.py --config configs/{config_file}
导出的 hbir 模型默认保存在ckpt_dir,可通过save-path指定自定义保存路径。其中 qat.bc 为伪量化 hbir 模型,quantized.bc 为量化后的定点 hbir 模型。
hbir 模型可以使用集成工具hb_model_info进行结构可视化:
hb_model_info xxx.bc -v
2.7 模型单帧推理注:默认保存在.hb_model_info目录下的 onnx 文件仅支持可视化,不支持推理
python3 tools/infer_hbir.py --config configs/{config_file} --save-path {save_path}
注:默认推理定点 hbir 模型(quantized.bc),推理的可视化结果保存路径通过--save-path指定。也可通过修改 config 文件中infer_cfg相关参数来更换推理伪量化 hbir 模型或指定输入,运行前需确认指定的输入路径有效
从 OE 3.0.19 版本以及之后版本开始,提供模型单帧推理 demo 所需的单份输入数据,可以从模型 config 文件目录下的README.md获取下载链接。此外用户也可以通过infer_hbir.py脚本来生成模型单帧推理所需的数据:
python3 tools/infer_hbir.py --config configs/{config_file} --save-path {save_path} --use-dataset
2.8 模型精度验证注:生成的单帧推理数据默认保存在 config 文件infer_cfg参数input_path指定的路径下,用户可自行修改。不指定--use-dataset情况下将自动读取input_path路径下的数据进行单帧推理,运行前需确认指定的路径和有效数据存在
python3 tools/predict.py --config configs/{config_file} --stage {stage}
通过命令行指定stage参数为float、calibration、qat分别来验证浮点模型、校准模型、QAT 模型的精度;
使用 NuScenes mini 数据集进行精度验证时需要修改 config 中涉及“version”的参数项,可参考“常见问题”章节。
此外在导出定点 hbir 模型后,也可以通过下面的方式来验证定点 hbir 模型的精度,也即模型定点化后的量化精度:
python3 tools/validation_hbir.py --config configs/{config_file} --stage int_infer2.9 模型编译
编译脚本执行前需确认 quantized.bc 所在的路径,为hbir_save_dir或ckpt_dir,若使用--save保存 hbir 模型,则需要将hbir_save_dir修改为--save指定的路径
定点 hbir 模型的精度满足要求后,使用以下方式将 hbir 模型编译成可以上板部署的 hbm 模型(同时该脚本也能预估在 BPU 上的运行性能):
python3 tools/compile_perf_hbir.py --config configs/{config_file}
编译完成后的产出物如下:
compile/2.10 模型板端部署2.10.1 性能测试
├── compile_hbir.bc # 删除模型首尾量化反量化节点的定点hbir模型
├── xxx.html # 编译器预估的模型在BPU上运行的性能
├── xxx.json # 预估性能html文件对应的json文件
└── model.hbm # 可上板部署执行的模型
需提前配置好开发板端底软环境和推理库环境
使用hrt_model_exec perf工具将生成的 hbm 模型文件上板做性能实测,hrt_model_exec perf参数如下:
hrt_model_exec perf --model_file {hbm_model} \2.10.2 AI Benchmark 示例
--thread_num 8 \ # 多线程评测FPS,单线程评测Latency
--frame_count 1000 \
--core_id 0
OE 开发包中提供了丰富的板端部署 AI Benchmark 示例,详细使用流程参考
3.征程 6 参考算法详解地平线参考算法面向硬件平台特性基于公版模型做了高效优化和改动,相关优化和改动总结于。针对每个模型的详细介绍和详解见下面表格:
场景模型文档高效BackboneHENET动态障碍物检测Bevformer动态障碍物检测SparseBev通用障碍物检测FlashOCC静态目标检测MapTR轨迹预测QCNet
4.常见问题参考算法 FAQ 见
使用 NuScenes mini 数据集时出现报错“Samples in split doesn’t match samples in predictions” 答:使用 NuScenes mini 数据集做模型精度验证时,记得对应修改
val_nuscenes_metric = dict(
type="NuscenesMetric",
data_root=meta_rootdir,
version="v1.0-trainval", # 修改为v1.0-mini
save_prefix=...,
)
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。