La localité NUMA affecte l’inférence lorsque les threads CPU, la mémoire de l’hôte et les GPU communiquent entre des domaines non locaux au lieu de rester à proximité de leur chemin PCIe.
Un serveur d’IA domestique à double socket peut exposer deux grands pools de RAM et plusieurs GPU comme une seule machine, mais les accès ne sont pas uniformes. Un processus planifié sur un socket peut préparer des tenseurs dans la mémoire rattachée à l’autre avant de les transférer vers un GPU situé sous une autre racine PCIe. L’impact dépend du placement du modèle, de la mise en mémoire tampon côté hôte, du trafic du parallélisme tensoriel, de la topologie des interconnexions, du traitement par lots et du fait que la charge soit limitée par le calcul ou les transferts.
NUMA transforme un pool mémoire unique en accès dépendants de la distance
Dans un système NUMA, chaque socket CPU ou domaine de calcul dispose d’une mémoire plus proche de certains cœurs que d’autres. Les logiciels peuvent adresser la capacité combinée, mais un accès distant doit traverser une interconnexion. Ce chemin présente généralement une latence et une bande passante disponible différentes de celles de la mémoire locale.
La topologie NUMA affecte également les transferts DMA des GPU, car les pages de l’hôte peuvent se trouver loin du complexe racine PCIe du GPU. La planification du CPU et le placement de la mémoire sont deux décisions distinctes, et une machine virtuelle peut ne pas voir automatiquement la topologie de l’hôte nécessaire pour les aligner.
L’effet est limité lorsque le trafic mémoire de l’hôte est faible par rapport aux calculs effectués par le GPU. Il s’accentue lors du chargement du modèle, du déport vers le CPU, de la tokenisation, des copies vers des tampons verrouillés en mémoire, des synchronisations fréquentes ou des charges qui dépassent la VRAM. La capacité NUMA ne garantit pas la localité NUMA.
Le placement des GPU ajoute une seconde topologie au chemin du modèle
Plusieurs GPU peuvent être reliés à différents sockets CPU, commutateurs PCIe ou partitions intégrées au boîtier. Un tenseur transféré entre deux accélérateurs peut emprunter un chemin pair à pair direct, une liaison GPU dédiée, un commutateur PCIe ou un itinéraire passant par la mémoire de l’hôte et un saut inter-socket. Ces chemins ne sont pas équivalents.
Des recherches sur les GPU à partitions multiples montrent que les accès non uniformes et les communications inter-partitions peuvent amplifier la contention et la latence des noyaux. Les stratégies de placement diffèrent selon que les données sont partagées globalement, partiellement ou uniquement au sein d’un groupe de travail ou d’une partition.
Le partitionnement du modèle doit suivre la topologie qui transporte le plus de trafic répétitif. Des couches adjacentes ou l’état d’attention placés de part et d’autre d’une frontière lente peuvent communiquer à chaque token, tandis qu’une séparation moins bavarde peut tolérer la distance. Compter les GPU sans cartographier leurs liaisons masque la relation pertinente.
Le parallélisme tensoriel peut faire de la localité un coût par token
L’inférence en parallélisme tensoriel répartit les opérations d’une couche entre plusieurs GPU et combine les résultats partiels au moyen d’opérations collectives. Cette approche permet de prendre en charge des modèles plus volumineux et d’exploiter davantage de calcul, mais les communications se répètent sur de nombreuses couches et pour de nombreux tokens. Un chemin distant devient donc un coût récurrent plutôt qu’une simple pénalité lors du chargement du modèle.
Le parallélisme tensoriel fonctionne au mieux lorsque les liaisons entre accélérateurs et le placement des fragments prennent en charge les synchronisations requises. Ajouter un GPU au-delà d’une frontière NUMA ou PCIe moins performante peut accroître la capacité tout en offrant un gain de débit inférieur à ce que laisserait penser le nombre de périphériques.
Le parallélisme des données ou le placement au niveau des requêtes peut être préférable lorsque les modèles tiennent individuellement et que les requêtes peuvent rester locales. Le parallélisme tensoriel devient nécessaire lorsqu’un modèle ne tient pas sur un seul périphérique, mais sa taille de lot, la fréquence des opérations collectives et l’interconnexion déterminent si la capacité supplémentaire améliore également la vitesse.
Le first-touch et la migration des threads peuvent compromettre une disposition prévue
Les systèmes d’exploitation placent souvent la mémoire à proximité du thread qui accède le premier à chaque page. Si l’initialisation s’exécute sur un socket et que les workers d’inférence s’exécutent ensuite sur un autre, les pages peuvent rester distantes. La migration par l’ordonnanceur peut également déplacer les threads de préparation CPU loin de la mémoire et du GPU qu’ils étaient censés servir.
La prise en compte de NUMA relie les banques de mémoire locales aux sockets CPU qui y accèdent le plus efficacement. Lier les threads CPU sans contrôler l’allocation mémoire, ou lier la mémoire sans aligner le GPU, ne résout qu’une partie du chemin.
Une disposition stable peut nécessiter une affinité CPU, une politique mémoire, l’affectation des périphériques et un lancement des processus tenant compte de la topologie. Les conteneurs et les machines virtuelles ajoutent une couche de mappage supplémentaire. L’objectif n’est pas de tout lier aveuglément, mais de maintenir les chemins à fort volume entre producteurs, tampons et consommateurs dans le domaine pratique le plus proche.
La localité compte surtout à certaines phases de l’inférence
Le chargement du modèle met l’accent sur les transferts du stockage vers l’hôte et de l’hôte vers le GPU. Le préremplissage traite de nombreux tokens d’invite et peut utiliser des opérations matricielles de plus grande taille, tandis que le décodage progresse à plusieurs reprises d’un ou de quelques tokens et peut devenir sensible à la bande passante mémoire, aux synchronisations et à la surcharge de lancement des noyaux. Les effets de NUMA peuvent donc varier au cours d’une même requête.
Les effets NUMA des GPU montrent qu’une planification tenant compte du placement peut améliorer l’attention en alignant le traitement sur les domaines mémoire et la réutilisation du cache. La conclusion est plus limitée qu’un gain universel : l’amélioration apparaît lorsque le schéma de partage du noyau correspond au mappage tenant compte de la topologie.
Un benchmark qui ne fournit que le nombre moyen de tokens par seconde peut masquer une latence élevée du premier token ou une mauvaise montée en charge pour une taille de lot donnée. Enregistrez séparément le temps de chargement, le débit de préremplissage, la latence inter-tokens, le trafic des liaisons GPU, les accès NUMA distants et la bande passante mémoire du CPU.
Centre Tech & IA
Plus à lire

Pourquoi l’architecture d’un serveur personnel Jellyfin évolue à mesure que vous ajoutez des services
Un boîtier Jellyfin devient une pile de services à mesure que l’on ajoute des applications : la gestion du processeur, du stockage, du réseau,...

Comment mesurer les performances de Jellyfin sans confondre cache et capacité
Un benchmark Jellyfin fiable distingue les états à froid et à chaud afin que les métadonnées mises en cache ou les pages du système...

De quelle marge de manœuvre l’iGPU de Jellyfin multi-utilisateur a-t-il besoin ?
La marge disponible de l’iGPU pour Jellyfin dépend de la charge de travail : prévoyez une marge au-delà du scénario de transcodage simultané reproductible...

