我在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中一样)线程参数intraOpNumThreads
和interOpNumThreads
,如上所述。
我想为sequential
和parallel
执行模式(由上面定义的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以获得最佳性能(最低推理延迟)或达到性能和功耗的平衡。选择完全取决于你。