Compartir a través de


Uso de operadores combinados para mejorar el rendimiento

Algunos operadores de DirectML admiten un concepto conocido como fusión. La fusión de operadores es una manera de mejorar el rendimiento mediante la combinación de un operador (normalmente, una función de activación) en un operador diferente para que se ejecuten juntos sin necesidad de un recorrido de ida y vuelta a la memoria.

Cuándo fusionar activaciones

Las activaciones fusionadas son una optimización del rendimiento. Un escenario muy común en muchos modelos de aprendizaje automático (ML) es aplicar una no linealidad (una función de activación) a la salida de cada capa del modelo.

Normalmente, esto requiere un recorrido de ida y vuelta a la memoria de gráficos. Por ejemplo, si a una Convolución le sigue una activación Relu no fusionada, la GPU debe esperar a que los resultados de la Convolución se escriban en la memoria de GPU para poder empezar a calcular la capa de activación Relu. Como la carga de trabajo de proceso de la mayoría de las funciones de activación tiende a ser pequeña, este recorrido de ida y vuelta a la memoria de gráficos puede ser un cuello de botella de rendimiento importante.

La fusión de operadores permite realizar la función de activación (Relu en el ejemplo anterior) como parte del operador anterior (convolución, por ejemplo). Esto permite que la GPU calcule la función de activación sin esperar a que los resultados del operador anterior se escriban en la memoria, lo que mejora el rendimiento.

Dado que las activaciones fusionadas producen el mismo resultado, pero son más rápidas en muchos casos, se recomienda eliminar las capas de activación al fusionarlas en su operador anterior siempre que sea posible.

Cómo fusionar activaciones

Los operadores que admiten activaciones fusionadas tienen un parámetro opcional adicional en su estructura de operador, const DML_OPERATOR_DESC* FusedActivation. Convolución, por ejemplo, admite la activación fusionada y tiene un valor FusedActivation correspondiente en la descripción de su operador (vea 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;
};

Para fusionar una activación, construya un DML_OPERATOR_DESC que describa el tipo de activación que se va a fusionar. Por ejemplo, para fusionar una función Relu, el tipo de operador correcto sería DML_OPERATOR_ACTIVATION_RELU.

Nota:

Al construir la descripción del operador para la función de activación, debe establecer los parámetros InputTensor y OutputTensor para la función de activación en NULL.

Ejemplo

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;

Para obtener un ejemplo completo, el ejemplo DirectMLSuperResolution utiliza activaciones fusionadas para mejorar el rendimiento.

Operadores que admiten la activación fusionada

La lista siguiente se basa en constantes de la enumeración DML_OPERATOR_TYPE. Cada constante de ese tema se vincula a la estructura de descripción adecuada que se va a usar.

  • DML_OPERATOR_NORMALIZACIÓN_POR_LOTES
  • 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

Activaciones soportadas para la fusión

La lista siguiente se basa en constantes de la enumeración DML_OPERATOR_TYPE. Cada constante de ese tema se vincula a la estructura de descripción adecuada que se va a usar.

  • 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
  • OPERADOR_DML_ACTIVACION_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
  • DML_OPERATOR_ELEMENT_WISE_CLIP (solo para Convolution y GEMM)

Los operadores que no estén en esta lista no son compatibles con la activación fusionada.

Consulte también