준비 사항
- NVIDIA Driver 545 버전 이상이 설치된 두 개의 우분투 서버
- Docker + NVIDIA Container Toolkit
- 두 서버가 통신 가능한 인터페이스 이름이 같아야함 (다르다면 pdsh 사용이 불가능하고 standard 방식으로 각 노드에서 NCCL_SOCKET_IFNAME를 설정 후 학습 명령어를 입력해야함)
사전 학습된 모델 다운로드
- (학습에 사용하려는 두 서버 모두)
- 허깅 페이스에 업로드 된 텍스트 생성 모델 중 Meta-Llama-3-8B를 사용 할 예정
- 허깅 페이스 엑세스 토큰 생성 및 사용하려는 모델에 엑세스 권한 요청이 필요함
- ~/volume/pretrained-models/ 디렉터리를 만든 후 디렉터리 내부에서 모델을 깃 클론
- 모든 safetensors가 잘 다운로드 되었는지 확인
도커 이미지 풀
- (학습에 사용하려는 두 서버 모두)
- 이미지는 nvcr.io/nvidia/pytorch:24.05-py3 기반으로 빌드했으며 크기가 크기 때문에 풀 받는 데 시간이 좀 걸림
docker pull asdfry/train-llm:tistory
컨테이너 생성
- (학습에 사용하려는 두 서버 모두)
docker run -itd --network host --gpus all --name my-container --shm-size=1g -v ~/volume:/root/mnt asdfry/train-llm:tistory /bin/bash -c "/usr/sbin/sshd -p 1041 && sleep infinity"
컨테이너 진입 및 GPU 확인
- (학습에 사용하려는 두 서버 모두)
- 컨테이너 진입
docker exec -it my-container /bin/bash
- GPU 확인 (파이썬 스크립트 결과 값이 False가 나온다면 NVIDIA Driver 버전 미스 매치일 확률이 높음)
python -c "import torch; print(torch.cuda.is_available())"
SSH 설정 파일 생성
- (학습에 사용하려는 두 서버 중 하나)
- 자기 자신과 나머지 한 서버에 SSH 접속이 가능하도록 아래 내용을 ~/.ssh/config에 생성
Host trainer-1
HostName 192.168.1.4 # 본인의 환경에 맞게 수정이 필요함
Port 1041
User root
IdentityFile /root/.ssh/key.pem
StrictHostKeyChecking no
Host trainer-2
HostName 192.168.1.5 # 본인의 환경에 맞게 수정이 필요함
Port 1041
User root
IdentityFile /root/.ssh/key.pem
StrictHostKeyChecking no
- 생성 후 SSH 접속이 정상적으로 동작하는지 확인
ssh trainer-1
ssh trainer-2
Hostfile 생성
- (학습에 사용하려는 두 서버 중 하나)
- 이 파일은 학습에 참여하는 서버의 호스트 이름과 GPU 개수를 적어놓은 설정 파일이며 딥스피드에서 사용함
- 아래 내용을 참고하여 ~/hostfile에 생성 (본인은 8개의 GPU를 장착한 두 서버를 사용하기 때문에 아래처럼 작성함)
trainer-1 slots=8
trainer-2 slots=8
Accelerate 설정 파일 생성
- (학습에 사용하려는 두 서버 중 하나)
- accelerate config를 입력하면 상호작용을 통해 accelerate 설정 파일을 생성 할 수 있음
- 아래처럼 생성한다면 ZeRO-3 Offload를 사용하여 멀티 노드 학습을 하게 됨
compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:
deepspeed_hostfile: /root/hostfile
deepspeed_multinode_launcher: pdsh
gradient_accumulation_steps: 1
offload_optimizer_device: none
offload_param_device: none
zero3_init_flag: true
zero3_save_16bit_model: true
zero_stage: 3
distributed_type: DEEPSPEED
downcast_bf16: 'no'
enable_cpu_affinity: false
machine_rank: 0
main_process_ip: 192.168.1.4
main_process_port: 1040
main_training_function: main
mixed_precision: bf16
num_machines: 2
num_processes: 16
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
에러 해결
- (학습에 사용하려는 두 서버 중 하나)
- pdsh 사용 시 아래 에러가 발생함
root@pnode4:~# pdsh
pdsh@pnode4: module path "/usr/lib/x86_64-linux-gnu/pdsh" insecure.
pdsh@pnode4: "/usr/lib": Owner not root, current uid, or pdsh executable owner
pdsh@pnode4: Couldn't load any pdsh modules
- /usr/lib의 소유권 수정
chown root:root /usr/lib
학습 준비
- 학습 로그와 GPU 모니터링을 동시에 볼 수 있도록 터미널을 아래처럼 배치 (상단: 1번 서버, 좌하단: 1번 서버, 우하단: 2번 서버)
- 도커 이미지 안에 nvitop이라는 GPU 모니터링 툴을 설치해놓았으며 컨테이너 접속 후 n을 입력하면 실행하도록 alias를 추가해놓음
- HPC-X 로드 후 환경변수 확인
source $HPCX_HOME/hpcx-init.sh && hpcx_load && env | grep HPCX
학습 시작
- (학습에 사용하려는 두 서버 중 하나)
- NCCL_SOCKET_IFNAME은 두 서버가 통신 가능한 네트워크 인터페이스이며 본인의 환경에 맞게 수정이 필요함
- 기본적으로 NCCL_SOCKET_IFNAME는 ib로 시작하는 인터페이스를 우선적으로 선택함 (참고)
- 인피니밴드 사용 시 통신에 사용할 HCA를 선택할 수 있음 (참고)
NCCL_SOCKET_IFNAME=bond0 accelerate launch train.py -b 32 -m Meta-Llama-3-8B -n tistory
결과 확인
- nccl 로그는 ~/mnt/output에 생성되며 NCCL_DEBUG_FILE과 NCCL_TOPO_DUMP_FILE로 경로 수정 가능
- torch 로그 및 모델 체크포인트는 ~/mnt/output/Meta-Llama-3-8B/np16/bs32/tistory에 생성됨
'딥러닝' 카테고리의 다른 글
[딥러닝] pytorch를 사용하여 GPU로 모델 학습 시 런타임 에러 (0) | 2023.06.21 |
---|