O Direct Machine Learning (DirectML) é uma API de baixo nível para aprendizado de máquina (ML). Ele tem uma interface de programação familiar (C++ nativo, nano COM) e fluxo de trabalho no estilo do DirectX 12. Você pode integrar cargas de trabalho com inferência a aprendizado de máquina em seu jogo, mecanismo, middleware, back-end ou outro aplicativo. O DirectML é compatível com todo o hardware compatível com DirectX 12.
As primitivas de aprendizado de máquina aceleradas por hardware (chamadas de operadores) são os blocos de construção do DirectML. A partir desses blocos de construção, é possível desenvolver técnicas de aprendizado de máquina como upscaling, suavização de borda e transferência de estilo, para citar apenas alguns. Denoising e super-resolução, por exemplo, permitem que você obtenha efeitos raytraced impressionantes com menos raios por pixel.
Você pode integrar cargas de trabalho com inferência a aprendizado de máquina em seu jogo, mecanismo, middleware, back-end ou outro aplicativo. O DirectML tem uma interface de programação e fluxo de trabalho familiar (C++ nativo, nano-COM) no estilo DirectX 12 e com suporte por todo o hardware compatível com DirectX 12. Para aplicativos de exemplo do DirectML, incluindo um exemplo de um aplicativo do DirectML mínimo, confira Aplicativos de exemplo do DirectML.
O DirectML é introduzido no Windows 10, versão 1903 e na versão correspondente do SDK do Windows.
O DirectML é apropriado para o meu projeto?
O DirectML é uma camada de abstração de hardware de baixo nível que permite executar cargas de trabalho de aprendizado de máquina em qualquer GPU compatível com DirectX 12.
Se você precisar otimizar seu desempenho de aprendizado de máquina para cenários em tempo real, de alto desempenho, baixa latência ou com restrição de recursos, o DirectML oferece o máximo de controle e flexibilidade. Você pode usar o DirectML para integrar o aprendizado de máquina diretamente ao seu mecanismo ou pipeline de renderização existente ou para criar suas próprias estruturas de aprendizado de máquina e middleware personalizados no Windows.
Você também pode usar o DirectML indiretamente por meio do ONNX Runtime, que é uma biblioteca de plataforma cruzada que oferece suporte ao formato ONNX padrão aberto para modelos de aprendizado de máquina. O ONNX Runtime pode usar o DirectML como um de seus provedores de execução, juntamente com outros back-ends, como CPU, CUDA ou TensorRT. Dessa forma, você pode aproveitar o desempenho e a compatibilidade do DirectML sem escrever nenhum código DirectML.
Como alternativa, você pode usar a API WinML, que é uma API focada em modelo de nível superior que simplifica o fluxo de trabalho de aprendizado de máquina com seu padrão load-bind-evaluation. WinML também usa o formato ONNX para modelos e pode usar DirectML como seu back-end. WinML é projetado para cenários onde você precisa integrar rápida e facilmente o aprendizado de máquina em seus aplicativos do Windows, sem se preocupar com os detalhes do hardware subjacente ou estrutura.
O que o DirectML faz; e que trabalho devo I fazer como desenvolvedor?
O DirectML executa com eficiência as camadas individuais do modelo de inferência na GPU (ou em núcleos de aceleração de IA, se houver). Cada camada é um operador, e o DirectML fornece uma biblioteca de operadores primitivos de aprendizado de máquina acelerados por hardware de baixo nível. É possível executar operações do DirectML isoladamente ou como um gráfico (confira a seção Fluxos de trabalho baseados em gráfico e camada por camada no DirectML).
Operadores e gráficos aplicam otimizações específicas de hardware e arquitetura. Ao mesmo tempo, como desenvolvedor, você verá uma interface única e independente do fornecedor para executar esses operadores.
A biblioteca de operadores no DirectML fornece todas as operações usuais que você esperaria poder usar em uma carga de trabalho de aprendizado de máquina.
Operadores de ativação, como linear, ReLU, sigmoid, tanh e muito mais.
Operadores elementares, como add, exp, log, max, min, sub e muito mais.
Operadores de convolução, como convolução 2D e 3D, e muito mais.
Operadores de redução, como argmin, average, l2, sum e muito mais.
Operadores de pooling, como average, lp e max.
Operadores de redes neurais (NN), como gemm, gru, lstm e rnn.
E muito mais.
Para obter o máximo desempenho e para que você não pague pelo que não usa, o DirectML coloca o controle em suas mãos como desenvolvedor sobre como sua carga de trabalho de aprendizado de máquina é executada no hardware. Como desenvolvedor, você é responsável por descobrir quais operadores executar e quando executá-los. As tarefas que são deixadas a seu critério incluem: transcrever o modelo; simplificando e otimizando suas camadas; pesos de carregamento; alocação de recursos, vinculação, gerenciamento de memória (assim como no Direct3D 12); e execução do gráfico.
Você retém conhecimento de alto nível dos gráficos (é possível codificar o modelo diretamente ou gravar seu próprio carregador de modelo). É possível criar um modelo de upscaling, por exemplo, usando várias camadas cada um dos operadores de upsample, convolução, normalização e ativação. Com essa familiaridade, programação cuidadosa e gerenciamento de barreiras, é possível extrair o máximo de paralelismo e desempenho do hardware. Se você estiver desenvolvendo um jogo, o gerenciamento cuidadoso de recursos e controle sobre o agendamento permitirá que você intercale cargas de trabalho de aprendizado de máquina e trabalho de renderização tradicional para saturar a GPU.
O que é o fluxo de trabalho DirectML de alto nível?
Veja aqui a receita de alto nível sobre como esperamos que o DirectML seja usado. Nas duas fases principais de inicialização e execução, você registra o trabalho em listas de comandos e, em seguida, executa-os em uma fila.
Inicialização
Crie os recursos do Direct3D 12 - o dispositivo Direct3D 12, a fila de comandos, a lista de comandos e recursos como heaps de descritores.
Como você está fazendo inferência de aprendizado de máquina, bem como de carga de trabalho de renderização, crie os recursos do DirectML (o dispositivo DirectML e instâncias de operador). Se você tiver um modelo de machine learning em que precise executar um tipo específico de convolução com um tamanho específico de tensor de filtro com um tipo de dados específico, esses serão todos os parâmetros no operador de convolução do DirectML.
Os registros do DirectML funcionam em listas de comandos do Direct3D 12. Dessa forma, depois de fazer a inicialização, você registrará a vinculação e inicialização de (por exemplo) o operador de convolução da lista de comandos. Em seguida, feche e execute sua lista de comandos na fila como de costume.
Execução
Carregue os tensores de peso em recursos. Um tensor no DirectML é representado usando um recurso regular do Direct3D 12. Por exemplo, se você quiser carregar dados de peso para a GPU, faça isso da mesma forma que faria com qualquer outro recurso do Direct3D 12 (use um heap de carregamento ou a fila de cópia).
Em seguida, você precisa vincular esses recursos do Direct3D 12 como tensores de entrada e saída. Registre na lista de comandos a vinculação e a execução dos operadores.
Feche e execute a lista de comandos.
Assim como no Direct3D 12, a vida útil e a sincronização dos recursos são de sua responsabilidade. Por exemplo, não libere os objetos DirectML pelo menos até que eles tenham concluído a execução na GPU.
Fluxos de trabalho baseados em gráficos e camada por camada no DirectML
O DirectML oferece suporte a abordagens baseadas em camada por camada e em gráficos para a execução do modelo. Ao executar camada por camada, você é responsável por criar e inicializar cada operador DirectML e gravá-los individualmente para execução em uma lista de comandos. Por outro lado, ao executar um gráfico, você cria um conjunto de nós e bordas em que cada nó representa um operador DirectML e as bordas representam os dados tensoriais que fluem entre nós. Em seguida, o gráfico inteiro é enviado para inicialização ou execução de uma só vez, e o DirectML lida com o agendamento e a gravação dos operadores individuais em seu nome.
Ambos os padrões são úteis em situações diferentes. Uma abordagem camada por camada oferece controle máximo sobre a ordenação e o agendamento do trabalho de computação. Por exemplo, esse nível de controle permite intercalar cargas de trabalho de renderização do Direct3D 12 com seus despachos de computação DirectML. Isso pode ser útil para aproveitar as vantagens da computação assíncrona ou das unidades de sombreador na GPU que, de outra forma, ficariam ociosas. A execução manual camada por camada também fornece ao desenvolvedor controle explícito sobre layouts de tensor e uso de memória.
** No entanto, os modelos de machine learning são frequentemente expressos em termos de gráficos de camadas. Como uma alternativa à abordagem camada por camada, o DirectML permite que você expresse seu modelo como um grafo direcionado acíclico de nós (operadores DirectML) e arestas entre eles (descrições de tensores). Depois de criar uma descrição do gráfico, será possível compilá-lo e enviá-lo de uma só vez para o DirectML para inicialização e execução. Nessa abordagem, o DirectML decide por uma ordem transversal e manipula cada operador individual e o fluxo de dados entre eles em seu nome. Essa geralmente é uma maneira mais simples e natural de expressar um modelo de machine learning e permitir que otimizações específicas da arquitetura sejam aplicadas automaticamente. Além disso, a biblioteca auxiliar do DirectMLX fornece uma sintaxe limpa e conveniente para criar gráficos complexos de operadores DirectML.
Seja qual for a abordagem que preferir, você sempre terá acesso ao mesmo amplo conjunto de operadores DirectML. Isso significa que você nunca precisa sacrificar a funcionalidade, quer prefira o controle refinado da abordagem camada por camada ou a conveniência da abordagem gráfica.
Aborda o que é atualmente compatível com o treinamento de aprendizado de máquina (ML) acelerado por GPU para o Windows Subsystem for Linux (WSL) e Windows nativo.