Docker
-
vLLM 이 매 iter 도중 자살할 수 있다 — 헬스 보장과 진단 자산을 한 함수에 (Ralph Loop 시리즈 3편)IT 2026. 5. 16. 23:00
장기 실행 자율 스크립트의 가장 짜증나는 실패 모드는 의존성 서비스가 도중에 죽고 우리는 한참 후에 알아차리는 케이스다. Ralph Loop 를 돌리던 어느 날, 30분간 진척이 0이 되어 의아해하다가 발견했다 — vLLM 이 KV cache 의 off-by-one assertion 으로 자살하고 docker compose 의 restart: "no" 정책 때문에 자동 재기동이 안 되어 컨테이너가 죽은 채로 방치된 상황이었다. 그동안 opencode 는 죽은 endpoint 에 호출을 던지고 5분 timeout 으로 종료하기를 반복하고 있었다.이 글은 그 이후 추가한 ensure_vllm_alive() 함수 — 매 iter 시작 시 + opencode 직후에 vLLM 헬스를 확인하고, 죽었으면 진단을 캡..
-
자율 스크립트의 부팅과 셧다운 — 외부 자원을 잡았다면 정확히 한 번만 놓아라 (Ralph Loop 시리즈 2편)IT 2026. 5. 16. 22:00
자율 코딩 루프 같은 장기 실행 스크립트의 시작과 끝은 의외로 까다롭다. 시작에서 외부 자원 — GPU lock, vLLM 컨테이너, 임시 파일 — 을 잡는 건 어렵지 않은데, 스크립트가 어떻게 끝나든 정확히 한 번 정리(cleanup)되도록 보장 하는 게 진짜 일이다. 정상 종료, Ctrl-C, kill -TERM, 스크립트 자체 exit 4, 또는 bash 의 set -e 가 발동시킨 갑작스런 종료까지 — 이 다섯 가지 종료 경로가 모두 같은 cleanup 함수로 합류하면서 동시에 중복 호출은 차단 되어야 한다.이 글은 ralph-loop.sh 의 startup·shutdown 시퀀스를 본다. 한 30줄 정도의 코드인데 그 안에 자율 스크립트가 외부 자원을 다룰 때 빠지기 쉬운 실수 4가지의 답이 들..
-
GPU 스케줄러를 Ollama warmup에서 vLLM 컨테이너로 옮긴 과정 — 시작·종료 시퀀스를 다시 짜다IT 2026. 5. 6. 23:30
들어가며 — "GPU 한 장에 여러 작업"이라는 제약홈서버 DGX Spark에는 GPU가 한 장이다. 그런데 그 위에서 돌아야 하는 작업이 여럿이다.LLM 채팅 서비스 (vLLM Qwen3.6, 80GB 점유)VLM 사진 분석 배치 (gemma3-vision, 30GB 점유)음성 전사 파이프라인 (whisper + pyannote, 15GB 점유)가끔 도는 동영상 인코딩 (NVENC만 쓰지만 GPU 점유)한 GPU에 다 동시에 못 올라간다. 그래서 자체 만든 단순한 GPU 스케줄러가 우선순위 기반 메모리 예산으로 시간차 분배를 한다. LLM이 한참 안 쓰이면 VLM이 들어와 사진 분석을 돌리고, LLM 요청이 들어오면 VLM을 일시 중지시키고 LLM이 GPU를 잡는 식이다.Ollama → vLLM 마이그..
-
벡터 DB 온디맨드 관리 — Qdrant와 임베딩 서버의 cold start 실측IT 2026. 4. 24. 21:00
왜 벡터 DB를 상시 띄워둘 필요가 없는가로컬 RAG 시스템을 운영하다 보면 Qdrant 같은 벡터 DB를 Docker 컨테이너로 띄워두게 된다. 검색할 때, 인덱싱할 때, 야간 배치 작업에서 모두 Qdrant가 필요하니 "그냥 항상 켜두자"가 자연스러운 선택이다.그런데 실제 사용 패턴을 보면, Qdrant에 요청이 들어오는 건 하루에 몇 번 정도다. 검색 한 번, 야간 인덱싱 한 번. 나머지 23시간 동안 컨테이너는 메모리만 차지한 채 아무것도 하지 않는다.통합 메모리 아키텍처(DGX Spark처럼 CPU와 GPU가 메모리를 공유하는 환경)에서는 이 문제가 더 부각된다. Qdrant가 잡고 있는 메모리가 GPU 작업에 쓸 수 있는 메모리를 줄이기 때문이다. 25,000개 벡터(4096차원) 정도의 컬렉..
-
Qdrant 벡터 DB, 임베디드 모드에서 Docker 서버로 전환한 이유 — 로컬 RAG 시스템 구축 삽질기IT 2026. 4. 10. 21:00
벡터 DB가 왜 필요했나나는 Obsidian으로 지식을 관리하고 있다. 공부 노트, 읽은 글 정리, 음성 메모 전사본까지 모두 마크다운 파일로 모인다. 그런데 파일이 1,300개를 넘어가면서 "이거 예전에 정리했는데 어디 있더라?"가 일상이 됐다.Obsidian의 내장 검색은 키워드 매칭이라, "GPU 메모리 관리 방법"을 검색하면 "GPU"와 "메모리"가 들어간 모든 문서가 나온다. 내가 원하는 건 의미적으로 비슷한 내용을 찾는 것인데, 키워드 검색으로는 한계가 있었다.그래서 벡터 DB 기반의 RAG(Retrieval-Augmented Generation) 시스템을 만들었다. 모든 노트를 임베딩해서 벡터로 변환하고, 질문을 던지면 의미적으로 가까운 문서 조각을 찾아주는 시스템이다.처음에는 임베디드 모드..
-
DGX Spark에서 Immich로 가족앨범 GPU 가속 관리하기IT 2026. 3. 16. 22:00
들어가며가족앨범을 AI로 관리하고 싶었다. "레고 블록을 쌓는 아이"로 검색하면 해당 사진이 나오고, 얼굴 인식으로 인물별 앨범이 자동으로 만들어지는 것. 구글 포토가 해주는 것을 내 서버에서 직접 돌리고 싶었다.Immich는 이 모든 것을 제공하는 셀프호스팅 사진 관리 솔루션이다. 하지만 DGX Spark(ARM64 + Blackwell GPU)에서 돌리려니 생각보다 많은 장벽이 있었다. 이것은 그 구축 과정의 기록이다.Immich란?구글 포토의 셀프호스팅 대안이다. GitHub 60,000+ stars.항목구글 포토Immich데이터 위치구글 서버내 서버원본 보존15GB 이후 압축/유료압축 없음, 무제한얼굴 인식✅✅자연어 검색✅✅ (CLIP)비용15GB 초과 유료무료프라이버시❌✅환경과 도전 과제항목값서..
-
DGX Spark에서 ONNX Runtime GPU 빌드 성공기 — 8번의 실패와 1번의 성공IT 2026. 3. 16. 21:00
들어가며22,500장의 가족 사진을 AI로 분석하고 싶었다. CLIP으로 자연어 검색을, InsightFace로 얼굴 인식을 돌리면 된다. 문제는 GPU 없이 CPU로 돌리면 며칠이 걸린다는 것이었다.NVIDIA DGX Spark라면 128GB 통합 메모리에 Blackwell 아키텍처 GB10 GPU까지 있으니 충분히 빠르게 돌릴 수 있을 것 같았다. 하지만 GPU를 쓰기까지 8번의 실패를 거쳐야 했다. 이것은 그 기록이다.환경항목값서버NVIDIA DGX SparkCPUNVIDIA Grace (ARM64 / aarch64)GPUNVIDIA GB10 (Blackwell, SM 121, compute 12.1)메모리128GB LPDDR5x (CPU/GPU 통합)CUDA13.0.88Driver580.126.0..