Les progrès du traitement du langage naturel (NLP) ont ouvert des opportunités sans précédent aux entreprises pour tirer parti de leurs données textuelles. Le traitement du langage naturel peut être utilisé pour un giant éventail d’purposes, notamment la synthèse de texte, la reconnaissance d’entités nommées (par exemple, des personnes et des lieux), la classification des sentiments, la classification de texte, la traduction et la réponse aux questions. Dans de nombreux cas, vous pouvez obtenir des résultats de haute qualité à partir de modèles d’apprentissage automatique qui ont été préalablement formés sur de grands ensembles de données textuelles. Beaucoup de ces modèles pré-formés sont disponibles en open supply et peuvent être utilisés gratuitement. Visage étreignant est une excellente supply de ces modèles, et leur Transformateurs library est un outil facile à utiliser pour appliquer les modèles et les adapter à vos propres données. Il est également doable d’ajuster ces modèles en affinant vos propres données.
Par exemple, une entreprise disposant d’une équipe d’help peut utiliser des modèles pré-formés pour fournir des résumés de texte lisibles par l’homme afin d’aider les employés à évaluer rapidement les problèmes clés dans les cas d’help. Cette société peut également former facilement des algorithmes de classification de classe mondiale basés sur les modèles de base facilement disponibles pour catégoriser automatiquement leurs données de assist dans leurs taxonomies internes.
Databricks est une excellente plate-forme pour exécuter Hugging Face Transformers. Les articles précédents de Databricks ont discuté de l’utilisation de transformateurs pour inférence de modèle pré-entraîné et réglage fin, mais cet article regroupe ces meilleures pratiques pour optimiser les performances et la facilité d’utilisation lorsque vous travaillez avec des transformateurs sur le Lakehouse. Ce doc comprend des exemples de code en ligne ainsi que des explications sur ces meilleures pratiques, et Databricks fournit également des exemples complets de blocs-notes pour inférence de modèle pré-entraîné et réglage fin.
Utilisation de modèles pré-entraînés
Pour de nombreuses purposes, telles que l’analyse des sentiments et la synthèse de texte, les modèles pré-formés fonctionnent bien sans aucune formation de modèle supplémentaire. 🤗 Transformateurs pipelines encapsulez les différents composants requis pour l’inférence sur le texte dans une interface easy. Pour de nombreuses tâches NLP, ces composants constant en un tokenizer et un modèle. Les pipelines encodent les meilleures pratiques, ce qui facilite le démarrage. Par exemple, les pipelines facilitent l’utilisation des GPU lorsqu’ils sont disponibles et permettent de regrouper les éléments envoyés au GPU pour un meilleur débit.
from transformers import pipeline
import torch
# use the GPU if obtainable
gadget = 0 if torch.cuda.is_available() else -1
summarizer = pipeline("summarization", gadget=gadget)
Pour distribuer l’inférence sur Spark, Databricks recommande d’encapsuler un pipeline dans un pandas UDF. Spark utilise la diffusion pour transmettre efficacement tous les objets requis par les UDF pandas aux nœuds de travail. Spark réaffecte également automatiquement les GPU aux travailleurs, de sorte que vous pouvez utiliser un cluster multi-machines multi-GPU de manière transparente.
import pandas as pd
from pyspark.sql.features import pandas_udf
@pandas_udf('string')
def summarize_batch_udf(texts: pd.Collection) -> pd.Collection:
pipe = summarizer(texts.to_list(), truncation=True, batch_size=1)
summaries = (abstract('summary_text') for abstract in pipe)
return pd.Collection(summaries)
summaries = df.choose(df.textual content, summarize_batch_udf(df.textual content).alias("abstract"))
Voici un exemple de résumé d’un instantané de l’article de Wikipedia sur le groupe Power Orchard. Notez que nous n’avons pas nettoyé le balisage Wikipédia avant de le transmettre au récapitulatif.


Cette part a démontré à quel level il est facile de commencer à utiliser Hugging Face Transformers pour traiter du texte à grande échelle sur Databricks. La part suivante décrit remark vous pouvez affiner les performances de ces modèles.
Performances de réglage
Il existe deux elements clés pour optimiser les performances de la fonction UDF. La première est que vous souhaitez utiliser chaque GPU efficacement, ce que vous pouvez ajuster en modifiant la taille des tailles de lot pour les éléments envoyés au GPU par le pipeline Transformers. La seconde consiste à vous assurer que votre dataframe est bien partitionné pour utiliser l’ensemble du cluster.
Votre UDF devrait fonctionner immédiatement avec un batch_size
de 1. Cependant, cela peut ne pas utiliser efficacement les ressources disponibles pour les travailleurs. Pour obtenir de meilleures performances, vous pouvez ajuster la taille du lot au modèle et au matériel que vous utilisez. Databricks recommande d’essayer différentes tailles de lot pour le pipeline sur votre cluster afin de trouver les meilleures performances. En savoir plus sur traitement par pipeline et autre choices de performances dans la documentation d’Hugging Face. Vous pouvez surveiller les performances du GPU en visionnant le stay métrique des ganglions pour un cluster et en choisissant une métrique, telle que « gpu0-util » pour l’utilisation du processeur GPU ou « gpu0_mem_util » pour l’utilisation de la mémoire GPU.


Votre objectif en ajustant la taille du lot est de la définir suffisamment grande pour qu’elle entraîne l’utilisation complète du GPU mais n’entraîne pas d’erreurs « CUDA à court docket de mémoire ».
Pour bien utiliser le matériel de votre cluster, vous devrez peut-être repartitionner votre Spark DataFrame. Généralement, un a number of du nombre de GPU sur vos nœuds de calcul (pour les clusters GPU) ou du nombre de cœurs sur les nœuds de calcul de votre cluster (pour les clusters CPU) fonctionne bien dans la pratique. L’utilisation de l’UDF est identique à l’utilisation d’autres UDF sur Spark. Par exemple, vous pouvez l’utiliser dans une instruction choose pour créer une colonne avec les résultats de l’inférence de modèle.
pattern = pattern.repartition(32)
summaries = pattern.choose(pattern.textual content, summarize_batch_udf(pattern.textual content).alias("abstract"))
Envelopper des modèles prédéfinis en tant que modèles MLflow
Le stockage d’un modèle pré-formé en tant que modèle MLflow facilite encore plus le déploiement d’un modèle pour le traitement par heaps ou inférence en temps réel. Cela permet également la gestion des variations du modèle by way of le Registre modèleet simplifie le code de chargement du modèle pour vos fees de travail d’inférence.
La première étape consiste à créer un modèle personnalisé pour votre pipeline, qui encapsule le chargement du modèle, l’initialisation de l’utilisation du GPU et la fonction d’inférence.
import mlflow
class SummarizationPipelineModel(mlflow.pyfunc.PythonModel):
def load_context(self, context):
gadget = 0 if torch.cuda.is_available() else -1
self.pipeline = pipeline("summarization", context.artifacts("pipeline"), gadget=gadget)
def predict(self, context, model_input):
texts = model_input.iloc(:,0).to_list() # get the primary column
pipe = self.pipeline(texts, truncation=True, batch_size=8)
summaries = (abstract('summary_text') for abstract in pipe)
return pd.Collection(summaries)
Le code est étroitement parallèle au code de création et d’utilisation d’un pandas_udf décrit ci-dessus. Une différence est que le pipeline est chargé à partir d’un fichier mis à la disposition du contexte du modèle MLflow. Ceci est fourni à MLflow lors de la journalisation d’un modèle. Les pipelines de transformateurs Hugging Face facilitent l’enregistrement du modèle dans un fichier native sur le pilote, qui est ensuite transmis à la fonction log_model pour les interfaces MLflow pyfunc.
summarizer.save_pretrained("./pipeline")
with mlflow.start_run() as run:
mlflow.pyfunc.log_model(artifacts={'pipeline': "./pipeline"}, artifact_path="summarization_model", python_model=SummarizationPipelineModel())
Inférence par heaps à l’aide de modèles MLflow
MLflow fournit une interface easy pour charger n’importe quel modèle enregistré ou enregistré dans une UDF Spark. Vous pouvez rechercher un URI de modèle à partir du registre de modèles ou de l’interface utilisateur d’exécution d’expérience consignée.
logged_model_uri = f"runs:/{run.information.run_id}/summarization_model"
loaded_model = mlflow.pyfunc.spark_udf(spark, model_uri=logged_model_uri, result_type='string')
summaries = df.choose(df.title, df.textual content, loaded_model(df.textual content).alias("abstract"))
Modèles de réglage fin sur une seule machine à l’aide de 🤗 Transformers Coach
Parfois, les modèles pré-formés ne répondent pas à vos besoins prêts à l’emploi et vous devez affiner les modèles sur vos propres données. Par exemple, vous souhaiterez peut-être créer un classificateur de texte basé sur un modèle de base qui classe les tickets d’help dans les ontologies de vos équipes d’help, ou vous souhaiterez peut-être créer un classificateur de spam personnalisé sur vos données.
Vous n’avez pas besoin de quitter Databricks pour affiner vos modèles. Pour les ensembles de données de taille moyenne, vous pouvez le faire sur une seule machine avec prise en cost GPU. L’utilitaire Hugging Face transformers Coach facilite la configuration et la formation de modèles. Pour les ensembles de données plus volumineux, Databricks prend également en cost apprentissage en profondeur distribué multi-machine multi-GPU.
Le processus est le suivant : créez un cluster de machine distinctive avec prise en cost GPU, préparez et téléchargez votre ensemble de données sur le pilote, effectuez une formation de modèle à l’aide de Coach et enregistrez le modèle résultant dans MLflow.
Préparation et téléchargement des données
Commencez par formater vos données d’entraînement dans un tableau répondant aux attentes du Formateur. Pour la classification de texte, il s’agit d’un tableau à deux colonnes : une colonne de texte et une colonne d’étiquettes. Dans notre exemple de cahier nous chargeons des données de spam de SMS :
Les transformateurs Hugging Face fournissent AutoModelForSequenceClassification en tant que chargeur de modèle pour la classification de texte, qui attend des ID entiers comme étiquettes de catégorie. Cependant, vous devez également spécifier des mappages entre les étiquettes d’entier et les étiquettes de chaîne et inversement. Si vous avez un DataFrame avec des étiquettes de chaîne, vous pouvez collecter ces informations comme go well with :
labels = sms.choose(sms.label).groupBy(sms.label).rely().gather()
id2label = {index: row.label for (index, row) in enumerate(labels)}
label2id = {row.label: index for (index, row) in enumerate(labels)}
Créez ensuite les identifiants entiers en tant que colonne d’étiquette avec un pandas_udf:
from pyspark.sql.features import pandas_udf
import pandas as pd
@pandas_udf('integer')
def replace_labels_with_ids(labels: pd.Collection) -> pd.Collection:
return labels.apply(lambda x: label2id(x))
sms_id_labels = sms.choose(replace_labels_with_ids(sms.label).alias('label'), sms.textual content)
Divisez les données en formation/check et mettez les données à la disposition du système de fichiers du pilote. Une façon de le faire est d’utiliser le Quantity racine DBFS ou factors de montage.
(prepare, check) = sms_id_labels.persist().randomSplit((0.8, 0.2))
# Write the tables to DBFS.
train_dbfs_path = f"{tutorial_path}/sms_train"
test_dbfs_path = f"{tutorial_path}/sms_test"
train_df = prepare.write.parquet(train_dbfs_path, mode="overwrite")
test_df = check.write.parquet(test_dbfs_path, mode="overwrite")
Ces fichiers parquet sont maintenant disponibles pour le système de fichiers sur le pilote en utilisant le chemin monté /dbfs. Vous pouvez spécifier les chemins d’accès aux fichiers de parquet à l’aide de la 🤗 Jeux de données utilitaires pour créer un ensemble de données d’entraînement et d’évaluation.
from datasets import load_dataset
train_test = load_dataset("parquet", data_files={"prepare":f"/dbfs{train_dbfs_path}/*.parquet", "check":f"/dbfs{test_dbfs_path}/*.parquet"})
Le modèle attend une entrée tokenisée, plutôt que le texte dans les données téléchargées. Pour garantir la compatibilité avec le modèle de base, utilisez l’AutoTokenizer chargé à partir du modèle de base. Les ensembles de données HuggingFace vous permettent d’appliquer directement le tokenizer de manière cohérente aux données d’entraînement et de check.
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(base_model)
def tokenize_function(examples):
return tokenizer(examples("textual content"), padding=False, truncation=True)
train_test_tokenized = train_test.map(tokenize_function, batched=True)
Construire un entraîneur
Le Entraîneur les lessons nécessitent que l’utilisateur fournisse des métriques, un modèle de base et une configuration de formation. Par défaut, le formateur calculera et utilisera la perte comme métrique, ce qui n’est pas très interprétable. Vous trouverez ci-dessous un exemple de création d’une fonction de métrique qui calculera en outre la précision lors de la formation du modèle.
import numpy as np
import consider
metric = consider.load("accuracy")
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return metric.compute(predictions=predictions, references=labels)
Pour la classification de texte, utilisez AutoModelForSequenceClassification pour charger un modèle de base pour la classification de texte. Ici, vous fournissez le nombre de lessons et les mappages d’étiquettes.
from transformers import AutoModelForSequenceClassification
mannequin = AutoModelForSequenceClassification.from_pretrained(base_model, num_labels=2, label2id=label2id, id2label=id2label)
Enfin, vous devez créer la configuration d’entraînement. Le TrainingArguments
classe permet de spécifier le répertoire de sortie, la stratégie d’évaluation, le taux d’apprentissage et d’autres paramètres.
from transformers import TrainingArguments, Coach
training_output_dir = "sms_trainer"
training_args = TrainingArguments(output_dir=training_output_dir, evaluation_strategy="epoch")
Utilisant un collecteur de données saisie de heaps dans les ensembles de données d’entraînement et d’évaluation. En utilisant le DataCollatorWithPadding
avec des valeurs par défaut donne de bonnes performances de base pour la classification de texte.
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer)
Avec tous ces paramètres construits, vous pouvez maintenant créer un entraîneur.
coach = Coach(
mannequin=mannequin,
args=training_args,
train_dataset=train_test_dataset("prepare"),
eval_dataset=train_test_dataset("check"),
compute_metrics=compute_metrics,
data_collator=data_collator,
)
Exécution de la formation et journalisation du modèle
Hugging Face s’interface bien avec MLflow, enregistrant automatiquement les métriques pendant la formation du modèle à l’aide du MLflowCallback. Cependant, vous devez enregistrer vous-même le modèle formé. Semblable à l’exemple ci-dessus, Databricks recommande d’encapsuler le modèle formé dans un pipeline de transformateurs et d’utiliser le pyfunc de MLflow log_model
capacités. Pour ce faire, vous aurez besoin d’une classe de modèle personnalisée.
import mlflow
import torch
pipeline_artifact_name = "pipeline"
class TextClassificationPipelineModel(mlflow.pyfunc.PythonModel):
def load_context(self, context):
gadget = 0 if torch.cuda.is_available() else -1
self.pipeline = pipeline("text-classification", context.artifacts(pipeline_artifact_name), gadget=gadget)
def predict(self, context, model_input):
texts = model_input(model_input.columns(0)).to_list()
pipe = self.pipeline(texts, truncation=True, batch_size=8)
labels = (prediction('label') for prediction in pipe)
return pd.Collection(labels)
Enveloppez la formation dans une exécution mlflow, en construisant un pipeline de transformateurs à partir du tokenizer et du modèle formé, en l’écrivant sur le disque native. Enfin, connectez le modèle à MLflow.
from transformers import pipeline
model_output_dir = "./sms_model"
pipeline_output_dir = "./sms_pipeline"
model_artifact_path = "sms_spam_model"
with mlflow.start_run() as run:
coach.prepare()
coach.save_model(model_output_dir)
pipe = pipeline("text-classification", mannequin=AutoModelForSequenceClassification.from_pretrained(model_output_dir), batch_size=8, tokenizer=tokenizer)
pipe.save_pretrained(pipeline_output_dir)
mlflow.pyfunc.log_model(artifacts={pipeline_artifact_name: pipeline_output_dir}, artifact_path=model_artifact_path, python_model=TextClassificationPipelineModel())
Le chargement du modèle pour l’inférence est identique au chargement du modèle pré-entraîné enveloppé par MLflow.
logged_model = "runs:/{run_id}/{model_artifact_path}".format(run_id=run.information.run_id, model_artifact_path=model_artifact_path)
# Load mannequin as a Spark UDF. Override result_type if the mannequin doesn't return double values.
sms_spam_model_udf = mlflow.pyfunc.spark_udf(spark, model_uri=logged_model, result_type='string')
check = check.choose(check.textual content, check.label, sms_spam_model_udf(check.textual content).alias("prediction"))
show(check)
Cette part a montré remark vous pouvez utiliser directement les API de Hugging Face Transformer Coach pour affiner un modèle à un nouveau problème de classification de texte. Vous pouvez affiner de nombreux autres modèles de PNL pour un giant éventail de tâches, et le Lessons AutoModel pour le traitement du langage naturel fournir une excellente base.
Conclusion
Ce billet de weblog a démontré quelques bonnes pratiques et montré à quel level il est facile de commencer à utiliser des transformateurs pour les tâches NLP sur Databricks.
Les factors clés à rappeler pour l’inférence sont :
- 🤗 Les pipelines de transformateurs facilitent l’utilisation des modèles de transformateurs,
- Repartitionnez vos données si nécessaire pour utiliser le cluster complet,
- Vous pouvez ajuster la taille de votre lot pour une utilisation efficace des GPU,
- Spark attribue automatiquement des GPU sur des clusters GPU multi-machines,
- Les UDF Pandas gèrent la diffusion de modèles et les données de traitement par heaps, et
- les pipelines simplifient la journalisation des modèles de transformateurs vers MLflow.
Les factors clés à rappeler pour la formation sur modèle de machine distinctive :
- 🤗 Les Transformers Trainers offrent un moyen accessible d’affiner les modèles,
- Préparez vos ensembles de données sur Spark, en mappant toutes les étiquettes aux identifiants si nécessaire pour la tâche de modélisation, en laissant la tokenisation à 🤗 Transformers,
- Rendre les jeux de données disponibles pour le système de fichiers du pilote,
- Tokenize les jeux de données à l’aide d’AutoTokenizer pour charger le bon tokenizer pour le modèle,
- Utilisez Coach pour effectuer un réglage fin,
- Construire un pipeline à partir du tokenizer et du modèle affiné, et
- Enregistrez le modèle dans MLflow à l’aide d’un modèle personnalisé qui encapsule le pipeline.
Databricks proceed d’investir dans des moyens plus simples pour mettre à l’échelle la formation et l’inférence des modèles sur Databricks. Restez à l’affût des améliorations apportées au chargement des données, à la formation de modèles distribués et au stockage 🤗 Pipelines et modèles Transformers en tant que modèles MLflow.
Pour commencer avec ces exemples, importez ces blocs-notes pour les utiliser modèles pré-formés et réglage fin.