AI/PyTorch

TOKENIZERS_PARALLELISM=(true | false) 경고 메세지는 무슨 뜻일까?

sangwonYoon 2023. 7. 21. 22:17

huggingface의 transformers 라이브러리를 사용하다보면 이런 경고 메세지를 본 적이 있을 것이다.

The current process just got forked. Disabling parallelism to avoid deadlocks... To disable this warning, please explicitly set TOKENIZERS_PARALLELISM=(true | false)

대부분의 경고 메세지가 그렇듯, 프로그램은 문제 없이 실행되지만 어느 부분에서 이 경고 메세지가 뜨고 어떤 문제에 대한 경고인지 궁금해졌다. 아래 내용들은 이 경고 메세지에 관한 자세한 탐구이므로 경고 메세지를 없애기 위한 해결책만을 원한다면 마지막 결론 부분만 읽으면 된다.

 

경고 메세지가 뜨는 조건

아래의 상황을 만족할 때 이 경고 메세지를 확인할 수 있다.

  1. Rust 기반의 fast tokenizer를 사용하고
  2. main process를 fork하여 multi processing을 사용하면서
  3. main process를 fork하기 전, fast tokenizer를 사용하는 경우

그렇다면, 이 상황이 왜 문제가 되는지 확인해보자.

 

Fast Tokenizer

fast tokenizer는 Python으로 구현된 일반적인 tokenizer과 달리, Rust로 구현되어 있다.

여기서 주목해야 하는 fast tokenizer의 특징은 문장을 tokenizing 과정을 병렬적으로 수행한다는 것이다. 다시 말해, 여러 문장을 동시에 tokenizing한다.

경고 메세지 마지막 부분에 please explicitly set TOKENIZERS_PARALLELISM=(true | false)의 의미가 바로 fast tokenizer가 tokenizing 과정을 병렬적으로 수행하도록 할 것인지 아닌지 명시하라는 것이다.

그렇다면 이 기능이 어떤 문제를 초래할 수 있는지 확인해보자.

 

Multi Processing

아마도 PyTorch에서 multi processing을 사용하는 가장 일반적인 경우는 data loader에서 num_workers를 사용하는 경우일 것이다.

 

Data Loader num_workers

data loader의 num_workers는 어떤 역할을 할까?

 

Pytorch DataLoader 공식 문서

공식 문서에 따르면 num_workers는 다음과 같은 역할을 한다.

num_workers (int, optional) – how many subprocesses to use for data loading. 0 means that the data will be loaded in the main process. (default: 0)

해석하자면 데이터 로딩을 위해 몇 개의 subprocess를 사용할 것인지 지정하는 역할이다. 만약 num_workers=0이면 main process에서 데이터를 로드할 것이고, num_workers가 0보다 크면 main process에서 데이터 로드가 진행되지 않고, main process를 fork하여 데이터 로드를 진행한다.

 

Fast Tokenizer + Multi Processing

fast tokenizer의 tokenizing 병렬 처리가 수행된 이후 process가 fork되면 deadlock이 발생할 수 있기 때문에 이 경고 메세지가 출력되는 것이다.

즉, 경고 메세지를 다시 해석해보면

  • The current process just got forked. : multi processing을 위해 process가 fork되었다.
  • Disabling parallelism to avoid deadlocks... : deadlock 문제가 발생할 수 있으므로 fast tokenizer의 병렬 처리 기능을 껐다.
  • To disable this warning, please explicitly set TOKENIZERS_PARALLELISM=(true | false) : 이 경고 메세지를 없애기 위해서는 TOKENIZERS_PARALLELISM을 true 또는 false로 명시해라.

 

경고 메세지 출력을 없애는 방법

가장 간단한 방법은 num_workers=0으로 data loader를 사용하는 것과 같이 multi processing을 사용하지 않는 것이다. 그러나 이 방법은 경고 메세지를 없애기 위해 모델 학습의 효율을 포기하는 것이기 때문에 별로 좋은 방법은 아니다.

다른 방법은 경고 메세지의 내용대로 TOKENIZERS_PARALLELISM를 true 또는 false로 설정하는 방법이다.

TOKENIZERS_PARALLELISM를 false로 설정하는 방법은 이 경고 메세지를 없애는 가장 효과적인 방법이다. 비록 fast tokenizer의 병렬 처리 기능을 쓸 수 없지만, 일반적인 tokenizer에 비하면 훨씬 빠른 tokenizing 속도를 보이기 때문에 일반적인 상황에서는 큰 문제가 되지 않는다.

그렇다면 TOKENIZERS_PARALLELISM를 true로 설정한다면 어떻게 될까? 어떠한 경고 메세지나 에러의 출력 없이 프로그램이 멈출 수 있다. 이 문제의 원인은 deadlock의 위험성 때문에 process가 fork되지 않아서 발생한다.

그렇다면 tokenizing 처리 속도가 매우 중요한 상황에서 fast tokenizer의 병렬 처리 기능을 끄지 않고 이 문제를 해결하는 방법은 없을까? 가능하다. 이 경고 메세지는 fast tokenizer의 병렬 처리 기능이 사용된 이후에 process가 fork되는 상황에서 출력되기 때문에 process가 fork되기 전에 fast tokenizer를 사용하지 않으면 된다. 예를 들어, data loader를 사용하기 이전에 데이터 셋이 tokenized된 결과물을 확인하기 위해 my_dataset[0]과 같이 출력하는 코드를 제거하면 된다.

 

결론

  • 이 경고 메세지는 deadlock이 발생할 위험이 있기 때문에 fast tokenizer의 병렬 처리 기능을 끈다고 알려주는 메세지이다.
  • 가장 간단하게 이 경고 메세지를 없애고 싶다면 파이썬 스크립트에 아래 코드를 추가하면 된다.
import os
os.environ["TOKENIZERS_PARALLELISM"] = "false"
  • 만약 process가 fork되기 전에 fast tokenizer가 불필요하게 사용된다면, 그것을 제거하는 것이 가장 최선의 해결책이다.

 

참고

stackoverflow.com/questions/62691279/…