vLLM
-
프롬프트만으로는 못 고친다 — 도구 가이드를 5단으로 줘도 schema 에러는 그대로였다 (Ralph Loop 시리즈 4편)IT 2026. 5. 17. 21:00
자율 코딩 루프를 짜면서 가장 답답했던 시기는 모델이 도구 호출 시 필수 필드를 빠뜨리는 schema 에러 가 매 iter 평균 3.7회 발생하던 때였다. filePath 누락 43회, description 누락 26회, content 누락 23회. 가장 기본적인 식별자조차 빠뜨리는 모델 을 두고 처음엔 prompt 가이드로 해결할 수 있다고 믿었다. 그래서 prompt 안에 도구 사용 필수 사항을 5단으로 명시했다 — Bash 도구의 두 필드, Edit 도구의 세 필드, Write 도구의 두 필드, commit 메시지 형식, 실패 시 즉시 재시도 명령. 결과는 — 효과가 사실상 0이었다.이 글은 ralph-loop.sh 의 prompt 템플릿이 어떻게 수행 순서 + 도구 사용 가이드 + 제약 조건 의 ..
-
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가지의 답이 들..
-
AI 한테 코드를 자동으로 시킬 때 — 컨텍스트를 3축으로 쪼개라 (Ralph Loop 시리즈 1편)IT 2026. 5. 16. 21:00
로컬 LLM 으로 자율 코딩 루프를 돌려본 적이 있다면 한 번쯤 마주치는 장면이 있다. 매 iteration 마다 모델이 "방금 내가 뭘 만들었더라" 부터 다시 헤매는 장면이다. 5분 전에 분명히 spawner.js 를 만들고 commit 까지 끝냈는데, 다음 iter 에 들어가면 모델은 그 사실을 모르고 처음부터 디렉토리를 훑는다. 더 나쁜 건 이미 만든 파일을 또 만들겠다고 시도 하다가 충돌을 일으키거나, "다 했다" 고 보고하고 끝내는데 정작 git log 에는 commit 이 없는 상황이다.이 글은 그 문제를 해결하기 위해 직접 짜본 Ralph Loop 패턴의 첫 디자인 결정을 다룬다. 결론부터 적으면 — LLM 한테 매 iter 던지는 컨텍스트를 한 덩어리로 던지지 말고, 불변·가변·실측 세 축..
-
로컬 챗봇 시리즈 #12 (완) — 정책을 데이터로 표현하기: jobs.conf 한 줄이 모든 GPU 동거 정책을 결정한다IT 2026. 5. 9. 23:30
들어가며 — 12편의 시리즈를 닫으며11편까지는 챗봇 자체의 기능을 다뤘다. 마지막 편은 그 챗봇이 올라가 있는 시스템 레이어의 디자인 한 가지에 집중한다 — "정책을 코드가 아니라 데이터로 표현"한다는 원칙이 GPU 스케줄러와 메모리 SoT 디자인에 어떻게 적용됐는지를 다룬다."좋은 인프라 디자인은 정책 변경이 데이터 한 줄 수정으로 끝난다"는 격언을 자주 듣는다. 이번 글은 그 격언이 실제 운영 시스템에서 어떻게 보이는지를 한 사례로 풀어쓴다.1. jobs.conf 한 줄이 표현하는 것 — GPU 동거 정책 전체DGX Spark 통합 메모리 128GB 안에 GPU를 쓰는 작업이 10개 정도 돌아간다. 텍스트 vLLM, vision vLLM, RAG 임베딩, voice-pipeline Whisper, ..
-
로컬 챗봇 시리즈 #4 — Vision 32B에서 7B로, 그리고 포기까지 — 두 vLLM 동거 시행착오IT 2026. 5. 8. 22:30
들어가며 — "이미지도 보내야지"가 호출하는 산수로컬 챗봇에 학원 시간표 사진, 에러 스크린샷, 지도 캡처 같은 이미지를 던지고 싶었다. 텍스트 모델(Qwen3.6:35B)은 이미지를 못 보니 vision 모델을 따로 띄워야 한다. 평범한 결정 같지만 — DGX Spark의 통합 메모리 128GB 안에서 텍스트 35B + vision을 어떻게 동거시킬 것인가가 곧바로 산수 문제가 된다.처음엔 32B로 등록했다가 7B로 다운그레이드했고, 결국 이 챗봇에서 이미지 분석 자체를 포기했다. 이 글은 그 시행착오의 기록이다. 메모리 산수와 GPU 스케줄러 우선순위 디자인까지는 깔끔했지만 실전에서 4가지 결함이 누적되면서 응답 ~10분이라는 수용 불가능한 비용에 도달했다. 다음 시도 — 외부 vision API, ..
-
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 마이그..
-
RAG 청크 맥락에서 thinking을 꺼야 하는 이유 — enable_thinking=False가 필요한 순간IT 2026. 5. 6. 23:00
들어가며 — "응답 본문이 비어 있다"RAG 인덱싱 코드가 청크 한 덩어리에 50토큰짜리 맥락 설명을 붙이는 호출을 했다. 응답을 받았는데, 본문이 비어 있다. 토큰 예산은 다 소진됐고, finish_reason은 length다.로그를 보니 모델이 블록 안에서만 1500토큰을 쓰다가 max_tokens 한도에 걸려 종료됐다. 본문은 시작도 안 했다.해결은 한 줄이다.chat_template_kwargs: { enable_thinking: false }이 옵션이 필요한 이유, 어떤 호출 패턴에서 켜고 끄는 게 옳은지를 풀어쓴다. thinking 모델을 운영해본 사람이라면 한 번쯤 마주치는 함정이다.1. thinking 모델은 토큰 예산을 어떻게 쓰는가thinking 모델은 답을 내기 전에 "먼저 생각하고..