
이 글에서는 허깅페이스 모델 캐시가 실제로 어디에 저장되는지 확인하는 방법과, 캐시 경로를 원하는 위치로 고정하고 오프라인 모드까지 켜는 절차를 순서대로 정리합니다. 핵심만 먼저 말씀드리면, Hugging Face 모델이 매번 다시 다운로드되는 것은 캐시가 진짜로 사라져서가 아니라 실행할 때마다 캐시 경로(HF_HOME)가 다르게 잡히거나, 캐시가 아예 없는 새 컨테이너·세션에서 스크립트가 돌아가기 때문인 경우가 대부분입니다. 캐시 경로를 명시적으로 고정하고 오프라인 모드 환경변수를 켜두면 대부분 해결됩니다.
허깅페이스 모델은 원래 로컬에 캐시됩니다
transformers나 diffusers, sentence-transformers처럼 huggingface_hub 라이브러리를 기반으로 하는 패키지에서 from_pretrained()를 호출하면, 모델 가중치는 처음 한 번만 서버에서 받아오고 이후에는 로컬 디스크에 저장된 캐시를 그대로 읽습니다. 기본 캐시 위치는 Linux·macOS 기준 ~/.cache/huggingface/hub, Windows 기준 C:\Users\사용자명\.cache\huggingface\hub입니다.
캐시 구조는 실제 가중치 파일(blob)을 한 곳에 저장해 두고, 리비전별 snapshots 폴더에서는 그 파일을 심볼릭 링크로 연결하는 방식입니다. 그래서 같은 모델을 여러 리비전으로 받아도 실제 용량은 크게 늘지 않습니다. 이 구조가 정상 작동하면 두 번째 실행부터는 네트워크 요청 없이 파일을 바로 읽습니다.
그런데도 매번 다시 다운로드되는 이유가 뭘까요
캐시가 분명히 있는데도 실행할 때마다 다시 받아지는 상황은 실제 캐시 손상보다 실행 환경 차이에서 오는 경우가 훨씬 많습니다. 실무에서 자주 보는 원인은 다음과 같습니다.
- Docker 컨테이너를 매번 새로 띄우는 경우: 볼륨을 마운트하지 않으면 컨테이너가 재시작될 때
/root/.cache/huggingface도 함께 초기화됩니다. - Colab·Kaggle 같은 세션형 환경: 세션이 끊기면 로컬 디스크 자체가 리셋되므로 캐시도 같이 사라집니다.
- cron·systemd 서비스로 실행하는 스크립트: 터미널에서 직접 실행할 때와 달리
HOME환경변수가 다르게 설정돼 있으면 huggingface_hub가 계산하는HF_HOME경로 자체가 달라져, 캐시가 있어도 다른 폴더를 보게 됩니다. cache_dir인자를 코드에서 매번 다른 임시 경로로 지정: 특히 배치 스크립트를 여러 서버에서 돌릴 때 흔한 실수입니다.- 리비전을 고정하지 않은 상태에서 네트워크가 살아 있는 경우: 캐시가 있어도 huggingface_hub는 기본적으로 최신 리비전인지 확인하려고 Hub에 짧은 요청을 보냅니다. 이 요청 자체가 재다운로드는 아니지만, 사설 프록시나 방화벽 때문에 이 요청이 타임아웃되면 캐시를 못 찾은 것처럼 처리되어 전체를 다시 받는 것처럼 보일 수 있습니다.
정리하면 “매번 다시” 받아지는 원인은 캐시 손상보다 캐시 경로 불일치나 캐시가 유지되지 않는 실행 환경 쪽을 먼저 의심하는 편이 맞습니다.
캐시 경로부터 확인해 보세요
huggingface_hub는 캐시 내역을 스캔하는 함수를 공식으로 제공합니다. 아래 코드로 지금 어떤 모델이, 어디에, 얼마나 저장돼 있는지 바로 확인할 수 있습니다.

from huggingface_hub import scan_cache_dir
info = scan_cache_dir()
for repo in info.repos:
print(repo.repo_id, repo.repo_type, repo.size_on_disk_str)
실행 결과는 대략 아래와 같은 형태로 나옵니다.
bert-base-uncased model 439.6M
sentence-transformers/all-MiniLM-L6-v2 model 90.9M
터미널에서 바로 확인하고 싶다면 huggingface-cli scan-cache 명령으로도 같은 정보를 볼 수 있고, 불필요한 리비전을 지우고 싶을 때는 huggingface-cli delete-cache로 대화형으로 정리할 수 있습니다. 캐시 경로 자체를 고정하려면 스크립트 실행 전에 환경변수를 지정합니다.
export HF_HOME=/data/hf-cache
# 또는 hub 캐시만 따로 지정하고 싶을 때
export HF_HUB_CACHE=/data/hf-cache/hub
주요 환경변수는 아래처럼 정리됩니다. huggingface_hub 0.19 이상, transformers 최신 버전 기준입니다.
| 환경변수 | 기본값 | 역할 |
|---|---|---|
HF_HOME |
~/.cache/huggingface |
캐시·토큰 등을 포함한 최상위 기준 경로 |
HF_HUB_CACHE |
$HF_HOME/hub |
모델·데이터셋 가중치가 실제로 저장되는 경로 |
TRANSFORMERS_CACHE |
(구버전 전용, deprecated) | transformers만 쓰던 옛 캐시 경로 지정 방식 |
HF_HUB_OFFLINE |
0 |
1로 설정하면 네트워크 접속 없이 캐시만 사용 |
TRANSFORMERS_OFFLINE |
0 |
transformers 자체 오프라인 스위치, HF_HUB_OFFLINE과 함께 켜는 걸 권장 |
HF_HOME을 지정할 때는 cron이나 systemd 서비스 파일에도 같은 값을 명시적으로 넣어야 합니다. 인터랙티브 셸에만 export해두면 서비스로 실행될 때는 적용되지 않아 결국 기본 경로로 돌아가고, 이게 바로 “분명히 캐시를 옮겼는데도 다시 받는다”는 문의의 상당수 원인입니다.
오프라인 모드로 재다운로드를 막는 법
캐시가 확실히 있는 상태라면 아예 네트워크 확인 단계 자체를 건너뛰게 만들 수 있습니다. 코드 안에서 환경변수를 설정하거나, 실행 전에 셸에서 지정하면 됩니다.

import os
os.environ["HF_HUB_OFFLINE"] = "1"
os.environ["TRANSFORMERS_OFFLINE"] = "1"
from transformers import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("bert-base-uncased")
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
환경변수 대신 함수 호출 시점에 옵션 하나로 지정할 수도 있습니다.
model = AutoModel.from_pretrained("bert-base-uncased", local_files_only=True)
이 상태에서는 huggingface_hub가 Hub에 리비전 확인 요청을 아예 보내지 않고 로컬 스냅샷만 읽기 때문에, 응답 속도도 빨라지고 사내 프록시·방화벽 환경에서 발생하던 타임아웃 문제도 함께 사라집니다. 배치 작업처럼 같은 모델을 반복 로드하는 스크립트라면 이 두 줄만 추가해도 체감 속도 차이가 꽤 큽니다.
오프라인 모드가 통하지 않는 경우도 있습니다
오프라인 모드는 만능이 아닙니다. 먼저 대상 모델이 최소 한 번은 온라인 상태에서 완전히 다운로드돼 있어야 합니다. 캐시에 없는 모델을 오프라인 상태에서 부르면 huggingface_hub는 네트워크 요청을 시도하지 않고 바로 LocalEntryNotFoundError 계열 예외를 던지며 실패합니다. 즉 오프라인 모드는 재다운로드를 막아주는 것이지, 다운로드 자체를 대신해주지는 않습니다.
또 컨테이너를 매번 새로 만들어 쓰는 환경이라면 HF_HOME을 아무리 고정해도 그 경로 자체가 컨테이너와 함께 사라지므로 별 의미가 없습니다. 이 경우에는 캐시 폴더를 호스트 볼륨이나 네트워크 스토리지에 마운트해서 컨테이너 재생성과 무관하게 유지되도록 해야 합니다. 그리고 오프라인 모드를 상시 켜두면 원본 저장소에 새 리비전이 올라와도 자동으로 감지하지 못하므로, 모델을 주기적으로 갱신해야 하는 파이프라인이라면 배포 전에 한 번은 오프라인 스위치를 끄고 최신 상태를 동기화하는 단계를 별도로 두는 편이 안전합니다.
윈도우 환경에서는 원인이 하나 더 있습니다. huggingface_hub 캐시는 원본 파일을 심볼릭 링크로 스냅샷 폴더에 연결하는 구조인데, 개발자 모드가 꺼져 있으면 심볼릭 링크를 만들 권한이 없어 파일을 통째로 복사하는 방식으로 대체됩니다. 이 과정에서 캐시 크기가 예상보다 커지거나 일부 도구에서 캐시를 인식하지 못해 재다운로드로 이어지는 사례가 보고돼 있습니다. 자세한 캐시 구조와 관리 옵션은 Hugging Face 공식 캐시 관리 가이드에서 확인할 수 있습니다.
배포 스크립트에 오늘 바로 넣어볼 두 줄
Hugging Face 모델이 매번 다시 다운로드되는 문제는 캐시 위치를 scan_cache_dir()로 먼저 눈으로 확인하고, 서비스가 돌아가는 실행 컨텍스트(터미널·cron·컨테이너)에 HF_HOME을 동일하게 고정한 다음, 모델이 이미 캐시돼 있는 배포 환경이라면 HF_HUB_OFFLINE=1과 local_files_only=True를 함께 켜는 순서로 접근하면 대부분 해결됩니다. 다만 컨테이너 재생성마다 캐시 폴더가 초기화되는 구조라면 환경변수만으로는 해결되지 않으니, 캐시 폴더를 영구 볼륨에 붙이는 작업이 먼저입니다.
지금 서버에서 반복 실행되는 스크립트가 있다면, 다음 실행 전에 scan_cache_dir()로 캐시 상태부터 찍어보는 것을 추천합니다. 캐시가 비어 있다면 환경변수 문제이고, 캐시가 차 있는데도 다시 받는다면 HF_HOME 값이 실행 시점마다 달라지고 있는지부터 확인해 보세요.
