과정 안내
실습 코드 사용 안내
실습 코드를 직접 돌리기 전에 장마다 무엇이 필요한지 한곳에 모았습니다. API 키가 필요한지, 어떤 모델을 받아 두어야 하는지, GPU 가 꼭 있어야 하는지, 앞의 어떤 실습을 먼저 돌려야 하는지를 표로 봅니다. 설치 방법은 환경설정에, 데이터 파일의 설명은 실습 데이터에 있습니다.
먼저 알아 둘 것
- 작업 폴더는 data 폴더입니다. 모든 실습 코드는
data폴더에서 실행한다고 보고 썼습니다. 파일을 읽고 쓰는 경로가 모두 이 폴더 기준입니다. - 실습 코드 파일: 원고의 실습과 프로젝트 코드는 장마다
code/chNN/에lab1.py,project1_solution.py처럼 파일로도 있습니다. 프로젝트 풀이는solutions/에 장마다 모여 있습니다. - 실습 절 하나는 위에서부터 이어서 돌립니다. 단계(
#### 1단계)마다 앞 단계의 변수를 씁니다. 주피터에서는 셀을 차례로, 파일로는lab1.py를 통째로 돌립니다. - out_ 로 시작하는 파일은 실습이 만듭니다. 없다는 오류가 나면 그 파일을 만드는 앞 실습을 먼저 돌립니다(아래 "장을 건너는 의존과 순서").
- 데이터는 다시 만들 수 있습니다. 실습 데이터는 모두 지어낸 연습용이고,
tools/make_data.py가 씨앗을 고정해 만듭니다. 지우거나 고쳤다면 과정 폴더에서 다시 만듭니다.
cd data
..\.venv\Scripts\python ..\code\ch19\lab1.py.venv\Scripts\python tools\make_data.py위는 data 폴더에서 19장 실습 1의 파일을 돌리는 예이고, 아래는 과정 폴더에서 데이터를 다시 만드는 명령입니다. 가상환경을 켜 두었다면 python 만 써도 됩니다.
API 키와 비밀 값
실행되는 실습 코드 가운데 진짜 API 키가 필요한 곳은 없습니다. 외부 서비스에 돈을 내고 받는 키 없이 과정 전체를 돌릴 수 있습니다. 키와 비밀 값이 나오는 곳은 아래와 같습니다.
| 장 | 나오는 값 | 진짜 키가 필요한가 | 어떻게 다루나 |
|---|---|---|---|
| 6장부터 | Ollama 호출의 api_key="ollama" | 아니요 | Ollama 는 키를 보지 않습니다. openai 라이브러리가 칸을 채우라고 해서 넣는 가짜 값입니다 |
| 6장 | 외부 API(OpenAI) 호출, OPENAI_API_KEY | 안내 코드만 | 실행하지 않은 안내 코드입니다. 해 보려면 발급받은_인증키 자리에 직접 발급받은 키를 환경 변수로 넣습니다. 요금이 듭니다 |
| 13장 | DELAY_API_KEYS, DELAY_JWT_SECRET, 시험 비밀번호, RULES_API_KEYS | 아니요 | 실행할 때 secrets 로 시험용 값을 만들어 환경 변수에 넣습니다 |
| 14장 | RULES_API_KEYS, UI_API_KEY, .env.example | 아니요 | 시험용 값은 secrets 로 만들고, .env.example 에는 발급받은_인증키 자리표시만 적습니다 |
| 17장 | SUMMARY_MODEL, OLLAMA_URL, INQUIRY_THRESHOLD 등 | 아니요 | 키가 아니라 설정값입니다. 없으면 기본값을 씁니다 |
| 18장 | CS_API_KEYS | 아니요 | 실행할 때 secrets 로 고객마다 시험용 키를 만듭니다 |
| 21장 | PII_KEY, GUARD_OFF, 가짜 관리 코드 HN-4729 | 아니요 | PII_KEY 는 secrets 로 만든 가명 처리 키, GUARD_OFF 는 CI 시험에서 방어를 끄는 스위치, 관리 코드는 유출을 재려고 넣은 가짜 값입니다 |
진짜 키를 쓰게 되면 지킬 것이 셋 있습니다.
- 키는 코드와 노트에 적지 않고 환경 변수나 사내 비밀 저장소에서 읽습니다.
- 저장소에 올리는 파일(
.env, 설정 파일)에 키가 들어가지 않게 합니다. 예시 파일에는 자리표시만 둡니다. - 키를 시스템 프롬프트에 넣지 않습니다. 21장에서 본 것처럼 프롬프트 속 비밀은 샙니다.
$env:OPENAI_API_KEY = "발급받은_인증키"
python -c "import os; print('키 있음' if os.environ.get('OPENAI_API_KEY') else '키 없음')"위는 PowerShell 창에서만 쓰는 환경 변수를 넣고 확인하는 꼴입니다. 창을 닫으면 사라집니다.
장별 실습 준비표: 모델과 GPU
Hugging Face 모델은 처음 실행할 때 한 번 내려받으므로 그때만 인터넷이 필요합니다. 받은 뒤에는 캐시에서 읽습니다. Ollama 모델은 ollama pull 로 미리 받고, 그 장을 돌리는 동안 Ollama 가 켜져 있어야 합니다.
| 장 | Ollama 모델 | Hugging Face 모델 | GPU |
|---|---|---|---|
| 1장 | 없음 | 없음 | 안 씀 |
| 2장 | 없음 | 없음 | 있으면 실습 1에서 CPU 와 속도를 견준다. 학습은 일부러 CPU |
| 3장 | 없음 | Helsinki-NLP/opus-mt-ko-en, Qwen/Qwen2.5-0.5B-Instruct | 안 씀(CPU, float32) |
| 4장 | 없음 | Qwen/Qwen2.5-0.5B, Qwen/Qwen2.5-0.5B-Instruct | 있으면 빠르다(실습 5가 30초쯤, 없으면 몇 분) |
| 5장 | 없음 | Qwen/Qwen2.5-0.5B-Instruct | 필요(실습 3, 6, 프로젝트의 학습). 실습 1, 4, 5는 CPU 로 된다 |
| 6장 | qwen2.5:0.5b, qwen2.5:1.5b, qwen2.5:3b | Qwen/Qwen2.5-0.5B-Instruct | 있으면 빠르다 |
| 7장 | 프로젝트: qwen2.5:1.5b, qwen2.5:3b, gemma3:1b, llama3.2:1b | intfloat/multilingual-e5-small, cross-encoder/mmarco-mMiniLMv2-L12-H384-v1 | 파이썬은 CPU, Ollama 만 GPU |
| 8장 | qwen2.5:3b | intfloat/multilingual-e5-small | Ollama 만 |
| 9장 | qwen2.5:3b, gemma3:1b | intfloat/multilingual-e5-small | Ollama 만 |
| 10장 | qwen2.5:3b(실습 3부터) | intfloat/multilingual-e5-small | Ollama 만 |
| 11장 | qwen2.5:3b(실습 1부터 켜 둔다) | intfloat/multilingual-e5-small(미리 받아 두어야 한다, 폐쇄망 흉내) | Ollama 만 |
| 12장 | qwen2.5vl:3b, qwen2.5:3b | clip-ViT-B-32, clip-ViT-B-32-multilingual-v1, intfloat/multilingual-e5-small, Qwen/Qwen2.5-0.5B-Instruct | 있으면 빠르다(프로젝트의 학습) |
| 13장 | 프로젝트: qwen2.5:3b | 프로젝트: intfloat/multilingual-e5-small | 안 씀 |
| 14장 | qwen2.5:3b(실습 2, 프로젝트) | intfloat/multilingual-e5-small | Ollama 만 |
| 15장 | qwen2.5:0.5b, qwen2.5:0.5b-instruct-q8_0, qwen2.5:0.5b-instruct-fp16 | Qwen/Qwen2.5-0.5B-Instruct, intfloat/multilingual-e5-small | 필요(실습 2의 bitsandbytes, 실습 6). 실습 4, 5는 CPU |
| 16장 | qwen2.5:3b | Qwen/Qwen2.5-0.5B-Instruct, intfloat/multilingual-e5-small, cross-encoder/mmarco-mMiniLMv2-L12-H384-v1 | 필요(실습 3). 나머지는 Ollama 만 |
| 17장 | qwen2.5:3b | intfloat/multilingual-e5-small | Ollama 만 |
| 18장 | qwen2.5:3b, qwen2.5:1.5b | intfloat/multilingual-e5-small | Ollama 만 |
| 19장 | 없음 | intfloat/multilingual-e5-small | 안 씀 |
| 20장 | qwen2.5:3b | intfloat/multilingual-e5-small | Ollama 만 |
| 21장 | qwen2.5:3b | intfloat/multilingual-e5-small | Ollama 만. 실습 6의 3단계는 NVIDIA GPU 가 있어야 한다 |
"Ollama 만"은 파이썬 코드가 GPU 를 직접 쓰지 않고, Ollama 가 있으면 GPU 로 빨리 돈다는 뜻입니다. GPU 가 없어도 Ollama 는 CPU 로 돌지만 답이 몇 배 느립니다.
장별 실습 준비표: 순서, 파일, 포트
| 장 | 새 패키지 | 먼저 돌릴 것 | 서버 포트 |
|---|---|---|---|
| 1장 | scikit-learn | 실습 2(out_delivery_clean.csv)를 실습 3~6보다 먼저 | 없음 |
| 2장 | torch | 없음 | 없음 |
| 3장 | transformers, sentencepiece | 없음 | 없음 |
| 4장 | datasets, accelerate | 실습 3(out_tok/) → 실습 4~6, 실습 5(out_pretrained) → 실습 6 | 없음 |
| 5장 | peft, trl | 실습 3(out_lora_shop) → 실습 4 | 없음 |
| 6장 | openai, Ollama | 없음 | Ollama 11434 |
| 7장 | sentence-transformers, faiss-cpu, chromadb | 없음 | Ollama 11434 |
| 8장 | 없음 | 프로젝트끼리 따로 | Ollama 11434 |
| 9장 | 없음 | 없음 | Ollama 11434 |
| 10장 | mcp | 실습 1(out_stock_server.py) → 실습 2, 3 | 없음(stdio) |
| 11장 | qdrant-client | 실습 1(out_offline.py) → 실습 4, 6, 프로젝트. 실습 2 → 3 → 4 → 6 | Ollama 11434 |
| 12장 | 없음 | 실습 3(out_captions.csv) → 4. 실습 5 → 6 → 프로젝트 | Ollama 11434 |
| 13장 | fastapi, uvicorn, PyJWT | 실습 1(out_delay_model.joblib) → 2~6. 실습 2(out_delay_api.py) → 3, 4 | 8013(실습 4) |
| 14장 | streamlit | 13차시 실습 1, 2 먼저. 실습 3 → 5 → 6 | 8013, 8501, 8014 |
| 15장 | bitsandbytes | 없음 | Ollama 11434 |
| 16장 | 없음 | 없음 | Ollama 11434 |
| 17장 | 없음 | 프로젝트 1, 2 → 프로젝트 3 | 8171, 8172 |
| 18장 | 없음 | 프로젝트 2 안에서 단계 차례대로 | 없음(TestClient) |
| 19장 | mlflow | 실습 1(out_flow.py) → 3, 6, 프로젝트. 실습 4 → 5 → 6 | 없음 |
| 20장 | 없음 | 실습 1(out_libbot.py) → 2 → 4, 실습 1 → 3 | 없음 |
| 21장 | 없음 | 실습 1 → 2, 실습 3 → 4, 실습 1 → 5, 실습 1~5 → 프로젝트 | 없음 |
같은 포트에 앞서 띄운 서버가 남아 있으면 address already in use 오류가 납니다. 앞 서버를 끄거나 포트 번호를 바꿉니다.
Ollama 모델 받기
과정에서 쓰는 Ollama 모델은 아래 여덟 가지입니다. 모두 받지 않아도 되고, 표의 장에 맞춰 필요한 것만 받습니다. 대부분의 장은 qwen2.5:3b 하나로 됩니다.
ollama pull qwen2.5:3b
ollama pull qwen2.5:1.5b
ollama pull qwen2.5:0.5b
ollama pull gemma3:1b
ollama pull llama3.2:1b
ollama pull qwen2.5vl:3b
ollama pull qwen2.5:0.5b-instruct-q8_0
ollama pull qwen2.5:0.5b-instruct-fp16
ollama listGPU 가 없거나 작을 때
교안은 GeForce GTX 1650(4GB)에서 만들었습니다. GPU 가 없어도 대부분의 장은 돌아갑니다. GPU 가 꼭 있어야 하는 곳과 대신 가는 길입니다.
| 곳 | 까닭 | GPU 가 없으면 |
|---|---|---|
| 5장 실습 3, 6, 프로젝트 | LoRA·DPO 학습 | CPU 로는 아주 오래 걸립니다. 실습 3은 건너뛰고, data 폴더에 저장된 어댑터(out_lora_shop)로 실습 4를 돌립니다 |
| 15장 실습 2 | bitsandbytes 의 8비트·4비트는 NVIDIA GPU 전용 | Ollama 의 양자화 단계(실습 3)로 같은 생각을 봅니다 |
| 15장 실습 6, 16장 실습 3 | GPU 에서 fp16 생성·묶음 생성 | 교안의 출력을 읽고 넘어갑니다 |
| 21장 실습 6의 3단계 | GPU 정보를 읽는다 | 1, 2, 4단계의 셈만 돌립니다 |
GPU 가 4GB 이고 Ollama 와 PyTorch 를 한 프로그램에서 함께 쓰면 메모리가 모자라거나 Ollama 가 오류를 낼 수 있습니다. 교안의 코드는 임베딩 모델을 device="cpu" 로 불러 GPU 를 Ollama 에 남기고, Ollama 가 오류를 내면 모델을 내렸다(keep_alive: 0) 다시 묻습니다. 다른 모델을 쓰기 전에는 ollama stop 모델이름 으로 내립니다.
실행하지 않은 안내 코드
이 PC(Windows, Docker 없음)에서 돌릴 수 없는 코드는 실행하지 않은 안내 코드로 싣고, 바로 아래에 "예상 출력(실행하지 않고 유추한 예시)"을 붙였습니다. 직접 해 보려면 Linux, WSL2, Docker 가 있는 곳에서 돌립니다.
| 장 | 안내 코드 | 돌리려면 |
|---|---|---|
| 6장 | 외부 API(OpenAI) 호출 | 발급받은 API 키(유료) |
| 14장, 17장, 19장 | docker build, docker compose | Docker Desktop(WSL2) 또는 Linux 의 Docker |
| 15장 | GPTQ·AWQ 양자화 | Linux 와 NVIDIA GPU |
| 16장 | vllm serve, vllm bench serve | Linux 또는 WSL2 와 NVIDIA GPU |
| 19장 | Airflow DAG, airflow dags test | Linux, WSL2 또는 Docker |
| 20장 | Prometheus 계기, 알림 규칙 | prometheus_client, Prometheus 서버 |
| 21장 | GitHub Actions 파일 | 깃허브 저장소와 실행기(self-hosted runner) |
장을 건너는 의존과 순서
대부분의 장은 그 장 안에서 끝나지만, 몇 곳은 앞 장의 파일이나 데이터를 씁니다.
| 뒤 장 | 앞 장에서 가져오는 것 | 없으면 |
|---|---|---|
| 14장 | 13장 실습 1의 out_delay_model.joblib, 실습 2의 out_delay_api.py | 13장 실습 1, 2를 먼저 돌립니다 |
| 4장 | 3장의 cs_dialogs.txt(실습 3의 토크나이저 학습) | 데이터 폴더에 있으면 됩니다 |
| 13장 | 1장의 delivery.csv | 데이터 폴더에 있으면 됩니다 |
| 17장, 19장 | 10장의 손으로 쓴 inquiries.csv, 17장의 inquiry_train.csv | 데이터 폴더에 있으면 됩니다 |
| 20장, 21장 | 19장의 library/day4/ 안내 문서 | 데이터 폴더에 있으면 됩니다 |
장 안의 순서는 "순서, 파일, 포트" 표의 "먼저 돌릴 것"을 따릅니다. 특히 19장 실습 4~6은 같은 MLflow 기록(out_mlflow.db)을 이어 쓰므로, 실습 4부터 차례로 돌려야 버전 번호가 교안과 같습니다.