초기화된 엔진 스냅샷
초기화된 엔진 스냅샷 (Initialized engine snapshots)
초기화된 엔진 스냅샷은 실험적으로, 로컬 디스크 공간과 호스트 권한을 희생하는 대신 vLLM 활성화를 더 빠르게 만드는 방법입니다. 스냅샷 생성은 엔진을 초기화하고 CRIU가 프로세스 트리와 CUDA 상태를 캡처하기 전에 결정적 생성 출력을 기록합니다. 복원(restore)은 저장된 환경을 검증하고, 엔진을 복원하며, HTTP 서버를 바인딩하고, 기록된 토큰과 샘플링된 토큰 로그 확률을 재현한 뒤에야 반환합니다.
출처: 문서
이 경로는 같은 머신에서 같은 모델·엔진 구성을 반복해서 활성화하는 것을 위한 것입니다. 이식 가능한 모델 아티팩트가 아닙니다.
본문
요구 사항 (Requirements)
스냅샷은 현재 다음이 필요합니다.
- NVIDIA GPU 1개를 장착한 x86-64 Linux.
- 인증 없는 평문 HTTP 서버 1개를 쓰는 TP1. 그 외 병렬 크기, TLS, 미들웨어, Unix 소켓, 스펙큘레이티브 디코딩은 지원되지 않습니다.
- 스냅샷 모드는 인증 없는 평문 HTTP 서버가 필요하므로, 신뢰할 수 있는 호스트나 네트워크 경계, 또는 외부 제어를 사용하세요. vLLM Security 가이드를 참고하세요.
- CRIU, 그 CUDA 플러그인,
cuda-checkpoint호환 헬퍼, 그리고nixl이PATH에 있어야 합니다. - CRIU를 위한 root 또는 비밀번호 없는
sudo. - CRIU가 덤프할 수 없으므로 시작 전에
io_uring을 비활성화해야 합니다. 권한 없는 프로세스에는kernel.io_uring_disabled=1을 사용하세요. 아래docker exec흐름을 포함해 root로 실행되는 프로세스는=1을 우회하므로, 호스트 전체에=2를 사용하세요. - 캡처된 프로세스 트리 밖의 피어로 맺어진 TCP 연결이 없어야 합니다. 현재 Hugging Face 허브 클라이언트는 프로세스 수명 동안 연결을 유지하므로, 모델을 별도 단계로 다운로드하고 아래 quickstart처럼
HF_HUB_OFFLINE=1로 create를 실행하세요. - 원격 모델 ID와 불변(immutable)한 40자
--revision. 로컬 모델 디렉토리와 변경 가능한 리비전은 지원되지 않습니다. - 아티팩트를 담을 충분한 디스크 공간이 필요하며, 복원 시 같은 설치된 vLLM 패키지·모델 파일·컨테이너 파일시스템·생성 캐시 경로가 있어야 합니다. 생성 캐시 파일은 아티팩트에 복사되지 않습니다. 매니페스트(manifest)는 캡처된 트리가 열어둔 파일들을 지문(fingerprint)하므로, 한 파일이 제거되거나 교체되면 복원이 일찍 실패하고 그 파일 이름을 알려줍니다. 열린 디스크립터만 기록됩니다. 트리가 매핑했다가 닫은 라이브러리는 지문에 없고 CRIU는 여전히 경로로 다시 여는데, 그 파일을 교체하면 조기 오류 없이 아티팩트가 영구적으로 무효화됩니다.
공식 vllm/vllm-openai Linux x86-64 이미지는 스냅샷 런타임을 포함합니다. 그래도 호환되는 호스트 드라이버·커널·권한이 필요합니다. Arm64 이미지는 이를 생략합니다. 소스 설치에서는 CRIU_CUDA_PLUGIN_DIR을 cuda_plugin.so가 있는 디렉토리로 설정해야 합니다.
스냅샷 명령은 오래 살아있는 컨테이너 안에서 docker exec로 실행하세요. 복원은 API 서버를 분리된(detached) 프로세스로 넘겨주므로, 일회성 컨테이너는 PID 1이 종료되면 그 서버를 멈춰버립니다. 스냅샷 사전 점검(preflight)은 아티팩트 경로의 모든 구성 요소가 호출 사용자나 root 소유여야 하고, 디렉토리 자체는 mode 0700이어야 합니다. 아래 명령들은 공식 이미지 안에서 root로 실행되므로, 바인드 마운트된 호스트 디렉토리를 sudo와 root 소유로 만들어야 합니다. 모델은 캡처된 트리가 허브 연결을 갖지 않도록 별도 단계로 다운로드하고, create는 오프라인으로 실행됩니다. 이 예제는 또한 컨테이너 파일시스템과 /dev/shm 네임스페이스를 아티팩트 수명 동안 안정적으로 유지합니다.
sudo sysctl kernel.io_uring_disabled=2
snapshot_root="$(pwd)/vllm-snapshots"
sudo install -d -m 0700 -o root -g root "${snapshot_root}"
docker run --detach --name vllm-snapshot \
--gpus all \
--privileged \
--pid=host \
--ipc=host \
--network=host \
--mount "type=bind,source=${snapshot_root},target=/snapshots" \
--entrypoint sleep \
vllm/vllm-openai:latest infinity
docker exec vllm-snapshot hf download Qwen/Qwen3-0.6B \
--revision c1899de289a04d12100db370d81485cdf75e47ca
docker exec -e HF_HUB_OFFLINE=1 vllm-snapshot vllm snapshot create Qwen/Qwen3-0.6B \
--snapshot-dir /snapshots/qwen3-0.6b \
--revision c1899de289a04d12100db370d81485cdf75e47ca \
--dtype float16 \
--max-model-len 512
docker exec vllm-snapshot vllm snapshot inspect /snapshots/qwen3-0.6b
docker exec vllm-snapshot vllm snapshot restore \
/snapshots/qwen3-0.6b --host 0.0.0.0 --port 8000
스냅샷이 사용 중인 동안 그 컨테이너와 마운트를 유지하세요. 복원된 API 서버가 더 이상 필요 없어진 후에만 중지·제거하세요.
create는 엔진을 초기화하고, 1-토큰 카나리아(canary)를 기록하며, 복원을 리허설하기 위해 가중치와 KV 캐시를 해제했다가 다시 로드하고, 캡처를 위해 다시 해제합니다. 매니페스트는 CRIU가 완료되고 소스 트리가 멈춘 후에만 게시됩니다. 생성은 오프라인 준비이며 복원 지연의 일부가 아닙니다.
비공개(0700) 아티팩트에는 프로세스 메모리, CUDA 상태, 엔진 인자, 호환성 정체성, 카나리아 출력이 들어 있으며, 매니페스트는 0600입니다. 리터럴 API 키와 Hugging Face 토큰은 매니페스트의 엔진 인자에서 삭제(redact)됩니다. 매니페스트는 선택된 환경 변수 이름과 결정적 이름 바인딩 지문만 기록하며, 그 값은 기록하지 않습니다. 보호된 CRIU 아티팩트는 여전히 프로세스 비밀을 담을 수 있으므로 민감 데이터로 취급하세요. 복원은 HTTP 바인딩 전에 모델 파일과 KV 캐시를 다시 로드한 뒤, 카나리아를 재현하거나 복원된 트리를 해체합니다. inspect 명령은 저장된 프로세스를 실행하지 않고도 그 정체성과 카나리아를 출력합니다.
복원 동작 (Restore behavior)
저장된 정체성이 현재 호스트와 일치하지 않으면 CRIU가 실행되기 전에 복원이 실패합니다. 일반 시작으로 조용히 폴백하지 않습니다. CRIU가 프로세스 트리를 복원한 후 vLLM은 저장된 엔진을 해제해 요청된 HTTP 주소를 바인딩하고, 첫 생성 토큰과 샘플링된 토큰 로그 확률을 스냅샷 카나리아와 비교합니다. 그 검사가 통과된 후에만 명령이 반환됩니다. 복원된 API 서버는 분리된 프로세스로 계속 실행됩니다.
출시 전 포트 프로브(pre-release port probe)는 best-effort일 뿐입니다. 포트를 예약하지도 않고 이후 나타나는 리스너를 인증하지도 않습니다.
롤백은 프로세스 정체성 검증이 성공한 뒤 복원된 트리를 종료하고 기다립니다. 검증이 실패하면 vLLM은 검증되지 않은 PID에 신호를 보내는 대신 스냅샷 서버에 대한 중단 마커를 씁니다. 그 서버가 이미 종료됐다면, 살아남은 엔진 프로세스는 운영자가 정리해야 할 수 있습니다. 재시도 전에 이전 트리가 멈췄는지 확인하세요. PID는 재사용될 수 있으므로, 매니페스트에 PID가 나왔다고 해서 그 프로세스를 죽이지는 마세요.
이전 복원 트리가 멈춘 후에는 아티팩트를 재사용할 수 있습니다. 공유 /dev/shm 마운트는 한 번에 하나의 스냅샷 또는 외부 CRIU 연산만 사용할 수 있습니다.
트레이드오프와 제한 (Tradeoffs and limitations)
- 생성 자체에도 지연이 있으며 잠시 전체 엔진이 필요합니다. 아티팩트 크기는 캡처된 프로세스 및 GPU 메모리에 근접할 수 있습니다.
- 아티팩트는 정전(power loss)에서 살아남는다는 보장이 없습니다. 매니페스트는 fsync되지만, 게시가 모든 캡처된 페이로드 파일과 디렉토리를 명시적으로 flush하지는 않습니다. 호스트가 비정상 종료된 후에는 아티팩트를 다시 만드세요.
- 복원은 현재 동일한 호스트, GPU, 드라이버, 커널, Python, PyTorch, 설치된 vLLM 버전, 모델 리비전, 엔진 인자, 선택된 환경 변수, CRIU 플러그인 바이너리가 필요합니다.
- 검증된 것은 dense float16 TP1뿐입니다. 다른 모델 포맷은 기존 sleep level 2 reload 지원에 의존하며, NCCL 상태는 복원되지 않습니다.
- CRIU 지원은 커널과 드라이버에 따라 다릅니다. 아티팩트 수명 동안 패키지·라이브러리·모델·생성 캐시 경로를 보존하세요.
- 스냅샷에는 프로세스에 존재하는 애플리케이션 비밀 또는 요청 상태가 포함될 수 있습니다. 트래픽이 오기 전에 만들고 프로세스 메모리처럼 보호하세요.
- 외부 연결을 여는 모든 기능은 캡처 전에 반드시 그 연결을 닫아야 합니다.
살아있는 프로세스를 유지하는 더 낮은 복잡도 옵션은 Sleep mode를 참고하세요. Sleep mode와 초기화된 스냅샷은 유지하는 상태의 양과 유휴 자원 비용이 다릅니다.
더 알아보기 (Learn more)
- Sleep mode — 살아있는 프로세스를 유지하는 더 간단한 대안
- Security guide — vLLM 보안 지침