왜 내 모델이 Hugging Face Spaces에 배포되지 않을까 (그리고 Git LFS가 실제로 하는 일)

발행: (2026년 1월 11일 오전 11:02 GMT+9)
10 분 소요
원문: Dev.to

Source: Dev.to

(번역을 진행하려면 번역하고자 하는 전체 텍스트를 제공해 주세요.)

내가 시도한 내용 (그리고 왜 계속 실패했는지)

리포지토리를 푸시하려고 했을 때, Git이 다음과 같은 오류와 함께 푸시를 거부했습니다:

remote: -------------------------------------------------------------------------
remote: Your push was rejected because it contains files larger than 10 MiB.
remote: Please use https://git-lfs.github.com/ to store large files.
remote: See also: https://hf.co/docs/hub/repositories-getting-started#terminal
remote:
remote: Offending files:
remote:   - model.pkl (ref: refs/heads/main)
remote: -------------------------------------------------------------------------
To https://huggingface.co/spaces/chloezhoudev/minima
 ! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://huggingface.co/spaces/chloezhoudev/minima'

Git이 불평하고 있는 것이 model.pkl 파일이 너무 크다는 것은 알았지만, 왜 이것이 문제인지, “Git LFS”가 실제로 무엇을 의미하는지 잘 이해하지 못했습니다. 이전에 사용해 본 적도 없었습니다.

그래서 오류 메시지에 적힌 안내를 따라 단계별로 해결해 보았습니다.

1️⃣ Git LFS 설치 및 초기화

brew install git-lfs    # Install Git LFS (macOS via Homebrew)
git lfs install         # Initialise Git LFS and register Git hooks
git lfs version         # Confirm Git LFS installation

2️⃣ 모델 파일을 추적하고 푸시

git lfs track "model.pkl"
git add model.pkl
git commit -m "Track model file with Git LFS"
git push

다시 같은 오류가 발생했습니다.

3️⃣ 인덱스에서 파일 제거 시도

git rm --cached model.pkl
git lfs track "model.pkl"
git commit -m "Store model file using Git LFS"
git push

여전히 같은 오류. 😅

4️⃣ 고아 브랜치 만들기

git checkout --orphan clean-main
git add .
git commit -m "Initial deployment with Git LFS model"
git branch -M main
git push -f origin main

이번에는 푸시가 성공했습니다.

결국 내가 Git과 Git LFS에 대해 배운 것

왜 Git이 내 푸시를 계속 거부했을까?

Hugging Face 저장소는 pre‑receive hook을 적용하여 푸시 내의 모든 커밋을 스캔하고, 어떤 커밋에든 10 MiB보다 큰 파일이 포함되어 있으면 푸시를 거부합니다.

큰 파일이 일반 Git 블롭으로 어떤 커밋에 저장되어 있으면, 나중에 LFS 트래킹을 추가하더라도 훅은 푸시를 거부합니다.

Git LFS는 실제로 무엇을 할까?

  • Normal Git은 파일 내용을 blob 객체로 저장합니다. 추가한 각 파일은 원본 크기 정도로 저장소 히스토리에 보관됩니다. 바이너리 파일의 경우 해당 파일을 수정하는 모든 커밋에 전체 데이터가 보관된다는 의미입니다.
  • Git LFS는 큰 파일을 포인터 파일(작은 텍스트 파일)로 대체하고 실제 바이너리 데이터는 전용 LFS 서버에 저장합니다. git add로 LFS 규칙에 맞는 파일을 추가하면 Git LFS가 포인터를 만들고 이를 Git에 전달하며, 실제 파일은 LFS 스토어에 업로드됩니다.

git rm --cached가 도움이 안 되었을까?

git rm --cached model.pkl은 현재 작업 트리의 인덱스에서만 파일을 제거했습니다. 큰 블롭은 이미 푸시하려던 이전 커밋에 존재하고 있었기 때문에, pre‑receive hook은 여전히 초과 크기 블롭이 포함된 커밋을 발견하고 푸시를 거부했습니다.

왜 고아 브랜치를 만들면 모든 문제가 해결됐을까?

git checkout --orphan clean-main은 이전 커밋이 전혀 없는 새로운 히스토리를 시작했습니다. LFS를 설정한 후에 파일을 추가하고 한 번만 커밋함으로써, 저장소의 유일한 커밋에는 큰 블롭 대신 LFS 포인터가 들어갔습니다. 따라서 pre‑receive hook은 초과 크기 블롭을 발견하지 못하고 푸시를 허용했습니다.

핵심 요점

  1. 대용량 파일은 저장소 기록에 들어가기 에 LFS로 추적해야 합니다.
    대용량 파일을 이미 커밋한 뒤에 LFS 추적을 추가해도 해당 커밋을 자동으로 다시 쓰지는 않습니다.

  2. .gitattributes 파일이 LFS 추적을 제어합니다.
    Hugging Face Spaces는 자동으로 다음과 같은 라인을 추가합니다:

    *.pkl filter=lfs diff=lfs merge=lfs -text

    이는 Git에게 *.pkl 파일을 LFS 객체로 취급하도록 지시합니다. 단, 파일을 처음 추가할 때 LFS가 설치되어 있어야 합니다.

  3. 파일을 인덱스에서 제거해도 기록에서 사라지지는 않습니다.
    과도한 블롭을 완전히 없애려면 히스토리를 다시 써야 합니다(예: git filter-repo 사용 또는 새로운 고아 브랜치 생성).

  4. 고아 브랜치는 깨끗하게 시작하는 빠른 방법입니다.
    작은 프로젝트에서 대용량 블롭이 없음을 보장하고 싶다면, LFS 설정 후 고아 브랜치를 만들어 첫 커밋을 깨끗하게 만들 수 있습니다.

TL;DR

  • 대용량 파일을 추가하기 전에 Git LFS를 설치하세요.
  • .gitattributes에 적절한 패턴이 포함되어 있는지 확인하세요.
  • 실수로 대용량 파일을 커밋했다면 히스토리를 다시 쓰거나 새 고아 브랜치를 만들고 LFS 추적을 활성화한 상태로 다시 커밋하세요.

이제 모델이 효율적으로 저장되고, Space가 오류 없이 배포되며, Git LFS가 무엇을 하는지와 고아‑브랜치 트릭이 왜 작동했는지 이해하게 되었습니다.

git rm — cached는 어떨까요?

⚠️ 중요

git rm --cached는 향후 커밋에만 영향을 미칩니다. 기존 Git 히스토리에서 파일을 제거하지 않습니다.

  • 이 명령은 파일을 스테이징 영역에서 제거하고 이후 커밋에서 추적을 중단하지만, 작업 디렉터리에는 파일을 그대로 남겨 둡니다.
  • 그러나 큰 파일이 처음 추가된 이전 커밋을 삭제하는 작업은 수행하지 않습니다.

원래 커밋에 model.pkl이 일반 Git 블롭으로 그대로 포함되어 있었기 때문에, 문제 파일은 리포지토리 히스토리에 남아 있었고 — 그 결과 Hugging Face는 푸시를 계속 거부했습니다.

작동한 해결책

새 브랜치를 히스토리 없이 만들면 (git checkout — orphan) 모든 것이 해결되었습니다. 시작부터 깨끗한 상태였고 커밋이 전혀 없었기 때문입니다.

  1. 오프린 브랜치 만들기

    git checkout --orphan new-main
  2. 파일 추가 (Git LFS가 이미 설정된 상태)

    git add .
    git commit -m "Add files with LFS"
  3. 브랜치를 main으로 이름 바꾸고 강제 푸시

    git branch -M main
    git push -f origin main

Warning: --orphan을 사용하고 특히 git push -f를 사용하는 것은 여러 협업자가 같은 브랜치를 사용할 경우 위험합니다. 이는 브랜치의 히스토리를 완전히 교체하기 때문입니다. 제 경우에는 Space 저장소가 배포 전용이었으므로 괜찮았지만, 팀 환경에서는 주의가 필요합니다.

💡 보너스: Git LFS가 더 이상 유일한 옵션이 아니다

Hugging Face는 이제 **git‑xet**도 추천합니다. 이는 대규모 머신러닝 아티팩트를 위해 특별히 설계된 최신 백엔드입니다.

  • Git LFS는 큰 파일을 Git 외부로 이동시킵니다.
  • git‑xet는 Git이 대용량 콘텐츠를 저장하는 방식을 완전히 재고합니다.

그 모든 디버깅을 마친 후, 모델이 최종적으로 배포되어 예상대로 작동합니다. 라이브 데모를 **여기**에서 체험해 보세요.

읽어 주셔서 감사합니다. 😊

Back to Blog

관련 글

더 보기 »

안녕, 뉴비 여기요.

안녕! 나는 다시 S.T.E.M. 분야로 돌아가고 있어. 에너지 시스템, 과학, 기술, 공학, 그리고 수학을 배우는 것을 즐겨. 내가 진행하고 있는 프로젝트 중 하나는...