제6부 생성형 AI 플랫폼
6.7 NIM I — 구조·OpenAI 호환 API
6.7.1 이 장에서 배우는 것 / 선수 지식
6.1~6.6에서 데이터(①)·학습/커스터마이즈(②③)를 봤다. 이제 라이프사이클 ④(배포)로 간다. 제5부(5.7~5.15)에서 우리는 LLM을 배포하려면 TRT-LLM 엔진을 빌드하고 → Triton을 설정하고 → API 서버를 붙이고 → 버전·GPU를 관리해야 함을 봤다. 이것은 강력하지만 마지막 1마일이 번거롭다. NIM(NVIDIA Inference Microservices) 은 그 1마일을 없앤다 — 모델 + 최적화 엔진(TRT-LLM/Triton) + 표준 API를 하나의 컨테이너로 묶어, docker run만으로 OpenAI 호환 엔드포인트가 뜨게 한다.
핵심 통찰: NIM = 제5부 스택(5.7~5.15)의 완제품 패키징이다. 5.15에서 "TRT-LLM·Triton·NIM은 양자택일이 아니라 계층"이라 했는데, NIM은 그 계층을 표준 컨테이너·표준 API로 감싼 최상위다. 앱 개발자는 TRT-LLM·KV·배칭을 몰라도 OpenAI 클라이언트로 호출하고, 운영자는 엔진 빌드 없이 컨테이너를 배포한다.
배우는 것:
- NIM이 무엇인가 — 모델·최적화 엔진·서빙·표준 API를 묶은 추론 마이크로서비스, "배포의 마지막 1마일".
- NIM 구조 — 컨테이너 안의 최적화 백엔드(TRT-LLM/Triton)·GPU에 맞는 엔진 자동 선택(모델 프로파일)·OpenAI 호환 API·헬스·메트릭.
- OpenAI 호환 API —
/v1/chat/completions·/v1/embeddings·스트리밍, 기존 OpenAI 클라이언트 drop-in. - NIM 계열 — LLM뿐 아니라 임베딩·리랭킹(Retriever, 6.9)·비전·음성 등 마이크로서비스 family.
- 커스텀 모델·LoRA — 파인튜닝 가중치·LoRA 어댑터(multi-LoRA, 6.4)를 NIM으로.
- 셀프 호스팅의 의미(데이터 주권)와, NIM이 제5부 스택을 어떻게 감싸나.
선수 지식: 5.7~5.15(TRT-LLM·Triton — NIM이 감싸는 것), 6.1(라이프사이클 배포), 6.4(LoRA → multi-LoRA NIM), 5.1.10(배포 선택). 배포·스케일 운영은 6.8. 환경은 컨테이너·GPU(0.3).
정직: NIM은 빠르게 진화하는 제품이다 — 지원 모델 카탈로그·라이선스·기능·API 표면이 자주 바뀐다. OpenAI 호환 API는 비교적 안정적이나, 모델 목록·프로파일·배포 방식은 그 시점 공식 문서로 확인("시점 의존"). 이 장은 구조·역할·의사결정을 가르치고 특정 모델·버전은 단정하지 않는다.
6.7.2 NIM은 무엇인가 — 배포의 마지막 1마일
제5부의 배포 경로를 떠올리자(5.7~5.15):
DIY는 강력하지만 단계가 많고 전문성이 필요하다(엔진 빌드·KV·배칭·config). NIM 배포는 내부에서 위 전부(최적화 엔진·서빙·API)가 이미 패키징되어 있다.
NIM이 컨테이너 안에 담은 것:
앱 개발자는 OpenAI 클라이언트로 호출하고(내부는 모른다), 운영자는 컨테이너를 배포한다(엔진 빌드 안 함).
NIM이 주는 것:
| 기능 | 의미 |
|---|---|
| 표준 API | OpenAI 호환 → 기존 앱·SDK 그대로(drop-in) |
| 최적화 내장 | TRT-LLM·Triton·인플라이트 배칭·양자화가 이미(5.7~5.15) |
| GPU 자동 최적화 | 감지된 GPU에 맞는 엔진 프로파일 선택(6.7.4) |
| 셀프 호스팅 | 자체 인프라(온프렘·클라우드)에서 — 데이터가 외부로 안 나감 |
| 운영 표준 | 헬스·메트릭·k8s 배포(6.8·7.3) |
| family | LLM·임베딩·리랭킹·비전·음성 등 여러 마이크로서비스 |
핵심: NIM은 "최적화된 추론을 표준 API·컨테이너로 제품화" 한 것이다. 가치는 ① 제5부 최적화를 추가 비용 없이(빌드 없이) 누리고, ② OpenAI 호환으로 앱 통합이 즉시이며, ③ 셀프 호스팅으로 데이터를 자기 환경에 둔다는 데 있다.
6.7.3 OpenAI 호환 API
NIM의 인터페이스는 OpenAI API와 호환된다 — 기존 OpenAI 클라이언트·프레임워크(LangChain·LlamaIndex 등)가 엔드포인트만 바꿔 그대로 동작한다.
표준 엔드포인트(LLM):
| 엔드포인트 | 용도 |
|---|---|
POST /v1/chat/completions | 챗(메시지 배열·스트리밍) |
POST /v1/completions | 텍스트 완성 |
POST /v1/embeddings | 임베딩(임베딩 NIM) |
GET /v1/models | 모델 목록 |
OpenAI SDK의 base_url만 NIM 엔드포인트로 바꾸면 된다.
# 기존 OpenAI 클라이언트를 NIM으로 — base_url만 변경
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed-or-token")
resp = client.chat.completions.create(
model="<배포된 모델 이름>",
messages=[{"role":"user","content":"KV 캐시를 한 문단으로 설명해줘."}],
stream=True, # 스트리밍(토큰 단위)
)
for chunk in resp: # 토큰을 받아 출력(서버는 인플라이트 배칭, 5.8)
print(chunk.choices[0].delta.content or "", end="")
함의:
- drop-in 교체: OpenAI를 쓰던 앱이 코드 거의 그대로 셀프 호스팅 NIM으로 전환 → 벤더 종속·데이터 외부 전송 제거.
- 생태계 호환: OpenAI 호환이라 LangChain·LlamaIndex·기존 도구가 그대로.
- 스트리밍·파라미터: temperature·max_tokens·stop 등 표준 파라미터, 스트리밍은 내부 인플라이트 배칭(5.8)과 연결.
견해: OpenAI 호환이 NIM의 채택을 쉽게 한다 — "OpenAI를 쓰다 데이터·비용·커스터마이즈 때문에 자체 모델로" 옮길 때 코드 변경이 최소. 셀프 호스팅이라 프롬프트·출력이 외부로 안 나가 규제·민감 데이터에 적합.
6.7.4 모델 프로파일 — GPU에 맞는 엔진 자동 선택
5.2·5.9에서 엔진은 GPU 아키텍처·정밀도·병렬도에 종속된다고 했다. NIM은 이를 자동으로 다룬다 — 감지된 GPU에 맞는 최적화 엔진 프로파일을 고른다.
NIM 시작 시:
사용자는 엔진 빌드·정밀도·TP를 직접 고를 필요가 없으며(자동), 단 오버라이드할 수 있다.
- 미리 최적화된 엔진: 흔한 GPU·구성에는 사전 빌드 엔진이 있어 즉시 최적 성능(빌드 대기 없음).
- 즉시 빌드/폴백: 사전 빌드가 없으면 시작 시 빌드하거나 호환 백엔드로 폴백(시점·구성 의존).
- 오버라이드: 정밀도·TP·프로파일을 수동 지정 가능(고급 튜닝).
핵심: NIM은 5.2·5.9의 "엔진은 GPU·버전 종속" 문제를 자동화한다 — 사용자가 trtexec·trtllm-build·TP를 수동으로 설정하지 않아도 그 GPU에 맞는 엔진이 선택된다. 이것이 "최적화를 추가 비용 없이"의 실체다. 단 성능을 극대화하려면 프로파일을 이해하고 오버라이드할 수 있다.
6.7.5 NIM family·커스텀 모델·LoRA
NIM은 LLM만이 아니다. 추론 마이크로서비스의 family다:
| NIM | 용도 |
|---|---|
| LLM NIM | 챗·생성(/v1/chat/completions) |
| 임베딩 NIM | 텍스트 임베딩(/v1/embeddings) — RAG retriever(6.9) |
| 리랭킹 NIM | 검색 결과 재정렬 — RAG(6.9) |
| 비전·멀티모달 | 이미지·VLM |
| 음성 | ASR·TTS |
RAG·에이전트(6.9~6.11)는 이 NIM들을 조합해 만든다.
커스텀 모델·LoRA 배포. 기성 모델뿐 아니라 자기 파인튜닝 가중치(6.4)나 LoRA 어댑터를 NIM으로 서빙:
| 대상 | NIM 서빙 |
|---|---|
| 파인튜닝(SFT) 가중치 | NIM에 적재해 최적화 엔진으로 서빙 |
| LoRA 어댑터(6.4) | NIM이 multi-LoRA 서빙(5.9): 한 베이스에 여러 어댑터. 요청마다 다른 어댑터 적용 → 한 NIM으로 여러 맞춤 모델 |
(구체 절차·지원 형식은 버전 의존, 확인 필요.)
견해: NIM family를 조합해 RAG·에이전트를 만든다(6.9~6.11) — 임베딩 NIM으로 검색, 리랭킹 NIM으로 정렬, LLM NIM으로 생성. 커스텀 LoRA를 multi-LoRA NIM으로 서빙하면 여러 작업·테넌트를 한 베이스로(6.4). NIM은 단일 모델 서버가 아니라 생성형 AI 시스템의 빌딩 블록이다.
6.7.6 워크스루 — NIM 실행·호출
개념 흐름(이미지·레지스트리·인증은 버전·라이선스 의존, 확인 필요):
# 1) NIM 컨테이너 실행(GPU 마운트). 모델은 컨테이너/볼륨에.
# (레지스트리·인증·태그는 NGC/문서 확인; -v 캐시 마운트는 엔진 재시작 가속)
docker run --gpus all -p 8000:8000 \
-e NGC_API_KEY=<key> \
-v ~/.cache/nim:/opt/nim/.cache \
<nim-image:tag>
# → 시작 시 GPU 감지·프로파일 선택(6.7.4)·엔진 로드 → API 뜸
# 2) 준비 확인
curl -s localhost:8000/v1/models # 배포된 모델
curl -s localhost:8000/v1/health/ready # readiness(경로는 버전 확인)
# 3) OpenAI 호환 호출(위 client.py 또는 curl)
curl localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model":"<model>","messages":[{"role":"user","content":"안녕"}],"stream":false}'
내부에서 일어나는 일(5.7~5.15):
사용자는 이 전부를 'OpenAI 호출'로만 경험한다.
운영: 엔진 캐시 볼륨(
-v)으로 재시작 시 빌드를 건너뛴다. 메트릭(Prometheus)·헬스를 k8s·모니터링에 연결(6.8·7.3). 배포·스케일·k8s는 다음 장(6.8).
6.7.7 중간 점검 (체크포인트)
- [ ] NIM이 모델+최적화 엔진(TRT-LLM/Triton)+표준 API를 묶은 컨테이너이며, 제5부 스택을 감싼 "배포의 마지막 1마일"임을 안다.
- [ ] OpenAI 호환 API로 기존 클라이언트가 drop-in 교체되고, 셀프 호스팅으로 데이터가 외부로 안 나감을 안다.
- [ ] 모델 프로파일이 GPU에 맞는 엔진(정밀도·TP)을 자동 선택해 5.2·5.9의 종속을 자동화함을 안다.
- [ ] NIM family(LLM·임베딩·리랭킹·비전·음성)와 커스텀·LoRA(multi-LoRA) 배포를 안다.
- [ ] NIM을 실행해 OpenAI 호환 엔드포인트를 호출하고, 내부(Triton·TRT-LLM)와의 관계를 안다.
증상→의심: NIM 시작이 느림(첫 실행) → 엔진 빌드(사전 빌드 없음) → 캐시 볼륨·사전 빌드 프로파일. OpenAI 코드가 안 붙음 → base_url·API 경로 불일치 → /v1 경로·모델 이름 확인. 성능이 기대 이하 → 자동 프로파일이 비최적 → 정밀도·TP 오버라이드. 데이터 유출 우려 → 셀프 호스팅이라 외부 전송 없음(클라우드 API와 차이) 확인. 여러 작업 배포 번거로움 → multi-LoRA NIM(6.4). GPU 안 맞음 → 프로파일·세대 미지원 → 지원 GPU·구성 확인.
6.7.8 트레이드오프·대안
LLM 배포 방법 선택(5.1.10·5.1.70 확장).
| 방법 | 누구에게 | 비고 |
|---|---|---|
| NIM | 표준 API·셀프 호스팅·최적화를 빌드 없이·엔터프라이즈 지원 | 완제품·간편, 모델·라이선스 카탈로그 의존 |
| DIY TRT-LLM+Triton(5.7~5.15) | 최대 제어·커스텀·세밀 튜닝 | 강력하나 빌드·config·운영 직접 |
| vLLM/SGLang 자체 서버(5.15) | 오픈소스·빠른 모델·간편 | OpenAI 호환 서버, 비-NVIDIA 가능성 |
| 클라우드 LLM API(외부) | 운영 안 함·즉시 | 데이터 외부 전송·비용·커스터마이즈 한계 |
견해: 셀프 호스팅 + 표준 API + 최적화를 한 번에면 NIM이 가장 매끄럽다 — 특히 데이터를 외부로 못 보내는(규제·민감) 조직이 OpenAI 호환으로 자체 모델을 운영할 때. 세밀한 제어·커스텀 엔진이 필요하면 DIY TRT-LLM+Triton, 빠른 모델 지원·이식성이면 vLLM(5.15), 운영 부담 0이면 클라우드 API(데이터 외부). NIM은 "DIY의 최적화 + 클라우드 API의 간편함 + 셀프 호스팅"의 절충.
비엔비디아 정직: OpenAI 호환 셀프 호스팅은 vLLM·SGLang·TGI도 제공한다(OpenAI 호환 서버). NIM의 차별점은 TRT-LLM 최적화·GPU 자동 프로파일·엔터프라이즈 지원·NIM family(임베딩·리랭킹 등)·검증된 패키징이다. 단순 OpenAI 호환 서버면 vLLM도 충분 — 최적화·지원·family·셀프 호스팅 통합이 필요한지로 판단하고, 성능은 워크로드로 실측(5.15).
6.7.9 흔한 함정
- NIM을 단순 모델 서버로만 봄. NIM은 최적화 엔진·표준 API·family·multi-LoRA를 묶은 것 — RAG·에이전트의 빌딩 블록(6.9~6.11).
- 자동 프로파일을 최적이라 가정. GPU 자동 선택이 항상 최적은 아님 — 성능 극대화하려면 정밀도·TP 오버라이드·실측.
- 첫 실행 빌드 시간 간과. 사전 빌드 엔진이 없으면 시작 시 빌드로 느림 → 캐시 볼륨·사전 빌드 프로파일.
- OpenAI 호환을 100% 동일로 가정. 대부분 호환되나 일부 파라미터·동작 차이 가능 — 핵심 경로 검증.
- 데이터 주권을 클라우드 API와 혼동. NIM은 셀프 호스팅이라 데이터가 자기 환경에 — 외부 API와의 핵심 차이.
- 라이선스·모델 카탈로그 미확인. 모델·NIM 가용성·라이선스는 시점 의존 — 배포 전 확인.
- 메트릭·헬스 미연결. 운영 가시성·k8s readiness가 없으면 production 부적합(6.8·7.3).
- LoRA를 따로 서버로. multi-LoRA NIM으로 한 베이스에 여러 어댑터 — 작업마다 서버 기동하지 말 것(6.4).
6.7.10 연습문제
연습 1 (NIM의 가치). 팀이 자체 파인튜닝 LLM을 production에 배포하려 한다. 5.7~5.15을 직접 하는 것 대비 NIM이 없애주는 단계 넷과, 그래도 NIM이 내부에서 쓰는 것을 설명하라.
정답
NIM이 없애는 단계: ① TRT-LLM 엔진 빌드(변환·trtllm-build·정밀도·TP 선택, 5.7~5.9) — 자동 프로파일. ② Triton config(model repository·config.pbtxt·배칭·인스턴스, 5.11~5.14) — 내장. ③ API 서버 작성(OpenAI 호환 레이어) — 내장. ④ GPU·버전 정합 관리(엔진 종속, 5.2) — GPU 감지·프로파일 자동. 그래도 NIM이 내부에서 쓰는 것: TRT-LLM 엔진(인플라이트 배칭·KV·양자화)·Triton 서빙·OpenAI API 레이어 — 즉 NIM은 제5부 스택(5.7~5.15)을 없애는 것이 아니라 패키징해 자동화한다. 사용자는 docker run + OpenAI 호출만, 내부는 그대로 그 최적화가 실행된다.
연습 2 (OpenAI 호환). OpenAI API로 만든 챗 앱을 데이터 주권 때문에 자체 모델로 옮기려 한다. NIM이 이 전환을 어떻게 쉽게 하나? 코드 변경과 데이터 흐름 관점에서.
정답
코드 변경: NIM이 OpenAI 호환 API(/v1/chat/completions 등)를 제공하므로, OpenAI SDK·LangChain 등 기존 코드에서 base_url을 NIM 엔드포인트로 바꾸는 정도의 최소 변경으로 동작(모델 이름·인증 조정). 앱 로직·프롬프트는 거의 그대로 — drop-in 교체. 데이터 흐름: 클라우드 OpenAI는 프롬프트·출력이 외부로 전송되지만, NIM은 셀프 호스팅(자체 온프렘·클라우드 환경)이라 데이터가 자기 인프라 안에 머문다 → 규제·민감 데이터(의료·금융·기밀)에 적합. 즉 NIM은 "OpenAI 호환 인터페이스"로 전환 비용을 낮추면서 "셀프 호스팅"으로 데이터 주권을 준다. 성능·비용은 자체 GPU 운영으로 바뀜(6.8 스케일).
연습 3 (모델 프로파일). NIM이 5.2·5.9의 "엔진은 GPU·정밀도·TP에 종속" 문제를 어떻게 자동화하나? 그리고 성능을 더 극대화하려면 무엇을 할 수 있나?
정답
자동화: NIM은 시작 시 GPU를 감지(아키텍처·수·메모리)하고, 그에 맞는 모델 프로파일을 선택 — 정밀도(FP8/FP16, GPU 세대 의존 5.5), 텐서 병렬도(TP, GPU 수, 5.9), 미리 빌드된 최적 엔진(있으면) 또는 즉시 빌드. 사용자는 trtllm-build·정밀도·TP를 수동으로 안 골라도 그 GPU에 맞는 엔진이 서빙된다(5.2의 종속·재빌드 부담 제거). 성능 더 극대화하기: ① 프로파일 오버라이드 — 정밀도(FP8 강제)·TP·배치 등을 수동 지정. ② 엔진 캐시로 재시작 빌드 회피. ③ 워크로드로 실측해 자동 선택이 최적인지 검증, 아니면 튜닝. 즉 자동이 기본이되 고급 사용자는 오버라이드·실측으로 최적화. "자동 = 항상 최적"은 아님.
연습 4 (family·LoRA). 사내 지식 챗봇(RAG)과 세 부서의 맞춤 어조 모델을 NIM으로 구축한다. 어떤 NIM들을 어떻게 조합하나?
정답
RAG 구성: ① 임베딩 NIM(/v1/embeddings)으로 문서·질의를 벡터화(retriever, 6.9). ② 리랭킹 NIM으로 검색 결과 재정렬(6.9). ③ LLM NIM으로 검색 문맥을 받아 답 생성. 이 셋을 파이프라인으로 묶어 RAG(6.9~6.10). 세 부서 맞춤 어조: 부서마다 별도 서버를 기동하지 말고, LoRA 어댑터(6.4)를 multi-LoRA NIM으로 — 한 베이스 LLM NIM에 부서별 LoRA 어댑터(각 수 MB)를 적재하고 요청마다 해당 어댑터 적용(5.9). 한 NIM으로 세 맞춤 모델 + 베이스 공유로 메모리 효율. 가드레일(6.11)을 앞단에 추가. 즉 NIM family(임베딩·리랭킹·LLM)를 조합하고 커스터마이즈는 multi-LoRA로 — 생성형 AI 시스템의 빌딩 블록.
연습 5 (배포 선택). 다음에 NIM / DIY TRT-LLM+Triton / vLLM 자체 서버 / 클라우드 API 중 무엇을 권하나: (a) 규제로 데이터 외부 전송 금지 + OpenAI 호환 + 운영 간소, (b) 커스텀 커널·세밀 엔진 튜닝이 필요한 연구, (c) 막 나온 신모델을 다음 주 PoC, (d) 운영 인력 없이 즉시 시작·데이터 민감도 낮음.
정답
(a) NIM — 셀프 호스팅(데이터 외부 전송 없음)+OpenAI 호환(앱 통합 쉬움)+최적화 내장(운영 간소)+엔터프라이즈 지원이 정확히 부합. (b) DIY TRT-LLM+Triton(또는 플러그인 5.6) — 커스텀 커널·세밀 엔진 제어는 완제품 NIM보다 직접 빌드가 유연. 최대 제어. (c) vLLM 자체 서버 — 신모델 즉시 지원·빌드 없이 HF에서 바로, 다음 주 PoC에 빠름(5.15). NIM은 카탈로그 지원 시간차 가능. (d) 클라우드 LLM API — 운영 인력 없이 즉시, 데이터 민감도 낮으면 외부 전송 OK, CapEx 0. 운영·GPU 불필요. 핵심: 데이터 주권+간소=NIM, 제어=DIY, 신모델 속도=vLLM, 운영 0=클라우드. 트래픽·SLA는 실측.
6.7.11 요약 · 다음 장
- NIM은 모델 + 최적화 엔진(TRT-LLM/Triton, 5.7~5.15) + 표준 API를 묶은 추론 마이크로서비스 컨테이너 — "배포의 마지막 1마일"을 없앤다.
docker run만으로 OpenAI 호환 엔드포인트. - OpenAI 호환 API로 기존 클라이언트가 drop-in 교체되고, 셀프 호스팅이라 데이터가 외부로 안 나간다(규제·민감 데이터). 모델 프로파일이 GPU에 맞는 엔진(정밀도·TP)을 자동 선택해 5.2·5.9의 종속을 자동화.
- NIM은 LLM만이 아니라 family(임베딩·리랭킹·비전·음성) — RAG·에이전트(6.9~6.11)의 빌딩 블록. 커스텀·LoRA(multi-LoRA) 도 배포.
- NIM은 DIY 최적화 + 클라우드 API 간편함 + 셀프 호스팅의 절충 — 제어는 DIY, 신모델 속도는 vLLM, 운영 0은 클라우드 API와 비교해 고른다.
- 정직: NIM은 빠르게 진화(모델 카탈로그·라이선스·기능 버전 의존), OpenAI 호환은 대체로 안정, 자동 프로파일은 실측·오버라이드, 성능은 워크로드로.
다음 장: 6.8 NIM II — 배포·스케일. 단일 NIM을 띄웠으니, 이제 production 운영 — 쿠버네티스 배포(NIM Operator)·오토스케일·다중 NIM·헬스/메트릭·GPU 자원 배분(MIG/MPS, 7.5)·롤아웃 — 으로 확장한다(실습). 제7부(엔터프라이즈·MLOps)의 k8s GPU 운영(7.2~7.3)과 이어진다.