在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

TensorRT中的自定義層滿(mǎn)足模型的特定需求

星星科技指導(dǎo)員 ? 來(lái)源:NVIDIA ? 作者:Ken He ? 2022-05-13 16:50 ? 次閱讀

NVIDIA TensorRT 支持多種類(lèi)型的層,其功能不斷擴(kuò)展;但是,在某些情況下,支持的層不能滿(mǎn)足模型的特定需求。

您可以通過(guò)實(shí)現(xiàn)自定義層(通常稱(chēng)為插件)來(lái)擴(kuò)展 TensorRT。

9.1. Adding Custom Layers Using The C++ API

您可以通過(guò)從 TensorRT 的插件基類(lèi)之一派生來(lái)實(shí)現(xiàn)自定義層。Table 3. Base classes, ordered from least expressive to most expressive

為了在網(wǎng)絡(luò)中使用插件,您必須首先將其注冊(cè)到 TensorRT 的PluginRegistry ( C++ 、 Python )。不是直接注冊(cè)插件,而是為插件注冊(cè)一個(gè)工廠類(lèi)的實(shí)例,派生自PluginCreator ( C++ , Python )。插件創(chuàng)建者類(lèi)還提供有關(guān)插件的其他信息:它的名稱(chēng)、版本和插件字段參數(shù)

您必須從插件的基類(lèi)之一派生插件類(lèi)。在支持具有不同類(lèi)型/格式的輸入/輸出或具有動(dòng)態(tài)形狀的網(wǎng)絡(luò)方面,它們具有不同的表達(dá)能力。下表總結(jié)了基類(lèi),按從最不具表現(xiàn)力到最具表現(xiàn)力的順序排列。

注意:如果插件用于一般用途,請(qǐng)?zhí)峁?FP32 實(shí)現(xiàn),以使其能夠在任何網(wǎng)絡(luò)上正常運(yùn)行。

TensorRT 提供了一個(gè)宏REGISTER_TENSORRT_PLUGIN ,它將插件創(chuàng)建者靜態(tài)注冊(cè)到注冊(cè)表中。

TensorRT 庫(kù)包含可以加載到您的應(yīng)用程序中的插件。有關(guān)開(kāi)源插件的列表,請(qǐng)參閱GitHub:TensorRT 插件。

注意:

要在應(yīng)用程序中使用 TensorRT 插件,必須加載libnvinfer_plugin.so庫(kù),并且必須通過(guò)在應(yīng)用程序代碼中調(diào)用initLibNvInferPlugins來(lái)注冊(cè)所有插件。

如果您有自己的插件庫(kù),則可以包含一個(gè)類(lèi)似的入口點(diǎn),以便在唯一命名空間下的注冊(cè)表中注冊(cè)所有插件。這確保了在構(gòu)建期間跨不同插件庫(kù)的插件名稱(chēng)沒(méi)有沖突。

有關(guān)這些插件的更多信息,請(qǐng)參閱NvInferPlugin.h文件以供參考。

調(diào)用IPluginCreator::createPlugin()返回IPluginV2類(lèi)型的插件對(duì)象。您可以使用addPluginV2()將插件添加到 TensorRT 網(wǎng)絡(luò),該插件使用給定插件創(chuàng)建網(wǎng)絡(luò)層。

例如,您可以將插件層添加到您的網(wǎng)絡(luò),如下所示:

// Look up the plugin in the registry

auto creator = getPluginRegistry()-》getPluginCreator(pluginName, pluginVersion);

const PluginFieldCollection* pluginFC = creator-》getFieldNames();

// Populate the fields parameters for the plugin layer

PluginFieldCollection *pluginData = parseAndFillFields(pluginFC, layerFields);

// Create the plugin object using the layerName and the plugin meta data

IPluginV2 *pluginObj = creator-》createPlugin(layerName, pluginData);

// Add the plugin to the TensorRT network

auto layer = network.addPluginV2(&inputs[0], int(inputs.size()), pluginObj);

… (build rest of the network and serialize engine)

// Destroy the plugin object

pluginObj-》destroy()

… (destroy network, engine, builder)

… (free allocated pluginData)

注意:

pluginData必須在傳遞給createPlugin之前在堆上分配PluginField條目。

前面描述的 createPlugin 方法在堆上創(chuàng)建一個(gè)新的插件對(duì)象并返回一個(gè)指向它的指針。如前所示,確保銷(xiāo)毀 pluginObj 以避免內(nèi)存泄漏。

IPluginV2類(lèi)型插件的插件類(lèi)型、插件版本和命名空間(如果存在) 。在反序列化期間,TensorRT 從插件注冊(cè)表中查找插件創(chuàng)建者并調(diào)用IPluginCreator::deserializePlugin() 。在反序列化過(guò)程中創(chuàng)建的插件對(duì)象由 TensorRT 引擎通過(guò)調(diào)用IPluginV2::destroy()方法在內(nèi)部銷(xiāo)毀。

IPluginV2類(lèi)型插件的插件類(lèi)型、插件版本和命名空間(如果存在), 在反序列化期間,TensorRT 從插件注冊(cè)表中查找插件創(chuàng)建者并調(diào)用IPluginCreator::deserializePlugin() 。在反序列化期間創(chuàng)建的插件對(duì)象由 TensorRT 引擎通過(guò)調(diào)用IPluginV2::destroy()方法在內(nèi)部銷(xiāo)毀。

9.1.1. Example: Adding A Custom Layer With Dynamic Shape Support Using C++

要支持動(dòng)態(tài)形狀,您的插件必須從IPluginV2DynamicExt派生。

關(guān)于這個(gè)任務(wù)

BarPlugin是一個(gè)有兩個(gè)輸入和兩個(gè)輸出的插件,其中: ? 第一個(gè)輸出是第二個(gè)輸入的拷貝 ? 第二個(gè)輸出是兩個(gè)輸入的串聯(lián),沿著第一個(gè)維度,所有類(lèi)型/格式必須相同并且是線性格式

BarPlugin需要按如下方式派生:

class BarPlugin : public IPluginV2DynamicExt

{

。..override virtual methods inherited from IPluginV2DynamicExt.

};

繼承的方法都是純虛方法,所以如果你忘記了,編譯器會(huì)提醒你。

受動(dòng)態(tài)形狀影響的四種方法是:

獲取輸出維度

支持格式組合

配置插件

隊(duì)列

getOutputDimensions的覆蓋根據(jù)輸入維度返回輸出維度的符號(hào)表達(dá)式。您可以使用傳遞給getOutputDimensions的IExprBuilder從輸入的表達(dá)式構(gòu)建表達(dá)式。在示例中,不必為案例 1 構(gòu)建新表達(dá)式,因?yàn)榈诙€(gè)輸出的維度與第一個(gè)輸入的維度相同。

DimsExprs BarPlugin::getOutputDimensions(int outputIndex,

const DimsExprs* inputs, int nbInputs,

IExprBuilder& exprBuilder)

{

switch (outputIndex)

{

case 0:

{

// First dimension of output is sum of input

// first dimensions.

DimsExprs output(inputs[0]);

output.d[0] =

exprBuilder.operation(DimensionOperation::kSUM,

inputs[0].d[0], inputs[1].d[0]);

return output;

}

case 1:

return inputs[0];

default:

throw std::invalid_argument(“invalid output”);

}

supportsFormatCombination的覆蓋必須指示是否允許格式組合。接口將輸入/輸出統(tǒng)一索引為“connections”,從第一個(gè)輸入的 0 開(kāi)始,然后依次為其余輸入,然后為輸出編號(hào)。在示例中,輸入是connections 0 和 1,輸出是connections 2 和 3。

TensorRT 使用supportsFormatCombination來(lái)詢(xún)問(wèn)給定的格式/類(lèi)型組合是否適用于連接,給定的格式/類(lèi)型用于索引較少的連接。因此,覆蓋可以假設(shè)較少索引的連接已經(jīng)過(guò)審查,并專(zhuān)注于與索引pos的連接。

bool BarPlugin::supportsFormatCombination(int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) override

{

assert(0 《= pos && pos 《 4);

const auto* in = inOut;

const auto* out = inOut + nbInputs;

switch (pos)

{

case 0: return in[0].format == TensorFormat::kLINEAR;

case 1: return in[1].type == in[0].type &&

in[0].format == TensorFormat::kLINEAR;

case 2: return out[0].type == in[0].type &&

out[0].format == TensorFormat::kLINEAR;

case 3: return out[1].type == in[0].type &&

out[1].format == TensorFormat::kLINEAR;

}

throw std::invalid_argument(“invalid connection number”);

}

這里的局部變量in和out允許通過(guò)輸入或輸出編號(hào)而不是連接編號(hào)檢查inOut 。

重要提示:覆蓋檢查索引小于pos的連接的格式/類(lèi)型,但絕不能檢查索引大于pos的連接的格式/類(lèi)型。該示例使用case 3來(lái)檢查連接 3 和連接 0,而不是使用case 0來(lái)檢查連接 0 和連接 3。

TensorRT 使用configurePlugin在運(yùn)行時(shí)設(shè)置插件。這個(gè)插件不需要configurePlugin來(lái)做任何事情,所以它是一個(gè)空操作:

void BarPlugin::configurePlugin(

const DynamicPluginTensorDesc* in, int nbInputs,

const DynamicPluginTensorDesc* out, int nbOutputs) override

{

}

如果插件需要知道它可能遇到的最小或最大尺寸,它可以檢查字段DynamicPluginTensorDesc::min或DynamicPluginTensorDesc::max的任何輸入或輸出。格式和構(gòu)建時(shí)維度信息可以在DynamicPluginTensorDesc::desc中找到。任何運(yùn)行時(shí)維度都顯示為 -1。實(shí)際維度提供給BarPlugin::enqueue 。

最后,重寫(xiě)B(tài)arPlugin::enqueue必須完成這項(xiàng)工作。由于形狀是動(dòng)態(tài)的,因此 enqueue 會(huì)收到一個(gè)PluginTensorDesc ,它描述了每個(gè)輸入和輸出的實(shí)際尺寸、類(lèi)型和格式。

9.1.2. Example: Adding A Custom Layer With INT8 I/O Support Using C++

PoolPlugin是一個(gè)插件,用于演示如何為自定義池層擴(kuò)展 INT8 I/O。推導(dǎo)如下:

class PoolPlugin : public IPluginV2IOExt

{

。..override virtual methods inherited from IPluginV2IOExt.

};

大多數(shù)純虛方法對(duì)插件來(lái)說(shuō)都是通用的。影響INT8 I/O的主要方法有:

支持格式組合

配置插件

enqueue

supportsFormatCombination的覆蓋必須指示允許哪個(gè) INT8 I/O 組合。此接口的用法類(lèi)似于示例:使用 C++ 添加具有動(dòng)態(tài)形狀支持的自定義層。在本例中,支持的 I/O 張量格式為線性 CHW,數(shù)據(jù)類(lèi)型為 FP32、FP16 或 INT8,但 I/O 張量必須具有相同的數(shù)據(jù)類(lèi)型。

bool PoolPlugin::supportsFormatCombination(int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) const override

{

assert(nbInputs == 1 && nbOutputs == 1 && pos 《 nbInputs + nbOutputs);

bool condition = inOut[pos].format == TensorFormat::kLINEAR;

condition &= ((inOut[pos].type == DataType::kFLOAT) ||

(inOut[pos].type == DataType::kHALF) ||

(inOut[pos].type == DataType::kINT8));

condition &= inOut[pos].type == inOut[0].type;

return condition;

}

重要的:

如果 INT8 校準(zhǔn)必須與具有 INT8 I/O 插件的網(wǎng)絡(luò)一起使用,則該插件必須支持 FP32 I/O,因?yàn)樗?FP32 校準(zhǔn)圖使用。

如果不支持 FP32 I/O 變體或未使用 INT8 校準(zhǔn),則必須明確設(shè)置所有必需的 INT8 I/O 張量尺度。

校準(zhǔn)無(wú)法確定插件內(nèi)部張量的動(dòng)態(tài)范圍。對(duì)量化數(shù)據(jù)進(jìn)行操作的插件必須為內(nèi)部張量計(jì)算自己的動(dòng)態(tài)范圍。

TensorRT 調(diào)用configurePlugin方法通過(guò)PluginTensorDesc將信息傳遞給插件,這些信息存儲(chǔ)為成員變量,序列化和反序列化。

void PoolPlugin::configurePlugin(const PluginTensorDesc* in, int nbInput, const PluginTensorDesc* out, int nbOutput)

{

。..

mPoolingParams.mC = mInputDims.d[0];

mPoolingParams.mH = mInputDims.d[1];

mPoolingParams.mW = mInputDims.d[2];

mPoolingParams.mP = mOutputDims.d[1];

mPoolingParams.mQ = mOutputDims.d[2];

mInHostScale = in[0].scale 》= 0.0f ? in[0].scale : -1.0f;

mOutHostScale = out[0].scale 》= 0.0f ? out[0].scale : -1.0f;

}

每個(gè)張量的 INT8 I/O 比例可以從PluginTensorDesc::scale獲得。 最后,重寫(xiě)UffPoolPluginV2::enqueue必須完成這項(xiàng)工作。它包括一組核心算法,可在運(yùn)行時(shí)通過(guò)使用實(shí)際批量大小、輸入、輸出、cuDNN 流和配置的信息來(lái)執(zhí)行自定義層。

int PoolPlugin::enqueue(int batchSize, const void* const* inputs, void** outputs, void* workspace, cudaStream_t stream)

{

。..

CHECK(cudnnPoolingForward(mCudnn, mPoolingDesc, &kONE, mSrcDescriptor, input, &kZERO, mDstDescriptor, output));

。..

return 0;

}

9.2. Adding Custom Layers Using The Python API

盡管 C++ API 是實(shí)現(xiàn)自定義層的首選語(yǔ)言,但由于可以訪問(wèn) CUDA 和 cuDNN 等庫(kù),您還可以在 Python 應(yīng)用程序中使用自定義層。

您可以使用 C++ API 創(chuàng)建自定義層,在 Python 中使用pybind11打包層,然后將插件加載到 Python 應(yīng)用程序中。有關(guān)更多信息,請(qǐng)參閱在 Python 中創(chuàng)建網(wǎng)絡(luò)定義。

相同的自定義層實(shí)現(xiàn)可用于 C++ 和 Python。

9.2.1. Example: Adding A Custom Layer To A TensorRT Network Using Python

可以使用插件節(jié)點(diǎn)將自定義層添加到 Python 中的任何 TensorRT 網(wǎng)絡(luò)。

Python API 有一個(gè)名為add_plugin_v2的函數(shù),可讓您將插件節(jié)點(diǎn)添加到網(wǎng)絡(luò)。以下示例說(shuō)明了這一點(diǎn)。它創(chuàng)建了一個(gè)簡(jiǎn)單的TensorRT網(wǎng)絡(luò),并通過(guò)查找TensorRT插件注冊(cè)表來(lái)添加一個(gè) Leaky ReLU 插件節(jié)點(diǎn)。

import tensorrt as trt

import numpy as np

TRT_LOGGER = trt.Logger()

trt.init_libnvinfer_plugins(TRT_LOGGER, ‘’)

PLUGIN_CREATORS = trt.get_plugin_registry().plugin_creator_list

def get_trt_plugin(plugin_name):

plugin = None

for plugin_creator in PLUGIN_CREATORS:

if plugin_creator.name == plugin_name:

lrelu_slope_field = trt.PluginField(“neg_slope”, np.array([0.1], dtype=np.float32), trt.PluginFieldType.FLOAT32)

field_collection = trt.PluginFieldCollection([lrelu_slope_field])

plugin = plugin_creator.create_plugin(name=plugin_name, field_collection=field_collection)

return plugin

def main():

builder = trt.Builder(TRT_LOGGER)

network = builder.create_network()

config = builder.create_builder_config()

config.max_workspace_size = 2**20

input_layer = network.add_input(name=“input_layer”, dtype=trt.float32, shape=(1, 1))

lrelu = network.add_plugin_v2(inputs=[input_layer], plugin=get_trt_plugin(“LReLU_TRT”))

lrelu.get_output(0).name = “outputs”

network.mark_output(lrelu.get_output(0))

9.3. Using Custom Layers When Importing A Model With A Parser

ONNX 解析器會(huì)自動(dòng)嘗試將無(wú)法識(shí)別的節(jié)點(diǎn)作為插件導(dǎo)入。如果在插件注冊(cè)表中找到與節(jié)點(diǎn)具有相同op_type的插件,則解析器將節(jié)點(diǎn)的屬性作為插件字段參數(shù)轉(zhuǎn)發(fā)給插件創(chuàng)建者,以創(chuàng)建插件。默認(rèn)情況下,解析器使用“1”作為插件版本, “”作為插件命名空間。可以通過(guò)在相應(yīng)的 ONNX 節(jié)點(diǎn)中設(shè)置plugin_version或plugin_namespace字符串屬性來(lái)覆蓋此行為。

在某些情況下,您可能希望在將 ONNX 圖導(dǎo)入 TensorRT 之前對(duì)其進(jìn)行修改。例如,用插件節(jié)點(diǎn)替換一組操作。為此,您可以使用ONNX GraphSurgeon 實(shí)用程序。有關(guān)如何使用 ONNX-GraphSurgeon 替換子圖的詳細(xì)信息,請(qǐng)參閱此示例。

有關(guān)更多示例,請(qǐng)參閱onnx_packnet示例。

9.4. Plugin API Description

所有新插件都應(yīng)從IPluginCreator和使用 C++ API 添加自定義層中描述的插件基類(lèi)之一派生類(lèi)。此外,新插件還應(yīng)調(diào)用REGISTER_TENSORRT_PLUGIN(。..)宏以將插件注冊(cè)到 TensorRT 插件注冊(cè)表或創(chuàng)建等效于initLibNvInferPlugins()的init函數(shù)。

9.4.1. Migrating Plugins From TensorRT 6.x Or 7.x To TensorRT 8.x.x

IPluginV2和IPluginV2Ext以分別向后兼容 TensorRT 5.1 和 6.0.x。但是,新插件應(yīng)針對(duì)IPluginV2DynamicExt或IPluginV2IOExt接口,而舊插件應(yīng)重構(gòu)以使用這些接口。

IPluginV2DynamicExt中的新特性如下:

virtual DimsExprs getOutputDimensions(int outputIndex, const DimsExprs* inputs, int nbInputs, IExprBuilder& exprBuilder) = 0;

virtual bool supportsFormatCombination(int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) = 0;

virtual void configurePlugin(const DynamicPluginTensorDesc* in, int nbInputs, const DynamicPluginTensorDesc* out, int nbOutputs) = 0;

virtual size_t getWorkspaceSize(const PluginTensorDesc* inputs, int nbInputs, const PluginTensorDesc* outputs, int nbOutputs) const = 0;

virtual int enqueue(const PluginTensorDesc* inputDesc, const PluginTensorDesc* outputDesc, const void* const* inputs, void* const* outputs, void* workspace, cudaStream_t stream) = 0;

IPluginV2IOExt中的新特性如下:

virtual void configurePlugin(const PluginTensorDesc* in, int nbInput, const PluginTensorDesc* out, int nbOutput) = 0;

virtual bool supportsFormatCombination(int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) const = 0;

遷移到IPluginV2DynamicExt或IPluginV2IOExt的指南:

getOutputDimensions實(shí)現(xiàn)給定輸入的輸出張量維度的表達(dá)式。

supportsFormatCombination檢查插件是否支持指定輸入/輸出的格式和數(shù)據(jù)類(lèi)型。

configurePlugin模仿IPluginV2Ext中等效的configurePlugin的行為,但接受張量描述符。

getWorkspaceSize和enqueue模仿IPluginV2Ext中等效 API 的行為,但接受張量描述符。

更多詳細(xì)信息,請(qǐng)參閱IPluginV2 API 說(shuō)明中的 API 說(shuō)明。

9.4.2. IPluginV2 API Description

以下部分介紹IPluginV2類(lèi)的功能。要將插件層連接到相鄰層并設(shè)置輸入和輸出數(shù)據(jù)結(jié)構(gòu),構(gòu)建器通過(guò)調(diào)用以下插件方法檢查輸出的數(shù)量及其維度。

getNbOutputs

用于指定輸出張量的數(shù)量。

getOutputDimensions

用于將輸出的維度指定為輸入維度的函數(shù)。

supportsFormat

用于檢查插件是否支持給定的數(shù)據(jù)格式。

getOutputDataType

用于獲取給定索引處輸出的數(shù)據(jù)類(lèi)型。返回的數(shù)據(jù)類(lèi)型必須具有插件支持的格式。

插件層可以支持四種數(shù)據(jù)格式,例如:

NCHW單精度 (FP32)、半精度 (FP16) 和整型 (INT32) 張量

NC / 2HW2和NHWC8半精度 (FP16) 張量

格式由PluginFormatType枚舉。

除了輸入和輸出張量之外,不計(jì)算所有數(shù)據(jù)并且需要內(nèi)存空間的插件可以使用getWorkspaceSize方法指定額外的內(nèi)存需求,該方法由構(gòu)建器調(diào)用以確定和預(yù)分配暫存空間。

在構(gòu)建和推理期間,可能會(huì)多次配置和執(zhí)行插件層。在構(gòu)建時(shí),為了發(fā)現(xiàn)最佳配置,層被配置、初始化、執(zhí)行和終止。為插件選擇最佳格式后,再次配置插件,然后在推理應(yīng)用程序的生命周期內(nèi)初始化一次并執(zhí)行多次,最后在引擎銷(xiāo)毀時(shí)終止。這些步驟由構(gòu)建器和引擎使用以下插件方法控制:

configurePlugin(配置插件)

傳達(dá)輸入和輸出的數(shù)量、所有輸入和輸出的維度和數(shù)據(jù)類(lèi)型、所有輸入和輸出的廣播信息、選擇的插件格式和最大批量大小。此時(shí),插件設(shè)置其內(nèi)部狀態(tài)并為給定配置選擇最合適的算法和數(shù)據(jù)結(jié)構(gòu)。

initialize(初始化)

此時(shí)配置是已知的,并且正在創(chuàng)建推理引擎,因此插件可以設(shè)置其內(nèi)部數(shù)據(jù)結(jié)構(gòu)并準(zhǔn)備執(zhí)行。

enqueue(排隊(duì))

封裝插件的實(shí)際算法和內(nèi)核調(diào)用,并提供運(yùn)行時(shí)批處理大小、指向輸入、輸出和暫存空間的指針,以及用于內(nèi)核執(zhí)行的CUDA流。

terminate(終止)

引擎上下文被銷(xiāo)毀,插件持有的所有資源必須被釋放。

clone(克隆)

每次創(chuàng)建包含此插件層的新構(gòu)建器、網(wǎng)絡(luò)或引擎時(shí)都會(huì)調(diào)用它。它必須返回一個(gè)帶有正確參數(shù)的新插件對(duì)象。

destroy(銷(xiāo)毀)

用于銷(xiāo)毀插件對(duì)象和/或每次創(chuàng)建新插件對(duì)象時(shí)分配的其他內(nèi)存。每當(dāng)構(gòu)建器或網(wǎng)絡(luò)或引擎被破壞時(shí)都會(huì)調(diào)用它。

“`set/getPluginNamespace`(設(shè)置/獲取插件命名空間)“

該方法用于設(shè)置該插件對(duì)象所屬的庫(kù)命名空間(默認(rèn)可以是“”)。來(lái)自同一個(gè)插件庫(kù)的所有插件對(duì)象都應(yīng)該具有相同的命名空間。

IPluginV2Ext支持可以處理廣播輸入和輸出的插件。此功能需要實(shí)現(xiàn)以下方法:

canBroadcastInputAcrossBatch

對(duì)每個(gè)輸入調(diào)用此方法,其張量在批次中進(jìn)行語(yǔ)義廣播。如果canBroadcastInputAcrossBatch返回true (意味著插件可以支持廣播),則 TensorRT 不會(huì)復(fù)制輸入張量。插件應(yīng)該在批處理中共享一個(gè)副本。如果它返回false ,則 TensorRT 會(huì)復(fù)制輸入張量,使其看起來(lái)像一個(gè)非廣播張量。

isOutputBroadcastAcrossBatch

這為每個(gè)輸出索引調(diào)用。該插件應(yīng)在給定索引處返回 true 輸出,并在整個(gè)批次中廣播。

IPluginV2IOExt 這由構(gòu)建器在initialize()之前調(diào)用。它為層提供了基于 I/O PluginTensorDesc和最大批量大小進(jìn)行算法選擇的機(jī)會(huì)。

注意:基于IPluginV2的插件在引擎級(jí)別共享,而不是在執(zhí)行上下文級(jí)別共享,因此這些可能被多個(gè)線程同時(shí)使用的插件需要以線程安全的方式管理它們的資源。創(chuàng)建ExecutionContext時(shí)會(huì)克隆基于IPluginV2Ext和派生接口的插件,因此這不是必需的。

9.4.3. IPluginCreator API Description

IPluginCreator類(lèi)中的以下方法用于從插件注冊(cè)表中查找和創(chuàng)建適當(dāng)?shù)牟寮?/p>

getPluginName

IPluginExt::getPluginType的返回值。

getPluginVersion 返回插件版本。對(duì)于所有內(nèi)部 TensorRT 插件,默認(rèn)為1 。

getFieldNames 要成功創(chuàng)建插件,需要了解插件的所有字段參數(shù)。此方法返回PluginFieldCollection結(jié)構(gòu),其中填充了PluginField條目以反映字段名稱(chēng)和PluginFieldType (數(shù)據(jù)應(yīng)指向nullptr )。

createPlugin

此方法用于使用PluginFieldCollection參數(shù)創(chuàng)建插件。應(yīng)填充PluginField條目的數(shù)據(jù)字段以指向每個(gè)插件字段條目的實(shí)際數(shù)據(jù)。

注意:傳遞給createPlugin函數(shù)的數(shù)據(jù)應(yīng)該由調(diào)用者分配,并在程序被銷(xiāo)毀時(shí)最終由調(diào)用者釋放。 createPlugin函數(shù)返回的插件對(duì)象的所有權(quán)被傳遞給調(diào)用者,并且也必須被銷(xiāo)毀。

deserializePlugin

此方法由 TensorRT 引擎根據(jù)插件名稱(chēng)和版本在內(nèi)部調(diào)用。它應(yīng)該返回要用于推理的插件對(duì)象。在該函數(shù)中創(chuàng)建的插件對(duì)象在引擎被銷(xiāo)毀時(shí)被 TensorRT 引擎銷(xiāo)毀。

set/getPluginNamespace 該方法用于設(shè)置此創(chuàng)建者實(shí)例所屬的命名空間(默認(rèn)可以是“”)。

9.5. Best Practices For Custom Layers Plugin

調(diào)試自定義層問(wèn)題

必須釋放插件中分配的內(nèi)存以確保沒(méi)有內(nèi)存泄漏。如果在initialize()函數(shù)中獲取資源,則需要在terminate()函數(shù)中釋放它們。應(yīng)該釋放所有其他內(nèi)存分配,最好在插件類(lèi)析構(gòu)函數(shù)中或在destroy()方法中。使用 C++ API 添加自定義層詳細(xì)概述了這一點(diǎn),并提供了一些使用插件時(shí)的最佳實(shí)踐說(shuō)明。

關(guān)于作者

Ken He 是 NVIDIA 企業(yè)級(jí)開(kāi)發(fā)者社區(qū)經(jīng)理 & 高級(jí)講師,擁有多年的 GPU人工智能開(kāi)發(fā)經(jīng)驗(yàn)。自 2017 年加入 NVIDIA 開(kāi)發(fā)者社區(qū)以來(lái),完成過(guò)上百場(chǎng)培訓(xùn),幫助上萬(wàn)個(gè)開(kāi)發(fā)者了解人工智能和 GPU 編程開(kāi)發(fā)。在計(jì)算機(jī)視覺(jué),高性能計(jì)算領(lǐng)域完成過(guò)多個(gè)獨(dú)立項(xiàng)目。并且,在機(jī)器人無(wú)人機(jī)領(lǐng)域,有過(guò)豐富的研發(fā)經(jīng)驗(yàn)。對(duì)于圖像識(shí)別,目標(biāo)的檢測(cè)與跟蹤完成過(guò)多種解決方案。曾經(jīng)參與 GPU 版氣象模式GRAPES,是其主要研發(fā)者。

審核編輯:郭婷

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • NVIDIA
    +關(guān)注

    關(guān)注

    14

    文章

    5026

    瀏覽量

    103273
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1505

    瀏覽量

    62185
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2112

    瀏覽量

    73723
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    think-cell;自定義think-cell(一)

    本章介紹如何自定義 think-cell,即如何更改默認(rèn)顏色和其他默認(rèn)屬性;這是通過(guò) think-cell 的樣式文件完成的,這些文件將在前四個(gè)部分中進(jìn)行討論。 第五部分 C.5 設(shè)置默認(rèn)議程幻燈片
    的頭像 發(fā)表于 01-08 11:31 ?90次閱讀
    think-cell;<b class='flag-5'>自定義</b>think-cell(一)

    Simulink自定義模塊開(kāi)發(fā)教程 Simulink 在控制系統(tǒng)的應(yīng)用

    在控制系統(tǒng)的設(shè)計(jì)和分析,Simulink 提供了一個(gè)強(qiáng)大的工具集,允許工程師通過(guò)圖形化界面快速構(gòu)建和測(cè)試復(fù)雜的系統(tǒng)模型。然而,Simulink 的標(biāo)準(zhǔn)庫(kù)可能不包含所有特定的功能,這時(shí)就需要開(kāi)發(fā)
    的頭像 發(fā)表于 12-12 09:21 ?468次閱讀

    創(chuàng)建自定義的基于閃存的引導(dǎo)加載程序(BSL)

    電子發(fā)燒友網(wǎng)站提供《創(chuàng)建自定義的基于閃存的引導(dǎo)加載程序(BSL).pdf》資料免費(fèi)下載
    發(fā)表于 09-19 10:50 ?0次下載
    創(chuàng)建<b class='flag-5'>自定義</b>的基于閃存的引導(dǎo)加載程序(BSL)

    如何創(chuàng)建TestStand自定義步驟

    在之前的課程簡(jiǎn)單地介紹過(guò)TestStand自帶的一些步驟類(lèi)型,如測(cè)試、消息彈窗、賦值、標(biāo)簽等等,這些簡(jiǎn)單的步驟從TestStand的插入選版中就可以添加到序列。那么在使用如果碰到需要實(shí)現(xiàn)更加靈活、復(fù)雜的功能,使用自帶的一些
    的頭像 發(fā)表于 09-11 14:46 ?1176次閱讀
    如何創(chuàng)建TestStand<b class='flag-5'>自定義</b>步驟

    請(qǐng)問(wèn)multisim怎么自定義元器件?

    為什么我在multisim自定義元器件始終出不了想要的波形效果呢?同一個(gè)pspice模型我同學(xué)之前都定義正確了,現(xiàn)在我想再來(lái)試一下結(jié)果一直失敗
    發(fā)表于 09-10 06:16

    如何自定義內(nèi)存控制器的設(shè)置

    策略都有其特定的使用場(chǎng)景和優(yōu)缺點(diǎn)。以下是一些步驟和建議,用于自定義內(nèi)存控制器的設(shè)置: 1. 選擇合適的內(nèi)存分配策略 heap_1 :最簡(jiǎn)單的內(nèi)存分配策略,但分配的內(nèi)存不允許釋放。適用于那些一旦分配就長(zhǎng)期使用的場(chǎng)景。 heap_2 :支持動(dòng)態(tài)內(nèi)存的申請(qǐng)和釋放,但不支持內(nèi)存碎
    的頭像 發(fā)表于 09-02 14:28 ?525次閱讀

    NVIDIA NeMo加速并簡(jiǎn)化自定義模型開(kāi)發(fā)

    如果企業(yè)希望充分發(fā)揮出 AI 的力量,就需要根據(jù)其行業(yè)需求量身定制的自定義模型
    的頭像 發(fā)表于 07-26 11:17 ?775次閱讀
    NVIDIA NeMo加速并簡(jiǎn)化<b class='flag-5'>自定義</b><b class='flag-5'>模型</b>開(kāi)發(fā)

    NVIDIA AI Foundry 為全球企業(yè)打造自定義 Llama 3.1 生成式 AI 模型

    Foundry 提供從數(shù)據(jù)策管、合成數(shù)據(jù)生成、微調(diào)、檢索、防護(hù)到評(píng)估的全方位生成式 AI 模型服務(wù),以便部署自定義 Llama 3.1 NVIDIA NIM 微服務(wù)和新的 NVIDIA NeMo
    發(fā)表于 07-24 09:39 ?724次閱讀
    NVIDIA AI Foundry 為全球企業(yè)打造<b class='flag-5'>自定義</b> Llama 3.1 生成式 AI <b class='flag-5'>模型</b>

    stm32cubemx如何自定義lwip平臺(tái)?

    有人知道stm32cubemx,如何自定義lwip平臺(tái)。(默認(rèn)只
    發(fā)表于 05-22 07:50

    HarmonyOS開(kāi)發(fā)案例:【 自定義彈窗】

    基于ArkTS的聲明式開(kāi)發(fā)范式實(shí)現(xiàn)了三種不同的彈窗,第一種直接使用公共組件,后兩種使用CustomDialogController實(shí)現(xiàn)自定義彈窗
    的頭像 發(fā)表于 05-16 18:18 ?1393次閱讀
    HarmonyOS開(kāi)發(fā)案例:【 <b class='flag-5'>自定義</b>彈窗】

    AWTK 開(kāi)源串口屏開(kāi)發(fā)(18) - 用 C 語(yǔ)言自定義命令

    如果AWTK-HMI內(nèi)置模型無(wú)法滿(mǎn)足需求,可以使用C語(yǔ)言來(lái)擴(kuò)展默認(rèn)模型。本文通過(guò)一個(gè)簡(jiǎn)單的例子,介紹一下用C語(yǔ)言擴(kuò)展默認(rèn)模型的方法。AWTK
    的頭像 發(fā)表于 05-11 08:24 ?456次閱讀
    AWTK 開(kāi)源串口屏開(kāi)發(fā)(18) - 用 C 語(yǔ)言<b class='flag-5'>自定義</b>命令

    TSMaster 自定義 LIN 調(diào)度表編程指導(dǎo)

    LIN(LocalInterconnectNetwork)協(xié)議調(diào)度表是用于LIN總線通信中的消息調(diào)度的一種機(jī)制,我們收到越來(lái)越多來(lái)自不同用戶(hù)希望能夠通過(guò)接口實(shí)現(xiàn)自定義LIN調(diào)度表的需求。所以在
    的頭像 發(fā)表于 05-11 08:21 ?705次閱讀
    TSMaster <b class='flag-5'>自定義</b> LIN 調(diào)度表編程指導(dǎo)

    HarmonyOS開(kāi)發(fā)案例:【UIAbility和自定義組件生命周期】

    本文檔主要描述了應(yīng)用運(yùn)行過(guò)程UIAbility和自定義組件的生命周期。對(duì)于UIAbility,描述了Create、Foreground、Background、Destroy四種生命周期。對(duì)于頁(yè)面
    的頭像 發(fā)表于 05-10 15:31 ?1287次閱讀
    HarmonyOS開(kāi)發(fā)案例:【UIAbility和<b class='flag-5'>自定義</b>組件生命周期】

    HarmonyOS開(kāi)發(fā)實(shí)例:【自定義Emitter】

    使用[Emitter]實(shí)現(xiàn)事件的訂閱和發(fā)布,使用[自定義彈窗]設(shè)置廣告信息。
    的頭像 發(fā)表于 04-14 11:37 ?1019次閱讀
    HarmonyOS開(kāi)發(fā)實(shí)例:【<b class='flag-5'>自定義</b>Emitter】

    鴻蒙ArkUI實(shí)例:【自定義組件】

    組件是 OpenHarmony 頁(yè)面最小顯示單元,一個(gè)頁(yè)面可由多個(gè)組件組合而成,也可只由一個(gè)組件組合而成,這些組件可以是ArkUI開(kāi)發(fā)框架自帶系統(tǒng)組件,比如?`Text`?、?`Button`?等,也可以是自定義組件,本節(jié)筆者簡(jiǎn)單介紹一下自定義組件的語(yǔ)法規(guī)范。
    的頭像 發(fā)表于 04-08 10:17 ?662次閱讀
    主站蜘蛛池模板: 午夜视频免费在线观看| 免费恐怖片| аⅴ天堂中文在线网| 78摸在线| 九九美剧| 欧美日韩免费大片| 四虎现在的网址入口| 干得好爽| 免费又爽又黄1000禁片| 午夜精品一区二区三区在线视| 国产一区二区三区美女在线观看| 欧美三级中文字幕hd| 色爽女视频| 新激情五月| 一级aaaaaa片毛片在线播放| 欧美亚洲第一区| 午夜三级网站| 亚洲综合图片人成综合网| 中国性猛交xxxxx免费看| 久久国产福利| 免费鲁丝片一级观看| 成年人午夜影院| 亚洲资源在线播放| 永久黄网站色视频免费观看| 一级特黄特黄xxx视频| 特黄特黄特色大片免费观看 | 激情丁香婷婷| 久草老司机| 永久免费看| 伊人操| 奇米影视7777| 久操久操| 在线视频毛片| 亚洲日本在线观看| 日本不卡在线观看免费v| 免费播放一区二区三区| 99久久精品免费看国产| 一区国产传媒国产精品| 日韩三级在线免费观看| 免费日韩毛片| 1000部啪啪勿入十八免费|