Hub documentation

fenic

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

fenic

fenic์€ PySpark์—์„œ ์˜๊ฐ์„ ๋ฐ›์€ DataFrame ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ํ”„๋กœ๋•์…˜ AI ๋ฐ ์—์ด์ „ํ‹ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. fenic์€ Hugging Face Hub์—์„œ ๋ฐ์ดํ„ฐ์…‹์„ ์ง์ ‘ ์ฝ๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

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

์‹œ์ž‘ํ•˜๋ ค๋ฉด fenic์„ pip๋กœ ์„ค์น˜ํ•˜์„ธ์š”:

pip install fenic

์„ธ์…˜ ๋งŒ๋“ค๊ธฐ

๊ธฐ๋ณธ ๊ตฌ์„ฑ์œผ๋กœ fenic ์„ธ์…˜์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค(๋ฐ์ดํ„ฐ์…‹ ์ฝ๊ธฐ ๋ฐ ๊ธฐํƒ€ ๋น„์˜๋ฏธ๋ก ์  ์ž‘์—…์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค):

import fenic as fc

session = fc.Session.get_or_create(fc.SessionConfig())

๊ฐœ์š”

fenic๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ฒฐํ•ฉํ•œ ์˜๊ฒฌ์ด ๋‹ด๊ธด ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค:

  • DataFrame API: PySpark์—์„œ ์˜๊ฐ์„ ๋ฐ›์€ ์นœ์ˆ™ํ•œ ๋ฐ์ดํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•œ ์—ฐ์‚ฐ
  • ์˜๋ฏธ๋ก ์  ์—ฐ์‚ฐ: ์˜๋ฏธ๋ก ์  ํ•จ์ˆ˜, ์ž„๋ฒ ๋”ฉ, ํด๋Ÿฌ์Šคํ„ฐ๋ง์„ ํฌํ•จํ•œ ๋‚ด์žฅ AI/LLM ์—ฐ์‚ฐ
  • ๋ชจ๋ธ ํ†ตํ•ฉ: AI ์ œ๊ณต์—…์ฒด(Anthropic, OpenAI, Cohere, Google)์— ๋Œ€ํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ์ง€์›
  • ์ฟผ๋ฆฌ ์ตœ์ ํ™”: ๋…ผ๋ฆฌ ๊ณ„ํš ๋ณ€ํ™˜์„ ํ†ตํ•œ ์ž๋™ ์ตœ์ ํ™”

Hugging Face Hub์—์„œ ์ฝ๊ธฐ

fenic์€ hf:// ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜์—ฌ Hugging Face Hub์—์„œ ๋ฐ์ดํ„ฐ์…‹์„ ์ง์ ‘ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ fenic์˜ DataFrameReader ์ธํ„ฐํŽ˜์ด์Šค์— ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€์›๋˜๋Š” ํ˜•์‹

fenic์€ Hugging Face์—์„œ ๋‹ค์Œ ํ˜•์‹์„ ์ฝ๋Š” ๊ฒƒ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:

  • Parquet ํŒŒ์ผ (.parquet)
  • CSV ํŒŒ์ผ (.csv)

๋ฐ์ดํ„ฐ์…‹ ์ฝ๊ธฐ

Hugging Face Hub์—์„œ ๋ฐ์ดํ„ฐ์…‹์„ ์ฝ์œผ๋ ค๋ฉด:

import fenic as fc

session = fc.Session.get_or_create(fc.SessionConfig())

# Read a CSV file from a public dataset
df = session.read.csv("hf://datasets/datasets-examples/doc-formats-csv-1/data.csv")

# Read Parquet files using glob patterns
df = session.read.parquet("hf://datasets/cais/mmlu/astronomy/*.parquet")

# Read from a specific dataset revision
df = session.read.parquet("hf://datasets/datasets-examples/doc-formats-csv-1@~parquet/**/*.parquet")

์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ์™€ ํ•จ๊ป˜ ์ฝ๊ธฐ

# Read multiple CSV files with schema merging
df = session.read.csv("hf://datasets/username/dataset_name/*.csv", merge_schemas=True)

# Read multiple Parquet files with schema merging
df = session.read.parquet("hf://datasets/username/dataset_name/*.parquet", merge_schemas=True)

์ฐธ๊ณ : fenic์—์„œ ์Šคํ‚ค๋งˆ๋ž€ ์ปฌ๋Ÿผ ์ด๋ฆ„๊ณผ ํ•ด๋‹น ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ์ง‘ํ•ฉ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. merge_schemas๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉด fenic์€ ๋ˆ„๋ฝ๋œ ์ปฌ๋Ÿผ์— null์„ ์ฑ„์šฐ๊ณ  ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ํƒ€์ž…์„ ํ™•์žฅํ•˜์—ฌ ํŒŒ์ผ ๊ฐ„ ์ฐจ์ด๋ฅผ ์กฐ์ •ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ ˆ์ด์•„์›ƒ์€ ๋ณ‘ํ•ฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ CSV ์Šคํ‚ค๋งˆ ๋ณ‘ํ•ฉ ์ œํ•œ ์‚ฌํ•ญ ๋ฐ Parquet ์Šคํ‚ค๋งˆ ๋ณ‘ํ•ฉ ์ œํ•œ ์‚ฌํ•ญ์— ๋Œ€ํ•ด fenic ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ธ์ฆ

๋น„๊ณต๊ฐœ ๋ฐ์ดํ„ฐ์…‹์„ ์ฝ์œผ๋ ค๋ฉด Hugging Face ํ† ํฐ์„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

export HF_TOKEN="your_hugging_face_token_here"

๊ฒฝ๋กœ ํ˜•์‹

fenic์˜ Hugging Face ๊ฒฝ๋กœ ํ˜•์‹์€ ๋‹ค์Œ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค:

hf://{repo_type}/{repo_id}/{path_to_file}

๋ฐ์ดํ„ฐ์…‹์˜ ๋ฆฌ๋น„์ „ ๋˜๋Š” ๋ฒ„์ „์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

hf://{repo_type}/{repo_id}@{revision}/{path_to_file}

๊ธฐ๋Šฅ:

  • glob ํŒจํ„ด(*, **)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค
  • Dataset์˜ revision/version์„ ์‚ฌ์šฉํ•  ๋•Œ @ ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:
    • ํŠน์ • ์ปค๋ฐ‹: @d50d8923b5934dc8e74b66e6e4b0e2cd85e9142e
    • Branch: @refs/convert/parquet
    • Branch alias: @~parquet
  • ๋น„๊ณต๊ฐœ ๋ฐ์ดํ„ฐ์…‹์˜ ๊ฒฝ์šฐ HF_TOKEN ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค

๋ฐ์ดํ„ฐ ์†Œ์Šค ํ˜ผํ•ฉ

fenic์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๋‹จ์ผ ์ฝ๊ธฐ ์ž‘์—…์œผ๋กœ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ์„ ํ˜ผํ•ฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค:

# Mix HF and local files in one read call
df = session.read.parquet([
    "hf://datasets/cais/mmlu/astronomy/*.parquet",
    "file:///local/data/*.parquet",
    "./relative/path/data.parquet"
])

์ด๋Ÿฌํ•œ ์œ ์—ฐ์„ฑ์„ ํ†ตํ•ด Hugging Face Hub์˜ ๋ฐ์ดํ„ฐ์™€ ๋กœ์ปฌ ํŒŒ์ผ์„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Hugging Face์—์„œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

Hugging Face์—์„œ ๋กœ๋“œํ•œ ํ›„, fenic์˜ ์ „์ฒด DataFrame API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

๊ธฐ๋ณธ DataFrame ์—ฐ์‚ฐ

import fenic as fc

session = fc.Session.get_or_create(fc.SessionConfig())

# Load IMDB dataset from Hugging Face
df = session.read.parquet("hf://datasets/imdb/plain_text/train-*.parquet")

# Filter and select
positive_reviews = df.filter(fc.col("label") == 1).select("text", "label")

# Group by and aggregate
label_counts = df.group_by("label").agg(
    fc.count("*").alias("count")
)

AI ๊ธฐ๋ฐ˜ ์šด์˜

semantic ๋ฐ embedding ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด SessionConfig์—์„œ ์–ธ์–ด ๋ฐ ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ์„ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์ด ์™„๋ฃŒ๋˜๋ฉด:

import fenic as fc

# Requires OPENAI_API_KEY to be set for language and embedding calls
session = fc.Session.get_or_create(
    fc.SessionConfig(
        semantic=fc.SemanticConfig(
            language_models={
                "gpt-4o-mini": fc.OpenAILanguageModel(
                    model_name="gpt-4o-mini",
                    rpm=60,
                    tpm=60000,
                )
            },
            embedding_models={
                "text-embedding-3-small": fc.OpenAIEmbeddingModel(
                    model_name="text-embedding-3-small",
                    rpm=60,
                    tpm=60000,
                )
            },
        )
    )
)

# Load a text dataset from Hugging Face
df = session.read.parquet("hf://datasets/imdb/plain_text/train-00000-of-00001.parquet")

# Add embeddings to text columns
df_with_embeddings = df.select(
    "*",
    fc.semantic.embed(fc.col("text")).alias("embedding")
)

# Apply semantic functions for sentiment analysis
df_analyzed = df_with_embeddings.select(
    "*",
    fc.semantic.analyze_sentiment(
        fc.col("text"),
        model_alias="gpt-4o-mini",  # Optional: specify model
    ).alias("sentiment")
)

์˜ˆ: MMLU ๋ฐ์ดํ„ฐ์…‹ ๋ถ„์„

import fenic as fc

# Requires OPENAI_API_KEY to be set for semantic calls
session = fc.Session.get_or_create(
    fc.SessionConfig(
        semantic=fc.SemanticConfig(
            language_models={
                "gpt-4o-mini": fc.OpenAILanguageModel(
                    model_name="gpt-4o-mini",
                    rpm=60,
                    tpm=60000,
                )
            },
        )
    )
)

# Load MMLU astronomy subset from Hugging Face
df = session.read.parquet("hf://datasets/cais/mmlu/astronomy/*.parquet")

# Process the data
processed_df = (df
    # Filter for specific criteria
    .filter(fc.col("subject") == "astronomy")
    # Select relevant columns
    .select("question", "choices", "answer")
    # Add difficulty analysis using semantic.map
    .select(
        "*",
        fc.semantic.map(
            "Rate the difficulty of this question from 1-5: {{question}}",
            question=fc.col("question"),
            model_alias="gpt-4o-mini"  # Optional: specify model
        ).alias("difficulty")
    )
)

# Show results
processed_df.show()

๋ฆฌ์†Œ์Šค

Update on GitHub