카테고리 보관물: NLP

“트랜스포머를 활용한 자연어 처리” Transformer 4.26 버전에서 재실행 완료

<트랜스포머를 활용한 자연어 처리> 책의 코드를 최신 버전의 라이브러리에서 재실행하여 깃허브에 업데이트했습니다. 재실행에서 사용한 라이브러리 버전은 다음과 같습니다.

  • transformers v4.26.1
  • datasets v2.10.1
  • accelerate v0.16.0

감사합니다!

“트랜스포머를 활용한 자연어 처리” 번역을 마쳤습니다.

NLP 분야에서 아마존 베스트 셀러 자리에 오른 <Natural Language Processing with Transformers>의 번역 작업을 마쳤습니다. 이 책은 최근 대세인 허깅 페이스(Hugging Face) 라이브러리를 활용하여 다양한 NLP 작업을 해결하는 방법을 소개합니다. 허깅 페이스의 머신러닝 엔지니어들이 직접 쓴 책으로도 유명하고 <핸즈온 머신러닝 2판>의 저자 오렐리앙 제롱이 직접 추천사를 쓰고 크게 칭찬한 책입니다! 자연어 처리에 관심이 모든 분에게 자신있게 추천합니다! 🙂

  • 1장은 트랜스포머의 탄생을 다룹니다. 인코더-디코더, 어텐션, 전이 학습, 허깅 페이스의 트랜스포머스를 소개합니다. 간단한 파이프라인 객체를 사용해 텍스트 분류, 객체명 인식, 질문 답변, 요약, 번역, 텍스트 생성 예를 보여줍니다. 마지막으로 허깅 페이스 생태계로 허브, 토크나이저, 데이터셋, 액셀러레이트를 언급합니다.
  • 2장은 emotion 데이터셋을 사용한 텍스트 분류 예제를 다루면서 본격적으로 NLP 작업에 뛰어듭니다. 허깅 페이스 데이터셋의 구조를 자세히 소개하고 여러 토큰화 방법의 장단점을 언급합니다. 그다음 DistilBERT 모델을 베이스로 사용해 헤드만 훈련하는 경우와 전체 모델을 튜닝하는 전이 학습을 각기 수행해 봅니다. 전체적으로 파이토치 기반 모델을 사용하지만 중간중간 텐서플로 모델과 케라스에 대한 안내도 빠지지 않습니다. 훈련한 뒤 오차 행렬을 사용해 모델의 예측 결과를 분석하고 마지막으로 허브에 훈련된 모델을 업로드한 후 파이프라인으로 다시 추론에 활용하는 방법까지 다루고 있습니다.
  • 3장은 트랜스포머 구조를 자세히 소개합니다. 수학은 최소화하고 그림과 코드로 사용해 설명합니다. 먼저 인코더, 디코더를 포함해 트랜스포머의 전체 구조를 소개하고 인코더에 필요한 구성 요소를 하나씩 파헤칩니다. 셀프 어텐션, 멀티 헤드 어텐션, 피드 포워드, 정규화, 위치 임베딩 등입니다. 이런 요소를 직접 코드로 작성해 트랜스포머 인코더를 만듭니다. 이 과정에서 BertViz를 사용해 어텐션 가중치를 시각화해보기도 하고, 쿼리/키/값에 대한 재미있는 비유도 들을 수 있습니다. 디코더 부분은 마스킹에 대해 자세히 소개하고 다른 구성 요소 부분은 숙제로 남깁니다. 마지막으로 트랜스포머 계열의 모델을 인코더, 디코더, 인코더-디코더 유형으로 나누고 각 유형에서 마일스톤 격의 모델들을 소개합니다.
  • 4장은 다국어 텍스트의 개체명 인식(NER)을 다룹니다. 이 장에서 사용하는 데이터셋인 pan-x를 둘러 보고 베이스 모델로 사용할 XLM-RoBERTa를 소개합니다. 그다음 XLM-RoBERTa의 토크나이저인 SentencePiece를 WordPiece와 비교하여 설명합니다. 또 텍스트 분류와 NER 모델의 비슷한 점과 다른 점을 설명합니다. 허깅페이스에 있는 NER 클래스를 사용하지 않고 여기서는 XLM-RoBERTa를 베이스로 NER 작업을 위한 헤드를 직접 만들어 올립니다. 이 과정에서 허깅페이스의 모델 클래스의 구조와 여러 상속 관계를 배울 수 있습니다. 만든 모델에 사전 훈련된 가중치를 로드하고 독일어 텍스트로 미세 튜닝한 다음 모델의 오류를 분석합니다. 마지막으로 독일어에서 미세 튜닝한 모델을 프랑스어, 이탈리아어, 영어 텍스트에 적용해 봅니다. 결과는 어떨까요? 이번에는 독일어와 프랑스어 데이터를 합쳐서 모델을 미세 튜닝합니다. 그다음 다시 프랑스어, 이탈리아어, 영어 텍스트에 적용해 봅니다. 결과는 어떨까요? 마지막으로 각 언어에서 미세 튜닝하고 또 전체를 합쳐서 모델을 훈련한 다음 결과를 확인합니다.
  • 5장은 흥미로운 주제인 텍스트 생성 작업을 다룹니다. 이 장에서는 텍스트 생성 모델을 직접 훈련하기 보다는 유명한 GPT-2 모델을 사용해 텍스트 생성 작업에 대해 알아 봅니다. 먼저 그리디 서치와 빔 서치를 사용하여 텍스트를 생성해 보고 다양성이 높은 텍스트 생성을 위한 샘플링 방법으로 넘어가서 top-k와 top-p 방식을 배웁니다. 이 모든 방식을 허깅페이스 트랜스포머스 라이브러리에서 지원합니다. 마지막으로 최선의 텍스트 디코딩 방법에 대해 고찰하는 것으로 장을 마무리합니다.
  • 6장은 요약 작업을 다룹니다. 이 장에서 사용할 데이터셋은 요약 작업에 널리 사용되는 CNN/DailyMail 데이터셋입니다. 먼저 허깅페이스의 파이프라인으로 사전 훈련된 GPT-2, T5, BART, PEGASUS 모델을 사용해 샘플 데이터의 요약을 생성하고 결과를 비교해 봅니다. 이 과정에서 네 모델의 특징도 간략히 살펴 보고 있습니다. 그다음 생성된 텍스트의 품질을 정량적으로 평가하기 위해 BLEU와 ROUGE 점수의 이론적인 부분을 소개하고 샘플 텍스트에 적용해 봅니다. 그다음 가장 성능이 뛰어난 PEGASUS 모델로 CNN/DailyMail 데이터셋의 테스트 세트 일부를 사용해 ROUGE 점수를 계산하는 방법을 알아봅니다. 마지막으로 삼성이 만든 SAMSum 데이터셋에서 PEGASUS 모델을 적용해 보고, 이 데이터셋에서 미세 튜닝한 후 결과를 비교합니다. 이 모델을 사용해 임의로 만든 샘플 대화를 요약한 결과를 보여주는 것으로 이 장을 마칩니다.
  • 7장은 질문 답변(question-answering, QA) 작업을 다룹니다. 먼저 QA 작업을 간단히 소개하고 이 장에서 사용할 SubjQA 데이터셋을 준비합니다. QA 시스템을 만들기 위해 텍스트에서 가능한 답변을 찾아 내는 방법을 알아 봅니다. 이를 위해 사용할 수 있는 허깅 페이스 사전 훈련된 모델을 몇 가지 소개하고 그 중에 MiniLM을 선택합니다. 그다음 질문과 텍스트를 토큰화하고 모델에 통과시켜 출력된 결과에서 답의 범위를 찾습니다. 그다음에는 긴 텍스트를 다루기 위해 슬라이딩 윈도를 적용하는 방법을 알아 봅니다. 하지만 전체 문서에서 답을 찾기 위해서는 질문에 관련된 문서를 검색하는 시스템이 필요합니다. 이를 위해 헤이스택 라이브러리를 사용해 리트리버-리더(retriever-reader) 구조를 만듭니다. 헤이스택에서 제공하는 여러 리트리버를 소개하고 이와 같이 사용할 수 있는 문서 저장소도 알아 봅니다. 여기에서는 BM25 리트리버와 문서 저장소로 일래스틱서치를 사용합니다. 일래스틱서치를 설치하고 로컬에서 서버를 실행한 다음 SubjQA 데이터를 저장합니다. 이제 리트리버와 리더 객체를 초기화합니다. 리더는 앞에서와 같이 SQuAD에서 미세 튜닝된 MiniLM 모델입니다. 그다음 헤이스택 파이프라인으로 리트리버와 리더를 통합하여 테스트 질문에 대한 답을 추출해 봅니다. 이제 시스템 성능을 높이기 위해 리트리버와 리더를 평가할 수 있는 지표에 대해 알아 봅니다. 리트리버는 재현율을 사용해 평가합니다. 이를 위해 헤이스택의 사용자 정의 파이프라인을 만듭니다. 그다음 질문과 문서에 대해 밀집 벡터를 만들어 사용하는 DPR에 대해 알아 보고 앞서 만든 리트리버와 성능을 비교해 봅니다. 리더는 EM과 F-1 점수로 평가하며 두 지표의 장단점을 소개합니다. 마지막으로 MiniLM 모델을 SubjQA에 다시 미세 튜닝하여 전체 파이프라인의 성능을 비교해 봅니다. 추출적 QA 시스템 외에도 생성적 QA를 소개하고 헤이스택이 제공하는 RAG 모델을 사용해 질문에 대한 답변을 생성해 봅니다. 이 모든 작업을 코랩 노트북으로 테스트해 볼 수 있습니다.
  • 8장은 트랜스포머 모델의 성능 개선을 위한 도구를 알아 봅니다. 먼저 여러 성능 개선 방법을 적용해 보기 위해 BERT 기반 의도 탐지 모델을 선택합니다. 의도 탐지 작업에 대한 간단한 소개와 함께 CLINC150 데이터셋에서 미세 튜닝한 BERT 모델을 허깅페이스 파이프라인으로 사용해 봅니다. 그다음 여러 방법을 적용하면서 성능, 레이턴시, 메모리 사용량을 편리하게 비교하기 위해 벤치마킹 클래스를 준비합니다. 먼저 지식 정제(knowledge distillation) 방법에 대해 자세히 설명한 다음 BERT 기반 모델로 DistilBERT 모델을 훈련합니다. 이를 위해 사용자 정의 허깅페이스 Trainer 클래스를 만듭니다. 지식 정제로 훈련된 DistilBERT 모델은 BERT 기반 모델에 비해 정확도, 레이턴시, 크기가 어떻게 다를까요? 이번에는 옵투나(Optuna)로 앞서 만든 정제 모델에 대해 하이퍼파라미터 튜닝을 수행합니다. 이 모델의 정확도, 레이턴시, 크기는 어떻게 달라졌을까요? 다음은 양자화(quantization)를 소개합니다. 기본적인 양자화 방식을 자세히 배우고 여러 양자화 방식을 소개한 후 앞서 옵투나로 최적화한 모델에 양자화를 적용해 봅니다. 양자화를 적용한 후 모델의 정확도, 레이턴시, 크기는 어떻게 달라졌을까요? 이번에는 ONNX를 사용한 최적화를 적용해봅니다. 옵투나로 최적화한 모델을 ONNX 포맷으로 바꾸어 모델의 성능을 측정합니다. 그다음 ONNX 런타임에서 제공하는 양자화를 적용한 다음 다시 성능을 측정합니다. 어떤 모델의 정확도, 레이턴시, 크기가 제일 좋을까요? 마지막으로 가중치 가지치기에 대해 소개하며 이 장을 마칩니다.
  • 9장은 레이블링된 데이터가 전혀 없거나 조금만 있을 때 트랜스포머로 할 수 있는 일을 알아 봅니다. 이 장에서 사용하는 예제는 깃허브 이슈 내용을 바탕으로 적절한 태그를 다는 일입니다. 데이터셋을 준비한 다음 나이브 베이즈로 기준 모델을 만듭니다. 그다음 레이블링된 데이터가 전혀 없다고 가정하고 BERT 모델에 마스킹된 프롬프트를 주입하여 제로-샷 분류 작업을 시도해 봅니다. 이어서 자연어 추론을 위한 MNLI 데이터셋에서 훈련한 모델로 제로-샷 분류를 수행해 봅니다. 그리고 다중 레이블 분류에서 예측 레이블을 선택하는 방법을 소개합니다. 레이블링된 데이터가 적을 때는 데이터 증식을 사용할 수 있습니다. 이를 위해 NlpAug 라이브러리를 사용하여 토큰 교체를 적용하여 나이브 베이즈의 성능이 얼마나 향상되었는지 평가합니다. 그다음 방법은 텍스트 임베딩을 룩업 테이블처럼 사용해 최근접 이웃의 레이블을 예측으로 사용할 수 있습니다. 이 작업을 위해 페이스북의 FAISS 라이브러리를 사용하고 임베딩을 얻기 위해 파이썬 코드에서 훈련한 GPT-2 모델을 사용합니다. 마지막으로 레이블링된 데이터에서 트랜스포머 모델을 미세 튜닝하는 것입니다. 각 방법들의 성능을 평가하고 그래프로 비교합니다. 레이블링되지 않은 데이터가 많이 있다면 이를 활용하여 아예 언어 모델을 더 훈련할 수도 있습니다.
  • 10장은 트랜스포머 모델을 직접 훈련하는 과정을 소개합니다. 이 장에서 훈련할 모델은 파이썬 코드의 앞부분을 주입하면 나머지 부분을 완성해 주는 코드 자동 완성 트랜스포머입니다. 먼저 대용량 데이터셋에 관련된 어려움을 소개하고 깃허브의 오픈소스 파이썬 코드로부터 대용량 데이터셋을 구축합니다. 이 과정에서 허깅 페이스 데이터셋의 메모리 매핑과 스트리밍 기능을 알아 봅니다. 데이터셋을 준비했으니 다음으로 토크나이저를 훈련합니다. 이를 위해 GPT-2의 토크나이저를 사용합니다. 토크나이저 훈련 방법을 배우면서 BPE 알고리즘이나 유니코드 표현을 함께 살펴봅니다. 코드 자동 완성을 위한 훈련 목표를 결정하고 하이퍼파라미터는 gpt2-xl를 그대로 사용하여 모델을 초기화합니다. 마지막으로 데이터로더를 구성하고 허깅 페이스 엑셀러레이트를 사용해 훈련 루프를 만듭니다. 그다음 모델을 훈련하고 결과를 확인합니다.
  • 11장은 마지막 장으로 트랜스포머 모델을 확장할 때 어려움을 먼저 소개합니다. 그다음 어텐션 메커니즘을 효율적으로 만들기 위한 희소 어텐션과 선형 어텐션을 설명합니다. 최근 트랜스포머는 텍스트를 넘어서 비전과 음성에도 적용됩니다. iGPT, ViT와 테이블 데이터에 적용하는 TAPAS를 소개합니다. 마지막으로 멀티모달 트랜스포머로 wav2vec 2.0, VQA, LayoutLM, DALL·E, CLIP을 소개합니다. 끝으로 허깅 페이스 라이브러리를 더 많이 배울 수 있는 방법을 소개하는 것으로 책을 마칩니다.