Gated DeltaNet(GDN) 계층을 쓰는 모델을 vLLM 으로 서빙할 때, 기동은 되는데 첫 API 호출에서 실패한다. 게이트웨이(LiteLLM 등) 쪽에는 백엔드 연결 실패로만 보인다.
Cannot connect to host 127.0.0.1:<port>
500 Internal Server Error
vLLM 로그를 보면 실제 원인이 드러난다.
flashinfer/jit/core.py
FileNotFoundError: [Errno 2] No such file or directory: 'ninja'
GDN prefill kernel warmup failed
GDN 계층의 prefill 연산은 FlashInfer 커널과 Triton/FLA 커널 두 가지 구현이 있다. 자동 선택에서 FlashInfer 가 잡히면 그 커널을 JIT 로 컴파일하려 하고, 이때 nvcc 와 ninja 가 필요하다. 빌드 도구가 없는 실행 환경에서는 이 단계가 실패한다.
GDN prefill -> FlashInfer -> JIT 빌드 -> ninja 없음 -> 실패
전날에는 되다가 다음 날 안 되는 경우가 있는데, FlashInfer 가 컴파일 결과를 ~/.cache/flashinfer 에 캐시하기 때문이다. 캐시가 살아 있으면 빌드를 건너뛴다. 실행 사용자나 HOME 이 바뀌거나(systemd 로 옮기는 경우가 대표적) 캐시가 지워지면 다시 빌드를 시도하다 실패한다.
vllm serve <model-path> \
--served-model-name <name> \
--gdn-prefill-backend triton
이 옵션은 GDN 의 prefill 단계 커널 구현만 바꾼다. 모델 가중치, 토크나이저, 일반 attention, tool calling 에는 영향이 없다. 커널 구현이 다르므로 기동 시간과 처리 속도에는 차이가 날 수 있지만 응답 품질을 바꾸려는 옵션은 아니다.
지원하는 값은 설치한 vLLM 버전에서 확인한다.
vllm serve --help=gdn-prefill-backend
아래 변수는 샘플러만 FlashInfer 에서 뺀다. GDN prefill 경로에는 영향을 주지 않는다.
export VLLM_USE_FLASHINFER_SAMPLER=0
TRITON_PTXAS_PATH 와 CUDA_HOME 을 지정해 두어도, vLLM 이 GDN 에 FlashInfer 를 자동 선택하면 그대로 JIT 경로로 들어간다. 백엔드 선택 자체를 고정해야 한다.
옵션을 못 쓰는 환경이면 ninja 를 설치해 JIT 가 성공하게 만드는 길도 있다.
<venv>/bin/python -m pip install --no-cache-dir ninja
<venv>/bin/python -c 'import shutil; print(shutil.which("ninja"))'
폐쇄망이면 wheel 로 반입한다.
python3.10 -m pip download --only-binary=:all: -d ./ninja-wheel ninja
다만 FlashInfer JIT 는 nvcc 도 요구하므로 CUDA 툴킷이 없는 이미지에서는 ninja 만으로 해결되지 않는다. Triton 백엔드로 고정하는 쪽이 의존성이 적다.
같은 작업에서 정리한 값이다. 위에서부터 먼저 건드린다.
| 인자 | 효과 |
|---|---|
--gpu-memory-utilization 0.80 |
vLLM 이 잡으려는 GPU 메모리 비율을 낮춘다 |
--max-model-len 8192 |
KV 캐시 크기를 크게 줄인다 |
--enforce-eager |
CUDA Graph 캡처용 추가 메모리를 쓰지 않는다 |
--max-num-seqs 1~4 |
동시 처리 시퀀스 수 제한 |
--max-num-batched-tokens |
한 번에 처리하는 토큰 수 제한 |
--cpu-offload-gb <N> |
일부 가중치를 CPU 로 내린다 |
--tensor-parallel-size 2 |
GPU 여러 장에 모델을 나눈다 |
모델 로딩이나 그래프 캡처 단계에서 OOM 이 나면 --gpu-memory-utilization 을 0.90 에서 단계적으로 낮춘다.
관리형 AI 플랫폼에서 모델을 띄우면 vllm serve 인자를 직접 줄 수 없는 경우가 있다. 이때는 GDN 계열 모델을 그 플랫폼에서 서빙할 수 없다. --trust-remote-code 가 필요한 모델도 같은 이유로 막힌다. 사유를 기록할 때는 모델 이름이 아니라 GDN 기반 모델 계열 로 묶어 적는 편이 정확하다.