Inteligența artificială
Modele de proiectare în Python pentru inginerii AI și LLM: un ghid practic

În calitate de ingineri AI, crearea unui cod curat, eficient și care poate fi întreținut este esențială, mai ales atunci când construiești sisteme complexe.
Modele de design sunt soluții reutilizabile la probleme comune în proiectarea software-ului. Pentru Ingineri AI și modele de limbaje mari (LLM)., modelele de proiectare ajută la construirea unor sisteme robuste, scalabile și care pot fi întreținute, care gestionează eficient fluxurile de lucru complexe. Acest articol analizează modelele de design în Python, concentrându-se pe relevanța lor în AI și LLMsisteme bazate pe . Voi explica fiecare model cu exemple practice de utilizare a inteligenței artificiale și cod Python.
Să explorăm câteva modele cheie de design care sunt deosebit de utile în contexte de AI și de învățare automată, împreună cu exemple Python.
De ce sunt importante modelele de proiectare pentru inginerii AI
Sistemele AI implică adesea:
- Crearea de obiecte complexe (de exemplu, încărcarea modelelor, conductele de preprocesare a datelor).
- Gestionarea interacțiunilor dintre componente (de exemplu, inferența modelului, actualizări în timp real).
- Gestionarea scalabilității, mentenabilității și flexibilității pentru cerințele în schimbare.
Modelele de design abordează aceste provocări, oferind o structură clară și reducând remediile ad-hoc. Ele se împart în trei categorii principale:
- Modele Creaționale: Concentrați-vă pe crearea de obiecte. (Singleton, Fabrică, Constructor)
- Modele structurale: Organizați relațiile dintre obiecte. (Adaptor, Decorator)
- Tipare comportamentale: Gestionați comunicarea între obiecte. (Strategie, Observator)
1. Model Singleton
Model Singleton asigură că o clasă are o singură instanță și oferă un punct de acces global la acea instanță. Acest lucru este deosebit de valoros în fluxurile de lucru AI în care resursele partajate, cum ar fi setările de configurare, sistemele de înregistrare sau instanțe de model, trebuie gestionate în mod constant, fără redundanță.
Când să utilizați
- Gestionarea configurațiilor globale (de exemplu, hiperparametrii modelului).
- Partajarea resurselor prin mai multe fire sau procese (de exemplu, memorie GPU).
- Asigurarea accesului consecvent la un singur Motor de inferență sau conexiune la baza de date.
Punerea în aplicare
Iată cum să implementați un model Singleton în Python pentru a gestiona configurațiile pentru un model AI:
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)
Explicație
-
__new__
Metodă: Acest lucru asigură că este creată o singură instanță a clasei. Dacă o instanță există deja, o returnează pe cea existentă. - Stat partajat: Ambele
config1
șiconfig2
indică aceeași instanță, făcând toate configurațiile accesibile și coerente la nivel global. - Caz de utilizare AI: utilizați acest model pentru a gestiona setările globale, cum ar fi căile către seturi de date, configurațiile de înregistrare sau variabilele de mediu.
2. Model de fabrică
Model de fabrică oferă o modalitate de a delega crearea de obiecte către subclase sau metode de fabrică dedicate. În sistemele AI, acest model este ideal pentru a crea diferite tipuri de modele, încărcătoare de date sau conducte dinamic, bazate pe context.
Când să utilizați
- Crearea dinamică a modelelor pe baza intrărilor utilizatorului sau a cerințelor sarcinilor.
- Gestionarea logicii complexe de creare a obiectelor (de exemplu, conducte de preprocesare în mai multe etape).
- Decuplarea instanțierii obiectului de restul sistemului pentru a îmbunătăți flexibilitatea.
Punerea în aplicare
Să construim o fabrică pentru crearea de modele pentru diferite sarcini AI, cum ar fi clasificarea textului, rezumatul și traducerea:
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!
Explicație
- Clasa de bază abstractă:
BaseModel
clasa definește interfața (predict
) pe care trebuie să le implementeze toate subclasele, asigurând coerența. - Logica fabricii:
ModelFactory
selectează în mod dinamic clasa corespunzătoare pe baza tipului de sarcină și creează o instanță. - Extensibilitate: Adăugarea unui nou tip de model este simplă — doar implementați o nouă subclasă și actualizați-o pe cea din fabrică
task_mapping
.
Caz de utilizare AI
Imaginați-vă că proiectați un sistem care selectează un LLM diferit (de exemplu, BERT, GPT sau T5) în funcție de sarcină. Modelul Factory facilitează extinderea sistemului pe măsură ce noi modele devin disponibile fără modificarea codului existent.
3. Modelul constructorului
Model de constructor separă construcția unui obiect complex de reprezentarea lui. Este util atunci când un obiect implică mai mulți pași de inițializare sau configurare.
Când să utilizați
- Construirea conductelor în mai multe etape (de exemplu, preprocesarea datelor).
- Gestionarea configurațiilor pentru experimente sau antrenament de model.
- Crearea de obiecte care necesită o mulțime de parametri, asigurând lizibilitatea și mentenabilitatea.
Punerea în aplicare
Iată cum să utilizați modelul Builder pentru a crea o conductă de preprocesare a datelor:
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
Explicație
- Metode înlănțuite:
add_step
metoda permite înlănțuirea pentru o sintaxă intuitivă și compactă la definirea conductelor. - Execuție pas cu pas: conducta prelucrează datele rulându-le prin fiecare pas în secvență.
- Caz de utilizare AI: Folosiți modelul Builder pentru a crea conducte complexe, reutilizabile de preprocesare a datelor sau configurații de formare a modelului.
4. Model de strategie
Model de strategie definește o familie de algoritmi interschimbabili, încapsulându-i pe fiecare și permițând comportamentului să se schimbe dinamic în timpul execuției. Acest lucru este util în special în sistemele AI în care același proces (de exemplu, inferență sau prelucrarea datelor) ar putea necesita abordări diferite în funcție de context.
Când să utilizați
- Comutarea între diferite deducție strategii (de exemplu, procesare batch vs. streaming).
- Aplicarea dinamică a diferitelor tehnici de prelucrare a datelor.
- Alegerea strategiilor de management al resurselor pe baza infrastructurii disponibile.
Punerea în aplicare
Să folosim modelul de strategie pentru a implementa două strategii de inferență diferite pentru un model AI: inferență în lot și inferență în flux.
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']
Explicație
- Clasa de strategie abstractă:
InferenceStrategy
definește interfața pe care trebuie să o urmeze toate strategiile. - Strategii concrete: Fiecare strategie (de ex.,
BatchInference
,StreamInference
) implementează logica specifică abordării respective. - Comutare dinamică:
InferenceContext
permite schimbarea strategiilor în timpul execuției, oferind flexibilitate pentru diferite cazuri de utilizare.
Când să utilizați
- Comutați între inferență în lot pentru procesare offline și inferență în flux pentru aplicații în timp real.
- Ajustați dinamic tehnicile de creștere sau preprocesare a datelor pe baza sarcinii sau a formatului de intrare.
5. Model de observator
Model de observator stabilește o relație unu-la-mulți între obiecte. Când un obiect (subiectul) își schimbă starea, toți dependenții lui (observatorii) sunt notificați automat. Acest lucru este util în special în sistemele AI pentru monitorizarea în timp real, gestionarea evenimentelor sau sincronizarea datelor.
Când să utilizați
- Monitorizarea valorilor precum acuratețea sau pierderea în timpul antrenamentului de model.
- Actualizări în timp real pentru tablouri de bord sau jurnale.
- Gestionarea dependențelor dintre componente în fluxurile de lucru complexe.
Punerea în aplicare
Să folosim modelul Observator pentru a monitoriza performanța unui model AI în timp real.
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
- Subiect: Gestionează o listă de observatori și îi anunță când starea acesteia se schimbă. În acest exemplu,
ModelMonitor
clasă urmărește valorile. - observatorii: Efectuați acțiuni specifice atunci când sunteți notificat. De exemplu, cel
LoggerObserver
înregistrează valorile, în timp ceAlertObserver
generează alerte dacă se depășește un prag. - Design decuplat: Observatorii și subiecții sunt cuplati lejer, făcând sistemul modular și extensibil.
Cum diferă modelele de proiectare pentru inginerii AI față de inginerii tradiționali
Modelele de proiectare, deși aplicabile universal, capătă caracteristici unice atunci când sunt implementate în ingineria AI, în comparație cu ingineria software tradițională. Diferența constă în provocările, obiectivele și fluxurile de lucru intrinsece sistemelor AI, care adesea necesită adaptarea sau extinderea tiparelor dincolo de utilizările lor convenționale.
1. Crearea obiectelor: Nevoi statice vs. dinamice
- Inginerie tradițională: Modelele de creare a obiectelor, cum ar fi Factory sau Singleton, sunt adesea folosite pentru a gestiona configurațiile, conexiunile la baze de date sau stările de sesiuni ale utilizatorilor. Acestea sunt în general statice și bine definite în timpul proiectării sistemului.
- Inginerie AI: Crearea obiectelor implică adesea fluxuri de lucru dinamice, Cum ar fi:
- Crearea de modele din mers pe baza intrărilor utilizatorului sau a cerințelor de sistem.
- Încărcarea diferitelor configurații de model pentru sarcini precum traducerea, rezumarea sau clasificarea.
- Instanțierea mai multor conducte de procesare a datelor care variază în funcție de caracteristicile setului de date (de exemplu, text tabelar vs. text nestructurat).
Exemplu: În AI, un model Factory poate genera în mod dinamic un model de învățare profundă bazat pe tipul de sarcină și constrângerile hardware, în timp ce în sistemele tradiționale, ar putea genera pur și simplu o componentă de interfață cu utilizatorul.
2. Constrângeri de performanță
- Inginerie tradițională: Tiparele de design sunt de obicei optimizate pentru latență și debit în aplicații precum servere web, interogări de baze de date sau redare UI.
- Inginerie AI: Cerințele de performanță în AI se extind la latența de inferență a modelului, GPU/TPU utilizare, și optimizarea memoriei. Modelele trebuie să găzduiască:
- Memorarea în cache a rezultatelor intermediare pentru a reduce calculele redundante (modele Decorator sau Proxy).
- Schimbarea dinamică a algoritmilor (model de strategie) pentru a echilibra latența și acuratețea pe baza încărcării sistemului sau a constrângerilor în timp real.
3. Natura centrată pe date
- Inginerie tradițională: Modelele operează adesea pe structuri de intrare-ieșire fixe (de exemplu, formulare, răspunsuri API REST).
- Inginerie AI: Modelele trebuie să se ocupe variabilitatea datelor atât în structură, cât și în scară, inclusiv:
- Streaming de date pentru sisteme în timp real.
- Date multimodale (de exemplu, text, imagini, videoclipuri) care necesită conducte cu pași flexibili de procesare.
- Seturi de date la scară largă care au nevoie de conducte eficiente de preprocesare și creștere, folosind adesea modele precum Builder sau Pipeline.
4. Experimentare vs. Stabilitate
- Inginerie tradițională: Accentul este pus pe construirea de sisteme stabile, previzibile, în care tiparele asigură performanță și fiabilitate consistente.
- Inginerie AI: fluxurile de lucru AI sunt adesea experimental și implică:
- Iterarea pe diferite arhitecturi de model sau tehnici de preprocesare a datelor.
- Actualizarea dinamică a componentelor sistemului (de exemplu, modele de reinstruire, algoritmi de schimb).
- Extinderea fluxurilor de lucru existente fără a întrerupe conductele de producție, folosind adesea modele extensibile precum Decorator sau Factory.
Exemplu: O fabrică în IA ar putea nu numai să instanțieze un model, ci și să atașeze greutăți preîncărcate, să configureze optimizatori și să conecteze apelurile de antrenament, toate în mod dinamic.