Hub documentation

PyArrow

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

PyArrow

Arrow์€ ์ปฌ๋Ÿผํ˜• ํ˜•์‹์ด๋ฉฐ, ๋น ๋ฅธ ๋ฐ์ดํ„ฐ ๊ตํ™˜๊ณผ ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ถ„์„์„ ์œ„ํ•œ ๋„๊ตฌ ๋ชจ์Œ์ž…๋‹ˆ๋‹ค. PyArrow๊ฐ€ ์›๊ฒฉ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๊ธฐ ์œ„ํ•ด fsspec์„ ์ง€์›ํ•˜๋ฏ€๋กœ, Hugging Face ๊ฒฝ๋กœ(hf://)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Hub์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Hugging Face์—์„œ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ํŒŒ์ผ ํ˜•์‹์ด Parquet์ด๊ธฐ ๋•Œ๋ฌธ์— Parquet ๋ฐ์ดํ„ฐ์— ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ Parquet์€ ๊ตฌ์กฐ, ํƒ€์ดํ•‘, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ฐ ์••์ถ• ๋•๋ถ„์— ํŠนํžˆ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

ํ…Œ์ด๋ธ” ๋กœ๋“œ

๋กœ์ปฌ ํŒŒ์ผ ๋˜๋Š” Hugging Face Datasets์™€ ๊ฐ™์€ ์›๊ฒฉ ์ €์žฅ์†Œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. PyArrow๋Š” CSV, JSON์„ ํฌํ•จํ•˜์—ฌ Parquet ๋“ฑ ๋‹ค์–‘ํ•œ ํฌ๋งท์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:

>>> import pyarrow.parquet as pq
>>> table = pq.read_table("path/to/data.parquet")

Hugging Face์—์„œ ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๋ ค๋ฉด ๊ฒฝ๋กœ๊ฐ€ hf://๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, stanfordnlp/imdb ๋ฐ์ดํ„ฐ์…‹ ์ €์žฅ์†Œ์˜ ๊ฒฝ๋กœ๋Š” hf://datasets/stanfordnlp/imdb์ž…๋‹ˆ๋‹ค. Hugging Face์˜ ๋ฐ์ดํ„ฐ์…‹์—๋Š” ์—ฌ๋Ÿฌ Parquet ํŒŒ์ผ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Parquet ํŒŒ์ผ ํ˜•์‹์€ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์˜ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋งŒ๋“ค๊ณ , ๋ฐ์ดํ„ฐ ๋ถ„์„ ์–ธ์–ด ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ณต์œ ๋ฅผ ์‰ฝ๊ฒŒ ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. plain_text/train-00000-of-00001.parquet ํŒŒ์ผ์„ pyarrow Table๋กœ ๋กœ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค(pyarrow>=21.0 ํ•„์š”):

>>> import pyarrow.parquet as pq
>>> table = pq.read_table("hf://datasets/stanfordnlp/imdb/plain_text/train-00000-of-00001.parquet")
>>> table
pyarrow.Table
text: string
label: int64
----
text: [["I rented I AM CURIOUS-YELLOW from my video store because of all the controversy that surrounded it (... 1542 chars omitted)", ...],...,[..., "The story centers around Barry McKenzie who must go to England if he wishes to claim his inheritan (... 221 chars omitted)"]]
label: [[0,0,0,0,0,...,0,0,0,0,0],...,[1,1,1,1,1,...,1,1,1,1,1]]

์ „์ฒด Parquet ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด Parquet ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ row group์„ ํ•˜๋‚˜์”ฉ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

>>> import pyarrow.parquet as pq
>>> pf = pq.ParquetFile("hf://datasets/stanfordnlp/imdb/plain_text/train-00000-of-00001.parquet")
>>> pf.metadata
<pyarrow._parquet.FileMetaData object at 0x1171b4090>
  created_by: parquet-cpp-arrow version 12.0.0
  num_columns: 2
  num_rows: 25000
  num_row_groups: 25
  format_version: 2.6
  serialized_size: 62036
>>> for i in pf.num_row_groups:
...     table = pf.read_row_group(i)
...     ...

Hugging Face ๊ฒฝ๋กœ ๋ฐ ๊ตฌํ˜„ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ HfFileSystem์— ๋Œ€ํ•œ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

ํ…Œ์ด๋ธ” ์ €์žฅ

pyarrow.parquet.write_table๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ pyarrow Table์„ ๋กœ์ปฌ ํŒŒ์ผ ๋˜๋Š” Hugging Face์— ์ง์ ‘ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Hugging Face์— Table์„ ์ €์žฅํ•˜๋ ค๋ฉด ๋จผ์ € Hugging Face ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

hf auth login

๊ทธ ํ›„ ๋ฐ์ดํ„ฐ์…‹ ์ €์žฅ์†Œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

from huggingface_hub import HfApi

HfApi().create_repo(repo_id="username/my_dataset", repo_type="dataset")

๋งˆ์ง€๋ง‰์œผ๋กœ, PyArrow์—์„œ Hugging Face ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

import pyarrow.parquet as pq

pq.write_table(table, "hf://datasets/username/my_dataset/imdb.parquet", use_content_defined_chunking=True)

# or write in separate files if the dataset has train/validation/test splits
pq.write_table(table_train, "hf://datasets/username/my_dataset/train.parquet", use_content_defined_chunking=True)
pq.write_table(table_valid, "hf://datasets/username/my_dataset/validation.parquet", use_content_defined_chunking=True)
pq.write_table(table_test , "hf://datasets/username/my_dataset/test.parquet", use_content_defined_chunking=True)

Hugging Face์˜ Parquet ํŒŒ์ผ์€ ์ €์žฅ ํšจ์œจ์„ฑ์„ ๋†’์ด๊ณ , ๋‹ค์šด๋กœ๋“œ ๋ฐ ์—…๋กœ๋“œ๋ฅผ ๊ฐ€์†ํ™”ํ•˜๋ฉฐ, ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ์…‹ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐ ํŽธ์ง‘์„ ๊ฐ€๋Šฅํ•˜๋„๋ก ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค:

  • Parquet Content Defined Chunking์€ Hugging Face์˜ ์Šคํ† ๋ฆฌ์ง€ ๋ฐฑ์—”๋“œ์ธ Xet์— ์ตœ์ ํ™”๋œ Parquet์ž…๋‹ˆ๋‹ค. ์ฒญํฌ ๊ธฐ๋ฐ˜ ์ค‘๋ณต ์ œ๊ฑฐ๋ฅผ ํ†ตํ•ด ์—…๋กœ๋“œ์™€ ๋‹ค์šด๋กœ๋“œ๋ฅผ ๊ฐ€์†ํ™”ํ•˜๋ฉฐ, ํšจ์œจ์ ์ธ ํŒŒ์ผ ํŽธ์ง‘์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • Page index๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์‹œ ํ•„ํ„ฐ๋ฅผ ๊ฐ€์†ํ™”ํ•˜๊ณ , Dataset Viewer์™€ ๊ฐ™์€ ํ™˜๊ฒฝ์—์„œ ํšจ์œจ์ ์ธ ๋žœ๋ค ์•ก์„ธ์Šค๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

PyArrow๋Š” ์ตœ์ ํ™”๋œ Parquet ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๋ ค๋ฉด ์ถ”๊ฐ€ ์ธ์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค:

import pyarrow.parquet as pq

pq.write_table(
    table,
    "hf://datasets/username/my_dataset/imdb.parquet",
    # Optimize for Xet
    use_content_defined_chunking=True,
    write_page_index=True,
)

Content defined chunking(CDC)์€ Parquet writer๊ฐ€ ์ค‘๋ณต ๋ฐ์ดํ„ฐ๊ฐ€ ๋™์ผํ•˜๊ฒŒ chunk๋˜๊ณ  ์••์ถ•๋˜๋„๋ก ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€๋ฅผ chunkingํ•ฉ๋‹ˆ๋‹ค. CDC๊ฐ€ ์—†์œผ๋ฉด ํŽ˜์ด์ง€๊ฐ€ ์ž„์˜๋กœ chunking๋˜๋ฏ€๋กœ, ์••์ถ• ๋•Œ๋ฌธ์— ์ค‘๋ณต ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. CDC ๋•๋ถ„์— ์ค‘๋ณต ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ๋ฒˆ๋งŒ ์—…๋กœ๋“œ ๋˜๋Š” ๋‹ค์šด๋กœ๋“œ๋˜๋ฏ€๋กœ, Hugging Face๋กœ์˜ Parquet ์—…๋กœ๋“œ ๋ฐ ๋‹ค์šด๋กœ๋“œ๊ฐ€ ๋” ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค.

Xet์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•˜์„ธ์š”.

Parquet์— Xet ์ค‘๋ณต ์ œ๊ฑฐ ํ™œ์šฉ

์ตœ์ ํ™”๋œ Parquet ํŒŒ์ผ์€ ์ค‘๋ณต ์ œ๊ฑฐ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” Content Defined Chunking์œผ๋กœ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด Hugging Face์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ฒญํฌ๋ฅผ ๋‹ค์‹œ ์—…๋กœ๋“œํ•  ํ•„์š”๊ฐ€ ์—†์–ด ์—…๋กœ๋“œ ์†๋„๊ฐ€ ๋นจ๋ผ์ง€๊ณ , I/O๋ฅผ ํฌ๊ฒŒ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ์ฝ”๋“œ๋Š” table์˜ ๋‚ด์šฉ์„ ์—…๋กœ๋“œํ•œ ํ›„ edited_table์˜ ๊ฒฝ์šฐ ๋ณ€๊ฒฝ๋œ ์ฒญํฌ๋งŒ ์—…๋กœ๋“œํ•˜๋ฏ€๋กœ ์—…๋กœ๋“œ๊ฐ€ ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค:

import pyarrow.parquet as pq

pq.write_table(
    table,
    "hf://datasets/username/my_dataset/imdb.parquet",
    # Optimize for Xet
    use_content_defined_chunking=True,
    write_page_index=True,
)

edited_table = ...  # e.g. with added/modified/removed rows or columns

pq.write_table(
    edited_table,
    "hf://datasets/username/my_dataset/imdb.parquet",
    # Optimize for Xet
    use_content_defined_chunking=True,
    write_page_index=True,
)

Chunk์€ ์•ฝ 64kB์ด๋ฉฐ Parquet๋Š” ์ปฌ๋Ÿผ๋ณ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋ฏ€๋กœ, ์‹ค์ œ๋กœ Optimized Parquet ํŒŒ์ผ์„ ํŽธ์ง‘ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค:

  • ์ƒˆ๋กœ์šด ์—ด์„ ์ถ”๊ฐ€ํ•˜๋ฉด -> ์ƒˆ๋กœ์šด ์—ด์˜ ์ฒญํฌ๋งŒ ์—…๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค
  • add/edit/delete a row -> ์ปฌ๋Ÿผ๋‹น ํ•˜๋‚˜์˜ chunk๊ฐ€ ์—…๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค

๊ทธ๋ฆฌ๊ณ  ์ด ์™ธ์—๋„ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” Parquet ํ‘ธํ„ฐ์˜ ์ฒญํฌ๋„ ์—…๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ์‚ฌ์šฉ

์ด๋ฏธ์ง€ ์ด๋ฆ„ ๋˜๋Š” ๊ฒฝ๋กœ ํ•„๋“œ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํŒŒ์ผ์ด ์žˆ๋Š” ํด๋”๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

Example 1:            Example 2:
folder/               folder/
โ”œโ”€โ”€ metadata.parquet  โ”œโ”€โ”€ metadata.parquet
โ”œโ”€โ”€ img000.png        โ””โ”€โ”€ images
โ”œโ”€โ”€ img001.png            โ”œโ”€โ”€ img000.png
...                       ...
โ””โ”€โ”€ imgNNN.png            โ””โ”€โ”€ imgNNN.png

์ด๋ฏธ์ง€ ๊ฒฝ๋กœ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

from pathlib import Path
import pyarrow as pq

folder_path = Path("path/to/folder")
table = pq.read_table(folder_path + "metadata.parquet")
for file_name in table["file_name"].to_pylist():
    image_path = folder_path / file_name
    ...

๋ฐ์ดํ„ฐ์…‹์ด ์ง€์›๋˜๋Š” ๊ตฌ์กฐ(file_name ํ•„๋“œ๊ฐ€ ํฌํ•จ๋œ metadata.parquet ํŒŒ์ผ)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ, ์ด ๋ฐ์ดํ„ฐ์…‹์„ Hugging Face์— ์ €์žฅํ•˜๋ฉด Dataset Viewer์—์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ์ด๋ฏธ์ง€๊ฐ€ ๋ชจ๋‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

from huggingface_hub import HfApi
api = HfApi()

api.upload_folder(
    folder_path=folder_path,
    repo_id="username/my_image_dataset",
    repo_type="dataset",
)

Parquet ๋‚ด๋ถ€์— ์ด๋ฏธ์ง€ ์ž„๋ฒ ๋“œ

PyArrow์—๋Š” Arrow ํ…Œ์ด๋ธ”์— ์ด๋ฏธ์ง€ ๋ฐ”์ดํŠธ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ํƒ€์ž…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€(๋ฐ”์ดํŠธ ๋ฐ ๊ฒฝ๋กœ)์™€ ์ƒ˜ํ”Œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๋‹จ์ผ Parquet ํŒŒ์ผ๋กœ ๋ฐ์ดํ„ฐ์…‹์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

import pyarrow as pa
import pyarrow.parquet as pq

# Embed the image bytes in Arrow
image_array = pa.array([
    {
        "bytes": (folder_path / file_name).read_bytes(),
        "path": file_name,
    }
    for file_name in table["file_name"].to_pylist()
])
table.append_column("image", image_array)

# (Optional) Set the HF Image type for the Dataset Viewer and the `datasets` library
features = {"image": {"_type": "Image"}}  # or using datasets.Features(...).to_dict()
schema_metadata = {"huggingface": {"dataset_info": {"features": features}}}
table = table.replace_schema_metadata(schema_metadata)

# Save to Parquet
# (Optional) with use_content_defined_chunking for faster uploads and downloads
pq.write_table(table, "data.parquet", use_content_defined_chunking=True)

Arrow ์Šคํ‚ค๋งˆ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— Image ์œ ํ˜•์„ ์„ค์ •ํ•˜๋ฉด ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ Hugging Face Dataset Viewer๊ฐ€ โ€œimageโ€ ํ•„๋“œ์— ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ์ด๋ฏธ์ง€๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Audios ์‚ฌ์šฉ

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํŒŒ์ผ์— ์˜ค๋””์˜ค์˜ ์ด๋ฆ„ ๋˜๋Š” ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ํ•„๋“œ๊ฐ€ ํฌํ•จ๋œ ํด๋”๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

Example 1:            Example 2:
folder/               folder/
โ”œโ”€โ”€ metadata.parquet  โ”œโ”€โ”€ metadata.parquet
โ”œโ”€โ”€ rec000.wav        โ””โ”€โ”€ audios
โ”œโ”€โ”€ rec001.wav            โ”œโ”€โ”€ rec000.wav
...                       ...
โ””โ”€โ”€ recNNN.wav            โ””โ”€โ”€ recNNN.wav

์Œ์„ฑ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

from pathlib import Path
import pyarrow as pq

folder_path = Path("path/to/folder")
table = pq.read_table(folder_path + "metadata.parquet")
for file_name in table["file_name"].to_pylist():
    audio_path = folder_path / file_name
    ...

๋ฐ์ดํ„ฐ์…‹์ด ์ง€์›๋˜๋Š” ๊ตฌ์กฐ(file_name ํ•„๋“œ๊ฐ€ ํฌํ•จ๋œ metadata.parquet ํŒŒ์ผ)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ Hugging Face์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Hub Dataset Viewer์—์„œ๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ์˜ค๋””์˜ค๋ฅผ ๋ชจ๋‘ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from huggingface_hub import HfApi
api = HfApi()

api.upload_folder(
    folder_path=folder_path,
    repo_id="username/my_audio_dataset",
    repo_type="dataset",
)

Parquet ๋‚ด๋ถ€์— ์˜ค๋””์˜ค ์ž„๋ฒ ๋“œ

PyArrow์—๋Š” Arrow ํ…Œ์ด๋ธ”์— ์˜ค๋””์˜ค ๋ฐ”์ดํŠธ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ํƒ€์ž…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์˜ค๋””์˜ค(๋ฐ”์ดํŠธ ๋ฐ ๊ฒฝ๋กœ)์™€ ์ƒ˜ํ”Œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๋‹จ์ผ Parquet ํŒŒ์ผ๋กœ ๋ฐ์ดํ„ฐ์…‹์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

import pyarrow as pa
import pyarrow.parquet as pq

# Embed the audio bytes in Arrow
audio_array = pa.array([
    {
        "bytes": (folder_path / file_name).read_bytes(),
        "path": file_name,
    }
    for file_name in table["file_name"].to_pylist()
])
table.append_column("audio", audio_array)

# (Optional) Set the HF Audio type for the Dataset Viewer and the `datasets` library
features = {"audio": {"_type": "Audio"}}  # or using datasets.Features(...).to_dict()
schema_metadata = {"huggingface": {"dataset_info": {"features": features}}}
table = table.replace_schema_metadata(schema_metadata)

# Save to Parquet
# (Optional) with use_content_defined_chunking for faster uploads and downloads
pq.write_table(table, "data.parquet", use_content_defined_chunking=True)

Arrow ์Šคํ‚ค๋งˆ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— Audio ์œ ํ˜•์„ ์„ค์ •ํ•˜๋ฉด ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ Hugging Face Dataset Viewer๊ฐ€ โ€œaudioโ€๊ฐ€ ๋‹จ์ˆœํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์˜ค๋””์˜ค ๋ฐ์ดํ„ฐ์ž„์„ ์ธ์‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Update on GitHub