Dweve

Por dentro do Core: mais de 2 900 operações em 12 backends

Centenas de milhares de kernels afinados manualmente. Mais de 2 900 operações em 76 categorias. 25 formatos numéricos e 12 backends. Conheça o Core, a base...

Por dentro do Core: mais de 2 900 operações em 12 backends

O que nos diz o número de operações

A multiplicação de matrizes parece uma tarefa única. A sua implementação depende do significado dos valores, da forma como são armazenados, de como se acumulam os resultados parciais e do hardware que executa o trabalho. Uma matriz binária compactada e uma matriz de vírgula flutuante podem partilhar uma operação abstrata, mas exigir regras numéricas e código diferentes.

O Core é a base de computação da Dweve para treino e inferência. O catálogo público abrange centenas de milhares de kernels afinados manualmente, em mais de 2 900 operações, 76 categorias, 25 formatos numéricos e 12 backends. Estes números descrevem partes diferentes do sistema. Uma operação identifica o cálculo. Um formato numérico define a representação. Um backend identifica o destino de execução. Um kernel implementa uma combinação específica destas escolhas.

É mais importante perceber esta distinção do que tratar o catálogo como um único total de funcionalidades. Quem desenvolve precisa de saber se existe a combinação necessária e que contrato segue.

Mais de 2 900 operações em 76 categorias; 25 formatos numéricos; 12 backends. Centenas de milhares de kernels afinados manualmente implementam as opções de execução disponíveis.

O cálculo e a representação fazem parte do mesmo problema

Consideremos uma redução: combinar um conjunto de valores para obter um resultado. A palavra «soma» deixa várias perguntas sem resposta. As entradas são inteiros com sinal, valores de vírgula fixa ou de vírgula flutuante? Que representação guarda o resultado acumulado? O que acontece quando essa representação já não comporta o valor seguinte?

O Core associa estas escolhas à operação. O contrato de execução inclui o tipo de dados, a largura, o empacotamento, o acumulador, o backend, o conjunto de instruções, a política de encaminhamento e o modo de determinismo. Alterar qualquer um destes elementos pode mudar o significado do cálculo, mesmo que a operação mantenha o mesmo nome.

Os 25 formatos numéricos incluem famílias binárias, ternárias, inteiras, de vírgula fixa, adaptativas e de vírgula flutuante. O nome da família é apenas o ponto de partida para descrever a aritmética. A largura, o sinal, a escala e a disposição em memória também contam. Por isso, o catálogo deve ser lido como um conjunto de combinações disponíveis, e não como uma promessa de que todas as operações existem em todos os formatos imagináveis e em todos os destinos.

É também por isso que um formato de intercâmbio não responde a todas as questões de execução. O ONNX descreve um grafo de computação com entradas, saídas e operadores tipados. Assim, os sistemas partilham uma descrição do modelo; ainda cabe ao runtime implementar esses operadores. A documentação dos conceitos do ONNX explica a diferença entre a representação do grafo e a sua execução.

Leia uma opção de execução considerando a operação, a representação, o acumulador, o backend e as regras de repetição. Este diagrama mostra um exemplo representativo, não uma matriz de cobertura.

12 backends, opções de execução explícitas

Os 12 backends do Core abrangem execução escalar, conjuntos de instruções de CPU e destinos para GPU e portáteis. A lista pública inclui Scalar, SSE2, AVX2, AVX-512, NEON, SVE2, CUDA, ROCm, Metal, Vulkan, WebGPU e WASM. São caminhos de execução dentro do Core, não versões diferentes de um modelo.

O encaminhamento seleciona no anfitrião atual uma implementação disponível para a operação e o respetivo contrato de execução. O caminho selecionado fica registado com a célula de execução, o anfitrião e o motivo da escolha. Assim, é possível inspecionar as opções efetivamente tomadas numa execução.

A portabilidade tem limites. A documentação de WebAssembly, por exemplo, distingue um formato binário portátil das API disponibilizadas pelo ambiente anfitrião. A execução num browser e fora dele pode expor interfaces diferentes. A documentação de portabilidade de WebAssembly ajuda a compreender esta distinção. O nome de um backend, por si só, não explica o ambiente operacional de uma aplicação.

O lugar do Core na Dweve

A biblioteca de primitivas é utilizada pelo Core para operações fundamentais. O Core integra essas bases no sistema de computação. O Loom assenta no Core e recorre à biblioteca de solvers para o seu trabalho de raciocínio. Cada componente tem, assim, uma responsabilidade clara: as primitivas fornecem operações básicas, o Core executa cálculos e o Loom constrói o raciocínio sobre essa base.

A Dweve é o serviço. O Fabric é a sua API e portal, através dos quais pessoas e aplicações acedem ao serviço. O Fabric não substitui a função de computação do Core nem a função de raciocínio do Loom. A interface e os sistemas que lhe dão suporte têm propósitos diferentes.

A biblioteca de primitivas é utilizada pelo Core. O Loom assenta no Core e utiliza a biblioteca de solvers. O Fabric é a API e o portal do serviço Dweve.

Comece pela execução de que precisa

Ao avaliar um sistema de computação, comece por definir um cálculo concreto e a representação de que necessita. Depois, pergunte que backend o vai executar, que regras se aplicam ao acumulador e ao empacotamento e que contrato de repetição está declarado. Estas perguntas tornam o catálogo útil para uma equipa.

Os números públicos do Core descrevem a amplitude do catálogo. O contrato de execução explica como o interpretar. Ambos fazem parte da mesma conversa: que trabalho o sistema abrange e o que significa uma implementação específica quando é utilizada.