Bagikan melalui


Inferensi model menggunakan Hugging Face Transformers untuk NLP

Artikel ini memperlihatkan kepada Anda cara menggunakan Hugging Face Transformers untuk inferensi model pemrosesan bahasa alami (NLP).

Memeluk transformator Wajah menyediakan kelas alur untuk menggunakan model yang telah dilatih sebelumnya untuk inferensi. 🤗 Alur transformator mendukung berbagai tugas NLP yang dapat Anda gunakan dengan mudah di Azure Databricks.

Persyaratan

  • MLflow 2.3
  • Kluster apa pun dengan pustaka Hugging Face transformers yang diinstal dapat digunakan untuk inferensi batch. transformers Pustaka ini telah diinstal sebelumnya pada Databricks Runtime 10.4 LTS ML ke atas. Banyak model NLP populer bekerja paling baik pada perangkat keras GPU, sehingga Anda mungkin mendapatkan performa terbaik menggunakan perangkat keras GPU terbaru kecuali Anda menggunakan model yang dioptimalkan khusus untuk digunakan pada CPU.

Menggunakan UDF Pandas untuk mendistribusikan komputasi model pada kluster Spark

Saat bereksperimen dengan model yang telah dilatih sebelumnya, Anda dapat menggunakan UDF Pandas untuk membungkus model dan melakukan komputasi pada CPU atau GPU pekerja. UDF Pandas mendistribusikan model ke setiap pekerja.

Anda juga dapat membuat alur Hugging Face Transformers untuk terjemahan mesin dan menggunakan Pandas UDF untuk menjalankan alur pada pekerja kluster Spark:

import pandas as pd
from transformers import pipeline
import torch
from pyspark.sql.functions import pandas_udf

device = 0 if torch.cuda.is_available() else -1
translation_pipeline = pipeline(task="translation_en_to_fr", model="t5-base", device=device)

@pandas_udf('string')
def translation_udf(texts: pd.Series) -> pd.Series:
  translations = [result['translation_text'] for result in translation_pipeline(texts.to_list(), batch_size=1)]
  return pd.Series(translations)

Mengatur dengan device cara ini memastikan bahwa GPU digunakan jika tersedia di kluster.

Alur Hugging Face untuk terjemahan mengembalikan daftar objek Python dict , masing-masing dengan satu kunci translation_text dan nilai yang berisi teks yang diterjemahkan. UDF ini mengekstrak terjemahan dari hasil untuk mengembalikan seri Pandas hanya dengan teks yang diterjemahkan. Jika alur Anda dibangun untuk menggunakan GPU dengan mengatur device=0, maka Spark secara otomatis menetapkan ulang GPU pada simpul pekerja jika kluster Anda memiliki instans dengan beberapa GPU.

Untuk menggunakan UDF untuk menerjemahkan kolom teks, Anda dapat memanggil UDF dalam select pernyataan:

texts = ["Hugging Face is a French company based in New York City.", "Databricks is based in San Francisco."]
df = spark.createDataFrame(pd.DataFrame(texts, columns=["texts"]))
display(df.select(df.texts, translation_udf(df.texts).alias('translation')))

Mengembalikan jenis hasil yang kompleks

Menggunakan UDF Pandas, Anda juga dapat mengembalikan output yang lebih terstruktur. Misalnya, dalam pengenalan entitas bernama, alur mengembalikan daftar dict objek yang berisi entitas, rentangnya, jenis, dan skor terkait. Meskipun mirip dengan contoh untuk terjemahan, jenis pengembalian untuk @pandas_udf anotasi lebih kompleks dalam kasus pengenalan entitas bernama.

Anda bisa merasakan jenis pengembalian yang akan digunakan melalui inspeksi hasil alur, misalnya dengan menjalankan alur pada driver.

Dalam contoh ini, gunakan kode berikut:

from transformers import pipeline
import torch
device = 0 if torch.cuda.is_available() else -1
ner_pipeline = pipeline(task="ner", model="Davlan/bert-base-multilingual-cased-ner-hrl", aggregation_strategy="simple", device=device)
ner_pipeline(texts)

Untuk menghasilkan anotasi:

[[{'entity_group': 'ORG',
   'score': 0.99933606,
   'word': 'Hugging Face',
   'start': 0,
   'end': 12},
  {'entity_group': 'LOC',
   'score': 0.99967843,
   'word': 'New York City',
   'start': 42,
   'end': 55}],
 [{'entity_group': 'ORG',
   'score': 0.9996372,
   'word': 'Databricks',
   'start': 0,
   'end': 10},
  {'entity_group': 'LOC',
   'score': 0.999588,
   'word': 'San Francisco',
   'start': 23,
   'end': 36}]]

Untuk mewakili ini sebagai jenis pengembalian, Anda bisa menggunakan array bidang struct , mencantumkan dict entri sebagai bidang structdari :

import pandas as pd
from pyspark.sql.functions import pandas_udf

@pandas_udf('array<struct<word string, entity_group string, score float, start integer, end integer>>')
def ner_udf(texts: pd.Series) -> pd.Series:
  return pd.Series(ner_pipeline(texts.to_list(), batch_size=1))

display(df.select(df.texts, ner_udf(df.texts).alias('entities')))

Menyetel performa

Ada beberapa aspek utama untuk menyetel performa UDF. Yang pertama adalah menggunakan setiap GPU secara efektif, yang dapat Anda sesuaikan dengan mengubah ukuran batch yang dikirim ke GPU oleh alur Transformers. Yang kedua adalah memastikan DataFrame dipartisi dengan baik untuk menggunakan seluruh kluster.

Terakhir, Anda mungkin ingin menyimpan model Hugging Face untuk menghemat waktu pemuatan model atau biaya masuk.

Pilih ukuran batch

Meskipun UDF yang dijelaskan di atas harus bekerja di luar kotak dengan batch_size 1, ini mungkin tidak menggunakan sumber daya yang tersedia untuk pekerja secara efisien. Untuk meningkatkan performa, sesuaikan ukuran batch ke model dan perangkat keras dalam kluster. Databricks merekomendasikan untuk mencoba berbagai ukuran batch untuk alur pada kluster Anda untuk menemukan performa terbaik. Baca selengkapnya tentang batching alur dan opsi performa lainnya dalam dokumentasi Hugging Face.

Coba temukan ukuran batch yang cukup besar sehingga mendorong pemanfaatan GPU penuh tetapi tidak mengakibatkan CUDA out of memory kesalahan. Saat Anda menerima CUDA out of memory kesalahan selama penyetelan, Anda perlu melepaskan dan memasang kembali notebook untuk merilis memori yang digunakan oleh model dan data di GPU.

Pantau performa GPU dengan melihat metrik kluster langsung untuk kluster, dan pilih metrik, seperti gpu0-util untuk pemanfaatan prosesor GPU atau gpu0_mem_util untuk pemanfaatan memori GPU.

Menyetel paralelisme dengan penjadwalan tingkat tahap

Secara default, Spark menjadwalkan satu tugas per GPU pada setiap komputer. Untuk meningkatkan paralelisme, Anda dapat menggunakan penjadwalan tingkat tahap untuk memberi tahu Spark berapa banyak tugas yang akan dijalankan per GPU. Misalnya, jika Anda ingin Spark menjalankan dua tugas per GPU, Anda dapat menentukannya dengan cara berikut:

from pyspark.resource import TaskResourceRequests, ResourceProfileBuilder

task_requests = TaskResourceRequests().resource("gpu", 0.5)

builder = ResourceProfileBuilder()
resource_profile = builder.require(task_requests).build

rdd = df.withColumn('predictions', loaded_model(struct(*map(col, df.columns)))).rdd.withResources(resource_profile)

Mempartisi ulang data untuk menggunakan semua perangkat keras yang tersedia

Pertimbangan kedua untuk performa adalah memanfaatkan perangkat keras secara penuh di kluster Anda. Umumnya, kelipatan kecil dari jumlah GPU pada pekerja Anda (untuk kluster GPU) atau jumlah inti di seluruh pekerja di kluster Anda (untuk kluster CPU) berfungsi dengan baik. DataFrame input Anda mungkin sudah memiliki partisi yang cukup untuk memanfaatkan paralelisme kluster. Untuk melihat berapa banyak partisi yang dikandung DataFrame, gunakan df.rdd.getNumPartitions(). Anda dapat mempartisi ulang DataFrame menggunakan repartitioned_df = df.repartition(desired_partition_count).

Cache model di DBFS atau pada titik pemasangan

Jika Anda sering memuat model dari kluster yang berbeda atau dimulai ulang, Anda mungkin juga ingin menyimpan model Hugging Face di volume akar DBFS atau pada titik pemasangan. Ini dapat mengurangi biaya masuk dan mengurangi waktu untuk memuat model pada kluster baru atau dimulai ulang. Untuk melakukan ini, atur TRANSFORMERS_CACHE variabel lingkungan dalam kode Anda sebelum memuat alur.

Contohnya:

import os
os.environ['TRANSFORMERS_CACHE'] = '/dbfs/hugging_face_transformers_cache/'

Atau, Anda dapat mencapai hasil yang sama dengan mencatat model ke MLflow dengan rasa MLflowtransformers.

Notebook: Memeluk inferensi Face Transformers dan pengelogan MLflow

Untuk memulai dengan cepat dengan contoh kode, notebook ini adalah contoh end-to-end untuk ringkasan teks dengan menggunakan inferensi alur Hugging Face Transformers dan pengelogan MLflow.

Memeluk notebook inferensi alur Transformer Wajah

Dapatkan buku catatan

Sumber Daya Tambahan:

Anda dapat menyempurnakan model Wajah Pelukan Anda dengan panduan berikut:

Pelajari selengkapnya tentang Apa itu Memeluk Transformer Wajah?