# Filesystem API를 통해 Hub와 상호작용

[HfApi](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_api#huggingface_hub.HfApi) 외에도 `huggingface_hub` 라이브러리는 Hugging Face Hub에 대한 파이썬 스타일의 [fsspec-compatible](https://filesystem-spec.readthedocs.io/en/latest/) 파일 인터페이스인 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)를 제공합니다. [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)는 [HfApi](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_api#huggingface_hub.HfApi)를 기반으로 구축되어 `cp`, `mv`, `ls`, `du`, `glob`, `get_file`, `put_file`와 같은 일반적인 파일 시스템 스타일의 작업을 제공합니다.

> [!WARNING]
> [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)은 fsspec 호환성을 제공하며, 이를 요구하는 라이브러리(예: `pandas`로 Hugging Face 데이터셋과 버킷을 직접 읽는 경우)에 유용합니다. 그러나 이러한 호환성 레이어로 인해 추가 오버헤드가 발생합니다. 더 나은 성능과 안정성을 위해 가능할 경우 [HfApi](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_api#huggingface_hub.HfApi) 메서드를 사용하는 것이 권장됩니다.

## 사용

```python
>>> from huggingface_hub import hffs

>>> # List all files in a dataset directory
>>> hffs.ls("datasets/my-username/my-dataset-repo/data", detail=False)
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']

>>> # List all files in a bucket directory
>>> hffs.ls("buckets/my-username/my-bucket/experiment-data", detail=False)
['bucket/my-username/my-bucket/data/train-0000.parquet', 'bucket/my-username/my-bucket/data/train-0001.parquet', ...]

>>> # List all ".csv" files in a dataset repository
>>> hffs.glob("datasets/my-username/my-dataset-repo/**/*.csv")
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']

>>> # Read a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/train.csv", "r") as f:
...     train_data = f.readlines()

>>> # Read the content of a remote file as a string
>>> train_data = hffs.read_text("datasets/my-username/my-dataset-repo/data/train.csv", revision="dev")

>>> # Write a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/validation.csv", "w") as f:
...     f.write("text,label")
...     f.write("Fantastic movie!,good")
```

선택적 `revision` 인수를 전달하여 브랜치, 태그 이름, 커밋 해시와 같은 특정 커밋에서 작업을 실행할 수 있습니다. `revision`은 Buckets와 호환되지 않는다는 점에 유의하세요.

Python의 내장 `open`과 달리, `fsspec`의 `open`은 기본적으로 바이너리 모드인 `"rb"`를 사용합니다. 따라서 텍스트 모드로 읽기에는 `"r"`, 쓰기에는 `"w"`를 명시적으로 설정해야 합니다. 파일에 추가하는 작업(모드 `"a"` 및 `"ab"`)은 아직 지원되지 않습니다.

## 대형 저장소 나열

`find`와 `glob`과 같이 파일을 재귀적으로 나열하는 작업은 저장소의 전체 콘텐츠를 가져와야 합니다. Hub는 이러한 항목을 페이지 단위로 반환하며, 이전 페이지를 수신한 후에만 다음 페이지를 요청할 수 있습니다. 따라서 80만 개의 파일을 보유한 저장소를 나열하려면 약 800개의 순차적 요청이 필요하며, 이로 인해 약 30분이 소요됩니다.

이를 방지하기 위해 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)는 대형 저장소를 디렉터리별로 병렬로 나열합니다:

```python
>>> from huggingface_hub import hffs

>>> # Takes ~30s on a repository holding 800k files
>>> files = hffs.glob("datasets/allenai/objaverse/**/*.glb", maxdepth=3)
```

동시 요청의 수는 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)의 `max_workers` 인자로 제어됩니다. 기본값은 16이며, 병렬 목록 표시를 비활성화하려면 1로 설정할 수 있습니다. `maxdepth`를 전달하면 Hub가 실제로 요청된 항목만 반환하므로 목록 표시 속도가 크게 빨라진다는 점에 유의하세요.

## 목록을 최신 상태로 유지

디렉터리는 한 번만 나열되고 그 내용이 캐시되므로, 다른 사람이 방금 변경한 디렉터리는 자동으로 반영되지 않습니다. [HfFileSystem.invalidate_cache()](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem.invalidate_cache)는 캐시된 나열을 삭제하며, 인자 없이 호출하면 모든 경로에 대해, 인자를 전달하면 해당 경로(및 상위 경로)에 대해 적용됩니다:

```python
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # listing is cached
>>> # ... another process uploads a file to the bucket ...
>>> hffs.invalidate_cache("buckets/my-username/my-bucket/data")
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # listed again
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']
```

버킷의 경우, `huggingface_hub`가 이를 대신 처리할 수 있습니다. Hub는 버킷의 파일 변경 사항을 발생 시점에 스트리밍하며, [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)은 변경 사항이 도착하는 즉시 해당 변경 사항에 영향을 받는 목록을 삭제합니다. `live_follow=True`로 활성화합니다:

```python
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(live_follow=True)
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # starts following that bucket
>>> # ... another process uploads a file to the bucket ...
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # refreshed as changes arrive
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']
```

또한 `fsspec.filesystem("hf", live_follow=True)`를 통해 fsspec으로 전달하거나, 해당 인수를 지원하는 라이브러리(pandas, arrow, ...)의 `storage_options` 인수를 통해 전달할 수도 있습니다.

다음과 같은 사항을 참고하세요:

- **버킷만 해당됩니다.** 모델, 데이터셋 및 스페이스 저장소는 git 저장소이며 Hub는 이러한 변경 사항을 스트리밍하지 않습니다: 새 커밋을 확인하려면 [HfFileSystem.ls()](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem.ls)에 `refresh=True`를 전달하거나 [HfApi.list_repo_tree()](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_api#huggingface_hub.HfApi.list_repo_tree)를 사용하세요.
- **목록과 해당 메타데이터만 새로고침됩니다.** 파일을 읽을 때는 항상 Hub에서 콘텐츠가 요청되므로, 라이브 팔로우는 `ls`, `info`, `exists`, `glob`, ...가 보고하는 내용에만 영향을 줍니다.
- 버킷이 나열되는 즉시 Following이 시작되며, 각 Following 대상 버킷당 하나의 백그라운드 연결이 유지됩니다. 이 연결은 모든 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem) 인스턴스에서 공유됩니다. 이러한 이유로 해당 옵션은 opt-in 방식입니다.

## 통합

URL이 다음 스키마를 따르는 경우, `fsspec`을 통합하는 모든 라이브러리와 함께 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)를 사용할 수 있습니다:

```
hf://[<repo_type_prefix>]<repo_id>[@<revision>]/<path/in/repo>
```

`repo_type_prefix`는 데이터셋의 경우 `datasets/`, Spaces의 경우 `spaces/`이며, 모델은 URL에 접두사가 필요 없습니다.

리포지토리 외에도 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)는 S3와 유사한 객체 저장소인 Hugging Face Buckets를 지원합니다(자세한 내용은 [이 가이드](./buckets)를 참고하세요):

```
hf://buckets/<bucket_id>/<path/in/bucket>
```

Hub와의 상호작용을 단순화하는 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)의 몇 가지 흥미로운 통합은 다음과 같습니다:

* Hub 저장소에서 [Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#reading-writing-remote-files) DataFrame 읽기/쓰기:

  ```python
  >>> import pandas as pd

  >>> # Read a remote CSV file into a dataframe
  >>> df = pd.read_csv("hf://datasets/my-username/my-dataset-repo/train.csv")
  >>> df = pd.read_csv("hf://buckets/my-username/my-bucket/train.csv")

  >>> # Write a dataframe to a remote CSV file
  >>> df.to_csv("hf://datasets/my-username/my-dataset-repo/test.csv")
  >>> df.to_csv("hf://buckets/my-username/my-bucket/test.csv")
  ```

동일한 워크플로우는 [Dask](https://docs.dask.org/en/stable/how-to/connect-to-remote-data.html) 및 [Polars](https://pola-rs.github.io/polars/py-polars/html/reference/io.html) DataFrame에도 사용할 수 있습니다.

* Querying (remote) [DuckDB](https://duckdb.org/docs/guides/python/filesystems)를 사용하는 Hub 파일:

  ```python
  >>> from huggingface_hub import HfFileSystem
  >>> import duckdb

  >>> fs = HfFileSystem()
  >>> duckdb.register_filesystem(fs)
  >>> # Query a remote file and get the result back as a dataframe
  >>> fs_query_file = "hf://datasets/my-username/my-dataset-repo/data_dir/data.parquet"
  >>> df = duckdb.query(f"SELECT * FROM '{fs_query_file}' LIMIT 10").df()
  ```

* [Zarr](https://zarr.readthedocs.io/en/stable/tutorial.html#io-with-fsspec)를 배열 저장소로 Hub를 사용하는 방법:

  ```python
  >>> import numpy as np
  >>> import zarr

  >>> embeddings = np.random.randn(50000, 1000).astype("float32")

  >>> # Write an array to a repo
  >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="w")
  >>> foo = root.create_group("embeddings")
  >>> foobar = foo.zeros(name="experiment_0", shape=(50000, 1000), chunks=(10000, 1000), dtype="f4")
  >>> foobar[:] = embeddings

  >>> # Read an array from a repo
  >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="r")
  >>> first_row = root["embeddings/experiment_0"][0]
  ```

## 인증

많은 경우, Hub와 상호작용하려면 Hugging Face 계정으로 로그인해야 합니다. Hub의 인증 방법에 대한 자세한 내용은 문서의 [Authentication](../quick-start#authentication) 섹션을 참고하세요.

`token`을 [HfFileSystem](/docs/huggingface_hub/v2.4.0/ko/package_reference/hf_file_system#huggingface_hub.HfFileSystem)의 인자로 전달하여 프로그래밍 방식으로 로그인하는 것도 가능합니다:

```python
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(token=token)
```

이 방식으로 로그인하는 경우, 소스 코드를 공유할 때 토큰이 실수로 노출되지 않도록 주의하세요!

