Transformers documentation
Apple Silicon
Apple Silicon
Les puces Apple Silicon (série M) exécutent PyTorch via le backend Metal Performance Shaders (MPS), avec la chaîne de périphérique mps. Le CPU et le GPU partagent un seul pool de mémoire unifiée.
MPS fonctionne avec l’installation standard de torch. Les versions actuelles de PyTorch pour Apple Silicon nécessitent macOS 14 ou une version ultérieure. Vérifiez que PyTorch a été compilé avec MPS et qu’il peut détecter le GPU.
import torch
print(torch.backends.mps.is_available())Il affiche True lorsque MPS est prêt à l'emploi.
Choisir un backend d'attention
Définissez le backend d’attention avec attn_implementation lors du chargement d’un modèle ; il s’applique à la fois à l’inférence et à l’entraînement. Les modèles utilisent SDPA par défaut. Avec PyTorch 2.13 ou une version ultérieure, SDPA sur MPS gère directement l’attention à requêtes groupées, sans avoir à répéter d’abord les têtes de clés et de valeurs.
Utilisez SDPA pour l’entraînement.
- kernels-community/metal-flash-sdpa ne prend en charge que les entrées de longueur variable, telles que des séquences empilées ou un lot dont le masque d’attention contient du bourrage. Un lot sans bourrage, comme un seul prompt, provoque une erreur. Il ne calcule pas les gradients pour les projections de requête, de clé et de valeur. gpt-oss y bascule automatiquement lorsque vous demandez l’attention flash sur MPS.
- ggml-org/ggml-attn est la valeur par défaut pour
transformers serveet pour les modèles GGUF lorsquekernelsest installé.
Installez l'extra kernels pour utiliser l'un ou l'autre noyau. Il installe une version prise en charge par Transformers.
pip install "transformers[kernels]"Exécuter l'inférence
Passez device_map="mps" à from_pretrained(). pipeline() sélectionne MPS automatiquement lorsque vous ne passez pas device.
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", device_map="mps")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
inputs = tokenizer("Apple Silicon is", return_tensors="pt")
output = model.generate(**inputs, max_new_tokens=50, do_sample=False)
print(tokenizer.decode(output[0], skip_special_tokens=True))Avec un device_map ciblant MPS, Transformers charge les poids safetensors directement sur l’appareil MPS.
Servir un modèle
transformers serve démarre un serveur compatible OpenAI. Son option --device est définie par défaut sur auto, ce qui permet de charger les modèles sur MPS sans drapeaux supplémentaires. Installez les dépendances de service et démarrez le serveur.
pip install "transformers[serving]"
transformers serveLe serveur charge un modèle la première fois qu’une requête le nomme. Envoyez une requête de chat à http://localhost:8000.
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen2.5-0.5B-Instruct",
"messages": [{"role": "user", "content": "What is Apple Silicon? Answer in one sentence."}],
"max_tokens": 64,
"temperature": 0
}'{"id":"b48e84c1-b3c6-484d-b781-4c9ce8022dff","choices":[{"finish_reason":"stop","index":0,"message":{"content":"Apple Silicon is a type of processor technology developed and manufactured by Apple Inc., designed to offer faster performance and lower power consumption compared to traditional silicon-based processors. This technology allows for the creation of more efficient and energy-efficient devices, such as high-performance computers, smartphones, and other Apple products.","role":"assistant"}}],"created":1791843839,"model":"Qwen/Qwen2.5-0.5B-Instruct@main","object":"chat.completion","usage":{"completion_tokens":59,"prompt_tokens":39,"total_tokens":98}}Lorsque kernels est installé, transformers serve utilise par défaut ggml-org/ggml-attn sur MPS et affiche un avertissement au démarrage. Passez --attn-implementation sdpa pour utiliser SDPA à la place.
Quantifier les modèles
Les poids du modèle partagent la mémoire unifiée avec macOS et tout le reste qui s’exécute sur le Mac, de sorte que leur quantification permet à un modèle plus volumineux de tenir pour l’inférence ou l’ajustement fin. Metal quantise un modèle lors de son chargement, tandis que GGUF exécute des points de contrôle déjà quantifiés. Les deux sont réservés à l’inférence.
- Metal quantifie en 2, 4 ou 8 bits à l’aide de noyaux Metal issus du Hub.
- GGUF conserve les poids compressés sur MPS lorsque le noyau
ggml-org/ggml-quantizationest disponible. - bitsandbytes quantifie en 4 bits avec des noyaux MPS natifs.
Pour affiner un modèle qui ne tient pas en mémoire, chargez-le en 4 bits avec bitsandbytes et entraînez des adaptateurs LoRA avec PEFT.
Entraîner avec Trainer
TrainingArguments détecte MPS et définit le dispositif sur mps, de sorte que Trainer entraîne dessus sans aucun paramètre de dispositif. Les précisions mixtes bf16 et fp16 fonctionnent. Chargez le modèle avec l’attention SDPA par défaut, car metal-flash-sdpa ne calcule pas les gradients pour les projections d’attention.
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="./outputs",
bf16=True,
)
print(training_args.device)Il affiche mps lorsque Trainer entraîne sur le GPU.
Sur macOS, Python démarre les processus de travail avec spawn par défaut, ce qui réimporte votre script et nécessite un dataset sérialisable ainsi qu'une collate_fn. Lorsque dataloader_num_workers est supérieur à 1, TrainingArguments définit dataloader_multiprocessing_context="fork" sur MPS, de sorte que les travailleurs démarrent à partir d'une copie du processus d'entraînement. Définissez-le sur "spawn" si une source de données n'est pas sûre pour le fork.
Limiter la croissance du cache de graphes
MPS compile un noyau Metal pour chaque forme de tenseur qu’il rencontre et les conserve dans un cache de graphes qui n’est jamais purgé. L’entraînement avec des entrées de longueur variable ajoute un noyau pour chaque nouvelle forme et peut épuiser la mémoire unifiée.
Réduisez le nombre de formes en remplissant chaque lot jusqu'à un multiple d'une longueur fixe à l'aide de l'argument pad_to_multiple_of de DataCollatorWithPadding.
from transformers import AutoTokenizer, DataCollatorWithPadding
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
data_collator = DataCollatorWithPadding(tokenizer, pad_to_multiple_of=64)Passez-le à Trainer avec data_collator=data_collator.
Limites
device_map="auto"ne peut pas décharger les couches sur le CPU, car MPS et le CPU partagent la même mémoire. Le débordement est transféré sur le disque.- Les points de contrôle FP8 de compressed-tensors se chargent sur MPS, mais leurs poids sont décompressés lors du premier passage avant, ce qui ne réduit pas la mémoire pendant l'inférence.
- Le parallélisme de tenseurs n’est pas pris en charge car un Mac ne dispose que d’un seul appareil.
- Certaines opérations PyTorch ne disposent pas encore d’une implémentation MPS. Définissez
PYTORCH_ENABLE_MPS_FALLBACK=1pour les exécuter sur le CPU au lieu de lever une erreur.
Étapes suivantes
- Consultez les notes sur le backend MPS de PyTorch pour les opérations prises en charge et les problèmes connus.
- Consultez le guide Backends d'attention pour comprendre comment
attn_implementationsélectionne une fonction d'attention. - Consultez la colonne Metal dans le aperçu de la quantification pour trouver toutes les méthodes de quantification qui s’exécutent sur MPS.