본문으로 건너뛰기
페이지 목차
이 페이지에서 검색

로컬 LLM

이 페이지에 묻기

로컬 LLM · 현재 차시와 목차 본문에서만 찾아 답합니다. 답을 지어내지 않고 해당하는 대목을 그대로 보여 주며, 여기에 없으면 없다고 알려 드립니다.

생성형 AI가 아니라 이 페이지 본문을 찾아 그대로 보여 주는 방식입니다. 외부로 나가는 요청이 없습니다.

LOCAL · LLM

로컬 LLM

생성 수정

로컬 모델 실행과 GPU·메모리 이해부터 서빙·RAG·도구 호출·업무형 앱 구현까지 차례로 살펴봅니다.

42개 문서 · 1일차 · 4 / 42

3차시 · 로컬 LLM 개발환경 구축

지도 위치 : 1일차 · ①하드웨어 층과 그 위의 소프트웨어 사슬 | 이전: 2차시 LLM 구조와 추론 원리 | 다음: 4차시 Hugging Face 오픈소스 LLM 활용 키워드 : Python, PyTorch, CUDA 환경 확인, GPU VRAM 확인, LLM 실행을 위한 하드웨어 환경 구성

이 차시를 다 읽으면

  1. GPU에서 모델이 돌기까지의 다섯 고리 사슬 (GPU → 드라이버 → CUDA → PyTorch → 라이브러리)을 순서대로 말할 수 있다.
  2. nvidia-smi 화면에서 Driver Version · CUDA Version · Memory-Usage · GPU-Util · Processes 를 읽고, "CUDA Version"이 무엇을 뜻하는지 바로 말할 수 있다.
  3. torch.cuda.is_available()가 False일 때 어느 고리부터 볼지 말할 수 있다.
  4. LLM용 하드웨어의 우선순위(VRAM > 메모리 대역폭 > RAM > 디스크 > CPU) 를 이유와 함께 말할 수 있다.
  5. 왜 엔진마다 가상환경을 따로 만드는지, 왜 Ollama는 PyTorch 없이 GPU를 쓰는지 설명할 수 있다.

0. 이 차시의 판별 축

#축왼쪽 (0)오른쪽 (1)이 축으로 갈리는 것큰 축 (README 5장)
1어디까지 적용되는가전역 (시스템 전체)격리 (이 프로젝트만)드라이버 ↔ 가상환경 안의 PyTorch⑤ 하나 ↔ 여럿의 파생 (환경 분리)
2어디에 있는가디스크 · RAMVRAM모델 파일 ↔ GPU에 올라간 가중치① 디스크 ↔ 메모리
3일꾼이 몇인가순차 (CPU)병렬 (GPU)왜 LLM에 GPU가 필요한가순차 ↔ 병렬 (파생 축)

이 차시의 질문은 "내 컴퓨터의 GPU로 모델을 돌릴 준비가 되었는가, 안 되었다면 어디가 끊겼는가" 입니다. 파이썬 · PyTorch · CUDA · 드라이버는 따로따로 설치하는 부품이 아니라 서로 맞물려야 하는 조합 입니다. 그래서 이 차시는 그 조합을 1절의 사슬 그림 으로 세우고, torch.cuda.is_available()가 False일 때 왜 nvidia-smi부터 보는지 를 그 그림으로 설명합니다. 그리고 2절에서 LLM에서 특히 중요한 VRAM 숫자 읽기 를 익힙니다.


1. GPU에서 모델이 돌기까지 — 다섯 고리 사슬 ⭐

1.1 사슬 그림

 ⑤ 라이브러리      transformers · accelerate · bitsandbytes · vllm   ┐
        │ 위에 얹힘                                                   │ 가상환경 안
 ④ PyTorch         텐서 계산 + GPU 할당. 빌드마다 CUDA 버전이 정해져 있음  ┘ (격리)
        │ 호출
 ③ CUDA 런타임     GPU에 계산을 시키는 NVIDIA의 플랫폼                  ← 대개 PyTorch 휠에 같이 들어 있음
        │ 호출
 ② NVIDIA 드라이버  OS가 GPU와 말하는 통로                              ┐ 시스템 전체
        │                                                            │ (전역)
 ① GPU             VRAM · 연산 코어                                   ┘

한 고리라도 끊기면 위쪽 전부가 CPU로 떨어지거나 에러가 납니다. 그래서 점검은 아래에서 위로 합니다.

고리정의 (유 + 종차)확인 명령적용 범위
② 드라이버[시스템 소프트웨어]인데, [ OS가 GPU 하드웨어를 부릴 수 있게 하는 통로 ]라는 점에서 응용 라이브러리와 구별된다nvidia-smi전역
③ CUDA[병렬 컴퓨팅 플랫폼]인데, [ NVIDIA GPU에 그래픽이 아닌 범용 계산(행렬 곱 등)을 시킨다 ]는 점에서 화면을 그리는 그래픽 API와 구별된다torch.version.cudaPyTorch에 묶여 들어옴
④ PyTorch[딥러닝 프레임워크]인데, [ 텐서(숫자를 여러 차원으로 늘어놓은 배열) 연산과 GPU 메모리 할당을 맡는다 ]는 점에서 그 위에 얹히는 모델 라이브러리와 구별된다torch.cuda.is_available()격리 (가상환경)
⑤ 라이브러리[Python 패키지]인데, [ PyTorch 위에서 모델 로딩 · 양자화 · 서빙을 한다 ]는 점에서 프레임워크 자체와 구별된다pip list격리

1.2 ⚠️ "CUDA를 따로 설치해야 하나요?"

대부분의 경우 아닙니다. pip로 받는 GPU용 PyTorch에는 필요한 CUDA 런타임이 같이 들어 있습니다. 시스템에 필요한 것은 충분히 새 드라이버 뿐입니다.

필요한 것Transformers로 실행 (4차시)Ollama로 실행 (5차시)
NVIDIA 드라이버⭕ 필요⭕ 필요
CUDA Toolkit (컴파일러 포함 전체)대개 불필요불필요
PyTorch⭕ 필요 (CUDA 포함 빌드)❌ 불필요

⭐ Ollama는 PyTorch 없이 GPU를 씁니다. Ollama는 llama.cpp 계열의 자체 엔진과 GPU 라이브러리를 함께 들고 오기 때문에 ②드라이버만 있으면 됩니다. 그래서 "PyTorch 설치가 꼬였는데 Ollama는 잘 돈다"는 정상입니다. 같은 GPU 위에 서로 다른 사슬 두 개 가 있는 것입니다.

앞으로 다시 만납니다 — 18차시 vLLM은 특정 PyTorch 버전을 고정해서 설치합니다. 그래서 Transformers용 환경과 반드시 다른 가상환경 을 씁니다(3절).


2. ⭐ nvidia-smi 읽는 법 — 이 과정에서 가장 자주 볼 화면

nvidia-smi를 치면 이런 화면이 나옵니다. (숫자는 예시 · 실측 아님 )

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 5xx.xx       Driver Version: 5xx.xx       CUDA Version: 12.x     |  ← ⓐ ⓑ
|-------------------------------+----------------------+----------------------+
| GPU  Name                     | Bus-Id               |                      |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|   0  NVIDIA GeForce RTX 4090  | 00000000:01:00.0     |                      |
|  30%   45C   P2   120W / 450W |  17500MiB / 24564MiB |     85%      Default |  ← ⓒ ⓓ
+-------------------------------+----------------------+----------------------+
| Processes:                                                                  |
|  GPU   PID   Type   Process name                            GPU Memory     |
|    0   1234     C   /usr/local/bin/ollama                     17200MiB     |  ← ⓔ
+-----------------------------------------------------------------------------+
표시뜻⚠️ 흔한 오해
ⓐ Driver Version설치된 드라이버 버전—
ⓑ CUDA Version이 드라이버가 지원하는 CUDA의 최대 버전❌ "설치된 CUDA 버전"이 아닙니다. CUDA를 하나도 안 깔아도 표시됩니다
ⓒ Memory-UsageVRAM 사용량 / 전체모델 크기만이 아님. KV 캐시 · CUDA 컨텍스트 · 다른 프로세스까지 합친 값
ⓓ GPU-Util최근 순간에 GPU가 일하고 있던 시간 비율❌ "GPU를 얼마나 꽉 채워 쓰는가"가 아님. 요청이 없으면 모델이 올라가 있어도 0%에 가까움
ⓔ Processes누가 VRAM을 쓰고 있는가환경(WSL · 컨테이너)에 따라 목록이 비어 보일 수 있음

⭐ ⓑ와 PyTorch의 관계 : PyTorch가 들고 온 CUDA 버전(torch.version.cuda)이 ⓑ보다 높으면 GPU를 못 잡을 수 있습니다. 대체로 ⓑ ≥ PyTorch의 CUDA 버전 이면 됩니다. 정확한 호환 범위는 버전에 따라 다르니 PyTorch 공식 설치 페이지에서 확인합니다.

💡 숫자를 계속 보려면 이렇게 씁니다. 14 · 22차시 측정 때 그대로 다시 씁니다.

watch -n 1 nvidia-smi
nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total --format=csv -l 1

🔍 읽는 포인트 : -n 1, -l 1은 1초마다 갱신 . --query-gpu= 뒤에 쉼표로 보고 싶은 열만 고른 것입니다.

앞으로 다시 만납니다 — 5차시에서 모델을 띄우고 내릴 때 ⓒ가 늘었다 줄었다 하는 것을 직접 봅니다. 9차시에서는 ⓒ의 숫자를 가중치 + KV 캐시 + 오버헤드 로 쪼개 계산과 맞춰 봅니다.


3. Python 쪽 — 격리와 확인

3.1 왜 엔진마다 가상환경을 따로 만드는가

먼저 두 용어를 정의합니다.

가상환경 (Virtual Environment) — [격리 장치]인데, [ 프로젝트마다 파이썬과 패키지 묶음을 별도의 폴더에 따로 둔다 ]는 점에서 컴퓨터 전체가 패키지 한 벌을 같이 쓰는 전역 설치와 구별된다. 격리하는 대상이 파이썬 패키지 라는 점에서, OS와 시스템 라이브러리까지 통째로 묶는 Docker 컨테이너(5차시 2.3)와도 구별된다.

의존성 (Dependency) — 내 코드가 돌기 위해 필요한 다른 패키지와 그 버전. 의존성 충돌 은 프로젝트 A는 torch 2.x의 한 버전을, B는 다른 버전을 원할 때 생깁니다. 한 컴퓨터에 전역으로는 한 버전만 깔 수 있으므로 하나를 맞추면 다른 하나가 깨집니다.

전역 설치가상환경
패키지가 놓이는 곳시스템 파이썬 한 곳환경마다 자기 폴더
A와 B가 다른 버전을 원하면둘 중 하나가 깨짐각자 자기 버전을 가짐
망가지면시스템 파이썬을 고쳐야 함그 환경만 지우고 다시 만들면 끝

LLM 쪽에서는 이 충돌이 반드시 일어납니다.

환경들어가는 것왜 따로인가
llm-hftorch, transformers, accelerate, bitsandbytes4 · 11차시 실습용
llm-vllmvllm (자기가 원하는 torch 버전을 고정해서 끌고 옴)기존 torch를 덮어써 llm-hf를 깨뜨림
llm-appollama, openai, streamlit, fastapi앱은 GPU 라이브러리가 필요 없음 — API로 부르기만 함

0절 축 1로 보면 이렇습니다.

전역 (0) — 시스템에 한 번격리 (1) — 환경마다 따로
NVIDIA 드라이버, OllamaPyTorch, transformers, vllm, 앱 라이브러리
바꾸면 모든 것 에 영향 → ⚠️ 사람 승인바꾸다 망가지면 환경만 지우고 다시
conda create -n llm-hf python=3.12 -y      # 또는: uv venv llm-hf --python 3.12
conda activate llm-hf

🔍 읽는 포인트 : -n llm-hf가 환경 이름 , python=3.12가 그 안의 파이썬 버전. 두 번째 줄 activate가 그 환경 안으로 들어가는 명령입니다. 터미널 프롬프트 앞에 (llm-hf)가 붙으면 격리 안으로 들어온 것이고, 이때부터 pip install은 이 환경 폴더에만 깔립니다. ⚠️ 새 터미널을 열면 다시 activate해야 합니다. 파이썬 버전은 설치할 라이브러리가 지원하는 범위에서 고릅니다.

3.2 ⭐ 다섯 줄 확인 스크립트

import sys, torch
print(sys.version)                         # ① 파이썬 버전
print(torch.__version__)                   # ② PyTorch 버전 — 끝에 +cpu 가 붙었는가?
print(torch.version.cuda)                  # ③ PyTorch가 들고 온 CUDA 버전 (CPU 빌드면 None)
print(torch.cuda.is_available())           # ④ GPU를 실제로 잡았는가
print(torch.cuda.get_device_name(0), torch.cuda.get_device_properties(0).total_memory / 1024**3)  # ⑤ 이름, VRAM(GB)

🔍 읽는 포인트 : ②의 끝에 +cpu 가 있거나 ③이 None 이면 그 순간 결론이 납니다 — CPU 전용 PyTorch 입니다. ④가 True이고 ⑤에 내 GPU 이름과 약 24가 찍혀야 통과입니다.

3.3 ⚠️ CPU용 PyTorch 함정

pip install torch가 CPU 전용 빌드 를 설치하는 경우가 있습니다(OS · 설치 방법 · 패키지 색인에 따라 다름). 에러가 나지 않습니다. 그냥 느립니다. 8B 모델이 "돌긴 도는데" 한 문장에 몇 분씩 걸리면 가장 먼저 의심할 곳입니다.

is_available()가 False일 때 점검 순서는 1.1의 사슬을 아래에서 위로 올라가는 것입니다. 아래 고리가 끊겼는데 위 고리를 아무리 고쳐도 소용없기 때문입니다.

순서확인이상하면
1nvidia-smi가 GPU를 보여 주는가②드라이버 문제 → ⚠️ 재설치는 사람이 승인
2torch.__version__에 +cpu가 붙었는가④CPU 빌드 → PyTorch 공식 설치 페이지의 CUDA용 명령 으로 다시 설치
3torch.version.cuda가 nvidia-smi의 CUDA Version 이하인가드라이버가 너무 오래됨 → 드라이버 업데이트(승인) 또는 낮은 CUDA용 PyTorch
4지금 활성화된 환경이 맞는가다른 환경에 깔았음 — 프롬프트 앞의 (환경 이름)을 확인 (3.1)

⚠️ 에러가 가리키는 곳과 원인이 있는 곳은 다를 수 있습니다. 예를 들어 컨테이너 안에서 GPU가 안 잡히면 "컨테이너라서 GPU를 못 쓴다"고 결론 내리기 쉽지만, 실제 원인은 그 안에 CPU 빌드 PyTorch가 깔려 있던 것 인 경우가 흔합니다. 증상은 GPU 쪽에서 보이지만 원인은 설치된 패키지에 있는 것입니다. 그래서 GPU 문제처럼 보이면 먼저 pip list로 무엇이 깔려 있는지 부터 봅니다.

💡 WSL에서 하는 경우 : 드라이버는 Windows 쪽에 설치 하고 WSL 안에는 Linux용 디스플레이 드라이버를 깔지 않는 것이 NVIDIA 안내입니다. WSL 안에서 nvidia-smi가 보이면 ②는 통과입니다.


4. LLM을 위한 하드웨어 — 무엇이 먼저인가

4.1 ⭐ 우선순위

순위자원왜 이 순위인가부족하면
1VRAM가중치 + KV 캐시가 여기에 다 들어가야 GPU 속도가 나옴 (README 7장 문장 1)일부가 RAM으로 밀려나 크게 느려짐 (12차시) 또는 로딩 실패
2메모리 대역폭Decode는 토큰 하나마다 가중치 전체를 읽음 (2차시 4절) → 읽는 속도가 곧 생성 속도의 상한같은 VRAM이라도 TPS가 낮음 (15차시)
3RAM모델 로딩 경로 · VRAM에 못 들어간 층의 피난처로딩 중 멈춤, CPU 혼합 추론 불가
4디스크모델 하나가 수 GB ~ 수십 GB. 용량 과 읽기 속도 (로딩 시간)다운로드 실패, 첫 로딩이 오래 걸림
5CPU토크나이저 · 앱 · 전처리. 추론 자체는 GPU가 함대개 병목이 아님

⭐ 가중치가 차지하는 메모리는 파라미터 수 × 숫자 하나의 바이트 수 로 어림합니다. 숫자 하나를 FP16/BF16(16비트)으로 저장하면 2바이트, 4bit로 줄이면 0.5바이트입니다. 여기에 KV 캐시와 실행 오버헤드가 더해집니다(9차시에서 완성). 이 식을 RTX 4090 24GB에 대 봅니다.

모델 · 정밀도가중치만 (계산값)24GB에
8B · FP16/BF16 (2바이트)8 × 2 ≈ 16GB들어감. KV 캐시 여유는 몇 GB
8B · 4bit (0.5바이트)8 × 0.5 ≈ 4GB (+ 메타데이터)넉넉함
32B · FP1632 × 2 ≈ 64GB❌ 안 들어감 → 양자화(10~12차시)

4.2 순차 ↔ 병렬 — 왜 GPU인가

순차 ↔ 병렬 은 "계산을 몇 개의 연산 장치가 나눠 하는가"의 축입니다(README 5.3).

CPUGPU
일꾼소수의 강한 일꾼 (코어 수 개~수십 개)수천 개의 단순한 일꾼
잘하는 일복잡하고 갈래가 많은 일을 차례로단순한 곱셈 · 덧셈을 한꺼번에
비유대학교수 1명초등학생 3,000명

병렬화의 조건은 하나입니다. 각 계산이 서로의 결과를 기다리지 않아도 되는가(서로 독립인가). Transformer 한 층의 계산은 거대한 행렬 곱이고, 행렬 곱의 각 칸은 다른 칸의 결과 없이 따로 계산할 수 있습니다. 그래서 수천 명의 일꾼에게 나눠 줄 수 있고, 그것이 LLM에 GPU가 필요한 이유입니다.

⚠️ 그런데 2차시에서 Decode는 순차 라고 했습니다. 모순이 아닙니다.

층위순차인가 병렬인가
토큰과 토큰 사이순차 — 앞 토큰이 나와야 다음 토큰 (Decode)
토큰 하나를 만드는 계산 안병렬 — 수십억 번의 곱셈을 GPU가 동시에

그리고 이것은 동기 ↔ 비동기와 다른 축 입니다(README 5.3, 7차시에서 자세히). GPU를 쓴다고 "기다리지 않게" 되는 것이 아니라, 계산 자체가 빨라지는 것입니다.


5. 실습 — 맡기고 검수하기

이 차시는 시스템을 건드리는 실습입니다. AI에게는 진단과 가상환경 작업만 맡기고, 전역 변경은 승인 절차를 둡니다.

지시

목표: 이 서버에서 LLM 실습(Transformers, 이후 vLLM)을 할 수 있는지 진단하고,
      Transformers용 가상환경 llm-hf를 만들어 GPU가 잡히는지 확인해줘.
맥락: PyTorch 설치 명령은 pytorch.org의 공식 설치 페이지(Get Started)에서 이 서버의
      드라이버가 지원하는 CUDA 버전에 맞는 것을 골라. 기억에 의존하지 마.
제약: - NVIDIA 드라이버, CUDA Toolkit 설치·삭제·업데이트는 하지 마. 필요하면 이유와 명령만 보고하고 멈춰.
      - 가상환경 llm-hf 밖에는 pip install 하지 마.
보고 형식: [항목 | 확인 명령 | 출력 원문 | 판정] 표
      항목: OS, GPU 이름, Driver Version, nvidia-smi CUDA Version, 전체/사용 중 VRAM,
            RAM 전체, 디스크 여유(모델 저장 위치 기준), Python 버전,
            torch.__version__, torch.version.cuda, torch.cuda.is_available()
추측하지 말고 실행 출력 원문을 붙여.

받을 증거

  • nvidia-smi 전체 화면 원문 (요약 금지)
  • 3.2절 다섯 줄 스크립트의 출력 원문
  • 설치에 쓴 pip 명령 그대로 (어느 색인에서 받았는지 보이도록)

내가 직접 볼 것

볼 것이걸로 아는 것
torch.__version__ 끝에 +cpu가 없는가CPU 빌드 함정에 빠지지 않았는가
torch.version.cuda ≤ nvidia-smi의 CUDA Version사슬 ②와 ④가 맞물리는가
Memory-Usage의 사용 중 값실습 전부터 VRAM을 먹는 프로세스가 있는가 — 있으면 Processes 목록(2절 ⓔ)에서 누구인지 확인
디스크 여유가 200GB 이상 인가2일차에 모델을 여러 개 받을 수 있는가 (README 8장)
AI가 드라이버를 건드리지 않았는가전역 변경은 내 승인 사항

부록 A. 스스로 확인하기

#질문답이 있는 곳
1GPU에서 모델이 돌기까지 다섯 고리를 아래에서부터 말하면?1.1
2다섯 고리 중 전역인 것과 격리인 것은? 가상환경은 무엇을 격리하며, 의존성 충돌은 왜 생기는가?1.1, 3.1
3GPU용 PyTorch를 쓰려면 CUDA Toolkit을 따로 깔아야 하는가?1.2
4Ollama가 PyTorch 없이 GPU를 쓰는 이유는?1.2
5nvidia-smi의 CUDA Version은 무엇의 버전인가?2
6GPU-Util이 0%인데 Memory-Usage가 높으면 무슨 상황인가?2
7is_available()가 False일 때 점검 순서는?3.3
8LLM 하드웨어 우선순위 1, 2위와 그 이유는?4.1
9CPU와 GPU는 순차 ↔ 병렬 축에서 어떻게 다르고, Decode는 순차인데 왜 GPU가 필요한가?4.2

부록 B. 자주 하는 실수

실수바로잡기
"nvidia-smi에 CUDA 12.x라고 나오니 CUDA 12.x가 설치돼 있다"❌ 드라이버가 지원하는 최대치 입니다
"에러 없이 돌아가니 GPU를 쓰고 있다"⚠️ CPU 빌드는 에러 없이 느립니다. +cpu와 is_available()로 확인
"PyTorch가 안 되니 드라이버부터 다시 깔자"❌ 사슬을 아래에서 위로 점검. 드라이버 재설치는 시스템 전체 변경 → 승인
"vLLM도 지금 환경에 같이 깔자"❌ vLLM은 torch 버전을 고정해 끌고 옴. 환경을 분리
"GPU-Util이 낮으니 GPU가 남는다"⚠️ 남는지는 Memory-Usage 로 판단. Util은 "지금 일하는 중인가"일 뿐
"CPU가 좋으면 LLM이 빠르다"❌ 순위는 VRAM > 대역폭 이 먼저

부록 C. NotebookLM 복습 프롬프트

이 3차시 노트만 근거로 6문제를 내줘. 비전공자 기준으로.
"nvidia-smi의 CUDA Version이 뜻하는 것", "CPU용 PyTorch 함정", "전역(드라이버) ↔ 격리(가상환경)"는 반드시 포함해줘.
답은 내가 답한 다음에 채점하고, 틀린 이유를 노트의 절 번호를 근거로 설명해줘.