
Essayez la nouvelle démo LLMS 40B à Kaggle
Exécutez de grands modèles Pytorch sur plusieurs GPU dans une ligne de code avec une accélération potentiellement linéaire.
import transformers
import tensor_parallel as tp
tokenizer = transformers . AutoTokenizer . from_pretrained ( "facebook/opt-13b" )
model = transformers . AutoModelForCausalLM . from_pretrained ( "facebook/opt-13b" ) # use opt-125m for testing
model = tp . tensor_parallel ( model , [ "cuda:0" , "cuda:1" ]) # <- each GPU has half the weights
inputs = tokenizer ( "A cat sat" , return_tensors = "pt" )[ "input_ids" ]. to ( "cuda:0" )
outputs = model . generate ( inputs , num_beams = 5 )
print ( tokenizer . decode ( outputs [ 0 ])) # A cat sat on my lap for a few minutes ...
model ( input_ids = inputs , labels = inputs ). loss . backward () # training works as usual Dernière version stable (recommandée):
pip install tensor_parallel
Version de bord de saignement:
pip install https://github.com/BlackSamorez/tensor_parallel/archive/main.zip
Enveloppez simplement votre modèle Pytorch avec tp.tensor_parallel et utilisez-le normalement. Pour une meilleure efficacité de la mémoire, appelez tp.tensor_parallel tandis que le modèle est toujours sur CPU.
Voici quelques cas d'utilisation:
examples/training_flan-t5-xl.ipynb - Finne Flan Flan-T5 sur le résumé de textetensor_parallel int8 LLM - Adaptateur-Tuning Un grand modèle de langue avec LLM.8BIT + TENSOR_PARALLER Paramètres avancés vers tensor_parallel :
device_ids: List[device] - quels appareils utiliser; par défaut à tous les GPU disponiblesoutput_device: device - Les sorties du modèle auront cet appareiltensor_parallel_config: tp.Config - Utilisez la stratégie de parallélisme personnalisée, voir slicing_configs.pydistributed: bool - Si vrai, utilisez Torch.Distributed backend au lieu de filetage (nécessite torchrun )sharded: bool - Si vrai, trouvez tous les paramètres formables qui n'étaient pas divisés par le parallélisme du tenseur et les divisent à l'aide de l'algorithme zéro-3.sharded_param_names: List[str] - noms de paramètres qui devraient être frappés de cette façon, par défaut = trouvé automatiquement Pour enregistrer un modèle tel qu'il pourrait être utilisé dans un contexte non tensor_parallel , vous devez utiliser un wrapper de contexte save_tensor_parallel .
import torch
import transformers
import tensor_parallel as tp
model = tp . tensor_parallel (
transformers . AutoModelForCausalLM . from_pretrained ( "facebook/opt-13b" ),
)
# A whole lot of trainig...
with tp . save_tensor_parallel ( model ):
torch . save ( model . state_dict (), "/tmp/" )
# or
model . save_pretrained ( "/tmp/" ) Un tel code enregistre un modèle comme s'il n'était jamais divisé. Il fonctionne en rassemblant des parties du modèle pendant la création state_dict .
Normalement, pour créer et répartir normalement un modèle tensor_parallel , il faut tout le modèle en mémoire. Cela peut être gênant, mais il y a un autre moyen.
Il est possible de convertir un state_dict d'un modèle de base en tensor_parallel state_dict correspondant à l'aide d'une fonction d'assistance convert_state_dict . Le dict d'état peut ensuite être envoyé et chargé dans le modèle:
import accelerate
import transformers
import tensor_parallel as tp
# Initialize a weightless tensor_parallel model from MyModel
with accelerate . init_empty_weights ():
model = tp . TensorParallel (
MyModel (),
device_ids = [ 0 , 1 ] # and prepare it to be put on GPUs 0 and 1
)
# Load partial state_dict for MyModel
state_dict = torch . load ( "my_model_part_1_of_5.bin" )
# Convert it into a tensor_parallel state_dict
tensor_parallel_state_dict = tp . convert_state_dict (
state_dict ,
tensor_parallel_config = model . tensor_parallel_config ,
world_size = len ( model . devices ),
)
# Dispatch the partial state_dict (load_state_dict doesn't work with meta so here I use accelerate)
device_map = tp . infer_sharded_device_map ( model )
for param_name , param in state_dict . items ():
module_name = param_name
while len ( module_name ) > 0 and module_name not in device_map :
module_name = "." . join ( module_name . split ( "." )[: - 1 ])
param_device = device_map [ module_name ]
accelerate . utils . set_module_tensor_to_device ( model , param_name , param_device , value = param )Avec cela, pas plus d'une partie du modèle doit être chargée en mémoire à la fois.
Q: Je n'ai pas de serveur multi-GPU. Puis-je utiliser Tensor_Parallel dans Google Colab?
R: Colab a un seul GPU, il n'y a donc aucun intérêt au parallélisme du tenseur. Cependant, Kaggle propose deux T4 gratuitement à tous les comptes vérifiés par téléphone.
Q: Qu'est-ce que le parallélisme du tenseur?
R: Vous divisez les poids de chaque couche en parties, multipliez chaque partie sur un GPU séparé, puis collectez des résultats. Lire la suite ici
Q: Dois-je utiliser TensorParallel ou DataParallel ?
A: Tensorparallèle pour les grands modèles, dataparallel pour les plus petits
Q: Comment se compare-t-il avec FullShardDataparalleall et zéro?
R: Zero est meilleur si vous pouvez installer un grand lot, Tensorparallel est meilleur pour les petits lots
Pourquoi utiliser tensor_parallel ...
alpaModel.parallelize() En bref, utilisez tensor_parallel pour un prototypage rapide sur une seule machine. Utilisez Deeppeed + Megatron ou Alpa pour des courses d'entraînement à un million de dollars.
Si vous ressentez des erreurs de NCCL ou une suspension aléatoire, vous pouvez avoir des erreurs de code qui ne sont pas affichées correctement. Pour déboguer ces erreurs, nous vous recommandons de redémarrer avec export TENSOR_PARALLEL_USE_NATIVE=1 ou sur un seul appareil.
Si vous avez trouvé un bogue ou rencontré un problème, veuillez le signaler à notre tracker de numéro. Nous ferons de notre mieux pour vous aider, mais cela peut prendre un certain temps avant d'y arriver. Veuillez créer des problèmes uniquement si votre problème est spécifiquement avec tensor_parallel . Par exemple, si vous avez besoin d'aide pour installer transformers ou optimiser votre code, veuillez le chercher ailleurs.
Nous utilisons Black et ISORT pour toutes les demandes de traction. Avant de commettre votre code, exécutez simplement black . && isort . Et tout ira bien.