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 là một định dạng cột và một bộ công cụ để trao đổi dữ liệu nhanh và phân tích trong bộ nhớ. Vì PyArrow hỗ trợ fsspec để đọc và ghi dữ liệu từ xa, bạn có thể sử dụng các đường dẫn Hugging Face (hf://) để đọc và ghi dữ liệu trên Hub. Điều này đặc biệt hữu ích cho dữ liệu Parquet, vì Parquet là định dạng tệp phổ biến nhất trên Hugging Face. Thật vậy, Parquet đặc biệt hiệu quả nhờ cấu trúc, kiểu dữ liệu, siêu dữ liệu và nén của nó.

Tải một Bảng

Bạn có thể tải dữ liệu từ các tệp cục bộ hoặc từ bộ lưu trữ từ xa như Hugging Face Datasets. PyArrow hỗ trợ nhiều định dạng bao gồm CSV, JSON và quan trọng hơn là Parquet:

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

Để tải một tệp từ Hugging Face, đường dẫn phải bắt đầu bằng hf://. Ví dụ, đường dẫn đến kho dữ liệu stanfordnlp/imdb là hf://datasets/stanfordnlp/imdb. Dữ liệu trên Hugging Face chứa nhiều tệp Parquet. Định dạng tệp Parquet được thiết kế để đọc và ghi các data frame hiệu quả, đồng thời giúp việc chia sẻ dữ liệu giữa các ngôn ngữ phân tích dữ liệu trở nên dễ dàng. Dưới đây là cách tải tệp plain_text/train-00000-of-00001.parquet dưới dạng pyarrow Table (yêu cầu 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]]

Nếu bạn không muốn tải toàn bộ dữ liệu Parquet, bạn có thể lấy metadata của Parquet hoặc tải từng row group một:

>>> 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)
...     ...

Để biết thêm thông tin về các đường dẫn của Hugging Face và cách chúng được triển khai, vui lòng tham khảo tài liệu của thư viện client về HfFileSystem.

Lưu một Bảng

Bạn có thể lưu một bảng pyarrow bằng cách sử dụng pyarrow.parquet.write_table vào một tệp cục bộ hoặc trực tiếp lên Hugging Face.

Để lưu Table trên Hugging Face, trước tiên bạn cần Đăng nhập bằng tài khoản Hugging Face, ví dụ bằng cách sử dụng:

hf auth login

Sau đó, bạn có thể tạo kho dữ liệu, ví dụ bằng cách sử dụng:

from huggingface_hub import HfApi

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

Cuối cùng, bạn có thể sử dụng đường dẫn Hugging Face trong PyArrow:

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)

Lưu ý rằng các tệp Parquet trên Hugging Face được tối ưu hóa để cải thiện hiệu quả lưu trữ, tăng tốc quá trình tải xuống và tải lên, cũng như cho phép phát trực tiếp và chỉnh sửa bộ dữ liệu một cách hiệu quả:

  • Phân chia chunk theo nội dung Parquet tối ưu hóa Parquet cho Xet, hệ thống lưu trữ phía sau của Hugging Face. Nó tăng tốc quá trình tải lên và tải xuống nhờ khử trùng lặp dựa trên chunk và cho phép chỉnh sửa tệp hiệu quả
  • Chỉ mục trang (Page index) tăng tốc bộ lọc khi phát trực tiếp và cho phép truy cập ngẫu nhiên hiệu quả, ví dụ như trong Dataset Viewer

PyArrow yêu cầu các đối số bổ sung để ghi các tệp Parquet được tối ưu hóa:

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,
)

Chunking dựa trên nội dung (CDC) cho phép trình ghi Parquet chia dữ liệu thành các trang theo cách khiến dữ liệu trùng lặp được chia và nén giống hệt nhau. Nếu không có CDC, các trang sẽ được chia một cách tùy ý, do đó không thể phát hiện dữ liệu trùng lặp do quá trình nén. Nhờ CDC, việc tải lên và tải xuống Parquet từ Hugging Face nhanh hơn, vì dữ liệu trùng lặp chỉ được tải lên hoặc tải xuống một lần.

Tìm thêm thông tin về Xet tại đây.

Tận dụng tính năng khử trùng lặp của Xet cho Parquet

Các tệp Parquet được tối ưu hóa được ghi với Content Defined Chunking, cho phép loại bỏ trùng lặp. Điều này tăng tốc quá trình tải lên vì các khối dữ liệu đã tồn tại trên Hugging Face không cần phải tải lên lại, và điều này tiết kiệm được rất nhiều I/O.

Ví dụ, đoạn mã này tải lên nội dung của table và sau đó với edited_table, quá trình tải lên nhanh hơn vì nó chỉ tải lên các khối đã thay đổi:

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,
)

Các chunk có kích thước ~64kB và Parquet lưu trữ dữ liệu theo từng cột, vì vậy trên thực tế, đây là những gì xảy ra khi chỉnh sửa một tệp Optimized Parquet:

  • thêm một cột mới -> chỉ các khối của cột mới được tải lên
  • thêm/sửa/xóa một hàng -> một chunk cho mỗi cột được tải lên

Ngoài ra, các khối của phần chân Parquet chứa dữ liệu mô tả cũng được tải lên.

Sử dụng hình ảnh

Bạn có thể tải một thư mục chứa tệp metadata có trường cho tên hoặc đường dẫn đến các hình ảnh, được cấu trúc như sau:

Example 1:            Example 2:
folder/               folder/
├── metadata.parquet  ├── metadata.parquet
├── img000.png        └── images
├── img001.png            ├── img000.png
...                       ...
└── imgNNN.png            └── imgNNN.png

Bạn có thể lặp qua các đường dẫn ảnh như sau:

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
    ...

Vì tập dữ liệu có cấu trúc được hỗ trợ (một tệp metadata.parquet với trường file_name), bạn có thể lưu tập dữ liệu này lên Hugging Face và Dataset Viewer sẽ hiển thị cả metadata lẫn hình ảnh.

from huggingface_hub import HfApi
api = HfApi()

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

Nhúng Ảnh bên trong Parquet

PyArrow có một kiểu nhị phân cho phép lưu trữ các byte của hình ảnh trong các bảng Arrow. Do đó, nó cho phép lưu dataset dưới dạng một tệp Parquet duy nhất chứa cả hình ảnh (byte và đường dẫn) lẫn metadata của các mẫu:

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)

Việc đặt kiểu Image trong metadata của schema Arrow cho phép các thư viện khác và Hugging Face Dataset Viewer biết rằng “image” chứa các hình ảnh chứ không chỉ là dữ liệu nhị phân.

Sử dụng Audios

Bạn có thể tải một thư mục chứa tệp metadata có trường cho tên hoặc đường dẫn đến các tệp âm thanh, được cấu trúc như sau:

Example 1:            Example 2:
folder/               folder/
├── metadata.parquet  ├── metadata.parquet
├── rec000.wav        └── audios
├── rec001.wav            ├── rec000.wav
...                       ...
└── recNNN.wav            └── recNNN.wav

Bạn có thể lặp qua các đường dẫn âm thanh như sau:

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
    ...

Vì tập dữ liệu có cấu trúc được hỗ trợ (một tệp metadata.parquet với trường file_name), bạn có thể lưu nó lên Hugging Face, và Hub Dataset Viewer sẽ hiển thị cả metadata lẫn audio.

from huggingface_hub import HfApi
api = HfApi()

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

Nhúng Âm thanh vào Parquet

PyArrow có một kiểu nhị phân cho phép lưu trữ các byte âm thanh trong các bảng Arrow. Do đó, nó cho phép lưu dataset dưới dạng một tệp Parquet duy nhất chứa cả âm thanh (byte và đường dẫn) lẫn metadata của các mẫu:

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)

Việc đặt kiểu Audio trong metadata của schema Arrow cho phép các thư viện khác và Hugging Face Dataset Viewer nhận biết rằng “audio” chứa dữ liệu âm thanh, chứ không chỉ là dữ liệu nhị phân.

Update on GitHub