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 gráfica. Por ejemplo, si una Convolución va seguida de 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. Dado que 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 gráfica 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 fusionándolas 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 una FusedActivation en su descripción del operador (ver 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, la muestra 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_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
Activaciones que se admiten 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_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
Los operadores que no están en esta lista no se admiten para la activación fusionada.
Consulte también
- Inteligencia artificial de Windows
- Ejemplo directMLSuperResolution
- DML_CONVOLUTION_OPERATOR_DESC