Intelligence Artificielle
Modèles de conception en Python pour les ingénieurs en IA et LLM : un guide pratique

En tant qu'ingénieurs en IA, il est essentiel de créer un code propre, efficace et maintenable, en particulier lors de la création de systèmes complexes.
Modèles de conception sont des solutions réutilisables aux problèmes courants de conception de logiciels. Ingénieurs en IA et grands modèles de langage (LLM)Les modèles de conception aident à créer des systèmes robustes, évolutifs et maintenables qui gèrent efficacement les flux de travail complexes. Cet article se penche sur les modèles de conception en Python, en se concentrant sur leur pertinence dans l'IA et LLMSystèmes basés sur l'IA. J'expliquerai chaque modèle avec des cas d'utilisation pratiques de l'IA et des exemples de code Python.
Explorons quelques modèles de conception clés particulièrement utiles dans les contextes d’IA et d’apprentissage automatique, ainsi que des exemples Python.
Pourquoi les modèles de conception sont importants pour les ingénieurs en IA
Les systèmes d’IA impliquent souvent :
- Création d'objets complexes (par exemple, chargement de modèles, pipelines de prétraitement de données).
- Gestion des interactions entre les composants (par exemple, inférence de modèle, mises à jour en temps réel).
- Gestion de l'évolutivité, de la maintenabilité et de la flexibilité pour répondre aux exigences changeantes.
Les modèles de conception répondent à ces défis en fournissant une structure claire et en réduisant les correctifs ad hoc. Ils se répartissent en trois catégories principales :
- Modèles de création:Concentrez-vous sur la création d'objets. (Singleton, Factory, Builder)
- Modèles structurels: Organiser les relations entre les objets. (Adaptateur, Décorateur)
- Modèles de comportement: Gérer la communication entre les objets. (Stratégie, Observateur)
1. Modèle Singleton
L'espace Motif singleton garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à cette instance. Cela est particulièrement utile dans les flux de travail d'IA où les ressources partagées, comme les paramètres de configuration, les systèmes de journalisation ou les instances de modèle, doivent être gérées de manière cohérente sans redondance.
Quand utiliser
- Gestion des configurations globales (par exemple, les hyperparamètres du modèle).
- Partage de ressources entre plusieurs threads ou processus (par exemple, Mémoire GPU).
- Assurer un accès cohérent à un seul moteur d'inférence ou connexion à la base de données.
Mise en œuvre
Voici comment implémenter un modèle Singleton en Python pour gérer les configurations d'un modèle d'IA :
class ModelConfig:
"""
A Singleton class for managing global model configurations.
"""
_instance = None # Class variable to store the singleton instance
def __new__(cls, *args, **kwargs):
if not cls._instance:
# Create a new instance if none exists
cls._instance = super().__new__(cls)
cls._instance.settings = {} # Initialize configuration dictionary
return cls._instance
def set(self, key, value):
"""
Set a configuration key-value pair.
"""
self.settings[key] = value
def get(self, key):
"""
Get a configuration value by key.
"""
return self.settings.get(key)
# Usage Example
config1 = ModelConfig()
config1.set("model_name", "GPT-4")
config1.set("batch_size", 32)
# Accessing the same instance
config2 = ModelConfig()
print(config2.get("model_name")) # Output: GPT-4
print(config2.get("batch_size")) # Output: 32
print(config1 is config2) # Output: True (both are the same instance)
Explication
- L'espace
__new__Méthode: Cela garantit qu'une seule instance de la classe est créée. Si une instance existe déjà , elle renvoie l'instance existante. - État partagé: Les deux
config1etconfig2pointer vers la même instance, rendant toutes les configurations globalement accessibles et cohérentes. - Cas d'utilisation de l'IA:Utilisez ce modèle pour gérer les paramètres globaux tels que les chemins d'accès aux ensembles de données, les configurations de journalisation ou les variables d'environnement.
2. Modèle d'usine
L'espace Modèle d'usine fournit un moyen de déléguer la création d'objets à des sous-classes ou à des méthodes d'usine dédiées. Dans les systèmes d'IA, ce modèle est idéal pour créer différents types de modèles, de chargeurs de données ou de pipelines de manière dynamique en fonction du contexte.
Quand utiliser
- Création dynamique de modèles en fonction des entrées utilisateur ou des exigences des tâches.
- Gestion d'une logique de création d'objets complexe (par exemple, pipelines de prétraitement en plusieurs étapes).
- Découplage de l'instanciation d'objet du reste du système pour améliorer la flexibilité.
Mise en œuvre
Construisons une usine pour créer des modèles pour différentes tâches d'IA, comme la classification, le résumé et la traduction de textes :
class BaseModel:
"""
Abstract base class for AI models.
"""
def predict(self, data):
raise NotImplementedError("Subclasses must implement the `predict` method")
class TextClassificationModel(BaseModel):
def predict(self, data):
return f"Classifying text: {data}"
class SummarizationModel(BaseModel):
def predict(self, data):
return f"Summarizing text: {data}"
class TranslationModel(BaseModel):
def predict(self, data):
return f"Translating text: {data}"
class ModelFactory:
"""
Factory class to create AI models dynamically.
"""
@staticmethod
def create_model(task_type):
"""
Factory method to create models based on the task type.
"""
task_mapping = {
"classification": TextClassificationModel,
"summarization": SummarizationModel,
"translation": TranslationModel,
}
model_class = task_mapping.get(task_type)
if not model_class:
raise ValueError(f"Unknown task type: {task_type}")
return model_class()
# Usage Example
task = "classification"
model = ModelFactory.create_model(task)
print(model.predict("AI will transform the world!"))
# Output: Classifying text: AI will transform the world!
Explication
- Classe de base abstraite: Les
BaseModella classe définit l'interface (predict) que toutes les sous-classes doivent implémenter, garantissant ainsi la cohérence. - Logique d'usine: Les
ModelFactorysélectionne dynamiquement la classe appropriée en fonction du type de tâche et crée une instance. - Extensibilité: L'ajout d'un nouveau type de modèle est simple : il suffit d'implémenter une nouvelle sous-classe et de mettre à jour la fabrique.
task_mapping.
Cas d'utilisation de l'IA
Imaginez que vous concevez un système qui sélectionne un LLM différent (par exemple, BERT, GPT ou T5) en fonction de la tâche. Le modèle Factory facilite l'extension du système à mesure que de nouveaux modèles deviennent disponibles sans modifier le code existant.
3. Modèle de constructeur
L'espace Modèle de constructeur sépare la construction d'un objet complexe de sa représentation. Elle est utile lorsqu'un objet nécessite plusieurs étapes d'initialisation ou de configuration.
Quand utiliser
- Création de pipelines en plusieurs étapes (par exemple, prétraitement des données).
- Gestion des configurations pour les expériences ou l'entraînement des modèles.
- Créer des objets nécessitant beaucoup de paramètres, garantissant lisibilité et maintenabilité.
Mise en œuvre
Voici comment utiliser le modèle Builder pour créer un pipeline de prétraitement de données :
class DataPipeline:
"""
Builder class for constructing a data preprocessing pipeline.
"""
def __init__(self):
self.steps = []
def add_step(self, step_function):
"""
Add a preprocessing step to the pipeline.
"""
self.steps.append(step_function)
return self # Return self to enable method chaining
def run(self, data):
"""
Execute all steps in the pipeline.
"""
for step in self.steps:
data = step(data)
return data
# Usage Example
pipeline = DataPipeline()
pipeline.add_step(lambda x: x.strip()) # Step 1: Strip whitespace
pipeline.add_step(lambda x: x.lower()) # Step 2: Convert to lowercase
pipeline.add_step(lambda x: x.replace(".", "")) # Step 3: Remove periods
processed_data = pipeline.run(" Hello World. ")
print(processed_data) # Output: hello world
Explication
- Méthodes enchaînées: Les
add_stepméthode permet le chaînage pour une syntaxe intuitive et compacte lors de la définition des pipelines. - Exécution étape par étape:Le pipeline traite les données en les exécutant à travers chaque étape de manière séquentielle.
- Cas d'utilisation de l'IA:Utilisez le modèle Builder pour créer des pipelines de prétraitement de données complexes et réutilisables ou des configurations de formation de modèles.
4. Modèle de stratégie
L'espace Modèle de stratégie définit une famille d'algorithmes interchangeables, encapsulant chacun d'eux et permettant au comportement de changer de manière dynamique lors de l'exécution. Cela est particulièrement utile dans les systèmes d'IA où le même processus (par exemple, l'inférence ou le traitement de données) peut nécessiter des approches différentes selon le contexte.
Quand utiliser
- Basculer entre différents inférence stratégies (par exemple, traitement par lots ou streaming).
- Appliquer de manière dynamique différentes techniques de traitement de données.
- Choisir des stratégies de gestion des ressources en fonction de l’infrastructure disponible.
Mise en œuvre
Utilisons le modèle de stratégie pour implémenter deux stratégies d’inférence différentes pour un modèle d’IA : l’inférence par lots et l’inférence en streaming.
class InferenceStrategy:
"""
Abstract base class for inference strategies.
"""
def infer(self, model, data):
raise NotImplementedError("Subclasses must implement the `infer` method")
class BatchInference(InferenceStrategy):
"""
Strategy for batch inference.
"""
def infer(self, model, data):
print("Performing batch inference...")
return [model.predict(item) for item in data]
class StreamInference(InferenceStrategy):
"""
Strategy for streaming inference.
"""
def infer(self, model, data):
print("Performing streaming inference...")
results = []
for item in data:
results.append(model.predict(item))
return results
class InferenceContext:
"""
Context class to switch between inference strategies dynamically.
"""
def __init__(self, strategy: InferenceStrategy):
self.strategy = strategy
def set_strategy(self, strategy: InferenceStrategy):
"""
Change the inference strategy dynamically.
"""
self.strategy = strategy
def infer(self, model, data):
"""
Delegate inference to the selected strategy.
"""
return self.strategy.infer(model, data)
# Mock Model Class
class MockModel:
def predict(self, input_data):
return f"Predicted: {input_data}"
# Usage Example
model = MockModel()
data = ["sample1", "sample2", "sample3"]
context = InferenceContext(BatchInference())
print(context.infer(model, data))
# Output:
# Performing batch inference...
# ['Predicted: sample1', 'Predicted: sample2', 'Predicted: sample3']
# Switch to streaming inference
context.set_strategy(StreamInference())
print(context.infer(model, data))
# Output:
# Performing streaming inference...
# ['Predicted: sample1', 'Predicted: sample2', 'Predicted: sample3']
Explication
- Classe de stratégie abstraite: Les
InferenceStrategydéfinit l'interface que toutes les stratégies doivent suivre. - Stratégies concrètes:Chaque stratégie (par exemple,
BatchInference,StreamInference) implémente la logique spécifique à cette approche. - Commutation dynamique: Les
InferenceContextpermet de changer de stratégie lors de l'exécution, offrant une flexibilité pour différents cas d'utilisation.
Quand utiliser
- Basculer entre inférence par lots pour le traitement hors ligne et inférence en continu pour les applications en temps réel.
- Ajustez dynamiquement les techniques d’augmentation ou de prétraitement des données en fonction de la tâche ou du format d’entrée.
5. Modèle d'observateur
L'espace Modèle d'observateur établit une relation un-à -plusieurs entre les objets. Lorsqu'un objet (le sujet) change d'état, tous ses dépendants (observateurs) sont automatiquement avertis. Cela est particulièrement utile dans les systèmes d'IA pour la surveillance en temps réel, la gestion des événements ou la synchronisation des données.
Quand utiliser
- Surveillance des mesures telles que la précision ou la perte pendant la formation du modèle.
- Mises à jour en temps réel des tableaux de bord ou des journaux.
- Gestion des dépendances entre les composants dans des workflows complexes.
Mise en œuvre
Utilisons le modèle Observer pour surveiller les performances d’un modèle d’IA en temps réel.
class Subject:
"""
Base class for subjects being observed.
"""
def __init__(self):
self._observers = []
def attach(self, observer):
"""
Attach an observer to the subject.
"""
self._observers.append(observer)
def detach(self, observer):
"""
Detach an observer from the subject.
"""
self._observers.remove(observer)
def notify(self, data):
"""
Notify all observers of a change in state.
"""
for observer in self._observers:
observer.update(data)
class ModelMonitor(Subject):
"""
Subject that monitors model performance metrics.
"""
def update_metrics(self, metric_name, value):
"""
Simulate updating a performance metric and notifying observers.
"""
print(f"Updated {metric_name}: {value}")
self.notify({metric_name: value})
class Observer:
"""
Base class for observers.
"""
def update(self, data):
raise NotImplementedError("Subclasses must implement the `update` method")
class LoggerObserver(Observer):
"""
Observer to log metrics.
"""
def update(self, data):
print(f"Logging metric: {data}")
class AlertObserver(Observer):
"""
Observer to raise alerts if thresholds are breached.
"""
def __init__(self, threshold):
self.threshold = threshold
def update(self, data):
for metric, value in data.items():
if value > self.threshold:
print(f"ALERT: {metric} exceeded threshold with value {value}")
# Usage Example
monitor = ModelMonitor()
logger = LoggerObserver()
alert = AlertObserver(threshold=90)
monitor.attach(logger)
monitor.attach(alert)
# Simulate metric updates
monitor.update_metrics("accuracy", 85) # Logs the metric
monitor.update_metrics("accuracy", 95) # Logs and triggers alert
- Sujet: Gère une liste d'observateurs et les avertit lorsque son état change. Dans cet exemple, le
ModelMonitorla classe suit les métriques. - Observateurs: Effectuer des actions spécifiques lorsqu'on vous en informe. Par exemple,
LoggerObserverenregistre les métriques, tandis que leAlertObservergénère des alertes si un seuil est dépassé. - Conception découplée:Les observateurs et les sujets sont faiblement couplés, ce qui rend le système modulaire et extensible.
En quoi les modèles de conception diffèrent-ils entre les ingénieurs en IA et les ingénieurs traditionnels ?
Les modèles de conception, bien qu'universellement applicables, présentent des caractéristiques uniques lorsqu'ils sont mis en œuvre dans l'ingénierie de l'IA par rapport à l'ingénierie logicielle traditionnelle. La différence réside dans les défis, les objectifs et les flux de travail intrinsèques aux systèmes d'IA, qui exigent souvent que les modèles soient adaptés ou étendus au-delà de leurs utilisations conventionnelles.
1. Création d'objets : besoins statiques et besoins dynamiques
- Ingénierie traditionnelle:Les modèles de création d'objets tels que Factory ou Singleton sont souvent utilisés pour gérer les configurations, les connexions aux bases de données ou les états des sessions utilisateur. Ceux-ci sont généralement statiques et bien définis lors de la conception du système.
- Ingénierie IA:La création d'objets implique souvent flux de travail dynamiques, Tels que:
- Création de modèles à la volée en fonction des entrées de l'utilisateur ou des exigences du système.
- Chargement de différentes configurations de modèles pour des tâches telles que la traduction, le résumé ou la classification.
- Instanciation de plusieurs pipelines de traitement de données qui varient selon les caractéristiques de l'ensemble de données (par exemple, texte tabulaire ou non structuré).
Exemple:En IA, un modèle d’usine peut générer dynamiquement un modèle d’apprentissage en profondeur en fonction du type de tâche et des contraintes matérielles, tandis que dans les systèmes traditionnels, il peut simplement générer un composant d’interface utilisateur.
2. Contraintes de performance
- Ingénierie traditionnelle:Les modèles de conception sont généralement optimisés pour la latence et le débit dans des applications telles que les serveurs Web, les requêtes de base de données ou le rendu de l'interface utilisateur.
- Ingénierie IA:Les exigences de performance en IA s'étendent à latence d'inférence du modèle, GPU/TPU utilisation, et optimisation de la mémoireLes modèles doivent prendre en compte :
- Mise en cache des résultats intermédiaires pour réduire les calculs redondants (modèles Décorateur ou Proxy).
- Algorithmes de commutation dynamique (modèle de stratégie) pour équilibrer la latence et la précision en fonction de la charge du système ou des contraintes en temps réel.
3. Nature centrée sur les données
- Ingénierie traditionnelle:Les modèles fonctionnent souvent sur des structures d'entrée-sortie fixes (par exemple, des formulaires, des réponses d'API REST).
- Ingénierie IA: Les modèles doivent gérer variabilité des données tant dans sa structure que dans son échelle, y compris :
- Diffusion de données en continu pour les systèmes en temps réel.
- Données multimodales (par exemple, texte, images, vidéos) nécessitant des pipelines avec des étapes de traitement flexibles.
- Ensembles de données à grande échelle nécessitant des pipelines de prétraitement et d'augmentation efficaces, utilisant souvent des modèles tels que Builder ou Pipeline.
4. Expérimentation vs. Stabilité
- Ingénierie traditionnelle:L’accent est mis sur la création de systèmes stables et prévisibles où les modèles garantissent des performances et une fiabilité constantes.
- Ingénierie IA:Les flux de travail de l'IA sont souvent expérimental et impliquent :
- Itérer sur différentes architectures de modèles ou techniques de prétraitement des données.
- Mise à jour dynamique des composants du système (par exemple, recyclage des modèles, échange d'algorithmes).
- Extension des flux de travail existants sans interrompre les pipelines de production, souvent en utilisant des modèles extensibles comme Decorator ou Factory.
Exemple:Une usine d'IA peut non seulement instancier un modèle, mais également attacher des poids préchargés, configurer des optimiseurs et lier des rappels de formation, le tout de manière dynamique.




