GPU H100 X8 가 깔려있는 remote server에 들어가 llama 3.3, deepseek r1 모델 vllm으로 서빙하기 대작전 (cuda out of memory, nccl error)

gunny·2025년 2월 19일

서론

AI engineer가 알아야할 기본 개발 소양이란 무엇일까..
ai 관련 알고리즘도 이해하기 벅찬데
처음 쪼렙데 jupyter notebook으로만 깔짝거리다가
실 서비스에서 py 파일로 이것저것 해야 해서 처음으로 PyCharm 을 처음 써보면서 버벅거렸던 시절을 지나서..
(아직도 잘 쓰진 못함)
이제 여기서 좀 더 편한 vs code를 사용하고 있다.

vs code를 이용해서 옆 팀원은 무슨 debugger도 기가막히게 써가면서
오류 난 곳을 딱딱 집는데.. 나는 그냥 영어 오류 호로록 보면서
유추해가면서 하고 있다..
(python 디버거 잘 쓰는 법도 곧.. 곧... 공부할 거임)

아무튼 AI engineer 로서 모델만 잘 끌어다가 쓰면 된다? ㄴㄴ
모델 학습만 잘하면 된다 ? ㄴㄴ
대 LLM의 시대에 학습은 커녕 파인튜닝도 어려운 이 시점에
LLM 모델을 실제 서비스에 잘 녹이고 서빙하고 스트럭처를 잘 짜는 것도
AI engineer의 기본 소양인 것이다.

말이 길었지만.. 일단 나는 팀원들이 L40S에 잘 설치해놓은 온 프레미스용 모델 llama3.1 불러와서만 쓰고 있었는데..
왠지 나도 별건 아니지만 해봐야할 것 같은 생각이 들었다.

본론

이번에 H100 x8 짜리 컨테이너에 원격으로 들어가서 해당 gpu를 사용할 수 있게 돼서, 좀 더 높은 사양의 llama를 서빙해서 테스트해야 할 테스크가 생겼다.
이번에는 내가 좀 해봐야 할 것 같아서 삽질이 시작됐다.

솔직히 다 해놓고 나니까 이게 무슨 어려운 일도 아니였지만
역시 처음은 다 힘들어 (??)

시행착오 1. ssh 로 접속하기

애석하게도 터미널에서 ssh 키로 접속할 기회가 적었던 나
ssh 로그인 할 때마다 메모장에서 복사 붙여 넣기 하니까
늘리가 있나. (지금은 ssh id@ip -p port) 잘 아니까 괜찮죠..?

id 가 test
ip가 192.168.1.1
port 8000
password test

인 경우

ssh test@192.168.1.1 -p 8000

으로 들어가서 password를 치면된다.

시행착오 2. cuda out of memory

로그인을 잘하고 huggingface 에서 vlllm을 serving 하는데 자꾸 에러가 났다. 그놈의 cuda out of memory

아니 H100 8개가 있는데 llama3.3 70B이 안올라갈 이유가 없다.
llama3.3 70B 찾아보니까 최소 24GB 이상의 VRAM을 갖춘 GPU가 필요하며, 더 원활한 실행을 위해서는 40GB 이상의 VRAM을 권장합니다.
로 되어있다.

NVIDIA H100 Tensor Core GPU 사양:
GPU 아키텍처: Hopper 아키텍처
CUDA 코어: 약 14,592개
Tensor 코어: 3세대 Tensor 코어
메모리: 80GB HBM3
메모리 대역폭: 2,000GB/s
FP64 성능: 60 TFLOPS
FP32 성능: 120 TFLOPS
FP16 성능: 240 TFLOPS
INT8 성능: 480 TOPS
TDP: 700W

이게 8대가 있는데..

해결방안

그래서 찾아보니까 병렬로 돌리면 된다고 한다.
아니 이미 그건 팀원한테 들어서 병렬로 돌리는 명령어 쓰고 있었는데
python 실행해서 보니까 gpu를 자꾸 1개로 잡고 있었다.

export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True

그래서 환경 설정 다시 해줬다.

그리고 처음에는 8대를 다 켜서 돌려봤는데 또 에러가 나는 것이다!!!!

시행착오 3. nccl error

아니 이것저것 해도 안돼서 이상하다 생각할 찰나
gpt와 심도 있는 대화 끝에 /dev/shm 의 이슈를 찾아냈다.

해결방안

df -h /dev/shm

/dev/shm 디렉토리의 디스크 사용량을 확인하는 명령어이다.
여기서 df는 "disk free"의 약자로,
디스크 공간 사용 상태를 보여주는 명령어입니다. -h 옵션은 사람이 읽기 쉬운 형식으로 출력해준다(예: KB, MB, GB 단위로 출력)

해당 디렉토리가 *"shared memory"**를 위한 디렉토리이고, 이 디렉토리는 메모리 기반 파일 시스템(tmpfs)을 사용하여 RAM에 저장되는 임시 파일을 저장하는 장소라고 한다.
근데 그게 size가 1.0G에 use가 100%임..

이게 문제일 수도 있을 거 같아서 서치했는데

적어도 200GB 이상은 있어야 한다고 해서 요청해서 늘렸다.

시행착오 4. remote ssh key error (host key verification failed)

여기서 처음에는 잘 들어가졌는데,
설치되어 있는 컨테이너의 설정 변경을 요청하면서
한번 컨테이너가 다시 올라간 적이 있었는데,
같은 id, ip, port, password를 쳐도 로그인이 안되는 것이다.

Host key verification failed.

약간 이런 종류의 에러가 났다.
그래서 처음에는 컨테이너를 다시 설정하시면서
ip랑 port 바뀌었나.. 했는데
아니였다.

해결 방법
클라이언트의 ~/.ssh/known_hosts 파일에서 해당 서버의 항목을 제거:

ssh-keygen -R hostname

다시 접속하여 새로운 호스트 키를 받아들이도록 해야 한다.

아무튼.. 이러한 난관을 거쳐서 서빙의 시작..
시행착오를 4개를 거쳐야 vllm 으로 서빙이 가능하다.

아무튼 vllm 을 깔고 hugging face에서 모델에 대한 인증을 요청하고 깔았고, 텐서 병렬화로 2,4,6 조절해가면서 GPU에 분배 가능한 최소 개수를 파악했다. LLama3.3은 H100 기준 4개였삼

vllm serve meta-llama/Llama-3.3-70B-Instruct --tensor-parallel-size 4 

시행착오 5

서빙하고 박수 짝짝 쳤는데, 그것도 잠시
이건 내부 컨테이너를 들어가서 열어 논 것이라서
외부에서 켜놓은 모델이 접근할 수 있도록 해야 했는데..
처음에 L40S 모델에 접근하게 했던 사람들이 외부 port를 받으라고 해서 외부 port 주세요 했는데.. 이게 멍청한 질문이었다.

내가 내부 포트를 몇번을 킬껀지 말해야.
그 포트에 해당하는 외부 포트를 알려주는 것이었다! 매친!!!

그리고 그 내부 포트는 내가 모델을 킬때 옵션으로 지정한다.
예를 들어 내가 vllm으로 해당모델을 port 8080(예시)으로 키고 싶다면

vllm serve meta-llama/Llama-3.3-70B-Instruct --tensor-parallel-size 4 --port 8080

이렇게 켜줘야 한다.

vllm serve meta-llama/Llama-3.3-70B-Instruct --tensor-parallel-size 4 --port 8080

그래서 내부 포트를 요청드려서 외부에 접근 할 수 있는
ip와 port를 받았다.

시행착오 6 VLLMChatOpenAI 클래스로 model serving connect error

여기서 끝난 것이 아니다 ^^
이제 만들어져있는 서비스에서 희망하는 model을 테스트하기 위해서
만들어져 있는 api에 맞춰서 넣었는데 api에서 VLLMChatOpenAI 클래스를 사용해서 Llama-3.3-70B-Instruct 모델을 기반으로 LLAMA3_3라는 객체를 생성한다.

LLAMA3_3 = VLLMChatOpenAI(
        model="meta-llama/Llama-3.3-70B-Instruct",
        metadata={
            "context_length": 128000,
            "model_code": "LLAMA3_3",
            "input_price": Decimal("0"),
            "output_price": Decimal("0"),
            "vision_capability": False,
        },
        vllm_api_base=f"{settings.on_premise_model_server.unicode_string()}",
        openai_api_key=settings.on_premise_model_api_key.get_secret_value(),
        stream_usage=True,
    )

근데 여기서 openai_api_key ?! 처음에는 hugging face key 인줄 알았는데 다른 모델과 매핑되어 있는 key를 봤는데 되게 단순한거다..

일단 내가 아는 api_key는 huggingface key라서 그거 넣고 했는데
conenction error 가 났다.

알고보니 내가 vllm을 띄울 때 또 옵션에 주는 key 이름이란다.
env 파일에 키를 test라고 넣어줬다면

vllm serve meta-llama/Llama-3.3-70B-Instruct --tensor-parallel-size 4 --port 8080 --api-key test 

로 키면된다.

그리고?

시행착오 7

그러면 연결되다가 enable-auto-tool-choice,
--tool-call-parser 넣으라는 에러가 또 발생하는데

해결방안
--enable-auto-tool-choice --tool-call-parser llama3_json
을 넣어주면 된다.. 뒤에 llama3_jon은 내가 llama3 모델을 쓰므로

vllm serve meta-llama/Llama-3.3-70B-Instruct --tensor-parallel-size 4 --port 8080 --api-key test --enable-auto-tool-choice --tool-call-parser llama3_json

의 느낌으로 띄워주면.. 외부에서 접근 가능한 vllm으로 llama3.3 모델 서빙 완..

추가

이와 같이 deepseek-r1 모델도 띄워봤다.
deepseek-r1 모델은 워낙 크니까 절대 안되고, 이와 같이DeepSeek-R1-Distill-Llama-70B 도 4개 까지로 띄울 수 있는데,
두개 동시에 띄워보려고 했는데 port 하나로는 모델 두개를 못 띄우더라..
그래서 포트를 다르게 해서 DeepSeek-R1-Distill-Llama-70B를 띄웠는데 4개,4개라 얼추 될 거라 생각했는데 동시에 8개 쓰면서 모델 2개는 쿠다 메모리 부족 에러가 났다.

그래서 테스트 하고 싶으면 모델 하나 띄웠다 내렸다 해야함
뭐 별수 있나

아무튼 우여곡절 완

profile
꿈꾸는 것도 개발처럼 깊게

0개의 댓글