Salut tout le monde, Nina ici, de retour sur agntbox.com ! Aujourd’hui, je veux parler d’un sujet qui fait du bruit dans mes canaux Slack et qui hante mes sessions de codage tard dans la nuit : les frameworks d’IA. En particulier, je souhaite explorer un coin particulier qui est souvent négligé lorsque tout le monde est occupé à chasser le dernier LLM : les outils autour du fine-tuning et du déploiement pour des modèles plus petits et plus spécialisés.
Nous connaissons tous les grands noms – TensorFlow, PyTorch. Ce sont les géants, les acteurs établis. Et pour de bonnes raisons ! Ils sont incroyablement puissants et polyvalents. Mais soyons honnêtes, parfois, vous n’avez pas besoin d’un cuirassé pour traverser un étang. Parfois, vous avez besoin d’un hors-bord agile, surtout lorsque vous travaillez dans des délais serrés, avec un ensemble de données spécifique et un objectif clair en tête. C’est là que je veux parler de quelque chose avec lequel je me sens assez à l’aise récemment : Hugging Face Optimum pour ONNX Runtime.
Maintenant, avant que vos yeux ne se voilent avec des acronymes, laissez-moi vous expliquer. Hugging Face, bien sûr, est le chouchou du monde NLP, rendant les modèles pré-entraînés accessibles à tous. ONNX (Open Neural Network Exchange) est un standard ouvert pour représenter des modèles d’apprentissage automatique, ce qui signifie essentiellement que vous pouvez convertir des modèles entraînés dans un cadre (comme PyTorch) et les exécuter dans un autre (comme TensorFlow, ou dans notre cas, ONNX Runtime). Et ONNX Runtime ? C’est le moteur d’inférence haute performance de Microsoft.
Alors, que fait Hugging Face Optimum pour ONNX Runtime ? C’est essentiellement un pont, un optimiseurs et un assistant au déploiement réunis en un. Il vous aide à prendre vos modèles Hugging Face, à les optimiser pour l’inférence ONNX Runtime, et souvent, à obtenir un gain de vitesse significatif sans sacrifier beaucoup (ou aucune) précision. Et ça, mes amis, c’est de l’or.
Pourquoi je suis obsédée par Optimum ONNX Runtime en ce moment
Mon voyage dans Optimum ONNX Runtime a commencé, comme la plupart de mes obsessions technologiques, par un problème. Je travaillais sur un projet pour un client qui impliquait le déploiement d’un modèle BERT relativement petit pour la classification de texte sur des tickets de support client. Le modèle était entraîné sur un ensemble de données personnalisé, et bien qu’il performât très bien, le temps d’inférence était juste un peu trop lent pour une interaction client en temps réel. Nous parlions d’environ 150-200ms par inférence sur un GPU puissant, ce qui n’est pas terrible, mais pour des applications en temps réel à fort volume, chaque milliseconde compte.
J’ai essayé tous les suspects habituels : le batching, l’optimisation des pipelines d’entrée, même une quantification de base. Nous avons obtenu quelques améliorations, mais rien de spectaculaire. Ensuite, un collègue a mentionné Optimum, et en particulier, son intégration avec ONNX. J’étais sceptique au début. Une autre couche d’abstraction ? Plus de dépendances ? Mais j’étais désespérée, alors je me suis lancée.
Ce que j’ai trouvé a été un flux de travail étonnamment simple qui a donné des résultats. Nous avons réussi à réduire notre temps d’inférence à environ 50-70ms par inférence sur le même GPU, et nous avons même vu une performance décente sur un CPU pour des tâches moins critiques. C’est un gain de 2-3x, ce qui, dans le monde de l’IA en temps réel, est un énorme succès. Cela signifiait que nous pouvions scaler notre service beaucoup plus efficacement et fournir des réponses plus rapides aux clients, impactant directement leur expérience.
Le problème qu’il résout : Performance et Portabilité
Soyons honnêtes, déployer des modèles d’IA peut être un réel casse-tête. Vous entraînez un magnifique modèle dans PyTorch, et ensuite, vous devez comprendre comment le faire fonctionner efficacement en production. Parfois, vous êtes bloqué avec un matériel spécifique, ou vous devez déployer sur un appareil edge avec des ressources limitées. C’est là qu’ONNX entre en jeu. Il fournit un format commun, découplant votre modèle du cadre d’entraînement.
Optimum va un pas plus loin. Ce n’est pas seulement une question de conversion en ONNX ; il s’agit d’optimiser ce modèle ONNX. Il peut appliquer des techniques telles que l’optimisation de graphes, la fusion d’opérateurs, et même quantifier votre modèle pour réduire sa taille et accélérer l’inférence, souvent avec un impact minimal sur la précision. C’est particulièrement utile pour les modèles plus petits ou lorsque vous êtes contraint par la mémoire ou le calcul sur votre cible de déploiement.
Le cas d’utilisation de mon client était un exemple parfait. Nous avions un modèle PyTorch, mais nous voulions le déployer sur une instance cloud avec des GPU NVIDIA, et nous avions besoin d’un débit maximal. Optimum ONNX Runtime nous a permis d’exporter le modèle, d’appliquer des optimisations spécifiques pour notre matériel cible, et de le faire fonctionner à merveille.
Commencer avec Optimum ONNX Runtime : Un Exemple Pratique
Passons en revue un exemple de base de la façon dont vous pourriez utiliser Optimum pour exporter et optimiser un modèle Hugging Face pour ONNX Runtime. Pour cela, nous utiliserons un modèle simple d’analyse de sentiments.
Tout d’abord, vous devrez installer les bibliothèques nécessaires :
pip install transformers optimum[onnxruntime] onnx
Maintenant, écrivons un peu de code Python pour exporter un modèle d’analyse de sentiments pré-entraîné.
Exemple 1 : Exportation d’un Modèle d’Analyse de Sentiments
Ici, nous prenons un modèle standard `distilbert-base-uncased-finetuned-sst-2-english` et l’exportons au format ONNX en utilisant Optimum.
from transformers import pipeline
from optimum.onnxruntime import ORTModelForSequenceClassification
from transformers import AutoTokenizer
model_id = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(model_id)
# Exportez le modèle au format ONNX
# Le `save_directory` est l'endroit où votre modèle ONNX et le tokenizer seront enregistrés.
# `opset` spécifie la version de l'ensemble d'opérateurs ONNX.
# `input_names` est important pour définir les entrées de votre graphe ONNX.
onnx_path = "./onnx_sentiment_model/"
ort_model = ORTModelForSequenceClassification.from_pretrained(model_id, from_transformers=True)
ort_model.save_pretrained(onnx_path)
tokenizer.save_pretrained(onnx_path)
print(f"Modèle et tokenizer exportés vers {onnx_path}")
Après avoir exécuté cela, vous aurez un répertoire nommé `onnx_sentiment_model` contenant votre fichier `model.onnx` et les fichiers du tokenizer. Ce fichier `model.onnx` est la version optimisée prête pour ONNX Runtime.
Exemple 2 : Exécution de l’Inférence avec le Modèle ONNX
Maintenant, chargeons ce modèle exporté et exécutons quelques inférences avec. Remarquez comment nous chargeons `ORTModelForSequenceClassification` directement depuis le `onnx_path` où nous l’avons enregistré.
from optimum.onnxruntime import ORTModelForSequenceClassification
from transformers import AutoTokenizer, pipeline
import time
onnx_path = "./onnx_sentiment_model/"
# Charger le modèle ONNX et le tokenizer
ort_model = ORTModelForSequenceClassification.from_pretrained(onnx_path)
tokenizer = AutoTokenizer.from_pretrained(onnx_path)
# Créer un pipeline pour une inférence facile
onnx_pipeline = pipeline(
"sentiment-analysis",
model=ort_model,
tokenizer=tokenizer,
accelerator="ort" # Cela indique au pipeline d'utiliser ONNX Runtime
)
text_samples = [
"J'adore ce produit, c'est incroyable !",
"Ce film était juste correct, un peu ennuyeux.",
"Je déteste absolument attendre dans de longues files.",
"Le service était incroyablement rapide et efficace."
]
print("\n--- Exécution de l'Inference avec le Modèle ONNX ---")
start_time = time.time()
results = onnx_pipeline(text_samples)
end_time = time.time()
for i, res in enumerate(results):
print(f"Texte : '{text_samples[i]}' -> Label : {res['label']}, Score : {res['score']:.4f}")
print(f"Temps d'inférence pour {len(text_samples)} échantillons : {(end_time - start_time):.4f} secondes")
Lorsque vous exécutez cela, vous verrez les prédictions de sentiments. Plus important encore, si vous deviez comparer le temps d’inférence avec le modèle PyTorch original sur le même matériel, vous constateriez probablement un gain de vitesse appréciable, surtout pour des lots plus importants ou des modèles plus complexes. Le paramètre `accelerator=”ort”` dans le pipeline est un petit mais puissant drapeau qui indique à Hugging Face d’utiliser ONNX Runtime pour l’inférence, c’est là que la magie opère.
Exemple 3 : Contrôle des Caractéristiques d’Optimisation (Optionnel mais Puissant)
Optimum permet un contrôle précis sur le processus d’optimisation. Par exemple, vous pouvez spécifier le niveau d’optimisation ou même choisir des optimisations de graphe spécifiques. Cela peut être crucial lorsque vous essayez d’extraire chaque goutte de performance de votre modèle ou lorsque vous devez faire des compromis entre vitesse et précision (par exemple, avec la quantification).
from optimum.onnxruntime import ORTModelForSequenceClassification, ORTConfig
from transformers import AutoTokenizer
from optimum.exporters.tasks import TasksManager
from optimum.onnxruntime.configuration import AutoOptimizationConfig
model_id = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(model_id)
# Définir la configuration d'optimisation
# Ici, nous utilisons l'optimisation par défaut mais vous pouvez personnaliser davantage
# Par exemple, pour appliquer la quantification : `optimization_config = AutoOptimizationConfig.O2()`
optimization_config = AutoOptimizationConfig.O1() # O1 pour une optimisation de base, O2 pour une optimisation plus agressive, O3 pour une optimisation complète
# Exporter le modèle avec la configuration d'optimisation explicite
onnx_path_optimized = "./onnx_sentiment_model_optimized/"
task = TasksManager.get_task_from_model_or_model_name(model_id)
# Vous devrez peut-être ajuster le paramètre `feature` en fonction de la tâche de votre modèle
# Pour la classification de séquences, c'est souvent 'sequence-classification'
ORTModelForSequenceClassification.from_pretrained(
model_id,
from_transformers=True,
export_feature=task.feature,
optimization_config=optimization_config,
).save_pretrained(onnx_path_optimized)
tokenizer.save_pretrained(onnx_path_optimized)
print(f"Modèle et tokenizer optimisés exportés vers {onnx_path_optimized}")
L’ `AutoOptimizationConfig` est votre ami ici. `O1` fournit des optimisations de graphe de base, `O2` ajoute des fusions et des suppressions de nœuds plus agressives, et `O3` inclut toutes les optimisations disponibles, y compris la quantification si applicable. Choisir le bon niveau dépend de vos besoins spécifiques et du matériel que vous ciblez. Pour mon client, nous avons expérimenté entre `O1` et `O2` pour trouver le bon équilibre, en privilégiant `O2` pour le meilleur compromis entre vitesse et précision.
Mes Retours et Ce Qui Suit
Mon expérience avec Hugging Face Optimum pour ONNX Runtime a été extrêmement positive. Ce n’est pas une solution miracle pour chaque déploiement d’IA, mais cela répond à un besoin très commun et critique : faire fonctionner vos modèles plus rapidement et plus efficacement en production, surtout lorsque vous travaillez avec des modèles Hugging Face.
- Amélioration des Performances : Le principal avantage est la réduction significative du temps d’inférence. Pour les applications en temps réel, cela peut représenter un changement important, améliorant l’expérience utilisateur et réduisant les coûts d’infrastructure.
- Portabilité : En convertissant en ONNX, vos modèles deviennent plus portables, exécutables sur différents matériels et systèmes d’exploitation sans être liés à un cadre d’apprentissage profond spécifique.
- Facilité d’Utilisation : L’intégration avec la bibliothèque `transformers` de Hugging Face est remarquablement fluide. Si vous êtes déjà familier avec Hugging Face, la courbe d’apprentissage pour Optimum est assez douce.
- Efficacité des Ressources : Les modèles optimisés nécessitent souvent moins de mémoire et de cycles CPU/GPU, ce qui est crucial pour les déploiements en edge ou les environnements cloud sensibles aux coûts.
Une chose que j’ai apprise est qu’il vaut la peine d’expérimenter avec différents niveaux et configurations d’optimisation. Ne vous contentez pas des réglages par défaut. Testez `O1`, `O2`, et même `O3` (avec quantification si votre cas d’utilisation le permet) et évaluez les résultats sur votre matériel cible réel. Les gains peuvent être surprenants !
En regardant vers l’avenir, je crois que des outils comme Hugging Face Optimum vont devenir encore plus essentiels. Alors que les modèles d’IA se multiplient et s’intègrent dans des environnements de déploiement plus diversifiés, la capacité d’optimiser et de rationaliser leur inférence sera primordiale. Je suis particulièrement enthousiaste de voir comment Optimum évolue avec de nouveaux accélérateurs matériels et des techniques de quantification plus avancées.
Conseils Pratiques pour Votre Prochain Projet IA :
- Évaluez Vos Besoins en Inférence : Avant d’explorer les optimisations, définissez clairement vos exigences de performance. Quelle est une latence acceptable ? Quel est votre objectif de débit ?
- Considérez ONNX Tôt : Si vous utilisez des modèles Hugging Face et que la performance est une préoccupation, commencez à réfléchir à l’exportation et à l’optimisation ONNX dès votre cycle de développement, et pas seulement au moment du déploiement.
- Mesurez, Mesurez, Mesurez : Mesurez toujours l’amélioration réelle de la performance (ou la dégradation) après avoir appliqué des optimisations. Ne vous fiez pas uniquement aux gains théoriques. Utilisez des données réelles et du matériel réel.
- Expérimentez avec les Niveaux d’Optimisation : Ne vous contentez pas des réglages par défaut. Jouez avec `AutoOptimizationConfig.O1()`, `O2()`, et `O3()` pour trouver le meilleur équilibre pour votre modèle et votre cas d’utilisation.
- Restez Informé : La bibliothèque Hugging Face Optimum est en développement actif. Gardez un œil sur leurs sorties et leur documentation pour de nouvelles fonctionnalités et améliorations de performances.
C’est tout pour moi cette semaine ! Si vous avez eu des difficultés avec les performances de déploiement de modèle, essayez Hugging Face Optimum pour ONNX Runtime. Cela pourrait être le propulseur dont vous avez besoin. Faites-moi savoir dans les commentaires si vous l’avez utilisé ou si vous avez d’autres outils de prédilection pour l’optimisation de modèles. Bonne inférence !
🕒 Published:
Related Articles
- Je découvre le SDK Python de Google Gemini au-delà de Chat.
- Assistentes de codificação IA: Minha exploração pessoal no maravilhoso mundo das ferramentas de desenvolvimento
- Confie em Nenhum Scanner: Quando Suas Ferramentas de Segurança se Voltaram Contra Você
- Herramientas de Análisis de Registros para Depuración de Agentes