Adlik如何实现与燧原芯片的对接?

引言

Adlik 1.0 版本,加入了与燧原科技合作的成果,增加了对燧原 i20 芯片的支持,该芯片是燧原科技发布的基于邃思 2.5 芯片打造的面向数据中心的第二代人工智能推理加速卡,具有高性能高能效、模型覆盖面广、易部署易运维等特点,可广泛应用于计算机视觉、语音识别与合成、自然语言处理、搜索与推荐等推理场景。该芯片使用推理引擎TopsInference为深度学习应用提供低延迟、高吞吐率的推理部署。

1. i20相关背景介绍

项目开发前,对燧原 i20 芯片进行了相关调研,调研结果如下:

  • 芯片采用 16GB 高带宽 HBM2E 存储,存储带宽高达 819GB/s。

  • 芯片采用 12nm 工艺、采用自研架构 GCU(General Compute Unit)。

  • 芯片主要应用范围是 AI 推算,支持图像分类、目标检测、自然语言处理等领域。

  • 芯片支持 fp32 、 fp16 ,以及混合精度,暂不支持 int8。

  • 芯片支持 ONNX 模型,但不是所有 ONNX 模型都支持。

  • 芯片对静态模型支持度高,暂不支持动态模型。

2. 对接方案

在 Adlik 中增加 i20 芯片的支持,需要增加以下内容:编译器部分增加原始模型格式到 i20 芯片支持的模型格式的转换,即加入一条从 ONNX 模型格式到燧原支持的 EXEC 模型格式的路径,运行时部分增加燧原运行时,提供使用 i20 芯片进行推理的支持。

由于 model_compiler 模型转换路径较多,可以分类为源模型格式直接到目的模型格式的方式,以及源模型格式到目的模型格式有中间状态的方式。编译器加入燧原模型,增加了一条ONNX 模型直接到燧原模型的路径。

增加后,源模式直接到目的模式的路径状态图如下:

Adlik如何实现与燧原芯片的对接?_第1张图片

adlik_serving 的功能是根据不同模型部署相应的服务,支持部署在 CPU、GPU 上。推理时,通过调度器,调度相应的推理引擎,由 http grpc 进行数据传输,将客户端数据传输到 Adlik 服务端进行推理。

Adlik 运行时支持情况:

推理引擎 TensorFlow OpenVino TensorRT TFLite ML PaddlePaddle TFtrt TVM Libtorch TopsInference
硬件 CPU/GPU CPU/GPU GPU CPU CPU CPU GPU CPU CPU/GPU GCU

Adlik runtime 增加燧原运行时后,可以将不同的深度学习模型通过 Adlik 服务平台部署到燧原 i20 芯片上,实现了在硬件 GCU 上使用 TopsInference 进行推理。可支持单 batch 、多 batch 、多模型、多实例的推理。

(1) 编译器的实现与使用

编译器部分首先使用TopsInference接口创建ONNX解析器,使用解析器读取ONNX模型,得到模型结构,接着使用TopsInference接口创建优化器,使用优化器构建燧原模型。代码如下:

with TopsInference.device(0, 0):
    onnx_parser = TopsInference.create_parser(TopsInference.ONNX_MODEL)
    network = onnx_parser.read(source.model_path)
    optimizer = TopsInference.create_optimizer()
    engine = optimizer.build(network)
#这是onnx模型到燧原模型转换过程

代码详见:Adlik/model_compiler/src/model_compiler/compilers/onnx_model_file_to_enflame_model.py

单元测试:

pytest tests/model_compiler/compilers/test_onnx_model_file_to_enflame_model.py 
pytest tests/model_compiler/models/targets/test_enflame_model.py

转换测试:

python3.8 compile_model.py

结果如下:6734c77e12814074e91a0f8362ac6c0d.png

生成的文件夹,目录结构如下:

model_repos
├── resnet50
│   ├── 1
│   │   └── model.exec
│   └── config.pbtxt
└── resnet50_1.zip

(2) 运行时的实现与使用

Adlik 提供了全面的 SDK(Software Development Kit),以 SDK 方式提供给开发者可扩展实现自定义推理运行时的能力,以便更快的开发新运行时。例如在 adlik_serving 中提供运行时的管理和调度功能,开发者只需要关注计算引擎的具体实现即可。在燧原运行时中,计算引擎的实现类为 BatchProcessor 类。这个类可以直接调用 TopsInference 计算引擎的执行 API 实现推理。在这个过程中,提炼了 Buffer 类概念,对此类进行实例化产生输入输出缓冲区对象,用于存储输入输出的数据。

执行推理的具体实现:

std::vector inputs_buffer_bound;
  for (auto& input : inputs) {
    inputs_buffer_bound.push_back(input.buffer_on_device);
  }
  std::vector outputs_buffer_bound;
  for (auto& output : outputs) {
    outputs_buffer_bound.push_back(output.buffer_on_device);
  }
  bool rtn = engine->run_with_batch(config.max_batch_size(),
                                    inputs_buffer_bound.data(),
                                    outputs_buffer_bound.data(),
                                    TopsInference::BufferType::TIF_ENGINE_RSC_IN_DEVICE_OUT_DEVICE,
                                    stream);
  if (!rtn) {
    return tensorflow::errors::Internal("Faild run in enflame reference.");
  }
  status = splitOutputs(payloads);
  TopsInference::synchronize_stream(stream);
//异步推理

代码详见:Adlik/adlik_serving/runtime/topsinference/model/topsinference_model.cc

测试过程:

(1)服务器首先部署燧原模型

adlik_serving --model_base_path=/workspace/Adlik/examples/topsinference_model/model_repos  --grpc_port=8500 --http_port=8501

(2)若成功则进入loop状态

I adlik_serving/server/http/internal/server_interface.cc:167] Entering the event loop ...

(3)等待客户端提出请求,服务器接受处理请求并返回响应。

python3.8 resnet50_client_acc.py -t data/val_map.txt data/figures/tench.JPEG data/imagenet_class.txt

(4)结果如下:

Image: 'data/figures/tench.JPEG', result: [{'idx': 0, 'score': 14.775530815124512, 'label': '0 tench'}]

3. 测试情况

测试选取图像分类领域 resnet50 模型,目标检测领域 yolov5s 模型,以及自然语言处理领域的 bert 模型。模型及大小,来源如下,数据类型是均为 fp32。

ONNX模型 大小 数据集 模型来源
resnet50 97.4M imagenet 链接1
剪枝resnet50 39.8M imagenet 链接2
yolov5s 27.6M coco2017 链接3
bert 415.2M dev-v1.1.json 燧原提供

其中模型均可在Adlik仓库中获取,链接如下。

链接1:https://github.com/Adlik/Adlik/blob/master/benchmark/tests/test_model/resnet50_pytorch/resnet50_pytorch.py

链接2:https://github.com/Adlik/model_zoo/tree/main/model_optimizer

链接3:https://github.com/Adlik/model_zoo

经测试,Adlik 模型编译器可以完成模型转换,Adlik 燧原运行时可以完成模型部署、模型推理,并返回相应的推理结果。

在测试时延的场景下,取 batch_size=1。resnet50、剪枝resnet50、yolov5s、bert 等迭代次数为 1200 次,warmup 10 次,推理时延取所有 batch 推理时延的平均数。

ONNX模型 Adlik推理时延(ms)
resnet50 4.86533
剪枝resnet50 3.3735
yolov5s 10.3394
bert 1154.33

在测量吞吐量的场景下,resnet50、剪枝 resnet50 和 bert batch_size 取 120,yolov5s 取 30 。

ONNX模型 Adlik推理时延(ms) 单实例-fps
resnet50 101.704 1179.894596
剪枝resnet50 68.6933 1746.895258
yolov5s 134.559 222.950527
bert 1233.91 97.251825

在同等条件下,燧原测试工具 topsexec 的吞吐量结果如下:

ONNX模型 batch_size 吞吐量
resnet50 120 1162.58
剪枝resnet50 120 1659.88
yolov5s 30 514.543
bert 120 86

4. 总结

Adlik 对接燧原芯片的工作还在继续。目前有一个遗留问题,能否将内存中的 onnx.onnx_ml_pb2.ModelProto 数据转换为燧原模型的格式,如果可以,编译器就可以提供TensorFlow、Keras 等到燧原格式的转换。此方法由于燧原构建模型的 API 暂不支持动态 shape 因此无法提供使用。后续将会继续跟踪燧原相关新特性消息,提高编译器对这种转换形式的支持程度。

你可能感兴趣的:(人工智能,计算机视觉,深度学习,机器学习)