새 시리즈 시작. FEMS (Factory Energy Management System) 프로젝트 일지.
이전에 회사에서 엣지 AI 보드 위에서 객체 감지를 돌려본 경험이 있어서 공장 / 산업 데이터 + AI 의 결합 이라는 흐름이 계속 머릿속에 남아 있었다. 그 연장선에서 FEMS 도메인을 학습하면서 RAG 프로토타입을 한 번 깎아보기로 결정. “공부했습니다” 보다 “이 정도까지 돌려봤습니다” 가 손에 더 잘 붙는다.
이 시리즈에서 경험하게 될 기술:
- RAG
- 허깅페이스, Ollama
- 임베딩, 벡터 DB
- 토큰 사용 전략 / 로컬 vs 클라우드 비교
RAG · 임베딩 · 벡터 DB 는 최근 RAG 직접 구현 / RAG 시스템 구축 에서 다뤄봤기 때문에 그나마 친숙. 로컬 LLM (Ollama) 이 새로 추가되는 축.
Table of contents
Open Table of contents
사양 체크 — VRAM 6GB 가 가른다
| 항목 | 값 |
|---|---|
| OS | Windows 11 |
| GPU | GTX 1660 Super |
| VRAM | 6 GB |
| RAM | 32 GB |
로컬 LLM 의 가성비/속도는 VRAM 이 가른다. VRAM 6GB 는 큰 모델이 안 돌아간다. 7B 모델도 양자화(4bit) 안 하면 빠듯. 13B 이상은 사실상 불가.
그래서 프로젝트 방향을 비교 실험으로 잡았다:
저사양 온프레미스 환경에서 로컬 추론 vs Claude / OpenAI API 호출 — 어느 쪽이, 어떤 상황에서 합리적인가
FEMS 도메인 자체와도 잘 맞는 질문이다. 공장은 데이터 외부 반출이 까다로워서 온프레미스 추론 수요가 분명히 있고, 동시에 도입 비용(GPU) 도 부담스러우니까 저사양에서 어디까지 되는지 가 실무적 질문이 된다.
데이터 — FEMS 도메인 문서 어떻게 모을까
RAG 가 답변할 근거 문서가 필요하다. FEMS 도메인에서 가능한 후보:
- FEMS 매뉴얼 / 가이드라인 문서
- 에너지 데이터 분석 리포트
- FEMS DB 의 측정값
오늘은 일단 테스트용 가이드라인을 직접 작성 해서 RAG 동작부터 검증. 내일부터 한국에너지공단 FEMS 구축 가이드, 에너지절약 기술자료 같은 공개 PDF 를 붙일 예정.
셋업 — Python 스캐폴딩 + Ollama
기본 골격:
- Python 프로젝트 스캐폴딩
- Ollama 설치 (로컬 LLM 런타임)
- Provider 3종 (Ollama / Claude / OpenAI) 을 동일한 인터페이스로 호출하는 어댑터
모델 선정 — 로컬은 VRAM 6GB 에 맞춰 qwen2.5:7b
3-provider 비교를 위해 각각의 모델을 다음과 같이 픽:
| Provider | 모델 | 선정 이유 |
|---|---|---|
| Ollama (로컬) | qwen2.5:7b | VRAM 6GB 에 들어가는 7B 급, 한국어 성능 우수 |
| Claude (클라우드) | claude-opus-4-8 | 현재 라인업 상위 모델 — 품질 상한 확인용 |
| OpenAI (클라우드) | gpt-4o | 중간 가격대 비교 기준 |
로컬은 VRAM 이 모델 선택을 가른다. 7B 모델은 양자화(4bit) 거치면 VRAM 4~5GB 정도라 6GB 환경에 들어감. 13B 이상은 시도조차 불가. qwen2.5 는 7B 라인에서 한국어/추론 성능이 균형 잡혀서 채택.
클라우드 쪽은 일부러 상위 (Opus 4.8) vs 중간 (gpt-4o) 으로 가격·품질 스펙트럼을 갖다 놨다. 이래야 “로컬이 어디까지 따라잡나” 를 두 기준으로 볼 수 있다.
Smoke test — 첫 실행 (콜드 스타트)
세 provider 가 동일한 질문에 답하는지부터 확인:
python -m scripts.smoke_test

| provider | 모델 | latency | in / out 토큰 | 비용 |
|---|---|---|---|---|
| ollama | qwen2.5:7b | 95.22s | 47 / 36 | $0.00000 |
| claude | opus-4-8 | 2.72s | 60 / 73 | $0.00213 |
| openai | gpt-4o | 6.43s | 45 / 30 | $0.00041 |
3개 다 정답. 차이는 latency 와 비용:
- Opus 4.8 이 gpt-4o 보다 약 5배 비쌈 ($0.00213 vs $0.00041)
- ollama (qwen2.5:7b) 가 95초 — 콜드 스타트 때문. 첫 호출이 모델 로딩이라 대부분이 로딩 시간.
Smoke test — 두 번째 실행 (워밍업 후)
이미 모델이 메모리에 올라온 상태로 다시 돌리면:

- ollama: 95s → 10.00s (콜드 스타트 풀린 결과)
- claude: 2.72s → 2.46s
- openai: 6.43s → 2.62s
95초 vs 10초 의 차이는 운영적으로 매우 크다. 즉, 로컬 LLM 은 “처음 한 번” 을 어떻게 다루느냐 가 latency 핵심:
- 항상 메모리에 올려둘 것인가 (메모리 소모)
- 사용 빈도에 따라 swap 할 것인가 (그때마다 콜드)
운영 모드 설계의 핵심 질문이 됨.
임베딩 모델 선정 — Ollama 의 bge-m3
임베딩을 Ollama 의 bge-m3 로 결정.
선정 이유:
- 한국어/다국어 우수 — FEMS 가이드라인이 한국어니까 핵심 조건
- 별도 임베딩 API 불필요 — Ollama 가 LLM 도 임베딩도 같이 줌
- 로컬 완결 — 외부 API 호출 없이 임베딩까지
검토했지만 안 쓴 것:
| 옵션 | 안 쓴 이유 |
|---|---|
| LangChain / LlamaIndex | 의존성이 너무 무겁고 추상화 과함 |
| sentence-transformers (로컬) | torch 설치 무겁고, Ollama 가 더 합리적 |
그리고 한 가지 주의 — Chroma 의 기본 임베딩 함수는 영어 특화. 한국어 문서를 그대로 넣으면 임베딩 품질이 떨어진다. 그래서 임베딩을 직접 계산해서 Chroma 에 주입 하는 식으로 진행.
지난 RAG 직접 구현 글 에서 OpenAI 임베딩으로 한국어를 돌렸을 때 유사도 절대값이 0.3 ~ 0.5 수준으로 낮게 나왔었다. bge-m3 는 다국어 특화라 이 점이 개선되는지가 이번 검증 포인트.
인덱스 구축 — 청크 5개부터
테스트용 가이드라인을 800자 이하로 청크 분할 후 인덱싱:
python -m scripts.build_index

총 5 청크:
- 압축공기 시스템 효율 가이드라인
- 피크 전력 관리 가이드라인
- 공조설비(HVAC) 최적화 가이드라인
- 에너지 절감 조명 가이드라인
- (그 외 1개)
RAG 동작 검증 — 3 질문 모두 정답
지정된 질문에 대해 출처가 정확히 매칭되는지 확인:
python -m scripts.rag_demo

| 질문 | 1순위 매칭 | dist (cosine 거리) |
|---|---|---|
| 압축공기 시스템에서 에너지 낭비를 줄이려면? | 02_compressed_air.md | 0.322 |
| 공장 전기요금의 피크 수요를 낮추는 방법은? | 01_peak_demand.md | 0.272 |
| 야간이나 주말에 조명 전력이 계속 잡히면 무엇을 점검? | 04_lighting.md | 0.392 |
3개 다 정답. (cosine distance 는 낮을수록 유사 — 0 이면 동일, 1 이면 무관)
특히 두 번째 질문 (피크 수요) 의 dist 0.272 는 굉장히 잘 매칭된 것. bge-m3 가 한국어를 제대로 다루고 있다 는 의미.
이전 글에서 OpenAI
text-embedding-3-small로 한국어를 돌렸을 땐 1위 유사도가 0.3 ~ 0.5 사이였는데, bge-m3 는 0.27 ~ 0.39 (distance, 낮을수록 좋음 → 유사도로 환산 시 0.6 ~ 0.73). 다국어 임베딩의 차이가 숫자로 드러남.
회고 — 일단 백본은 섰다
오늘 하루로 잡힌 골격:
- Python 스캐폴딩 ✅
- Ollama 로컬 모델 동작 ✅
- 3-provider 동시 호출 (ollama / claude / openai) ✅
- bge-m3 임베딩 + Chroma 인덱스 ✅
- 5청크 RAG 데모 정답률 100% ✅
내일은 실제 공개 데이터 PDF (한국에너지공단 FEMS 구축 가이드, 에너지절약 기술자료 등) 를 붙여서 청크 수를 키우고, 로컬 vs 클라우드 답변 품질을 진짜 도메인 질문으로 비교 할 예정.
다음 글부터는 본격 비교 실험으로 들어간다.
더 공부해볼 것
1. Ollama 운영 모드 — Keep-alive vs Swap
OLLAMA_KEEP_ALIVE환경 변수로 모델 메모리 상주 시간 제어- VRAM 6GB 에서 모델을 여러 개 돌릴 때 swap 비용
- 사용 빈도 기반 자동 swap 전략
2. bge-m3 vs 다른 한국어 임베딩
- KoSimCSE / KoSBERT — 한국어 sentence embedding 의 사실상 표준
- multilingual-e5-large — 다국어 모델 중 한국어 성능 양호
- 동일 문서 셋으로 임베딩 벤치마크 (1순위 dist 비교)
3. Chroma 의 기본 임베딩 함수가 영어 특화인 이유
- Chroma 기본값이
all-MiniLM-L6-v2(sentence-transformers, 영어 중심) - 직접 임베딩 주입 방식이 표준 — collection 생성 시
embedding_function=None - pgvector 등 다른 벡터 DB 의 임베딩 정책 차이
4. 토큰 사용 전략 — RAG 관점에서
- 컨텍스트 윈도우 와 청크 수 × 청크 크기 의 관계
- Prompt Caching 으로 시스템 프롬프트 / 도구 정의 캐싱
- Top-K retrieval 의 K 값이 비용에 미치는 영향
5. FEMS 도메인 자체
- 한국에너지공단 FEMS 구축 가이드 (공개 PDF)
- 에너지절약 기술자료 — 산업 부문 (한국에너지공단)
- 피크 관리 / 압축공기 / HVAC / 조명 — 4대 공통 절감 영역
- 측정 항목: 전력 (kW, kWh), 역률, 디맨드, 가스/스팀 등 다양한 에너지 흐름
6. 온프레미스 LLM 도입의 trade-off
- 데이터 보안 ↑ vs 모델 품질 ↓
- 초기 GPU 비용 vs API 호출 비용 (BEP 계산)
- 모델 업데이트 주기 — 클라우드는 자동, 온프레미스는 수동 fine-tune / 교체