Share via


NLP용 포옹 얼굴 변환기를 사용하여 모델 유추

이 문서에서는 NLP(자연어 처리) 모델 유추에 포옹 얼굴 변환기를 사용하는 방법을 보여 줍니다.

Hugging Face 변압기는 미리 학습된 모델을 유추에 사용할 수 있는 파이프라인 클래스를 제공합니다. 🤗 변환기 파이프라인은 Azure Databricks에서 쉽게 사용할 수 있는 다양한 NLP 작업을 지원합니다.

요구 사항

  • MLflow 2.3
  • Hugging Face transformers 라이브러리가 설치된 모든 클러스터는 일괄 처리 유추에 사용할 수 있습니다. 라이브러리는 transformers Databricks Runtime 10.4 LTS ML 이상에 미리 설치되어 있습니다. 많은 인기 있는 NLP 모델은 GPU 하드웨어에서 가장 잘 작동하므로 CPU에서 사용하도록 특별히 최적화된 모델을 사용하지 않는 한 최근 GPU 하드웨어를 사용하여 최상의 성능을 얻을 수 있습니다.

Pandas UDF를 사용하여 Spark 클러스터에 모델 계산 배포

미리 학습된 모델을 실험할 때 Pandas UDF를 사용하여 모델을 래핑하고 작업자 CPU 또는 GPU에서 계산을 수행할 수 있습니다. Pandas UDF는 각 작업자에게 모델을 배포합니다.

기계 번역을 위한 Hugging Face Transformers 파이프라인을 만들고 Pandas UDF를 사용하여 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)

device 이러한 방식으로 설정하면 클러스터에서 GPU를 사용할 수 있는 경우 GPU가 사용됩니다.

번역을 위한 Hugging Face 파이프라인은 각각 단일 키 translation_text 와 번역된 텍스트가 포함된 값을 가진 Python dict 개체 목록을 반환합니다. 이 UDF는 결과에서 번역을 추출하여 번역된 텍스트만 사용하여 Pandas 시리즈를 반환합니다. 파이프라인이 설정 device=0하여 GPU를 사용하도록 생성된 경우 클러스터에 여러 GPU가 있는 인스턴스가 있는 경우 Spark는 작업자 노드에 GPU를 자동으로 다시 할당합니다.

UDF를 사용하여 텍스트 열을 번역하려면 문에서 UDF를 select 호출할 수 있습니다.

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')))

복합 결과 형식 반환

Pandas UDF를 사용하면 보다 구조화된 출력을 반환할 수도 있습니다. 예를 들어 명명된 엔터티 인식에서 파이프라인은 엔터티, 해당 범위, 형식 및 연결된 점수를 포함하는 개체 목록을 dict 반환합니다. 번역 예제와 비슷하지만 명명된 엔터티 인식의 경우 주석의 반환 형식 @pandas_udf 이 더 복잡합니다.

예를 들어 드라이버에서 파이프라인을 실행하여 파이프라인 결과를 검사하여 사용할 반환 형식을 파악할 수 있습니다.

이 예제에서는 다음 코드를 사용합니다.

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)

주석을 생성하려면 다음을 수행합니다.

[[{'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}]]

이 항목을 반환 형식으로 나타내려면 필드를 사용하여 array 항목을 다음의 structstruct필드로 나열 dict 할 수 있습니다.

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')))

성능 조정

UDF의 튜닝 성능에는 몇 가지 주요 측면이 있습니다. 첫 번째는 각 GPU를 효과적으로 사용하는 것이며, 변환기 파이프라인에서 GPU로 전송되는 일괄 처리의 크기를 변경하여 조정할 수 있습니다. 두 번째는 데이터 프레임이 전체 클러스터를 활용하도록 잘 분할되었는지 확인하는 것입니다.

마지막으로, Hugging Face 모델을 캐시하여 모델 로드 시간 또는 수신 비용을 절감할 수 있습니다.

일괄 처리 크기 선택

위에서 설명한 UDF는 1을 사용하여 기본적으로 batch_size 작동해야 하지만 작업자가 사용할 수 있는 리소스를 효율적으로 사용하지 못할 수 있습니다. 성능을 향상시키려면 일괄 처리 크기를 클러스터의 모델 및 하드웨어로 조정합니다. Databricks는 최상의 성능을 찾기 위해 클러스터의 파이프라인에 대해 다양한 일괄 처리 크기를 시도하는 것이 좋습니다. Hugging Face 설명서에서 파이프라인 일괄 처리 및 기타 성능 옵션에 대해 자세히 알아보세요.

전체 GPU 사용률을 구동하지만 오류가 발생하지 CUDA out of memory 않도록 충분히 큰 일괄 처리 크기를 찾아보세요. 튜닝 중에 오류가 발생하면 CUDA out of memory 노트북을 분리하고 다시 연결하여 GPU의 모델 및 데이터에 사용되는 메모리를 해제해야 합니다.

클러스터에 대한 라이브 클러스터 메트릭을 보고 GPU 프로세서 사용률 또는 gpu0_mem_util GPU 메모리 사용률과 같은 gpu0-util 메트릭을 선택하여 GPU 성능을 모니터링합니다.

단계 수준 예약을 사용하여 병렬 처리 조정

기본적으로 Spark는 각 컴퓨터에서 GPU당 하나의 작업을 예약합니다. 병렬 처리를 늘리려면 단계 수준 일정 예약을 사용하여 SPARK에 GPU당 실행할 작업 수를 알려줄 수 있습니다. 예를 들어 Spark가 GPU당 두 개의 작업을 실행하도록 하려면 다음과 같은 방법으로 이를 지정할 수 있습니다.

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)

사용 가능한 모든 하드웨어를 사용하도록 데이터 다시 분할

성능에 대한 두 번째 고려 사항은 클러스터의 하드웨어를 최대한 활용하는 것입니다. 일반적으로 작업자의 GPU 수(GPU 클러스터의 경우) 또는 클러스터의 작업자(CPU 클러스터용)에 있는 코어 수의 작은 배수가 잘 작동합니다. 입력 DataFrame에는 클러스터의 병렬 처리를 활용할 수 있는 충분한 파티션이 이미 있을 수 있습니다. DataFrame에 포함된 파티션 수를 확인하려면 .를 사용합니다 df.rdd.getNumPartitions(). 를 사용하여 repartitioned_df = df.repartition(desired_partition_count)DataFrame을 다시 분할할 수 있습니다.

DBFS 또는 탑재 지점에서 모델 캐시

다른 클러스터 또는 다시 시작한 클러스터에서 모델을 자주 로드하는 경우 DBFS 루트 볼륨 또는 탑재 지점에서 Hugging Face 모델을 캐시할 수도 있습니다. 이렇게 하면 수신 비용이 감소하고 새 클러스터 또는 다시 시작한 클러스터에서 모델을 로드하는 시간을 줄일 수 있습니다. 이렇게 하려면 파이프라인을 TRANSFORMERS_CACHE 로드하기 전에 코드에서 환경 변수를 설정합니다.

예시:

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

또는 MLflow transformers 버전으로 MLflow에 모델을 로깅하여 비슷한 결과를 얻을 수 있습니다.

Notebook: 얼굴 변환기 유추 및 MLflow 로깅 포옹

예제 코드로 빠르게 시작하기 위해 이 Notebook은 Hugging Face Transformers 파이프라인 유추 및 MLflow 로깅을 사용하여 텍스트 요약을 위한 엔드투엔드 예제입니다.

얼굴 변압기 파이프라인 유추 Notebook 포옹

전자 필기장 가져오기

추가 리소스

다음 가이드를 사용하여 Hugging Face 모델을 미세 조정할 수 있습니다.

포옹 얼굴 변압기에 대해 자세히 알아보기