Présentation des tensors

Les tensors sont des abstractions mathématiques qui résolvent des problèmes de représentation de données multidimensionnelles. Ils sont utilisés dans les réseaux de neurones, de la simple couche de perception à la GPT-5. Un tensor est essentiellement un tableau plat de nombres avec des métadonnées qui indiquent comment interpréter ces nombres comme un objet multidimensionnel.

Fonctionnement des tensors

Un tensor est représenté par un tableau de nombres et des métadonnées telles que la forme et les étapes. La forme d'un tensor est représentée par un tableau d'entiers qui indiquent le nombre de dimensions et la taille de chaque dimension. Les étapes sont utilisées pour calculer l'indice d'un élément dans le tableau plat. Les tensors peuvent être créés et détruits dynamiquement, et il est possible de partager les mêmes données entre plusieurs tensors.

struct ut_shape {
  int ndim; // nombre de dimensions
  int nelem; // nombre d'éléments
  int shape[4]; // forme du tensor
  int strides[4]; // étapes pour chaque dimension
};

Implémentation des opérations sur les tensors

Les opérations sur les tensors peuvent être implémentées de manière élémentaire, en utilisant des boucles sur tous les éléments pour appliquer une fonction à chaque élément. Les opérations binaires peuvent être implémentées de la même manière, en utilisant deux tensors en entrée. Il est possible d'optimiser la gestion de la mémoire en utilisant un allocateur d'arène ou un pool de mémoire pour éviter les appels fréquents à malloc et free.

static void ew_neg(float* out, const float* a, int n) {
  for (int i = 0; i  n; i++) out[i] = -a[i];
}

Utilisation de l'unité de traitement graphique (GPU)

Il est possible d'utiliser l'unité de traitement graphique (GPU) pour accélérer les opérations sur les tensors. Cela nécessite de gérer la mémoire à la fois sur le CPU et le GPU, de transférer les données de manière efficace et d'apprendre à écrire des noyaux de GPU. Cependant, cela peut être complexe en raison de la variété des accélérateurs de GPU et de la nécessité de gérer la mémoire de manière efficace.