ML/MLOps Engineer
MLOps 03: Feast Feature Store — An In-depth Overview Experimentation and Applica

MLOps 03: Feast Feature Store โ€” An In-depth Overview Experimentation and Application in Tabular data๋ฅผ ์ฝ๊ณ  ๋ฒˆ์—ญํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

์™œ Feature Store๊ฐ€ ํ•„์š”ํ•œ๊ฐ€

์˜ˆ์‹œ) ํ•œ ๋ฐ์ดํ„ฐ ๊ณผํ•™ ํŒ€์ด ๊ณ ๊ฐ ์ดํƒˆ์„ ์˜ˆ์ธกํ•˜๋Š” ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ ์ค‘ํ•˜๊ฒŒ ์ˆ˜์ง‘ํ•˜๊ณ  ์ •๋ฆฌํ•œ ํ›„, ์ด์ œ ํ”ผ์ฒ˜ ์—”์ง€๋‹ˆ์–ด๋ง์— ์ฐฉ์ˆ˜ํ•  ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋งˆ์ฃผํ•ฉ๋‹ˆ๋‹ค.

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

์ด๋•Œ Feature Store๊ฐ€ ๋“ฑ์žฅํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋จธ์‹ ๋Ÿฌ๋‹ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ๊ฐ„์†Œํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค.

์™œ Feast๋ฅผ Feature Store๋กœ ์„ ํƒํ•˜๋Š”๊ฐ€?


์—ฌ๋Ÿฌ Feature Store๊ฐ€ ์กด์žฌํ•˜์ง€๋งŒ, Feast๋Š” ๋›ฐ์–ด๋‚œ ๊ธฐ๋Šฅ์„ ์กฐํ•ฉํ•ด ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ์ธํ”„๋ผ๋ฅผ ํ™œ์šฉํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘์–ด, ๋จธ์‹ ๋Ÿฌ๋‹ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ตœ์ ํ™”ํ•˜๊ณ ์ž ํ•˜๋Š” ์กฐ์ง์— ๊ฐ•๋ ฅํ•œ ์„ ํƒ์ง€๋กœ ์ž๋ฆฌ ์žก๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
Feast๋Š” ์˜คํ”ˆ ์†Œ์Šค ํŠน์„ฑ, ํ™•์žฅ์„ฑ, ๊ทธ๋ฆฌ๊ณ  ํ™œ๋ฐœํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ง€์›์„ ํ†ตํ•ด ํ”ผ์ฒ˜ ์Šคํ† ์–ด ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑ์‹œํ‚ค๋Š” ๊ฐ•๋ ฅํ•œ ํ›„๋ณด๋กœ ๋– ์˜ค๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Feast์˜ ๋ฌธ์„œ์™€ ๋ฆฌ์†Œ์Šค๋ฅผ ํƒ์ƒ‰ํ•˜์—ฌ ํŒ€์˜ ํ•„์š”์— ๋ถ€ํ•ฉํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ๊ณ ์„ฑ๋Šฅ ML ๋ชจ๋ธ ๊ตฌ์ถ•์„ ์œ„ํ•ด ํŒ€์„ ์ง€์›ํ•ด ๋ณด์„ธ์š”.
Feast๊ฐ€ ๋‹๋ณด์ด๋Š” ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  • ํŒ€๊ณผ ํ”„๋กœ์ ํŠธ ๊ฐ„ ํ”ผ์ฒ˜๋ฅผ ๊ณต์œ ํ•˜์—ฌ ์ค‘๋ณต ์ž‘์—…์„ ์ค„์ž…๋‹ˆ๋‹ค.
  • ํ”„๋กœ์ ํŠธ ๊ฐ„ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ํ”ผ์ฒ˜ ์—”์ง€๋‹ˆ์–ด๋ง๊ณผ ๋ชจ๋ธ ๊ฐœ๋ฐœ์„ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค (๋ฐ์ดํ„ฐ ๊ณผํ•™์ž๋“ค์ด ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค).
  • ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ”ผ์ฒ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ML ์ „๋ฌธ๊ฐ€๋“ค์ด ์นœ์ˆ™ํ•œ ๊ธฐ์กด ๋„๊ตฌ๋“ค๊ณผ ํ†ตํ•ฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค (์˜ˆ: Airflow, Dagster, MLFlow, K8s).Feast๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผ์ฒ˜ ์ €์žฅ ๋ฐ ์„œ๋น™ํ•˜๋Š” ๋ฐฉ๋ฒ•
    Source: MLOps Tools Part 5: BigQuery + Memorystore vs. FEAST for Feature StoreEntity, Datasource, ๊ทธ๋ฆฌ๊ณ  FeatureView๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผ์ฒ˜ ์ €์žฅํ•˜๊ธฐ
  1. ํ”ผ์ฒ˜ ์ •์˜ํ•˜๊ธฐ:

Feast๋Š” ํ”ผ์ฒ˜ ์ •์˜๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ํ”ผ์ฒ˜ ์ด๋ฆ„, ๋ฐ์ดํ„ฐ ์œ ํ˜•, ๊ทธ๋ฆฌ๊ณ  ์—ฐ๊ฒฐ๋œ ์—”ํ„ฐํ‹ฐ ํ‚ค(์˜ˆ: ์‚ฌ์šฉ์ž ID, ์ œํ’ˆ ID)๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ณผ์ •์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ๋ฐ์ดํ„ฐ ์›จ์–ดํ•˜์šฐ์Šค, ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋น„์Šค์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์œ„ํ•ด ํ”ผ์ฒ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from feast import Entity  
from feast.infra.offline_stores.contrib.spark_offline_store.spark_source import SparkSource  
from feast import FeatureView, Field  

# Entity  
user = Entity(  
    name="user",  
    join_keys=["user_id"],  
    description="Entity to represent user for loan default prediction",  
)  

# Datasource  
sparksource_user_loan = SparkSource(  
   path=os.path.join(get_feature_folder_path(), "loan_default_gen"),  
   file_format="parquet",
   timestamp_field="txn_datetime",
   name="user_loan",  
)  

# FeatureView  
user_info_fv = FeatureView(  
    name="user_info",
    entities=[user],  
    schema=[  
        Field(name="Age", dtype=Int64),  
        Field(name="Education", dtype=String),  
        Field(name="CreditScore", dtype=Int64),  
        Field(name="MonthsEmployed", dtype=Int64),  
    ],
    source=sparksource_user_loan,  
    description="Calculate overall transaction behaviors of customer",  
)
  1. ํ”ผ์ฒ˜ ์ €์žฅ์†Œ ๊ตฌ์ถ•ํ•˜๊ธฐ:

ํ”ผ์ฒ˜ ์ €์žฅ์†Œ๋Š” Feast์˜ ์„ค๊ณ„๋„ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ํ”ผ์ฒ˜ ์ •์˜์™€ ์˜จ๋ผ์ธ ๋ฐ ์˜คํ”„๋ผ์ธ ์ €์žฅ์„ ์œ„ํ•œ ์„ค์ •์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. Feast๋Š” ๋‹ค์–‘ํ•œ ์ €์žฅ ์˜ต์…˜์„ ์ œ๊ณตํ•˜์—ฌ ํ•„์š”์— ๋”ฐ๋ผ ์œ ์—ฐํ•˜๊ฒŒ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐ Feast ๋ฐฐํฌ์—๋Š” ๋‹จ์ผ ํ”ผ์ฒ˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๊ฐ€ ์žˆ์œผ๋ฉฐ, ํ˜„์žฌ Feast๋Š” ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋งŒ ์ง€์›ํ•˜์ง€๋งŒ, ๋„ค ๊ฐ€์ง€ ๋ฐฑ์—”๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

  • Local: ๊ฐœ๋ฐœ ์ค‘ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋กœ์ปฌ ๋ฐฑ์—”๋“œ
  • S3: AWS์—์„œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฑ์—”๋“œ
  • GCS: GCP์—์„œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฑ์—”๋“œ
  • [Alpha] Azure: Azure Blob ์Šคํ† ๋ฆฌ์ง€์—์„œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ์ค‘์•™ ์ง‘์ค‘์‹์œผ๋กœ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฑ์—”๋“œ
    # https://docs.feast.dev/getting-started/architecture-and-components/registry  
    from feast import FeatureStore  
    

Simple: for local development

fs = FeatureStore("my_feature_repo/")


3. ํ”ผ์ฒ˜ ์ƒ์„ฑํ•˜๊ธฐ
Feast๋Š” โ€œmaterializationโ€ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜คํ”„๋ผ์ธ ์ €์žฅ์†Œ์— ๊ณผ๊ฑฐ ํ”ผ์ฒ˜ ๊ฐ’์„ ์ฑ„์›๋‹ˆ๋‹ค. ํŠน์ • ์‹œ๊ฐ„ ๋ฒ”์œ„์— ๋Œ€ํ•ด ํ”ผ์ฒ˜ ์ƒ์„ฑ์„ ์‹คํ–‰ํ•˜์—ฌ, ๋ชจ๋ธ์ด ์ผ๊ด€๋œ ๋ฐ์ดํ„ฐ ์Šค๋ƒ…์ƒท์œผ๋กœ ํ•™์Šต๋  ์ˆ˜ ์žˆ๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
```python
list_entities = [user]  
list_datasources = [sparksource_user_loan]  
list_feature_views = [user_info_fv]  

fs.apply(  
  objects=[  
      *list_entities,  
      *list_datasources,  
      *list_feature_views,  
  ],  
)

์‹ค์‹œ๊ฐ„ ์ถ”๋ก ์„ ์œ„ํ•ด Feast๋Š” ๋‚ฎ์€ ์ง€์—ฐ ์‹œ๊ฐ„์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์˜จ๋ผ์ธ ์ €์žฅ์†Œ๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ”ผ์ฒ˜ ์ƒ์„ฑ์€ ์ตœ์‹  ํ”ผ์ฒ˜ ๊ฐ’์„ ์˜จ๋ผ์ธ ์ €์žฅ์†Œ์— ์ฑ„์›Œ ๋„ฃ์–ด, ๋ชจ๋ธ์ด ์˜ˆ์ธก ์‹œ ์ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

dt = datetime.now()  
fs.materialize(start_date=dt - relativedelta(months=24), end_date=dt)

get_historical_features, get_online_features๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผ์ฒ˜ ์„œ๋น™ํ•˜๊ธฐ

  1. ํ›ˆ๋ จ์„ ์œ„ํ•œ ํ”ผ์ฒ˜ ๊ฐ€์ ธ์˜ค๊ธฐ

Feast๋Š” ์˜จ๋ผ์ธ ๋ฐ ์˜คํ”„๋ผ์ธ ์ €์žฅ์†Œ์—์„œ ํ”ผ์ฒ˜๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ›ˆ๋ จ ์‹œ, ์ด API๋ฅผ ํ†ตํ•ด ์˜คํ”„๋ผ์ธ ์ €์žฅ์†Œ์—์„œ ๊ณผ๊ฑฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import pandas as pd  

# Prepare entity dataframe with (user_id, event_timestamp) so that Feast can do Point-in-time joins  
# https://docs.feast.dev/getting-started/concepts/point-in-time-joins  
entity_df=pd.DataFrame(  
    [  
        ['HlWpZydxscnmjGgeIPLi', pd.datetime(2023,1,2)],  
        ['RckfsuJrhXFYAToUVlmy', pd.datetime(2024,1,9)],  
        ['WJGbtTpKalFBqmMhcnPC', pd.datetime(2024,5,9)],   
    ],  
    columns=['user_id','event_timestamp']  
)  

#  
df_feature = fs.get_historical_features(  
    entity_df=entity_df,  
    features=[  
        'user_info:Age',  
        'user_info:Education',  
        'user_loan_ts:median_previous_income'  
    ]  
)
  1. ํ”ผ์ฒ˜ ์„œ๋น™ํ•˜๊ธฐ (์˜จ๋ผ์ธ ์ €์žฅ์†Œ):

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์‹ค์‹œ๊ฐ„ ์˜ˆ์ธก์„ ์œ„ํ•ด ์„œ๋น™ ์ธํ”„๋ผ๊ฐ€ ์˜จ๋ผ์ธ ์ €์žฅ์†Œ์—์„œ ์ตœ์‹  ํ”ผ์ฒ˜๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import pandas as pd  

# Prepare entity dataframe with (user_id, event_timestamp) so that Feast can do Point-in-time joins  
# https://docs.feast.dev/getting-started/concepts/point-in-time-joins  
entity_df=pd.DataFrame(  
    [  
        ['HlWpZydxscnmjGgeIPLi', pd.datetime(2023,1,2)],  
        ['RckfsuJrhXFYAToUVlmy', pd.datetime(2024,1,9)],  
        ['WJGbtTpKalFBqmMhcnPC', pd.datetime(2024,5,9)],  
    ],  
    columns=['user_id','event_timestamp']  
)  

#  
df_feature = fs.get_online_features(  
    entity_rows=[{'user_id': 'kyHoSmrOEWTzDRlpqBVQ'},  
    features=[  
        'user_info:Age',  
        'user_info:Education',  
        'user_loan_ts:median_previous_income'  
    ]  
)

๋‹ค์Œ์œผ๋กœ, ๊ฐ ์‹œ๋‚˜๋ฆฌ์˜ค ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

์‹œ๋‚˜๋ฆฌ์˜ค 01: DS - ๋ฏธ๋ฆฌ ๊ณ„์‚ฐ๋œ ํ”ผ์ฒ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์‹คํ—˜ํ•˜๊ธฐ

1. ํ”ผ์ฒ˜ ์ƒ์„ฑ ๋ฐ ๋“ฑ๋ก (์Šคํ…Œ์ด์ง•)

  • 1๋‹จ๊ณ„: ํ”ผ์ฒ˜ ๊ตฌ์ถ•
  • 2๋‹จ๊ณ„: ํ”ผ์ฒ˜๋ฅผ ์ €์žฅ์†Œ์— ์ €์žฅ
  • 3๋‹จ๊ณ„: ํ”ผ์ฒ˜ ์Šคํ† ์–ด์— ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋“ฑ๋ก2. ๋‹ค๋ฅธ ํ›ˆ๋ จ์„ ์œ„ํ•œ ํ”ผ์ฒ˜ ์žฌ์‚ฌ์šฉ
  • 1๋‹จ๊ณ„: Feast UI๋ฅผ ํƒ์ƒ‰ํ•˜์—ฌ ๊ณ ๋ คํ•  ํ”ผ์ฒ˜ ๋ชฉ๋ก์„ ์ฐพ์Šต๋‹ˆ๋‹ค.
  • 2๋‹จ๊ณ„: get_historical_features, get_online_features๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผ์ฒ˜ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.์‹œ๋‚˜๋ฆฌ์˜ค 02: DE โ€” ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ํ†ตํ•ฉ (ํ”„๋กœ๋•์…˜)
  • CI/CD ํŒŒ์ดํ”„๋ผ์ธ ์ค€๋น„ ๋ฐ ํ”ผ์ฒ˜ ์ž๋™ ๊ฐ€์ ธ์˜ค๊ธฐ


์—”ํ„ฐํ‹ฐ ๋ชฉ๋ก ์ •์˜


FeatureView ๋ชฉ๋ก ์ •์˜


๋ชจ๋“  ์—”ํ„ฐํ‹ฐ์™€ ํ”ผ์ฒ˜๋ฅผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋“ฑ๋ก

์‹œ๋‚˜๋ฆฌ์˜ค 03: MLE โ€” ์˜จ๋ผ์ธ API ์ถ”๋ก  ์„œ๋น™


Source: A State of Feast

@app.post("/predict_loan_default")  
def predict_loan_default(request_loan_predict: Request) -> Response:  

    # 1. Load model and parse requests' info  
    xgb: XGBClassifier=ml_models['model']  
    feature_dict={}  
    user_id=request_loan_predict.user_id  
    feature_dict['loan_amount']=request_loan_predict.loan_amount  
    feature_dict['loan_term']=request_loan_predict.loan_term  
    feature_dict['dti_ratio']=request_loan_predict.dti_ratio  
    feature_dict['interest_rate']=request_loan_predict.interest_rate  

    # 2. Get pre-built features from Feature store  
    store:FeatureStore=ml_models['store']  
    fs_model=store.get_feature_service('user_xgb_v1')  
    features_from_store = store.get_online_features(  
        features=fs_model, entity_rows=[{'user_id':user_id}]  
    ).to_dict()  

    # 3. Combine all features  
    list_feature=[]  
    for feature in xgb.feature_names_in_:  
        if feature not in feature_dict:  
            feature_dict[feature]=features_from_store[feature][0]  

        list_feature.append(feature_dict[feature])  

    # 4. Make model inference  
    score=xgb.predict_proba(np.array([list_feature]))[0][1]  

    # 5. Response results  
    response=Response(request=request_loan_predict,default_score=score)  

    return response

๋…ผ์˜

Future Directions:

  • ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ง€์› ํ™•์žฅ: ์ถ”๊ฐ€ ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ํ˜ธํ™˜์„ฑ ์ถ”๊ฐ€๋ฅผ ํƒ์ƒ‰ํ•˜์—ฌ ๋” ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž ์š”๊ตฌ์™€ ์„ ํ˜ธ๋ฅผ ์ถฉ์กฑ์‹œํ‚ต๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ํ’ˆ์งˆ ๋ชจ๋‹ˆํ„ฐ๋ง ์„ฑ์ˆ™ํ™”: ๋ฒกํ„ฐํ™”๋œ ๋ฐ์ดํ„ฐ ๋‚ด์˜ ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ํ•ด๊ฒฐํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ ํ’ˆ์งˆ ๋ชจ๋‹ˆํ„ฐ๋ง ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์„ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค.
  • ํ…์ŠคํŠธ ๋ฐ ์ด๋ฏธ์ง€ ํ”ผ์ฒ˜ ํ†ตํ•ฉ: ํ…์ŠคํŠธ ๋ฐ ์ด๋ฏธ์ง€ ํ”ผ์ฒ˜์— ๋Œ€ํ•œ ์›Œํฌํ”Œ๋กœ์šฐ์™€์˜ ์›ํ™œํ•œ ํ†ตํ•ฉ์„ ํƒ์ƒ‰ํ•˜์—ฌ, ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ์ง€ ๊ฒ€์ƒ‰์ด๋‚˜ ํ…์ŠคํŠธ ์œ ์‚ฌ๋„ ๋ถ„์„๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์œ„ํ•ด VectorDB๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.Strengths:
  • ํ‘œ์ค€ํ™”๋˜๊ณ  ์ผ๊ด€๋œ ํ”ผ์ฒ˜: ๋™์ผํ•œ ์ •์˜์™€ ๋ณ€ํ™˜์ด ์ ์šฉ๋œ ๋ชจ๋ธ ๊ฐ„์— ํ”ผ์ฒ˜ ์‚ฌ์šฉ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ์‹œ๊ณ„์—ด ์ง€์›: ์‹œ๊ฐ„ ์ง€์ ์˜ ์ •ํ™•์„ฑ์„ ์ œ๊ณตํ•˜์—ฌ ๊ธˆ์œต ๋ฐ์ดํ„ฐ๋‚˜ ๊ฑฐ๋ž˜ ๋ฐ์ดํ„ฐ์—์„œ ์ค‘์š”ํ•œ ์š”์†Œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅธ ๋„๊ตฌ์™€์˜ ํ†ตํ•ฉ: Feast๋Š” Airflow, Dagster, MLFlow, K8s์™€ ๊ฐ™์€ ์ธ๊ธฐ ์žˆ๋Š” ๋จธ์‹ ๋Ÿฌ๋‹ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์ž˜ ํ†ตํ•ฉ๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ ๋ฐ ๋ชจ๋ธ ๊ด€๋ฆฌ ๋„๊ตฌ์™€๋„ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค.
  • ์˜จ๋ผ์ธ ๋ฐ ์˜คํ”„๋ผ์ธ ์ง€์›: ์‹ค์‹œ๊ฐ„ ์˜ˆ์ธก๊ณผ ๋ฐฐ์น˜ ์˜ˆ์ธก์„ ๋•๊ณ , ํ›ˆ๋ จ๊ณผ ์˜ˆ์ธก์„ ์œ„ํ•œ ๋ชจ๋“  ํ”ผ์ฒ˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํ†ตํ•ฉ๋œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์—ฌ ๋ชจ๋ธ ๋ฐฐํฌ ๋ฐ ์„œ๋น™์„ ๊ฐ„์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ Feast๋Š” SnowFlake, BigQuery, PostgreSQL, MySQL, RedShift, Athena, DuckDB, Trino, Ibis, Redis, DynamoDB, Cassandra, HBase, Rockset, Hazelcast ๋“ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๋ฒ„์ „ ๊ด€๋ฆฌ: ํ”ผ์ฒ˜์˜ ๋‹ค์–‘ํ•œ ๋ฒ„์ „์„ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.Weaknesses:
  • ๋ณต์žก์„ฑ: ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ๋‚˜ ๋จธ์‹ ๋Ÿฌ๋‹์„ ์‹œ์ž‘ํ•˜๋Š” ํŒ€์—๊ฒŒ๋Š” ๊ณผ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ตœ์†Œํ•œ์˜ UI: ํ”ผ์ฒ˜ ํƒ์ƒ‰ ๋ฐ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์ตœ์†Œํ•œ์˜ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ œํ•œ๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ง€์›: ํ˜„์žฌ Feast๋Š” Google BigQuery, Redshift, Snowflake, Spark, PostgreSQL๊ณผ ๊ฐ™์€ ์ œํ•œ๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฌธ์„œ ๋ถ€์กฑ: ๊ฐœ์„  ์ค‘์ด์ง€๋งŒ, Feast์˜ ๋ฌธ์„œ๋Š” ํŠนํžˆ ๋ณต์žกํ•œ ๋ฐฐํฌ๋‚˜ ๊ณ ๊ธ‰ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์—ฌ์ „ํžˆ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค.