Freigeben über


Verwendung von Fused-Operatoren zur Leistungssteigerung

Einige DirectML-Operatoren unterstützen ein Konzept, das als Fusion bezeichnet wird. Die Operator-Fusion ist eine Möglichkeit, die Leistung zu verbessern, indem sie einen Operator (in der Regel eine Aktivierungsfunktion) in einen anderen Operator zusammenführen, sodass sie zusammen ausgeführt werden, ohne dass ein Roundtrip zum Speicher erforderlich ist.

Gründe für die Sicherung von Aktivierungen

Fused-Aktivierungen sind eine Leistungsoptimierung. Ein extrem häufiges Szenario in vielen ML-Modellen (Machine Learning) besteht darin, eine Nichtlinearität (eine Aktivierungsfunktion) auf die Ausgabe jeder Ebene im Modell anzuwenden.

Normalerweise erfordert dies einen Roundtrip zum Grafikspeicher. Wenn z. B. auf eine Convolution eine nicht fused Relu-Aktivierung folgt, muss die GPU warten, bis die Ergebnisse der Convolution in den GPU-Speicher geschrieben werden, bevor sie mit der Berechnung der Relu-Aktivierungsebene beginnen kann. Da die Rechenauslastung der meisten Aktivierungsfunktionen tendenziell klein ist, kann dieser Roundtrip zum Grafikspeicher ein großer Leistungsengpässe sein.

Bei der Operatorfusion wird die Aktivierungsfunktion (im obigen Beispiel Relu) als Teil des vorhergehenden Operators (z. B. Konvolution) ausgeführt. Dadurch kann die GPU die Aktivierungsfunktion berechnen, ohne darauf zu warten, dass die Ergebnisse des vorherigen Operators in den Arbeitsspeicher geschrieben werden. Dies verbessert die Leistung.

Da fused-Aktivierungen dasselbe Ergebnis erzeugen, aber in vielen Fällen schneller sind, empfehlen wir, Aktivierungsschichten zu beseitigen, indem Sie sie nach Möglichkeit in ihren vorhergehenden Operator verschieben.

So werden Aktivierungen gefused

Operatoren, die fused-Aktivierungen unterstützen, weisen einen zusätzlichen optionalen Parameter in der Operatorstruktur auf. const DML_OPERATOR_DESC* FusedActivation Konvolution unterstützt z. B. die Fused-Aktivierung und verfügt in der Operatorbeschreibung über eine entsprechende FusedActivation (siehe DML_CONVOLUTION_OPERATOR_DESC).

struct DML_CONVOLUTION_OPERATOR_DESC
{
    const DML_TENSOR_DESC* InputTensor;
    const DML_TENSOR_DESC* FilterTensor;
    _Maybenull_ const DML_TENSOR_DESC* BiasTensor;
    const DML_TENSOR_DESC* OutputTensor;
    DML_CONVOLUTION_MODE Mode;
    DML_CONVOLUTION_DIRECTION Direction;
    UINT DimensionCount;
    _Field_size_(DimensionCount) const UINT* Strides;
    _Field_size_(DimensionCount) const UINT* Dilations;
    _Field_size_(DimensionCount) const UINT* StartPadding;
    _Field_size_(DimensionCount) const UINT* EndPadding;
    _Field_size_(DimensionCount) const UINT* OutputPadding;
    UINT GroupCount;
    _Maybenull_ const DML_OPERATOR_DESC* FusedActivation;
};

Um eine Aktivierung zu verwenden, erstellen Sie eine DML_OPERATOR_DESC, die den Typ der Aktivierung beschreibt, die gefused werden soll. Um z. B. eine Relu-Funktion zu verwenden, wäre der richtige Operatortyp DML_OPERATOR_ACTIVATION_RELU.

Hinweis

Beim Erstellen der Operatorbeschreibung für die Aktivierungsfunktion müssen Sie die Parameter InputTensor und OutputTensor für die Aktivierungsfunktion auf NULL festlegen.

Beispiel

DML_ACTIVATION_LEAKY_RELU_OPERATOR_DESC leakyReluDesc;
leakyReluDesc.InputTensor = nullptr;
leakyReluDesc.OutputTensor = nullptr;
leakyReluDesc.Alpha = 0.01f;

DML_OPERATOR_DESC activationDesc = { DML_OPERATOR_ACTIVATION_LEAKY_RELU, &leakyReluDesc };

DML_CONVOLUTION_OPERATOR_DESC convDesc;
// ...
convDesc.FusedActivation = &activationDesc;

Für ein vollständiges Beispiel verwendet das DirectMLSuperResolution-Beispiel fused-Aktivierungen, um die Leistung zu verbessern.

Operatoren, die die Fused-Aktivierung unterstützen

Die folgende Liste basiert auf Konstanten aus der DML_OPERATOR_TYPE Enumeration. Jede Konstante in diesem Thema verweist auf die entsprechende Beschreibungsstruktur, die verwendet werden soll.

  • DML_OPERATOR_BATCH_NORMALIZATION
  • DML_OPERATOR_BATCH_NORMALIZATION_TRAINING
  • DML_OPERATOR_CONVOLUTION
  • DML_OPERATOR_ELEMENT_WISE_ADD1
  • DML_OPERATOR_GEMM
  • DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION
  • DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION1

Aktivierungen, die für die Fusion unterstützt werden

Die folgende Liste basiert auf Konstanten aus der DML_OPERATOR_TYPE Enumeration. Jede Konstante in diesem Thema verweist auf die entsprechende Beschreibungsstruktur, die verwendet werden soll.

  • DML_OPERATOR_ELEMENT_WISE_CLIP
  • DML_OPERATOR_ACTIVATION_LINEAR
  • DML_OPERATOR_ACTIVATION_SIGMOID
  • DML_OPERATOR_ACTIVATION_HARD_SIGMOID
  • DML_OPERATOR_ACTIVATION_TANH
  • DML_OPERATOR_ACTIVATION_SCALED_TANH
  • DML_OPERATOR_ACTIVATION_RELU
  • DML_OPERATOR_ACTIVATION_LEAKY_RELU
  • DML_OPERATOR_ACTIVATION_THRESHOLDED_RELU
  • DML_OPERATOR_ACTIVATION_ELU
  • DML_OPERATOR_ACTIVATION_CELU
  • DML_OPERATOR_ACTIVATION_SCALED_ELU
  • DML_OPERATOR_ACTIVATION_SOFTPLUS
  • DML_OPERATOR_ACTIVATION_PARAMETRIC_SOFTPLUS
  • DML_OPERATOR_ACTIVATION_SOFTSIGN
  • DML_OPERATOR_ACTIVATION_IDENTITY
  • DML_OPERATOR_ACTIVATION_SHRINK
  • DML_OPERATOR_ACTIVATION_GELU

Alle Operatoren, die sich nicht in dieser Liste befinden, werden für die Aktivierung von Fused nicht unterstützt.

Weitere Informationen