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๋Š” AI๋ฅผ ์œ„ํ•œ ์˜คํ”ˆ ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ๋ ˆ์ดํฌํ•˜์šฐ์Šค ํ…Œ์ด๋ธ” ํ˜•์‹์ž…๋‹ˆ๋‹ค. Hugging Face ๊ฒฝ๋กœ(hf://)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Hub์˜ Lance ๋ฐ์ดํ„ฐ์…‹์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Hugging Face Hub์˜ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ์…‹์„ ๋กœ์ปฌ๋กœ ์ „์ฒด๋ฅผ ๋ณต์‚ฌํ•˜์ง€ ์•Š๊ณ ๋„ ์Šค์บ” ๋ฐ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ

์‹œ์ž‘ํ•˜๋ ค๋ฉด pylance์™€ pyarrow๋ฅผ pip๋กœ ์„ค์น˜ํ•˜์„ธ์š”:

pip install pylance pyarrow

์™œ Lance์ธ๊ฐ€์š”?

  • ML/AI ์›Œํฌ๋กœ๋“œ์— ์ตœ์ ํ™”: Lance๋Š” ์Šค์บ” ์„ฑ๋Šฅ์„ ์ €ํ•ดํ•˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ๋น ๋ฅธ ๋žœ๋ค ์•ก์„ธ์Šค๋ฅผ ์ง€์›ํ•˜๋Š” ํ˜„๋Œ€์ ์ธ ์ปฌ๋Ÿผํ˜• ํฌ๋งท์œผ๋กœ, ๊ฒ€์ƒ‰, ๋ถ„์„, ํ•™์Šต, ํ”ผ์ฒ˜ ์—”์ง€๋‹ˆ์–ด๋ง ๋“ฑ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ์ž์‚ฐ์€ ์ž„๋ฒ ๋”ฉ๊ณผ ์ „ํ†ต์ ์ธ ์Šค์นผ๋ผ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ Lance์—์„œ ๋ฐ”์ดํŠธ, ์ฆ‰ ๋ฐ”์ด๋„ˆ๋ฆฌ ๊ฐ์ฒด("ํŒŒ์ผ๋กœ ์ €์žฅ๋œ blob")๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Hub๋ฅผ ํ†ตํ•ด ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ์…‹์„ ๊ด€๋ฆฌํ•˜๊ณ  ๊ณต์œ ํ•˜๋ฉฐ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.
  • ์ธ๋ฑ์‹ฑ์€ 1๊ธ‰ ์‹œ๋ฏผ(ํฌ๋งท ์ž์ฒด์— ๋„ค์ดํ‹ฐ๋ธŒ)์ž…๋‹ˆ๋‹ค: Lance์—๋Š” ๋ฐ์ดํ„ฐ์…‹๊ณผ ํ•จ๊ป˜ Hub์— ๋ฐ”๋กœ ๋ฐฐ์น˜๋˜๋Š” ๋น ๋ฅด๊ณ , ๋””์Šคํฌ ๊ธฐ๋ฐ˜์ด๋ฉฐ, ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๋ฒกํ„ฐ ๋ฐ FTS ์ธ๋ฑ์Šค๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š” ์—†์ด ๋ฐ์ดํ„ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ž„๋ฒ ๋”ฉ๊ณผ ์ธ๋ฑ์Šค๋„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์œ ์—ฐํ•œ ์Šคํ‚ค๋งˆ์™€ ๋ฐ์ดํ„ฐ ์ง„ํ™”๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ/์—ด(๋ชจ๋”๋ ˆ์ด์…˜ ํƒœ๊ทธ, ์ž„๋ฒ ๋”ฉ ๋“ฑ)์„ ์ „์ฒด ํ…Œ์ด๋ธ”์„ ๋‹ค์‹œ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ์ ์ง„์ ์œผ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๊ณณ์— ์ €์žฅํ•˜์„ธ์š”

Lance์—์„œ๋Š” ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ๋ฐ์ดํ„ฐ ์ž์‚ฐ(์ด๋ฏธ์ง€, ์˜ค๋””์˜ค, ๋น„๋””์˜ค)์ด ์Šค์นผ๋ผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ์ž„๋ฒ ๋”ฉ๊ณผ ํ•จ๊ป˜ ์›์‹œ ๋ฐ”์ดํŠธ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์ €์žฅ ์‹œ์Šคํ…œ์„ ํ†ตํ•ฉํ•  ํ•„์š” ์—†์ด ํ•œ ๊ณณ์—์„œ ๋ฐ์ดํ„ฐ์…‹์„ ์Šค์บ”ํ•˜๊ณ  ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

datasets๋กœ Hub์—์„œ ์ŠคํŠธ๋ฆฌ๋ฐ

load_dataset(..., streaming=True)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ์ปฌ๋กœ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š๊ณ  ์Šค์บ”ํ•˜๊ณ  ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.

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์€ ๋ณด์œ  ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒ˜ํ”Œ๋งํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฒกํ„ฐ ๊ฒ€์ƒ‰์ด๋‚˜ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ธ”๋กญ์„ ๋‹ค๋ฃจ๋ ค๋ฉด ์•„๋ž˜์—์„œ ์„ค๋ช…ํ•˜๋Š” Lance dataset API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Streaming์€ ๋‹จ์ˆœํ•œ ์Šค์นผ๋ผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒ˜ํ”Œ๋งํ•˜๋Š” ๋ฐ๋Š” ๋น ๋ฅด์ง€๋งŒ, ์ž„๋ฒ ๋”ฉ์ด๋‚˜ ๋Œ€๊ทœ๋ชจ ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ์—์…‹์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆฝ๋‹ˆ๋‹ค. ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ์…‹์„ ๋‹ค๋ฃจ๋ ค๋ฉด ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์Šค์บ”ํ•˜์—ฌ ํ•„์š”ํ•œ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์„ ์‹๋ณ„ํ•œ ํ›„, ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ๋กœ์ปฌ๋กœ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ Hub์˜ ๋ ˆ์ดํŠธ ๋ฆฌ๋ฐ‹ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค: hf download lance-format/laion-1m --repo-type dataset --local-dir ./laion

lance.dataset๋กœ Hub์—์„œ ์ŠคํŠธ๋ฆฌ๋ฐ

Hugging Face Hub์— ์ €์žฅ๋œ Lance ๋ฐ์ดํ„ฐ์…‹์„ hf:// ๊ฒฝ๋กœ ์ง€์ •์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šค์บ”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋กœ์ปฌ๋กœ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š๊ณ  ์›๊ฒฉ ๋ฐ์ดํ„ฐ์…‹์„ ์Šค์บ”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lance dataset API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก ์ œํ•œ, ํ•„ํ„ฐ ๋ฐ ํ”„๋กœ์ ์…˜์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

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)

๋ฐ”์ด๋„ˆ๋ฆฌ ์ž์‚ฐ ์ž‘์—…

์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” Lance ๋ฐ์ดํ„ฐ์…‹์—์„œ image ์ปฌ๋Ÿผ์˜ ์ด๋ฏธ์ง€๊ฐ€ ์›๋ณธ JPEG ๋ฐ”์ดํŠธ๋กœ ๊ฐ€์ ธ์™€์ ธ ํ•˜์œ„ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ds.take๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ”์ดํŠธ๋ฅผ ๊ฐ€์ ธ์™€ ๋””์Šคํฌ์— ์ €์žฅํ•˜๋ฉด ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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']}")

Write a subset to a new Lance dataset

๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์…‹์„ ๋‹ค๋ฃจ๊ณ  ๊ณ„์‹ ๊ฐ€์š”? Hub์—์„œ ํ–‰์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•ด ํ•„ํ„ฐ๋ง๋œ ์Šค์บ”์„ ์‹คํ–‰ํ•˜๊ณ  ์ด๋ฅผ ๋กœ์ปฌ Lance ๋ฐ์ดํ„ฐ์…‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

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

์ธ๋ฑ์Šค ์ƒ์„ฑ

๋ฐ์ดํ„ฐ์…‹์— ์ด๋ฏธ ์ธ๋ฑ์Šค๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ, ๋กœ์ปฌ๋กœ ๋‹ค์šด๋กœ๋“œํ•œ ํ›„ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋ฒกํ„ฐ ์ธ๋ฑ์Šค ์ƒ์„ฑ์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ์˜ˆ์ œ๋Š” Lance ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. ๋ฒกํ„ฐ ์ธ๋ฑ์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ์ž„๋ฒ ๋”ฉ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์—์„œ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒกํ„ฐ ๊ฒ€์ƒ‰

Lance์—์„œ ์ธ๋ฑ์Šค๋Š” ์ผ๊ธ‰ ์‹œ๋ฏผ(first-class citizen)์ด๋ฏ€๋กœ, ๋ฐ์ดํ„ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ž„๋ฒ ๋”ฉ๊ณผ ์ธ๋ฑ์Šค๋„ ํ•จ๊ป˜ ์ €์žฅํ•˜๊ณ  Hub์—์„œ ์ง์ ‘ ์ฟผ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. describe_indices() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์…‹์˜ ์ธ๋ฑ์Šค ์ •๋ณด๋ฅผ ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์…‹์— ์ธ๋ฑ์Šค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, lance.write_dataset()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์…‹์˜ ๋กœ์ปฌ ๋ฒ„์ „์„ ์ž‘์„ฑํ•˜๊ณ  LanceDataset.create_index๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ๋Š” 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
#.   )
# ]

โ€ฆ ์›๊ฒฉ ๋ฐ์ดํ„ฐ์…‹์„ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š๊ณ ๋„ ๋ฒกํ„ฐ ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์›ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ์…‹์„ ๋กœ์ปฌ๋กœ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ ์ƒˆ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค). ์•„๋ž˜ ์˜ˆ์ œ๋Š” ์ด๋ฏธ์ง€ ์ž„๋ฒ ๋”ฉ์„ ์ฟผ๋ฆฌ ๋ฒกํ„ฐ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒกํ„ฐ ์ธ๋ฑ์Šค์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ด์›ƒ ๊ฒ€์ƒ‰์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

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

ํฐ k ๋˜๋Š” nprobes ๊ฐ’์„ ์„ค์ •ํ•˜๊ฑฐ๋‚˜, ๋Œ€๋Ÿ‰์˜ ์ฟผ๋ฆฌ๋ฅผ ํ•œ ๋ฒˆ์— ๋ณด๋‚ด๋ฉด Hub์˜ ์†๋„ ์ œํ•œ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋Ÿ‰ ์‚ฌ์šฉ์˜ ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ์…‹(๋˜๋Š” ๊ทธ ์ผ๋ถ€)์„ ๋กœ์ปฌ๋กœ ๋‹ค์šด๋กœ๋“œํ•œ ํ›„ Lance๋ฅผ ๋กœ์ปฌ ๊ฒฝ๋กœ๋กœ ์ง€์ •ํ•˜์—ฌ ์†๋„ ์ œํ•œ์„ ํ”ผํ•˜์„ธ์š”.

๋ฐ์ดํ„ฐ์…‹์˜ ์ง„ํ™”

Lance์˜ ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” ์œ ์—ฐํ•˜๊ณ  ๋น„์šฉ์ด ๋“ค์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ ์ง„ํ™”์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์›๋ณธ ํ…Œ์ด๋ธ”์„ ๋‹ค์‹œ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ํŒŒ์ƒ๋œ ์ปฌ๋Ÿผ์„ ์†์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์šฉ๋Ÿ‰ ๋ธ”๋กญ์ด ๋งŽ์ด ํฌํ•จ๋œ ๋งค์šฐ ํฐ ํ…Œ์ด๋ธ”์˜ ๊ฒฝ์šฐ, I/O ์ ˆ๊ฐ ํšจ๊ณผ๊ฐ€ ์ƒ๋‹นํžˆ ํด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ML/AI ์—”์ง€๋‹ˆ์–ด๋ง ์ž‘์—…์„ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์‹คํ—˜ํ•˜๊ณ , ์ƒˆ๋กœ์šด ํŠน์ง•, ์ž„๋ฒ ๋”ฉ, ๋˜๋Š” ํŒŒ์ƒ๋œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ž์ฃผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๊ธฐ๋Šฅ์ด ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ๋Š” ๊ธฐ์กด ์ ์ˆ˜ ์ปฌ๋Ÿผ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ NSFW๋กœ ํ‘œ์‹œํ•˜๋Š” ํŒŒ์ƒ moderation_label ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•  ๋•Œ, ์ƒˆ ์ปฌ๋Ÿผ์„ ๋ฐฑํ•„ํ•˜๋ฉด ์›๋ณธ ์ด๋ฏธ์ง€ ๋ธ”๋กญ์ด๋‚˜ ๋‹ค๋ฅธ ์ปฌ๋Ÿผ์˜ ๋ฐ์ดํ„ฐ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ์ƒˆ ์ปฌ๋Ÿผ ๋ฐ์ดํ„ฐ๋งŒ ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฑํ•„ํ•˜์ง€ ์•Š๊ณ  ์ƒˆ ์ปฌ๋Ÿผ ์Šคํ‚ค๋งˆ๋งŒ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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"
    }
)

Lance ๋ฐ์ดํ„ฐ์…‹์—์„œ ์ปฌ๋Ÿผ์„ ์ˆ˜์ •ํ•˜๊ณ  ์‚ญ์ œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋ ค๋ฉด ๋ฐ์ดํ„ฐ ์ง„ํ™”์— ๋Œ€ํ•œ Lance ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋น„๋””์˜ค blob ์ž‘์—…

Lance ํ…Œ์ด๋ธ”์€ ๋Œ€์šฉ๋Ÿ‰ ์ธ๋ผ์ธ ๋น„๋””์˜ค ๋ธ”๋กญ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋…ผ๋ฌธ์˜ OpenVid-1M ๋ฐ์ดํ„ฐ์…‹์—๋Š” ๊ณ ํ’ˆ์งˆ์ด๊ณ  ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•œ ๋น„๋””์˜ค์™€ ๊ทธ์— ๋Œ€ํ•œ ์บก์…˜์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„๋””์˜ค ๋ฐ์ดํ„ฐ๋Š” Hub์˜ ๋‹ค์Œ Lance ๋ฐ์ดํ„ฐ์…‹์˜ video_blob ์ปฌ๋Ÿผ์— ์ €์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ํฌ๋งท๊ณผ ๋‹ฌ๋ฆฌ, ๋Œ€๊ทœ๋ชจ ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ๋ฐ”์ด๋„ˆ๋ฆฌ ๊ฐ์ฒด(blob)๋Š” Lance์—์„œ ์ผ๊ธ‰ ์‹œ๋ฏผ(first-class citizen)์ž…๋‹ˆ๋‹ค. blob API๋Š” Lance ๋ฐ์ดํ„ฐ์…‹์— ๋Œ€๊ทœ๋ชจ blob์„ ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•œ ๊ณ ์ˆ˜์ค€ API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ๋Š” ๋ฌด๊ฑฐ์šด ๋น„๋””์˜ค blob์„ ๋กœ๋“œํ•˜์ง€ ์•Š๊ณ  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํƒ์ƒ‰ํ•œ ํ›„, ํ•„์š”ํ•œ ๋น„๋””์˜ค blob์„ ์˜จ๋””๋งจ๋“œ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

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

ํ•™์Šต์„ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ์ค€๋น„

Training์€ Lance์˜ ๋น ๋ฅธ ๋žœ๋ค ์•ก์„ธ์Šค ๋ฐ ์Šค์บ” ์„ฑ๋Šฅ์ด ์œ ์šฉํ•˜๊ฒŒ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ์˜์—ญ์ž…๋‹ˆ๋‹ค. ํ•™์Šต ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ Lance ๋ฐ์ดํ„ฐ์…‹์„ ์‚ฌ์šฉํ•˜๊ณ , ํ•™์Šต ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ผ๋ถ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์…”ํ”Œ๋งํ•˜๊ณ  ๋ฐฐ์น˜๋กœ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Lance์˜ blob API๋Š” torchcodec๊ณผ ํ˜ธํ™˜๋˜๋ฏ€๋กœ, ๋น„๋””์˜ค blob์„ torch ํ…์„œ๋กœ ์‰ฝ๊ฒŒ ๋””์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

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

ํšจ์œจ์ ์ธ ๋น„๋””์˜ค ๋””์ฝ”๋”ฉ์„ ์œ„ํ•œ ์ถ”๊ฐ€ ํ•จ์ˆ˜๋Š” torchcodec ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

์ถ”๊ฐ€๋กœ, ์ž์ฒด ์ด๋ฏธ์ง€ ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ธฐ ์œ„ํ•ด torchvision์— ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋” ๋งŽ์€ ์˜ˆ์ œ๋Š” Lance ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

๋” ๋งŽ์€ Lance ๋ฐ์ดํ„ฐ์„ธํŠธ ํƒ์ƒ‰

Lance๋Š” ์ „ํ†ต์ ์ธ ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ๋ธ”๋กญ์— ๋Œ€ํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ์ง€์›์„ ์ œ๊ณตํ•˜๋Š” ์˜คํ”ˆ ํฌ๋งท์ž…๋‹ˆ๋‹ค. Hugging Face Hub ํ†ตํ•ฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฏธ์ง€, ์˜ค๋””์˜ค, ๋น„๋””์˜ค, ํ…์ŠคํŠธ, ์ž„๋ฒ ๋”ฉ, ์Šค์นผ๋ผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ํ•œ ๊ณณ์—์„œ ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Hugging Face Hub์—์„œ ๋” ๋งŽ์€ Lance ๋ฐ์ดํ„ฐ์…‹์„ ํƒ์ƒ‰ํ•˜๊ณ , ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์™€ ์ง์ ‘ ๋งŒ๋“  Lance ๋ฐ์ดํ„ฐ์…‹์„ ๊ณต์œ ํ•ด ๋ณด์„ธ์š”. ๋” ๋งŽ์€ ์ฝ”๋“œ ์Šค๋‹ˆํŽซ๊ณผ ์˜ˆ์ œ๋Š” lance.org์—์„œ ํ™•์ธํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Update on GitHub