Erstellen Sie Tools in maschinellen Lernprojekten, eine Übersicht

Ich habe mich über maschinelles Lernen / datenwissenschaftliche Projektstruktur / Workflow gewundert und verschiedene Meinungen zu diesem Thema gelesen. Und wenn Leute anfangen, über Workflows zu sprechen, möchten sie, dass ihre Workflows reproduzierbar sind. Es gibt viele Posts, die empfehlen, make zu verwenden , um den Workflow reproduzierbar zu halten. Obwohl make sehr stabil und weit verbreitet ist, mag ich persönlich plattformübergreifende Lösungen. Es ist immerhin 2019, nicht 1977. Man kann argumentieren, dass make plattformübergreifend ist, aber in Wirklichkeit werden Sie Probleme haben und Zeit damit verbringen, Ihr Werkzeug zu reparieren, anstatt die eigentliche Arbeit zu erledigen. Also habe ich beschlossen, mich umzuschauen und herauszufinden, welche anderen Tools verfügbar sind. Ja, ich habe beschlossen, einige Zeit mit Werkzeugen zu verbringen.

Bild

Dieser Beitrag ist eher eine Einladung zum Dialog als ein Tutorial. Vielleicht ist Ihre Lösung perfekt. Wenn ja, wird es interessant sein, davon zu hören.

In diesem Beitrag werde ich ein kleines Python-Projekt verwenden und die gleichen Automatisierungsaufgaben mit verschiedenen Systemen ausführen:


Am Ende des Beitrags wird eine Vergleichstabelle angezeigt .

Die meisten Tools, die ich mir ansehen werde, sind als Build-Automatisierungssoftware oder Build-Systeme bekannt . Es gibt unzählige von ihnen in allen verschiedenen Geschmacksrichtungen, Größen und Komplexitäten. Die Idee ist dieselbe: Der Entwickler definiert Regeln für die automatisierte und konsistente Erstellung einiger Ergebnisse. Ein Ergebnis kann beispielsweise ein Bild mit einem Diagramm sein. Um dieses Bild zu erstellen, müsste man die Daten herunterladen, die Daten bereinigen und einige Datenmanipulationen durchführen (wirklich ein klassisches Beispiel). Sie können mit ein paar Shell-Skripten beginnen, die den Job erledigen. Wenn Sie ein Jahr später zum Projekt zurückkehren, wird es schwierig sein, sich alle Schritte und deren Reihenfolge zu merken, die Sie ausführen müssen, um dieses Bild zu erstellen. Die naheliegende Lösung besteht darin, alle Schritte zu dokumentieren. Gute Nachrichten! Mit Build-Systemen können Sie die Schritte in Form eines Computerprogramms dokumentieren. Einige Build-Systeme ähneln Ihren Shell-Skripten, verfügen jedoch über zusätzliche Schnickschnack.

Die Grundlage dieses Beitrags ist eine Reihe von Beiträgen von Mateusz Bednarski zum automatisierten Workflow für ein maschinelles Lernprojekt. Mateusz erklärt seine Ansichten und liefert Rezepte für die Verwendung von make . Ich ermutige Sie, zuerst seine Beiträge zu überprüfen. Ich werde hauptsächlich seinen Code verwenden, aber mit verschiedenen Build-Systemen.

Wenn Sie mehr über make erfahren möchten, finden Sie im Folgenden einige Referenzen für einige Beiträge. Brooke Kennedy bietet einen allgemeinen Überblick in 5 einfachen Schritten, um Ihr Data Science-Projekt reproduzierbar zu machen. Zachary Jones gibt weitere Details zur Syntax und zu den Funktionen sowie Links zu anderen Posts. David Stevens schreibt einen sehr Hype-Beitrag darüber, warum Sie make sofort verwenden müssen. Er liefert schöne Beispiele, die den alten und den neuen Weg vergleichen . Samuel Lampa hingegen schreibt darüber, warum die Verwendung von make eine schlechte Idee ist.

Meine Auswahl an Build-Systemen ist weder umfassend noch unvoreingenommen. Wenn Sie Ihre Liste erstellen möchten, ist Wikipedia möglicherweise ein guter Ausgangspunkt. Wie oben erwähnt, werde ich CMake , PyBuilder , Pynt , Paver , Doit und Luigi behandeln . Die meisten Tools in dieser Liste basieren auf Python und sind sinnvoll, da sich das Projekt in Python befindet. In diesem Beitrag wird nicht beschrieben, wie die Tools installiert werden. Ich gehe davon aus, dass Sie Python ziemlich gut beherrschen.

Ich bin hauptsächlich daran interessiert, diese Funktionalität zu testen:

  1. Angeben einiger Ziele mit Abhängigkeiten. Ich möchte sehen, wie es geht und wie einfach es ist.
  2. Überprüfen, ob inkrementelle Builds möglich sind. Dies bedeutet, dass das Build-System nicht neu erstellt, was seit dem letzten Lauf nicht geändert wurde, d. H. Sie müssen Ihre Rohdaten nicht erneut herunterladen. Eine andere Sache, nach der ich suchen werde, sind inkrementelle Builds, wenn sich die Abhängigkeit ändert. Stellen Sie sich vor, wir haben ein Diagramm der Abhängigkeiten A -> B -> C Wird Ziel C wiederhergestellt, wenn sich B ändert? Wenn ein?
  3. Überprüfen, ob eine Neuerstellung ausgelöst wird, wenn der Quellcode geändert wird, d. H. Wir ändern den Parameter des generierten Diagramms. Beim nächsten Erstellen des Bildes muss es neu erstellt werden.
  4. Überprüfen der Möglichkeiten zum Bereinigen von Build-Artefakten, d. H. Entfernen von Dateien, die während des Builds erstellt wurden, und Zurücksetzen auf den sauberen Quellcode.

Ich werde nicht alle Build-Ziele aus Mateusz 'Post verwenden, nur drei davon, um die Prinzipien zu veranschaulichen.

Der gesamte Code ist auf GitHub verfügbar.

CMake


CMake ist ein Build-Skript-Generator, der Eingabedateien für verschiedene Build-Systeme generiert. Und sein Name steht für plattformübergreifende Marke. CMake ist ein Software-Engineering-Tool. Das Hauptanliegen ist das Erstellen von ausführbaren Dateien und Bibliotheken. CMake weiß also, wie man Ziele aus dem Quellcode in unterstützten Sprachen erstellt. CMake wird in zwei Schritten ausgeführt: Konfiguration und Generierung. Während der Konfiguration ist es möglich, den zukünftigen Build nach Bedarf zu konfigurieren. In diesem Schritt werden beispielsweise vom Benutzer bereitgestellte Variablen angegeben. Die Generierung ist normalerweise unkompliziert und erzeugt Dateien, mit denen Build-Systeme arbeiten können. Mit CMake können Sie weiterhin make , aber anstatt Makefile direkt zu schreiben, schreiben Sie eine CMake-Datei, die das Makefile für Sie generiert.

Ein weiteres wichtiges Konzept ist, dass CMake Out-of-Source-Builds fördert. Out-of-Source-Builds halten den Quellcode von Artefakten fern, die er erzeugt. Dies ist sehr sinnvoll für ausführbare Dateien, bei denen eine einzelne Quellcodebasis unter verschiedenen CPU-Architekturen und Betriebssystemen kompiliert werden kann. Dieser Ansatz kann jedoch der Arbeitsweise vieler Datenwissenschaftler widersprechen. Es scheint mir, dass die Data Science Community tendenziell eine hohe Kopplung von Daten, Code und Ergebnissen aufweist.

Mal sehen, was wir brauchen, um unsere Ziele mit CMake zu erreichen. Es gibt zwei Möglichkeiten, benutzerdefinierte Dinge in CMake zu definieren: benutzerdefinierte Ziele und benutzerdefinierte Befehle. Leider müssen wir beide verwenden, was zu mehr Typisierung im Vergleich zu Vanila-Makefile führt. Ein benutzerdefiniertes Ziel wird als immer veraltet angesehen, d. H. Wenn es ein Ziel zum Herunterladen von Rohdaten gibt, lädt CMake es immer wieder herunter. Eine Kombination aus benutzerdefiniertem Befehl und benutzerdefiniertem Ziel ermöglicht es, Ziele auf dem neuesten Stand zu halten.

Für unser Projekt erstellen wir eine Datei mit dem Namen CMakeLists.txt und legen sie im Stammverzeichnis des Projekts ab. Schauen wir uns den Inhalt an:

 cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR) project(Cmake_in_ml VERSION 0.1.0 LANGUAGES NONE) 

Dieser Teil ist grundlegend. Die zweite Zeile definiert den Namen Ihres Projekts und Ihre Version und gibt an, dass wir keine integrierte Sprachunterstützung verwenden (Sinus werden wir Python-Skripte nennen).

Unser erstes Ziel wird den IRIS-Datensatz herunterladen:

 SET(IRIS_URL "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data" CACHE STRING "URL to the IRIS data") set(IRIS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data/raw) set(IRIS_FILE ${IRIS_DIR}/iris.csv) ADD_CUSTOM_COMMAND(OUTPUT ${IRIS_FILE} COMMAND ${CMAKE_COMMAND} -E echo "Downloading IRIS." COMMAND python src/data/download.py ${IRIS_URL} ${IRIS_FILE} COMMAND ${CMAKE_COMMAND} -E echo "Done. Checkout ${IRIS_FILE}." WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) ADD_CUSTOM_TARGET(rawdata ALL DEPENDS ${IRIS_FILE}) 

Die erste Zeile definiert den Parameter IRIS_URL , der dem Benutzer während des Konfigurationsschritts zur Verfügung gestellt wird. Wenn Sie die CMake-GUI verwenden, können Sie diese Variable über die GUI festlegen:



Als Nächstes definieren wir Variablen mit dem heruntergeladenen Speicherort des IRIS-Datasets. Dann fügen wir einen benutzerdefinierten Befehl hinzu, der IRIS_FILE als Ausgabe erzeugt. Am Ende definieren wir benutzerdefinierte Ziel- rawdata , die von rawdata abhängen. IRIS_FILE bedeutet, dass zum Erstellen von rawdata IRIS_FILE muss. Option ALL des benutzerdefinierten Ziels besagt, dass rawdata eines der zu erstellenden Standardziele sind. Beachten Sie, dass ich CMAKE_CURRENT_SOURCE_DIR verwende, um die heruntergeladenen Daten im CMAKE_CURRENT_SOURCE_DIR und nicht im Build-Ordner zu speichern. Dies ist nur, um es das gleiche wie Mateusz zu machen.

Okay, mal sehen, wie wir es nutzen können. Ich führe es derzeit auf Windows mit installiertem MinGW-Compiler aus. Möglicherweise müssen Sie die Generatoreinstellung an Ihre Bedürfnisse anpassen (führen Sie cmake --help , um die Liste der verfügbaren Generatoren cmake --help ). Starten Sie das Terminal und wechseln Sie in den übergeordneten Ordner des Quellcodes.

 mkdir overcome-the-chaos-build cd overcome-the-chaos-build cmake -G "MinGW Makefiles" ../overcome-the-chaos 

Ergebnis
- Konfiguration abgeschlossen
- Generieren erledigt
- Build-Dateien wurden geschrieben in: C: / home / workspace / überwinden-das-Chaos-Build

Mit modernem CMake können wir das Projekt direkt aus CMake erstellen. Dieser Befehl ruft build all Befehl build all :

 cmake --build . 

Ergebnis
Scannen von Abhängigkeiten von Ziel-Rohdaten
[100%] Ziel-Rohdaten erstellt

Wir können auch die Liste der verfügbaren Ziele anzeigen:

 cmake --build . --target help 

Und wir können heruntergeladene Dateien entfernen durch:

 cmake --build . --target clean 

Stellen Sie sicher, dass wir das saubere Ziel nicht manuell erstellen mussten.

Gehen wir nun zum nächsten Ziel - den vorverarbeiteten IRIS-Daten. Mateusz erstellt zwei Dateien aus einer einzigen Funktion: processed.pickle und processed.xlsx . Sie können sehen, wie er diese Excel-Datei mit rm mit Platzhalter bereinigt. Ich denke, das ist kein sehr guter Ansatz. In CMake haben wir zwei Möglichkeiten, damit umzugehen. Die erste Option ist die Verwendung der Verzeichniseigenschaft ADDITIONAL_MAKE_CLEAN_FILES . Der Code lautet:

 SET(PROCESSED_FILE ${CMAKE_CURRENT_SOURCE_DIR}/data/processed/processed.pickle) ADD_CUSTOM_COMMAND(OUTPUT ${PROCESSED_FILE} COMMAND python src/data/preprocess.py ${IRIS_FILE} ${PROCESSED_FILE} --excel data/processed/processed.xlsx WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS rawdata ${IRIS_FILE} ) ADD_CUSTOM_TARGET(preprocess DEPENDS ${PROCESSED_FILE}) # Additional files to clean set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/processed/processed.xlsx ) 

Die zweite Option besteht darin, eine Liste von Dateien als benutzerdefinierte Befehlsausgabe anzugeben:

 LIST(APPEND PROCESSED_FILE "${CMAKE_CURRENT_SOURCE_DIR}/data/processed/processed.pickle" "${CMAKE_CURRENT_SOURCE_DIR}/data/processed/processed.xlsx" ) ADD_CUSTOM_COMMAND(OUTPUT ${PROCESSED_FILE} COMMAND python src/data/preprocess.py ${IRIS_FILE} data/processed/processed.pickle --excel data/processed/processed.xlsx WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS rawdata ${IRIS_FILE} src/data/preprocess.py ) ADD_CUSTOM_TARGET(preprocess DEPENDS ${PROCESSED_FILE}) 

In diesem Fall habe ich die Liste erstellt, sie jedoch nicht im benutzerdefinierten Befehl verwendet. Ich kenne keine Möglichkeit, auf Ausgabeargumente eines benutzerdefinierten Befehls darin zu verweisen.

Eine weitere interessante Sache ist die Verwendung von depends in diesem benutzerdefinierten Befehl. Wir legen die Abhängigkeit nicht nur von einem benutzerdefinierten Ziel fest, sondern auch von der Ausgabe und dem Python-Skript. Wenn wir IRIS_FILE keine Abhängigkeit IRIS_FILE , iris.csv manuelle Ändern von iris.csv nicht zur IRIS_FILE des preprocess . Nun, Sie sollten Dateien in Ihrem Build-Verzeichnis zunächst nicht manuell ändern. Lass es dich nur wissen. Weitere Details in Sam Thursfields Beitrag . Die Abhängigkeit zum Python-Skript wird benötigt, um das Ziel neu zu erstellen, wenn sich das Python-Skript ändert.

Und schließlich das dritte Ziel:

 SET(EXPLORATORY_IMG ${CMAKE_CURRENT_SOURCE_DIR}/reports/figures/exploratory.png) ADD_CUSTOM_COMMAND(OUTPUT ${EXPLORATORY_IMG} COMMAND python src/visualization/exploratory.py ${PROCESSED_FILE} ${EXPLORATORY_IMG} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${PROCESSED_FILE} src/visualization/exploratory.py ) ADD_CUSTOM_TARGET(exploratory DEPENDS ${EXPLORATORY_IMG}) 

Dieses Ziel ist im Grunde das gleiche wie das zweite.

Zum Abschluss. CMake sieht chaotisch und schwieriger aus als Make. In der Tat kritisieren viele Leute CMake wegen seiner Syntax. Nach meiner Erfahrung wird das Verständnis kommen und es ist absolut möglich, auch sehr komplizierte CMake-Dateien zu verstehen.

Sie werden immer noch viel selbst kleben, da Sie die richtigen Variablen weitergeben müssen. Ich sehe keine einfache Möglichkeit, die Ausgabe eines benutzerdefinierten Befehls in einem anderen zu referenzieren. Es scheint möglich zu sein, dies über benutzerdefinierte Ziele zu tun.

Pybuilder


Der PyBuilder-Teil ist sehr kurz. Ich habe Python 3.7 in meinem Projekt verwendet und PyBuilder aktuelle Version 0.11.17 unterstützt es nicht. Die vorgeschlagene Lösung ist die Verwendung der Entwicklungsversion. Diese Version ist jedoch an pip v9 gebunden. Pip ist zum Zeitpunkt des Schreibens Version 19.3. Schade. Nachdem ich ein bisschen herumgespielt hatte, funktionierte es bei mir überhaupt nicht. Die PyBuilder-Bewertung war von kurzer Dauer.

pynt


Pynt basiert auf Python, was bedeutet, dass wir Python-Funktionen direkt verwenden können. Es ist nicht erforderlich, sie mit einem Klick zu verpacken und eine Befehlszeilenschnittstelle bereitzustellen. Pynt kann jedoch auch Shell-Befehle ausführen. Ich werde Python-Funktionen verwenden.

Build-Befehle werden in einer Datei build.py . Ziele / Aufgaben werden mit Funktionsdekoratoren erstellt. Aufgabenabhängigkeiten werden über denselben Dekorator bereitgestellt.

Da ich Python-Funktionen verwenden möchte, muss ich sie in das Build-Skript importieren. Pynt enthält das aktuelle Verzeichnis nicht als Python-Skript. Schreiben Sie also Folgendes:

 from src.data.download import pydownload_file 

wird nicht funktionieren. Wir müssen tun:

 import os import sys sys.path.append(os.path.join(os.path.dirname(__file__), '.')) from src.data.download import pydownload_file 

Meine anfängliche build.py Datei war wie build.py :

 #!/usr/bin/python import os import sys sys.path.append(os.path.join(os.path.dirname(__file__), '.')) from pynt import task from path import Path import glob from src.data.download import pydownload_file from src.data.preprocess import pypreprocess iris_file = 'data/raw/iris.csv' processed_file = 'data/processed/processed.pickle' @task() def rawdata(): '''Download IRIS dataset''' pydownload_file('https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', iris_file) @task() def clean(): '''Clean all build artifacts''' patterns = ['data/raw/*.csv', 'data/processed/*.pickle', 'data/processed/*.xlsx', 'reports/figures/*.png'] for pat in patterns: for fl in glob.glob(pat): Path(fl).remove() @task(rawdata) def preprocess(): '''Preprocess IRIS dataset''' pypreprocess(iris_file, processed_file, 'data/processed/processed.xlsx') 

Und das preprocess hat nicht funktioniert. Es beschwerte sich ständig über Eingabeargumente der pypreprocess Funktion. Es scheint, dass Pynt optionale Funktionsargumente nicht sehr gut verarbeitet. Ich musste das Argument für die Erstellung der Excel-Datei entfernen. Denken Sie daran, wenn Ihr Projekt Funktionen mit optionalen Argumenten hat.

Wir können pynt aus dem Ordner des Projekts ausführen und alle verfügbaren Ziele auflisten:

 pynt -l 

Ergebnis
 Tasks in build file build.py: clean Clean all build artifacts exploratory Make an image with pairwise distribution preprocess Preprocess IRIS dataset rawdata Download IRIS dataset Powered by pynt 0.8.2 - A Lightweight Python Build Tool. 


Machen wir die paarweise Verteilung:

 pynt exploratory 

Ergebnis
 [ build.py - Starting task "rawdata" ] Downloading from https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data to data/raw/iris.csv [ build.py - Completed task "rawdata" ] [ build.py - Starting task "preprocess" ] Preprocessing data [ build.py - Completed task "preprocess" ] [ build.py - Starting task "exploratory" ] Plotting pairwise distribution... [ build.py - Completed task "exploratory" ] 


Wenn wir jetzt denselben Befehl erneut pynt exploratory (dh pynt exploratory ), wird eine vollständige pynt exploratory . Pynt hat nicht verfolgt, dass sich nichts geändert hat.

Fertiger


Paver sieht fast genauso aus wie Pynt. Es unterscheidet sich geringfügig in einer Weise, wie man Abhängigkeiten zwischen Zielen definiert (ein anderer Dekorateur @needs ). Paver führt jedes Mal eine vollständige Neuerstellung durch und spielt nicht gut mit Funktionen, die optionale Argumente haben. Bauanweisungen finden Sie in der Datei pavement.py .

doit


Doit scheint ein Versuch zu sein, ein wirklich erstelltes Automatisierungstool in Python zu erstellen. Es kann Python-Code und Shell-Befehle ausführen. Es sieht ziemlich vielversprechend aus. Was (im Kontext unserer spezifischen Ziele) zu fehlen scheint, ist die Fähigkeit, mit Abhängigkeiten zwischen Zielen umzugehen. Angenommen, wir möchten eine kleine Pipeline erstellen, in der die Ausgabe von Ziel A als Eingabe von Ziel B verwendet wird. Nehmen wir an, wir verwenden Dateien als Ausgaben. Ziel A erstellt also eine Datei mit dem Namen outA .



Um eine solche Pipeline zu erstellen, outA wir die Datei outA zweimal in Ziel A angeben (als Ergebnis eines Ziels, aber auch den Namen als Teil der Zielausführung zurückgeben). Dann müssen wir es als Eingabe für Ziel B angeben. Es gibt also insgesamt 3 Stellen, an denen wir Informationen über die Datei outA . Und selbst nachdem wir dies getan haben, führt die Änderung der Datei outA nicht zu einer automatischen outA von Ziel B. Dies bedeutet, dass doit nur dann prüft, ob Ziel B auf dem neuesten Stand ist, ohne dass eines überprüft wird der Abhängigkeiten. Um dies zu überwinden, müssen wir outA viermal angeben - auch als outA von Ziel B. Ich sehe dies als Nachteil. Sowohl Make als auch CMake können mit solchen Situationen richtig umgehen.

Abhängigkeiten in doit sind dateibasiert und werden als Zeichenfolgen ausgedrückt. Dies bedeutet, dass die Abhängigkeiten ./myfile.txt und myfile.txt als unterschiedlich angesehen werden. Wie ich oben geschrieben habe, finde ich die Art und Weise, wie Informationen von Ziel zu Ziel (bei Verwendung von Python-Zielen) weitergegeben werden, etwas seltsam. Das Ziel hat eine Liste von Artefakten, die es produzieren wird, aber ein anderes Ziel kann sie nicht verwenden. Stattdessen muss die Python-Funktion, die das Ziel bildet, ein Wörterbuch zurückgeben, auf das in einem anderen Ziel zugegriffen werden kann. Sehen wir uns ein Beispiel an:

 def task_preprocess(): """Preprocess IRIS dataset""" pickle_file = 'data/processed/processed.pickle' excel_file = 'data/processed/processed.xlsx' return { 'file_dep': ['src/data/preprocess.py'], 'targets': [pickle_file, excel_file], 'actions': [doit_pypreprocess], 'getargs': {'input_file': ('rawdata', 'filename')}, 'clean': True, } 

Hier hängt der rawdata von den rawdata . Die Abhängigkeit wird über getargs Eigenschaft getargs bereitgestellt. Es heißt, dass das Argument input_file der Funktion doit_pypreprocess der Ausgabedateiname der Ziel- rawdata . Schauen Sie sich das vollständige Beispiel in der Datei dodo.py an.

Es kann sich lohnen, die Erfolgsgeschichten von doit zu lesen. Es hat definitiv nette Funktionen wie die Möglichkeit, eine benutzerdefinierte, aktuelle Zielprüfung bereitzustellen.

Luigi


Luigi unterscheidet sich von anderen Tools, da es sich um ein System zum Bau komplexer Pipelines handelt. Es erschien auf meinem Radar, nachdem mir ein Kollege erzählt hatte, dass er Make ausprobiert hatte, es nie unter Windows / Linux verwenden konnte und nach Luigi zog.

Luigi strebt serienreife Systeme an. Es wird mit einem Server geliefert, mit dem Sie Ihre Aufgaben visualisieren oder einen Verlauf der Aufgabenausführungen abrufen können. Der Server wird als zentraler Schedler bezeichnet . Für Debugging-Zwecke steht ein lokaler Scheduler zur Verfügung.

Luigi unterscheidet sich auch von anderen Systemen darin, wie Aufgaben erstellt werden. Lugi reagiert nicht auf eine vordefinierte Datei (wie dodo.py , pavement.py oder dodo.py ). Vielmehr muss man einen Python-Modulnamen übergeben. Wenn wir also versuchen, es auf ähnliche Weise wie andere Tools zu verwenden (eine Datei mit Aufgaben im Stammverzeichnis des Projekts platzieren), funktioniert es nicht. Wir müssen entweder unser Projekt installieren oder die Umgebungsvariable PYTHONPATH ändern, indem PYTHONPATH den Pfad zum Projekt hinzufügen.

Was an luigi großartig ist, ist die Art und Weise, Abhängigkeiten zwischen Aufgaben anzugeben. Jede Aufgabe ist eine Klasse. Die Methodenausgabe teilt Luigi mit, wo die Ergebnisse der Aufgabe landen werden. Ergebnisse können ein einzelnes Element oder eine Liste sein. Methode requires spezifiziert Aufgabenabhängigkeiten (andere Aufgaben; obwohl es möglich ist, eine Abhängigkeit von sich selbst zu machen). Und das war's. Was in Aufgabe A als output angegeben ist, wird als Eingabe an Aufgabe B übergeben, wenn Aufgabe B auf Aufgabe A beruht.


Luigi kümmert sich nicht um Dateimodifikationen. Es kümmert sich um die Existenz von Dateien. Es ist daher nicht möglich, Neuerstellungen auszulösen, wenn sich der Quellcode ändert. Luigi verfügt nicht über eine integrierte Clean- Funktionalität.

Luigi-Aufgaben für dieses Projekt sind in der Datei luigitasks.py verfügbar. Ich starte sie vom Terminal aus:

 luigi --local-scheduler --module luigitasks Exploratory 

Vergleich


Die folgende Tabelle fasst zusammen, wie verschiedene Systeme in Bezug auf unsere spezifischen Ziele funktionieren.
Ziel mit Abhängigkeit definierenInkrementelle BuildsInkrementelle Builds, wenn der Quellcode geändert wirdMöglichkeit herauszufinden, welche Artefakte während des clean
CMakejajajaja
Pyntjaneinneinnein
Fertigerjaneinneinnein
doitEtwas jajajaja
Luigijaneinneinnein

Source: https://habr.com/ru/post/de451962/


All Articles