로컬 AI 서버 (Mac mini M4 Pro 64GB)

이 저장소는 Apple Silicon(M4 Pro, RAM 64GB) 환경에서 로컬 AI 모델을 실행해 API 서버로 활용하기 위한 기본 구성과 가이드를 제공합니다.

현재 설치 상태

  • 러너: Ollama 0.11.4 확인됨
  • Ollama 로컬 모델:
    • qwen2.5:1.5b
    • mistral:7b
  • LM Studio 로컬 모델:
    • gemma-3-4b-it

하드웨어 요약 (권장 기준)

  • 칩셋: Apple M4 Pro (Metal/ANE 가속 활용 가능)
  • 메모리: 64GB 통합 메모리
  • 권장 동시성: 13 세션(프롬프트 길이에 따라 조절)

권장 모델 (M4 Pro 64GB)

  • 일반 대화/업무

    • Llama 3.1 8B Instruct: 품질·속도 밸런스 좋음, 긴 문서 요약/대화에 적합
    • Qwen2.5 7B Instruct: 정보 회수/한글 대응 우수, 속도 양호
    • Mistral 7B Instruct: 경량/속도 지향, 기본 품질 안정적
    • Gemma 2 9B IT: 간결한 답변과 대화 품질 균형
  • 코딩 보조

    • Qwen2.5-Coder 7B: 코드 생성/수정/해설에 실용적, 메모리 요구도 낮음
    • DeepSeek-Coder 6.7B 또는 16B(Lite): 코드 품질 강점, 16B는 속도·메모리 여유 필요
  • 초경량

    • Phi-3.5/3.1 Mini(34B): 간단 질의응답/요약, 서버 부하가 낮음
  • 참고: 1432B급도 구동 가능하나(예: Qwen2.5 14B/32B), 긴 컨텍스트/동시성 시 메모리 여유가 적어질 수 있음. 70B급은 64GB 환경에서 가능하더라도 속도·안정성 상 비권장.

설치 (Ollama)

아래 명령으로 권장 모델을 내려받을 수 있습니다. 태그는 상황에 따라 업데이트될 수 있으니 ollama run <model> 시 안내를 확인하세요.

# 일반 대화
ollama pull llama3.1:8b-instruct
ollama pull qwen2.5:7b-instruct
ollama pull mistral:7b
ollama pull gemma2:9b-instruct

# 코딩 보조
ollama pull qwen2.5-coder:7b
ollama pull deepseek-coder:6.7b

# 초경량
ollama pull phi3:mini

이미 설치된 모델 확인:

ollama list

모델 실행(대화형 테스트):

ollama run qwen2.5:7b-instruct

REST API로 바로 쓰기 (Ollama 내장 서버)

Ollama는 기본적으로 http://localhost:11434에서 API를 제공합니다.

# 단발성 텍스트 생성
curl http://localhost:11434/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5:7b-instruct",
    "prompt": "한국어로 이 모델의 장점을 3가지로 요약해줘",
    "stream": false
  }'

# Chat 형식
curl http://localhost:11434/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.1:8b-instruct",
    "messages": [
      {"role": "user", "content": "로컬 LLM 서버 운영 팁을 알려줘"}
    ],
    "stream": false
  }'

TIP: 긴 문서를 다루려면 num_ctx(컨텍스트 길이)와 num_thread를 모델/하드웨어에 맞춰 조정하세요. 과도하게 늘리면 속도와 메모리 사용량이 크게 증가합니다.

포트 정책

  • AI 서버 표준 포트: 26000 이상 사용 권장 (예: 26000)
  • 환경 변수 AI_SERVER_PORT로 조정 가능. 기본값 26000.

개발 서버 실행 스크립트(scripts/dev_server.sh)는 위 정책을 따릅니다.

레포지토리/데이터 정책

  • 커밋 제외: 문서 원본(PDF 등)과 런타임 산출물(추출 텍스트/인덱스)은 저장소에 커밋하지 않습니다.
    • .gitignore: data/, *.pdf 적용됨
  • 재현 방법(로컬에서 데이터 생성):
    • PDF → 텍스트/토큰 산출: scripts/venv_setup.shsource .venv/bin/activatepython scripts/pdf_stats.py
    • 텍스트 임베딩/인덱스 생성: Ollama 실행 후 python scripts/embed_ollama.py
    • 서버 기동: scripts/dev_server.sh (기본 포트 26000)

운영 워크플로(요약)

  • 모델 정책(24/7 + 부스팅)

    • 기본 상시: BASE_MODEL(권장: qwen2.5:7b-instruct 또는 llama3.1:8b-instruct)
    • 필요 시 부스팅: BOOST_MODEL(권장: qwen2.5:14b-instruct)으로 자동/강제 전환
    • 장문은 32k 컨텍스트 + RAG(인덱스 Top-k 주입)로 처리
  • Paperless 연동

    • 문서 처리 완료 시(웹훅/잡) → 본문 텍스트 추출 → /index/upsert로 인덱스 갱신
    • 선택적으로 /paperless/hook에 문서 ID를 통지 후 서버가 Paperless API로 조회하도록 확장 가능
  • 시놀로지 메일/오피스 연동

    • 본문/첨부 텍스트를 /index/upsert로 누적(사전 색인)
    • 사용자 질의는 /chat 호출(use_rag=true, 필요 시 force_boost=true)

API 개요(요약)

  • 헬스: GET /health
  • 검색: POST /search { query, top_k }
  • 챗: POST /chat { messages, use_rag, top_k, force_boost, options }
  • 인덱스 업서트: POST /index/upsert { rows:[{id,text,source}], embed }
  • 인덱스 리로드: POST /index/reload
  • Paperless 훅 자리표시자: POST /paperless/hook

API 개요 (Paperless/시놀로지 연동)

  • 기본 베이스 모델(24/7): BASE_MODEL (기본: qwen2.5:7b-instruct)
  • 온디맨드 부스팅 모델: BOOST_MODEL (기본: qwen2.5:14b-instruct)
  • 임베딩(RAG): EMBEDDING_MODEL (기본: nomic-embed-text), 인덱스 파일 INDEX_PATH (기본: data/index.jsonl)
  • 문서화: http://localhost:26000/docs (FastAPI 자동 문서)

헬스체크

curl -s http://localhost:26000/health

검색(Search, RAG용)

curl -s -X POST http://localhost:26000/search \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "질문 내용",
    "top_k": 5
  }'

채팅(Chat, RAG/부스팅 자동)

curl -s -X POST http://localhost:26000/chat \
  -H 'Content-Type: application/json' \
  -d '{
    "messages": [
      {"role": "user", "content": "문서 내용 기반으로 요약해줘"}
    ],
    "use_rag": true,
    "top_k": 5,
    "force_boost": false,
    "options": {"num_ctx": 32768, "temperature": 0.3}
  }'

필드 설명:

  • use_rag: 인덱스(INDEX_PATH)에서 상위 청크를 검색해 시스템 프롬프트로 주입
  • force_boost: 강제로 부스팅 모델 사용(고난도/장문)
  • options: Ollama 옵션(예: num_ctx, temperature 등)

인덱스 갱신(Upsert)

Paperless/시놀로지에서 추출한 본문 텍스트를 직접 인덱스에 추가합니다.

curl -s -X POST http://localhost:26000/index/upsert \
  -H 'Content-Type: application/json' \
  -d '{
    "rows": [
      {"id": "paperless:123", "text": "문서 본문 텍스트", "source": "paperless"}
    ],
    "embed": true
  }'

인덱스 리로드

curl -s -X POST http://localhost:26000/index/reload

Paperless 훅(Webhook) 자리표시자

curl -s -X POST http://localhost:26000/paperless/hook \
  -H 'Content-Type: application/json' \
  -d '{"document_id": 123, "title": "문서제목", "tags": ["finance"]}'

해당 훅은 문서 도착을 통지받는 용도로 제공됩니다. 실제 본문 텍스트는 Paperless API로 조회해 /index/upsert로 추가하세요.

시놀로지 메일/오피스 연동 가이드(요약)

  • 검색/QA 호출 엔드포인트: http://<AI서버IP>:26000/search, http://<AI서버IP>:26000/chat
  • 권장 흐름:
    • 메일/문서 본문 → /index/upsert로 인덱스 추가(임베딩 생성)
    • 사용자 질의 → /chat 호출(use_rag=true) → 관련 청크 Top-k 주입 후 응답
  • 모델 라우팅:
    • 기본: 베이스 모델(7B/8B)
    • 장문/고난도: force_boost=true 또는 메시지 길이에 따라 자동 부스팅(14B)

환경 변수

  • AI_SERVER_PORT(기본 26000): 서버 포트
  • OLLAMA_HOST(기본 http://localhost:11434): Ollama API 호스트
  • BASE_MODEL(기본 qwen2.5:7b-instruct)
  • BOOST_MODEL(기본 qwen2.5:14b-instruct)
  • EMBEDDING_MODEL(기본 nomic-embed-text)
  • INDEX_PATH(기본 data/index.jsonl)
  • PAPERLESS_BASE_URL, PAPERLESS_TOKEN(선택): Paperless API 연동 시 사용

이 저장소 사용 계획

  1. Ollama API를 감싸는 경량 서버(Express 또는 FastAPI) 추가
  2. 표준화된 엔드포인트(/v1/chat/completions, /v1/completions) 제공
  3. 헬스체크/모델 선택/리밋/로깅 옵션 제공

우선 본 문서로 설치/선택 가이드를 정리했으며, 다음 단계에서 서버 스켈레톤과 샘플 클라이언트를 추가할 예정입니다.

Description
ai 서버
Readme 3.3 MiB
Languages
Python 56.2%
HTML 30.5%
JavaScript 6.7%
CSS 5.9%
Shell 0.7%