본문 바로가기
WIKI 기술 지식 베이스

lakeFS 데이터를 로컬에서 다루기

원문 보기 위키 갱신

lakeFS 데이터를 로컬에서 다루기 (Working with lakeFS Data Locally)

lakeFS는 수십억 개의 객체까지 확장되도록 설계된 확장형 데이터 버전 관리 시스템이에요. 데이터가 커질수록 한 대의 머신에서 데이터를 소비하기는 점점 어려워지죠. lakeFS는 원격에 저장된 대규모 데이터를 효율적으로 관리하게 해서 이 문제를 다뤄요.

대용량 데이터셋을 관리하는 능력에 더해, lakeFS는 버전이 관리되는 데이터를 로컬 파일시스템 디렉터리처럼 노출하는 유연성도 제공해요.

이 문서는 lakeFS 데이터를 로컬로 노출하는 두 가지 대표 방법, 그러니까 lakeFS Mount와 lakectl local을 소개해요. 두 방법은 성능 특성이 서로 달라요.

출처: 문서

본문

사용 사례

ML 모델의 로컬 개발

머신러닝 모델 개발은 다양한 데이터 버전, 변환, 알고리즘, 하이퍼파라미터를 실험하는 역동적이고 반복적인 과정이에요. 이 반복 워크플로를 최적화하려면 실험이 빠르고, 추적이 쉽고, 재현 가능해야 해요. 개발 중에 모델 데이터를 로컬로 두면 개발 과정이 좋아져요. 인터랙티브하고 오프라인인 개발이 가능해지고 데이터 접근 지연이 줄어들어 개발 속도가 빨라져요.

데이터를 로컬에서 사용할 수 있어야 데이터 버전 관리 시스템과 Git 같은 소스 관리 시스템을 자연스럽게 통합할 수 있어요. 이 통합은 모델 재현성에 필수적이고, 더 효율적이고 협업적인 모델 개발 환경을 만들어 줘요.

GPU 활용 최적화를 위한 데이터 로컬성

딥러닝 모델 학습은 값비싼 GPU를 요구해요. 이런 프로그램을 돌릴 때의 목표는 GPU 사용을 최적화하고 놀게 두지 않는 것이죠. 많은 딥러닝 작업은 이미지에 접근하고, 경우에 따라 같은 이미지를 여러 번 접근해요. 데이터를 로컬로 두면 원격 스토리지에 접근하는 불필요한 왕복 시간을 없애 비용을 줄일 수 있어요.

Git과 함께 사용하기

코드와 데이터 버전 관리를 통합하면 코드 버전과 그 코드가 실행된 정확한 데이터 버전을 연결할 수 있어요. 여러 부품이 움직이는 복잡한 환경도 재현 가능해지죠. lakeFS가 데이터를 버저닝하는 방식이 Git이 코드를 버저닝하는 방식과 같아서 두 도구가 자연스럽게 맞물리고, 코드와 데이터를 아우르는 단일 재현 가능 워크플로가 생겨요.

이 조합은 몇 가지 흔한 목표를 지원해요. 재현 가능한 ML 모델을 개발하려면 모델 코드 버전과 입력 데이터 버전을 함께 기록해 뒀다가 나중에 결과를 재현하면 돼요. 보통은 lakectl local 명령으로 아래 예시처럼 코드 옆에 데이터를 체크아웃해요. 재현 가능한 ETL 파이프라인을 만들려면 각 단계의 코드 버전과 입력·출력 데이터 버전을 함께 추적하세요. 데이터 오류를 문제 해결하고 재현하기가 훨씬 쉬워져요. Airflow with Git and lakeFS 샘플이 이 과정을 처음부터 끝까지 보여 줘요.

lakeFS Mount: lakeFS 데이터를 로컬 디렉터리처럼 효율적으로 노출하기

정보

Mount는 별도 설치가 필요 없어요. 접근 권한은 문의를 통해 받으세요.

사전 준비물

  • lakeFS Enterprise 또는 lakeFS Cloud로 동작 중인 lakeFS 서버

  • lakectl 명령줄 유틸리티 설치: 공식 lakeFS CLI이고 lakeFS Mount는 이 위에 만들어져 있어요.

  • 설정 안내에 따라 lakeFS 서버에 접근하도록 lakectl이 제대로 구성되어 있어야 해요.

lakeFS 참조를 로컬 디렉터리로 마운트하기

lakeFS Mount는 호스트 컴퓨터에 가상 마운트포인트를 노출하는 방식으로 동작해요.

이건 "로컬 디렉터리처럼" 행동해서, 애플리케이션이 모든 데이터가 로컬에 있는 것처럼 읽고 쓰고 상호작용할 수 있게 해 줘요. lakeFS Mount는 그 뒤에서 요청 시 데이터를 느리게(lazily) 가져오고, 접근된 객체를 캐싱하고, 메타데이터를 효율적으로 관리해 최상의 성능을 내요. lakeFS Mount의 성능 최적화 방식에 대해 더 읽어 보세요.

참조를 마운트하는 건 명령 한 줄이에요:

everest mount lakefs://example-repo/example-branch/path/to/data/ ./my_local_dir

실행하고 나면 my_local_dir 디렉터리에 우리가 지정한 원격 경로의 내용이 나타나야 해요. 확인해 볼게요:

ls -l ./my_local_dir/

마운트된 경로의 목록이 반환되면 성공이에요.

팁

lakeFS Mount는 최적 성능을 위한 다양한 튜닝 옵션을 제공해요. lakeFS Mount의 동작 방식과 설정 방법을 더 읽어 보세요.

마운트에서 읽기

lakeFS Mount에서 읽는 데는 특별한 도구, 통합, SDK가 필요 없어요! 코드에서 그 디렉터리를 가리키고 진짜 로컬인 것처럼 읽으면 돼요:

#!/usr/bin/env python
import glob

for image_path in glob.glob('./my_local_dir/*.png'):
    with open(image_path, 'rb') as f:
        process(f)

언마운트

다 썼으면 간단히 실행하세요:

everest umount ./my_local_dir

lakeFS Mount를 언마운트하면서 백그라운드 작업을 정리해요.

lakectl local: lakeFS 데이터를 로컬 디렉터리와 동기화하기

lakeFS CLI lakectl의 local 명령은 데이터를 호스트 머신으로 복사해 로컬에서 lakeFS 데이터를 다룰 수 있게 해 줘요. 로컬 디렉터리를 원격 lakeFS 위치와 동기화하고, lakeFS를 Git과 자연스럽게 통합할 수 있죠.

사용할 수 있는 lakectl local 명령은 다음과 같아요:

명령 하는 일 비고
init 데이터 동기화를 위해 로컬 디렉터리와 lakeFS 원격 URI를 연결해요 init을 되돌리려면 초기화된 디렉터리에 생성된 .lakefs_ref.yaml 파일을 지우면 돼요
clone 경로에서 빈 로컬 디렉터리로 lakeFS 데이터를 클론하고 디렉터리를 초기화해요 디렉터리 하나는 단일 lakeFS 원격 위치만 추적할 수 있어요. 즉, 이미 초기화된 디렉터리로는 데이터를 클론할 수 없어요
list lakeFS와 동기화된 디렉터리를 나열해요 init이나 clone 명령 뒤에는 list 명령으로 성공 여부를 확인하는 걸 권해요
status 디렉터리와 그 디렉터리가 추적하는 원격 위치의 원격·로컬 변경을 보여 줘요
commit 로컬 디렉터리에서 추적 중인 lakeFS 브랜치로 변경을 커밋해요 lakeFS 원격 위치에 연결된 디렉터리의 커밋되지 않은 변경은 lakectl local commit을 하기 전까지 lakeFS에 반영되지 않아요.
pull lakeFS 원격 위치에서 연결된 로컬 디렉터리로 최신 변경을 가져와요
checkout 로컬 디렉터리를 lakeFS ref의 상태와 동기화해요

경고

로컬에서 다루는 데이터 크기는 로컬 머신에서 매끄럽게 동작할 만한 수준이어야 해요. 보통 15 GB를 넘지 않는 게 좋아요.

설정

lakectl local 명령은 lakectl 설정 파일로 설정할 수 있어서 심볼릭 링크 같은 특수한 경우를 다룰 수 있어요. 다음 설정 옵션들이 local 섹션 아래에서 쓸 수 있어요:

설정 옵션 설명 기본값
skip_non_regular_files 기본적으로 lakectl local은 로컬 디렉터리에 일반 파일이 아닌 파일이 있으면 실패해요. true로 설정하면 실패 대신 무시해요. false
symlink_support lakectl local 명령이 심볼릭 링크를 지원하고 처리할지 제어해요. false

설정 예시:

local:
  symlink_support: true

symlink_support를 켜면 lakectl local 명령은 심볼릭 링크 대상을 지정하는 특수 메타데이터 객체를 만들어 심볼릭 링크의 상태를 저장하고 복원해요. 심볼릭 링크를 표현하는 메타데이터 객체는 데이터 업로드 시 생성돼요. 반대로 데이터 다운로드 시에는 lakectl이 이 메타데이터 객체를 바탕으로 로컬 디렉터리에 심볼릭 링크를 다시 만들어요. 덕분에 데이터 관리 워크플로 안에서 심볼릭 링크를 매끄럽게 통합할 수 있죠. 다만 이 기능을 끄면 이전에 만든 심볼릭 링크가 빈 객체로 취급되어, 동기화 작업에서 대상이 보존되거나 재생성되지 않아요. 워크플로가 심볼릭 링크에 의존한다면 데이터 무결성과 일관성을 위해 이 기능을 켜는 게 중요해요.

참고

skip_non_regular_files를 켜면 동기화 작업에서 로컬 디렉터리의 심볼릭 링크가 무시돼요. 심볼릭 링크를 다뤄야 한다면 symlink_support를 대신 고려하세요. 다만 이 기능은 동작과 제한이 다를 수 있어요.

경고

심볼릭 링크는 시스템의 어떤 파일이든 가리킬 수 있어서 잠재적으로 위험할 수 있어요. symlink_support가 켜져 있을 때 lakeFS는 대상이 심볼릭 링크인 곳으로는 데이터를 다운로드하지 않아요. 예상 밖의 동작을 막기 위해서예요.

예시: lakectl local을 Git과 함께 사용하기

이미지가 알파카(alpaca)인지 아닌지 예측하는 ML 모델을 개발해 볼게요. 목표는 모델의 입력을 개선하는 거예요. 모델 코드는 Git으로, 모델 데이터셋은 lakeFS로 버저닝돼요. lakectl local로 코드 버전과 데이터 버전을 묶어 모델 재현성을 달성할 거예요.

준비

시작하기 위해 모델 코드를 담은 is_alpaca라는 Git 저장소를 초기화했어요.

lakeFS 저장소도 만들고 Kaggle의 is_alpaca 학습 데이터셋을 업로드했어요.

실험을 위한 격리 환경 만들기

목표는 모델 예측을 개선하는 거예요. 그러려면 학습 데이터셋을 편집해 가며 실험할 거예요. 데이터가 개선됐고 준비됐다고 확신한 뒤에야 무엇이든 바꾸려고, 실험은 격리된 환경에서 진행해요.

experiment-1이라는 새 lakeFS 브랜치를 만들게요. is_alpaca 데이터셋은 그 브랜치에서 접근 가능하고, 그 브랜치로만 데이터와 상호작용할 거예요.

코드 쪽에서는 데이터셋 튜닝 중에 메인 브랜치를 오염시키지 않도록 역시 experiment-1이라는 Git 브랜치를 만들어요.

lakeFS 데이터를 로컬 Git 저장소로 클론하기

train.py 스크립트를 살펴보면 input 디렉터리의 입력을 기대하는 걸 볼 수 있어요.

#!/usr/bin/env python
import tensorflow as tf

input_location = './input'
model_location = './models/is_alpaca.h5'

def get_ds(subset):
    return tf.keras.utils.image_dataset_from_directory(
        input_location, validation_split=0.2, subset=subset,
        seed=123, image_size=(244, 244), batch_size=32)

train_ds = get_ds("training")
val_ds = get_ds("validation")

model = tf.keras.Sequential([
    tf.keras.layers.Rescaling(1./255),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(2)])

# Fit and save
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])
model.fit(train_ds, validation_data=val_ds, epochs=3)
model.save(model_location)

즉, 모델을 로컬에서 개발하고 실험하려면 lakeFS가 관리하는 is_alpaca 데이터셋을 그 경로에 로컬로 둬야 해요. 그러려면 로컬 Git 저장소 루트에서 lakectl local clone 명령을 실행할 거예요:

lakectl local clone lakefs://is-alpaca/experiment-1/dataset/train/ input

이 명령은 (지금까지 존재하지 않던) 로컬 input 디렉터리와 지정한 lakeFS 경로 사이의 diff를 수행하고, lakeFS에서 내려받을 파일이 있다는 걸 파악해요.

Successfully cloned lakefs://is-alpaca/experiment-1/dataset/train/ to ~/ml_models/is_alpaca/input

Clone Summary:

Downloaded: 250
Uploaded: 0
Removed: 0

Git 저장소 루트에서 lakectl local list를 실행하면 input 디렉터리가 lakeFS 접두사(Remote URI)와 동기화됐고, 어떤 lakeFS 데이터 버전(Synced Commit)을 추적 중인지 보여 줘요:

 is_alpaca % lakectl local list
+-----------+------------------------------------------------+------------------------------------------------------------------+
| DIRECTORY | REMOTE URI                                     | SYNCED COMMIT                                                    |
+-----------+------------------------------------------------+------------------------------------------------------------------+
| input     | lakefs://is-alpaca/experiment-1/dataset/train/ | 589f87704418c6bac80c5a6fc1b52c245af347b9ad1ea8d06597e4437fae4ca3 |
+-----------+------------------------------------------------+------------------------------------------------------------------+

코드 버전과 데이터 버전 묶기

이제 Git에게 추가한 데이터셋을 스테이징하라고 알리고 Git 브랜치 상태를 살펴볼게요:

is_alpaca % git add input/
is_alpaca % git status
On branch experiment-1
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
 new file:   input/.lakefs_ref.yaml

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
 modified:   .gitignore

.gitignore 파일이 바뀌었고, lakeFS에서 input 디렉터리로 클론한 파일들은 git이 추적하지 않는 걸 볼 수 있어요. 의도된 거예요 — 데이터를 관리하는 건 lakeFS라는 점을 기억하세요. 그런데 Git이 추적하는 input/.lakefs_ref.yaml이라는 특별한 파일은 뭘까요?

is_alpaca % cat input/.lakefs_ref.yaml

src: lakefs://is-alpaca/experiment-1/dataset/train/s
at_head: 589f87704418c6bac80c5a6fc1b52c245af347b9ad1ea8d06597e4437fae4ca3

이 파일에는 Git 저장소가 현재 가리키는 데이터의 lakeFS 버전이 담겨 있어요.

다음 명령으로 변경을 Git에 커밋할게요:

git commit -m "added is_alpaca dataset"

Git에 커밋하면 모델의 현재 코드 버전이 input/.lakefs_ref.yaml에 나타난 lakeFS 데이터셋 버전과 묶여요.

실험하고 결과 버저닝하기

클론한 입력으로 학습 스크립트를 실행했고 모델이 만들어졌어요. 이제 모델로 도롱뇽(axolotl) 이 알파카인지 예측해 볼게요.

상기하자면 — 도롱뇽은 이렇게 생겼어요. 알파카처럼 생기지 않았죠!

(놀라운) 결과는 다음과 같아요:

is_alpaca % ./predict.py ~/axolotl1.jpeg
{'alpaca': 0.32112, 'not alpaca': 0.07260383}

모델이 더 분명한 예측을 해 주길 기대했으니 개선해 볼게요. 도롱뇽 이미지를 모델 입력 디렉터리에 더 추가할 거예요:

is_alpaca % cp ~/axolotls_images/* input/not_alpaca

데이터셋에 어떤 변경을 했는지 살펴보려면 lakectl local status를 써요.

is_alpaca % lakectl local status input
diff 'local:///ml_models/is_alpaca/input' <--> 'lakefs://is-alpaca/589f87704418c6bac80c5a6fc1b52c245af347b9ad1ea8d06597e4437fae4ca3/dataset/train/'...
diff 'lakefs://is-alpaca/589f87704418c6bac80c5a6fc1b52c245af347b9ad1ea8d06597e4437fae4ca3/dataset/train/' <--> 'lakefs://is-alpaca/experiment-1/dataset/train/'...

╔════════╦════════╦════════════════════════════╗
║ SOURCE ║ CHANGE ║ PATH                       ║
╠════════╬════════╬════════════════════════════╣
║ local  ║ added  ║ not_alpaca/axolotl2.jpeg   ║
║ local  ║ added  ║ not_alpaca/axolotl3.png    ║
║ local  ║ added  ║ not_alpaca/axolotl4.jpeg   ║
╚════════╩════════╩════════════════════════════╝

이 시점에서 데이터셋 변경은 아직 lakeFS가 추적하지 않아요. 실험 브랜치의 커밋되지 않은 변경 영역을 살펴보고 비어 있는지 확인하며 검증할 수 있어요.

이 변경을 lakeFS에 커밋하려면 lakectl local commit을 쓸 거예요:

is_alpaca % lakectl local commit input -m "add images of axolotls to the training dataset"

Getting branch: experiment-1

diff 'local:///ml_models/is_alpaca/input' <--> 'lakefs://is-alpaca/589f87704418c6bac80c5a6fc1b52c245af347b9ad1ea8d06597e4437fae4ca3/dataset/train/'...
upload not_alpaca/axolotl3.png              ... done! [5.04KB in 679ms]
upload not_alpaca/axolotl2.jpeg             ... done! [38.31KB in 685ms]
upload not_alpaca/axolotl4.jpeg             ... done! [7.70KB in 718ms]

Sync Summary:

Downloaded: 0
Uploaded: 3
Removed: 0

Finished syncing changes. Perform commit on branch...
Commit for branch "experiment-1" completed.

ID: 0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6
Message: add images of axolotls to the training dataset
Timestamp: 2024-02-08 17:41:20 +0200 IST
Parents: 589f87704418c6bac80c5a6fc1b52c245af347b9ad1ea8d06597e4437fae4ca3

lakeFS UI를 보면 lakeFS 커밋에, 커밋 시점에 연결된 Git 저장소의 코드 버전이 무엇이었는지 알려 주는 메타데이터가 포함된 걸 확인할 수 있어요.

Git 저장소를 살펴보면 input/.lakefs_ref.yaml이 최신 lakeFS 커밋 0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6를 가리키고 있어요.

이제 수정된 데이터셋으로 모델을 다시 학습시키고 도롱뇽이 알파카인지 예측해 볼게요:

is_alpaca % ./predict.py ~/axolotl1.jpeg
{'alpaca': 0.12443, 'not alpaca': 0.47260383}

결과가 실제로 더 정확해졌어요.

로컬 디렉터리를 lakeFS와 동기화하기

최신 모델이 신뢰할 만한 예측을 한다고 판단했으니, 이번엔 사진 한 장이 아니라 테스트 데이터셋으로 검증해 볼게요. Kaggle이 제공하는 테스트 데이터셋을 사용할 거예요. Git 저장소에 로컬 testDataset 디렉터리를 만들고 테스트 데이터셋으로 채워 넣어요.

이제 lakectl local init으로 testDataset 디렉터리를 lakeFS 저장소와 동기화할 거예요:

is_alpaca % lakectl local init lakefs://is-alpaca/main/dataset/test/ testDataset
Location added to /is_alpaca/.gitignore
Successfully linked local directory '/is_alpaca/testDataset' with remote 'lakefs://is-alpaca/main/dataset/test/'

디렉터리가 성공적으로 연결됐는지 검증할게요:

is_alpaca % lakectl local list
+-------------+-------------------------------------------------+------------------------------------------------------------------+
| DIRECTORY   | REMOTE URI                                      | SYNCED COMMIT                                                    |
+-------------+-------------------------------------------------+------------------------------------------------------------------+
| input       | lakefs://is-alpaca/main/dataset/train/          | 0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6 |
| testDataset | lakefs://is-alpaca/main/dataset/test/           | 0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6 |
+-------------+-------------------------------------------------+------------------------------------------------------------------+

이제 git add testDataset으로 Git이 testDataset 디렉터리를 추적하도록 알릴게요. 앞서 봤듯이 Git은 그 디렉터리의 내용이 아니라 testDataset/.lakefs_ref.yaml만 추적해요.

로컬 testDataset 디렉터리와 그 lakeFS 위치 lakefs://is-alpaca/main/dataset/test/ 사이의 차이를 보려면 lakectl local status를 써요:

is_alpaca % lakectl local status testDataset

diff 'local:///ml_models/is_alpaca/testDataset' <--> 'lakefs://is-alpaca/0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6/dataset/test/'...
diff 'lakefs://is-alpaca/0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6/dataset/test/' <--> 'lakefs://is-alpaca/main/dataset/test/'...

╔════════╦════════╦════════════════════════════════╗
║ SOURCE ║ CHANGE ║ PATH                           ║
╠════════╬════════╬════════════════════════════════╣
║ local  ║ added  ║ alpaca/alpaca (1).jpg          ║
║ local  ║ added  ║ alpaca/alpaca (10).jpg         ║
║    .         .                  .                ║
║    .         .                  .                ║
║    .         .                  .                ║
║ local  ║ added  ║ not_alpaca/not_alpaca (9).jpg  ║
╚════════╩════════╩════════════════════════════════╝

여러 파일이 로컬에서 동기화된 디렉터리에 추가된 걸 볼 수 있어요.

이 변경을 lakeFS에 적용하려면 커밋할게요:

is_alpaca % lakectl local commit testDataset -m "add is_alpaca test dataset to lakeFS"

Getting branch: experiment-1

diff 'local:///ml_models/is_alpaca/testDataset' <--> 'lakefs://is-alpaca/0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6/dataset/test/'...
upload alpaca/alpaca (23).jpg            ... done! [113.81KB in 1.241s]
upload alpaca/alpaca (26).jpg            ... done! [102.74KB in 1.4s]
          .                                             .
          .                                             .
upload not_alpaca/not_alpaca (42).jpg    ... done! [886.93KB in 14.336s]

Sync Summary:

Downloaded: 0
Uploaded: 77
Removed: 0

Finished syncing changes. Perform commit on branch...
Commit for branch "experiment-1" completed.

ID: c8be7f4f5c13dd2e489ae85e6f747230bfde8e50f9cd9b6af20b2baebfb576cf
Message: add is_alpaca test dataset to lakeFS
Timestamp: 2024-02-10 12:31:53 +0200 IST
Parents: 0b376f01b925a075851bbaffacf104a80de04a43ed7e56054bf54c42d2c8cce6

lakeFS UI를 보면 테스트 데이터가 이제 lakeFS에서 사용 가능해진 걸 알 수 있어요.

마지막으로 로컬 변경을 Git 커밋해 Git 저장소와 lakeFS 저장소의 상태를 연결해요.

팁

로컬 디렉터리를 lakeFS 접두사와 동기화할 때는, 먼저 데이터를 lakeFS에 커밋한 뒤에 동기화된 디렉터리의 .lakefs_ref.yaml 변경을 포함한 Git 커밋을 하는 걸 권해요. 데이터가 lakeFS에 커밋된 후에야 .lakefs_ref.yaml 파일이 그 디렉터리에서 추가된 내용을 포함하는 lakeFS 커밋을 가리키기 때문이에요.

모델 결과 재현하기

도롱뇽이 알파카일 가능성이 더 높다고 예측했던 모델을 다시 실행하고 싶다면 어떻게 할까요? 이 질문은 "학습 데이터셋을 최적화하기 전 시점으로 코드와 데이터를 어떻게 되돌리지?"라는 질문으로 바뀌고, 다시 "그 시점의 Git 커밋 ID가 무엇이었지?"라는 질문이 돼요.

Git 로그를 찾아 보니 이 커밋이 있네요:

commit 5403ec29903942b692aabef404598b8dd3577f8a

    added is_alpaca dataset

이제 git checkout 5403ec29903942b692aabef404598b8dd3577f8a만 하면 모델 결과를 재현할 준비가 끝나요!

lakeFS와 Git이 어떻게 매끄럽게 함께 동작하는지 다른 예시도 보고 싶다면 ML Data Version Control and Reproducibility at Scale 아티클을 확인하세요.

POSIX 파일 권한 추적

실험적 기능

이 기능은 POSIX 호환 파일시스템에서만 lakectl local로 관리되는 파일의 파일 모드, 소유권, 그룹 정보를 추적해요. 현재 Unix 기반 운영체제에서 지원돼요. 실험적 기능을 활성화하기 전에 lakeFS 팀에 문의하세요.

기본적으로 이 기능은 꺼져 있어요. lakectl.yaml의 experimental.local.posix_permissions.enabled 설정이나 LAKECTL_EXPERIMENTAL_LOCAL_POSIX_PERMISSIONS_ENABLED 환경 변수로 켤 수 있어요:

experimental:
  local:
    posix_permissions:
      enabled: true

켜면 lakectl local은 원격 서버와의 동기화의 일부로 파일 권한과 소유권 변경을 추적해요. 원격 경로의 첫 동기화 시 그 경로 아래의 모든 객체를 갱신해 lakeFS에 권한을 저장하기 때문에, 그 첫 동기화 동안에는 파일이 수정된 것처럼 보여요. 기존 원격 경로에서 파일·디렉터리 구조를 만들 때는 기본값이 적용돼요: 파일에는 0o0666 & ~umask, 디렉터리에는 0o0777 & ~umask, 그리고 현재 사용자의 숫자 UID와 GID가요. 디렉터리 권한을 추적하려고 lakectl local은 크기 0짜리 디렉터리 마커(/로 끝나는 경로)를 원격에 기록하고, 파일의 모드·UID·GID 변화를 수정으로 취급해요.

몇 가지 제한이 있어요. POSIX 권한과 함께 lakectl local을 쓰는 모든 머신은 UID와 GID를 공유해야 해요. 추적된 모드는 lakectl local에서만 보이고 UI, lakeFS API, S3 게이트웨이에서는 보이지 않아요. lakectl local이 아닌 클라이언트가 덮어쓰면 유지되지 않는다고 기대해야 해요. 권한이나 소유권 변경에서 비롯된 충돌이 있으면 머지가 실패하고 수정된 파일로 보고돼요. 권한 추적을 켠 채로 로컬 경로를 한 번 동기화했다면, 그 원격 경로로 계속 작업할 때도 이 기능을 켜 두세요.

더 알아보기 (Learn more)

공식 문서: lakeFS Working with Data Locally 가이드