5 leistungsstarke Python-Dekoratoren zum Erstellen sauberen KI-Codes
Bild vom Herausgeber

# Einführung

Python-Dekoratoren kann bei Projekten, an denen beteiligt ist, unglaublich nützlich sein Entwicklung von KI- und maschinellen Lernsystemen. Sie zeichnen sich dadurch aus, dass sie wichtige Logik wie Modellierung und Datenpipelines von anderen Standardaufgaben wie Checks und Validierung, Timing, Protokollierung usw. trennen.

In diesem Artikel werden fünf besonders nützliche Python-Dekoratoren vorgestellt, die sich auf der Grundlage der Erfahrung von Entwicklern als wirksam erwiesen haben, wenn es darum geht, KI-Code sauberer zu machen.

Die folgenden Codebeispiele umfassen einfache, zugrunde liegende Logik, die auf Python-Standardbibliotheken und Finest Practices basiert, z functools.wraps. Ihr Hauptziel besteht darin, die Verwendung jedes einzelnen Dekorators zu veranschaulichen, sodass Sie sich nur um die Anpassung der Logik des Dekorators an Ihr KI-Codierungsprojekt kümmern müssen.

# 1. Parallelitätsbegrenzer

Ein sehr nützlicher Dekorator, wenn es um (oft ärgerliche) Free-Tier-Beschränkungen bei der Verwendung von Giant Language Fashions (LLMs) von Drittanbietern geht. Wenn aufgrund des Sendens zu vieler asynchroner Anforderungen solche Grenzwerte erreicht werden, führt dieses Muster einen Drosselungsmechanismus ein, um diese Aufrufe sicherer zu machen. Durch Semaphoren wird die Anzahl der Ausführungen einer asynchronen Funktion begrenzt:

import asyncio
from functools import wraps

def limit_concurrency(restrict=5):
    sem = asyncio.Semaphore(restrict)
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            async with sem:
                return await func(*args, **kwargs)
        return wrapper
    return decorator

# Utility
@limit_concurrency(5)
async def fetch_llm_batch(immediate):
    return await async_api_client.generate(immediate)

# 2. Strukturierter Machine-Studying-Logger

Es ist keine Überraschung, dass in komplexer Software program wie der, die maschinelle Lernsysteme regelt, Normal print() Anweisungen gehen leicht verloren, insbesondere wenn sie in der Produktion eingesetzt werden.

Mit dem folgenden Protokollierungsdekorator ist es möglich, Ausführungen und Fehler zu „fangen“ und sie in strukturierte JSON-Protokolle zu formatieren, die für ein schnelles Debugging leicht durchsuchbar sind. Das folgende Codebeispiel kann als Vorlage verwendet werden, um beispielsweise eine Funktion zu dekorieren, die eine Trainingsepoche in einem auf einem neuronalen Netzwerk basierenden Modell definiert:

import logging, json, time
from functools import wraps

def json_log(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        begin = time.time()
        attempt:
            res = func(*args, **kwargs)
            logging.information(json.dumps({"step": func.__name__, "standing": "success", "time": time.time() - begin}))
            return res
        besides Exception as e:
            logging.error(json.dumps({"step": func.__name__, "error": str(e)}))
            increase
    return wrapper

# Utility
@json_log
def train_epoch(mannequin, training_data):
    return mannequin.match(training_data)

# 3. Characteristic-Injektor

Geben Sie während der Modellbereitstellungs- und Inferenzphase einen besonders nützlichen Dekorateur ein! Angenommen, Sie verschieben Ihr maschinelles Lernmodell von einem Pocket book in eine einfache Produktionsumgebung, z. B. mithilfe von a FastAPI Endpunkt. Die manuelle Sicherstellung, dass eingehende Rohdaten von Endbenutzern denselben Transformationen unterliegen wie die ursprünglichen Trainingsdaten, kann manchmal etwas mühsam sein. Der Characteristic-Injektor sorgt dafür, dass die Artwork und Weise, wie Options aus Rohdaten generiert werden, unter der Haube konsistent bleibt.

Dies ist während der Bereitstellungs- und Inferenzphase äußerst nützlich. Beim Verschieben eines Modells von einem Jupyter-Pocket book in eine Produktionsumgebung besteht ein großes Downside darin, sicherzustellen, dass die rohen eingehenden Benutzerdaten dieselben Transformationen erhalten wie Ihre Trainingsdaten. Dieser Dekorator stellt sicher, dass diese Funktionen unter der Haube konsistent generiert werden, bevor die Daten jemals Ihr Modell erreichen.

Das folgende Beispiel vereinfacht das Hinzufügen einer Funktion namens 'is_weekend'basierend darauf, ob eine Datumsspalte in einem vorhandenen Datenrahmen ein Datum enthält, das einem Samstag oder Sonntag zugeordnet ist:

from functools import wraps

def add_weekend_feature(func):
    @wraps(func)
    def wrapper(df, *args, **kwargs):
        df = df.copy() # Prevents Pandas mutation warnings
        df('is_weekend') = df('date').dt.dayofweek.isin((5, 6)).astype(int)
        return func(df, *args, **kwargs)
    return wrapper

# Utility
@add_weekend_feature
def process_data(df):
    # 'is_weekend' is assured to exist right here
    return df.dropna()

# 4. Deterministischer Samensetzer

Dieses zeichnet sich durch zwei spezifische Phasen des KI-/maschinellen Lernlebenszyklus aus: Experimentieren und Hyperparameter-Tuning. Diese Prozesse erfordern typischerweise die Verwendung eines Zufallsstartwerts als Teil der Anpassung wichtiger Hyperparameter wie der Lernrate eines Modells. Angenommen, Sie haben gerade den Wert angepasst und plötzlich sinkt die Modellgenauigkeit. In einer solchen State of affairs müssen Sie möglicherweise wissen, ob die Ursache für diesen Leistungsabfall die neue Hyperparametereinstellung oder einfach eine fehlerhafte zufällige Initialisierung der Gewichte ist. Indem wir den Seed sperren, isolieren wir Variablen und machen so die Ergebnisse von Checks wie A/B zuverlässiger.

import random, numpy as np
from functools import wraps

def lock_seed(seed=42):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            random.seed(seed)
            np.random.seed(seed)
            return func(*args, **kwargs)
        return wrapper
    return decorator

# Utility
@lock_seed(42)
def initialize_weights():
    return np.random.randn(10, 10)

# 5. Dev-Mode-Fallback

Ein lebensrettender Dekorateur, insbesondere in lokalen Entwicklungsumgebungen und CI/CD-Checks. Angenommen, Sie bauen eine Anwendungsschicht auf einem LLM auf – zum Beispiel ein RAG-System (Retrieval-Augmented Era). Wenn eine dekorierte Funktion aufgrund externer Faktoren wie Verbindungszeitüberschreitungen oder API-Nutzungsbeschränkungen fehlschlägt, wird der Fehler von diesem Dekorator abgefangen und ein vordefinierter Satz von „Mock-Testdaten“ zurückgegeben, anstatt eine Ausnahme auszulösen.

Warum ein Lebensretter? Denn dieser Mechanismus kann sicherstellen, dass Ihre Anwendung nicht vollständig stoppt, wenn ein externer Dienst vorübergehend ausfällt.

from functools import wraps

def fallback_mock(mock_data):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            attempt:
                return func(*args, **kwargs)
            besides Exception: # Catches timeouts and charge limits
                return mock_data
        return wrapper
    return decorator

# Utility
@fallback_mock(mock_data=(0.01, -0.05, 0.02))
def get_text_embeddings(textual content):
    return external_api.embed(textual content)

# Zusammenfassung

In diesem Artikel wurden fünf effektive Python-Dekoratoren untersucht, die dazu beitragen, Ihren KI- und Machine-Studying-Code in einer Vielzahl spezifischer Situationen sauberer zu gestalten: von strukturierter, einfach zu durchsuchender Protokollierung bis hin zu kontrolliertem Zufalls-Seeding für Aspekte wie Datenstichproben, Checks und mehr.

Iván Palomares Carrascosa ist ein führender Autor, Redner und Berater in den Bereichen KI, maschinelles Lernen, Deep Studying und LLMs. Er schult und leitet andere darin, KI in der realen Welt zu nutzen.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert