Les paramètres du moteur vLLM que nous allons discuter :
- max-num-batched-tokens
- max-model-len
- gpu-memory-utilization
- enable-prefix-caching
- enable-chunked-prefill
- enforce-eager
max-model-len :
TL;DR : correspond à la quantité maximale de tokens utilisés (entrée + sortie)
- Par défaut, la longueur maximale du modèle est égale à la longueur maximale de contexte de votre modèle. Par exemple, pour la modèle llama 3 8B instruct, elle sera de 8192.
- Si vous pouvez déterminer la longueur maximale de contexte pour votre cas d’usage et qu’elle est inférieure à la longueur maximale de contexte de votre modèle, il est préférable de fixer cette valeur pour ce paramètre.
- Cela évitera non seulement les erreurs de mémoire insuffisante lors du chargement ou de l’utilisation du modèle, mais aidera également à configurer d’autres paramètres tels que max-num-batched-tokens et gpu-memory-utilization.
- Cette valeur inclut le nombre de tokens d’entrée et de sortie, donc si dans votre cas, le nombre total de tokens ne dépasse pas, disons 2046, fixez cette valeur pour ce paramètre.
max-num-batched-tokens :
TL;DR : commencez par max-model-len, puis essayez de doubler cette valeur : max-model-len*2, puis *3… jusqu’à ce que vous obtenez une erreur de mémoire insuffisante ou un avertissement de déplacement. Choisissez une valeur qui assure une bonne performance. Si vous utilisez enable-chunked-prefill, commencez par une valeur plus faible, par exemple 128, et essayez différentes valeurs. Voir les explications ci-dessous.
- Notez que ce paramètre désigne le nombre de tokens, et non la taille du batch.
- Chaque requête doit passer par une étape de préremplissage (calcul des valeurs KV pour les tokens d’entrée et leur distribution dans les blocs de cache KV), puis une étape de décodage, où se produit un calcul récursif direct pour générer les tokens un par un.
- Ainsi, la valeur minimale de ce paramètre est égale à la longueur maximale du modèle que vous avez définie pour le préremplissage (sauf si vous utilisez chunked-prefill, plus de détails plus tard).
- Plus il y a de tokens dans le batch, plus il y a de préremplissements, donc le premier token sera généré plus rapidement. Le planificateur vLLM par défaut privilégie les préremplissements.
- Ainsi, un grand batch peut aider à augmenter la capacité de traitement, mais cela ne fonctionne pas dans tous les cas, car la capacité et la latence dépendent également du rapport des ressources de calcul et de la mémoire de la carte graphique (plus de détails dans la section chunked-prefill), et généralement, les préremplissements nécessitent beaucoup de ressources de calcul, donc ils atteignent rapidement la limite maximale de tokens dans le batch que nous pouvons conserver.
- Par conséquent, commencez par la valeur max-model-len, essayez d’augmenter cette valeur en double et observez comment cela affecte la performance jusqu’à ce que vous obteniez une erreur de mémoire insuffisante ou un avertissement de déplacement, comme indiqué ici, pour choisir le bon nombre de tokens dans le batch. Ensuite, essayez d’appliquer cette théorie pour comprendre comment fonctionne votre système.
enable-prefix-caching :
En bref : activez-le sauf si vous utilisez enable-chunked-prefill
- Il cache les valeurs KV calculées pour une utilisation ultérieure, ce qui permet d’économiser beaucoup de temps.
- Si une grande partie de votre requête reste inchangée lors de l’entrée des données, vous remarquerez une amélioration significative de la performance par rapport à une configuration où une très petite partie des tokens de la requête reste inchangée.
- Si le paramètre enable-chunked-prefill est utilisé, ce paramètre n’est pas autorisé (au moment de la publication de cet article).
gpu-memory-utilization :
TL;DR : plus c’est élevé, mieux c’est, sauf si vous obtenez une erreur de mémoire insuffisante. Par défaut 0,9
- Plus la mémoire de la carte graphique est allouée pour stocker le cache KV, meilleure est la performance.
- Réduisez cette valeur si vous rencontrez une erreur de mémoire insuffisante ou si la carte graphique doit exécuter une autre tâche nécessitant de réduire cette valeur.
enforce-eager :
TL;DR : activez cette fonction si la mémoire est insuffisante
- Lors de son utilisation, aucun graphe CUDA n’est créé, ce qui peut affecter la performance, mais permet d’économiser de la mémoire qui aurait été nécessaire pour le graphe.
- Dans certains réglages, le graphe CUDA n’affecte pas significativement la performance, et la mémoire économisée peut être utile pour augmenter les valeurs des paramètres mentionnés ci-dessus, tels que gpu-memory-utilization, max-num-batched-tokens, etc.
enable-chunked-prefill :
TL;DR : essayez d’activer cette fonction et utilisez les tokens batchés, en commençant par une valeur de 128 et en augmentant progressivement. Comparez avec la configuration sans ce paramètre. Voir ci-dessous pour plus de détails.
- L’étape de décodage est moins exigeante en ressources de calcul par rapport au préremplissage (multiplication d’un vecteur par une matrice au lieu de multiplication de matrices), mais plus exigeante en mémoire, car elle doit lire les valeurs KV calculées.
- Si vous souhaitez en savoir plus, consultez cet article et cette page vLLM.
- Comme déjà mentionné, par défaut, le planificateur vLLM privilégie le préremplissage, qui nécessite des ressources de calcul, tandis que pendant le décodage, la mémoire devient un goulot d’étranglement, empêchant pleinement d’utiliser le décodage à faible consommation de ressources mais à forte demande de mémoire, car il faut lire les valeurs KV.
- Chunk prefill divise l’étape de préremplissage en fragments, ce qui permet de réduire le nombre de tokens dans le batch et de former d’abord un batch en regroupant les requêtes de décodage et en ajoutant des requêtes de fragmentation pour le préremplissage, afin d’utiliser efficacement les ressources de la carte graphique, en combinant à la fois la fragmentation coûteuse en ressources pour le préremplissage et un nombre suffisant de requêtes de décodage à faible consommation de ressources mais à forte demande de mémoire.
- Réessayez d’activer cette fonction et utilisez un petit nombre maximal de tokens dans le batch, par exemple 128, et augmentez-le jusqu’à ce que vous obteniez les performances de capacité et de latence souhaitées.
- Cette méthode peut réduire la latence entre les tokens, car le décodage a un avantage en raison de la petite taille du batch (ce qui réduit la charge sur la mémoire), mais peut affecter la capacité de traitement, donc il faut essayer différentes tailles de batch, ainsi que comparer les résultats lorsque ce paramètre n’est pas utilisé.
Exemple :
- Nous allons utiliser les points d’entrée vLLM API au lieu du serveur compatible avec OpenAI
- Pour lancer le serveur sans préremplissage fragmenté, vous pouvez utiliser l’exemple suivant :
python3 -m vllm.entrypoints.api_server — model MaziyarPanahi/Meta-Llama-3–8B-Instruct-GPTQ — gpu-memory-utilization 0.95 — port 5000 — dtype half — enforce-eager — max-model-len 4096 — max-num-batched-tokens 8192 — enable-prefix-caching
- Si la fonction de préremplissage fragmenté est activée, la commande peut ressembler à ceci :
python3 -m vllm.entrypoints.api_server — model MaziyarPanahi/Meta-Llama-3–8B-Instruct-GPTQ — gpu-memory-utilization 0.95 — port 5000 — dtype half — enforce-eager — max-model-len 4096 — max-num-batched-tokens 256 — enable-chunked-prefill
- Envoyez une requête à l’endpoint du serveur mentionné ci-dessus pour vérifier la performance avec différents paramètres.
- Effectuez un benchmark à l’aide des scripts fournis par vLLM, et j’essaierai également d’écrire un script similaire et de le partager ici.