연산 장비와 공개 서비스 장비를 나누는 하이브리드 구조

맥에서 AI를 돌리고 IDC 서버로 웹서비스를 하는 이유의 핵심 흐름도
그림. IDC는 공개 접점을, 맥은 모델 연산을 맡아 역할과 장애 영역을 나눈다.

두 장비의 역할

AI 서비스는 하나의 프로그램처럼 보이지만 실제로는 성격이 다른 두 문제가 섞여 있다.

첫째는 모델을 메모리에 올리고 추론하거나 학습하는 연산 문제다. 큰 메모리, GPU 또는 가속기, 모델 파일, 실험 데이터가 필요하다. 둘째는 사용자의 요청을 안정적으로 받는 웹서비스 문제다. 고정된 도메인, HTTPS 인증서, 24시간 네트워크, 접근 로그와 방화벽이 필요하다.

이 둘을 다음처럼 나눌 수 있다.

사용자
  ↓ HTTPS
IDC 서버: DNS, TLS, Nginx, 웹 UI, 인증, 요청 제어
  ↓ 암호화된 전용 연결
맥: 모델 로딩, AI 추론, 학습, 이미지·보드 분석

사용자는 IDC 서버만 본다. IDC가 요청을 검사한 뒤 필요한 AI 작업만 맥으로 보내고 결과를 받아 응답한다.

맥이 AI 연산에 유리한 이유

이미 확보한 연산 자원을 활용한다

Apple Silicon 맥은 CPU, GPU, Neural Engine이 통합 메모리를 함께 사용한다. 모델 전체를 CPU 메모리와 GPU 메모리 사이에 반복 복사하지 않고, 장비의 통합 메모리 안에서 처리할 수 있다. MLX, PyTorch MPS, llama.cpp, Ollama처럼 맥을 지원하는 도구를 이용하면 로컬 추론과 일부 학습을 수행할 수 있다.

항상 클라우드 GPU보다 빠르다는 뜻은 아니다. CUDA 전용 라이브러리와 대규모 병렬 학습은 NVIDIA GPU 서버가 더 적합한 경우가 많다. 그러나 이미 가진 맥에서 모델이 요구하는 속도와 메모리를 충족한다면 별도 GPU 임대 비용 없이 서비스를 시작할 수 있다.

모델과 데이터가 로컬에 있다

모델 가중치, LoRA 어댑터, 실험 데이터, 이미지 데이터셋은 크다. 수십 GB의 모델을 IDC에 매번 복사하면 저장 공간과 전송 시간이 든다. 실험이 잦을수록 배포 대상도 계속 바뀐다.

맥에 모델과 학습 환경을 유지하면 개발과 추론이 같은 환경에서 이어진다. 개인 데이터나 외부 반출을 피해야 하는 데이터도 로컬 경계 안에 둘 수 있다. 다만 웹 요청에 개인정보가 들어오면 그 데이터가 IDC와 맥 사이를 지나므로 전송 암호화, 로그 마스킹, 보관 정책은 별도로 필요하다.

개발과 관찰이 빠르다

로컬 화면에서 모델 로그, GPU 사용량, 결과 이미지를 바로 볼 수 있다. 새 모델과 프롬프트를 시험하고 문제가 생기면 서비스를 외부에 노출하지 않은 채 확인할 수 있다. 웹서비스는 안정된 API 계약만 유지하고 모델 내부는 교체할 수 있다.

IDC 서버가 웹서비스에 유리한 이유

공개 주소와 안정된 네트워크

가정이나 사무실의 맥은 공유기 NAT 뒤에 있을 수 있고, 공인 주소가 바뀌거나 통신사 정책 때문에 외부 포트 개방이 어려울 수 있다. 절전, 재부팅, Wi-Fi 전환도 공개 서비스에 불리하다.

IDC 서버는 일반적으로 고정된 공인 주소와 계속 켜진 유선 네트워크를 제공한다. DNS A/AAAA 레코드를 IDC로 향하게 하고 80·443 포트만 공개할 수 있다. 사용자는 맥의 현재 위치나 내부 주소를 알 필요가 없다.

TLS와 도메인을 한곳에서 관리한다

Nginx가 도메인별 요청을 받고 HTTPS 인증서를 적용한다. 여러 AI 서비스가 있어도 하나의 IDC에서 서브도메인이나 경로로 나눌 수 있다.

ai.example.com      → AI 웹 UI
api.example.com     → API
board.example.com   → 게시판

인증서 갱신, HTTP에서 HTTPS 전환, 보안 헤더, 업로드 크기, timeout과 접근 로그를 공개 진입점에서 통일한다.

맥을 인터넷에 직접 노출하지 않는다

맥의 AI 서버는 `127.0.0.1` 또는 전용 VPN 주소에서만 수신하게 할 수 있다. 외부 사용자는 IDC까지만 연결한다. 맥의 SSH, 모델 서버, 개발 포트를 인터넷에 직접 열지 않는다.

이 분리는 공격 표면을 줄이지만 IDC가 안전을 자동 보장하지는 않는다. IDC의 Nginx와 웹 애플리케이션에 인증, 입력 검증, 요청 제한, 보안 업데이트가 필요하다. 터널에 들어온 요청도 신뢰하지 말고 API에서 검증한다.

연결 방식 1: WireGuard

IDC와 맥을 WireGuard 피어로 연결하면 두 장비 사이에 암호화된 사설 IP 네트워크가 생긴다.

IDC VPN 주소 ───── WireGuard UDP ───── 맥 VPN 주소
Nginx proxy_pass                        AI API

IDC의 Nginx는 맥의 WireGuard 주소와 AI 포트로 요청을 전달한다.

location /api/ai/ {
    proxy_pass http://MAC_WIREGUARD_ADDRESS:9000/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_connect_timeout 3s;
    proxy_read_timeout 120s;
}

실제 주소는 공개 문서와 저장소에서 가리고 운영 설정에만 둔다. 방화벽은 IDC 피어에서 오는 AI API 포트만 허용한다.

WireGuard 방식의 장점은 여러 포트를 자연스러운 사설망처럼 연결할 수 있다는 점이다. AI API, 상태 확인, 메트릭처럼 서비스가 늘어나도 각 포트의 접근 정책을 방화벽으로 관리할 수 있다.

단점은 UDP 포트 도달성과 양쪽 라우팅·AllowedIPs·방화벽을 구성해야 한다는 점이다. 맥이 NAT 뒤에서도 먼저 서버에 연결하고 keepalive를 보내면 연결을 유지할 수 있다.

연결 방식 2: 리버스 SSH 터널

맥에서 IDC로 SSH 접속할 수 있다면, 맥이 먼저 연결을 열고 IDC의 로컬 포트를 맥의 AI 서버로 되돌릴 수 있다.

ssh -N -T \
  -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=30 \
  -o ServerAliveCountMax=3 \
  -R 127.0.0.1:19000:127.0.0.1:9000 \
  tunnel@idc.example.com

흐름은 다음과 같다.

Nginx → IDC 127.0.0.1:19000
          ↓ 리버스 SSH 터널
        맥 127.0.0.1:9000 → AI 모델

Nginx는 IDC 로컬 포트로 전달한다.

location /api/ai/ {
    proxy_pass http://127.0.0.1:19000/;
}

맥이 NAT 뒤에 있어도 맥에서 IDC 방향의 SSH 연결만 가능하면 된다. IDC의 터널 포트는 `127.0.0.1`에 묶어 인터넷에서 직접 접속하지 못하게 한다.

리버스 SSH 터널은 서비스 한두 개를 빠르게 연결하기 좋다. 서비스가 많고 장비 간 양방향 통신이 필요하면 WireGuard가 구조를 이해하기 쉽다. 두 방식을 동시에 같은 경로에 겹치면 장애 원인을 찾기 어려우므로 주 연결 방식과 비상 방식을 명확히 구분한다.

웹 요청의 실제 흐름

이미지 분석 요청을 예로 들면 다음 순서로 처리할 수 있다.

  1. 사용자가 IDC의 HTTPS API로 이미지를 보낸다.
  2. IDC는 인증, 파일 크기, 형식, 요청 횟수를 검사한다.
  3. 작업 ID를 만들고 큐에 넣거나 맥 AI API로 전달한다.
  4. 맥은 모델을 실행하고 결과를 반환한다.
  5. IDC는 결과를 검증하고 필요한 정보만 사용자에게 응답한다.
  6. 원본과 결과의 보관 기간이 끝나면 삭제한다.

짧은 추론은 HTTP 요청을 유지한 채 기다릴 수 있다. 수십 초에서 수분이 걸리는 학습이나 생성 작업은 작업 큐가 낫다.

POST /jobs → 202 Accepted + job_id
GET /jobs/{id} → queued | running | completed | failed

사용자 연결이 끊겨도 작업이 사라지지 않고, 재시도와 동시 실행 수를 관리할 수 있다.

왜 모델 서버를 IDC에 직접 두지 않는가

IDC 서버에 충분한 GPU와 메모리가 있다면 직접 두는 편이 네트워크 지연과 장애 지점을 줄인다. 모든 경우에 맥 분리가 최선은 아니다.

맥과 IDC를 나누는 이유는 보통 다음 조건이 함께 있을 때다.

  • IDC는 CPU와 메모리는 충분하지만 AI 가속기가 없다.
  • 이미 보유한 맥이 목표 모델을 실행할 수 있다.
  • 모델과 데이터가 크거나 자주 바뀐다.
  • 공개 네트워크와 인증서 운영은 IDC가 안정적이다.
  • 초기 비용과 GPU 임대 비용을 줄이고 싶다.

요청량이 커지고 24시간 낮은 지연과 고가용성이 필요해지면 GPU 서버나 관리형 추론 서비스로 옮기는 것이 맞을 수 있다. 하이브리드 구조는 비용과 기존 자원을 활용하는 선택이지 절대적인 정답이 아니다.

이 구조의 비용

맥이 꺼지면 AI 기능이 멈춘다

웹페이지 자체는 IDC에서 열려도 AI 요청은 실패한다. IDC는 이를 502 오류로 그대로 노출하지 말고, AI 서비스가 일시적으로 준비되지 않았다는 응답을 제공해야 한다.

상태 확인은 단순히 포트가 열렸는지만 보지 않는다. 모델이 로드되었고 작은 추론을 받을 수 있는지 가벼운 health endpoint로 확인한다.

GET /health/live   프로세스가 살아 있는가
GET /health/ready  모델이 준비되어 요청을 받을 수 있는가

네트워크 지연과 대역폭이 추가된다

요청과 결과가 IDC와 맥 사이를 한 번 더 이동한다. 큰 이미지나 영상은 지연과 업로드 대역폭을 차지한다. IDC에서 파일 크기를 제한하고 압축 형식을 유지하며, 같은 모델 입력을 반복 전송하지 않도록 캐시를 검토한다.

장애 지점이 늘어난다

DNS, Nginx, 웹 앱, VPN 또는 SSH 터널, 맥 AI 프로세스, 모델이 모두 정상이어야 한다. 상태를 계층별로 분리해 감시해야 한다.

공개 HTTPS 응답
IDC → 터널 포트 연결
터널 handshake 또는 SSH 프로세스
맥 AI readiness
실제 추론 성공률과 처리 시간

맥의 절전과 재시작

데스크톱 맥도 절전되면 네트워크와 추론이 멈출 수 있다. 서비스 장비로 쓴다면 전원 복구 후 자동 시작, 화면 잠금과 시스템 절전의 차이, 운영체제 업데이트 재부팅 정책을 정한다.

macOS에서는 launchd가 AI 서버와 터널 프로세스를 관리할 수 있다. 프로세스가 끝났을 때 재시작하고 표준 출력과 오류를 파일 또는 로그 수집기로 보낸다. 셸에서 `nohup ... &`만 실행하면 재부팅 복구와 상태 관리가 어렵다.

모델 서버를 다시 시작할 때 모델 로딩 시간이 길 수 있다. 프로세스가 떴다는 이유만으로 readiness를 성공시키지 않고 로드 완료 뒤 준비 상태를 바꾼다.

동시 요청과 자원 제한

로컬에서 한 번 잘 실행된 모델도 여러 웹 요청이 동시에 들어오면 메모리가 부족해질 수 있다. IDC에서 동시 작업 수와 대기열 길이를 제한한다.

최대 동시 추론 수
최대 대기 작업 수
요청당 업로드 크기
사용자별 요청 속도
작업 timeout

맥의 AI 워커가 한 번에 하나만 처리해야 하면 큐에서 하나씩 꺼낸다. 요청마다 모델을 새로 로드하지 않고 프로세스가 모델을 메모리에 유지한다. 메모리 누수와 장시간 작업을 감시해 안전한 시점에 워커를 재시작한다.

timeout을 계층별로 맞추기

AI 추론이 60초 걸릴 수 있는데 Nginx가 30초에 연결을 끊으면 사용자는 실패를 받고 맥은 필요 없는 계산을 계속할 수 있다.

다음 시간의 관계를 의도적으로 정한다.

클라이언트 timeout
Nginx proxy_read_timeout
IDC 웹 앱 timeout
맥 AI 작업 timeout
큐 작업 만료 시간

무조건 모두 크게 만들면 고장 난 요청이 자원을 오래 점유한다. 정상 처리 시간의 분포를 측정하고, 긴 작업은 비동기 작업 API로 분리한다.

보안 경계

IDC가 공개 진입점이므로 다음 검사를 AI 서버 앞에서 수행한다.

  • 사용자 인증과 권한
  • 파일 형식과 실제 내용 검사
  • 업로드 크기와 요청 속도 제한
  • 프롬프트와 입력 길이 제한
  • 작업별 timeout과 동시 실행 수
  • 로그의 개인정보·토큰 마스킹

맥의 AI API에도 별도 인증 또는 피어 방화벽을 둔다. VPN에 들어왔다는 사실만으로 모든 요청을 신뢰하지 않는다. IDC의 특정 VPN 주소에서 특정 포트로 오는 연결만 허용하고, 가능하면 애플리케이션 토큰이나 상호 인증을 추가한다.

모델 출력은 신뢰할 수 없는 데이터다. 출력 문자열을 셸 명령, SQL, HTML로 검증 없이 실행하거나 삽입하지 않는다. 웹 페이지에 표시할 때는 이스케이프하고, 도구 호출은 허용 목록과 스키마 검증을 거친다.

데이터와 로그

AI 요청이 어느 장비에 남는지 먼저 정한다.

데이터권장 원칙
원본 업로드필요한 기간만 보관하고 자동 삭제한다.
모델 입력민감값을 제거하고 디버깅 목적을 정한다.
모델 출력사용자별 접근 권한과 보관 기간을 적용한다.
접근 로그요청 ID, 상태, 처리 시간 위주로 남긴다.
모델 로그프롬프트 전체와 토큰을 기본으로 기록하지 않는다.

IDC와 맥에 같은 원본이 각각 남으면 삭제 요청을 두 곳에 적용해야 한다. 한쪽을 원본 저장 위치로 정하고 다른 쪽은 처리 후 즉시 지우는 정책이 단순하다.

배포를 분리하는 방법

웹 코드와 모델 코드는 배포 주기가 다르다.

IDC 배포: Nginx, 웹 UI, 인증, API 계약
맥 배포: 모델 버전, 추론 코드, LoRA, 런타임

API에 버전을 둔다. IDC가 기대하는 요청·응답 스키마와 맥 모델 서버의 버전이 맞지 않으면 배포를 중단한다. 새 모델을 준비 상태로 올린 뒤 IDC 트래픽을 전환하고, 문제가 있으면 이전 모델로 되돌릴 수 있게 한다.

모델 파일을 Git에 넣지 않고 모델 저장소나 권한이 제한된 디렉터리에서 관리한다. 어떤 코드 버전이 어떤 모델과 설정을 사용했는지 메타데이터를 남긴다.

관찰할 지표

최소한 다음 값은 IDC와 맥에서 함께 본다.

  • 공개 요청 수, 성공률, 4xx와 5xx 비율
  • IDC에서 맥까지의 연결 실패율
  • 큐 길이와 대기 시간
  • 추론 시간의 중앙값과 상위 백분위
  • 맥의 메모리, GPU 사용량, 온도와 디스크
  • 모델 로드 상태와 재시작 횟수
  • 터널 재연결 횟수와 마지막 정상 통신 시각

요청 ID를 IDC에서 만들고 맥까지 전달하면 한 요청이 어디서 지연되었는지 로그를 연결할 수 있다. 사용자 입력 전체를 ID 대신 로그에 복사하지 않는다.

장애 시 사용자 경험

맥 또는 터널이 끊겼을 때 IDC의 웹 전체가 함께 죽을 필요는 없다. 정적 페이지, 게시판, 계정 기능은 계속 제공하고 AI 버튼만 일시 중지할 수 있다.

정상      요청을 큐에 넣고 결과를 제공한다.
과부하    429 또는 대기 안내와 재시도 시간을 제공한다.
AI 중단   503과 명확한 일시 장애 메시지를 제공한다.
입력 오류 400으로 어떤 조건이 잘못됐는지 알려 준다.

자동 재시도는 같은 생성 작업을 중복 실행할 수 있다. 작업 ID와 idempotency key를 사용해 동일 요청이 한 번만 실행되게 한다.

언제 한 장비로 합칠 것인가

다음 조건이면 GPU가 있는 데이터센터나 클라우드 서버로 통합하는 편이 낫다.

  • 맥의 전원과 네트워크를 24시간 보장할 수 없다.
  • 요청량이 맥 한 대의 동시 처리 능력을 넘는다.
  • IDC와 맥 사이 전송 지연이 서비스 목표를 넘는다.
  • 여러 모델 워커의 자동 확장이 필요하다.
  • 규정상 데이터가 관리되는 데이터센터 밖으로 이동하면 안 된다.
  • 운영 인력이 두 장소의 장애를 관리하기 어렵다.

반대로 개인 프로젝트, 연구 결과 공개, 낮거나 중간 수준의 요청량, 자주 바뀌는 로컬 모델에는 맥과 IDC를 나누는 구조가 비용과 개발 속도의 균형이 될 수 있다.

운영 점검 목록

  • 맥의 AI 포트는 인터넷에 직접 공개하지 않는다.
  • IDC와 맥 사이를 WireGuard 또는 SSH 터널로 암호화한다.
  • 터널 수신 포트는 필요한 인터페이스에만 바인딩한다.
  • 전용 키와 최소 권한 계정을 사용한다.
  • 양쪽 프로세스를 launchd 또는 systemd로 자동 복구한다.
  • AI readiness와 실제 추론 성공 여부를 감시한다.
  • Nginx, 웹 앱, AI 작업 timeout을 함께 설계한다.
  • 동시 실행 수와 큐 길이를 제한한다.
  • 개인정보와 비밀값을 로그에 남기지 않는다.
  • 맥 중단 시 IDC가 503으로 안전하게 실패하도록 한다.
  • 모델과 웹 API의 버전을 맞추고 롤백 경로를 둔다.

맥에서 AI를 돌리고 IDC에서 웹서비스를 하는 핵심 이유는 맥이 무조건 더 좋은 서버여서가 아니다. 이미 가진 AI 연산 자원과 로컬 데이터를 활용하면서, 공개 인터넷 서비스에 필요한 고정 주소와 HTTPS 운영은 IDC에 맡길 수 있기 때문이다. 이 구조가 효과적이려면 터널 하나만 연결하는 데서 끝내지 않고, 장애·보안·timeout·큐·데이터 수명을 두 장비에 걸쳐 설계해야 한다.