Naia
목차
  1. 1동영상 매뉴얼
  2. 2Naia OS 라이브 USB
  3. 3설치
  4. 3.1Naia OS 설치 (ISO)
  5. 3.2리눅스 앱 설치
  6. 4시작하기
  7. 4.1Naia 모델 가격 정책
  8. 4.2Naia-0.9-omni-24g 실시간 멀티모달 모듈
  9. 4.3라이브 데모
  10. 4.4Naia 모델 다운로드
  11. 4.5Naia 모델 상세 이용 (개발)
  12. 4.6Naia 모델 온라인 이용안내 (예정)
  13. 5메인 화면
  14. 6채팅
  15. 6.1개인 라디오 DJ와 행사 소개
  16. 7대화 기록
  17. 8작업 현황
  18. 9스킬 관리
  19. 10채널 연동
  20. 11에이전트
  21. 12시스템 진단
  22. 13워크스페이스
  23. 14브라우저
  24. 15패널 관리
  25. 16음성 대화
  26. 17설정
  27. 18도구 상세
  28. 19Naia 계정
  29. 20문제 해결
  30. 21오픈소스 활용 및 기여

4.5. Naia 모델 상세 이용 (개발)

Naia 모델을 코드에서 직접 쓰는 개발자용 안내입니다. 4.4 Naia 모델 다운로드로 모델을 띄운 뒤, 로컬에서 직접 제공되는 OpenAI 호환 API를 그대로 사용합니다. OpenAI SDK·도구라면 접속 주소(baseURL)만 이 모델로 바꾸면 됩니다.

naia-os(쉘) 전용이 아닙니다 — OpenAI Realtime/Chat/Audio/Embeddings를 쓰는 어떤 코드든 그대로 붙고, 이 모델 위에서 새로운 애플리케이션을 개발·응용할 수 있습니다.

1. 접속 · 인증

  • REST 베이스: http://<host>:8892/v1 (같은 PC면 127.0.0.1)
  • Realtime(WS): ws://<host>:8892/v1/realtime (베이스 ws://<host>:8892 만 줘도 자동으로 /v1/realtime + 기본 model 적용)
  • 연결: 로컬(127.0.0.1)·Tailscale에선 인증 불필요 — 컨테이너가 라이선스로 자체검증합니다. 키 필드가 필요한 클라이언트(OpenAI SDK 등)는 아무 값(naia)을 넣으면 됩니다. 원격 노출 시 §4.4 Tailscale/VPN을 앞단에.

🔑 키는 하나 — 구독 인증키

  • 구독 인증키 — 포털에서 받는 구독 키. 컨테이너 구동(활성화) 시에만 씁니다 (-e NAIA_ACCOUNT_TOKEN=<구독 인증키>). 구독을 확인하고 시한부 라이선스(인증서)를 받는 용도입니다.
  • 연결할 때는 별도 키가 없습니다. 한 번 활성화되면 컨테이너가 인증서로 로컬에서 자체검증하므로, 클라이언트(naia-os·OpenAI SDK)는 URL로 연결만 하면 됩니다 — 같은 PC면 127.0.0.1, 다른 기기면 Tailscale/VPN(§4.4)으로. 연결마다 게이트웨이를 호출하지 않습니다.
  • 아래 예제의 api_key자리만 채우는 값입니다(OpenAI SDK 필수 필드) — 오프라인 컨테이너는 이 값을 검사하지 않으니 "naia" 등 아무 값이나 넣으면 됩니다.

2. 엔드포인트 (OpenAI 호환)

엔드포인트용도
GET /health준비 상태 {"ready":true} (인증 불필요)
GET /v1/models모델 목록
WS /v1/realtime실시간 음성 세션 (VAD·끼어들기·감정)
POST /v1/chat/completions챗 (스트리밍 지원)
POST /v1/audio/speech음성 합성(TTS)
POST /v1/audio/transcriptions음성 인식(STT)
POST /v1/embeddings임베딩

챗 (curl):

curl -s http://127.0.0.1:8892/v1/chat/completions \
  -H "Authorization: Bearer naia" -H "Content-Type: application/json" \
  -d '{"model":"naia-0.9-omni-24g","messages":[{"role":"user","content":"안녕"}],"stream":false}'

OpenAI SDK (Python) — baseURL만 교체:

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8892/v1", api_key="naia")
print(client.chat.completions.create(
    model="naia-0.9-omni-24g",
    messages=[{"role": "user", "content": "안녕"}],
).choices[0].message.content)

3. 실시간 음성 — 연결 플로우 (WS)

4.3 라이브 데모가 쓰는 흐름과 동일합니다. (오프라인은 게이트웨이 대기열·배정 없이 바로 시작.)

  1. 연결ws://<host>:8892 에 접속.

  2. 첫 프레임(인증·언어) — 브라우저 WebSocket은 헤더 불가라 첫 메시지로:

    { "setup": { "apiKey": "naia", "locale": "ko" } }
    
  3. 서버가 session.created 를 보내면 session.update 로 세션 설정:

    {
      "type": "session.update",
      "session": {
        "modalities": ["text", "audio"],
        "input_audio_format": "pcm16",
        "output_audio_format": "pcm16",
        "instructions": "<페르소나(성격) 지시문>",
        "turn_detection": { "type": "server_vad" },
        "input_audio_transcription": { "language": "ko" },
        "ref_audio_url": "<따라할 목소리 샘플 URL (선택)>"
      }
    }
    
  4. 주고받기

    클라이언트 → 서버
    음성 입력{"type":"input_audio_buffer.append","audio":"<base64 PCM16 24kHz>"} (서버 VAD가 말 끝 감지)
    텍스트 입력conversation.item.createresponse.create
    끼어들기response.cancel
    서버 → 클라이언트
    response.audio.deltabase64 PCM16 24kHz 음성 조각
    response.audio_transcript.delta / response.text.delta답변 텍스트(스트리밍)
    conversation.item.input_audio_transcription.completed내 발화 인식 결과
    emotion.updated감정/지문 태그 (§5)
    response.done한 턴 종료

4. 언어 — 30개 언어 (기본 = 자동/글로벌)

모델은 30개 언어를 지원합니다 (Arabic, Burmese, Chinese, Danish, Dutch, English, Finnish, French, German, Greek, Hebrew, Hindi, Indonesian, Italian, Japanese, Khmer, Korean, Lao, Malay, Norwegian, Polish, Portuguese, Russian, Spanish, Swahili, Swedish, Tagalog, Thai, Turkish, Vietnamese).

  • 기본(미지정) = 글로벌/자동 — 사용자가 말한 언어를 인식해 그 언어로 응답합니다(턴마다 자동).
  • 특정 언어로 고정하려면 setup.locale 또는 session.updateinput_audio_transcription.language 에 ISO-639-1 코드(예 ko/en/ja)를 주세요.

5. 출력 형식 (감정·운율 태그)

음성 대화에 맞게 출력 형식이 조정되어 있습니다 — 클라이언트가 알면 더 풍부하게 표현할 수 있습니다.

  • prosody(운율) 태그: 답변 텍스트에 [laughing], [sigh], [breath], [pause], [hesitation] 같은 소문자 영어 대괄호 태그가 감정이 바뀌는 지점에 섞여 나옵니다(발화 운율 표현용). [웃음] 같은 한국어 태그·(웃으며) 괄호 지문·*smiles* 별표는 쓰지 않도록 모델에 지시돼 있습니다. 알려진 어휘: laughing/laugh/laughter/chuckle/giggle · sigh/exhale · breath/inhale · pause · hesitation · gasp/cough/sneeze/yawn/sniff/hum · cry/sob/moan/whisper/shout/cheer (그 외 태그도 그대로 전달).
  • 태그가 나올 때마다 서버가 emotion.updated 이벤트를 1:1로 보냅니다 (state == 태그명, 소문자):
    { "type": "emotion.updated", "state": "laughing", "tag": "[laughing]", "known": true }
    
  • TTS path 는 태그를 보존한 채 음성 합성 단계로 보내 발화 운율에 반영하고, chat text.delta 는 태그를 제거한 깨끗한 텍스트로 보냅니다. (출력에 이모지·마크다운·괄호 자기서술은 들어가지 않습니다.)
  • 클라이언트 매핑 (naia-os 참고 구현): emotion.updated.state(운율 태그)를 아바타 표정으로 매핑합니다 — laughing/chuckle/giggle/cheer → happy, sigh/exhale/cry/sob → sad, gasp → surprised, shout → angry, hesitation → think. breath·pause 같은 비감정 운율은 표정을 바꾸지 않습니다(직전 표정 유지 — 매 호흡마다 neutral 로 깜빡이지 않게).
  • 견고한 처리 권장: LLM 출력은 항상 정확하지 않습니다. emotion.updated우선으로 쓰되, 누락 시 transcript 자체에서 태그(대문자 [HAPPY] / 소문자 운율 태그)나 새어 나온 지문 ((smiles)·*sigh*)을 자동으로 잡아 표정에 반영하고, 단서가 없으면 표정을 유지하는 것이 좋습니다 (참고: naia-os shell/src/lib/vrm/expression.tsextractExpression).

6. 대화 모델 바꾸기 · 새 버전 올리기 (운영)

명령줄로 직접 바꾸는 상세 안내입니다. 개인 구독자도 그대로 쓸 수 있고(키 불필요), 공유·키오스크 운영을 위한 잠금 옵션도 포함합니다. 쉬운 요약4.4 오프라인에 있습니다.

6.1 대화 모델 바꾸기 (0.91부터)

컨테이너는 그대로 둔 채 대화를 맡는 모델만 실행 중에 바꿉니다. 목소리(말하기·듣기)와 워터마크, 구독 인증은 그대로 유지됩니다.

먼저 알아둘 세 가지:

  1. 기본 채팅 모델은 내장 오픈 LLM입니다. 바꿨다가 언제든 기본으로 되돌릴 수 있습니다.
  2. 새로 올릴 모델은 GGUF 형식이어야 합니다. 그리고 음성 기능이 메모리를 약 10GB 쓰고 있어, 대화 모델은 대략 14GB까지 올라갑니다. 더 큰 모델은 거절되고, 혹시 올리다 실패해도 쓰던 모델로 자동으로 돌아갑니다(대화는 끊기지 않습니다).
  3. 개인 구독자는 별도 키가 필요 없습니다. 본인 기계의 구독 인증(라이선스)이 곧 권한이라, 그냥 아래 명령으로 바꾸면 됩니다 — 음성에 키가 필요 없는 것과 같습니다. (여러 사람이 함께 쓰는 공유·키오스크 박스에서만, 운영자가 구동 시 -e NAIA_ADMIN_KEY=정한_비번으로 잠금을 걸 수 있고, 그때는 요청에 -H "Authorization: Bearer 정한_비번"을 함께 보냅니다.)

실습 — 주소만 정해 둡니다:

BASE=http://127.0.0.1:8892     # 다른 기기에서 하면 §4.4 의 https 주소(예: ...:8443)

① 지금 어떤 모델이고 메모리는 얼마나 남았는지 봅니다:

curl -s $BASE/admin/llm/status

② 모델을 바꿉니다 — 큰따옴표 안 모델 자리만 바꿔 붙여넣으세요. HuggingFace 모델카드 주소(https://huggingface.co/Qwen/Qwen2.5-7B-Instruct-GGUF)나 그 id(Qwen/Qwen2.5-7B-Instruct-GGUF)를 그대로 넣으면 됩니다:

curl -s -X POST $BASE/admin/llm/swap \
  -H "Content-Type: application/json" \
  -d '{"model":"Qwen/Qwen2.5-7B-Instruct-GGUF","pull":true}'

hf.co/ 접두사나 화질(quant)은 자동으로 붙습니다(기본은 Q4_K_M). 특정 화질을 원하면 Qwen/Qwen2.5-7B-Instruct-GGUF:Q5_K_M 처럼 뒤에 적습니다. 모델을 처음 받을 땐 수십 초에서 몇 분이 걸립니다.

②-오프라인 — 인터넷 없이, 내가 가진 GGUF 파일로 바꾸기. 전시·상담처럼 인터넷이 없으면 HuggingFace에서 받지 않고 이미 가진 GGUF 파일을 등록해 바꿉니다. (구분 규칙: 이름에 조직/저장소처럼 슬래시가 있으면 HuggingFace 온라인, 슬래시 없는 단순 이름이면 로컬 모델.)

한 줄씩 복사해 붙여넣으세요. 내모델 자리에 원하는 이름, 내모델.gguf 자리에 실제 파일명을 쓰면 됩니다:

podman cp ./내모델.gguf naia-omni:/app/models/내모델.gguf
podman exec naia-omni sh -lc 'printf "FROM /app/models/내모델.gguf\n" > /tmp/Modelfile && ollama create 내모델 -f /tmp/Modelfile'
curl -s -X POST $BASE/admin/llm/swap -H "Content-Type: application/json" -d '{"model":"내모델:latest","pull":false}'

⚠️ 직접 변환·병합한 GGUF는 채팅 템플릿이 빠져 응답이 횡설수설/잘릴 수 있습니다. 그 경우 2번 단계 Modelfile에 모델 계열 채팅 템플릿(TEMPLATE)과 정지토큰(PARAMETER stop)을 추가해 등록하세요 — 개발자용 상세는 [참고 구현 §7]. (HuggingFace 공식 Instruct GGUF는 보통 내장돼 그대로 써도 됩니다.)

③ 기본 모델로 되돌립니다:

curl -s -X POST $BASE/admin/llm/restore

공유·키오스크 박스(운영자가 NAIA_ADMIN_KEY를 건 경우)면 위 각 명령에 -H "Authorization: Bearer 정한_비번"을 추가하세요. 개인 구독자는 필요 없습니다.

바꾼 다음에도 naia-os 같은 앱은 같은 주소로 그대로 연결하면 됩니다(다시 연결할 필요 없습니다). 재시작이나 업데이트 후에도 계속 그 모델로 시작하고 싶으면, 컨테이너를 띄울 때 -e NAIA_LLM_MODEL=Qwen/Qwen2.5-7B-Instruct-GGUF 로 기본 모델을 지정해 두세요.

6.2 새 버전으로 업데이트하기

새 버전이 나오면 이미지(버전)만 바꾸고 구독·설정은 그대로 둡니다. 새 버전을 처음 켤 때 컨테이너가 인터넷으로 자동 재인증합니다(기존 구독·기기 그대로 — 키를 손으로 다시 넣을 필요 없음). 그러니 업데이트할 땐 인터넷에 연결돼 있어야 합니다.

podman pull ghcr.io/nextain/naia-0.9-omni-24g:latest      # 최신 버전 받기
podman stop naia-omni && podman rm naia-omni      # 컨테이너만 정리 (아래 주의)
# 처음 설치할 때 쓴 실행 명령을 그대로 다시 실행하세요 — 같은 라이선스 볼륨을 그대로 물리면 끝입니다.

⚠️ 업데이트할 때 "기기 해제(release)"를 누르지 마세요. 해제는 쓰던 컴퓨터를 다른 컴퓨터로 옮길 때만 쓰는 기능입니다. 업데이트하려다 해제하면 처음부터 다시 인증해야 합니다. 업데이트는 라이선스 볼륨만 그대로 두면 구독과 기기 등록이 유지됩니다.

기존에 인증해 둔 사용자는 위처럼 최신 버전을 받아 다시 켜기만 하면, 모델을 바꿀 수 있는 새 버전으로 그대로 넘어갑니다(인증 유지). 특정 버전을 콕 집어 받으려면 :latest 대신 :0.91 처럼 버전 번호를 쓰면 됩니다.

7. 참고

  • 참조 구현 / 샘플 코드 (오픈소스): naia-os의 voice 클라이언트 shell/src/lib/voice/ (Apache 2.0) — 이 API에 직결하는 실제 클라이언트(naia-omni.ts)와 감정/운율 처리(emotion-tags.ts, 표정 매핑·견고한 추출은 vrm/expression.ts)가 들어 있습니다. 새 모델 테스트·Tauri 앱 개발의 출발점으로 그대로 활용하세요. 동작 체험은 4.3 라이브 데모.
  • 라인업·가격: 4.1 모델 가격 정책
  • 클라우드(예정): 4.6 온라인 이용