Zum Hauptinhalt springen

PyTorch Mobile

Definition

PyTorch Mobile ist die Familie von Tools und Runtimes, die PyTorch-trainierte Modelle ohne Server oder Cloud-Verbindung auf Android- und iOS-Geräte bringt. Es bewahrt die PyTorch-Entwicklungserfahrung – Forscher und Ingenieure trainieren in der vertrauten Eager-Mode-Python-API und exportieren ihre Modelle dann entweder über den TorchScript- oder den neueren ExecuTorch-Pfad für die On-Device-Bereitstellung. Diese enge Kopplung zwischen Trainings- und Bereitstellungsumgebungen reduziert die Angriffsfläche für numerische Diskrepanzfehler, die oft auftreten, wenn zwischen Frameworks gewechselt wird.

Der historische Bereitstellungspfad zentriert sich auf TorchScript, eine statisch-typisierte Teilmenge von Python, die kompiliert und in ein plattformunabhängiges Format serialisiert werden kann (.ptl für Mobile). TorchScript unterstützt zwei Kompilierungsmodi: Tracing, bei dem eine Beispieleingabe durch das Modell geleitet wird und der ausgeführte Pfad aufgezeichnet wird, und Scripting, bei dem Python-Kontrollfluss statisch analysiert wird. Beide erzeugen ein ScriptModule, das von der LibTorch C++ Runtime geladen werden kann, die im mobilen SDK eingebettet ist.

Google und Meta haben ExecuTorch gemeinsam als das Framework der nächsten Generation für die Ausführung von PyTorch-Modellen am Edge entwickelt. ExecuTorch führt ein portables Ausführungsformat (.pte), eine minimale C++ Runtime (unter 50 KB für einfache Modelle) und erstklassige Unterstützung für die Delegation an Hardware-Backends ein, einschließlich Qualcomm AI Engine, Apple Neural Engine, Arm Ethos NPUs und Cadence DSPs. ExecuTorch ist für den Produktionseinsatz konzipiert und ersetzt die ursprüngliche PyTorch Mobile Runtime für neue Projekte, die breite Hardware-Portabilität und minimale Binärgröße erfordern.

Funktionsweise

TorchScript Tracing und Scripting

Tracing (torch.jit.trace) führt eine Beispieleingabe durch das Modell und zeichnet die Sequenz der Tensor-Operationen auf, was einen statischen Berechnungsgraph erzeugt. Tracing ist einfach und deckt die meisten Standardarchitekturen ab, erfasst aber nur den Ausführungspfad für die gegebene Eingabe – datenabhängiger Kontrollfluss (if-Anweisungen, Schleifen, die mit Eingabewerten variieren) wird stillschweigend fest eingebacken. Scripting (torch.jit.script) analysiert den Python-Quellcode mit einem TorchScript-Typ-Checker und bewahrt den Kontrollfluss, was es für Modelle mit verzweigter Logik korrekt macht. In der Praxis sind Hybridansätze üblich: Das Top-Level-Modul scripten, während innere Sub-Module, die keinen dynamischen Kontrollfluss haben, getraced werden.

ExecuTorch Export-Pipeline

ExecuTorch verwendet torch.export.export, um eine strikte, seiteneffektfreie Repräsentation des Modells in ATen IR zu erfassen – ein kanonischer Satz von PyTorch-Operatoren mit garantiert wohldefinierten Semantiken. Das exportierte Programm wird dann durch to_edge auf die Edge IR abgesenkt, was Backend-spezifische Graph-Passes durchführt (Operator-Dekompositionen, Layout-Propagation). Backends (Delegationsziele) können Subgraphen während des to_backend-Schritts beanspruchen und sie durch Hardware-spezifische Implementierungen ersetzen. Das finale Artefakt wird in ein .pte-Flatbuffer serialisiert, das von der ExecuTorch C++ Runtime geladen wird, die während der Inferenz keine dynamische Speicherzuweisung benötigt.

Optimierung: Quantisierung und Pruning

PyTorch bietet Post-Training statische und dynamische Quantisierung über torch.quantization (legacy) und den neueren torch.ao.quantization-Namespace. Statische INT8-Quantisierung erfordert ein repräsentatives Kalibrierungsdataset und reduziert die Modellgröße um ~4x mit 2–3x Latenzverbesserung auf ARM-CPUs. Quantization-Aware Training (QAT) fügt FakeQuantize-Knoten in den Vorwärts-Graph während des Fine-Tunings ein, was es dem Modell ermöglicht, seine Gewichte an INT8-Präzision anzupassen. Pruning (torch.nn.utils.prune) entfernt individuelle Gewichte oder ganze Kanäle basierend auf Magnitude- oder strukturierten Kriterien, was die effektive Rechenlast vor der Quantisierung reduziert. Beide Techniken können kombiniert werden: zuerst prunen, um Kanäle zu reduzieren, dann quantisieren, um die Präzision zu reduzieren.

Mobile Runtime und Plattform-Integration

Das .ptl-Bundle, das durch optimize_for_mobile erzeugt wird, enthält Operator-Fusions-Optimierungen und entfernt unbenutzte Operatoren aus der Operator-Registry, was den Binary-Footprint reduziert. Das Android SDK (pytorch_android) wird auf Maven Central veröffentlicht und stellt eine Kotlin/Java API bereit. Das iOS SDK wird als CocoaPod oder Swift Package verteilt und bietet Objective-C- und Swift-Bindungen. Beide SDKs umhüllen denselben LibTorch C++ Kern. ExecuTorch zielt auf dieselben Plattformen ab, stellt aber eine schlankere C-API bereit und unterstützt auch Bare-Metal-eingebettete Ziele. Die torch::executor::Module-Klasse bietet eine minimale execute()-API, die direkt auf vorzugewiesenen EValue-Tensoren operiert, um JNI-ähnlichen Overhead zu vermeiden.

GPU- und NPU-Beschleunigung

PyTorch Mobiles GPU-Delegate für Android funktioniert über das Vulkan-Backend (torch.backends.vulkan), das Konvolutionen und Matrizenmultiplikationen auf die GPU verlagert. ExecuTorchs XNNPACK-Backend beschleunigt Gleitkomma- und INT8-Operationen auf ARM-CPUs über NEON-SIMD-Anweisungen und ist das empfohlene Standard für CPU-Beschleunigung. Das Qualcomm AI Engine Direct-Backend und das Apple Core ML-Backend bieten NPU-Beschleunigung über ExecuTorchs Delegations-API und erzielen typischerweise 5–15x Beschleunigungen gegenüber Referenz-CPU-Pfaden für Standard-Vision- und NLP-Modelle.

Wann verwenden / Wann NICHT verwenden

Verwenden wennVermeiden wenn
Ihre Trainingscode-Basis PyTorch ist und Sie minimale Konvertierungsreibung möchtenIhre Modelle in TensorFlow/Keras entstehen und der Konvertierungsaufwand ein Problem ist
Sie auf Android oder iOS mit einem Python-vertrauten Workflow bereitstellen müssenSie Mikrocontroller-Ziele mit <256 KB RAM benötigen (TFLM ist besser geeignet)
Sie ExecuTorch für Next-Gen-Hardware-NPU-Delegation wünschen (Qualcomm, Apple ANE)Ihr Modell Python-Ebene dynamischen Kontrollfluss verwendet, den TorchScript nicht über Tracing erfassen kann
Schnelle Iteration: dasselbe Modell für Training und mobiles Inferenz wiederverwendenSie ausgereifte Produktions-Tooling mit breiter Hardware-Delegate-Abdeckung heute benötigen (TFLite ist ausgereifter)
Sie auf dem Hugging Face-Ökosystem aufbauen (viele Modelle exportieren über TorchScript)Die Binärgröße extrem eingeschränkt ist und der LibTorch-Runtime-Footprint (~3–8 MB komprimiert) zu groß ist

Vergleiche

Vergleich von PyTorch Mobile mit TFLite und ONNX Runtime für Edge-Bereitstellungsszenarien.

KriteriumPyTorch MobileTensorFlow LiteONNX Runtime
PlattformunterstützungAndroid, iOS; ExecuTorch erweitert auf eingebettete und Bare-Metal-ZieleAndroid, iOS, eingebettetes Linux, Mikrocontroller (TFLM)Windows, Linux, macOS, Android, iOS, WebAssembly
Modellkonvertierungtorch.jit.trace / script (PyTorch-nativ) oder torch.export (ExecuTorch)TFLite Converter von TF/Keras SavedModelBeliebiges Framework → ONNX-Export (interoperabelster Weg)
On-Device-LeistungXNNPACK auf ARM-CPUs; Vulkan GPU; ExecuTorch NPU-DelegationAusgezeichnet auf Android über NNAPI/GPU-Delegate; best-in-class für MikrocontrollerWettbewerbsfähiger CPU EP; CUDA/TensorRT EPs glänzen in GPU-fähigen Edge-Geräten
ÖkosystemStark in der Forschung; Hugging Face-Integration; wachsende ExecuTorch-CommunityAusgereift: MediaPipe, TF Hub, Model Garden; größte mobile ML-CommunityBreite Enterprise-Unterstützung; Framework-agnostisch; starke Microsoft/Azure-Integration
QuantisierungsunterstützungPTQ (dynamisch + statisch INT8) und QAT über torch.ao.quantization; ExecuTorch Backend-spezifische QuantisierungUmfassend: dynamischer Bereich, INT8, FP16, QAT mit vollen INT8-PfadenINT8 über QDQ-Knoten; Hardware-INT8 hängt vom Ausführungsanbieter ab

Vor- und Nachteile

VorteileNachteile
Nahtloser Workflow für PyTorch-Benutzer — dieselbe Modellklasse trainiert und bereitstelltLibTorch Mobile Binary fügt der App-Größe komprimiert ~3–8 MB hinzu
ExecuTorch bietet eine moderne, erweiterbare Architektur für NPU-DelegationTorchScript-Tracing übersieht stillschweigend datenabhängigen Kontrollfluss
Starke Hugging Face-Ökosystem-IntegrationWeniger ausgereift als TFLite für Produktions-Android/iOS-Bereitstellungen
QAT ist gut in den Standardtrainings-Loop integriertVulkan-GPU-Delegate-Abdeckung ist schmaler als TFLites GPU-Delegate
Aktive Entwicklung mit starker Meta- und Community-UnterstützungONNX-Interoperabilität erfordert einen zusätzlichen Konvertierungsschritt über den ONNX-Exporter

Code-Beispiele

import torch
import torch.nn as nn

# ── 1. Ein einfaches Faltungsmodell definieren ────────────────────────────
class SmallCNN(nn.Module):
"""Minimales CNN zur Demonstration. Durch Ihr echtes Modell ersetzen."""

def __init__(self, num_classes: int = 10):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(1, 16, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(2),
nn.Conv2d(16, 32, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.AdaptiveAvgPool2d(1),
)
self.classifier = nn.Linear(32, num_classes)

def forward(self, x: torch.Tensor) -> torch.Tensor:
x = self.features(x)
x = x.flatten(1)
return self.classifier(x)


model = SmallCNN(num_classes=10)
model.eval() # Modell in Inferenzmodus setzen

# ── 2. Mit TorchScript Tracing exportieren ───────────────────────────────
example_input = torch.rand(1, 1, 28, 28)

scripted_model = torch.jit.trace(model, example_input)

from torch.utils.mobile_optimizer import optimize_for_mobile

optimized_model = optimize_for_mobile(scripted_model)
optimized_model._save_for_lite_interpreter("model.ptl")
print("Saved model.ptl")

# ── 3. Post-Training Dynamic Quantisierung anwenden ───────────────────────
quantized_model = torch.quantization.quantize_dynamic(
model,
qconfig_spec={nn.Linear, nn.Conv2d},
dtype=torch.qint8,
)
quantized_model.eval()

with torch.no_grad():
output = quantized_model(example_input)
print(f"Output shape: {output.shape}, predicted class: {output.argmax(dim=1).item()}")

# ── 4. .ptl auf Python laden ──────────────────────────────────────────────
loaded = torch.jit.load("model.ptl")
loaded.eval()
with torch.no_grad():
result = loaded(example_input)
print(f"Loaded mobile model predicted class: {result.argmax(dim=1).item()}")

Praktische Ressourcen

  • PyTorch Mobile Dokumentation — offizieller Leitfaden zum TorchScript-Export, den Android- und iOS-SDKs, Modelloptimierung und Leistungs-Profiling auf Geräten.
  • ExecuTorch Dokumentation — die Next-Generation-Edge-Runtime-Dokumentation, die die Export-Pipeline, Backend-Delegation und Hardware-Integrationsanleitungen für Qualcomm, Apple und ARM-Ziele abdeckt.
  • torch.ao.quantization Leitfaden — umfassende Referenz für PyTorchs Quantisierungs-API.
  • PyTorch Android Demo-Apps — Open-Source-Android-Apps als Integrations-Templates.
  • ExecuTorch Tutorials — Schritt-für-Schritt-Tutorials zum Exportieren von Modellen durch die ExecuTorch-Pipeline.

Siehe auch