5 points par GN⁺ 2025-06-02 | 1 commentaires | Partager sur WhatsApp
  • Certains modèles d’IA comme DeepSeek-V3 sont peu coûteux et rapides lorsqu’ils sont proposés à grande échelle, mais deviennent lents et coûteux en exécution locale
  • La raison tient à un compromis fondamental entre throughput (débit) et latency (latence), lié à l’efficacité d’utilisation des GPU
  • Quand on augmente la taille de batch, le GPU fonctionne plus efficacement, mais l’utilisateur doit attendre que les tokens s’accumulent, ce qui entraîne une hausse de la latence
  • Les modèles avec une architecture Mixture-of-Experts et un pipeline profond nécessitent des batches importants et donc davantage de latence
  • Dans un environnement local à utilisateur unique, il est difficile de former des batches suffisamment grands, ce qui dégrade les performances et augmente les coûts
  • OpenAI, Anthropic et d’autres obtiennent des réponses rapides grâce à une architecture plus efficace, des stratégies de batching avancées, ou un surdimensionnement important en GPU

Inférence par batch et efficacité des GPU

  • Les GPU sont du matériel optimisé pour les grandes multiplications de matrices (GEMM)
  • Lorsque les tokens de plusieurs utilisateurs sont regroupés en une seule exécution batch sous la forme d’une grande matrice, le faible surcoût d’aller-retour et l’efficacité mémoire améliorent fortement le débit
  • Les serveurs d’inférence empilent les tokens de plusieurs requêtes dans une file d’attente, sélectionnent un batch de taille appropriée, puis exécutent de grandes opérations GEMM
  • Dans ce processus, le serveur doit choisir entre taille de batch (hausse du throughput) et temps d’attente (hausse de la latency)

Pourquoi certains modèles sont optimisés pour de très grands batches

Mixture of Experts (MoE) et batching

  • L’architecture MoE (DeepSeek-V3, GPT-4 présumé) est l’une des principales causes d’une faible efficacité GPU
  • Comme des centaines de blocs « experts » demandent chacun des multiplications de matrices séparées, les petits batches sont peu efficaces, car chaque expert a trop peu de travail
  • Il faut de nombreuses requêtes simultanées pour utiliser correctement tous les experts ; au niveau du service, les grands batches sont donc indispensables
  • Avec une courte attente (fenêtre de 5 ms), les experts restent fréquemment inactifs ; avec une attente longue (fenêtre de 200 ms), on peut maximiser l’efficacité

Problèmes de batch dans les modèles à pipeline profond

  • Les grands transformers de plusieurs centaines de couches sont exécutés en répartissant les couches sur plusieurs GPU (pipelining)
  • Si le nombre de tokens dans un batch est inférieur au nombre d’étapes du pipeline, un phénomène de pipeline bubble se produit, ce qui réduit le débit
  • Pour l’éviter, un grand batch est indispensable, ce qui impose une attente plus longue et allonge le temps de réponse du modèle

Pourquoi ne peut-on pas toujours remplir la file d’attente

  • En théorie, avec beaucoup de trafic simultané, on pourrait penser qu’il est toujours possible de remplir la file et d’éviter les bulles
  • Mais en pratique, à l’étape d’attention des transformers, les dimensions des matrices (longueurs) doivent être identiques pour permettre le batching, ce qui rend difficile un fonctionnement parfait avec une file unique
  • De plus, si l’on sépare les étapes FFN et attention, cela entraîne une forte surcharge mémoire et des inefficacités dans les transferts de données

Résumé et conclusion

  • Le traitement par grands batches est indispensable pour réduire les coûts GPU et augmenter le débit, mais il allonge le temps d’attente côté utilisateur
  • Les modèles à Mixture-of-Experts et à grande architecture pipeline sont, par nature, optimisés pour des environnements de batching à haute efficacité fondés sur l’attente
  • Dans des environnements à faible trafic comme le local, il est impossible de constituer de grands batches optimisés, d’où une chute brutale de l’efficacité GPU et une hausse des coûts d’exécution
  • Si OpenAI, Anthropic et d’autres affichent une bonne réactivité, c’est possiblement parce que
    • (1) leur architecture est plus efficace et n’est pas forcément du MoE
    • (2) ils appliquent des optimisations avancées de batch/pipeline et des techniques d’inférence sophistiquées
    • (3) ils peuvent tout simplement mobiliser bien plus de GPU que nécessaire pour acheter de la vitesse

En plus : différence entre batch de prefill et batch du corps principal

  • Avec les transformers, le prefill d’un prompt utilisateur (entrée longue) peut lui aussi être exécuté en batch, ce qui permet une inférence initiale rapide
  • Mais le batch discuté dans le corps de l’article concerne le compromis débit-latence pendant la véritable phase de génération de tokens sur plusieurs requêtes utilisateurs
  • Le batch de prefill n’a pas de lien direct avec les grands batches simultanés évoqués dans l’article

Remarques

  • Les systèmes d’inférence réels utilisent aussi le continuous batching, qui lance l’exécution dès qu’un batch est prêt
  • Mais la structure fondamentale du compromis throughput-latency reste la même

1 commentaires

 
GN⁺ 2025-06-02
Avis Hacker News
  • Je fais tourner DeepSeek V3 moi-même à la maison, et je trouve que le coût reste raisonnable, avec une vitesse et des performances satisfaisantes. Beaucoup pensent qu’on ne peut pas faire tourner de gros modèles sans GPU, mais d’après mon expérience, un serveur CPU est au contraire plus pratique et consomme moins d’électricité. Mon serveur domestique repose sur une carte Supermicro équipée d’un EPYC série 9004 milieu de gamme et de 384 Go de RAM, pour un coût total d’environ 4 000 dollars. Sans GPU, avec simplement beaucoup de RAM, la consommation peut même être inférieure à celle d’un PC gaming. J’utilise le modèle Unsloth Dynamic GGUF avec environ 270 Go de RAM, et en pratique il prend en charge diverses tâches avec une qualité presque identique à l’original. Je l’utilise habituellement avec un contexte de 16k, extensible à 24k si besoin. La génération de tokens tourne à 9–10 par seconde, et descend à 7 quand le contexte augmente fortement. Il existe aussi des cas où le modèle complet tourne encore plus vite en tokens par seconde sur des environnements à 2 CPU
    • Je me demande à quel point Unsloth Dynamic GGUF se rapproche réellement du modèle d’origine. D’après mon expérience, la différence n’est pas énorme sur des tâches simples, mais elle devient nette sur des tâches complexes ou avec de longs contextes. Il est vrai qu’Unsloth fait un excellent travail, mais il manque des évaluations comparatives directes avec le modèle original non quantifié. La réalité, c’est aussi que beaucoup de particuliers et d’entreprises n’ont pas les moyens de faire tourner le modèle d’origine
    • Je me demande s’il est possible de faire tourner DeepSeek pour de la génération de code avec un outil comme Ollama sur un CPU 40 cœurs et 256 Go de RAM. Je pensais allouer environ 200 Go de mémoire au modèle
    • Mention que le site personnel n’est pas accessible. Je me présente comme Jeff Carr, cofondateur de DigitalOcean, en espérant pouvoir entrer en contact
    • Je pensais qu’un GPU avec mémoire rapide était indispensable, alors je demande s’il est vraiment possible de faire de l’inférence sans GPU, uniquement avec beaucoup de mémoire. Je suis curieux de comprendre comment cela fonctionne avec de la mémoire non unifiée
    • Je suis d’accord sur le fait que DeepSeek V3 est réellement très pratique parmi les modèles open-weight. Beaucoup de tâches n’ont pas besoin d’autant de tokens de reasoning qu’on l’imagine, et l’avantage est qu’il n’y a pas besoin d’attendre. Et si besoin, on peut toujours choisir une option de reasoning plus élevée. Si on ne l’exécute pas soi-même, certains fournisseurs proposent aussi un service avec contexte complet (16k), 80 tps et promesse de ne pas exploiter les données. Bel exemple d’usage d’un home server 9004, configuration impressionnante
  • Ce billet de blog m’a impressionné. Je suis d’accord avec la conclusion (« il faut du batching »), mais je pense que la discussion sur l’inférence des modèles MoE devrait être plus nuancée. Si les gros batchs sont importants, c’est parce que l’inférence LLM n’est pas limitée par la puissance de calcul, mais par le chargement de tous les poids depuis la VRAM. En comparant les TFLOPS et la bande passante mémoire d’un H100, on peut calculer qu’il y a en fait de quoi traiter 300 FLOP par octet. Plus le batch est grand, plus on peut effectuer d’opérations par paramètre chargé, d’où la nécessité de maximiser la taille de batch. C’est pour cela qu’on parle de « roofline model ». À mesure que les modèles grossissent, ils ne tiennent plus entièrement en VRAM, donc il faut les répartir sur plusieurs GPU ou plusieurs nœuds. Mais même avec NVLink ou Infiniband, ce n’est pas aussi rapide qu’un chargement direct depuis la VRAM, ce qui crée un goulot d’étranglement. La force du MoE, c’est l’expert parallelism : on peut placer différents experts en mémoire sur différents nœuds tout en minimisant la communication inter-nœuds. Cela ne fonctionne toutefois que si tous les experts tiennent en VRAM et si l’on a assez de nœuds pour absorber le KV cache et les autres surcoûts. Au final, la taille de batch finit forcément par augmenter, et il faut qu’elle augmente pour que chaque GPU fonctionne efficacement
    • Proposition d’affecter les différents « experts » à un nœud en round-robin, puis de ne regrouper opportunément en batch que les requêtes qui utilisent le même expert. En pratique, cela revient à mettre une file d’attente à la place du batch ; la latence augmente, mais cela reste acceptable dans des environnements comme les workflows de recherche approfondie
    • Quand le modèle ne tient pas sur un seul GPU, il existe des cas réels où l’on fait l’inférence en le découpant par couche, puis en envoyant le petit vecteur au GPU chargé de la couche suivante pour le calcul. Cerebras utiliserait cette approche sur Llama 4 Maverick avec 2 500 tokens par seconde. Le transfert de vecteurs sur le fabric est très rapide, donc le temps d’inactivité est quasiment nul
    • On imagine qu’un fonctionnement serait bien plus rapide si tous les nœuds et tous les poids étaient placés sur des circuits analogiques
    • L’un des arguments pour investir dans AMD serait que le modèle entier peut tenir dans un seul châssis, avec les avantages du map/reduce et une réduction des coûts réseau. Demande d’avis contraires si quelqu’un a des insights
  • Résumé en une ligne pour ceux qui veulent gagner du temps : la réponse, c’est l’inférence par batch. On injecte simultanément les prompts de plusieurs personnes dans une même instance du modèle, ce qui est bien plus efficace qu’un simple time-slicing serré. Cela explique aussi pourquoi, même avec température et seed fixes, les réponses peuvent varier d’une requête à l’autre : on ne contrôle pas avec quels autres prompts le sien est batché. On peut même imaginer que ce phénomène devienne un vecteur d’attaque pour exfiltrer des données
    • L’un des avantages du batch, c’est que lorsqu’on veut évaluer plusieurs fois le même contenu pour vérifier s’il y a réellement des « hallucinations », il suffit de lancer autant d’exécutions que la batch-size. En réalité, la notion de batch a toujours été présente dans les LLM, mais on a tendance à n’en mesurer la vraie valeur qu’avec le temps
    • Je supposais naïvement que les fournisseurs de service faisaient toujours du batching sur tous les modèles, mais je me demande si cela ne s’applique qu’à certaines familles de modèles
    • Je me demande pourquoi le fait d’être batché avec d’autres prompts introduit de la variabilité dans la réponse du modèle
    • Si mon prompt peut être regroupé avec celui d’autres personnes, cela pourrait devenir un vecteur d’attaque très efficace
  • Pour résumer brièvement :<br>- les modèles à forte sparsity ont besoin de gros batchs (beaucoup de requêtes simultanées) pour rendre une multiplication de matrices suffisamment intensive en calcul<br>- pour absorber un batch de cette taille, il faut environ 8 à 16 GPU afin de faire tenir les poids du modèle ainsi que le cache MLA/KV dans la HBM. Mais avec seulement 8 à 16 GPU, le débit total reste faible, donc le temps de réponse individuel devient vraiment lent. Pour obtenir une expérience fluide, il faudrait plutôt quelque chose comme 256 GPU
    • J’exploite un service DeepSeek sur 16 H100 (2 nœuds). On obtient 50 à 80 tokens/s par requête, avec un débit global stable jusqu’à plusieurs milliers de tokens. Le time to first token est lui aussi stable, et l’expérience est plus rapide que n’importe quel service cloud auquel nous avons accès
    • On dit que forte sparsity = besoin de gros batchs, mais j’ai du mal à comprendre le lien. Dire qu’un sparse matmul revient en gros à un matmul avec beaucoup de zéros me semble un peu moqueur
  • Je trouve que c’est une excellente explication du point de vue LLM. Les entreprises hyperscale du LLM analysent probablement les traces de calcul réelles de très près pour repérer les goulots d’étranglement, puis optimisent sérieusement la charge avec des load balancers, des architectures en pipeline, des schedulers, etc. Le « prérequis du batch » pour obtenir de l’efficacité peut en revanche être défavorable aux applications très sécurisées, car l’isolation stricte des requêtes devient extrêmement coûteuse. La virtualisation vGPU de nVidia segmente la mémoire GPU dans le temps, mais semble nécessiter un déchargement/rechargement à chaque context switch, sans déduplication. MIG aussi partitionne la mémoire de façon fixe entre utilisateurs, et la reconfiguration impose un redémarrage du GPU ; je comprends donc très bien qu’on n’ait pas envie de découper un GPU de 96 Go en 4x24 Go. On peut imaginer ajouter une mémoire secondaire (DRAM) sur la carte GPU pour charger divers blocs matriciels plus vite que via PCIe, en utilisant la HBM comme cache.<br>J’apprécie aussi le ton franc du guide pratique de survie en Software Engineering
  • Il reste selon moi une grande marge d’optimisation logicielle pour DeepSeek. En pratique, l’optimisation d’accessibilité vise surtout soit les petits GPU avec énormément de RAM (ktransformers), soit les systèmes avec une énorme quantité de VRAM. Une architecture avec 192 Go de VRAM + le reste en mémoire classique (DGX station, 2xRTX Pro 6000, etc.) pourrait faire tourner DeepSeek 4bit assez vite grâce à la puissance du MoE. Avec DeepSeek, si le prompt n’est pas en chinois, la plupart des experts ne sont pas activés. Le pruning devient donc aussi plus facile. À l’avenir, la direction prise par les systèmes enthusiast semble bien correspondre à ce type d’optimisations logicielles. Sur Reddit, on trouve aussi un exemple d’un système 16x3090 (Pcie 3.0 x4) qui atteint environ 7 tokens/s sous llama.cpp, et comme une 3090 peut à elle seule balayer toute sa VRAM 39 fois par seconde, il doit y avoir d’autres goulots d’étranglement de performance
    • La consommation électrique d’un système 16x3090 monte quand même à 5 kW. À ce niveau-là, en tenant compte de la facture d’électricité, utiliser une API revient moins cher. Et si beaucoup d’experts ne s’activent pas hors prompts en chinois sur DeepSeek, on peut imaginer alléger le modèle et router les tokens vers des experts plus proches
    • Une seule MI300x peut fournir 192 Go de VRAM
  • Je ne suis ni chercheur en ML ni ingénieur, donc à prendre avec précaution. DeepSeek V3/R1 est tellement plus gros que les modèles locaux précédents que son exécution en local est réellement coûteuse. Le nombre de paramètres actifs est inférieur à la taille totale, mais cela ne réduit que les besoins en calcul, pas les besoins mémoire ; en pratique, sans GPU géants, c’est presque inutilisable. On ne peut pas non plus le comparer directement aux principaux modèles frontier propriétaires, puisque leurs tailles et d’autres informations ne sont pas publiques. Rien ne permet de penser qu’ils tourneraient moins cher en local. Au contraire, le MoE offre un compromis plus adapté au local/single-user, car l’inefficacité du batching y est moins pénalisante. Quand on augmente le batch, la latence d’attente par token peut monter à 200 ms, mais en contrepartie les opérations feed-forward (GEMM) grossissent et le calcul devient plus efficace. Je me demande si cela signifie que la matrice elle-même devient plus grande avec le batch. Dans ma représentation mentale, le batching ne sert pas à « augmenter la taille de la matrice d’entrée », mais à « déplacer la contrainte de la bande passante mémoire vers une contrainte de calcul ». Les poids sont déjà découpés couche par couche, chargés de HBM vers SRAM, multipliés morceau par morceau, puis agrégés à la fin. Le batching permet alors de réutiliser les mêmes poids pour plusieurs calculs simultanés, ce qui maximise l’usage des FLOPS. Je ne suis pas certain que la rapidité de réponse des grands modèles comme OpenAI ou Anthropic soit réellement aussi bonne ; le billet ne donne pas de chiffres sur le time to first token, donc j’estime l’argument un peu faible
    • Je suis l’auteur du billet original. Je ne suis pas chercheur en ML, juste un ingénieur très intéressé par le sujet. Dans le scénario local mono-utilisateur du MoE, l’avantage du batching multi-utilisateur disparaît, donc le débit par GPU s’effondre. C’est ce qui se passe sauf si l’on envoie une énorme quantité de requêtes d’inférence en parallèle. Avec le batching, on augmente la taille de la matrice d’entrée : si le batch vaut 1, l’opération porte sur une matrice 1xdim ; si le batch augmente, on passe à batch-size x dim, ce qui fait bondir le taux d’utilisation du GPU et permet de basculer vers une limite calcul. Enfin, à l’usage, on sent bien que DeepSeek est plus lent que d’autres modèles
  • Les mixture of experts nécessitent de gros batchs, mais avec Apple Silicon, cela reste utilisable même avec une batch size de 1. Grâce à la unified memory, de gros modèles peuvent tourner en local, mais la bande passante et les FLOPS restent plus faibles, donc l’exécution est relativement lente. Le MoE a pour caractéristique de réduire la quantité de paramètres traités à chaque étape, donc la charge de calcul est plus faible. De nombreuses personnes rapportent avoir fait tourner DeepSeek sur Mac à une vitesse acceptable en inférence single-batch. Bien sûr, équiper la machine avec assez de mémoire reste coûteux. Si des machines comme les Mac, ou de même architecture, se généralisent, elles formeront un duo idéal avec les modèles MoE. À l’inverse, faire tourner des modèles denses sur un Mac avec grosse mise à niveau mémoire est nettement plus pénible
  • En discutant avec un collègue, j’en suis arrivé à la conclusion que, pour l’assistance à la programmation, les LLM évoluent peut-être dans une direction qui s’éloigne des optimisations vraiment essentielles. Pour des raisons de politique interne, je compare presque tout en local entre des modèles 4–30B et plusieurs séries GPT ; GPT-4o donne en moyenne d’excellents résultats, mais il a aussi tendance à « inventer » certaines parties de sa réponse, ce qui oblige à investir beaucoup de temps dans la vérification et les itérations. Au final, j’en arrive à l’idée que « l’écart n’est pas aussi grand qu’on pourrait le croire au regard de l’effort fourni, face à des modèles locaux à faible nombre de paramètres ». Le problème, c’est que les deux sont vraiment lents, donc il est impossible d’itérer rapidement. Même avec une qualité inférieure, je préfère largement un grand modèle avec grand contexte qui répond instantanément ou presque. J’aimerais qu’on accorde plus d’importance à la « vitesse d’itération perçue » qu’aux seuls gains sur les métriques de qualité
  • Je ne suis pas d’accord avec l’idée que ce soit « lent et cher ». Même sur une ancienne station de travail avec mémoire DDR4, on peut, avec llama.cpp, sortir 3 tokens/s sur un système autour de 1 000 dollars
    • Tu confonds peut-être avec une version distillée plutôt qu’avec le vrai modèle DeepSeek. Sans au moins 192 Go de RAM, il est impossible de faire tourner le vrai modèle