반응형


Ubuntu 같은 이름 프로세스 한번에 종료하기

 

리눅스를 사용하다보면, 프로세스를 한번에 종료해야하는 경우가 있다.

물론 killall과 같은 명령어를 사용할 수도 있지만, 

필자의 경우 Jupyter 노트북에서 멀티프로세싱을 통한 TPU 학습을 자주 했었는데,

TPU 특유의 멀티프로세싱 방식때문에 오류가 발생하거나 커널이 종료되었을 때, 자식 프로세스가 꺼지지 않고 유휴상태로 남아있는 경우가 잦았다. Jupyter 쓰시는 분들에게 아주 추천한다.

 

 

$ ps -elf | grep "프로세스명" | awk '{print $4}' | while read line; do kill $line; done

#예시 - Jupyter 커널 모두 종료하기
# ps -elf | grep "ipykernel" | awk '{print $4}' | while read line; do kill $line; done

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


TPU terminate called after throwing an instance of 'std::bad_alloc', Core Dumped(Aborted) 해결법

 

 

에러 메시지

ttcmalloc: large alloc 500236124160 bytes == (nil) @  0x7f51b5df3680 0x7f51b5e13ff4 0x7f51b590a309 0x7f51b590bfb9 0x7f51b590c056 0x7f4e5cc6a659 0x7f4e526a0954 0x7f51b5fe7b8a 0x7f51b5fe7c91 0x7f51b5d46915 0x7f51b5fec0bf 0x7f51b5d468b8 0x7f51b5feb5fa 0x7f51b5bbb34c 0x7f51b5d468b8 0x7f51b5d46983 0x7f51b5bbbb59 0x7f51b5bbb3da 0x67299f 0x682dcb 0x684321 0x5c3cb0 0x5f257d 0x56fcb6 0x56822a 0x5f6033 0x56ef97 0x5f5e56 0x56a136 0x5f5e56 0x569f5e
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
https://symbolize.stripped_domain/r/?trace=7f51b5c2918b,7f51b5c2920f&map=
*** SIGABRT received by PID 14088 (TID 14088) on cpu 95 from PID 14088; stack trace: ***
PC: @     0x7f51b5c2918b  (unknown)  raise
    @     0x7f4f86e6d800        976  (unknown)
    @     0x7f51b5c29210  (unknown)  (unknown)
https://symbolize.stripped_domain/r/?trace=7f51b5c2918b,7f4f86e6d7ff,7f51b5c2920f&map=2a762cd764e70bc90ae4c7f9747c08d7:7f4f79f2b000-7f4f871ac280
E0628 16:55:18.669807   14088 coredump_hook.cc:292] RAW: Remote crash data gathering hook invoked.
E0628 16:55:18.669833   14088 coredump_hook.cc:384] RAW: Skipping coredump since rlimit was 0 at process start.
E0628 16:55:18.669843   14088 client.cc:222] RAW: Coroner client retries enabled (b/136286901), will retry for up to 30 sec.
E0628 16:55:18.669852   14088 coredump_hook.cc:447] RAW: Sending fingerprint to remote end.
E0628 16:55:18.669864   14088 coredump_socket.cc:124] RAW: Stat failed errno=2 on socket /var/google/services/logmanagerd/remote_coredump.socket
E0628 16:55:18.669874   14088 coredump_hook.cc:451] RAW: Cannot send fingerprint to Coroner: [NOT_FOUND] Missing crash reporting socket. Is the listener running?
E0628 16:55:18.669881   14088 coredump_hook.cc:525] RAW: Discarding core.
E0628 16:55:18.673655   14088 process_state.cc:771] RAW: Raising signal 6 with default behavior
Aborted (core dumped)

정말 사람을 미치게 하는 에러였다.

아무리 검색해도, TPU 학습에 대한 정보는 매우 미미하고, 해결법 또한 정말 상상도 못한 방법이었기에,

최대한 많은 분들이 TPU 학습에 있어서 나와 같은 삽질을 하지 않기를 바라는 맘으로 글을 작성한다.

 

에러 발생 지점

 

# Transformer 기반 NLP 모델과 함께 사용시
xmp.spawn(map_fn, args=(flags,), nprocs=8, start_method='fork')

 

 

해결법

 

해결 방법을 아무리 검색해도 잘 나오지 않아서 포기에 가까운 상태였다가,

Transformer와 함께 사용할 때 해당 증상이 발생하는 점을 고려하여,

 

Transformer Github Issue를 뒤져본 결과,

나와 같은 현상을 호소하는 사람이 있었고, 놀라운 답변을 발견했다.

 

 

왜인지는 모르겠지만, tensorflow-cpu를 설치하면 에러가 놀랍게도 사라진다고 한다.

나는 코드가 완전히 pytorch 베이스였기 때문에 당연히 해당 사항으로 해결이 안될거라고 생각했지만,

 

이거 된다!

 

TPU-VM 자체가 내부적으로 Tensorflow를 사용해서 그런지, tensorflow-cpu를 설치하는 순간 에러가 사라졌다!

설령 Tensorflow를 사용하지 않는다고 하더라도 Core dump가 뜨면 무조건 pip install tensorflow-cpu를 시도해보자.

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

AttributeError: Can’t get attribute ‘new_block’ on 

module ‘pandas.core.internals.blocks’ 해결

 

 

에러 메시지


AttributeError: Can’t get attribute ‘new_block’ on <module ‘pandas.core.internals.blocks’

 

 

에러 발생 지점


# pandas.read_pickle에서 생기는 문제
train_df = pd.read_pickle('train_set.pickle')

 

 

해결법


pickle파일을 만든 컴퓨터의 pandas 버전과, 

read_pickle을 진행하고자하는 컴퓨터의 pandas 버전이 다를 때 발생하는 에러이다.

 

pickle 파일을 만든 컴퓨터의 pandas 버전을 다음과 같은 명령어로 알아낸 뒤,

$ pip list | grep pandas
#pandas                   1.3.3

 

같은 버전의 pandas로 맞춰주면 해결된다.

 

pip install pandas==1.3.3

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


[W ProcessGroupNCCL.cpp:1618] Rank 1 using best-guess GPU 1 to perform barrier as devices used by this process are currently unknown. This can potentially cause a hang if this rank to GPU mapping is incorrect.Specify device_ids in barrier() to force use of a particular device. 해결법

 

에러 메시지


[W ProcessGroupNCCL.cpp:1618] Rank 1 using best-guess GPU 1 to perform barrier as devices used by this process are currently unknown. 
This can potentially cause a hang if this rank to GPU mapping is incorrect.Specify device_ids in barrier() to force use of a particular device.

 

이후 코드 돌아가다가 갑자기 사망.

 

 

에러 발생 지점


$python -m torch.distributed.launch

 

pytorch의 torch.distributed.launch, 즉 multi-gpu 상황일 때 발생한다.

일반적으로 torch.distributed.launch를 하게 되면, 자동으로 프로세스에 process local rank가 할당되고, local rank에 따라 cuda:0, cuda:1 형식으로 디바이스를 할당하게 된다. 그리고 다른 프로세스가 동시 점유 하여 문제가 발생하지 않도록, barrier라는 개념이 있는데, 이 barrier가 정상적으로 작동하지 못하게 되면 문제가 발생한다.

 

다양한 원인이 존재한다.

  • NCCL, NVCC 버전 문제 / 드라이버 손상
  • 동일한 Local Rank를 가진 Zombie 프로세스가 백그라운드에 살아있어서 발생하는 문제
  • Pytorch 버전 문제(?)

 

해결법


  1. NCCL, NVCC 드라이버 문제

    NCCL과 CUDA와 cuDNN을 다시 설치해주면 문제가 해결될 수 있다.

  2. Zombie Process 문제

    $ps -ef | grep python

    위 명령어를 통해 Python이 사용되고 있는 프로세스를 찾고 종료시킨다.
    일반적으로, 그래픽카드를 사용하여 생기는 문제이므로, 간단하게

    $nvidia-smi

    위 명령어를 통해 process의 pid를 얻어내고 종료시켜도 좋다.

  3. Pytorch 버전 문제

    물론 정상적인 방법은 아니다. 위 방법을 모두 시도했을때도 실패했다면 시도를 해보는 것이 바람직하다.
    해당 이슈는 Pytorch가 1.9로 버전업되면서 분산학습에 torch elastic이 사용되는 경우가 있다. 여기서 문제가 발생하는 경우가 꽤 많은 것 같다.

    완벽한 대응은 아니었지만, 필자는 huggingface의 BERT를 Tesla V100 2대로 분산학습 시키는 과정에서 위 에러를 만났고, 끝까지 해결법을 찾지 못해 torch 버전을 아예 1.6버전으로 낮춰버리고 다시 학습을 돌렸더니 정상적으로 동작을 하는 모습을 확인할 수 있었다. 

    코드에 버전 호환이 가능하다면, Torch 버전을 내려서 해결할 수도 있을 것 같다.

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

리눅스 파일 split으로 쪼개기

 

리눅스를 사용하다보면, 로그파일이나 머신러닝에서 필요한 데이터셋등 거대한 파일을 주로 다루게 된다.

문제는 이렇게 너무 거대한 파일들은 정상적으로 Editor로 열어보기도 힘들 뿐더러, 

파일 입출력이라도 시도했다간, Memory 전체 크기보다 파일의 용량이 크기 때문에 프로그램이 죽어버리게 되는 불상사가 생긴다.

 

이러한 문제점을 해결하기 위해서, 리눅스는 split이라는 커맨드를 통해 거대한 파일을 다양한 방식으로 sharding 하는 기능을 제공한다. 이번 포스팅에서는 split과 사용 방법에 대해 다룬다.

 

 

 

파일 크기 기준으로 쪼개기


$split -b 크기(byte) 파일명

# Example
$split -b 1024 console_log # 1024 바이트 단위로 분할
$split -b 1k console_log # 1kb 단위로 분할
$split -b 1m console_log # 1mb 단위로 분할
$split -b 1024m console_log #1gb 단위로 분할

# g는 지원안함

 

파일을 원하는 용량 단위로 나눠주는 역할을 하게 된다. 다만 접두사 설정을 달지 않으면, xaa xab xac 이런식으로 굉장히 분할이 너저분하게 되므로  접두사 설정을 확인하자.

 

파일명 지정 (prefix 설정)


$split console_log [원하는 접두사]_

# Example
$split console_log log_

 

위와 같은 설정을 통해 보다 가독성 좋게 파일을 쪼갤 수 있다.

 

 

라인 수 기준으로 쪼개기


$split -l [원하는 라인수] [분할할 파일 이름]

# Example
$split -l 10000 console_log log_ #10000라인 단위로 자르기

# TIP
$wc -l console_log # 원본 파일의 총 라인수가 몇인지 알 수 있음

 

또한 라인수를 기준으로 자르는 것도 가능하다.

이는 머신러닝에서 NLP를 다룰 때 매우 유용하게 사용된다.

Corpus가 일반적으로 행 마다 sentence 하나를 저장하게끔 설계된 경우가 많기 때문에, 애용하는 옵션이다.

 

 

쪼갠 파일 합치기


$cat log_* > console_log_merged

 

split을 통해 나눠진 파일들은 다시 합치는 것 또한 가능하다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

Failed to initialize NumPy: module compiled against API version 0xe but this version of numpy is 0xd 해결법

 

에러 메시지


Failed to initialize NumPy: module compiled against API version 0xe but this version of numpy is 0xd

RuntimeError: Numpy is not available

 

에러 발생 지점


Numpy를 사용하는 시점에 Traceback 호출되며 종료,

Numpy 버전이 낮거나, 혹은 numpy가 오류로 인해 정상작동하지 않는 상황일 때 오류가 발생함

 

 

해결법


$pip install numpy --upgrade

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

GCP VM Instance에 Disk 용량 추가하기

 

Google Cloud Platform 사용하다보면, VM의 부트디스크 용량을 가격을 고려하여 최대한 작게 잡았다가,도커나 이것저것 프로그램을 설치하다보니, 최대 용량을 넘겨버리는 사태가 자주 발생하곤한다.

 

Disk가 꽉차게되면 기본적인 리눅스 터미널 명령어 자체도 호출이 안되기 때문에, GCP로 서비스를 운영하는 이들에게는 매우 주의해야 하는 상황이다.

 

용량이 부족해서 급하게 Disk를 추가하되, VM 인스턴스를 새로 만들기 어려울 때, GCP에서는 인스턴스를 다시 만들 필요 없이 Disk 용량을 빠르게 추가할 수 있다.

 

Disk 추가하기


 

 

  1. GCP 콘솔에서 Storage 항목의 Disks로 이동
  2. CREATE Disk 버튼 클릭
  3. 디스크 생성, 이 때 반드시 Disk의 지역을 VM의 지역과 맞춰주어야 속도가 빠르다.
  4. Disk의 용량은 언제든지 추가가 가능하지만, 한번 늘어난 용량은 줄일 수 없으므로 신중하게 사이즈를 설정

 

Disk VM에 연결하기


  1. VM Instances 리스트에 가서, Detail 정보 확인
  2. EDIT를 눌러 VM 인스턴스 수정으로 들어감

  3.  쭉 내려보면, Additional Disks 영역이 있는데, Attach Existing Disk 버튼을 클릭 한 후, 아까 만든 Disk를 Attach

 

 

Disk VM에서 마운트하기


  1. lsblk 명령어를 통해 추가된 disk의 위치를 확인
  2. 최초 추가 시, EXT4 포멧
  3. 디스크를 특정경로로 마운트
  4. 마운트 디렉터리에 권한 추가
  5. 정상 추가 여부 확인
$sudo lsblk
-------------------------------------------
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda       8:0    0   50G  0 disk 
├─sda1    8:1    0 49.9G  0 part /
├─sda14   8:14   0    3M  0 part 
└─sda15   8:15   0  124M  0 part /boot/efi
sdb       8:16   0    3T  0 disk 
-------------------------------------------
# sdb로 추가되었음을 확인

$sudo mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb
$sudo mount -o discard,defaults /dev/sdb path/to/mount(마운트하고싶은 경로)
$sudo chmod a+w (추가한경로)
$sudo df -h (마운팅 확인)

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

Linux에서 buffer/cache 비우기

 

 

linux에서 현재 메모리 상태를 보는 top 명령을 통해 메모리 상태를 보게 되면, buff/cache라는 값이 있다는 것을 확인할 수 있다. Used도 아니고 Available도 아닌 이 메모리는 무엇일까?

 

이 메모리는 실제로 사용되는게 아니라, 버퍼와 캐시에서 사용하는 메모리 할당량이다. 물론 일반적으로 캐시에 저장된 값은 자주 사용되기 때문에 OS에서 등록한 정보이고, 이로 인해 성능의 향상을 불러오지만, 딥러닝등 일반적이지 않은 대용량 데이터를 빈번히 Load 해야 하는 상황에서는 캐시에 저장된 값을 자꾸 바꿔주는데 들어가는 비용이 더 커지기 때문에, 학습 스크립트를 모두 돌린 후에, 새로운 학습 스크립트를 돌리기 위해서는 미리 비워주는 것이 오히려 더 좋다.

 

즉, cache의 hit ratio가 앞으로 극히 낮아질 것이라는 확신이 있다면, buffer/cache를 미리 비워줌으로써 새로운 데이터를 금방 할당받을 수 있도록 하는 것이 유리하다.

 

Page Cache 해제


sync
$echo 1 > /proc/sys/vm/drop_caches

 

첫줄의 sync는 플러싱을 해주는 역할로, 현재 사용하고 있는 메모리 데이터를 동기화해주는 역할을 한다.

삭제 전에 sync를 통해 불필요한 메모리 손실이 일어나지 않도록 한다.

 

 

Dentries, I-nodes 해제


sync
echo 2 > /proc/sys/vm/drop_caches

 

Page Cache, Dentries, I-nodes 모두 해제


sync
echo 3 > /proc/sys/vm/drop_caches

 

위와 같은 방식을 통해, 버퍼/캐시 메모리를 모두 비워주고 나면, Free Memory의 값이 커지고, Buff/Cache 값이 줄어들게 된다.

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형

어제 평소와 같이 열심히 카카오 잔여백신을 확인 하던 중,

당연히 안될 줄 알았는데 뜬금없이 백신 예약에 성공해서 급하게 백신을 맞고 왔습니다.

 

예약 방법 꿀팁과 부작용 여부, 

증상은 어땠는지 후기 남겨보겠습니다.

 

 

예약 방법


먼저 기본적으로, 카카오톡 알림, 네이버 알림등은 서버를 통해 어느정도 딜레이가 발생 한 후 푸시 알림이 도착하므로, 알림을 받아서 예약하는건 사실상 불가능합니다.

 

빨리빨리의 민족 한국답게 1초만에 이미 예약이 완료되는 경우가 많기 때문에, 

자주 잔여백신이 나오는 병원을 미리 잘 파악하고 있다가, 해당 병원들에 대해서 무한 업데이트를 진행하는 방식이 가장 빠르게 예약 페이지로 넘어갈 수 있는 방법인 것 같습니다. 다만 손가락이 아플정도로 업데이트해야하고, 계속 들여다봐야 한다는 단점이 있습니다. 그렇게 하다보니 성공적으로 예약이 성공했습니다.

 

 

 

접종 방법


3시쯤 예약이 잡혔는데, 4시까지 운영한다는 내용이 와있어서,

급하게 허겁지겁 출발했습니다.

 

제가 예약한 곳은 그렇게 큰 병원은 아니었어서 대기가 길지도 않았고,

"잔여백신 맞으러 왔어요!"하면서 가면 접종 전 문답지를 주시고,

문답지만 작성하면 바로 진료실에 들어가 접종받는 방식이었습니다.

 

문답지 작성 후에 접종받는 건 사실상 1분도 안걸렸고,

이상반응이 있는지 없는지 15분간 병원에서 대기 후 귀가하도록 안내받았습니다.

생각보다 너무 빨리빨리 진행되서 당황스러울 정도였습니다 ㅋㅋ

직장인분들도 살짝 나가서 접종받을 수도 있지 않을까 싶을 정도로 빠르게 진행됩니다.

 

2차접종에 대해서 다들 궁금하실텐데,

잔여백신은 1차 예약하는 순간 자동으로 2차접종 예약까지 진행된다고 합니다.

실제로 접종 후 5분정도 지나니까 2차 접종 안내 국민비서 문자가 왔습니다.

 

 

유의 사항


의사 선생님께서, 20대 초반 남자분들이 심근염등 부작용이 생길 수 있다고 말씀하셨는데,

사실 100만명중에 3~4명 꼴로 일어나는 희귀한 상황이니 걱정할 필요는 없다고 하셨습니다.

다만 유의사항을 몇가지 말씀해주셨는데 다음과 같습니다.

 

  • 밤까지 늦게 스마트폰/컴퓨터 하지 않고 무조건 일찍 잠자리에 들고, 충분한 시간 수면 취할 것
    -> 수면이 부족할 경우 몸안에서 염증 반응이 급격히 증가하고, 부작용 가능성이 높아질 수 있다.
  • 가능한 일주일 동안은 격렬한 운동 하지 않을 것
    -> 무산소성 근력운동 또한 몸에 염증 수치를 높이므로, 기본적으로 염증과 관련된 모든 신체 활동은 자제하는 것이 좋다.
  • 2~3일간은 무기력증을 동반한 근육통이 있을 수 있다. 정상적인 현상이니 너무 심하면 타이레놀을 먹고, 물을 많이 마셔주는 것이 도움이 된다.
    -> 타이레놀은 사실 필수는 아니고, 물을 충분히 많이 마셔주는 것도 통증 완화에 도움이 된다고 한다.
  • 첫날은 목욕 자제, 둘째날에도 접종 부위에 직접 물 닿는건 피할 것
    -> 감염? 때문이 아닐까 싶습니다.

 

접종 후기


처음 접종 할 때는, 그냥 일반적인 주사랑 별반 다를 바가 없습니다.

딱히 더 아프거나 덜 아프거나 하지 않고, 살짝 따끔하고 끝납니다.

 

그 후에도 별다른 느낌은 없으나, 2~3시간 쯤 지나면 슬슬 접종 부위 주변으로 근육이 뭉치는 느낌이 들고, 

손끝이 살짝 저립니다.

 

백신 먹고 삼겹살 먹으면 덜 아프다는 민간 요법이 있는데, 당연히 비과학적이고 아무 효과도 없을 거라는 걸 알지만 괜히 갑자기 고기 땡겨서 목살을 구워먹었습니다 ㅋㅋㅋ

 

접종 후 4~5시간 쯤 지나면 근육통이 좀 더 생기는데, 걱정하실 정도는 아니고 남자분들이라면 헬스장에서 팔 운동 했을 때, 근육통 온 느낌입니다. 아무래도 지인들의 사례를 봤을 때는 근육통에 익숙하지 않은 여성분들이 더 고통을 많이 호소하는 듯 한 느낌입니다.

 

7시간 쯤 지나면, 팔에서 어깨쪽까지 근육통 범위가 점점 늘어납니다.

많이 아픈 수준은 아니고, 이것도 마찬가지로 어깨 운동 한 다음날 근육 뻐근한 느낌과 가장 흡사합니다.

그리고 이 때부터는 37도가 넘어가면서 미열이 발생합니다. 

 

그냥 자도 되겠지만, 열이 높아지면 두통 증상이 생긴다고 들어서 그냥 저는 타이레놀을 먹고 잤습니다.

 

그리고 오늘, 하루가 지난 상태인데,

약간의 어지러움은 있지만 딱히 부작용은 없고, 팔은 어제랑 비슷한 강도로 뻐근합니다.

일상 생활에는 딱히 지장이 없습니다!

 

2차 접종은 3주후인데 화이자는 2차 접종이 보통 부작용 빈도가 높다고 하니,

2차 접종 후기로 찾아뵙겠습니다!!

 

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,
반응형


 

자체 데이터로 Bert Training 하기

 

이전 글에서는, Corpus 전처리 하는 방법

2021.07.26 - [Machine Learning/BERT 학습] - [Python / NLTK] 텍스트 파일 문장 단위로 분해하기 (Sentence Tokenize)

 

[Python / NLTK] 텍스트 파일 문장 단위로 분해하기 (Sentence Tokenize)

 NLTK 사용하여 .txt파일 문장 단위로 쪼개기 딥러닝 모델들이 사용하는 Corpus 파일들은 대부분 Sentence 단위로 학습을 진행하고, 이를 위해서라도 Sentence 단위별로 나눠주는 것이 편리하다. NLTK를

cryptosalamander.tistory.com

 

자체 데이터로 BertTokenizer 학습하는 방법

2021.07.25 - [Machine Learning/BERT 학습] - [Pytorch / Huggingface] Custom Dataset으로 BertTokenizer 학습하기

 

[Pytorch / Huggingface] Custom Dataset으로 BertTokenizer 학습하기

자체 데이터셋으로 BertTokenizer 학습하기 이번 게시글에서는 Pretrained Weight를 이용하지 않고, 특정 Domain에 맞도록 직접 Custom Dataset을 통해 BertTokenizer를 학습시키는 방법을 다룬다. 현재 진행하고..

cryptosalamander.tistory.com

 

두가지 내용을 다뤘다. 이제 Sentence 단위로 나눠진 Corpus 파일과, 직접 구현한 BertTokenizer를 통해 BERT를 GPU를 사용하여 학습해보자.

 

Requirements


$git clone https://github.com/huggingface/transformers.git
$cd transformers
$pip install -e .

 

Bert를 학습시키는 코드까지 포함하여 huggingface의 transformer 깃허브 레포지토리를 통째로 다운 받은 후, pip install 을 통해 transformers를 설치시켜준다. 

 

 

Training


transformers 레포지토리 내부에 examples/pytorch/language-modeling/run_mlm.py 통해서 학습을 진행할 수 있다.

하지만 그전에 먼저 체크해야할 것이 있다.

해당 파일의 check_min_version에 dev가 붙어있다면, master branch가 아니라 가장 최근 release 된 Tag를 찾아 다시 다운받아야한다. 

<포스팅 당시의 가장 최근 Release Tag 버전>

 

<master branch로 받았을 때 모습>

마스터 브랜치로 다운받았는데, dev0가 붙어있다면 개발자들이 내부적으로 테스팅을 진행하고 있는 단계로, 정상적으로 동작이 되질 않는다. 이를 방지하기 위해서라도 tag를 확인하도록 하자.

 

그 후, 코드는 바꿀 필요 없이 인자값만 전달하여 학습을 진행하면 된다.

 

 

주요 인자에 대해 설명은 다음과 같다.

--model_name_or_path : 기존 모델의 weight를 불러온 뒤, 전이학습을 할 때 사용된다.

https://huggingface.co/transformers/pretrained_models.html

 

Pretrained models

Here is a partial list of some of the available pretrained models together with a short presentation of each model. For the full list, refer to https://huggi...

huggingface.co

위 링크에 기술된 식별자를 통해서 모델을 불러올 수 있다. 

--model_type : pretrained weight 없이 구조만 가져와서 처음부터 학습을 진행할 시 사용된다. 본 포스팅에서는 bert를 학습하므로, bert를 입력하면 된다.

 

--tokenizer_name: pretrained tokenizer를 불러오거나, tokenizer가 저장된 폴더의 경로를 전달하여 tokenizer를 불러온다. 기본적으로, tokenizer_config.json, vocab.txt, special_tokens_map.json을 불러오며, 이는 이전 포스팅에서 학습한 tokenizer를 저장한 경로에 존재한다.

 

--max_seq_length : input으로 사용될 문장의 길이 한도를 의미한다. bert-based 모델은 512를 사용하므로 512를 입력

 

--train_file : 학습에 사용될 Corpus 데이터를 전달하면 된다.

 

--validation_file : validation 과정에 사용될 Corpus 데이터 경로를 전달하면 된다.

 

--validation_split_percentage : 별도의 validation_file이 없을 경우, train set에서 몇퍼센트를 추출하여 validation_set으로 활용한다. 10정도 입력하면 적절하다.

 

--cache_dir : 전처리된 임시 파일, 로그, checkpoint등이 저장될 경로, 입력하지 않으면 기본값인 nltk_data cache로 가지만, 지정해주면 해당 경로에 저장된다. 생각보다 용량이 커질 수 있으므로 용량이 넉넉한 파티션에 지정하는 것이 좋다.

 

--preprocessing_num_workers : 전처리에 사용할 프로세스의 개수이다. CPU Core수에 맞게 적절히 세팅해주면 좋다. 
기본값으로 돌릴 시 47시간 걸리던 전처리가, num_workers를 16으로 해줬더니 10시간으로 줄어들었다. 하지만 너무 클 경우 CPU와 메모리에 부하가 크므로, CPU 사양을 고려하여 설정해야한다.

 

--line_by_line : 문장이 라인 단위로 쪼개져있는 Corpus에서 사용한다. 기본적으로 False 상태로 되어있다. 기본적으로 huggingface에서는 line_by_line이 꺼져있으면, 문장들을 합친 뒤 512를 넘기지 않도록 적절히 chunks를 만들고 이를 이용해 학습을 진행한다. line_by_line은 왠만하면 키지 않는 것이 좋다. 오용될 경우, Corpus에 불필요한 [PAD]가 매우 많이 발생하기 때문이다.

 

--pad_to_max_length : 512보다 짧은 문장에 padding을 추가하여 512로 만들어준다. 기본적으로 켜주는게 좋지만, 잘못된 방식으로 line_by_line과 함께 사용될 경우, 전체 데이터 단어 1개에 [PAD] 토큰 99개가 붙는 최악의 상황이 발생할 수 있다. 

 

--per_device_train_batch_size : 말 그대로 train batch size

 

--per_device_eval_batch_size : eval batch size

 

--save_steps : 몇 step 마다 저장할 것인지, 기본값은 5000이지만, Corpus가 크다면 넉넉히 설정하는게 좋다. 너무 자주 저장되면 checkpoints 용량도 어마어마하게 크기 때문이다.

 

 

Example 


$python ./examples/pytorch/language-modeling/run_mlm.py \
  --max_seq_length 512 \
  --pad_to_max_length \
  --logging_dir ./tensorboard-metrics \
  --cache_dir /mnt/disks/sdc/cache_dir \
  --train_file ./train.txt \
  --tokenizer_name ./mytokenizer/ \
  --preprocessing_num_workers 8 \
  --do_train \
  --do_eval \
  --model_type bert \
  --validation_split_percentage 10 \
  --overwrite_output_dir \
  --output_dir my-bert \
  --num_train_epochs 3 \
  --per_device_train_batch_size 8 \
  --per_device_eval_batch_size 8 \
  --save_steps 500000

 

위와 같은 방식으로 학습을 진행할 수 있다. 

--tokenizer_name에는 기존 pretrained tokenizer들을 쓸 수도 있지만, 자체 데이터에 가장 잘맞는 tokenizer를 학습한 뒤, 이를 불러와서 사용하는 것이 가장 좋으므로, 이전 포스팅에서 저장한 tokenizer를 불러오도록 하자.

 

Corpus 크기가 크다면, 학습과 전처리에 상당히 많은 시간이 소요되므로 유의하자.

 

반응형
블로그 이미지

Hyunsoo Luke HA

석사를 마치고 현재는 Upstage에서 전문연구요원으로 활동중인 AI 개발자의 삽질 일지입니다! 이해한 내용을 정리하는 용도로 만들었으니, 틀린 내용이 있으면 자유롭게 의견 남겨주세요!

,