Install-Modi

TL;DR

  • Install-Modi entscheiden, wann die requirements.txt-Abhängigkeiten einer component installieren: zur Publish-Zeit, in das Image eingebacken, oder zur Deploy-Zeit, auf dem Node installiert, wenn der Container startet. Ein optionaler Schlüssel in component.yml wählt den Modus — lass ihn weg für Build-Zeit-Installation, setze install: node für Deploy-Zeit-Installation.
  • Die Build-Zeit-Installation backt jede Abhängigkeit in das veröffentlichte Image ein. Deploys sind reine Image-Pulls, daher sind sie schnell und vorhersagbar, aber das Image wächst mit dem Abhängigkeitssatz — erheblich für ML-Stacks — und der publish dauert länger wegen des Install-Schritts.
  • install: node veröffentlicht ein Skelett-Image, das den Quellcode und requirements.txt trägt, aber keine installierten Abhängigkeiten. Der erste Deploy auf einem frischen Node führt die Installation auf diesem Node aus; Same-Node-Redeploys verwenden die gecachte Installation wieder.
  • Die beiden Modi leisten dieselbe gesamte Install-Arbeit und unterscheiden sich nur darin, welche Lebenszyklus-Stufe dafür zahlt, sodass die Wahl ein Trade-off über Deploy-Geschwindigkeit, Image-Größe und Iterationszeit ist.
  • install: node zu entfernen ist ein Modus-Wechsel, keine Bereinigung. Es verschiebt die Install-Kosten zurück zum publish, vergrößert das Image und ändert das Deploy-Verhalten, daher bestätige, dass der neue Modus zum Workload passt, bevor du das Feld umlegst.

Mentales Modell — wo die Installation landet

   Build-time install (default; install: omitted)
   ┌────────────────────────────────────────────────────────────┐
   │ ppl component publish                                      │
   │   build_system image + pip install requirements.txt        │
   │     ─▶ FAT image (multi-GB for ML)                         │
   │                ─▶ registry                                 │
   │                                                            │
   │ ppl backend deploy                                         │
   │   every Node:  pull FAT image  ▶  start container          │
   └────────────────────────────────────────────────────────────┘

   install: node
   ┌────────────────────────────────────────────────────────────┐
   │ ppl component publish                                      │
   │   build_system image + Component source + requirements.txt │
   │     ─▶ SKELETON image (no deps installed)                  │
   │                ─▶ registry                                 │
   │                                                            │
   │ ppl backend deploy                                         │
   │   every Node:                                              │
   │     pull skeleton  ▶  install deps locally                 │
   │     (layered on the skeleton)  ▶  start container          │
   └────────────────────────────────────────────────────────────┘

Die gesamte Install-Arbeit ist dieselbe. Die Wahl ist, welche Stufe des Lebenszyklus dafür zahlt.

Warum zwei Modi existieren

Die Build-Zeit-Installation ist der Standard, weil ein reiner Image-Pull schnell und vorhersagbar ist. Sie landet einen bekannten Satz von Bits auf dem Node und startet den Container, ohne PyPI-Abhängigkeit zur Deploy-Zeit, ohne Auflösungsüberraschungen und ohne Pro-Node-Install-Variabilität. Diese Vorhersagbarkeit passt zu Produktions-Deployments und jedem Workload, der auf vielen frischen Nodes landet.

Die Kosten sind die Image-Größe. Ein ML-Stack mit PyTorch, CUDA, transformers, torchvision und einer Handvoll opencv-Extras backt in ein Multi-Gigabyte-Image. Jede veröffentlichte Version der component trägt dieses Image, und jeder Node, der die component ausführt, zieht es. Für ML-lastige components dominiert die Image-Größe: Pulls dauern Minuten, Registry-Speicher wächst mit jeder Version, und die Publish-Iterate-Schleife verlangsamt sich, weil jede Änderung das Einbacken erneut ausführt.

install: node passt zu Workloads, bei denen die Image-Größen-Kosten die Deploy-Zeit-Install-Kosten überwiegen. Das veröffentlichte Image ist ein Skelett — die runtime-Basis, der component-Quellcode und die requirements.txt, ohne installierte Abhängigkeiten. Der erste Deploy auf einem frischen Node führt pip install auf diesem Node aus, über dem Skelett gelayert; nachfolgende Deploys auf demselben Node verwenden die gecachte Installation wieder und starten fast augenblicklich.

install: node zahlt sich aus, wenn der Abhängigkeitssatz groß ist, dieselben Nodes über viele Deploys hinweg wiederverwendet werden und die Iterationsgeschwindigkeit der publish-Schleife wichtig ist. Ein Autor, der an einer großen ML-component iteriert, gewinnt ein viel kleineres Skelett-Image, das schnell veröffentlicht und die Install-Kosten nur beim ersten Deploy pro Node zahlt. Der gegenteilige Fall — ein kleiner Abhängigkeitssatz, kurzlebige Nodes, seltene Deploys — profitiert nicht, weil die Deploy-Zeit-Install-Maschinerie mehr kostet als das Einbacken gekostet hätte.

Die CUDA-Wheel-Variante ist die Aufgabe des Build-Systems, nicht des Install-Modus

Lies dies, wann immer eine component CUDA-, CPU-Feature- oder architekturspezifische Abhängigkeiten zieht.

Manche Python-wheels sind nicht über Hardware hinweg portierbar. torch+cu126 ist ein anderes Wheel als torch+cu128, OpenCV mit AVX-512 ist ein anderes Binary als der generische CPU-Build, und bitsandbytes liefert pro-CUDA-Version-wheels. Das Wheel, das eine component bekommt, wird durch den build_system-Schlüssel entschieden, nicht durch den Install-Modus: jedes CUDA-aromatisierte Build-System pinnt seinen eigenen Stack (torch+cu126 auf einem CUDA-12.6-Stack, torch+cu128 auf einem CUDA-12.8-Stack) und seine eigenen Paket-Index-URLs. Dasselbe gepinnte Template ist das, was die Deploy-Zeit-Node-Installation wiederverwendet.

install: node inspiziert nicht die GPU-Klasse, CPU-Features oder CUDA-Version des Node und wählt nicht automatisch ein Wheel für die Hardware, auf der es landet. Der Deploy-Zeit-Node-Build erhält nur das Skelett-Image und das feste Install-Template des Build-Systems; er löst dieselben wheels auf, die der Build-Zeit-Pfad aufgelöst hätte. Um eine bestimmte CUDA-Version anzuvisieren, wähle das passende build_system — das Umschalten des Install-Modus ändert nicht, welches Wheel installiert wird.

Durchgang — den Modus umlegen

# component.yml (build-time install — default)name: "..."language: pybuild_system: 2-cuda12.8-torch2.8-onnxrtgpu1.22# component.yml (deploy-time install on the Node)name: "..."language: pybuild_system: 2-cuda12.8-torch2.8-onnxrtgpu1.22install: node
ppl component publish -m "<msg>"ppl component promote

install: ist ein Freiform-String. Nur node verschiebt die Installation auf die Deploy-Zeit; das Weglassen des Felds — oder jeder andere Wert — verwendet das Build-Zeit-Einbacken. Es gibt kein spezielles install: build-Literal. Ein Nicht-node-Wert backt immer noch zur Build-Zeit ein, erfordert aber ein höheres Build-Tier (die Plattform legt einen zusätzlichen Install-Schritt auf den Standard-Builder) und wird nur in Plänen akzeptiert, die dieses Tier berechtigen.

Variationen — welchen Modus wählen

Wähle install: node wenn:

  • Der dep-Satz groß genug ist, dass die eingebackene Image-Größe die Pull-Zeit und den Registry-Speicher dominiert. Einbacken ist verschwenderisch.
  • Iterationsgeschwindigkeit mehr zählt als Deploy-Geschwindigkeit. Schnellere publish-Schleife beim Entwickeln — ein kleines Skelett veröffentlicht schnell und die Installation läuft nur beim ersten Deploy pro Node.

Wähle den Standard (Build-Zeit-Installation) wenn:

  • Der dep-Satz klein ist. Die Deploy-Zeit-Install-Maschinerie kostet mehr als das Einbacken.
  • Deploys auf vielen frischen Nodes landen. Die First-Touch-Installation würde dominieren.
  • Jeder Deploy muss ein garantiert-schneller Pull sein — keine PyPI-Abhängigkeit zur Deploy-Zeit.

Die CUDA-Wheel-Variante (torch+cu126 vs torch+cu128 usw.) wird durch den build_system-Schlüssel gesetzt, nicht durch den Install-Modus; install: node wählt nicht automatisch ein Wheel für die Hardware des Node aus. Wähle das passende build_system für die CUDA-Version, die du anvisierst.

Das Mischen von Dockerfile-base mit install: node funktioniert, aber Dockerfile-base läuft zur Publish-Zeit, während die Installation zur Deploy-Zeit läuft. Entsprechend anordnen.

Referenz-Snapshot

Das YAML-Feld

install: node    # OR omit entirely for build-time install

Den Modus erkennen

grep '^install:' component.yml
  • Zeile vorhanden und lautet install: node → Deploy-Zeit-Installation auf dem Node.
  • Zeile fehlt, auskommentiert oder jeder andere Wert als node → Build-Zeit-Installation (deps in das veröffentlichte Image eingebacken).

Image-Größen-Hinweis

  • Skelett-Image (install: node): die runtime-Basis plus der Quellcode, ohne installierte Abhängigkeiten.
  • Build-Zeit-installiertes Image: dasselbe, plus der gesamte Abhängigkeitssatz eingebacken — erheblich größer für einen ML-Stack.

Häufige Fehler

FehlerWarum er falsch ist
„Deploy ist langsam — lass mich install: node weglassen."Rückwärts. Es zu entfernen verlangsamt publish und bläht das Image auf; Gesamtarbeit unverändert.
install: node zu einer winzigen component hinzufügen.Die Deploy-Zeit-Install-Maschinerie kostet mehr als das Einbacken eines kleinen dep-Satzes.
requirements.txt bearbeiten und eine In-Place-Neuinstallation auf einem Live-deployment erwarten.Kein Modus installiert gegen ein laufendes deployment neu; du musst eine neue Version veröffentlichen und neu deployen.

Wo das hineinpasst

Install-Modi entscheiden, wo im Build-Deploy-Lebenszyklus die Abhängigkeitsinstallation landet. Die richtige Antwort hängt vom Workload ab: Image-Bake-Kosten gegenüber Deploy-Zeit-Install-Kosten, Iterationsgeschwindigkeit gegenüber Produktionszuverlässigkeit, Registry-Speicher gegenüber First-Deploy-Latenz. Die Plattform überlässt die Wahl dem component-Autor, mit einem sinnvollen Standard und genannten Trade-offs, statt jede component in ein Design zu zwingen. Der build_system-Schlüssel steht neben dieser Wahl — er wählt das kuratierte Basis-Image und pinnt den Abhängigkeits-Stack (einschließlich der CUDA-Wheel-Variante), unabhängig davon, wann die Installation läuft (siehe Build-Systeme).

Die Disziplin besteht darin, den Modus zu wählen, der zum Workload passt, statt den Standard zu kopieren. install: node passt zu einer iterationslastigen ML-component mit einem großen Abhängigkeitssatz; die Build-Zeit-Installation passt zu einer kleinen Utility-component mit einem bescheidenen. Die falsche Wahl erzeugt Kosten, die das Team später in Deploy-Geschwindigkeit, Image-Größe oder Iterationszeit zahlt.

Verwandt

  • Build-Systemebuild_system: wählt den kuratierten Stack unabhängig von install:.
  • Components — wo requirements.txt / xmake_packages erstellt werden.
  • Deployments — was sich ändert, wenn ein install: node-Deploy auf einem frischen Node landet.
  • Publish-Semantik — die publish + promote-Schleife, in der die Installation läuft.

War diese Seite hilfreich?