본문 바로가기
AI

GPU EC2에 Ollama + Open WebUI로 사내 로컬 LLM API 서버 구축하기 (OpenAI 호환 엔드포인트)

냉장고를사다줘·2026년 6월 23일·조회 6

요약부터 말씀드릴게요. Ollama를 GPU 서버에 설치하면 그 자체로 11434 포트에 OpenAI 호환 API(/v1/chat/completions)가 열립니다. 여기에 Open WebUI를 컨테이너로 붙이면 사내 사용자용 ChatGPT 같은 웹 화면까지 한 번에 끝납니다. 즉 외부 API 비용 없이, 사내망 안에서만 도는 LLM 챗봇 + API 서버를 구성하는 방식입니다. 아래에서 설치부터 OpenAI SDK로 붙이는 코드까지 순서대로 보겠습니다.

1. 개요: 무엇을 어떻게 붙이나

구성은 단순합니다. 세 덩어리예요.

  • Ollama: 모델을 받아서 추론을 돌리는 엔진. 설치하면 11434 포트에 자체 API와 OpenAI 호환 API가 같이 열립니다.
  • Open WebUI: 사용자에게 보여줄 웹 채팅 화면. Docker로 띄우고 Ollama에 연결합니다. 기본 포트 3000(컨테이너 내부는 8080).
  • OpenAI 호환 엔드포인트: 기존에 OpenAI SDK로 짜둔 코드가 있다면 base_url만 사내 서버로 바꿔 그대로 재사용합니다.

제가 직접 구성해보면 사람들이 가장 많이 막히는 지점이 두 곳입니다. 하나는 Ollama가 기본적으로 127.0.0.1에만 바인딩돼서 외부에서 안 붙는 것, 다른 하나는 GPU가 컨테이너 안으로 안 넘어가는 것. 이 두 가지를 중심으로 짚겠습니다.

권장 환경: AWS라면 g5.xlarge(NVIDIA A10G, 24GB) 정도면 7B~14B 모델이 편하게 돌아갑니다. 더 작게 가려면 g4dn.xlarge(T4, 16GB)로 7B 양자화 모델까지는 됩니다. OS는 Ubuntu 22.04 기준으로 설명할게요.

2. 사전 준비: NVIDIA 드라이버 확인

GPU EC2를 띄웠으면 드라이버부터 확인합니다. Deep Learning AMI를 골랐다면 이미 깔려 있고, 순정 Ubuntu라면 직접 설치해야 해요. 먼저 인식되는지 봅니다.

$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 535.183.01   Driver Version: 535.183.01   CUDA Version: 12.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
|   0  NVIDIA A10G          Off  | 00000000:00:1E.0 Off |                    0 |
|  0%   28C    P8    15W / 300W  |      0MiB / 23028MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

여기서 command not found가 나오면 드라이버가 없는 겁니다. Ubuntu에서는 아래로 설치하고 재부팅하면 됩니다.

$ sudo apt update
$ sudo ubuntu-drivers install
$ sudo reboot

참고로 Ollama만 호스트에서 직접 돌릴 거라면 NVIDIA Container Toolkit은 없어도 됩니다. 하지만 Open WebUI나 Ollama를 컨테이너로 돌리면서 GPU를 쓰려면 toolkit이 필요해요. 이 글은 Ollama는 호스트에 직접, Open WebUI는 컨테이너로 올리는 방식이라 toolkit 없이도 GPU를 다 씁니다.

3. Ollama 설치와 모델 받기

리눅스 설치는 공식 스크립트 한 줄입니다. 이 스크립트가 systemd 서비스(ollama.service)까지 자동 등록하고 GPU를 감지해 줍니다.

$ curl -fsSL https://ollama.com/install.sh | sh
>>> Installing ollama to /usr/local
>>> Downloading Linux amd64 bundle
>>> Creating ollama user...
>>> Enabling and starting ollama service...
>>> NVIDIA GPU installed.

마지막 줄에 NVIDIA GPU installed.가 떠야 정상입니다. 서비스 상태를 확인해 봅니다.

$ systemctl status ollama
● ollama.service - Ollama Service
     Loaded: loaded (/etc/systemd/system/ollama.service; enabled; preset: enabled)
     Active: active (running)

이제 모델을 받습니다. 한국어가 섞인 사내 용도면 qwen2.5 계열이 무난하고, 영어 위주 코딩이면 llama3.1도 좋습니다. 일단 받아서 바로 대화까지 해보겠습니다.

$ ollama pull qwen2.5:7b
pulling manifest
pulling 2bada8a74506... 100%   4.7 GB
verifying sha256 digest
writing manifest
success

$ ollama run qwen2.5:7b "한 문장으로 자기소개 해줘"
저는 로컬에서 동작하는 한국어 지원 언어 모델입니다.

여기까지 되면 추론 엔진은 끝났습니다. 받아둔 모델 목록은 ollama list로 확인합니다.

4. 외부에서 붙게 만들기 (OLLAMA_HOST 바인딩)

여기서 한 번 걸립니다. 설치 직후 Ollama는 127.0.0.1:11434에만 바인딩돼서, 같은 서버 안에서만 접근됩니다. 다른 PC나 Open WebUI 컨테이너에서 호출하려고 하면 이런 식으로 거부당해요.

$ curl http://<서버IP>:11434/api/tags
curl: (7) Failed to connect to <서버IP> port 11434: Connection refused

원인은 명확합니다. systemd로 뜬 서비스라 셸에서 export OLLAMA_HOST 해봐야 안 먹습니다. systemd 드롭인으로 환경변수를 박아야 해요. 공식 FAQ가 안내하는 방식 그대로입니다.

$ sudo systemctl edit ollama.service

편집기가 열리면 아래 블록을 넣고 저장합니다.

[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"

그리고 리로드 후 재시작합니다.

$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama
$ ss -tlnp | grep 11434
LISTEN 0  4096  *:11434  *:*

*:11434로 바뀌었으면 모든 인터페이스에 열린 겁니다. 중요한 보안 주의: 이 상태면 Ollama API에는 인증이 없습니다. 절대 인터넷에 직접 노출하지 마세요. AWS라면 보안 그룹에서 11434는 사내 VPC CIDR나 특정 IP에서만 허용하고, 외부 접근은 뒤에서 다룰 Open WebUI(또는 Nginx + 인증) 쪽으로만 받는 걸 권장합니다.

5. OpenAI 호환 엔드포인트 확인

Ollama는 별도 설정 없이 OpenAI 호환 API를 같이 제공합니다. 경로 앞에 /v1/을 붙이면 됩니다. 지원 엔드포인트는 이렇습니다.

  • /v1/chat/completions - 채팅
  • /v1/completions - 텍스트 완성
  • /v1/embeddings - 임베딩
  • /v1/models - 모델 목록

curl로 OpenAI 포맷 그대로 때려봅니다. Authorization 헤더의 API 키는 필요하지만 값은 무시됩니다(아무 값이나 넣으면 됩니다, 관례상 ollama).

$ curl http://localhost:11434/v1/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ollama" \
    -d '{
      "model": "qwen2.5:7b",
      "messages": [{"role": "user", "content": "Hello!"}]
    }'
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "choices": [{"index":0,"message":{"role":"assistant","content":"Hello! How can I help you today?"}}],
  "model": "qwen2.5:7b"
}

응답 JSON 구조가 OpenAI와 동일하죠. 그래서 기존 코드 재사용이 됩니다.

6. Open WebUI 붙이기 (웹 채팅 화면)

이제 사용자용 화면을 올립니다. Docker로 띄우는 게 제일 깔끔합니다. Docker가 없다면 먼저 설치하세요.

$ curl -fsSL https://get.docker.com | sh

Open WebUI는 공식 이미지를 그대로 받아 실행합니다. Ollama가 같은 호스트에 떠 있으니 OLLAMA_BASE_URL로 연결해 줍니다.

$ sudo docker run -d -p 3000:8080 \
    -e OLLAMA_BASE_URL=http://172.17.0.1:11434 \
    -v open-webui:/app/backend/data \
    --name open-webui \
    --restart always \
    ghcr.io/open-webui/open-webui:main

여기 함정이 있습니다. 컨테이너 안에서 localhost는 컨테이너 자기 자신이라, OLLAMA_BASE_URL=http://localhost:11434로 넣으면 Ollama를 못 찾습니다. 그래서 4단계에서 Ollama를 0.0.0.0에 바인딩한 거고, 여기서는 도커 브리지 게이트웨이 주소 172.17.0.1로 호스트를 가리킵니다. (호스트 사설 IP를 넣어도 됩니다.)

참고로 GPU를 함께 쓰는 Ollama 번들 이미지(:ollama 태그)도 있는데, 그건 --gpus=all과 Container Toolkit이 필요합니다. 저는 Ollama를 호스트에 직접 두는 이 방식을 더 권장합니다. GPU 설정이 단순하고, 모델 데이터도 호스트의 /usr/share/ollama/.ollama에 그대로 남아 관리가 쉽거든요.

브라우저에서 http://<서버IP>:3000으로 접속하면 첫 화면이 뜹니다. 처음 가입하는 계정이 자동으로 관리자가 되니, 사내 배포 전에 관리자 계정을 먼저 만들어 두세요. 로그인하면 우측 상단 모델 선택에 qwen2.5:7b가 잡혀 있고, 바로 대화가 됩니다.

7. 애플리케이션에서 OpenAI SDK로 붙이기

가장 실용적인 부분입니다. 기존 OpenAI 코드가 있으면 base_urlapi_key만 바꾸면 끝입니다. Python 예시예요.

from openai import OpenAI

client = OpenAI(
    base_url="http://<서버IP>:11434/v1",
    api_key="ollama",  # 값은 무시되지만 비워두면 SDK가 에러를 냅니다
)

resp = client.chat.completions.create(
    model="qwen2.5:7b",
    messages=[{"role": "user", "content": "사내 위키 요약 규칙을 알려줘"}],
)
print(resp.choices[0].message.content)

스트리밍, 임베딩, 함수 호출(tool calls)도 OpenAI SDK 그대로 동작합니다. 다만 모든 모델이 tool calls를 지원하진 않으니, 함수 호출을 쓸 거면 llama3.1이나 qwen2.5처럼 tool을 지원하는 모델인지 모델 카드를 확인하세요.

운영 팁 하나. 외부 노출이 필요하면 Ollama의 11434를 직접 열지 말고, 앞단에 Nginx를 두고 Basic Auth나 헤더 토큰 검사를 거는 방식을 권장합니다. Ollama API에는 자체 인증이 없기 때문입니다.

8. 확인 체크리스트

  • nvidia-smi로 GPU 인식 확인
  • systemctl status ollama active 확인
  • ss -tlnp | grep 11434*:11434인지 확인(외부 접근용)
  • curl .../v1/models로 OpenAI 호환 엔드포인트 응답 확인
  • http://<서버IP>:3000 Open WebUI 접속 및 모델 선택 확인
  • 추론 중 nvidia-smi로 GPU 사용률이 올라가는지 확인(안 오르면 CPU로 도는 중)

마지막 항목이 의외로 중요합니다. 모델이 GPU 메모리에 안 올라가고 CPU로 떨어지면 응답이 체감상 몇 배 느려집니다. 모델 로드 직후 nvidia-smi의 메모리 사용량이 올라오는지 한 번 봐주세요.

버전 번호와 출력 일부는 설치 시점이나 저장소 상태에 따라 달라질 수 있습니다.

자주 묻는 질문

Ollama API 키는 꼭 필요한가요?

OpenAI 호환 엔드포인트에서는 Authorization 헤더가 형식상 필요하지만 값은 무시됩니다. 관례적으로 'ollama'를 넣습니다. 단 자체 인증이 없으므로 외부 노출 시에는 Nginx 등 앞단에서 별도 인증을 걸어야 합니다.

GPU 없이 CPU만으로도 돌아가나요?

돌아갑니다. Ollama는 GPU가 없으면 자동으로 CPU 추론으로 떨어집니다. 다만 7B 모델 기준 응답 속도가 크게 느려지므로, 사내 다수 사용자를 받을 거면 GPU 서버를 권장합니다.

Open WebUI에서 Ollama 모델이 안 보입니다.

대부분 OLLAMA_BASE_URL 문제입니다. 컨테이너 안 localhost는 컨테이너 자신을 가리키므로, Ollama를 0.0.0.0:11434에 바인딩한 뒤 도커 게이트웨이(172.17.0.1)나 호스트 사설 IP로 지정해야 합니다.

기존 OpenAI 코드를 그대로 쓸 수 있나요?

네. base_url을 http://서버IP:11434/v1로, api_key를 아무 값으로 바꾸고 model을 Ollama에 받아둔 모델명으로 지정하면 됩니다. 스트리밍과 임베딩도 동일하게 동작합니다.

어떤 인스턴스 타입이 적당한가요?

7B~14B 모델 기준 AWS g5.xlarge(A10G 24GB)가 편합니다. 7B 양자화 모델까지만 쓴다면 g4dn.xlarge(T4 16GB)로도 가능합니다. 모델 크기가 GPU 메모리를 넘으면 CPU로 떨어지니 VRAM을 기준으로 고르세요.

관련 글

댓글 0

로그인 후 댓글을 남길 수 있습니다.

아직 댓글이 없습니다.