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 incomponent.ymlwählt den Modus — lass ihn weg für Build-Zeit-Installation, setzeinstall: nodefü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: nodeveröffentlicht ein Skelett-Image, das den Quellcode undrequirements.txtträ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: nodezu 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
| Fehler | Warum 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-Systeme —
build_system:wählt den kuratierten Stack unabhängig voninstall:. - Components — wo
requirements.txt/xmake_packageserstellt 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.