1. 版权声明

以下条款适用于所有访问燧原产品和服务相关文档的用户或阅读者(以下统称“您”),本文档包括本文档提供的信息属于上海燧原科技股份有限公司和/或其子公司(以下统称“燧原”)或其许可方所有,且燧原保留不经通知随时对本文档信息或对本文档所述任何产品和服务做出修改的权利。本文档所含信息和本文档所引用燧原其他信息均“按原样”提供。燧原不担保信息、文本、图案、链接或本文档内所含其他项目的准确性或完整性。燧原不对本文档所述产品的可销售性、所有权、不侵犯知识产权、准确性、完整性、稳定性或特定用途适用性做任何暗示担保、保证。燧原可不经通知随时对本文档或本文档所述产品或服务做出更改,但不承诺因此更新本文档。

在任何情况下,燧原不对因使用或未使用本文档而导致的任何损害(包括但不限于利润损失、业务中断和信息损失等损害)承担任何责任。除非另行书面同意,燧原不对本文档承担任何责任,不论该责任因任何原因而产生或基于任何侵权理论。

本文档所列的规格参数、性能数据和等级基于特定芯片或计算机系统或组件测试所得。经该等测试,本文档所示结果反映了燧原产品在上述测试环境中的性能表现。测试系统配置及软硬件版本、环境变量等的任何变化都会影响产品或服务的实际性能,如产品或服务的实际效果与本文档描述存在差异的,均属正常现象。燧原不担保测试本文档中每种产品或服务的所有参数的准确性和稳定性。您自行承担对本文档中产品或服务是否适合并适用于您计划的应用进行评估以及进行必要测试的责任。您的使用环境、系统配置、产品设计等特性可能会影响燧原产品或服务的质量和可靠性并导致超出本文档范围的额外或不同的情况和/或要求,燧原对此不做任何担保或承担任何责任。

燧原®、Enflame ®和本文档中显示的其他所有商标、标志是上海燧原科技股份有限公司或其许可方申请和/或注册的商标。本文档并未明示或暗示地授予您任何专利、版权、商标、集成电路布图设计、商业秘密或任何其他燧原或其许可方知识产权的权利或许可。

本文档为燧原或其许可方版权所有并受全世界版权法律和条约条款的保护。未经燧原或其许可方的事先书面许可,任何人不可以任何方式复制、修改、出版、上传、发布、传输或分发本文档。为免疑义,除了允许您按照本文档要求使用本文档相关信息外,燧原或其许可方不授予其他任何明示或暗示的权利或许可。

本文档可能保留有与第三方网站或网址的链接,访问这些链接将由您自己作出决定,燧原并不保证这些链接上所提供的任何信息、数据、观点、图片、陈述或建议的准确性、完整性、充分性和可靠性。燧原提供这些链接仅仅在于提供方便,并不表示燧原对这些信息的认可和推荐,也不是用于宣传或广告目的。

您同意在使用本文档及其内容时,遵守国家法律法规、社会公共道德。您不得利用本文档及其内容从事制作、查阅、复制和传播任何违法、侵犯他人权益等扰乱社会秩序、破坏社会稳定的行为,亦不得利用本文档及其内容从事任何危害或试图危害计算机系统及网络安全的活动。

您同意,与您访问或使用本文档相关的所有事项,应根据中华人民共和国法律解释、理解和管辖。您同意,中国上海市有管辖权的法院具有相关的管辖权。

燧原对本文档享有最终解释权。

2. 前言

2.1. 版本信息

日期 版本 作者 新增功能
20230209 v1.0 Enflame
20230904 v2.4 Enflame 新增--pinnedMemory、--loadCompileOptions

3. 原理介绍

topsexec 是一个快速使用TopsInference的工具,无需开发您自己的应用,依赖于TopsInference C++ api。

topsexec 主要包括两个用途:

  • 方便地使用随机输入数据对网络进行性能基准测试

  • 方便地从模型生成序列化引擎

性能基准测试 - 如果你有一个以ONNX格式保存的模型文件,可以用topsexec在TopsInference上运行网络的推理,测试性能表现

生成引擎 - 如果你想要生成序列化的引擎文件,也可以使用topsexec

4. 安装使用说明

topsexec可执行程序会随着TopsInference c++ library安装,安装后可以直接使用。

源码也包括在TopsInference cpp samples目录中,如果需要从源码编译,可以进入topsexec的文件夹,执行cmake . && make进行编译。

5. 用户使用说明

使用topsexec时,需要用户提供onnx模型文件或之前保存的TopsInference序列化引擎。对于onnx,如果不是固定形状,还需要用户已知模型输入的名称和需测试的形状。

  • 帮助信息可以用 “-h” or “–help” 获得,包括选项含义、必要和可选配置

===Help Messages===
---Device Params---
 --device=N
     Card id
 --cluster=N[,N]
     Cluster ids, N values in [0,6), and max count of cluster is 6 (i.e. --cluster=0,1,2,3,4,5).
     Specially, default value is --cluster=-1 , which represents using all clusters in a card.

---Model Params---
 --onnx=<file>
     ONNX model
 --input=<name>,<DType>
     Input tensor name and its datatype, it can be specified multiple times;
     At least one is required for topsinference parser;
     DType is not necessary, default as fp32
 --inputShape=spec
     Input tensor shape. It can be specified multiple times, but invalid when more times for --inputShape than --input
     spec format: comma-separated dimension values (Eg. 1,3,224,224);
 --inputMaxShape=spec
     Max input tensor shape. It can be specified multiple times, but invalid when more times for --inputMaxShape than --input
     spec format is same with --inputShape
 --inputMinShape=spec
     Min input tensor shape. It can be specified multiple times, but invalid when more times for --inputMinShape than --input
     spec format is same with --inputShape
 --inputValueRange=min,max
     Specify random value range [min,max] for input, defaults to [0,1].
     It can be specified multiple times, but invalid when more times for --inputShape than input number
 --output=<name>,<DType>
     Output tensor name and its data type, it can be specified multiple times;
     At least one is required for topsinference parser;
     DType is not necessary, default as fp32

---Build Params---
 --fp16
     Enable fp16 mixed precision for network (default = disabled)
 --loadExecutable=<File>
     Load a previously built executable.
 --saveExecutable=<File>
     Save executable to a static file
 --resourceMode=<Mode>
     Resource mode used to build executable, must equal one of 1c12s 1c6s 1c4s 2c24s
     Also necessary when loading executable.
     See TopsInference docs for more information.
 --loadCompileOptions=<JsonFile>
     Load TopsInference compile options from json file and set.
     See TopsInference docs for more information.
     This will overwrite --resourceMode.
 --refit
     Mark the engine as refittable.
 --layerPrecisions
     Set layer precision by ONNX node name.
     eg. --layerPrecisions=Conv_1:fp32,Add_2:fp32

---Runtime Params---
 --iterations=N
     Iterations of inference
 --warmup=N
     Iterations of warm up
 --runBatch=N
     Batch size for inference.
 --runShape=spec
     Shape for infernece (mainly for dynamic input shape models).
     It can be specified multiple times, but invalid when more times for --runShape than inputs
     spec format is same with --inputShape, overwrite --runBatch.
 --verbose
     Log more information.
 --threads
     How many threads to run execution. Defaults to cluster_num * 2.
 --streams
     How many streams PER THREAD to run execution.
     Defaults to 0 which means sync mode. Set positive value to enable async mode.
 --separateTransfer
     Inference from device memory to device memory.
     This option DOES NOT bypass H2D and D2H, only schedule them above TopsInference
 --pinnedMemory
     Use pinned host memory for better H2D and D2H performance.
 --inferOutputShape
     Infer output shape before run.
  • –device: 使用的卡的序号,默认为0

  • –cluster: 使用的cluster的序号列表,默认-1,代表所有cluster

  • –onnx: topsexec使用的onnx模型,对onnx模型必须

  • –input: 模型输入的名字和数据类型,对多输入模型可以指定多次。如果使用动态形状模型,需要配合“–inputShape”使用,数据类型是可选项,默认fp32

  • –inputShape=spec : 模型输入的形状,维度使用逗号分割,如1,3,224,224,对多输入模型可以指定多次,但是不能超出“–input”的次数。

  • –inputValueRange=min,max:指定输入数据的随机范围,[min,max],默认[0,1]

  • –output: 模型输出的名字和数据类型,格式和“–input”相同,如果不指定则所有输出

  • –fp16: 开启fp16混合精度,默认关闭

  • –loadExecutable: 读取预编译的引擎

  • –saveExecutable: 保存编译好的引擎

  • –iterations: 执行全推理过程的迭代次数

  • –warmup: 在统计推理数据的迭代前进行预热迭代数

  • –resourceMode: 设置编译时优化器的resource_mode,例如1c4s或1c12s,查看TopsInference文档获取更多信息

  • –loadCompileOptions:从json文件中读取TopsInference的编译选项,例如{"enable_gcu_only":true,"resource_mode":"1c12s"},可配置内容请参考TopsInference文档相关章节

  • –refit:使生成的引擎可以进行refit(权重热更新)

  • –layerPrecisions: 根据ONNX中的节点名,手动指定部分layer的计算精度

  • –runBatch: 推理时使用的batch size,根据–resourceMode有不同的默认值,设置较大的值会提高吞吐量

  • –verbose: 打印更多日志

  • –threads: 线程数,默认为cluster数量*2

  • –streams: 每个线程的stream数量,默认为0,代表同步模式,设置大于0的数开启异步模式

  • –separateTransfer: 独立地进行H2D、推理和D2H,即推理是使用D2D模式(并不跳过数据搬运)

  • –pinnedMemory:使用固定内存加快H2D和D2H

  • –inputMaxShape: 编译模型时每个输入的最大形状,维度使用逗号分割,如1,3,640,640–input”的次数。

  • –inputMinShape: 编译模型时每个输入的最小形状,维度使用逗号分割,如1,3,320,320,对多输入模型可以指定多次,但是不能超出“–input”的次数。

  • –runShape: 动态模型测试时实际输入数据的形状,维度使用逗号分割,如1,3,480,480,对多输入模型可以指定多次,但是不能超出“–input”的次数。

  • –inferOutputShape: 在推理之前推理输出形状

5.1. 使用示例

  1. 从固定形状的ONNX文件直接获取吞吐量和延迟数据

    • 直接传入onnx文件路径即可

    topsexec --onnx=static-shape.onnx
    
    • 开启fp16 混合精度计算

    topsexec --onnx=static-shape.onnx --fp16
    

    控制台的输出样例:

     ========================
     TopsInference.topsexec version: 2.0.0
     --model path: static-shape.onnx
     --model type: onnx
     --quantization: float16
     --resourceMode: 
     --device id: 0
     --cluster ids number: 1
     --cluster ids: -1
     --iterations: 120
     --warmup: 6
     --runBatch: 1
     --verbose: 0
     --threads: 12
     --streams: 0
       async:false
     --separateTransfer: 0
     --pinnedMemory: false
     ========================
     Total 120 queries over 0.0348256s
     Trace averages of 10 queries:
       Average latency on 10 runs: 0.003885s
       Average latency on 10 runs: 0.00539418s
       Average latency on 10 runs: 0.00747247s
       Average latency on 10 runs: 0.009668s
       Average latency on 10 runs: 0.00963948s
       Average latency on 10 runs: 0.00993728s
       Average latency on 10 runs: 0.00977794s
       Average latency on 10 runs: 0.00983828s
       Average latency on 10 runs: 0.00992614s
       Average latency on 10 runs: 0.00982859s
       Average latency on 10 runs: 0.00998038s
       Average latency on 10 runs: 0.00973959s
     Mean Latency (s): 0.00875728
     Min Latency (s): 0.00220181
     Max Latency (s): 0.0107133
     99% Latency (s): 0.0106484
     Batch Throughput (batch/s): 3445.74
     Sample Throughput (sample/s): 3445.74
     ========================
    
  2. 对于包含 动态batch size的ONNX模型,需要使用–input和–inputShape来指定确定的形状

    • 以resnet50为例,输入名称是input,输入形状是N,3,224,224,如果需要测试N=1时的性能:

    topsexec --onnx=resnet50_v1.5-torchvision-op13-fp32-N.onnx --input=input --inputShape=1,3,224,224 --fp16
    
    • 对于多输入,需要依次指定每个输入的名称和形状: (如果输入的数据类型不是fp32,需要在–input中指定)

    topsexec --onnx=multi-input.onnx --input=input0,int32 --inputShape=1,256 --input=input1,int32 --inputShape=1,256 --fp16
    
  3. 对于包含 动态形状的ONNX模型

    • 以yolov5为例, 如果你想测试 640x640 图片的性能,但引擎可以推理 320x320 ~ 672x672 的图片:

    topsexec --onnx=yolov5s-v6.2-op13-fp32-N.onnx --input=images --inputShape=1,3,-1,-1 --inputMinShape=1,3,320,320 --inputMaxShape=1,3,672,672 --runShape=1,3,640,640 --fp16
    
    • 如果你想测试 640x640 图片的性能,且引擎只可以推理 640x640 的图片:

    topsexec --onnx=yolov5s-v6.2-op13-fp32-N.onnx --input=images --inputShape=1,3,640,640 --fp16
    
  4. 对于模型包括输入范围限制的模型(如BERT的mask),可以用–inputValueRange指定随机输入的范围

    • 以BERT为例,输入均为int32类型,形状均为N,384,输入input_ids的取值范围是[0,30521]、input_mask和segment_ids取值范围是[0,1]则可以用下列命令

    topsexec --onnx=bert_large-squad-mlperf-op13-fp32-N.onnx --input=input_ids,int32 --inputShape=1,384 --inputValueRange=0,30521 --input=input_mask,int32 --inputShape=1,384 --inputValueRange=0,1 --input=segment_ids,int32 --inputShape=1,384 --inputValueRange=0,1 --fp16
    
  5. 多线程,多stream和设备内存到设备内存推理

    • topsexec 默认使用多线程,同步,主机内存到主机内存的方式,等价于

    topsexec ... --threads=12 --streams=0
    
    • 如果你希望使用多stream异步方式,使用

    topsexec ... --threads=1 --streams=12
    
    • 如果你希望测试独立H2D搬运、D2D推理、D2H搬运的性能,使用

    topsexec ... --separateTransfer
    
    • 如果你希望测试TopsInference auto batch的性能(topsexec 0.4版本默认),使用

    topsexec ... --threads=1 --runBatch=60
    
  6. 将ONNX模型转化并保存为序列化引擎文件 / 读取引擎并进行基准测试

    # 编译并保存
    topsexec --onnx=static-shape.onnx --saveExecutable=model.executable --fp16
    
    # 读取并运行
    topsexec --loadExecutable=model.executable
    

5.2. 性能指标说明

Latency: 延迟,代表一个请求在host侧端到端的时间,包括H2D、推理、D2H和相关的队列时间,每个请求分别计时。

Throughput: 吞吐量,由总请求数除以总墙钟时间计算,代表单位时间可以处理的请求数。

  • Batch Throughput: 以batch为单位计算的吞吐量,单位是每秒batch数。

  • Sample Throughput: 以sample为单位计算的吞吐量,单位是每秒样本数,由Batch Throughput乘batch size折算而来。需要注意的是,对于第一个输入的形状的第一个维度不代表batch size的语义时,需要用户自行推算。

吞吐量和延迟的关系:吞吐量和延迟是分别统计的。由于每个请求之间在时间上可能有重叠的部分(例如第二个请求的H2D和第一个请求的推理可以并行),吞吐量并不由每个样本的延迟折算而来,它们之间也并不具备直接的倒数关系。此外,在请求调度过程中,为了提高吞吐量而产生的额外队列时间也会被记入延迟中,也会使得topsexec测得的延迟时间比一般情况下(例如单线程少量请求)要长一些。