Exécution de Qwen2.5-7B sur CPU avec vLLM

Présentation

Dans le paysage actuel des LLMs, le coût du matériel GPU demeure un obstacle majeur. L'inférence sur CPU devient une alternative viable et économique grâce aux optimisations des cadriciels de déduction. Ce guide détaille le déploiement du modèle Qwen2.5-7B-Instruct à l'aide du framework vLLM sur un environnement purement CPU, permettant une génération de texte performante et stable.

Cette approche convient particulièrement aux scénarios avec un budget limité, pour le traitement par lots de données ou pour les services légers nécessitant une réduction des coûts d'exploitation à long terme.

  1. Pourquoi ce choix technique ?

1.1 Le modèle Qwen2.5-7B

Ce modèle de la série Qwen présente des améliorations significaitves :

  • Connaissance approfondie issue de l'entraînement sur 18T de tokens.
  • Performance élevée en programmation (HumanEval >85) et en mathématiques (MATH >80).
  • Support de contextes étendus jusqu'à 128K tokens, avec une génération de 8K tokens.
  • Compatibilité multilingue étendue (chinois, anglais et plus de 29 autres langues).

1.2 Le framework vLLM

vLLM est un moteur d'inférence open-source conçu pour les performances. Son architecture de cache optimisée via PagedAttention offre un débit considérablement supérieur. Même sur CPU, il apporte des avantages clés :

  • Gestion mémoire améliorée, réduisant les calculs redondants.
  • Support du déchargement des poids du modèle vers la mémoire CPU (offload), outrepassant les limites de la mémoire vidéo.
  • API simplifiée pour l'intégration dans les systèmes de production.
  1. Préparation de l'environnement

2.1 Configuration système recommandée

Composant Recommandation
Système d'exploitation CentOS 7 / Ubuntu 20.04+
Cœurs CPU ≥16 (Intel Xeon ou AMD EPYC)
Mémoire RAM ≥64 Go (le chargement du modèle requiert ~15 Go)
Espace disque ≥20 Go SSD
Version Python 3.8 – 3.10

Note : Assurez-vous d'avoir suffisamment de mémoire physique. Une partition swap peut être utilisée en secours, mais elle dégradera les performances.

2.2 Téléchargement du modèle

Le modèle peut être obtenu via ModelScope ou Hugging Face.

Via ModelScope :

pip install modelscope-cli -i https://pypi.tuna.tsinghua.edu.cn/simple
git clone https://www.modelscope.cn/qwen/Qwen2.5-7B-Instruct.git

Via Hugging Face :

git lfs install
git clone https://huggingface.co/Qwen/Qwen2.5-7B-Instruct

Conservez le chemin vers le répertoire du modèle téléchargé, il sera nécessaire pour la suite.

  1. Installation et configuration de vLLM

3.1 Créer un environnement virtuel

conda create --name llm-cpu python=3.10
conda activate llm-cpu
pip install torch==2.1.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

L'utilisation de PyTorch pour CPU évite les erreurs liées à CUDA.

3.2 Installer vLLM

pip install vllm -i https://pypi.tuna.tsinghua.edu.cn/simple

Les versions de vLLM ≥ 0.4.0 supportent nativement l'inférence sur CPU.

3.3 Vérification

import vllm
print(vllm.__version__) # Doit afficher >= 0.4.0
  1. Implémentation de l'inférence

4.1 Génération par lots hors-ligne

Pour le traitement simultané de plusieurs requêtes (résumé, génération de contenu).

# -*- coding: utf-8 -*-
from vllm import LLM, SamplingParams

def execute_generation(model_dir, input_texts):
    params = SamplingParams(
        temperature=0.4,
        top_p=0.85,
        max_tokens=1024
    )

    engine = LLM(
        model=model_dir,
        dtype='float16',
        device='cpu',
        swap_space=8,
        cpu_offload_gb=10
    )

    results = engine.generate(input_texts, params)
    return results

if __name__ == "__main__":
    model_location = "/chemin/vers/Qwen2.5-7B-Instruct"

    batch_inputs = [
        "Décrivez les avantages de l'énergie solaire.",
        "Écrivez un algorithme Python pour calculer la suite de Fibonacci.",
        "Quels sont les principes du développement durable ?"
    ]

    generation_results = execute_generation(model_location, batch_inputs)

    for res in generation_results:
        print(f"Entrée: {res.prompt}")
        print(f"Sortie: {res.outputs[0].text}\n")

Paramètres clés :

  • dtype='float16' : Réduit l'empreinte mémoire des poids.
  • device='cpu' : Force l'utilisation du processeur.
  • cpu_offload_gb=10 : Décharge 10 Go de couches du modèle vers la RAM.

4.2 Dialogue structuré avec rôle système

Pour des interactions conversationnelles avec un prompt système définissant un rôle.

# -*- coding: utf-8 -*-
from vllm import LLM, SamplingParams

def converse(model_dir, chat_history):
    params = SamplingParams(
        temperature=0.5,
        top_p=0.9,
        max_tokens=512
    )

    engine = LLM(
        model=model_dir,
        dtype='float16',
        device='cpu',
        cpu_offload_gb=8
    )

    response = engine.chat(
        messages=chat_history,
        sampling_params=params
    )
    return response

if __name__ == "__main__":
    model_location = "/chemin/vers/Qwen2.5-7B-Instruct"

    history = [
        {"role": "system", "content": "Tu es un expert en informatique, répondez de manière concise et précise."},
        {"role": "user", "content": "Expliquez la différence entre la pile et la file."}
    ]

    dialogue_result = converse(model_location, history)
    print("Réponse:", dialogue_result[0].outputs[0].text)
  1. Résolution de problèmes et optimisation

5.1 Gestion de la mémoire insuffisante

Symptôme Solution
Erreur Out-Of-Memory (OOM) Augmenter la valeur de cpu_offload_gb (ex: 12-14).
Lenteur excessive Réduire max_tokens et max_model_len dans la configuration du LLM.
Erreurs au démarrage Ajouter enforce_eager=True pour désactiver certaines optimisations graphiques.

Exemple de configuration économe en mémoire :

llm = LLM(
    model=model_dir,
    dtype='float16',
    device='cpu',
    cpu_offload_gb=14,
    enforce_eager=True,
    max_model_len=2048
)

5.2 Conseils de performance

  • Préférez float16 à bfloat16 pour une compatibilité CPU universelle.
  • Le paramètre tensor_parallel_size doit rester à 1, car la parallélisation tensorielle n'est pas supportée sur CPU.
  • Surveillez l'utilisation mémoire avec des outils comme htop pour dimensionner correctement le swap_space.

5.3 Interprétation des logs

Les messages suivanst peuvent apparaître au démarrage :

INFO ... Using XFormers backend.
WARNING Casting torch.bfloat16 to torch.float16.
INFO Loading model weights took 12.5 GB

Ces logs sont informatifs et indiquent le chargement réussi du modèle et les conversions de précision effectuées.

Conclusion

En combinant le modèle Qwen2.5-7B et le framework vLLM, il est possible de déployer une solution d'inférence LLM performante sur du matériel CPU standard. Cette configuration offre un excellent rapport coût/efficacité, une intégration simplifiée et la capacité de générer des sorties structurées, ouvrant la voie à une démocratisation plus large des modèles de langage.

Les pratiques recommandées incluent l'utilisation du dtype float16 combiné au déchargement mémoire (offloading), le contrôle de la taille des lots (batch size) et une surveillance continue des ressources système.

Étiquettes: Qwen2.5 vLLM inférence-CPU LLM Déploiement

Publié le 5 août à 00h00