ollama pull과 run 차이, 모델 저장 위치와 이동 방법
ollama pull은 모델을 다운로드하고 종료하며, ollama run은 다운로드 후 채팅을 엽니다. VPS root 디스크가 차는 저장 위치와 모델 이동 방법을 설명합니다.
ollama pull과 ollama run 비교
ollama pull은 모델을 다운로드한 후 종료한다. ollama run은 모델이 없을 때만 다운로드한 다음 메모리에 로드하고 대화형 채팅을 연다. 다운로드 방식은 동일하며 파일도 같은 위치에 저장된다. 이후에도 계속 실행되는 것은 run뿐이다.
이 한 가지 차이로 스크립트에 사용할 명령과 키보드에서 사용할 명령이 결정된다.
ollama pull gemma4
ollama run gemma4
ollama run gemma4 "Reply with one word: ready"첫 번째 줄은 모델을 가져온 후 종료하므로 프로비저닝과 systemd unit에서 안전하게 사용할 수 있다. 두 번째 줄은 채팅 세션을 연다. 종료하려면 /bye을 입력하거나 Ctrl+D를 누른다. 세 번째 줄은 단일 프롬프트를 보내고 응답을 출력한 후 종료한다. 세션이 아니라 응답이 필요한 스크립트에서는 이 형식을 사용한다. 모델 이름은 자주 변경되므로 여기의 gemma4은 자리 표시자로 간주한다. 이는 2026년 8월 기준 공식 Ollama 문서에서 사용하는 예시이며, library의 모든 태그가 같은 방식으로 동작한다.
첫 ollama run이 멈춘 것처럼 보이는 이유
새 VPS에서 처음 실행하는 run은 몇 분 동안 출력 없이 진행될 수 있다. 문제가 발생한 것이 아니다. 모델을 디스크에 저장하고 메모리에 로드해야 채팅 프롬프트가 표시되므로, run은 사용자에게 표시할 내용이 생기기 전에 수 GB를 다운로드한다.
이 작업이 보이지 않는 이유는 2가지다. Ollama는 출력 대상이 터미널일 때만 진행률 표시줄을 그린다. 따라서 셸 스크립트, cron 작업, CI 단계 또는 일반 ssh host ollama run ... 안에서 실행되는 run은 다운로드하는 동안 아무것도 출력하지 않는다. 다운로드가 끝난 뒤에도 첫 토큰을 출력하려면 파일을 디스크에서 읽어 RAM으로 로드해야 한다. 소형 VPS에서는 이 작업이 느리다. 서버에 모델을 수용할 메모리가 없으면 커널이 스와핑을 시작하므로 대기 시간이 훨씬 길어진다.
추측하지 말고 두 번째 세션에서 다음과 같이 확인한다.
df -h /
watch -n5 df -h /사용 가능한 공간이 단계적으로 줄어들면 다운로드가 계속 진행 중이라는 뜻이다. 명령이 계속 실행 중인데 사용 가능한 공간이 더 이상 줄어들지 않으면 다운로드가 끝나고 메모리 로드가 시작된 것이다.
이 때문에 미리 pull해야 한다. ollama run을 입력하는 사용자가 다운로드 비용까지 부담하게 해서는 안 된다.
요청이 들어오기 전에 모델을 pull합니다
새 서버에서는 서버를 설치하는 동일한 스크립트에서 모델을 pull합니다.
curl -fsSL https://ollama.com/install.sh | sh
ollama pull gemma4서버를 처음 구성하는 경우 VPS에서 Ollama를 설치하는 전체 과정에서 서비스 자체와 접근이 허용되는 대상을 설명합니다. 그다음에는 터미널보다 오래 실행되는 pull을 설정하는 것이 좋습니다. 다운로드가 중간에 종료되면 모델 저장소가 일부만 채워질 수 있기 때문입니다.
tmux 안에서 실행하거나, 부팅 시 실행되는 one-shot unit으로 systemd에 전달합니다. /etc/systemd/system/ollama-pull.service를 작성합니다.
[Unit]
Description=Pre-pull Ollama models
Wants=ollama.service network-online.target
After=ollama.service network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c 'until ollama list >/dev/null 2>&1; do sleep 2; done'
ExecStart=/bin/sh -c 'ollama pull gemma4'
[Install]
WantedBy=multi-user.target두 명령 모두 의도적으로 /bin/sh -c을 통해 실행합니다. 단순한 ExecStart=에는 절대 경로가 필요합니다. 또한 설치 프로그램이 항상 같은 디렉터리에 바이너리를 배치하는 것은 아니므로, 자체 서버에서 command -v ollama을 확인하는 방법이 유일하게 신뢰할 수 있습니다. shell을 거치면 가이드에서 복사한 경로가 아니라 서비스의 PATH를 사용합니다. 첫 번째 ExecStart도 중요합니다. After=ollama.service은 서버 unit이 시작되었다는 뜻일 뿐, 준비가 완료되었다는 뜻은 아닙니다. 따라서 pull을 시작하기 전에 루프가 ollama list의 응답을 기다립니다.
sudo systemctl daemon-reload
sudo systemctl enable --now ollama-pull.service
journalctl -u ollama-pull.servicejournal에는 오류 없이 pull이 완료되었다는 내용이 표시되어야 합니다. 그런 다음 ollama list에서 모델을 확인할 수 있습니다. 변경되는 tag를 최신 상태로 유지하려면 동일한 pull을 실행하는 systemd timer 또는 주간 cron 항목을 추가합니다. 변경된 tag를 다시 pull하면 새 layer가 다운로드됩니다. 이전 layer는 더 이상 참조되지 않으며, 다음에 서버가 시작될 때 정리됩니다.
pull이 중단되면 발생하는 일
모델의 각 레이어는 해당 콘텐츠 자체의 해시를 기준으로 저장된다. 따라서 중단된 pull은 작업 손실로 이어지지 않는다. 동일한 ollama pull을 다시 실행하면 이미 완료된 레이어는 인식되어 건너뛰고, 다운로드는 중단된 레이어부터 계속된다.
한 가지 작업은 이 진행 상태를 삭제한다. Ollama 서버가 시작되면 어떤 모델 매니페스트에서도 참조하지 않는 저장된 레이어를 제거한다. 중단된 pull이 남긴 부분 레이어가 바로 여기에 해당한다. 따라서 재시도하기 전에 서비스를 재시작하면 이미 다운로드한 데이터가 삭제된다. 먼저 pull을 재시도하고 나중에 재시작해야 한다. 부분 다운로드를 재시작 후에도 유지해야 한다면 서비스 환경에 OLLAMA_NOPRUNE=1을 설정한 다음, 해당 설정을 다시 제거해야 한다. 시작 시 정리가 수행되어야 디스크에 고아 레이어가 계속 쌓이는 것을 막을 수 있기 때문이다.
no space left on device와 함께 pull이 중단되었다면 재시도하기 전에 공간을 확보해야 한다. df에서 디스크가 가득 찼다고 보고하지만 모델 디렉터리의 du로 그 사용량이 설명되지 않는다면, 공간이 다른 위치에서 사용된 것이다. 무엇이 원인인지 확인하려면 파일을 삭제하기 전에 df와 du의 결과가 일치하지 않는 이유를 읽어 보는 것이 좋다.
VPS에서 Ollama는 모델을 어디에 저장하는가?
이 안내서를 포함해 어떤 가이드의 경로도 그대로 믿지 말고, 직접 서버에 확인해야 한다. 패키지 설치와 컨테이너에서는 위치가 다르며, 누군가 OLLAMA_MODELS을 설정했다면 위치가 다시 달라진다.
systemctl cat ollama.service
getent passwd ollama
sudo find / -xdev -type d -name blobs 2>/dev/nullsystemctl cat은 모든 drop-in과 함께 unit 파일을 출력하므로, 직접 설정했거나 이미지에 포함된 OLLAMA_MODELS 줄도 여기에 표시된다. 이러한 줄이 없으면 저장소는 서비스가 실행되는 계정의 홈 디렉터리 아래에 있다. getent passwd은 콜론으로 구분된 필드 중 여섯 번째 필드에서 해당 홈 디렉터리를 출력한다. find은 하나의 파일 시스템에서 blobs 디렉터리를 검색한다. 실제 레이어는 이 디렉터리에 기록된다. 모델이 별도의 마운트에 이미 있을 수 있다면 -xdev을 제거한다.
이제 용량을 측정하고, 직접 얻은 값을 확인한다.
ollama list
df -h /
sudo du -sh /the/directory/you/found
sudo du -h -d1 /the/directory/you/found저장소는 두 부분으로 구성된다. manifests에는 모델 태그마다 작은 파일이 하나씩 있으며, 각 파일에는 해당 태그를 구성하는 레이어가 기록된다. blobs에는 레이어 자체가 저장된다. 각 레이어의 이름은 콘텐츠의 해시이며, 용량 대부분은 여기에 사용된다. 레이어는 여러 태그가 공유한다. 따라서 동일한 가중치로 만든 두 모델은 ollama list에서 각각 자체 크기로 표시되지만, 디스크에서는 해당 공간을 한 번만 차지한다. 이 때문에 표시된 크기의 합계가 디렉터리에 대해 du이 보고하는 크기보다 클 수 있다.
모델 파일은 설치할 가능성이 높은 다른 항목보다 작은 VPS의 root 파일 시스템을 더 빠르게 채운다. 모델 크기에 가장 크게 영향을 주는 요소는 가중치 형식이다. q4, q8, fp16 중 선택은 모델당 수 GB의 차이를 만들 수 있으므로 검토할 가치가 있다.
OLLAMA_MODELS로 모델을 데이터 볼륨으로 이동하기
두 번째 디스크나 더 큰 데이터 볼륨을 사용할 계획이라면 root 파일 시스템이 가득 차기 전에 모델 저장소를 이동합니다. 아직 쓰는 중인 파일을 복사하지 않도록 먼저 서버를 중지합니다.
sudo systemctl stop ollama
sudo mkdir -p /mnt/data/ollama-models
sudo rsync -a /the/directory/you/found/ /mnt/data/ollama-models/
sudo chown -R ollama:ollama /mnt/data/ollama-models
sudo systemctl edit ollama.servicesystemctl edit는 drop-in 파일을 편집기로 엽니다. 따라서 패키지에서 제공하는 unit 파일은 수정되지 않으며, 패키지 업그레이드로 변경 내용이 덮어쓰이지 않습니다. 다음 두 줄을 추가합니다.
[Service]
Environment="OLLAMA_MODELS=/mnt/data/ollama-models"sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environment
ollama listsystemctl show는 새 경로를 출력해야 합니다. ollama list는 이동하기 전에 표시되던 모델과 같은 모델을 표시해야 합니다. 목록이 비어 있으면 서버가 새 디렉터리를 읽지 못하는 것입니다. 서비스는 ollama 사용자로 실행되므로 해당 사용자가 대상 경로에 대한 읽기 및 쓰기 권한을 가져야 합니다. 위의 chown 줄이 이 권한을 설정합니다. 새 경로를 가리키는 권한 오류가 있는지 journalctl -e -u ollama를 확인합니다. 목록이 올바른 것을 확인한 후에만 이전 복사본을 삭제합니다. 이동이 실패한 상태에서 원본까지 삭제하면 모든 모델을 다시 다운로드해야 합니다.
다른 방법은 원래 경로를 유지하고 데이터 볼륨을 해당 경로에 마운트하는 것입니다.
echo '/mnt/data/ollama-models /the/directory/you/found none bind 0 0' | sudo tee -a /etc/fstab
sudo mount -a
findmnt /the/directory/you/found
df -h /findmnt가 마운트를 출력하면 bind mount가 적용된 상태입니다. 다른 항목이 서버에서 이미 기본 경로를 사용하고 있을 때 bind mount를 이용하면 됩니다. 한 가지 주의할 점이 있습니다. 복사해 둔 파일은 여전히 root 디스크의 마운트 지점 아래에 남아 있습니다. 마운트로 가려져 있을 뿐이므로, 마운트를 해제하고 파일을 삭제하기 전까지 디스크 공간이 반환되지 않습니다. 두 방법 중에서는 환경 변수가 다음에 로그인할 사람에게 설명하기 더 쉽습니다.
컨테이너가 대신 모델을 보관하는 위치
공식 이미지는 모델을 ollama 사용자가 소유한 호스트 디렉터리가 아니라, 마운트한 위치에 저장한다. 문서에 나온 실행 명령은 다음과 같다.
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama콜론 앞의 ollama은 이름이 지정된 Docker 볼륨이고, /root/.ollama은 서버가 컨테이너 내부에서 쓰는 경로다. 따라서 이전 섹션의 경로에 대해 du을 실행해도 아무것도 찾지 못한다. 해당 경로에는 아무것도 없기 때문이다. 실제 위치와 크기를 출력한다.
docker volume inspect ollama
docker system df -v
docker exec -it ollama ollama listdocker volume inspect에서 Mountpoint 필드를 확인한 다음, 해당 값에 sudo du -sh을 실행한다. 모델을 데이터 볼륨에 저장하려면 이름이 지정된 볼륨을 호스트 디렉터리(-v /mnt/data/ollama:/root/.ollama)로 바꾸고 컨테이너를 다시 생성한다. 컨테이너는 root로 쓰므로 호스트 디렉터리의 소유자는 root가 된다. rootless Podman에서는 ID가 사용자의 subuid 범위에 매핑되므로 호스트에서 보이는 소유자가 다시 달라진다. 이 매핑은 rootless Podman에서 Ollama 실행하기에서 설명한다.
정리 작업과 관련해 한 가지 주의할 점이 있다. docker volume prune은 어떤 컨테이너도 참조하지 않는 모든 볼륨을 제거한다. 볼륨 없이 ollama 컨테이너를 제거하거나 다시 생성하면, 이후 prune을 실행할 때 다운로드한 모든 모델이 삭제된다. 다시 다운로드하는 방법 외에는 복구할 수 없다. 모델을 호스팅하는 서버에서 prune을 실행하기 전에 VPS에서 Docker 디스크 사용량 정리하기를 읽는다.
ollama rm으로 모델을 제거하고 rm은 사용하지 않는다
ollama list
ollama rm gemma4
ollama list
df -h /ollama rm는 해당 태그의 매니페스트를 삭제한 다음, 남아 있는 매니페스트가 참조하지 않는 레이어를 삭제한다. 파일의 링크가 해제되는 즉시 공간이 반환되므로 df의 변경 사항이 바로 반영된다. 레이어는 공유되므로 서로 밀접하게 관련된 두 태그 중 하나를 제거해도 태그 옆에 ollama list가 표시한 크기보다 훨씬 적은 공간만 확보될 수 있다. 이는 삭제 실패가 아니라 정상적인 동작이다.
파일을 직접 삭제하면 매니페스트와 레이어의 연결이 깨진다. rm로 blob을 제거해도 매니페스트에는 해당 blob이 계속 나열되므로 ollama list에는 모델이 계속 표시된다. 누락된 레이어를 읽는 시점에 모델 사용이 실패한다. 매니페스트를 직접 제거하면 해당 레이어를 가리키는 항목이 없어도 레이어가 디스크에 남아 공간을 차지한다. Ollama 명령으로는 이 공간을 확인할 수 없다. 이미 직접 삭제했다면 해당 태그에 ollama rm를 실행해 남은 항목을 정리할 수 있다. 서버를 다시 시작하면 아무것도 참조하지 않는 레이어도 정리된다.
마지막으로 두 개념을 구분해야 한다. 두 개념은 자주 혼동된다. ollama rm는 디스크에 관한 명령이다. ollama stop gemma4는 메모리에서 모델을 언로드하지만 디스크 공간은 전혀 확보하지 않는다. 다운로드가 끝난 뒤 모델을 RAM에 얼마나 오래 유지할지는 별도의 설정이다. 각 요청마다 모델을 다시 로드하지 않고 계속 로드된 상태로 유지하기에서 이 설정을 설명한다.
FAQ
ollama pull과 ollama run의 차이는 무엇입니까?
ollama pull은 모델을 디스크에 다운로드한 후 종료합니다. ollama run은 모델이 이미 디스크에 있는지 확인하고, 없으면 다운로드한 다음 메모리에 로드하고 대화형 채팅 세션을 엽니다. 두 명령은 동일한 파일을 동일한 디렉터리에 기록합니다. 프로비저닝과 스크립트에서는 pull을 사용하고, 사용자가 키보드 앞에서 직접 작업할 때는 run을 사용합니다. ollama run <model> "your prompt"은 프롬프트 하나를 전송한 후 종료합니다. 이는 run의 스크립트 실행 방식입니다.
첫 번째 ollama run이 멈춘 것처럼 보이는 이유는 무엇입니까?
다운로드 중인 것입니다. 모델이 디스크에 저장되고 메모리에 로드되기 전에는 채팅 프롬프트가 나타날 수 없습니다. 모델 크기는 수 GB에 이릅니다. Ollama는 출력 대상이 터미널일 때만 진행률 표시줄을 표시하므로, 스크립트, cron 작업 또는 ssh host ollama run ... 안에서 실행한 run은 작업 중에도 아무것도 표시하지 않습니다. 두 번째 세션을 열고 watch -n5 df -h /을 실행합니다. 디스크 여유 공간이 단계적으로 줄어들면 다운로드가 진행 중이라는 뜻입니다. 모델을 미리 pull하면 대기 시간이 사라집니다.
Ollama는 모델을 어디에 저장합니까?
저장 위치는 설치 방식에 따라 다릅니다. 따라서 추측하지 말고 출력해야 합니다. systemctl cat ollama.service을 실행하여 OLLAMA_MODELS이 unit 또는 drop-in에 설정되어 있는지 확인합니다. 설정되어 있지 않으면 서비스가 실행되는 계정의 홈 디렉터리 아래에 저장소가 있습니다. 해당 경로는 getent passwd ollama이 출력합니다. sudo find / -xdev -type d -name blobs 2>/dev/null은 layer 디렉터리의 위치를 직접 찾습니다. 컨테이너 이미지에서는 저장소가 마운트된 volume 안에 있으며, docker volume inspect ollama은 해당 volume의 호스트 Mountpoint을 출력합니다.
Ollama 모델을 다른 디스크로 어떻게 옮깁니까?
서비스를 중지하고 rsync -a을 사용하여 저장소를 새 위치로 복사합니다. sudo chown -R ollama:ollama <directory>을 사용하여 해당 디렉터리의 소유자를 서비스 계정으로 설정한 다음, sudo systemctl edit ollama.service을 실행하고 [Service] 줄 아래에 Environment="OLLAMA_MODELS=<directory>"을 추가합니다. sudo systemctl daemon-reload으로 설정을 다시 로드하고 서비스를 재시작합니다. systemctl show ollama --property=Environment와 ollama list로 확인합니다. 목록이 비어 있으면 거의 항상 ollama 사용자가 새 디렉터리를 읽을 수 없다는 뜻입니다. journalctl -e -u ollama이 경로를 표시합니다.
모델 파일을 삭제하면 디스크 공간이 확보됩니까?
파일을 직접 삭제하면 해당 바이트는 확보되지만 저장소의 일관성이 깨집니다. blob을 삭제해도 manifest에는 모델이 계속 등록되어 있으므로 ollama list에 계속 표시되고 사용 시 실패합니다. manifest를 삭제하면 해당 레이어는 디스크에 남지만 이를 참조하는 항목이 없어집니다. ollama rm <model>을 사용하면 manifest를 삭제한 다음 다른 모델이 필요로 하지 않는 레이어를 삭제합니다. 이미 파일을 직접 삭제했다면 tag에 ollama rm을 실행하여 항목을 정리한 다음 서버를 재시작합니다. 그러면 어떤 manifest도 참조하지 않는 레이어가 삭제됩니다.