Snowpark ML Ops: 모델 레지스트리¶
참고
이 항목에서 설명하는 모델 레지스트리 API는 Snowpark ML 패키지 버전 1.2.0 이상에서 사용할 수 있습니다.
고객은 Snowpark ML Operations(MLOps)의 일부인 Snowpark 모델 레지스트리를 사용해 원본에 관계없이 Snowflake에서 모델과 해당 메타데이터를 안전하게 관리할 수 있습니다. Snowpark 모델 레지스트리는 머신 러닝 모델을 Snowflake의 일급 스키마 수준 오브젝트로 저장하므로 조직의 다른 사람들이 쉽게 찾아서 사용할 수 있습니다. Snowpark ML을 사용하여 레지스트리를 만들고 그곳에 모델을 저장할 수 있습니다. 모델에는 여러 버전이 있을 수 있으며, 한 버전을 기본값으로 지정할 수 있습니다.
모델을 저장한 후에는 해당 메서드(함수 또는 저장 프로시저와 동일)를 호출하여 Snowflake 가상 웨어하우스 에서 추론과 같은 모델 작업을 수행할 수 있습니다.
팁
모델 레지스트리를 포함한 Snowpark ML의 엔드 투 엔드 워크플로 예시는 Snowpark ML을 이용한 머신 러닝 소개 를 참조하십시오.
Snowpark 모델 레지스트리 API의 세 가지 주요 오브젝트는 다음과 같습니다.
snowflake.ml.registry.Registry
: 스키마 내에서 모델을 관리합니다.snowflake.ml.model.Model
: 모델을 나타냅니다.snowflake.ml.model.ModelVersion
: 모델의 버전을 나타냅니다.
이러한 클래스에 대한 자세한 내용은 Snowpark ML API 참조 를 확인하십시오.
Snowpark 모델 레지스트리는 다음 유형의 모델을 지원합니다.
scikit-learn
XGBoost
PyTorch
TensorFlow
MLFlow PyFunc
HuggingFace 파이프라인
이 항목에서는 Snowpark ML을 사용하여 Python에서 레지스트리 작업을 수행하는 방법을 설명합니다. 또한 SQL에서는 많은 레지스트리 작업을 수행할 수 있습니다. 자세한 내용은 모델 명령 섹션을 참조하십시오.
비공개 미리 보기와의 차이점¶
Snowflake는 이전에 특정 고객에게 비공개로 모델 레지스트리를 제공했습니다. 이 항목에 설명된 레지스트리 기능은 비공개 미리 보기 버전에 비해 기능과 API가 크게 변경되었습니다. 가장 주목할 만한 점은 모델 레지스트리 기능이 이제는 새로운 스키마 수준 오브젝트를 사용하여 Snowflake 내에서 기본적으로 호스팅된다는 점입니다.
참고
이 공개 미리 보기 버전은 아직 Snowpark Container Services (SPCS)에 모델 배포를 지원하지 않습니다. 이 기능을 사용하는 경우 지금은 비공개 미리 보기 레지스트리를 계속 사용하십시오.
이 두 API의 차이점에 대한 자세한 내용은 Snowpark ML Ops: Model Registry Preview API에서 마이그레이션하기 섹션을 참조하십시오.
필수 권한¶
모델을 생성하려면 모델이 생성된 스키마를 소유하거나 모델에 대한 CREATE MODEL 권한이 있어야 합니다. 모델을 사용하려면 모델을 소유하거나 모델에 대한 USAGE 권한이 있어야 합니다.
Snowpark 모델 레지스트리 열기¶
모델은 일급 Snowflake 오브젝트이며 다른 Snowflake 오브젝트와 함께 데이터베이스 및 스키마 내에서 구성할 수 있습니다. Snowpark 모델 레지스트리는 스키마 내에서 모델을 관리하기 위한 Python 클래스입니다. 따라서 모든 Snowflake 스키마를 레지스트리로 사용할 수 있습니다. 이 목적을 위해 스키마를 초기화하거나 준비할 필요는 없습니다. Snowflake에서는 이 목적을 위해 ML.REGISTRY와 같은 전용 스키마를 하나 이상 생성할 것을 권장합니다. CREATE SCHEMA 를 사용하여 스키마를 생성할 수 있습니다.
레지스트리에서 모델을 생성하거나 수정하려면 먼저 레지스트리를 열어야 합니다. 레지스트리를 열면 이에 대한 참조가 반환되며, 이를 사용하여 새 모델을 추가하고 기존 모델에 대한 참조를 얻을 수 있습니다.
from snowflake.ml.registry import Registry
reg = Registry(session=sp_session, database_name="ML", schema_name="REGISTRY")
참고
이 공개 미리 보기 중에는 Model
오브젝트가 복제 또는 복제본 생성을 지원하지 않습니다.
모델 및 버전 등록하기¶
레지스트리에 모델을 추가하는 것을 모델 로깅 이라고 합니다. 레지스트리의 log_model
메서드를 호출하여 모델을 로깅합니다. 이 메서드:
Python 오브젝트인 모델을 직렬화하고 여기에서 Snowflake 모델 오브젝트를 생성합니다.
log_model
호출에 지정된 대로 설명과 같은 메타데이터를 모델에 추가합니다.
참고
태그는 모델의 속성이고 log_model
은 특정 모델 버전을 추가하므로 레지스트리에 모델을 추가할 때 모델에 태그를 추가할 수 없습니다. 모델의 첫 번째 버전을 로깅한 후 모델 태그를 업데이트 할 수 있습니다.
각 모델에는 여러 버전이 있을 수 있습니다. 모델의 추가 버전을 로깅하려면 동일한 model_name
및 다른 version_name
을 사용하여 log_model
을 다시 호출하십시오.
아래 예에서 “classifier”(분류자)의 약어인 clf
는 코드의 다른 곳에서 이미 생성된 Python 모델 오브젝트입니다. 여기에 표시된 대로 등록 시 설명과 태그를 추가할 수 있습니다. 이름과 버전의 조합은 스키마에서 고유해야 합니다. conda_dependencies
목록을 지정할 수 있으며, 지정된 패키지가 모델과 함께 배포됩니다.
mv = reg.log_model(clf,
model_name="my_model",
version_name="1",
conda_dependencies=["scikit-learn"],
comment="My awesome ML model",
metrics={"score": 96},
sample_input_data=train_features)
log_model
의 인자는 여기에 설명되어 있습니다.
필수 인자
인자 |
설명 |
---|---|
|
지원되는 모델 유형의 Python 모델 오브젝트입니다. 직렬화 가능(“피클 가능”)해야 합니다. |
|
레지스트리에서 모델을 식별하기 위해 |
|
모델 버전을 지정하는 문자열로, 레지스트리에서 모델을 식별하기 위해 |
참고
모델 이름과 버전의 조합은 스키마에서 고유해야 합니다.
선택적 인자
인자 |
설명 |
---|---|
|
모델을 로드하거나 배포할 때 가져올 코드의 디렉터리 경로 목록입니다. |
|
주석(예: 모델에 대한 설명)입니다. |
|
모델에 필요한 Conda 패키지 목록입니다. 이 인자는 Conda 형식, 즉 |
|
모델과 함께 피클링할 외부 모듈의 목록입니다. scikit-learn, Snowpark ML, PyTorch, TorchScript, 사용자 지정 모델에서 지원됩니다. |
|
모델 버전에 연결된 메트릭이 포함된 사전입니다. |
|
모델 생성 옵션이 포함된 사전입니다. 모든 모델 유형에 대해 다음 옵션을 사용할 수 있습니다.
개별 모델 유형은 추가 옵션을 지원할 수 있습니다. 특정 모델 유형에 대한 참고 사항 섹션을 참조하십시오. |
|
모델에 필요한 PyPI 패키지의 패키지 사양 목록입니다. |
|
모델이 실행될 Python 버전입니다. 기본값은 웨어하우스에서 사용 가능한 최신 버전을 지정하는 |
|
샘플 입력 데이터가 포함된 DataFrame입니다. 모델에 필요한 특성 이름과 해당 유형이 이 DataFrame에서 추출됩니다. Snowpark ML 및 MLFlow 모델을 제외한 모든 모델에 이 인자 또는 |
|
대상 메서드 이름에서 입력 및 출력 서명으로의 매핑으로 사용되는 모델 메서드 서명입니다. Snowpark ML 및 MLFlow 모델을 제외한 모든 모델에 이 인자 또는 |
log_model
은 레지스트리에 추가된 모델의 버전을 나타내는 snowflake.ml.model.ModelVersion
오브젝트를 반환합니다.
일단 등록되면 모델 자체를 수정할 수 없습니다(단, 해당 메타데이터는 변경할 수 있음). 모델과 해당 버전을 모두 삭제하려면 레지스트리의 delete_model 메서드를 사용하십시오.
모델 삭제하기¶
모델과 해당 버전을 모두 삭제하려면 레지스트리의 delete_model
메서드를 사용하십시오.
reg.delete_model("mymodel")
레지스트리에서 모델 가져오기¶
각 모델에 대한 정보를 얻으려면 show_models
메서드를 사용하십시오.
model_df = reg.show_models()
show_models
의 결과는 pandas DataFrame입니다. 사용 가능한 열은 아래와 같습니다.
열 |
설명 |
---|---|
created_on |
모델이 생성된 날짜 및 시간입니다. |
이름 |
모델의 이름입니다. |
데이터베이스_이름 |
모델이 저장되는 데이터베이스입니다. |
스키마_이름 |
모델이 저장되는 스키마입니다. |
owner |
모델을 소유한 역할입니다. |
comment |
모델에 대한 설명입니다. |
versions |
모델의 JSON 배열 목록 버전입니다. |
default_version_name |
버전이 없는 모델을 참조할 때 사용되는 모델의 버전입니다. |
대신 레지스트리에서 모델 목록을 각각 Model
인스턴스로 가져오려면 models
메서드를 사용하십시오.
model_list = reg.models()
이름으로 레지스트리에서 특정 모델에 대한 참조를 가져오려면 레지스트리의 get_model
메서드를 사용하십시오. 이 메서드는 Model
인스턴스를 반환합니다.
m = reg.get_model("MyModel")
참고
Model
인스턴스는 로깅된 Python 모델 오브젝트 원본의 복사본이 아니라 레지스트리의 기본 모델 오브젝트에 대한 참조입니다.
모델에 대한 참조(models
메서드에서 반환된 목록의 참조 또는 get_model
을 사용하여 검색된 참조)가 있으면 해당 메타데이터 및 해당 버전 으로 작업할 수 있습니다.
모델의 메타데이터 보기 및 업데이트하기¶
주석, 태그, 지표를 포함하여 레지스트리에서 모델의 메타데이터 속성을 보고 업데이트할 수 있습니다.
주석 검색 및 업데이트하기¶
모델의 주석을 검색하고 업데이트하려면 모델의 comment
속성을 사용하십시오.
print(m.comment)
m.comment = "A better description than the one I provided originally"
참고
description
속성은 comment
의 별칭입니다. 위의 코드는 다음과 같이 작성할 수도 있습니다.
print(m.description)
m.description = "A better description than the one I provided originally"
모델 버전 관련 작업하기¶
모델에는 버전이 여러 개 있을 수 있으며 각 버전은 문자열로 식별됩니다. 원하는 버전 명명 규칙을 사용할 수 있습니다. 모델을 로깅하면 실제로 모델의 특정 버전 이 기록됩니다. 모델의 추가 버전을 로깅하려면 동일한 model_name
및 다른 version_name
을 사용하여 log_model
을 다시 호출하십시오.
모델 버전은 snowflake.ml.model.ModelVersion
클래스의 인스턴스로 표시됩니다.
모델의 모든 버전 목록을 가져오려면 모델 오브젝트의 versions
메서드를 호출하십시오. 결과는 ModelVersion
인스턴스의 목록입니다.
version_list = m.versions()
대신 각 모델에 대한 정보를 DataFrame으로 가져오려면 모델의 show_versions
메서드를 호출하십시오.
version_df = m.show_versions()
결과 DataFrame에는 다음 열이 포함됩니다.
열 |
설명 |
---|---|
created_on |
모델 버전이 생성된 날짜 및 시간입니다. |
이름 |
버전의 이름입니다. |
데이터베이스_이름 |
버전이 저장되는 데이터베이스입니다. |
스키마_이름 |
버전이 저장되는 스키마입니다. |
model_name |
이 버전이 속한 모델의 이름입니다. |
is_default_version |
이 버전이 모델의 기본 버전인지 여부를 나타내는 부울 값입니다. |
functions |
이 버전에서 사용할 수 있는 함수 이름의 JSON 배열입니다. |
metadata |
메타데이터를 키-값 페어로 포함하는 JSON 오브젝트입니다(메타데이터가 지정되지 않은 경우에는 |
user_data |
모델 정의 매니페스트의 |
모델 버전 삭제하기¶
모델의 delete_version
메서드를 사용하여 모델 버전을 삭제할 수 있습니다.
m.delete_version("rc1")
기본 버전¶
모델의 버전이 기본 모델로 지정될 수 있습니다. 현재 기본 버전을 (ModelVersion
오브젝트로) 가져오거나 (문자열을 사용하여) 변경하려면 모델의 default
속성을 검색하거나 설정하십시오.
default_version = m.default
m.default = "2"
모델 버전에 대한 참조 가져오기¶
특정 버전의 모델에 대한 참조를 ModelVersion
인스턴스로 가져오려면 모델의 version
메서드를 사용하십시오. 모델의 기본 버전을 가져오려면 모델의 default
속성을 사용하십시오.
mv = m.version("1")
mv = m.default
모델의 특정 버전에 대한 참조(예: 바로 위 예의 변수 mv
)가 있으면 다음 섹션에 표시된 대로 참조의 주석이나 메트릭을 검색하거나 업데이트하고 모델의 메서드(함수)를 호출할 수 있습니다.
주석 검색 및 업데이트하기¶
모델과 마찬가지로 모델 버전에도 주석이 있을 수 있으며, 주석은 모델 버전의 comment
또는 description
속성을 통해 액세스하고 설정할 수 있습니다.
print(mv.comment)
print(mv.description)
mv.comment = "A model version comment"
mv.description = "Same as setting the comment"
메트릭 검색 및 업데이트하기¶
메트릭은 예측 정확도 및 기타 모델 버전 특성을 추적하는 데 사용되는 키-값 페어입니다. 모델 버전을 생성할 때 메트릭을 설정하거나 set_metric
메서드를 사용하여 설정할 수 있습니다. 메트릭 값은 숫자, 문자열, 목록, 사전을 포함하여 JSON으로 직렬화할 수 있는 모든 Python 오브젝트일 수 있습니다. 태그와 달리, 메트릭 이름과 가능한 값을 미리 정의할 필요가 없습니다.
테스트 정확도 메트릭은 sklearn의 accuracy_score
를 사용하여 생성될 수 있습니다.
from sklearn import metrics
test_accuracy = metrics.accuracy_score(test_labels, prediction)
혼동 행렬은 sklearn을 사용하여 유사하게 생성할 수 있습니다.
test_confusion_matrix = metrics.confusion_matrix(test_labels, prediction)
그런 다음 이러한 값을 다음과 같이 메트릭으로 설정할 수 있습니다.
# scalar metric
mv.set_metric("test_accuracy", test_accuracy)
# hierarchical (dictionary) metric
mv.set_metric("evaluation_info", {"dataset_used": "my_dataset", "accuracy": test_accuracy, "f1_score": f1_score})
# multivalent (matrix) metric
mv.set_metric("confusion_matrix", test_confusion_matrix)
모델 버전의 메트릭을 Python 사전으로 검색하려면 show_metrics
를 사용하십시오.
metrics = mv.show_metrics()
메트릭을 삭제하려면 delete_metric
을 호출하십시오.
mv.delete_metric("test_accuracy")
모델 메서드 호출하기¶
모델 버전에는 추론이나 기타 모델 작업을 수행하기 위해 실행할 수 있는 연결된 함수인 메서드 가 있을 수 있습니다. 모델 버전에는 다양한 메서드가 있을 수 있으며 이러한 메서드의 서명도 다를 수 있습니다.
모델 버전의 메서드를 호출하려면 mv.run
을 사용하여 호출할 함수의 이름을 지정하고 추론 데이터와 기타 모든 필수 매개 변수가 포함된 DataFrame을 전달하십시오. 이 메서드는 Snowflake 웨어하우스에서 실행됩니다.
참고
메서드를 호출하면 레지스트리에 연결하는 데 사용하는 세션에 지정된 웨어하우스에서 해당 메서드가 실행됩니다. 웨어하우스 지정하기 섹션을 참조하십시오.
다음 예에서는 모델의 predict
메서드를 실행하는 방법을 보여줍니다. 이 모델의 predict
메서드에는 추론 데이터(여기서는 test_features
) 외에 어떤 매개 변수도 필요하지 않습니다. 필요한 경우에는 추론 데이터 뒤에 추가 인자로 전달됩니다.
remote_prediction = mv.run(test_features, function_name="predict")
특정 모델에서 호출할 수 있는 메서드를 확인하려면 mv.show_functions
를 호출하십시오. 이 메서드의 반환 값은 ModelFunctionInfo
오브젝트의 목록입니다. 이러한 각 오브젝트에는 다음 속성이 포함됩니다.
name
: Python 또는 SQL에서 호출할 수 있는 함수의 이름입니다.target_method
: 원래 로깅된 Python 모델의 원래 메서드 이름입니다.
SQL에서 모델 레지스트리로 작업하기¶
모델은 일급 스키마 수준 오브젝트이므로 Snowflake SQL은 모델을 사용한 작업을 위한 명령을 제공합니다. 다음과 같습니다.
참고
Snowflake SQL에는 모델과 버전을 생성하기 위한 명령이 포함되어 있지만 이는 Snowpark 모델 레지스트리 Python API에서 사용하도록 고안되었습니다. 모델 및 버전 등록하기 에 표시된 대로 Python의 로그 모델입니다.
SQL에서 모델 메서드 호출하기¶
model_name!method_name(...)
구문을 사용하여 SQL에서 모델의 메서드를 호출하거나 불러올 수 있습니다. 모델에서 사용할 수 있는 메서드는 기본 Python 모델 클래스에 따라 결정됩니다. 예를 들어, 많은 유형의 모델에서는 추론을 위해 predict
라는 메서드를 사용합니다.
최신 버전의 모델 메서드를 호출하려면 여기에 표시된 구문을 사용하여 메서드에 인자를 전달하고(있는 경우에 괄호로 묶어) FROM 절에 추론 데이터가 포함된 테이블 이름을 전달합니다.
SELECT <model_name>!<method_name>(...) FROM <table_name>;
특정 모델 버전의 메서드를 호출하려면 먼저 특정 버전의 모델에 대한 별칭을 만든 다음 별칭을 통해 원하는 메서드를 호출하십시오.
WITH <model_version_alias> AS MODEL <model_name> VERSION <version>
SELECT <model_version_alias>!<method_name>(...) FROM <table_name>;
비용 고려 사항¶
Snowpark ML 모델 레지스트리를 사용하면 표준 Snowflake 소비 기반 비용이 발생합니다. 다음과 같은 오브젝트가 이에 해당합니다.
모델 아티팩트, 메타데이터, 함수를 저장하는 비용. 저장소 비용에 대한 일반적인 정보는 저장소 비용 살펴보기 섹션을 참조하십시오.
스테이지 간에 파일을 Snowflake에 복사하는 데 드는 비용. COPY FILES 섹션을 참조하십시오.
모델 및 모델 버전 표시, 모델 주석, 태그 및 메트릭 변경과 같은 Snowsight UI나 SQL 또는 Python 인터페이스를 통한 서버리스 모델 오브젝트 작업 비용.
모델 유형과 추론에 사용된 데이터의 양에 따라 달라지는 웨어하우스 컴퓨팅 비용. Snowflake 컴퓨팅 비용에 대한 일반적인 정보는 컴퓨팅 비용 이해하기 섹션을 참조하십시오. 다음에 대해 웨어하우스 컴퓨팅 비용이 발생합니다.
모델 및 버전 생성 작업.
모델의 메서드 호출.
특정 모델 유형에 대한 참고 사항¶
이 섹션에서는 특정 유형의 모델을 Snowpark 모델 레지스트리에 로깅하는 방법에 대한 추가 정보를 제공합니다.
Snowpark ML¶
레지스트리는 Snowpark ML 모델링 API (snowpark.ml.modeling.framework.base.BaseEstimator
에서 파생된 모델)를 사용하여 생성된 모델을 지원합니다. log_model
을 호출할 때 options
사전에서 다음 추가 옵션을 사용할 수 있습니다.
옵션 |
설명 |
---|---|
|
모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. Snowpark ML 모델에는 대상 메서드가 존재한다고 가정하면 기본적으로 |
Snowpark ML 모델을 로깅할 때 sample_input_data
또는 signatures
를 지정할 필요가 없습니다. 이들은 피팅 중에 자동으로 추론됩니다.
예¶
import pandas as pd
import numpy as np
from sklearn import datasets
from snowflake.ml.modeling.xgboost import XGBClassifier
iris = datasets.load_iris()
df = pd.DataFrame(data=np.c_[iris["data"], iris["target"]], columns=iris["feature_names"] + ["target"])
df.columns = [s.replace(" (CM)", "").replace(" ", "") for s in df.columns.str.upper()]
input_cols = ["SEPALLENGTH", "SEPALWIDTH", "PETALLENGTH", "PETALWIDTH"]
label_cols = "TARGET"
output_cols = "PREDICTED_TARGET"
clf_xgb = XGBClassifier(
input_cols=input_cols, output_cols=output_cols, label_cols=label_cols, drop_input_cols=True
)
clf_xgb.fit(df)
model_ref = registry.log_model(
clf_xgb,
model_name="XGBClassifier",
version_name="v1",
)
model_ref.run(df.drop(columns=label_cols).head(10), function_name='predict_proba')
scikit-learn¶
레지스트리는 scikit-learn을 사용하여 생성된 모델(sklearn.base.BaseEstimator
또는 sklearn.pipeline.Pipeline
에서 파생된 모델)을 지원합니다. log_model
을 호출할 때 options
사전에서 다음 추가 옵션을 사용할 수 있습니다.
옵션 |
설명 |
---|---|
|
모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. scikit-learn 모델에는 대상 메서드가 존재한다고 가정하면 기본적으로 |
레지스트리가 대상 메서드의 서명을 알도록 scikit-learn 모델을 로깅할 때 sample_input_data
또는 signatures
매개 변수를 지정해야 합니다.
예¶
from sklearn import datasets, ensemble
iris_X, iris_y = datasets.load_iris(return_X_y=True, as_frame=True)
model = ensemble.RandomForestClassifier(random_state=42)
model.fit(iris_X, iris_y)
model_ref = registry.log_model(
model,
model_name="RandomForestClassifier",
version_name="v1",
sample_input_data=iris_X,
options={
"method_options": {
"predict": {"case_sensitive": True},
"predict_proba": {"case_sensitive": True},
"predict_log_proba": {"case_sensitive": True},
}
},
)
model_ref.run(iris_X[-10:], function_name='"predict_proba"')
XGBoost¶
레지스트리는 XGBoost(xgboost.XGBModel
또는 xgboost.Booster
에서 파생된 모델)를 사용하여 생성된 모델을 지원합니다. log_model
을 호출할 때 options
사전에서 다음 추가 옵션을 사용할 수 있습니다.
옵션 |
설명 |
---|---|
|
모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. |
|
GPU로 플랫폼에 배포할 때 사용할 CUDA 런타임 버전으로 기본값은 11.7입니다. 수동으로 |
레지스트리가 대상 메서드의 서명을 알도록 XGBoost 모델을 로깅할 때 sample_input_data
또는 signatures
매개 변수를 지정해야 합니다.
예¶
import xgboost
from sklearn import datasets, model_selection
cal_X, cal_y = datasets.load_breast_cancer(as_frame=True, return_X_y=True)
cal_X_train, cal_X_test, cal_y_train, cal_y_test = model_selection.train_test_split(cal_X, cal_y)
params = dict(n_estimators=100, reg_lambda=1, gamma=0, max_depth=3, objective="binary:logistic")
regressor = xgboost.train(params, xgboost.DMatrix(data=cal_X_train, label=cal_y_train))
model_ref = registry.log_model(
regressor,
model_name="xgBooster",
version_name="v1",
sample_input_data=cal_X_test,
options={
"target_methods": ["predict"],
"method_options": {
"predict": {"case_sensitive": True},
},
},
)
model_ref.run(cal_X_test[-10:])
PyTorch¶
모델의 forward
메서드가 하나 이상의 torch.Tensor
인스턴스를 입력으로 받고 torch.Tensor
또는 그 튜플을 반환하는 경우 레지스트리는 PyTorch 모델(torch.nn.Module
또는 torch.jit.ModuleScript
에서 파생된 클래스)을 지원합니다. 레지스트리는 모델을 호출하고 결과를 반환할 때 pandas DataFrames와 텐서 간에 변환합니다. 텐서는 데이터 프레임의 열에 해당합니다.
예를 들어 모델이 다음과 같이 두 개의 텐서를 허용한다고 가정해 보겠습니다.
import torch
class TorchModel(torch.nn.Module):
def __init__(self, n_input: int, n_hidden: int, n_out: int, dtype: torch.dtype = torch.float32) -> None:
super().__init__()
self.model = torch.nn.Sequential(
torch.nn.Linear(n_input, n_hidden, dtype=dtype),
torch.nn.ReLU(),
torch.nn.Linear(n_hidden, n_out, dtype=dtype),
torch.nn.Sigmoid(),
)
def forward(self, tensor_1: torch.Tensor, tensor_2: torch.Tensor) -> torch.Tensor:
return self.model(tensor_1) + self.model(tensor_2)
torch.Tensor([[1,2],[3,4]])
를 tensor_1
로, torch.Tensor([[5,6], [7,8]])
을 tensor_2
로 전달하려면 다음과 같이 DataFrame을 만들어 모델에 전달하십시오.
import pandas as pd
tensors = pd.DataFrame([[[1,2],[5,6]],[[3,4],[7,8]]])
그러면 tensors
DataFrame은 다음과 같습니다.
0 1
0 [1, 2] [5, 6]
1 [3, 4] [7, 8]
마찬가지로, 모델이 (torch.Tensor([[1,2],[3,4]]), torch.Tensor([[5,6], [7,8]]))
과 같은 두 개의 텐서를 반환하는 경우 결과는 위에 나온 것과 같은 DataFrame입니다.
PyTorch 모델에 대한 샘플 입력 데이터를 제공할 때 (pandas DataFrame으로 변환될) 텐서 목록 또는 DataFrame을 제공해야 합니다. 목록에는 단일 텐서가 포함될 수 있지만 텐서 단독으로는 허용되지 않습니다.
모델 로깅하기¶
log_model
을 호출할 때 options
사전에서 다음 추가 옵션을 사용할 수 있습니다.
옵션 |
설명 |
---|---|
|
모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. PyTorch 모델의 기본값은 |
|
GPU로 플랫폼에 배포할 때 사용할 CUDA 런타임 버전으로 기본값은 11.7입니다. 수동으로 |
레지스트리가 대상 메서드의 서명을 알도록 PyTorch 모델을 로깅할 때 sample_input_data
또는 signatures
매개 변수를 지정해야 합니다.
예¶
import torch
import numpy as np
class TorchModel(torch.nn.Module):
def __init__(self, n_input: int, n_hidden: int, n_out: int, dtype: torch.dtype = torch.float32) -> None:
super().__init__()
self.model = torch.nn.Sequential(
torch.nn.Linear(n_input, n_hidden, dtype=dtype),
torch.nn.ReLU(),
torch.nn.Linear(n_hidden, n_out, dtype=dtype),
torch.nn.Sigmoid(),
)
def forward(self, tensor: torch.Tensor) -> torch.Tensor:
return self.model(tensor)
n_input, n_hidden, n_out, batch_size, learning_rate = 10, 15, 1, 100, 0.01
dtype = torch.float32
x = np.random.rand(batch_size, n_input)
data_x = torch.from_numpy(x).to(dtype=dtype)
data_y = (torch.rand(size=(batch_size, 1)) < 0.5).to(dtype=dtype)
model = TorchModel(n_input, n_hidden, n_out, dtype=dtype)
loss_function = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
for _epoch in range(100):
pred_y = model.forward(data_x)
loss = loss_function(pred_y, data_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
model_ref = registry.log_model(
model,
model_name="torchModel",
version_name="v1",
sample_input_data=[data_x],
)
model_ref.run([data_x])
TensorFlow¶
tensorflow.Module
또는 tensorflow.keras.Model
을 확장하는 모델은 텐서를 허용 및 반환하고 컴파일 가능하거나 컴파일될 때 지원됩니다.
tensorflow.Module
의__call__
메서드 또는tensorflow.keras.Model
의call
메서드는 하나 이상의tensorflow.Tensor
또는tensorflow.Variable
을 입력으로 받고tensorflow.Tensor
또는tensorflow.Variable
또는 이러한 유형 중 하나의 튜플을 반환합니다.모델이
Module
을 확장하는 경우 컴파일 가능해야 하는데, 이는__call__
메서드가@tensorflow.function
으로 데코레이트된다는 뜻입니다. tf.function 설명서 를 참조하십시오.Model
을 확장하는 경우 컴파일해야 합니다. 컴파일 설명서 를 참조하십시오.
레지스트리는 모델을 호출하고 결과를 반환할 때 pandas DataFrames와 텐서 간에 변환합니다. 텐서는 데이터 프레임의 열에 해당합니다.
예를 들어 모델이 다음과 같이 두 개의 텐서를 허용한다고 가정해 보겠습니다.
import tensorflow as tf
class KerasModel(tf.keras.Model):
def __init__(self, n_hidden: int, n_out: int) -> None:
super().__init__()
self.fc_1 = tf.keras.layers.Dense(n_hidden, activation="relu")
self.fc_2 = tf.keras.layers.Dense(n_out, activation="sigmoid")
def call(self, tensor_1: tf.Tensor, tensor_2: tf.Tensor) -> tf.Tensor:
input = tensor_1 + tensor_2
x = self.fc_1(input)
x = self.fc_2(x)
return x
tf.Tensor([[1,2],[3,4]])
를 tensor_1
로, tf.Tensor([[5,6], [7,8]])
을 tensor_2
로 전달하려면 다음과 같이 DataFrame을 만들어 모델에 전달하십시오.
import pandas as pd
tensors = pd.DataFrame([[[1,2],[5,6]],[[3,4],[7,8]]])
그러면 tensors
DataFrame은 다음과 같습니다.
0 1
0 [1, 2] [5, 6]
1 [3, 4] [7, 8]
마찬가지로, 모델이 (tf.Tensor([[1,2],[3,4]]), tf.Tensor([[5,6], [7,8]]))
과 같은 두 개의 텐서를 반환하는 경우 결과는 위에 나온 것과 같은 DataFrame입니다.
TensorFlow 모델에 대한 샘플 입력 데이터를 제공할 때 (pandas DataFrame으로 변환될) 텐서 목록 또는 DataFrame을 제공해야 합니다. 목록에는 단일 텐서가 포함될 수 있지만 텐서 단독으로는 허용되지 않습니다.
모델 로깅하기¶
log_model
을 호출할 때 options
사전에서 다음 추가 옵션을 사용할 수 있습니다.
옵션 |
설명 |
---|---|
|
모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. TensorFlow 모델의 기본값은 |
|
GPU로 플랫폼에 배포할 때 사용할 CUDA 런타임 버전으로 기본값은 11.7입니다. 수동으로 |
레지스트리가 대상 메서드의 서명을 알도록 TensorFlow 모델을 로깅할 때 sample_input_data
또는 signatures
매개 변수를 지정해야 합니다.
예¶
import tensorflow as tf
import numpy as np
class KerasModel(tf.keras.Model):
def __init__(self, n_hidden: int, n_out: int) -> None:
super().__init__()
self.fc_1 = tf.keras.layers.Dense(n_hidden, activation="relu")
self.fc_2 = tf.keras.layers.Dense(n_out, activation="sigmoid")
def call(self, tensor: tf.Tensor) -> tf.Tensor:
input = tensor
x = self.fc_1(input)
x = self.fc_2(x)
return x
n_input, n_hidden, n_out, batch_size, learning_rate = 10, 15, 1, 100, 0.01
dtype = tf.float32
x = np.random.rand(batch_size, n_input)
data_x = tf.convert_to_tensor(x, dtype=dtype)
raw_data_y = tf.random.uniform((batch_size, 1))
raw_data_y = tf.where(raw_data_y > 0.5, tf.ones_like(raw_data_y), tf.zeros_like(raw_data_y))
data_y = tf.cast(raw_data_y, dtype=dtype)
model = KerasModel(n_hidden, n_out)
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate), loss=tf.keras.losses.MeanSquaredError())
model.fit(data_x, data_y, batch_size=batch_size, epochs=100)
model_ref = registry.log_model(
model,
model_name="tfModel",
version_name="v1",
sample_input_data=[data_x],
)
model_ref.run([data_x])
MLFlow¶
PyFunc 버전을 제공하는 MLFlow 모델이 지원됩니다. MLFlow 모델에 서명이 있는 경우 signature
인자는 모델에서 추론됩니다. 그렇지 않으면 signature
또는 sample_input_data
를 제공해야 합니다.
log_model
을 호출할 때 options
사전에서 다음 추가 옵션을 사용할 수 있습니다.
옵션 |
설명 |
---|---|
|
MLFlow 모델 아티팩트의 URI입니다. 모델의 메타데이터에서 |
|
|
|
|
예¶
import mlflow
from sklearn import datasets, model_selection, ensemble
db = datasets.load_diabetes(as_frame=True)
X_train, X_test, y_train, y_test = model_selection.train_test_split(db.data, db.target)
with mlflow.start_run() as run:
rf = ensemble.RandomForestRegressor(n_estimators=100, max_depth=6, max_features=3)
rf.fit(X_train, y_train)
# Use the model to make predictions on the test dataset.
predictions = rf.predict(X_test)
signature = mlflow.models.signature.infer_signature(X_test, predictions)
mlflow.sklearn.log_model(
rf,
"model",
signature=signature,
)
run_id = run.info.run_id
model_ref = registry.log_model(
mlflow.pyfunc.load_model(f"runs:/{run_id}/model"),
model_name="mlflowModel",
version_name="v1",
conda_dependencies=["mlflow<=2.4.0", "scikit-learn", "scipy"],
options={"ignore_mlflow_dependencies": True}
)
model_ref.run(X_test)
Hugging Face 파이프라인¶
레지스트리는 transformers.Pipeline
에서 파생되는 변환기 로 정의된 Hugging Face 모델 클래스를 지원합니다. 다음 코드는 호환 가능한 모델을 로깅하는 예입니다.
lm_hf_model = transformers.pipeline(
task="text-generation",
model="bigscience/bloom-560m",
token="...", # Put your HuggingFace token here.
return_full_text=False,
max_new_tokens=100,
)
lmv = reg.log_model(lm_hf_model, model_name='bloom', version_name='v560m')
중요
huggingface_pipeline.HuggingFacePipelineModel
기반 모델에는 구성 데이터만 포함되는데, 모델을 사용할 때마다 Hugging Face Hub에서 모델 가중치가 다운로드됩니다.
모델 레지스트리는 현재 웨어하우스에만 모델을 배포하도록 지원합니다. 웨어하우스는 특별 구성 없이는 외부 네트워크 액세스를 지원하지 않습니다. 필요한 외부 액세스 통합이 생성되었더라도 현재로서는 특정 모델에 필요한 통합을 지정할 방법이 없습니다.
현재 가장 좋은 방법은 위의 예에 나타낸 것처럼 transformers.Pipeline
을 대신 사용하는 것입니다. 그러면 모델 가중치가 로컬 시스템에 다운로드되고 전체 모델이 웨어하우스에 업로드됩니다. 그 결과 인터넷 액세스가 필요하지 않은 자급식 모델이 탄생합니다.
파이프라인에 다음 목록의 작업만 포함되어 있는 한 레지스트리는 signatures
인자를 추론합니다.
conversational
fill-mask
question-answering
summarization
table-question-answering
text2text-generation
text-classification
(별칭은sentiment-analysis
)text-generation
token-classification
(별칭은ner
)translation
translation_xx_to_yy
zero-shot-classification
추론된 서명을 보려면 show_functions
메서드를 사용하십시오. 예를 들어 다음은 lmv.show_functions()
의 결과이며, 여기서 lmv
는 위에 로깅된 모델입니다.
{'name': '__CALL__',
'target_method': '__call__',
'signature': ModelSignature(
inputs=[
FeatureSpec(dtype=DataType.STRING, name='inputs')
],
outputs=[
FeatureSpec(dtype=DataType.STRING, name='outputs')
]
)}]
이 정보를 사용하여 다음과 같이 모델을 호출할 수 있습니다.
import pandas as pd
remote_prediction = lmv.run(pd.DataFrame(["Hello, how are you?"], columns=["inputs"]))
사용법 노트¶
많은 Hugging Face 모델은 크기가 커서 표준 웨어하우스에 맞지 않습니다. Snowpark에 최적화된 웨어하우스를 사용하거나 더 작은 버전의 모델을 선택하십시오. 예를 들어
Llama-2-70b-chat-hf
모델을 사용하는 대신Llama-2-7b-chat-hf
를 사용해 보십시오.Snowflake 웨어하우스에는 GPU가 없습니다. CPU에 최적화된 Hugging Face 모델만 사용하십시오.
일부 Hugging Face 변환기는 입력 행마다 사전 배열을 반환합니다. 이 레지스트리는 이러한 출력을 배열의 JSON 표현을 포함하는 문자열로 변환합니다. 예를 들어 다중 출력 질문-응답 출력은 다음과 같습니다.
[{"score": 0.61094731092453, "start": 139, "end": 178, "answer": "learn more about the world of athletics"}, {"score": 0.17750297486782074, "start": 139, "end": 180, "answer": "learn more about the world of athletics.\""}]
레지스트리가 대상 메서드의 서명을 알도록 Hugging Face 모델을 로깅할 때 sample_input_data
또는 signatures
매개 변수를 지정해야 합니다.
예¶
# Prepare model
import transformers
import pandas as pd
finbert_model = transformers.pipeline(
task="text-classification",
model="ProsusAI/finbert",
top_k=2,
)
# Log the model
mv = registry.log_model(
finbert_model,
model_name="finbert",
version_name="v1",
)
# Use the model
mv.run(pd.DataFrame(
[
["I have a problem with my Snowflake that needs to be resolved asap!!", ""],
["I would like to have udon for today's dinner.", ""],
]
)
)
결과:
0 [{"label": "negative", "score": 0.8106237053871155}, {"label": "neutral", "score": 0.16587384045124054}]
1 [{"label": "neutral", "score": 0.9263970851898193}, {"label": "positive", "score": 0.05286872014403343}]