🎯 프로젝트 개요

개인 프로젝트로 원격 GPU 서버를 활용해 LLM 챗봇 서비스를 구축했습니다. 목표는 간단했습니다:

  • 5명 이상 동시 사용 가능한 AI 챗봇
  • 안정적인 성능과 빠른 응답
  • 모니터링 및 자동 관리

하지만 실제로 구축하고 테스트해보니 예상보다 훨씬 강력한 성능을 확인했습니다. 최종적으로 50명 동시 접속도 무리 없이 처리하는 시스템이 완성되었습니다.

🏗️ 시스템 구성

하드웨어

원격 서버

  • GPU: NVIDIA GB10
  • RAM: 119.6GB
  • CPU: 20-core ARM64 (aarch64)
  • OS: NVIDIA DGX Spark 7.4.0 (Linux 6.14.0)

Main 서버 (yeonghoon-kim)

  • GPU: 미사용 (원격 서버 활용)
  • 역할: Open WebUI 호스팅, 모니터링

소프트웨어 스택

┌─────────────────────────────────────────┐
│ Main 서버 (Open WebUI)                   │
│ - 웹 인터페이스                          │
│ - 사용자 인증                            │
│ - 채팅 이력 관리                         │
└─────────────────────────────────────────┘
              ↓ HTTP/WebSocket
┌─────────────────────────────────────────┐
│ 원격 LLM 서버 (Ollama)                   │
│ - Nginx 로드밸런서                       │
│ - Ollama 인스턴스 (GPU 가속)             │
│ - 12개 LLM 모델 호스팅                   │
└─────────────────────────────────────────┘
              ↓ Prometheus
┌─────────────────────────────────────────┐
│ 모니터링 (Grafana + Prometheus)          │
│ - GPU 사용률, 메모리, 온도               │
│ - 시스템 리소스                          │
└─────────────────────────────────────────┘

🚀 구축 과정

1단계: Ollama 배포

원격 서버에 Docker를 사용해 Ollama를 배포했습니다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
services:
  ollama-1:
    image: ollama/ollama:latest
    container_name: ollama-1
    ports:
      - "32777:11434"
    environment:
      - OLLAMA_NUM_PARALLEL=5
      - OLLAMA_KEEP_ALIVE=5m
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    volumes:
      - ollama-data:/root/.ollama

주요 설정:

  • OLLAMA_NUM_PARALLEL=5: 동시 요청 5개 처리
  • OLLAMA_KEEP_ALIVE=5m: 미사용 모델 5분 후 자동 언로드
  • GPU 전체 활용

2단계: Nginx 로드밸런서

처음엔 2개의 Ollama 인스턴스로 시작했지만, 메모리 중복 로드 문제가 발견되었습니다:

ollama-1: codellama:34b (33.8GB)
ollama-2: codellama:34b (33.8GB)  ← 중복!
----------------------------------
합계: 67.6GB (메모리 낭비)

해결: ollama-2를 중지하고 ollama-1만 운영

  • 메모리 사용량 50% 절감
  • 성능 저하 없음 (단일 인스턴스로도 50명 처리 가능)

3단계: Open WebUI 연동

Main 서버에서 Open WebUI를 배포:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "8080:8080"
    environment:
      - OLLAMA_BASE_URL=http://remote-llm-server:8080
      - WEBUI_AUTH=true
      - ENABLE_SIGNUP=true
      - RAG_EMBEDDING_ENGINE=  # RAG 비활성화 (안정성)
    volumes:
      - open-webui-data:/app/backend/data

도메인: 내부 도메인 (비공개)

  • Caddy를 통한 HTTPS 지원
  • IP 제한 (내부 네트워크만 접근)

4단계: GPU 모니터링

Prometheus + Grafana로 실시간 모니터링:

수집 메트릭:

  • GPU 사용률
  • GPU 메모리 (nvidia-smi 파싱)
  • GPU 온도
  • 시스템 리소스 (CPU, 메모리, 디스크)

Grafana 대시보드:

  • Row 1: GPU 사용률
  • Row 2: GPU 메모리 (used/total)
  • Row 3: GPU 온도

🧪 성능 테스트

동시 접속 테스트

테스트 방법:

  • 간단한 프롬프트 (“Say hello in 5 words”)
  • curl을 사용한 동시 요청
  • 성공/실패 및 응답 시간 측정

경량 모델 (neural-chat:7b, 3.8GB)

동시 사용자성공률평균 응답 시간
5명100%5-15초 (첫 로드)
10명100%0.4-3.6초
20명100%0.4-3.9초
50명100%0.4-5초

발견:

  • 모델이 로드되면 초고속 (0.4초)
  • 메모리 공유로 효율적 처리
  • 50명 동시 접속도 타임아웃 없음

대형 모델 (codellama:34b, 17.7GB)

동시 사용자성공률평균 응답 시간
10명100%10-14초 (첫 로드)
20명100%2-9초
50명100%2-28초

발견:

  • 대형 모델도 50명 처리 가능
  • 첫 로드 후 성능 대폭 향상
  • 메모리 관리로 안정적 처리

모델 순차 로드 테스트

목적: GPU 메모리 한계 및 Ollama 자동 관리 확인

테스트 방법:

  1. 모든 모델 언로드 (Ollama 재시작)
  2. 12개 모델 5초 간격 순차 로드
  3. 각 모델 로드 후 GPU 메모리 측정

결과:

모델크기로드 시간GPU 메모리상태
neural-chat:7b3.8GB6.0초6.7 GB
mistral:latest4.1GB8.0초31.7 GB
mistral-openorca:latest3.8GB8.3초56.4 GB
deepseek-r1:7b4.4GB14.4초40.7 GB
gemma2:9b5.1GB8.3초60.0 GB
codellama:13b6.9GB14.9초90.7 GB 🔥
orca2:13b6.9GB8.7초42.7 GB
gemma3:12b7.6GB13.3초95.5 GB 🔥🔥✅ (최대치)
deepseek-r1:14b8.4GB61.3초-❌ 메모리 부족
gpt-oss:20b12.8GB9.4초30.1 GB
qwen3:30b17.3GB2.2초-❌ 모델 파일 손상
codellama:34b17.7GB21.4초63.9 GB

주요 발견:

  1. GPU 메모리 최대치: ~95.5GB (gemma3:12b 로드 시)
  2. Ollama 자동 메모리 관리 작동
    • 90.7GB → 42.7GB (이전 모델 자동 언로드)
    • 95.5GB → 30.1GB (자동 언로드)
  3. 성공률: 10/12 (83%)
    • deepseek-r1:14b: GPU 메모리 부족 (하드웨어 한계)
    • qwen3:30b: 모델 파일 손상

💡 최적화 포인트

1. 단일 인스턴스 운영

Before:

ollama-1 (33.8GB) + ollama-2 (33.8GB) = 67.6GB

After:

ollama-1 (33.8GB) = 33.8GB (50% 절감)

효과:

  • 메모리 효율 2배 증가
  • 단일 인스턴스로도 50명 처리 가능

2. RAG 비활성화

Open WebUI의 RAG 기능을 비활성화하여:

  • HuggingFace 의존성 제거
  • ‘NoneType’ 에러 방지
  • 시작 시간 단축

3. 자동 메모리 관리

Ollama의 OLLAMA_KEEP_ALIVE=5m 설정:

  • 미사용 모델 5분 후 자동 언로드
  • GPU 메모리 자동 최적화
  • 수동 관리 불필요

📊 운영 가이드

권장 모델 선택

일반 사용 (7B-9B):

  • neural-chat:7b (코딩)
  • mistral:latest (범용)
  • gemma2:9b (안정)

전문 작업 (13B):

  • codellama:13b (코딩 전문)
  • orca2:13b (추론 강화)

대형 작업 (20B-34B):

  • gpt-oss:20b (창의적 작업)
  • codellama:34b (대규모 코딩)

피하기:

  • deepseek-r1:14b (메모리 부족)
  • qwen3:30b (불안정)

동시 접속 가이드

시간대예상 사용자권장 모델메모리 사용
일반10-20명7B-13B~30-40GB
피크30-50명7B-9B~40-60GB
대형 작업5-10명34B~60-70GB

모니터링 알림 설정

권장 임계값:

  • GPU 메모리 > 90%: 경고
  • GPU 온도 > 80°C: 경고
  • GPU 온도 > 85°C: 위험

🎯 결론

원격 GPU 서버를 활용한 LLM 챗봇 서비스를 성공적으로 구축했습니다:

✅ 달성한 목표:

  • 50명 동시 접속 처리 (목표의 10배)
  • 경량 모델 0.4초 응답 (초고속)
  • 자동 메모리 관리 (안정적)
  • 실시간 모니터링 (Grafana)

✅ 핵심 교훈:

  • 단일 인스턴스도 충분히 강력
  • Ollama 자동 관리가 우수
  • 모델 크기와 메모리 trade-off 중요

🚀 다음 단계:

  • Grafana 알림 설정
  • 사용자 가이드 작성
  • 더 많은 모델 테스트

기술 스택:

  • Ollama (LLM 서버)
  • Open WebUI (웹 인터페이스)
  • Nginx (로드밸런서)
  • Prometheus + Grafana (모니터링)
  • Docker Compose (배포)