실행 프로그램과 확장
최종 업데이트
NInfer로 Qwen3.8 로컬 실행하기: RTX 5090과 MTP·DFlash2
11.18GB짜리 NInfer 전용 모델 파일을 받아 RTX 5090 서버에서 질문에 답하게 만들어요.
NInfer는 .ninfer 모델 파일을 NVIDIA GPU1에서 실행하고, OpenAI 호환 API2로 답변을 돌려주는 CUDA3 추론 엔진이에요. Underdog Saluki를 Docker 서버에 올려 짧은 질문을 보내고, MTP4와 DFlash2 초안 생성을 같은 요청으로 비교할 수 있어요.
NInfer는 모델 파일을 받아 API 답변을 돌려줘요
NInfer는 NVIDIA GPU에서 NInfer 형식의 모델 파일을 계산하고, 서버에 보낸 대화 요청에 답을 돌려주는 추론 엔진이에요. 입력은 모델 아티팩트와 텍스트 요청이고 결과는 OpenAI 호환 API의 답변입니다. 여기서는 저비트 Qwen3.8-27B 파생 모델 Underdog Saluki를 한 장의 RTX GPU에서 띄워 짧은 질문을 보내요.
GGUF5 원본의 각 텐서 블록을 그대로 보존한 변환 파일이며, 모델 가중치 외에 MTP 헤드와 DFlash2 어댑터도 담고 있어요. 파일은 약 2비트/가중치의 혼합 정밀도 구성이며 크기는 11,180,119,296바이트(10.41GiB)예요. 표준 NInfer 빌드는 파일 안의 gguf_* 형식을 처리하지 못하므로 이 통합 저장소의 빌드가 필요해요.
MTP(Multi-Token Prediction)는 모델의 별도 다음 토큰6 헤드가 여러 후보를 제안하고 본 모델이 검증하는 방식이에요. DFlash2는 별도 초안 어댑터가 여러 후보를 제안한 뒤 본 모델이 확인해요. 제안이 받아들여진 토큰은 한 번에 더 많이 내보낼 수 있지만, 속도 차이는 입력과 초안 수, GPU에 따라 달라져요.

Docker 경로로 모델을 받고 서버를 시작해요
Linux에서 Docker, NVIDIA 드라이버 580 이상, NVIDIA Container Toolkit을 준비하세요. 이 글의 Docker 이미지는 CUDA 13 계열을 사용해요. Toolkit의 공식 샘플 워크로드로 컨테이너가 GPU를 인식하는지 확인한 뒤 Hugging Face CLI7의 hf 명령을 준비해요. 모델은 11.18GB이고 서버 이미지도 내려받으므로 저장 공간을 확보하세요. GPU에는 모델과 KV 캐시8를 함께 담을 여유가 필요해요.
다운로드 명령은 11.18GB짜리 .ninfer 파일을 models 폴더에 저장해요. hf download가 없다면 Hugging Face Hub Python 패키지의 CLI를 설치한 뒤 다시 실행하세요.
서버는 127.0.0.1:8080에서만 요청을 받아요. 문맥 창은 65,536토큰, MTP 초안은 3개로 시작합니다. 현재 폴더의 models를 컨테이너 경로 /models에 연결해요.
mkdir -p models
hf download satoshifukimoto/Underdog-Saluki-27B-1.0-IQ2-mix-NInfer-v3 Underdog-Saluki-27B-1.0-IQ2-mix-ninfer-v3.ninfer --local-dir modelsdocker run --rm --gpus all -p 127.0.0.1:8080:8080 --ulimit memlock=-1 \
-v "$PWD/models:/models" -v ninfer-cache:/cache \
ghcr.io/iamwavecut/ninfer-all serve /models/Underdog-Saluki-27B-1.0-IQ2-mix-ninfer-v3.ninfer \
--model-id underdog-saluki --max-context 65536 --kv-capacity 65536 --kv-dtype rk8v4 \
--gdn-state-fp16 --spec mtp --draft-tokens 3 --lm-head-draft --vision
첫 요청을 보내고 서버 응답을 확인해요
서버를 실행한 터미널은 그대로 두고 새 터미널을 열어요. 모델 목록에 underdog-saluki가 보이면 서버가 모델을 준비한 상태예요. 아래 요청은 OpenAI 호환 채팅 경로에 짧은 영어 질문과 최대 128토큰 출력 한도를 전달해요.
정상 응답에서는 choices[0].message.content에 모델의 답이 들어와요. connection refused는 서버가 아직 뜨지 않았거나 포트 매핑이 빠진 경우가 많고, 모델 ID 오류는 요청의 model 값과 서버의 --model-id가 다른 경우예요.
curl -sS http://127.0.0.1:8080/v1/models
curl -sS http://127.0.0.1:8080/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"underdog-saluki","messages":[{"role":"user","content":"Explain why a local model server uses a context window in two sentences."}],"max_tokens":128}'MTP와 DFlash2는 초안 후보를 다르게 만들어요
첫 요청이 되면 같은 모델과 질문으로 초안 방식을 비교할 수 있어요. MTP는 모델에 포함된 다음 토큰 헤드를 쓰고, DFlash2는 같은 아티팩트 안의 별도 adapter를 사용합니다. 한 번에 하나의 설정만 바꾸고 --spec mtp --draft-tokens 3 --lm-head-draft를 --spec dflash2 --draft-tokens 5로 바꿔 서버를 다시 시작하세요.
초안 수를 늘리면 한 차례 검증에서 더 많은 토큰을 제안하지만, 실제로 받아들여지지 않는 후보까지 계산할 수 있어요. 짧은 채팅에는 DFlash2 5개가 유리할 수 있고 MTP는 보통 3~5개에서 좋은 결과를 내지만, Saluki의 MTP 수용률은 요청에 따라 30~100%로 보고됐어요. 사용자의 문체·코드·언어가 달라지면 결과도 달라지니 한 번의 최고 속도보다 같은 요청 여러 번의 분포를 비교하세요.
생성 속도는 질문 길이와 답변 길이를 고정해 비교해요. 캐시와 GPU 온도가 달라지지 않도록 같은 서버를 재시작하고, 같은 문장을 여러 번 요청해 출력 토큰 수와 걸린 시간을 기록하세요. 기본 생성으로 되돌리려면 --spec, --draft-tokens, --lm-head-draft 옵션을 빼고 서버를 다시 시작하면 돼요.

RTX 5090 커뮤니티 측정 결과
표에는 Saluki의 디코드9·프리필10 속도와 메모리·적재 시간을 나눠 적었어요.
| 실행 항목 | 커뮤니티 측정값 |
|---|---|
| 512토큰 출력 · MTP 3개 | 223 tok/s |
| 512토큰 출력 · DFlash2 5개 | 209 tok/s |
| 약 9.7K 입력 프리필 | 3,955 tok/s |
| 65K KV 유휴 메모리 · MTP 3개 | 약 14.3 GB |
| 모델 적재 | 20.2초 |
2026년 10월 9일 커뮤니티 단일 실행: Windows RTX 5090(sm_120a 빌드), rk8v4 KV, thinking off. 디코드는 512토큰 출력, 프리필은 약 9.7K 토큰 입력, 유휴 메모리는 65K KV와 MTP-3 조건이에요.
첫 오류는 파일 형식과 GPU 연결부터 확인해요
unsupported model이나 블록 형식 오류가 나오면 NInfer-all에서 받은 실행 엔진인지 확인하세요. 이 IQ2-mix 파일은 NInfer-all 전용 gguf_* 블록을 써서 stock NInfer 빌드에서는 열리지 않습니다. 컨테이너에서 GPU를 사용할 수 있는지는 NVIDIA Container Toolkit 공식 샘플 워크로드로 점검하고, 모델 경로와 .ninfer 확장자도 확인하세요.
no CUDA device나 GPU 아키텍처 오류는 컨테이너 런타임11 또는 빌드 대상을 확인할 때예요. 지원 대상 86, 89, 120a는 각각 GPU 아키텍처예요. 이 글의 Windows RTX 5090 결과는 sm_120a 빌드에서 나왔으므로 5090에서 재현하려면 이 아키텍처용 빌드가 필요해요. Windows 직접 빌드에는 CUDA 13, CMake, Visual Studio C++ 도구와 vcpkg 의존성이 필요해요. 저장소의 현재 빌드 절차를 따라야 해요.
메모리 부족으로 적재나 긴 요청이 멈추면 먼저 문맥 한도를 65,536보다 낮추거나 --kv-capacity를 줄여 KV 캐시 공간을 낮춰요. GPU 메모리가 부족한 상태에서 길이를 늘리면 모델을 끄거나 서버가 실패할 수 있어요. 컨테이너 실행을 중단하려면 서버 터미널에서 Ctrl+C를 누르고 Docker 명령을 다시 실행하지 않으면 돼요. 모델 파일은 남아 있으므로 옵션을 고친 뒤 재시작할 수 있어요.
기존 API 서버와 나란히 짧게 시험해요
기존 모델 서버는 유지하고 NInfer는 로컬 주소 127.0.0.1:8080에서 시험해요. 모델 목록과 짧은 응답을 확인한 뒤 실제 한국어 질문, 코드 입력, 긴 문서로 범위를 넓히며 답변 내용과 메모리 사용을 기록하세요. 속도와 별도로 내 작업의 정답률과 도구 호출12도 비교할 수 있어요.
NInfer 아티팩트와 일반 GGUF는 실행 형식이 달라요. 다른 체크포인트13를 변환하려면 NInfer-all의 모델별 recipe와 MTP·DFlash2·Vision 구성요소 지원을 확인하세요. 준비된 Saluki 파일은 위 명령대로 실행하면 돼요.
빠른 설정을 골랐다면 자주 쓰는 질문 몇 개를 고정해 답변 내용도 비교하세요. 요약에서 빠진 내용, 코드 실행 결과, 도구에 전달한 인자를 함께 기록하면 다음 모델 업데이트 때 같은 작업을 다시 시험하기 쉬워요.
다른 실행 엔진도 비교하고 싶다면 아래 llama.cpp 가이드를 참고하세요. Saluki 가이드에서는 일반 GGUF 설치와 양자화14 파일 선택을 이어서 살펴볼 수 있어요.
용어 각주
GPU — 많은 계산을 병렬로 처리하는 프로세서입니다. AI 모델 실행에서는 모델 계산을 맡습니다.
본문으로 돌아가기API — 프로그램의 기능을 다른 코드에서 호출하기 위한 약속된 인터페이스입니다.
본문으로 돌아가기CUDA — NVIDIA GPU에서 범용 계산을 실행하기 위한 소프트웨어 플랫폼입니다.
본문으로 돌아가기MTP — 한 번에 여러 미래 토큰을 예측하도록 학습하는 목표 또는 이를 수행하는 모델 구성입니다. 추측 디코딩에서는 이 예측을 후보 토큰으로 제안할 수 있습니다.
본문으로 돌아가기GGUF — 모델 정보를 담는 파일 형식으로 llama.cpp 계열 도구에서 널리 사용됩니다.
본문으로 돌아가기토큰 — 모델이 입력이나 출력을 나누어 처리하는 단위입니다.
본문으로 돌아가기CLI — Command-Line Interface의 약자입니다. 터미널에 명령어를 입력해 프로그램을 조작하는 방식입니다.
본문으로 돌아가기KV 캐시 — 어텐션에서 이전 토큰의 키·값을 저장해 다음 토큰 생성 때 재사용하는 메모리입니다. 문맥 길이와 배치 크기에 따라 용량이 달라집니다.
본문으로 돌아가기토큰 디코드 — 입력과 앞서 만든 답변을 바탕으로 다음 출력 토큰을 차례로 생성하는 단계입니다.
본문으로 돌아가기프리필 — LLM이 입력 프롬프트를 읽고 각 토큰의 내부 표현을 계산하는 단계입니다. 입력이 길수록 처리할 토큰이 많아집니다.
본문으로 돌아가기런타임 — 프로그램이 실행될 때 필요한 기능을 제공하는 소프트웨어 환경입니다. 로컬 AI에서는 모델을 실행하는 엔진을 가리키기도 합니다.
본문으로 돌아가기도구 호출 — 모델이 파일 읽기·검색·명령 실행 같은 외부 기능의 이름과 인자를 요청하는 형식입니다. 요청을 실제로 실행할지는 에이전트 런타임과 권한 설정이 결정합니다.
본문으로 돌아가기체크포인트 — 학습된 모델의 가중치 등을 저장한 파일입니다. 같은 모델 계열도 버전이나 용도에 따라 다른 체크포인트를 쓸 수 있습니다.
본문으로 돌아가기양자화 — 모델의 가중치나 계산값을 더 적은 비트로 표현해 저장 공간과 메모리 사용량을 줄이는 방법입니다. 표현 단계가 거칠어져 정확도에도 영향을 줄 수 있습니다.
본문으로 돌아가기
자주 묻는 질문
- 이 글에서 가장 먼저 확인할 것은 무엇인가요?
- NInfer는 `.ninfer` 모델 파일을 NVIDIA GPU에서 실행하고, OpenAI 호환 API로 답변을 돌려주는 CUDA 추론 엔진이에요. Underdog Saluki를 Docker 서버에 올려 짧은 질문을 보내고, MTP와 DFlash2 초안 생성을 같은 요청으로 비교할 수 있어요.
- 필요한 메모리는 어느 정도인가요?
- 기존 모델 서버는 유지하고 NInfer는 로컬 주소 `127.0.0.1:8080`에서 시험해요. 모델 목록과 짧은 응답을 확인한 뒤 실제 한국어 질문, 코드 입력, 긴 문서로 범위를 넓히며 답변 내용과 메모리 사용을 기록하세요. 속도와 별도로 내 작업의 정답률과 도구 호출도 비교할 수 있어요.
