🗓 Save the Date KI-Snack Week 2026 – Das KI-Event für Macher & Entscheider · 09.–13. November 2026 · München + Online Jetzt anmelden →
Tipps & Tricks

Häufige Fehler in Python bei KI-Workflows und wie man sie vermeidet

10 min Lesezeit
Häufige Fehler in Python bei KI-Workflows und wie man sie vermeidet

Ein reibungsloser Ablauf beweist lediglich, dass der Prozess ausgeführt wurde. Er sagt jedoch nichts darüber aus, was die Pipeline gelernt hat, aus welchen Zeilen, in welchem Zustand oder ob das gespeicherte Ergebnis an anderer Stelle vertrauenswürdig ist.

Ein Modell erzielt einen Validierungswert von 0,83, das Notebook läuft ohne einen einzigen Fehler von oben bis unten, und drei Wochen nach der Bereitstellung sind die Vorhersagen nutzlos. In dieser Geschichte ist nichts abgestürzt. Das macht die Fehler in KI-Workflows anders als gewöhnliche Python-Fehler: Die APIs akzeptieren problemlos Code, der gegen einen Daten-, Zustand-, Form- oder Artefaktvertrag verstößt. Die Strafe kommt dann als glaubwürdige Zahl anstelle eines Tracebacks. Ein reibungsloser Ablauf beweist lediglich, dass der Prozess ausgeführt wurde. Er sagt jedoch nichts darüber aus, was die Pipeline gelernt hat, aus welchen Zeilen, in welchem Zustand oder ob das gespeicherte Ergebnis an anderer Stelle vertrauenswürdig ist.

Die sieben häufigsten Fehler

Die folgenden sieben Fehler teilen sich diese Stille, und jeder von ihnen bringt eine Überprüfung mit sich, die ihn an der Grenze aufdeckt, wo er beginnt.

  • Vorverarbeitung: Transformation vor der Aufteilung angepasst
    Irreführendes Symptom: Der Validierungswert ist optimistisch aufgebläht
    Die Überprüfung: Alle Fit-Aufrufe lokalisieren; die sichtbaren Zeilen benennen.
  • Aufteilung: Verwandte Zeilen auf beiden Seiten der Aufteilung
    Irreführendes Symptom: Starke Validierung, schwach bei neuen Entitäten
    Die Überprüfung: Gruppen- oder zeitbewusster Splitter, der an die echte Grenze angepasst ist.
  • Bereitstellung: Zweiter handgeschriebener Vorverarbeitungspfad
    Irreführendes Symptom: Trainieren und Bereitstellen der Ausgaben driften still auseinander
    Die Überprüfung: Ein Fixture durch beide Pfade; Ausgaben als identisch bestätigen.
  • Zufälligkeit: Ein Seed wird als Reproduzierbarkeit behandelt
    Irreführendes Symptom: Wiederholungen unterscheiden sich trotz der gesäten Bibliothek
    Die Überprüfung: Seeds, Daten, Code, Konfiguration und Abhängigkeiten aufzeichnen.
  • Bewertung: eval() und no_grad() werden austauschbar verwendet
    Irreführendes Symptom: Dropout oder Batch-Norm aktiv während der Validierung
    Die Überprüfung: Beide Aufrufe in der Schleife, dann model.train() beim Fortsetzen.
  • Verlustgrenze: Broadcasting verbirgt eine [batch, 1] vs. [batch] Diskrepanz
    Irreführendes Symptom: Plausibler Verlust aus der falschen Berechnung
    Die Überprüfung: assert output.shape == target.shape vor dem Verlust.
  • Artefakt: Gespeichertes Modell wird als inerte Daten behandelt
    Irreführendes Symptom: Codeausführung oder Versionsbruch beim Laden
    Die Überprüfung: Nur vertrauenswürdige Quellen; Smoke-Test in der Bereitstellungsumgebung.

1. Vorverarbeitung vor der Datenaufteilung anpassen

Hier ist eine Demonstration, die es wert ist, einmal durchgeführt zu werden. Nehmen Sie 100 Proben reinen Zufallsrauschs, 1.000 Merkmale breit, mit Labels, die durch Münzwurf zugewiesen werden. Fragen Sie nun SelectKBest nach den 20 „besten“ Merkmalen und validieren Sie einen Klassifikator über die Überlebenden:

sel = SelectKBest(f_classif, k=20).fit(X, y) # auf ALLEN Zeilen anpassen
scores = cross_val_score(model, sel.transform(X), y, cv=5

Bei Daten, aus denen nichts zu lernen ist, berichtet dieses Paar von Zeilen dennoch eine Genauigkeit von 0,83. Der Selektor sah jede Zeile, einschließlich derjenigen, die später in jedem Fold als ungesehen behandelt werden, sodass Informationen aus den zurückgehaltenen Daten bereits die zu bewertenden Merkmale prägten. Wenn die Auswahl in eine scikit-learn-Pipeline verschoben wird, sodass jeder Fold seine eigene Transformation anpasst, sinkt dasselbe Experiment auf 0,49, was die ehrliche Antwort für Rauschen ist. Diese Regel verallgemeinert über die Merkmalsauswahl hinaus auf Skalierung, Imputation und Dimensionsreduktion. Das Diagnoseverfahren ist eine Suche und kein erneuter Lauf: Finden Sie jeden Fit- und Fit_Transform-Aufruf im Workflow und benennen Sie die Zeilen, die zu diesem Zeitpunkt sichtbar waren. Scikit-learn führt ein ganzes Verzeichnis dieser Fallstricke, wobei Leckagen aus gutem Grund an oberster Stelle stehen. Weitere Informationen zu den wesentlichen Python-Konzepte für KI-Ingenieure finden Sie hier.

2. Zufälliges Aufteilen von Zeilen, die nicht unabhängig sind

Ein zufälliger Split beantwortet eine Frage: ob das Modell Zeilen vorhersagen kann, die es nicht gesehen hat. Die Produktion stellt normalerweise eine schwierigere Frage — ob es Benutzer, Patienten oder Geräte vorhersagen kann, die es nicht gesehen hat. Wenn fünf Zeilen zu demselben Benutzer gehören, streut ein zufälliger Split sie über Training und Validierung. Das Modell erhält dann Anerkennung dafür, Benutzer zu erkennen, anstatt auf neue zu verallgemeinern. Eine synthetische Version mit 60 Benutzern und nahezu doppelten Zeilen pro Benutzer erzielt 0,97 unter train_test_split und sinkt auf 0,89, sobald GroupShuffleSplit jeden Benutzer auf einer Seite der Linie hält. Diese acht Punkte sind die Rückerstattung der Memorierung. Gruppierte Daten benötigen GroupKFold oder GroupShuffleSplit, während zeitlich geordnete Daten TimeSeriesSplit benötigen, da ein zufälliger Split fröhlich auf der Zukunft trainiert, um die Vergangenheit vorherzusagen. Stratifizierung nach dem Label bringt hier nichts, und train_test_split hat überhaupt kein Konzept von Gruppen. Der Leitfaden zur Kreuzvalidierung zeigt, welcher Splitter zu welcher Grenze passt. Entscheiden Sie, was das Modell über eine Entität oder einen Zeitpunkt hinaus verallgemeinern muss, bevor Sie einen auswählen.

3. Unterschiedlichen Vorverarbeitungscode beim Training und bei der Inferenz ausführen

Skew sieht aus wie der Zwillingsleakage, zeigt jedoch in die andere Richtung. Leakage lässt die Bewertung aus zurückgehaltenen Zeilen schöpfen, während Skew einen anderen Transformationspfad nach dem Training anwendet. Die Skew-Version beginnt normalerweise harmlos, mit einem Notebook, das Merkmale auf eine Weise skaliert, und einer Bereitstellungsfunktion, die die „gleiche“ Skalierung von Hand neu implementiert. Der Fehler hat eine echte Größe. Das erneute Lernen eines Scalers auf einer fünfzeiligen Serviercharge anstelle der Wiederverwendung des angepassten kann das gleiche Fixture um fast vier Standardabweichungen verschieben — der Unterschied zwischen einer Vorhersage und einem Münzwurf. Ähnlich aussehender Code ist kein Vertrag. Die Inferenz muss die exakt gelernten Parameter, die Merkmalsreihenfolge, den Datentyp und die Regeln für fehlende Werte verwenden, die auch beim Training verwendet wurden. Die günstigste Garantie besteht darin, das angepasste Pipeline-Objekt selbst über beide Pfade zu versenden. Die Überprüfung dafür erfordert ein rohes Fixture, das sowohl durch den Trainingspfad als auch durch den Servierpfad geschoben wird. Wenn die beiden Ausgaben irgendwo unterschiedlich sind — in Namen, Reihenfolge, Datentyp, Form oder Werten — lügt der Servierpfad über etwas.

4. Einen einzigen Bibliotheks-Seed setzen und das Experiment als reproduzierbar betrachten

random.seed(42) am Anfang eines Skripts kauft meist nur Beruhigung. Pythons random-Modul, NumPy und PyTorch führen jeweils ihren eigenen Generator aus, und das Setzen des ersten lässt die anderen beiden genau die ungesäten Ausgaben produzieren, die sie ohnehin produziert hätten. Ein DataLoader mit Arbeitsprozessen fügt seine eigenen Seed-Regeln hinzu.

Vollständig deterministische Kerne müssen explizit angefordert werden, manchmal auf Kosten der Leistung, wie die Reproduzierbarkeitsnotizen von PyTorch darlegen. Diese Notizen setzen auch die ehrliche Obergrenze. Identische Ergebnisse werden nicht über PyTorch-Versionen, Plattformen oder CPU- und GPU-Ausführungen hinweg versprochen, egal wie viele Seeds gesetzt werden. Reproduzierbarkeit ist daher eher ein Aufzeichnungsproblem als ein Seed-Problem.

Ein Lauf, der seine Seeds, Datenschnappschüsse, Codeversion, Konfiguration und Abhängigkeitsversionen protokolliert, kann rekonstruiert werden, während ein einzelner 42 keine Umgebung wiederherstellen kann. Der Crashkurs von Weights & Biases zeigt eine praktische Möglichkeit, diese Aufzeichnung automatisch zu machen.

5. Bewertungszustand mit deaktivierten Gradienten verwechseln

model.eval() und torch.no_grad() werden als austauschbar behandelt, da beide in Validierungsschleifen erscheinen, aber sie steuern unterschiedliche Mechanismen. Der Evaluierungsmodus schaltet trainingssensible Module wie Dropout und Batch-Normalisierung in den Inferenzmodus um, während no_grad lediglich verhindert, dass autograd die Arbeit aufzeichnet.

Führen Sie ein Dropout-Modell zweimal mit denselben Eingaben unter no_grad aus, während es sich noch im Trainingsmodus befindet, und die beiden Ausgaben unterscheiden sich, da Dropout weiterhin aktiv ist. In einem kleinen Modell kamen die Paare als -0,1410 und 0,0071 zurück. Wechseln Sie zu model.eval() und die beiden Aufrufe geben die gleiche Antwort zurück.

Die Abhängigkeit läuft auch in die andere Richtung, da ein Modell im Evaluierungsmodus ohne no_grad dennoch Gradienten bei jedem Vorwärtsdurchlauf aufzeichnet. Eine Validierungsschleife benötigt beide Schalter und das Modell muss danach wieder in den Trainingsmodus versetzt werden:

model.eval()
with torch.no_grad():
val_loss = criterion(model(x_val), y_val)
model.train()

Die Autograd-Notizen decken die Grenze im Detail ab. Wenn nichts innerhalb des Blocks jemals Gradienten benötigt, schließt torch.inference_mode() diese Tür härter als no_grad. Selbst ein Modell, das derzeit kein Dropout hat, verdient den expliziten eval()-Aufruf, da sich Architekturen ändern und der Aufruf nichts kostet.

6. Broadcasting verstecken lassen, um eine falsche Tensorform zu verbergen

Broadcasting ist ein Merkmal, bis es zu einer Verlustfunktion kommt. Angenommen, die Vorhersage hat die Form [batch, 1], während das Ziel [batch] ist. Innerhalb von MSELoss sendet die Subtraktion dieses Paares in eine vollständige Matrix, sodass jede Vorhersage mit jedem Label verglichen wird.

Bei einer Charge von 32 bedeutet das ein 32-mal-32-Raster, und der Verlust wird dennoch berechnet: 1,63, während die korrekt geformte Version 1,85 mit denselben Tensoren ergibt. Nichts an 1,63 sieht verdächtig aus, und es wird niemals eine Ausnahme ausgelöst. PyTorch gibt hier eine UserWarning aus, die Tests zu einem Fehler befördern sollten. MSELoss dokumentiert das Ziel als Übereinstimmung mit der Eingabestruktur, sodass die Korrektur darin besteht, den Vertrag einmal zu entscheiden und ihn an der Grenze durchzusetzen:

pred = model(x).squeeze(1) # [batch, 1] -> [batch], absichtlich
assert pred.shape == target.shape
loss = criterion(pred, target)

Nicht jedes Broadcasting ist ein Fehler, wie die Broadcasting-Semantik deutlich macht. Der Fehler besteht darin, eine implizite Erweiterung an einer Grenze zuzulassen, an der der Verlust, die Metrik oder der Labelvertrag eine genaue Übereinstimmung verlangen.

7. Ein gespeichertes Modell wie eine inerte, tragbare Datei behandeln

Die letzte Grenze ist die Datei selbst. Ein gepickeltes Modell — ob von pickle, joblib oder cloudpickle geschrieben — ist keine passive Daten. Das Laden eines solchen Modells kann beliebigen Code ausführen, und eine fünfzeilige Datei mit einer bösartigen __reduce__-Methode wird während pickle.load ohne Warnung ihr Payload ausführen. Daher sollte ein Artefakt aus einer Quelle, die niemand überprüft hat, einfach niemals geladen werden.

Versionsabweichungen verursachen weniger Drama, beißen jedoch in denselben Workflow, da scikit-learn das Laden eines Modells, das unter einer anderen Bibliotheksversion gespeichert wurde, nicht unterstützt. Versenden Sie jedes Artefakt mit seinem Trainingsrezept, Datenreferenz, Abhängigkeitsversionen und dem Validierungswert, den es beansprucht.

Vor der Bereitstellung laden Sie es in der realen Bereitstellungsumgebung und schieben ein festes Fixture durch den gesamten Vorverarbeitungs- und Vorhersagepfad. Alternative Formate verschieben diese Probleme eher, als sie zu beseitigen, sodass kein einzelnes Format die Sicherheitslösung ist.

Die Workflow-Grenzen beweisen

Keiner dieser sieben Fehler kündigt sich an, weshalb die Überprüfung zur Gewohnheit werden muss, anstatt eine Reaktion zu sein. Vier Fragen decken das Gebiet ab. Was hat jeder Schritt gelernt, und aus welchen Zeilen? Welcher Code wandelt rohe Eingaben zur Servierzeit um, und ist es der Vertrag, den das Training verwendet hat? Welcher Zustand und welche Form haben die Metrik erreicht? Und welche Umgebung ist vertrauenswürdig, um das Artefakt zu laden? Ein Workflow, der diese Fragen aus Code und aufgezeichneten Metadaten beantwortet, hat sich seine Punktzahl verdient. Einer, der das nicht kann, hält eine vielversprechende Vermutung.

Nahla Davies ist Softwareentwicklerin und technische Autorin. Bevor sie ihre Arbeit vollständig dem technischen Schreiben widmete, war sie unter anderem als leitende Programmiererin in einer Inc. 5.000-Erlebnisbranding-Organisation tätig, deren Kunden Samsung, Time Warner, Netflix und Sony umfassen.

„`


Quellen: kdnuggets

Bildquelle: KI generiert

Dieser Text wurde mit Hilfe von künstlicher Intelligenz in Zusammenarbeit mit unserer Redaktion erstellt.

🚀
KI-Snack Week 2026 · 09.–13. November
Das KI-Event für Macher & Entscheider
2 Tage live in München + 3 Tage Online-Masterclasses · Jetzt Ticket sichern
Mehr erfahren →
KI Snack