🗜️Optimierung: kleiner und schneller
.mlpackage (datenfrei) oder schon in PyTorch (mit Kalibrierdaten oder Feintuning). 📎 Optimization Overview🧰Die Verfahren
FP16
Jedes Gewicht als 16-Bit-Gleitkommazahl. Standard bei convert_to="mlprogram".
Lineare Quantisierung (Int8/Int4)
Werte werden auf ein gleichmäßiges Ganzzahlraster abgebildet. Standard in coremltools: symmetrisch (Nullpunkt 0), eine Skala je Ausgabekanal.
Palettisierung
k-means sucht 2ⁿ Zentren (Lookup-Tabelle); jedes Gewicht speichert nur noch einen n-Bit-Index. n ∈ {1, 2, 3, 4, 6, 8}.
Pruning
Betragskleine Gewichte werden 0 und dünn besetzt gespeichert: Bitmaske + nur die Nicht-Null-Werte. Auch n:m- und Block-Sparsity.
📏Größenrechner: Parameter × Bits
Vereinfachung: alle Parameter als ein Gewichtstensor mit 1 024 Ausgabekanälen; in echten Modellen bleiben kleine Tensoren (unter weight_threshold, Standard 2 048 Elemente) unkomprimiert, dazu kommen Dateiköpfe und Ausrichtung. Parameterzahlen: 📎 torchvision Modell-Metadaten (num_pa… · Verfahren/OS: 📎 Optimization – What’s New (OS-Verfüg…📎 Optimization Overview
🎯Was mit den Gewichten passiert
Zeile 0: scale = max|w| / 7 = 0.11891 → 15 mögliche Werte je Zeile (−7…7)
📊Echte Messwerte am Lehrmodell
| Variante | MIL-Op für Gewichte | weight.bin | Genauigkeit (360 Testbilder) | max |Δ| zu PyTorch |
|---|---|---|---|---|
FP32 | const | 9.984 B | 96,7 % | 1.19e-7 |
FP16 (Standard) | const + cast | 5.140 B | 96,7 % | 7.84e-4 |
Int8 linear pro Kanal OpLinearQuantizerConfig(mode="linear_symmetric", dtype="int8", granularity="per_channel", weight_threshold=256) | constexpr_affine_dequantize | 3.432 B | 96,7 % | 1.77e-3 |
Int4 linear pro Kanal OpLinearQuantizerConfig(mode="linear_symmetric", dtype="int4", granularity="per_channel", weight_threshold=256) – Basis mit minimum_deployment_target=iOS18 | constexpr_blockwise_shift_scale | 2.024 B | 97,2 % | 1.92e-1 |
Palette 4 Bit (k-means) OpPalettizerConfig(nbits=4, mode="kmeans", granularity="per_tensor", weight_threshold=256) | constexpr_lut_to_dense | 1.984 B | 97,2 % | 7.00e-2 |
Pruning 50 % OpMagnitudePrunerConfig(target_sparsity=0.5, weight_threshold=256) | constexpr_sparse_to_dense | 5.672 B | 81,4 % | 9.77e-1 |
Beim Lehrmodell sind die Gewichte winzig – Dateiköpfe und die unkomprimierten Biases fallen deshalb stark ins Gewicht (Int4 spart hier „nur“ 80 % statt 87,5 %). Int4 und Palette liegen auf den 360 Testbildern sogar minimal über FP32 (97,2 % statt 96,7 %) – Zufall bei zwei Bildern, kein Qualitätsgewinn. Pruning von 50 % ohne Nachtraining zerstört dieses kleine Netz dagegen deutlich. 📎 eigene Konvertierung
🧾Der Code dazu
Gewichte komprimieren mit coremltools.optimize
✔ echte coremltools-Ausgabeimport coremltools.optimize as cto
# Int8 linear, symmetrisch, eine Skala je Ausgabekanal (ab iOS 16)
cfg = cto.coreml.OptimizationConfig(global_config=cto.coreml.OpLinearQuantizerConfig(
mode="linear_symmetric", dtype="int8", granularity="per_channel", weight_threshold=256))
m_int8 = cto.coreml.linear_quantize_weights(mlmodel, config=cfg)
# Int4 – braucht minimum_deployment_target=ct.target.iOS18
cfg4 = cto.coreml.OptimizationConfig(global_config=cto.coreml.OpLinearQuantizerConfig(
mode="linear_symmetric", dtype="int4", granularity="per_channel", weight_threshold=256))
m_int4 = cto.coreml.linear_quantize_weights(mlmodel_ios18, config=cfg4)
# Palettisierung: 16 Clusterzentren (k-means) als Lookup-Tabelle (ab iOS 16)
pcfg = cto.coreml.OptimizationConfig(global_config=cto.coreml.OpPalettizerConfig(
nbits=4, mode="kmeans", granularity="per_tensor", weight_threshold=256))
m_pal = cto.coreml.palettize_weights(mlmodel, config=pcfg)
# Pruning: 50 % der betragskleinsten Gewichte auf 0 (ab iOS 16)
prcfg = cto.coreml.OptimizationConfig(global_config=cto.coreml.OpMagnitudePrunerConfig(
target_sparsity=0.5, weight_threshold=256))
m_pruned = cto.coreml.prune_weights(mlmodel, config=prcfg)⚡Neural Engine & Performance
cto.coreml.experimental.linear_quantize_activations ist experimentell. 📎 Quantization Overview + API📎 Quantization Performance📎 Optimization – What’s New (OS-Verfüg…per_block (iOS 18) bringt vor allem auf der GPU Speicher- und Latenzgewinne; läuft das Modell auf der Neural Engine, empfiehlt der Guide per_channel. Palettisierte Gewichte werden ab iOS 17 eher „just in time“ entpackt, vor allem auf der NE. 📎 Quantization Performance📎 Palettization Performancecoremltools.optimize.torch. Unser Pruning-Beispiel zeigt, wie stark ein kleines Netz ohne Nachtraining leiden kann. 📎 Optimization Overview📎 Optimization – What’s New (OS-Verfüg…📎 eigene Konvertierung