Onnxruntime NodeJS通过执行方式设置intraOpNumThreads和interOpNumThread



我在NodeJS中使用Onnxruntime在cpu后端执行onnx转换模型以运行推理。

根据文档,可选参数如下:

var options = {
/**
* 
*/
executionProviders: ['cpu'],
/*
* The optimization level.
* 'disabled'|'basic'|'extended'|'all'
*/
graphOptimizationLevel: 'all',
/**
* The intra OP threads number.
* change the number of threads used in the threadpool for Intra Operator Execution for CPU operators 
*/
intraOpNumThreads: 1,
/**
* The inter OP threads number.
* Controls the number of threads used to parallelize the execution of the graph (across nodes).
*/
interOpNumThreads: 1,
/**
* Whether enable CPU memory arena.
*/
enableCpuMemArena: false,
/**
* Whether enable memory pattern.
*
*/
enableMemPattern: false,
/**
* Execution mode.
* 'sequential'|'parallel'
*/
executionMode: 'sequential',
/**
* Log severity level
* @see ONNX.Severity
* 0|1|2|3|4
*/
logSeverityLevel: ONNX.Severity.kERROR,
/**
* Log verbosity level.
*
*/
logVerbosityLevel: ONNX.Severity.kERROR,
};

具体来说,我可以控制(像在Tensorflow中一样)线程参数intraOpNumThreadsinterOpNumThreads,如上所述。

我想为sequentialparallel执行模式(由上面定义的executionMode参数控制)优化它们。我的方法是

var numCPUs = require('os').cpus().length;
options.intraOpNumThreads = numCPUs;

为了至少有一些线程,比如可用cpu的数量,因此在我的macbook pro上,我得到了sequential执行模式的会话配置:

{
executionProviders: [ 'cpu' ],
graphOptimizationLevel: 'all',
intraOpNumThreads: 8,
interOpNumThreads: 1,
enableCpuMemArena: false,
enableMemPattern: false,
executionMode: 'sequential',
logSeverityLevel: 3,
logVerbosityLevel: 3
}

parallel执行模式,我设置两者:

{
executionProviders: [ 'cpu' ],
graphOptimizationLevel: 'all',
intraOpNumThreads: 8,
interOpNumThreads: 8,
enableCpuMemArena: false,
enableMemPattern: false,
executionMode: 'parallel',
logSeverityLevel: 3,
logVerbosityLevel: 3
}

或者另一种方法是考虑可用cpu的百分比:

var perc = (val, tot) => Math.round( tot*val/100 );
var numCPUs = require('os').cpus().length;
if(options.executionMode=='parallel') { // parallel
options.interOpNumThreads = perc(50,numCPUs);
options.intraOpNumThreads = perc(10,numCPUs);
} else { // sequential
options.interOpNumThreads = perc(100,numCPUs);
options.intraOpNumThreads = 1;
}

,但我没有找到任何文档来确保这是基于executionMode("顺序"one_answers"并行"执行模式)的这两个场景的最佳配置。这种方法在理论上正确吗?

这实际上取决于模型结构。通常,我使用顺序执行模式,因为大多数模型都是顺序模型——例如,对于CNN模型,每一层都依赖于前一层,所以你必须一个接一个地执行每一层。

我的答案是尝试测试不同的配置,并根据perf数字选择您的选择。

另一个考虑因素是您希望应用程序如何执行:消耗所有cpu以获得最佳性能(最低推理延迟)或达到性能和功耗的平衡。选择完全取决于你。

最新更新