Reading Time: 8 minutes

Das Management von Abhängigkeiten in wissenschaftlicher Python ist einer der wichtigsten Teile der reproduzierbaren Forschung. Eine Simulation kann Monate später fehlschlagen, da die Paketversionen geändert, ein Python-Interpreter verschoben oder eine numerische Bibliothek in einer Weise aktualisiert wurde, die sich auf die Ergebnisse auswirkt.

In diesem Leitfaden erfahren Sie, wie Lockfiles, Umgebungen und moderne Paketmanager Forschern helfen, wissenschaftliche Python-Workflows reproduzierbar, tragbar und einfacher zu warten.

Schlüssel zum Mitnehmen

  • Lockfiles sind einer der wirkungsvollsten Schritte für reproduzierbare wissenschaftliche Python-Workflows.
  • uv ist ein schneller moderner Paketmanager und wird zunehmend als Alternative zu PIP, PIP-Tools und Poesie eingesetzt.
  • PEP 751 führt ein standardisiertes Lockfile-Format pylock.toml ein, um die Fragmentierung des Werkzeugs zu reduzieren.
  • Conda bleibt wichtig für wissenschaftliche Python-Projekte mit Nicht-Python-Abhängigkeiten wie C, C++, MPI, HDF5 und CUDA.
  • Ihre Werkzeugauswahl sollte Ihrem Workflow entsprechen: uv für Geschwindigkeit und Reproduzierbarkeit, Conda für wissenschaftliche und HPC-Stacks und Poesie für ausgereifte Publishing-Pipelines.

Der Hidden Failure-Modus in Scientific Python

Jeder wissenschaftliche Computerforscher sieht schließlich das gleiche Problem. Eine Simulation hat letzten Monat funktioniert, aber jetzt schlägt sie mit einer Versionsfehlanpassung fehl. Schlimmer noch, es kann immer noch laufen, aber subtil unterschiedliche Ergebnisse hervorbringen.

Dies ist nicht nur eine Unannehmlichkeit. Es handelt sich um einen Reproduzierbarkeitsfehler. Die Rechenumgebung wurde geändert, einschließlich Paketversionen, Python-Interpreter oder Abhängigkeiten auf niedrigerer Ebene. Ihr Code ist entweder kaputt gegangen oder hat lautlos Ergebnisse erzielt, die nicht mehr dem ursprünglichen Lauf entsprechen.

Die Hauptursache sind in der Regel nicht angeheftete Abhängigkeiten. Selbst wenn der Code versionsgesteuert ist, bleibt die Arbeit an eine bestimmte Maschine und Moment in der Zeit gebunden, wenn die Umgebung nicht reproduzierbar ist.

Wissenschaftliche Python macht dieses Problem besonders ernst. Im Gegensatz zu vielen Webprojekten hängt das wissenschaftliche Rechnen häufig von komplexen Ketten numerischer Bibliotheken, kompilierter Pakete und hardwareempfindlicher Builds ab. NumPy, Scipy, Fipy, HDF5, MPI, OpenBlas und bestimmte Python-Versionen müssen alle zusammenarbeiten.

Die Lösung besteht darin, Abhängigkeiten absichtlich zu verwalten. Verwenden Sie Lockfiles, um genaue Versionen einzufrieren, Umgebungen in der Versionskontrolle zu verfolgen und zu dokumentieren, wie die Umgebung neu erstellt werden soll.

Was ist ein Lockfile?

Ein Lockfile ist eine Momentaufnahme der genauen Softwareumgebung eines Projekts. Es zeichnet die spezifischen Versionen aller Abhängigkeiten auf, einschließlich der Subabhängigkeiten, die bei der letzten Konfiguration des Projekts installiert wurden.

Betrachten Sie es als ein eingefrorenes Rezept für Ihre Software-Setup. Jeder kann die gleiche Umgebung später neu erstellen, auch wenn sich die Paketversionen im Upstream geändert haben.

ohne Lockfiles

# requirements.txt without a lockfile
numpy>=1.25.0
scipy>=1.11.0
fipy>=4.3.0

# On another machine or after a month:
pip install -r requirements.txt

# This might install newer versions:
# numpy 1.26.x, scipy 1.12.x, or different dependency builds

Diese Art der Einrichtung ermöglicht das Verschieben von Paketversionen. Der Code kann immer noch ausgeführt werden, aber das numerische Verhalten, die Präzision, das Solververhalten oder die Abhängigkeitsinterne können sich ändern.

Mit Lockfiles

# uv.lock or another lockfile records exact resolved versions

uv sync

# Anyone who runs the sync command gets the same resolved environment

Dies ist für Simulationsprojekte von Bedeutung, da numerische Bibliotheken die Codepfade über Versionen hinweg ändern können. Das Gleitkommaverhalten kann zwischen Builds unterschiedlich sein. PDE-Solver und wissenschaftliche Frameworks können sich auch versionsübergreifend verhalten.

Ein Lockfile verringert diese Unsicherheit, indem die Installation deterministisch gemacht wird.

Die Python-Abhängigkeitsverwaltungslandschaft

Das Python-Ökosystem verfügt über mehrere praktische Optionen für das Abhängigkeitsmanagement. Jedes Werkzeug hat unterschiedliche Stärken, und die richtige Wahl hängt davon ab, ob das Projekt rein Python, HPC-fokussiert, paketorientiert oder auf langfristige Reproduzierbarkeit ausgelegt ist.

UV: Die moderne Schnelloption

uv ist ein rostbasierter Paketmanager, der von Astral erstellt wurde. Ziel ist es, mehrere gängige Python-Tools, darunter PIP, PIP-Tools, PIPX, PYENV und VirtualEnv, durch einen einzigen schnellen Workflow zu ersetzen.

Forscher wechseln aus mehreren Gründen zu uv:

  1. Geschwindigkeit uv kann Pakete viel schneller installieren als herkömmliche PIP-basierte Workflows, insbesondere beim Caching.
  2. Universal Lockfile. Ein einziger uv.lock kann reproduzierbare Installationen über Plattformen hinweg unterstützen.
  3. PIP-Kompatibilität. Befehle wie uv pip install erleichtern die Migration.
  4. Python-Versionsverwaltung. uv Kann Python-Interpreter installieren und verwalten, wodurch die Notwendigkeit separater Tools verringert wird.
  5. Standalone-Installation. uv erfordert nicht zuerst die Installation von Python.

Verwenden Sie uv für neue Projekte, bei denen Geschwindigkeit, Reproduzierbarkeit und einfache Migration von PIP-Materie.

Es ist besonders nützlich für:

  • Neue Simulationsprojekte.
  • CI / CD-Pipelines, bei denen die Installationszeit wichtig ist.
  • Projekte, die Abhängigkeitsmanagement und Python-Versionsverwaltung zusammen benötigen.
  • Teams, die von PIP- oder PIP-Tools migrieren.

Grundlegender UV-Workflow

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create a new project with Python 3.11
uv init my-simulation --python 3.11
cd my-simulation

# Add dependencies
uv add numpy scipy fipy

# Generate a lockfile
uv lock

# Sync to install from the lockfile
uv sync

Der Hauptkompromiss ist, dass Poesie immer noch ausgereifte Veröffentlichungsworkflows und erweiterte Abhängigkeitsgruppenhandhabung hat. Wenn Sie ein wissenschaftliches Python-Paket für Pypi pflegen, ist Poesie möglicherweise immer noch attraktiv.

Poesie: Der etablierte Projektmanager

Poesie ist ein komplettes Projektmanagement-Tool. Es verarbeitet Abhängigkeitsauflösung, virtuelle Umgebungen, Paketerstellung und Veröffentlichung auf Pypi.

Forscher wählen aus mehreren Gründen immer noch Poesie:

  1. Abhängigkeitsgruppen. Poesie kann Entwicklung, Tests, Dokumentation und CI-Abhängigkeiten sauber trennen.
  2. Veröffentlichungsworkflow. Es verfügt über integrierte Unterstützung für das Erstellen und Veröffentlichen von Paketen.
  3. reifes Ökosystem. Poesie hat jahrelange Produktionsnutzung, umfangreiche Dokumentation und eine große Gemeinschaft.

Verwenden Sie Poesie, wenn:

  • Sie veröffentlichen ein Python-Paket in Pypi.
  • Sie benötigen eine ausgereifte Abhängigkeitsgruppenverwaltung.
  • Ihr Team schätzt eine lange Erfolgsbilanz und etablierte Dokumentationen.

Der Kompromiss ist Geschwindigkeit. Poesie kann länger als uv für Kaltinstallationen, Lockfile-Generierung und Paketergänzungen dauern. Bei kleinen Projekten kann das keine Rolle spielen. Bei großen Projekten und CI-Pipelines kann sich der Unterschied bemerkbar machen.

Conda: Das wissenschaftliche Heftklammern

Conda bleibt eines der wichtigsten Werkzeuge für wissenschaftliche Python, insbesondere wenn das Projekt keine Abhängigkeiten benötigt.

Conda ist für die Forschung nützlich, da es Python-Pakete, R-Pakete, kompilierte Bibliotheken, Compiler, MPI, HDF5, CUDA und andere Abhängigkeiten auf Systemebene in einer Umgebung verwalten kann.

Conda ist wichtig, wenn:

  • Sie benötigen Nicht-Python-Abhängigkeiten wie C, C++, MPI, HDF5, FFTW oder CUDA.
  • Sie zielen auf HPC-Cluster ab.
  • Ihre wissenschaftlichen Bibliotheken hängen von kompiliertem C- oder Fortran-Code ab.
  • Sie arbeiten über Python und R.

Der Kompromiss besteht darin, dass Conda für die Auflösung der Abhängigkeit von Python-Abhängigkeit langsamer als uv sein kann und möglicherweise nicht so einfach universelle plattformübergreifende Lockfiles erzeugt.

Grundlegender Conda-Workflow

# Create environment
conda create -n my-sim python=3.11
conda activate my-sim

# Install packages, including non-Python dependencies
conda install numpy scipy hdf5 openmpi

# Export to environment file
conda env export --no-builds | grep -v "prefix:" > environment.yml

# Restore the environment
conda env create -f environment.yml

PIP-Tools: Die minimalistische Option

pip-tools Überbrückt herkömmliche PIP-Workflows und Lockfiles. Es ist leicht und bleibt in der Nähe der PIP-Oberfläche.

Verwenden Sie PIP-Tools, wenn:

  • Sie wollen einen einfachen Ansatz.
  • Sie migrieren von PIP und möchten kein größeres Tool lernen.
  • Ihr Projekt ist klein und benötigt keine fortgeschrittenen Abhängigkeitsgruppen.

Der Kompromiss besteht darin, dass PIP-Tools plattformspezifische Ausgabedateien generieren können. Es ist auch weniger umfassend als Poesie oder uv .

PEP 751: Die Zukunft der Lockfiles

PEP 751 schlägt ein standardisiertes Dateiformat für die Aufzeichnung von Python-Abhängigkeiten vor, damit Umgebungen reproduzierbar installiert werden können. Dieses Format heißt pylock.toml.

Was es löst

Python-Abhängigkeitswerkzeuge haben in der Vergangenheit verschiedene Lockfile-Formate verwendet. PDM, PIP Freeze, PIP-Tools, Poesie und uv Alle näheren sich die Umgebungs- sperrung.

Dies führt zu mehreren Problemen:

  • Verkäufersperre. Es kann schwierig sein, zwischen Werkzeugen zu wechseln.
  • Werkzeugfragmentierung. Sicherheitsscanner und Automatisierungstools unterstützen möglicherweise nur einige Formate.
  • Prüfungsschwierigkeiten. Unterschiedliche Formate haben unterschiedliche Syntax und Konventionen.

PEP 751 schlägt pylock.toml als standardisiertes Format vor.

Warum es für wissenschaftliche Python wichtig ist

Das vorgeschlagene Format ist für die Forschung nützlich, da es:

  • Von Menschen lesbar, mit toml.
  • Maschinengeneriert, damit Werkzeuge konsistente Ausgabe schreiben können.
  • Verbrauchsmaterial durch Nicht-Python-Tools.
  • Sicher durch Design, mit kryptografischen Hashes für den Schutz der Lieferkette.
  • Flexibel genug, um mehrere Umgebungen oder Abhängigkeitsgruppen darzustellen.

Sobald pylock.toml weit verbreitet ist, kann der Bedarf an werkzeugspezifischen Lockfile-Formaten verringert werden. Für Forscher bedeutet dies eine bessere Interoperabilität. Ein Lockfile könnte von jedem konformen Tool verbraucht und einfacher von externen Diensten auditiert werden.

Das Reproduzierbarkeitsspektrum

Reproduzierbarkeit ist ein Spektrum. Das richtige Niveau ist abhängig von Risiko, Projektdauer und Veröffentlichungsanforderungen.

Ebene Sich nähern Kosten Reproduzierbarkeit am besten für
Gut Dokumentabhängigkeiten in Readme Minimal Manuelle Überprüfung Schnelle Skripte und Tutorials
Besser Umgebungsdatei wie requirements.txt oder environment.yml Niedrig Automatisierte Installation Gemeinsame Projekte und Mitarbeiter
Beste Lockfile Plus versionsgesteuerte Umgebung Mäßig Exakte Reproduktion Publikationen und Langzeitarchive
Maximal Containerisierung mit Docker oder Singularität Hoch Starke Isolation HPC und veröffentlichte Workflows

Für Forschungsprojekte gilt es, die exakten Versionen in requirements.txt oder environment.yml anzuheften. Der empfohlene Ansatz ist die Verwendung von uv lock oder Conda-Export, um eine reproduzierbare Umgebungsdatei zu erstellen. Die beste Vorgehensweise besteht darin, diese Datei in git zu verfolgen und zu dokumentieren, wie die Umgebung in der Readme neu erstellt wird.

Praktische Workflows für wissenschaftliche Projekte

Workflow 1: Neues Simulationsprojekt mit UV

# Initialize project
uv init my-simulation --python 3.11
cd my-simulation

# Add core dependencies
uv add numpy scipy matplotlib

# Add scientific libraries
uv add fipy mpmath

# Generate lockfile
uv lock

# Add dev dependencies
uv add --group dev pytest black ruff

# Commit everything
git add pyproject.toml uv.lock
git commit -m "Initial project structure with pinned dependencies"

Dies funktioniert, weil die Datei uv.lock an git festgeschrieben ist. Jeder, der das Repository klont und uv sync ausführt, erhält die gleichen aufgelösten Versionen.

Workflow 2: HPC-Projekt mit Conda und Singularität

# On your workstation
conda create -n hpc-sim python=3.11
conda activate hpc-sim
conda install numpy scipy hdf5 openmpi

# Export environment
conda env export --no-builds | grep -v "prefix:" > environment.yml

# Build Singularity image from Docker
docker build -t my-sim:latest .
singularity build my-sim.sif docker://my-sim:latest

# Transfer to HPC cluster
scp my-sim.sif hpc-cluster:/scratch/

Dies funktioniert, weil Conda Abhängigkeiten von der Workstation verwaltet, während Singularity HPC-kompatible Containerisierung bereitstellt. Die Datei environment.yml kann versionsgesteuert und auf einem anderen System neu erstellt werden.

Workflow 3: Migration von PIP zu UV

# Start with existing requirements.txt
pip install uv

# Replace pip with uv for installs
uv pip install -r requirements.txt

# Generate a uv lockfile
uv lock

# From now on, use uv sync instead of pip install
uv sync

Dieser Migrationspfad ist einfach, da uv mit vielen PIP-Workflows kompatibel ist. Die uv.lock-Datei wird zur einzigen Wahrheitsquelle für die Umgebung.

häufige Fehler und wie man sie vermeidet

Fehler 1: Verwenden nicht angehefteter Abhängigkeiten

# WRONG: Allows automatic updates
numpy>=1.0
scipy>=1.0

# RIGHT: Pin exact versions
numpy==1.26.4
scipy==1.11.4

Kleinere Versionsänderungen können numerisches Verhalten, Konvergenzkriterien oder Gleitkomma-Präzision verändern. Pin exakte Versionen, wenn die Reproduzierbarkeit wichtig ist.

Fehler 2: Kein Lockfile festlegen

Wenn Ihr Repository pyproject.toml aber kein Lockfile enthält, ist Ihr Projekt nicht vollständig reproduzierbar. Ein Lockfile ist die Mindestanforderung für deterministische Builds.

Generieren Sie ein Lockfile und begehen Sie es:

uv lock  # or conda export
git add uv.lock  # or environment.yml
git commit -m "Add lockfile for reproducible environment"

Fehler 3: Sub-Abhängigkeiten ignorieren

Selbst wenn Sie Pakete der obersten Ebene anheften, können Unterabhängigkeiten das Verhalten ändern.

# If you pin fipy but not its dependencies:
# numpy, mpmath, and other packages may upgrade independently

Verwenden Sie ein Tool, das den vollständigen Abhängigkeitsbaum auflöst und anheftet, z. B. uv, Conda oder Poesie.

Fehler 4: Plattformspezifische Umgebungen

Einige Tools können plattformspezifische Ausgaben generieren. Wenn Sie unter macOS entwickeln, aber unter Linux bereitstellen, können Umgebungsdateien fehlschlagen oder unterschiedlich auflösen.

Verwenden Sie Tools, die plattformübergreifende Lockfiles unterstützen, oder generieren Sie Lockfiles auf der Zielplattform.

Fehler 5: Externe Datenabhängigkeiten

Wenn eine Simulation von externen APIs oder Datenbanken abhängt, die sich ändern, kann die Reproduzierbarkeit bei gesperrter Python-Umgebung brechen.

Snapshot externe Daten, wenn möglich. Wenn dies nicht möglich ist, verwenden Sie versionierte API-Endpunkte und dokumentieren Sie die genaue Version oder das Zugriffsdatum.

Was wir empfehlen: ein Entscheidungsrahmen

Verwenden Sie dieses Entscheidungsframework bei der Auswahl eines Abhängigkeitsmanagement-Tools für ein wissenschaftliches Python-Projekt.

  1. Benötigen Sie Nicht-Python-Abhängigkeiten wie C, C++, MPI, CUDA, HDF5 oder FFTW?

    • Ja: Verwenden Sie Conda oder Conda in Docker oder Singularity.
    • Nein: Weiter zur nächsten Frage.
  2. Veröffentlichen Sie ein Python-Paket für Pypi?

    • Ja: Betrachten Sie Poesie für ausgereifte Veröffentlichungsworkflows oder uv für Geschwindigkeit.
    • Nein: Weiter zur nächsten Frage.
  3. Arbeiten Sie in CI / CD-Pipelines?

    • Ja: Verwenden Sie uv, da schnellere Installationen die CI-Zeit verkürzen können.
    • Nein: Entweder uv, Conda oder Poesie können je nach Projekt funktionieren.
  4. Wie wichtig ist die plattformübergreifende Kompatibilität?

    • Hoch: Verwenden Sie uv , wo ein universelles Lockfile Ihren Anforderungen entspricht.
    • Moderat: Conda kann gut funktionieren, insbesondere auf Unix-ähnlichen Forschungssystemen.

Für die meisten neuen Forschungsprojekte ist uv eine starke Standardeinstellung, wenn Sie Geschwindigkeit und Reproduzierbarkeit benötigen. Kombinieren Sie für HPC-Projekte oder Workflows mit Nicht-Python-Abhängigkeiten Conda mit Containerisierung.

Zusammenfassung

Das Verwalten von Abhängigkeiten in wissenschaftlichem Python ist nicht optional. Es ist eine Grundlage reproduzierbarer Forschung.

Die wichtigsten Punkte sind:

  1. Lockfiles sind unerlässlich. Pin genaue Versionen und verfolgen Sie sie in git.
  2. uv ist eine starke moderne Option für schnelle, reproduzierbare Umgebungen.
  3. Conda bleibt für wissenschaftliche Stacks mit Nicht-Python-Abhängigkeiten von entscheidender Bedeutung.
  4. PEP 751 zielt darauf ab, Lockfile-Formate durch pylock.toml zu vereinheitlichen.
  5. Eine Readme mit übersichtlichen Installationsanweisungen ist die Mindestdokumentation, die jedes Projekt benötigt.

Beginnen Sie mit der Prüfung aktueller Projekte. Überprüfen Sie, ob Umgebungen dokumentiert und Abhängigkeiten angeheftet sind. Konvertieren Sie ein Projekt, um ein Lockfile zu verwenden. Die Vorabkosten zahlen sich aus, wenn Sie oder ein anderer Forscher die Simulation Monate oder Jahre später mit Zuversicht erneut ausführen müssen.

Verwandte Anleitungen

Referenzen und Weiterlesen