# Comment exécuter Stable Diffusion avec Core ML

[Core ML](https://developer.apple.com/documentation/coreml) est le format de modèle et la bibliothèque d’apprentissage automatique pris en charge par les frameworks Apple. Si vous souhaitez exécuter des modèles Stable Diffusion dans vos applications macOS ou iOS/iPadOS, ce guide vous montre comment convertir des points de contrôle PyTorch existants au format Core ML et les utiliser pour l’inférence avec Python ou Swift.

Les modèles Core ML peuvent exploiter tous les moteurs de calcul disponibles sur les appareils Apple : le CPU, le GPU et l’Apple Neural Engine (ou ANE, un accélérateur optimisé pour les tenseurs disponible sur les Mac Apple Silicon et les iPhone/iPad modernes). Selon le modèle et l’appareil sur lequel il s’exécute, Core ML peut également combiner les moteurs de calcul, de sorte que certaines parties du modèle s’exécutent sur le CPU tandis que d’autres s’exécutent sur le GPU, par exemple.

> [!TIP]
> Vous pouvez également exécuter le code Python `diffusers` sur des Mac Apple Silicon en utilisant l'accélérateur `mps` intégré à PyTorch. Cette approche est expliquée en détail dans [le guide mps](mps), mais elle n'est pas compatible avec les applications natives.

## Points de contrôle Core ML de Stable Diffusion

Les poids (ou points de contrôle) de Stable Diffusion sont stockés au format PyTorch, il est donc nécessaire de les convertir au format Core ML avant de pouvoir les utiliser dans des applications natives.

Heureusement, les ingénieurs d’Apple ont développé [un outil de conversion](https://github.com/apple/ml-stable-diffusion#-converting-models-to-core-ml) basé sur `diffusers` pour convertir les points de contrôle PyTorch en Core ML.

Avant de convertir un modèle, prenez un moment pour explorer le Hugging Face Hub – il est probable que le modèle qui vous intéresse soit déjà disponible au format Core ML :

- l'organisation [Apple](https://huggingface.co/apple) comprend les versions 1.4, 1.5, 2.0 base et 2.1 base de Stable Diffusion
- [coreml community](https://huggingface.co/coreml-community) inclut des modèles finement ajustés
- utilisez ce [filtre](https://huggingface.co/models?pipeline_tag=text-to-image&library=coreml&p=2&sort=likes) pour renvoyer tous les points de contrôle Core ML disponibles

Si vous ne trouvez pas le modèle qui vous intéresse, nous vous recommandons de suivre les instructions pour [Convertir les modèles en Core ML](https://github.com/apple/ml-stable-diffusion#-converting-models-to-core-ml) fournies par Apple.

## Sélectionner la variante Core ML à utiliser

Les modèles Stable Diffusion peuvent être convertis en différentes variantes Core ML destinées à des usages spécifiques :

- Le type de blocs d'attention utilisés. L'opération d'attention sert à « prêter attention » aux relations entre différentes zones des représentations d'image et à comprendre comment les représentations d'image et de texte sont liées. L'attention est gourmande en calculs et en mémoire, il existe donc différentes implémentations qui tiennent compte des caractéristiques matérielles des différents appareils. Pour les modèles Stable Diffusion Core ML, il existe deux variantes d'attention :
    * `split_einsum` ([introduit par Apple](https://machinelearning.apple.com/research/neural-engine-transformers)) est optimisé pour les dispositifs ANE, disponibles dans les iPhone, iPad et ordinateurs de la série M modernes.
    * L'attention « originale » (l'implémentation de base utilisée dans `diffusers`) n'est compatible qu'avec CPU/GPU et non avec ANE. Il peut être *plus rapide* d'exécuter votre modèle sur CPU + GPU en utilisant l'attention `original` que sur ANE. Consultez [ce benchmark de performances](https://huggingface.co/blog/fast-mac-diffusers#performance-benchmarks) ainsi que certaines [mesures supplémentaires fournies par la communauté](https://github.com/huggingface/swift-coreml-diffusers/issues/31) pour plus de détails.

- Le framework d'inférence pris en charge.
    * `packages` conviennent à l’inférence Python. Ils permettent de tester les modèles Core ML convertis avant de tenter de les intégrer dans des applications natives, ou d’explorer les performances de Core ML sans avoir à prendre en charge les applications natives. Par exemple, une application avec une interface web peut tout à fait utiliser un backend Core ML Python.
    * Les modèles `compiled` sont requis pour le code Swift. Les modèles `compiled` du Hub divisent les poids du grand modèle UNet en plusieurs fichiers pour assurer la compatibilité avec les appareils iOS et iPadOS. Cela correspond à l’option de conversion [`--chunk-unet`](https://github.com/apple/ml-stable-diffusion#-converting-models-to-core-ml). Si vous souhaitez prendre en charge les applications natives, vous devez sélectionner la variante `compiled`.

Les [modèles](https://huggingface.co/apple/coreml-stable-diffusion-v1-4/tree/main) officiels de Stable Diffusion pour Core ML incluent ces variantes, mais ceux de la communauté peuvent varier :

```
coreml-stable-diffusion-v1-4
├── README.md
├── original
│   ├── compiled
│   └── packages
└── split_einsum
    ├── compiled
    └── packages
```

Vous pouvez télécharger et utiliser la variante dont vous avez besoin, comme indiqué ci-dessous.

## Inférence Core ML en Python

Installez les bibliothèques suivantes pour exécuter l'inférence Core ML en Python :

```bash
pip install huggingface_hub
pip install git+https://github.com/apple/ml-stable-diffusion
```

### Télécharger les points de contrôle du modèle

Pour exécuter l'inférence en Python, utilisez l'une des versions stockées dans les dossiers `packages`, car les versions `compiled` ne sont compatibles qu'avec Swift. Vous pouvez choisir d'utiliser l'attention `original` ou `split_einsum`.

Voici comment télécharger la variante d'attention `original` depuis le Hub vers un répertoire nommé `models` :

```Python
from huggingface_hub import snapshot_download
from pathlib import Path

repo_id = "apple/coreml-stable-diffusion-v1-4"
variant = "original/packages"

model_path = Path("./models") / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
snapshot_download(repo_id, allow_patterns=f"{variant}/*", local_dir=model_path, local_dir_use_symlinks=False)
print(f"Model downloaded at {model_path}")
```

### Inférence[[python-inference]]

Une fois que vous avez téléchargé un instantané du modèle, vous pouvez le tester à l'aide du script Python d'Apple.

```shell
python -m python_coreml_stable_diffusion.pipeline --prompt "a photo of an astronaut riding a horse on mars" -i ./models/coreml-stable-diffusion-v1-4_original_packages/original/packages -o </path/to/output/image> --compute-unit CPU_AND_GPU --seed 93
```

Transmettez le chemin du point de contrôle téléchargé au script avec le drapeau `-i`. `--compute-unit` indique le matériel que vous souhaitez autoriser pour l'inférence. Il doit être l'une des options suivantes : `ALL`, `CPU_AND_GPU`, `CPU_ONLY`, `CPU_AND_NE`. Vous pouvez également fournir un chemin de sortie facultatif et une graine pour la reproductibilité.

Le script d’inférence suppose que vous utilisez la version originale du modèle Stable Diffusion, `CompVis/stable-diffusion-v1-4`. Si vous utilisez un autre modèle, vous *devez* spécifier son identifiant Hub dans la ligne de commande d’inférence, à l’aide de l’option `--model-version`. Cela fonctionne pour les modèles déjà pris en charge ainsi que pour les modèles personnalisés que vous avez entraînés ou affinés vous-même.

Par exemple, si vous souhaitez utiliser [`stable-diffusion-v1-5/stable-diffusion-v1-5`](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5) :

```shell
python -m python_coreml_stable_diffusion.pipeline --prompt "a photo of an astronaut riding a horse on mars" --compute-unit ALL -o output --seed 93 -i models/coreml-stable-diffusion-v1-5_original_packages --model-version stable-diffusion-v1-5/stable-diffusion-v1-5
```

## Inférence Core ML en Swift

L’exécution de l’inférence en Swift est légèrement plus rapide qu’en Python, car les modèles sont déjà compilés au format `mlmodelc`. Cette différence est perceptible au démarrage de l’application, lorsque le modèle est chargé, mais elle ne devrait pas être notable si vous effectuez plusieurs générations par la suite.

### Télécharger

Pour exécuter l'inférence en Swift sur votre Mac, vous avez besoin de l'une des versions de point de contrôle `compiled`. Nous vous recommandons de les télécharger localement à l'aide de code Python similaire à l'exemple précédent, mais avec l'une des variantes `compiled` :

```Python
from huggingface_hub import snapshot_download
from pathlib import Path

repo_id = "apple/coreml-stable-diffusion-v1-4"
variant = "original/compiled"

model_path = Path("./models") / (repo_id.split("/")[-1] + "_" + variant.replace("/", "_"))
snapshot_download(repo_id, allow_patterns=f"{variant}/*", local_dir=model_path, local_dir_use_symlinks=False)
print(f"Model downloaded at {model_path}")
```

### Inférence[[swift-inference]]

Pour exécuter l'inférence, veuillez cloner le dépôt d'Apple :

```bash
git clone https://github.com/apple/ml-stable-diffusion
cd ml-stable-diffusion
```

Puis utilisez l'outil en ligne de commande d'Apple, [Swift Package Manager](https://www.swift.org/package-manager/#) :

```bash
swift run StableDiffusionSample --resource-path models/coreml-stable-diffusion-v1-4_original_compiled --compute-units all "a photo of an astronaut riding a horse on mars"
```

Vous devez spécifier dans `--resource-path` l'un des points de contrôle téléchargés à l'étape précédente, veuillez donc vous assurer qu'il contient des bundles Core ML compilés avec l'extension `.mlmodelc`. La valeur de `--compute-units` doit être l'une de ces valeurs : `all`, `cpuOnly`, `cpuAndGPU`, `cpuAndNeuralEngine`.

Pour plus de détails, veuillez consulter les [instructions du dépôt d'Apple](https://github.com/apple/ml-stable-diffusion).

## Fonctionnalités Diffusers prises en charge

Les modèles Core ML et le code d'inférence ne prennent pas en charge de nombreuses fonctionnalités, options et flexibilités de 🧨 Diffusers. Voici certaines des limites à garder à l'esprit :

- Les modèles Core ML ne conviennent que pour l'inférence. Ils ne peuvent pas être utilisés pour l'entraînement ou l'ajustement fin.
- Seuls deux planificateurs ont été portés vers Swift : le planificateur par défaut utilisé par Stable Diffusion et `DPMSolverMultistepScheduler`, que nous avons porté vers Swift à partir de notre implémentation `diffusers`. Nous vous recommandons d’utiliser `DPMSolverMultistepScheduler`, car il produit une qualité équivalente en environ la moitié du nombre d’étapes.
- Les prompts négatifs, l'échelle de guidage sans classifieur et les tâches d'image à image sont disponibles dans le code d'inférence. Les fonctionnalités avancées telles que le guidage de profondeur, ControlNet et les upscalers latents ne sont pas encore disponibles.

Le dépôt de [conversion et d'inférence](https://github.com/apple/ml-stable-diffusion) d'Apple et notre propre dépôt [swift-coreml-diffusers](https://github.com/huggingface/swift-coreml-diffusers) sont conçus comme des démonstrations technologiques permettant à d'autres développeurs de s'appuyer dessus.

Si vous estimez qu'il manque des fonctionnalités, n'hésitez pas à ouvrir une demande de fonctionnalité ou, mieux encore, une PR de contribution 🙂.

## Application Swift native Diffusers

Une façon simple d’exécuter Stable Diffusion sur votre propre matériel Apple consiste à utiliser [notre dépôt open source en Swift](https://github.com/huggingface/swift-coreml-diffusers), basé sur `diffusers` et le dépôt de conversion et d’inférence d’Apple. Vous pouvez étudier le code, le compiler avec [Xcode](https://developer.apple.com/xcode/) et l’adapter à vos besoins. Pour votre confort, une [application Mac autonome est également disponible sur l’App Store](https://apps.apple.com/app/diffusers/id1666309574), ce qui vous permet de l’essayer sans avoir à gérer le code ou l’IDE. Si vous êtes développeur et que vous avez déterminé que Core ML est la meilleure solution pour construire votre application Stable Diffusion, vous pouvez utiliser le reste de ce guide pour démarrer votre projet. Nous avons hâte de voir ce que vous allez créer 🙂.

