Hub documentation

Lance

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Lance

Lance là định dạng bảng lakehouse đa phương thức mã nguồn mở cho AI. Bạn có thể sử dụng đường dẫn Hugging Face (hf://) để truy cập các bộ dữ liệu Lance trên Hub. Điều này cho phép bạn quét và tìm kiếm các bộ dữ liệu lớn trên Hugging Face Hub mà không cần sao chép toàn bộ bộ dữ liệu về máy cục bộ.

Bắt đầu

Để bắt đầu, hãy cài đặt pylance và pyarrow bằng pip:

pip install pylance pyarrow

Tại sao chọn Lance?

  • Tối ưu cho các tác vụ ML/AI: Lance là một định dạng cột hiện đại được thiết kế để truy cập ngẫu nhiên nhanh chóng mà không làm giảm hiệu năng quét, giúp ích cho tìm kiếm, phân tích, huấn luyện, kỹ thuật đặc trưng và nhiều trường hợp sử dụng khác.
  • Tài nguyên đa phương thức được lưu trữ dưới dạng byte, hoặc các đối tượng nhị phân (“blobs as files”) trong Lance cùng với các embedding và dữ liệu vô hướng truyền thống — điều này giúp việc quản lý, chia sẻ và phân phối các bộ dữ liệu lớn của bạn qua Hub trở nên dễ dàng hơn.
  • Indexing là một công dân hạng nhất (có sẵn trong chính định dạng): Lance đi kèm các chỉ mục vector và FTS nhanh, trên đĩa, có khả năng mở rộng, nằm ngay cạnh bộ dữ liệu trên Hub, nhờ đó bạn có thể chia sẻ không chỉ dữ liệu mà còn cả embeddings và chỉ mục của mình mà người dùng không cần phải tính lại chúng.
  • Sơ đồ linh hoạt và tiến hóa dữ liệu cho phép bạn thêm dần các tính năng/cột mới (nhãn kiểm duyệt, embeddings, v.v.) mà không cần viết lại toàn bộ bảng.

Lưu trữ tất cả dữ liệu của bạn ở một nơi

Trong Lance, các tài sản dữ liệu đa phương thức của bạn (ảnh, âm thanh, video) được lưu trữ dưới dạng byte thô cùng với các metadata dạng scalar và embeddings của bạn. Điều này giúp việc quét và lọc bộ dữ liệu của bạn tại một nơi duy nhất trở nên dễ dàng mà không cần phải ghép nối nhiều hệ thống lưu trữ khác nhau.

Truyền trực tiếp từ Hub bằng datasets

Sử dụng load_dataset(..., streaming=True) để quét và lặp qua dữ liệu mà không cần tải về cục bộ.

from datasets import load_dataset

# Return as a Hugging Face dataset
ds = load_dataset(
    "lance-format/laion-1m",
    split="train",
    streaming=True
)
# Take first three rows
for row in ds.take(3):
    print(row["caption"])

Streaming rất hữu ích để lấy mẫu metadata nhằm hiểu rõ dữ liệu bạn đang có. Đối với tìm kiếm vector hoặc làm việc với các khối nhị phân lớn, bạn có thể sử dụng API dataset của Lance, được giải thích bên dưới.

Streaming có tốc độ nhanh khi lấy mẫu các metadata vô hướng đơn giản nhưng không nhanh bằng khi xử lý embeddings hoặc các tài sản đa phương thức lớn. Để làm việc với các bộ dữ liệu lớn, bạn nên quét metadata, xác định các tập con cần thiết và tải phần đó của bộ dữ liệu về máy cục bộ để tránh gặp giới hạn tần suất truy cập của Hub: hf download lance-format/laion-1m --repo-type dataset --local-dir ./laion

Truy xuất trực tiếp từ Hub bằng lance.dataset

Bạn cũng có thể quét một dataset Lance được lưu trữ trên Hugging Face Hub bằng cách sử dụng chỉ định đường dẫn hf://. Thao tác này quét dataset từ xa mà không yêu cầu bạn phải tải nó về máy cục bộ. Khi sử dụng API dataset của Lance, việc thiết lập các giới hạn, bộ lọc và phép chiếu để chỉ lấy dữ liệu cần thiết là rất đơn giản.

import lance

# Return as a Lance dataset
ds = lance.dataset("hf://datasets/lance-format/laion-1m/data/train.lance")

scanner = ds.scanner(
    columns=["caption", "url", "similarity"],
    limit=5
)

rows = scanner.to_table().to_pylist()
for row in rows:
    print(row)

Làm việc với tài sản nhị phân

Ví dụ dưới đây cho thấy cách các hình ảnh được lấy từ một tập dữ liệu Lance dưới dạng byte JPEG thô trong cột image, và được sử dụng ở các bước tiếp theo. Sử dụng ds.take để lấy các byte và ghi chúng ra đĩa để bạn có thể sử dụng chúng ở nơi khác.

import lance
from pathlib import Path

ds = lance.dataset("hf://datasets/lance-format/laion-1m/data/train.lance")

dir_name = "laion_samples"
Path(dir_name).mkdir(exist_ok=True)

rows = ds.take([0, 1], columns=["image", "caption"]).to_pylist()
for idx, row in enumerate(rows):
    with open(f"{dir_name}/{idx}.jpg", "wb") as f:
        f.write(row["image"])
        print(f"Wrote image with caption: {row['caption']}")

Viết một tập con vào một tập dữ liệu Lance mới

Đang làm việc với các bộ dữ liệu lớn? Rất đơn giản để chạy một lượt quét có lọc nhằm chọn một tập con các dòng từ Hub và vật chất hóa chúng thành một tập dữ liệu Lance cục bộ.

import lance

ds = lance.dataset("hf://datasets/lance-format/laion-1m/data/train.lance")
scanner = ds.scanner(
    columns=["image", "caption", "width", "height"],
    filter="width >= 200 AND height >= 100",
    limit=10,
)
subset = scanner.to_table()

lance.write_dataset(subset, "./laion_subset")

Tạo chỉ mục

Nếu tập dữ liệu của bạn chưa có chỉ mục liên quan, bạn có thể tạo một chỉ mục sau khi tải nó về máy cục bộ.

# ds is a local Lance dataset
ds.create_index(
    "img_emb",
    index_type="IVF_PQ",
    num_partitions=256,
    num_sub_vectors=96,
    replace=True,
)

Xem tài liệu Lance về việc tạo chỉ mục vector để có ví dụ chi tiết hơn. Sau khi đã tạo chỉ mục vector, bạn có thể chạy tìm kiếm tương tự trên dữ liệu thông qua các embedding.

Tìm kiếm vector

Vì index là công dân hạng nhất trong Lance, bạn có thể lưu trữ không chỉ dữ liệu mà còn cả embeddings và index của mình cùng nhau, sau đó truy vấn chúng trực tiếp trên Hub. Chỉ cần sử dụng phương thức describe_indices() để liệt kê thông tin index của dataset. Nếu một index không tồn tại trong dataset, bạn có thể sử dụng lance.write_dataset() để ghi một phiên bản cục bộ của dataset và dùng LanceDataset.create_index để tạo index theo nhu cầu của bạn.

Ví dụ dưới đây cho thấy một tập dữ liệu mà chúng ta đã có một chỉ mục vector trên trường img_emb:

import lance

ds = lance.dataset("hf://datasets/lance-format/laion-1m/data/train.lance")

print(ds.list_indices())

# Returns
# [
#   IndexDescription(
#       name=img_emb_idx,
#       type_url=/lance.table.VectorIndexDetails,
#       num_rows_indexed=1209588,
#       fields=[15],
#       field_names=["img_emb"],
#       num_segments=1
#.   )
# ]

Bạn có thể chạy các truy vấn tìm kiếm vector trực tiếp trên bộ dữ liệu từ xa mà không cần tải xuống (hoặc, nếu bạn muốn, hãy tải bộ dữ liệu về cục bộ và tạo một chỉ mục mới). Ví dụ dưới đây cho thấy cách chạy tìm kiếm láng giềng gần nhất trên một chỉ mục vector bằng cách sử dụng nhúng hình ảnh làm vector truy vấn.

import lance
import pyarrow as pa

ds = lance.dataset("hf://datasets/lance-format/laion-1m/data/train.lance")

emb_field = ds.schema.field("img_emb")
ref = ds.take([0], columns=["img_emb"]).to_pylist()[0]["img_emb"]
query = pa.array([ref], type=emb_field.type)

neighbors = ds.scanner(
    nearest={
        "column": emb_field.name,
        "q": query[0],
        "k": 6,
        "nprobes": 16,
        "refine_factor": 30,
    },
    columns=["caption", "url", "similarity"],
).to_table().to_pylist()

Việc đặt giá trị k hoặc nprobes lớn, hoặc gửi một lô lớn các truy vấn cùng lúc có thể chạm đến giới hạn tần suất của Hub. Đối với việc sử dụng cường độ cao, hãy tải bộ dữ liệu (hoặc một tập con của nó) về cục bộ và trỏ Lance đến đường dẫn cục bộ để tránh bị hạn chế.

Sự tiến hóa của bộ dữ liệu

Một trong những tính năng mạnh mẽ nhất của Lance là khả năng tiến hóa dữ liệu linh hoạt, không tốn chi phí, nghĩa là bạn có thể dễ dàng thêm các cột dẫn xuất mà không cần ghi đè lại bảng gốc. Đối với các bảng rất lớn chứa nhiều blob kích thước lớn, mức tiết kiệm I/O có thể khá đáng kể. Tính năng này đặc biệt hữu ích nếu bạn đang thử nghiệm với dữ liệu cho các tác vụ kỹ thuật ML/AI và thường xuyên phải thêm các đặc trưng, embedding hoặc metadata dẫn xuất mới.

Ví dụ dưới đây cho thấy cách thêm cột moderation_label dẫn xuất, đánh dấu một hình ảnh là NSFW dựa trên cột điểm có sẵn. Khi bạn thực hiện thay đổi này, việc backfill cột mới chỉ ghi dữ liệu của cột mới, không đụng đến các blob hình ảnh gốc hay dữ liệu trong các cột khác. Bạn cũng có thể chọn chỉ thêm schema của cột mới mà không backfill bất kỳ dữ liệu nào.

import lance
import pyarrow as pa

# Assumes you ran the export to Lance example above to store a local subset of the data
local_ds = lance.dataset("./laion_subset")

# schema only (data to be added later)
local_ds.add_columns(pa.field("moderation_label", pa.string()))

# with data backfill
local_ds.add_columns(
    {
        "moderation_label": "case WHEN \"NSFW\" > 0.5 THEN 'review' ELSE 'ok' END"
    }
)

Xem tài liệu Lance về biến đổi dữ liệu để tìm hiểu cách thay đổi và xóa các cột trong bộ dữ liệu Lance.

Làm việc với các blob video

Bảng Lance cũng hỗ trợ các blob video inline có kích thước lớn. Bộ dữ liệu OpenVid-1M (từ bài báo này) chứa các video chất lượng cao, giàu biểu cảm cùng với chú thích của chúng. Dữ liệu video được lưu trữ trong cột video_blob của bộ dữ liệu Lance sau đây trên Hub.

import lance

lance_ds = lance.dataset("hf://datasets/lance-format/Openvid-1M/data/train.lance")
blob_file = lance_ds.take_blobs("video_blob", ids=[0])[0]
video_bytes = blob_file.read()

Khác với các định dạng dữ liệu khác, các đối tượng nhị phân đa phương thức lớn (blob) là công dân hạng nhất trong Lance. API blob cung cấp một API cấp cao để lưu trữ và truy xuất các blob lớn trong các tập dữ liệu Lance. Ví dụ sau minh họa cách duyệt metadata một cách hiệu quả mà không cần tải các blob video nặng hơn, sau đó lấy các blob video liên quan theo yêu cầu.

import lance

ds = lance.dataset("hf://datasets/lance-format/Openvid-1M/data/train.lance")

# 1. Browse metadata without loading video blobs.
metadata = ds.scanner(
    columns=["caption", "aesthetic_score"],
    filter="aesthetic_score >= 4.5",
    limit=2,
).to_table().to_pylist()

# 2. Fetch a single video blob by row index.
selected_index = 0
blob_file = ds.take_blobs("video_blob", ids=[selected_index])[0]
with open("video_0.mp4", "wb") as f:
    f.write(blob_file.read())

Chuẩn bị dữ liệu cho huấn luyện

Training là một lĩnh vực khác mà hiệu năng truy cập ngẫu nhiên và quét nhanh của Lance có thể phát huy tác dụng. Bạn có thể sử dụng các dataset Lance làm cơ chế lưu trữ cho dữ liệu huấn luyện, trộn (shuffle) và nạp vào các batch như một phần của các pipeline huấn luyện.

API blob trong Lance tương thích với torchcodec, vì vậy bạn có thể dễ dàng giải mã các blob video thành các tensor torch:

from torchcodec.decoders import VideoDecoder
decoder = VideoDecoder(blob_file)
tensor = decoder[0]  # uint8 tensor of shape [C, H, W]

Xem tài liệu torchcodec để biết thêm các hàm để giải mã video hiệu quả.

Ngoài ra, bạn cũng có thể xem tài liệu Lance để tìm thêm các ví dụ về việc nạp dữ liệu ảnh vào torchvision nhằm huấn luyện các mô hình ảnh của riêng bạn.

Khám phá thêm các bộ dữ liệu Lance

Lance là một định dạng mã nguồn mở với hỗ trợ bản địa cho các blob đa phương thức bên cạnh dữ liệu bảng truyền thống của bạn. Với tích hợp Hugging Face Hub, bạn có thể dễ dàng làm việc với hình ảnh, âm thanh, video, văn bản, embeddings và metadata vô hướng tất cả trong một nơi.

Khám phá thêm các bộ dữ liệu Lance trên Hugging Face Hub, và chia sẻ các bộ dữ liệu Lance của bạn với những người khác trong cộng đồng! Bạn có thể truy cập lance.org để xem thêm các đoạn mã và ví dụ.

Update on GitHub