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 모델 레지스트리는 다음 유형의 모델을 지원합니다.

  • Snowpark ML Modeling

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

참고

이 공개 미리 보기 중에는 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)
Copy

log_model 의 인자는 여기에 설명되어 있습니다.

필수 인자

인자

설명

model

지원되는 모델 유형의 Python 모델 오브젝트입니다. 직렬화 가능(“피클 가능”)해야 합니다.

model_name

레지스트리에서 모델을 식별하기 위해 version_name 과 함께 사용되는 모델 이름입니다. 모델이 로깅된 후에는 이름을 변경할 수 없습니다.

version_name

모델 버전을 지정하는 문자열로, 레지스트리에서 모델을 식별하기 위해 model_name 과 함께 사용됩니다.

참고

모델 이름과 버전의 조합은 스키마에서 고유해야 합니다.

선택적 인자

인자

설명

code_paths

모델을 로드하거나 배포할 때 가져올 코드의 디렉터리 경로 목록입니다.

comment

주석(예: 모델에 대한 설명)입니다.

conda_dependencies

모델에 필요한 Conda 패키지 목록입니다. 이 인자는 Conda 형식, 즉 "[channel::]package [operator version]" 으로 패키지 이름과 선택적 버전을 지정합니다. 채널을 지정하지 않으면 Snowflake 채널인 것으로 가정합니다.

ext_modules

모델과 함께 피클링할 외부 모듈의 목록입니다. scikit-learn, Snowpark ML, PyTorch, TorchScript, 사용자 지정 모델에서 지원됩니다.

metrics

모델 버전에 연결된 메트릭이 포함된 사전입니다.

options

모델 생성 옵션이 포함된 사전입니다. 모든 모델 유형에 대해 다음 옵션을 사용할 수 있습니다.

  • embed_local_ml_library: 로컬 Snowpark ML 라이브러리의 복사본을 모델에 포함할지 여부입니다. 기본값: False.

  • relax_version: 종속성의 버전 제약 조건을 완화할지 여부입니다. 이는 ==x.y.z 와 같은 버전 지정자를 <=x.y, <(x+1) 과 같은 지정자로 바꿉니다. 기본값: False. Snowpark ML 패키지 버전 1.2.1부터 사용 가능합니다.

  • method_options: 메서드별 옵션 사전으로, 여기서 키는 메서드의 이름이고 값은 여기에 설명된 옵션 중 하나 이상이 포함된 사전입니다. 사용 가능한 옵션은 다음과 같습니다.

    • case_sensitive: 메서드와 해당 서명이 대/소문자를 구분하는지 여부를 나타냅니다. 대/소문자를 구분하는 메서드는 SQL에서 사용 시 큰따옴표로 묶어야 합니다. 이 옵션은 메서드 이름에 알파벳이 아닌 문자도 허용합니다. 기본값: False.

    • max_batch_size: 웨어하우스에서 호출 시 메서드가 허용하는 최대 배치 크기입니다. 기본값: None (배치 크기가 자동으로 결정됨)

개별 모델 유형은 추가 옵션을 지원할 수 있습니다. 특정 모델 유형에 대한 참고 사항 섹션을 참조하십시오.

pip_requirements

모델에 필요한 PyPI 패키지의 패키지 사양 목록입니다.

python_version

모델이 실행될 Python 버전입니다. 기본값은 웨어하우스에서 사용 가능한 최신 버전을 지정하는 None 입니다.

sample_input_data

샘플 입력 데이터가 포함된 DataFrame입니다. 모델에 필요한 특성 이름과 해당 유형이 이 DataFrame에서 추출됩니다. Snowpark ML 및 MLFlow 모델을 제외한 모든 모델에 이 인자 또는 signatures 를 제공해야 합니다.

signatures

대상 메서드 이름에서 입력 및 출력 서명으로의 매핑으로 사용되는 모델 메서드 서명입니다. Snowpark ML 및 MLFlow 모델을 제외한 모든 모델에 이 인자 또는 sample_input_data 를 제공해야 합니다.

log_model 은 레지스트리에 추가된 모델의 버전을 나타내는 snowflake.ml.model.ModelVersion 오브젝트를 반환합니다.

일단 등록되면 모델 자체를 수정할 수 없습니다(단, 해당 메타데이터는 변경할 수 있음). 모델과 해당 버전을 모두 삭제하려면 레지스트리의 delete_model 메서드를 사용하십시오.

모델 삭제하기

모델과 해당 버전을 모두 삭제하려면 레지스트리의 delete_model 메서드를 사용하십시오.

reg.delete_model("mymodel")
Copy

레지스트리에서 모델 가져오기

각 모델에 대한 정보를 얻으려면 show_models 메서드를 사용하십시오.

model_df = reg.show_models()
Copy

show_models 의 결과는 pandas DataFrame입니다. 사용 가능한 열은 아래와 같습니다.

설명

created_on

모델이 생성된 날짜 및 시간입니다.

이름

모델의 이름입니다.

데이터베이스_이름

모델이 저장되는 데이터베이스입니다.

스키마_이름

모델이 저장되는 스키마입니다.

owner

모델을 소유한 역할입니다.

comment

모델에 대한 설명입니다.

versions

모델의 JSON 배열 목록 버전입니다.

default_version_name

버전이 없는 모델을 참조할 때 사용되는 모델의 버전입니다.

대신 레지스트리에서 모델 목록을 각각 Model 인스턴스로 가져오려면 models 메서드를 사용하십시오.

model_list = reg.models()
Copy

이름으로 레지스트리에서 특정 모델에 대한 참조를 가져오려면 레지스트리의 get_model 메서드를 사용하십시오. 이 메서드는 Model 인스턴스를 반환합니다.

m = reg.get_model("MyModel")
Copy

참고

Model 인스턴스는 로깅된 Python 모델 오브젝트 원본의 복사본이 아니라 레지스트리의 기본 모델 오브젝트에 대한 참조입니다.

모델에 대한 참조(models 메서드에서 반환된 목록의 참조 또는 get_model 을 사용하여 검색된 참조)가 있으면 해당 메타데이터해당 버전 으로 작업할 수 있습니다.

모델의 메타데이터 보기 및 업데이트하기

주석, 태그, 지표를 포함하여 레지스트리에서 모델의 메타데이터 속성을 보고 업데이트할 수 있습니다.

주석 검색 및 업데이트하기

모델의 주석을 검색하고 업데이트하려면 모델의 comment 속성을 사용하십시오.

print(m.comment)
m.comment = "A better description than the one I provided originally"
Copy

참고

description 속성은 comment 의 별칭입니다. 위의 코드는 다음과 같이 작성할 수도 있습니다.

print(m.description)
m.description = "A better description than the one I provided originally"
Copy

태그 검색 및 업데이트하기

태그는 모델의 목적, 알고리즘, 학습 데이터 세트, 수명 주기 스테이지 또는 선택하는 기타 정보를 기록하는 데 사용되는 메타데이터입니다. 모델이 등록될 때나 그 이후 언제든지 태그를 설정할 수 있습니다. 기존 태그의 값을 업데이트하거나 태그를 완전히 제거할 수도 있습니다.

참고

모든 태그의 이름과 잠재적으로 가능한 태그의 값은 CREATE TAG를 사용하여 미리 정의해야 합니다. 오브젝트 태그 지정 섹션을 참조하십시오.

모델의 모든 태그를 Python 사전으로 가져오려면 show_tags 를 사용하십시오.

print(m.show_tags())
Copy

새 태그를 추가하거나 기존 태그의 값을 변경하려면 set_tag 를 사용하십시오.

m.set_tag("live_version", "1")
Copy

태그 값을 검색하려면 get_tag 를 사용하십시오.

m.get_tag("live_version")
Copy

태그를 제거하려면 unset_tag 를 사용하십시오.

model.unset_tag("live_version")
Copy

모델 버전 관련 작업하기

모델에는 버전이 여러 개 있을 수 있으며 각 버전은 문자열로 식별됩니다. 원하는 버전 명명 규칙을 사용할 수 있습니다. 모델을 로깅하면 실제로 모델의 특정 버전 이 기록됩니다. 모델의 추가 버전을 로깅하려면 동일한 model_name 및 다른 version_name 을 사용하여 log_model 을 다시 호출하십시오.

모델 버전은 snowflake.ml.model.ModelVersion 클래스의 인스턴스로 표시됩니다.

모델의 모든 버전 목록을 가져오려면 모델 오브젝트의 versions 메서드를 호출하십시오. 결과는 ModelVersion 인스턴스의 목록입니다.

version_list = m.versions()
Copy

대신 각 모델에 대한 정보를 DataFrame으로 가져오려면 모델의 show_versions 메서드를 호출하십시오.

version_df = m.show_versions()
Copy

결과 DataFrame에는 다음 열이 포함됩니다.

설명

created_on

모델 버전이 생성된 날짜 및 시간입니다.

이름

버전의 이름입니다.

데이터베이스_이름

버전이 저장되는 데이터베이스입니다.

스키마_이름

버전이 저장되는 스키마입니다.

model_name

이 버전이 속한 모델의 이름입니다.

is_default_version

이 버전이 모델의 기본 버전인지 여부를 나타내는 부울 값입니다.

functions

이 버전에서 사용할 수 있는 함수 이름의 JSON 배열입니다.

metadata

메타데이터를 키-값 페어로 포함하는 JSON 오브젝트입니다(메타데이터가 지정되지 않은 경우에는 {}).

user_data

모델 정의 매니페스트의 user_data 섹션에 있는 JSON 오브젝트입니다(사용자 데이터가 지정되지 않은 경우에는 {}).

모델 버전 삭제하기

모델의 delete_version 메서드를 사용하여 모델 버전을 삭제할 수 있습니다.

m.delete_version("rc1")
Copy

기본 버전

모델의 버전이 기본 모델로 지정될 수 있습니다. 현재 기본 버전을 (ModelVersion 오브젝트로) 가져오거나 (문자열을 사용하여) 변경하려면 모델의 default 속성을 검색하거나 설정하십시오.

default_version = m.default
m.default = "2"
Copy

모델 버전에 대한 참조 가져오기

특정 버전의 모델에 대한 참조를 ModelVersion 인스턴스로 가져오려면 모델의 version 메서드를 사용하십시오. 모델의 기본 버전을 가져오려면 모델의 default 속성을 사용하십시오.

mv = m.version("1")
mv = m.default
Copy

모델의 특정 버전에 대한 참조(예: 바로 위 예의 변수 mv)가 있으면 다음 섹션에 표시된 대로 참조의 주석이나 메트릭을 검색하거나 업데이트하고 모델의 메서드(함수)를 호출할 수 있습니다.

주석 검색 및 업데이트하기

모델과 마찬가지로 모델 버전에도 주석이 있을 수 있으며, 주석은 모델 버전의 comment 또는 description 속성을 통해 액세스하고 설정할 수 있습니다.

print(mv.comment)
print(mv.description)

mv.comment = "A model version comment"
mv.description = "Same as setting the comment"
Copy

메트릭 검색 및 업데이트하기

메트릭은 예측 정확도 및 기타 모델 버전 특성을 추적하는 데 사용되는 키-값 페어입니다. 모델 버전을 생성할 때 메트릭을 설정하거나 set_metric 메서드를 사용하여 설정할 수 있습니다. 메트릭 값은 숫자, 문자열, 목록, 사전을 포함하여 JSON으로 직렬화할 수 있는 모든 Python 오브젝트일 수 있습니다. 태그와 달리, 메트릭 이름과 가능한 값을 미리 정의할 필요가 없습니다.

테스트 정확도 메트릭은 sklearn의 accuracy_score 를 사용하여 생성될 수 있습니다.

from sklearn import metrics

test_accuracy = metrics.accuracy_score(test_labels, prediction)
Copy

혼동 행렬은 sklearn을 사용하여 유사하게 생성할 수 있습니다.

test_confusion_matrix = metrics.confusion_matrix(test_labels, prediction)
Copy

그런 다음 이러한 값을 다음과 같이 메트릭으로 설정할 수 있습니다.

# 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)
Copy

모델 버전의 메트릭을 Python 사전으로 검색하려면 show_metrics 를 사용하십시오.

metrics = mv.show_metrics()
Copy

메트릭을 삭제하려면 delete_metric 을 호출하십시오.

mv.delete_metric("test_accuracy")
Copy

모델 메서드 호출하기

모델 버전에는 추론이나 기타 모델 작업을 수행하기 위해 실행할 수 있는 연결된 함수인 메서드 가 있을 수 있습니다. 모델 버전에는 다양한 메서드가 있을 수 있으며 이러한 메서드의 서명도 다를 수 있습니다.

모델 버전의 메서드를 호출하려면 mv.run 을 사용하여 호출할 함수의 이름을 지정하고 추론 데이터와 기타 모든 필수 매개 변수가 포함된 DataFrame을 전달하십시오. 이 메서드는 Snowflake 웨어하우스에서 실행됩니다.

참고

메서드를 호출하면 레지스트리에 연결하는 데 사용하는 세션에 지정된 웨어하우스에서 해당 메서드가 실행됩니다. 웨어하우스 지정하기 섹션을 참조하십시오.

다음 예에서는 모델의 predict 메서드를 실행하는 방법을 보여줍니다. 이 모델의 predict 메서드에는 추론 데이터(여기서는 test_features) 외에 어떤 매개 변수도 필요하지 않습니다. 필요한 경우에는 추론 데이터 뒤에 추가 인자로 전달됩니다.

remote_prediction = mv.run(test_features, function_name="predict")
Copy

특정 모델에서 호출할 수 있는 메서드를 확인하려면 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>;
Copy

특정 모델 버전의 메서드를 호출하려면 먼저 특정 버전의 모델에 대한 별칭을 만든 다음 별칭을 통해 원하는 메서드를 호출하십시오.

WITH <model_version_alias> AS MODEL <model_name> VERSION <version>
    SELECT <model_version_alias>!<method_name>(...) FROM <table_name>;
Copy

비용 고려 사항

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 사전에서 다음 추가 옵션을 사용할 수 있습니다.

옵션

설명

target_methods

모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. Snowpark ML 모델에는 대상 메서드가 존재한다고 가정하면 기본적으로 predict, transform, predict_proba, predict_log_proba, decision_function 대상 메서드가 있습니다.

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')
Copy

scikit-learn

레지스트리는 scikit-learn을 사용하여 생성된 모델(sklearn.base.BaseEstimator 또는 sklearn.pipeline.Pipeline 에서 파생된 모델)을 지원합니다. log_model 을 호출할 때 options 사전에서 다음 추가 옵션을 사용할 수 있습니다.

옵션

설명

target_methods

모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. scikit-learn 모델에는 대상 메서드가 존재한다고 가정하면 기본적으로 predict, transform, predict_proba, predict_log_proba, decision_function 대상 메서드가 있습니다.

레지스트리가 대상 메서드의 서명을 알도록 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"')
Copy

XGBoost

레지스트리는 XGBoost(xgboost.XGBModel 또는 xgboost.Booster 에서 파생된 모델)를 사용하여 생성된 모델을 지원합니다. log_model 을 호출할 때 options 사전에서 다음 추가 옵션을 사용할 수 있습니다.

옵션

설명

target_methods

모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. XGBModel 에서 파생된 모델에는 대상 메서드가 존재한다고 가정하면 기본적으로 predict, predict_proba, apply 대상 메서드가 있습니다. Booster 에서 파생된 모델에는 기본적으로 predict 메서드가 있습니다.

cuda_version

GPU로 플랫폼에 배포할 때 사용할 CUDA 런타임 버전으로 기본값은 11.7입니다. 수동으로 None 으로 설정하면 GPU가 있는 플랫폼에 모델을 배포할 수 없습니다.

레지스트리가 대상 메서드의 서명을 알도록 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:])
Copy

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

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]]])
Copy

그러면 tensors DataFrame은 다음과 같습니다.

        0       1
0  [1, 2]  [5, 6]
1  [3, 4]  [7, 8]
Copy

마찬가지로, 모델이 (torch.Tensor([[1,2],[3,4]]), torch.Tensor([[5,6], [7,8]])) 과 같은 두 개의 텐서를 반환하는 경우 결과는 위에 나온 것과 같은 DataFrame입니다.

PyTorch 모델에 대한 샘플 입력 데이터를 제공할 때 (pandas DataFrame으로 변환될) 텐서 목록 또는 DataFrame을 제공해야 합니다. 목록에는 단일 텐서가 포함될 수 있지만 텐서 단독으로는 허용되지 않습니다.

모델 로깅하기

log_model 을 호출할 때 options 사전에서 다음 추가 옵션을 사용할 수 있습니다.

옵션

설명

target_methods

모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. PyTorch 모델의 기본값은 forward 입니다.

cuda_version

GPU로 플랫폼에 배포할 때 사용할 CUDA 런타임 버전으로 기본값은 11.7입니다. 수동으로 None 으로 설정하면 GPU가 있는 플랫폼에 모델을 배포할 수 없습니다.

레지스트리가 대상 메서드의 서명을 알도록 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])
Copy

TensorFlow

tensorflow.Module 또는 tensorflow.keras.Model 을 확장하는 모델은 텐서를 허용 및 반환하고 컴파일 가능하거나 컴파일될 때 지원됩니다.

  • tensorflow.Module__call__ 메서드 또는 tensorflow.keras.Modelcall 메서드는 하나 이상의 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
Copy

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]]])
Copy

그러면 tensors DataFrame은 다음과 같습니다.

        0       1
0  [1, 2]  [5, 6]
1  [3, 4]  [7, 8]
Copy

마찬가지로, 모델이 (tf.Tensor([[1,2],[3,4]]), tf.Tensor([[5,6], [7,8]])) 과 같은 두 개의 텐서를 반환하는 경우 결과는 위에 나온 것과 같은 DataFrame입니다.

TensorFlow 모델에 대한 샘플 입력 데이터를 제공할 때 (pandas DataFrame으로 변환될) 텐서 목록 또는 DataFrame을 제공해야 합니다. 목록에는 단일 텐서가 포함될 수 있지만 텐서 단독으로는 허용되지 않습니다.

모델 로깅하기

log_model 을 호출할 때 options 사전에서 다음 추가 옵션을 사용할 수 있습니다.

옵션

설명

target_methods

모델 오브젝트에서 사용할 수 있는 메서드 이름 목록입니다. TensorFlow 모델의 기본값은 forward 입니다.

cuda_version

GPU로 플랫폼에 배포할 때 사용할 CUDA 런타임 버전으로 기본값은 11.7입니다. 수동으로 None 으로 설정하면 GPU가 있는 플랫폼에 모델을 배포할 수 없습니다.

레지스트리가 대상 메서드의 서명을 알도록 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])
Copy

MLFlow

PyFunc 버전을 제공하는 MLFlow 모델이 지원됩니다. MLFlow 모델에 서명이 있는 경우 signature 인자는 모델에서 추론됩니다. 그렇지 않으면 signature 또는 sample_input_data 를 제공해야 합니다.

log_model 을 호출할 때 options 사전에서 다음 추가 옵션을 사용할 수 있습니다.

옵션

설명

model_uri

MLFlow 모델 아티팩트의 URI입니다. 모델의 메타데이터에서 model.metadata.get_model_info().model_uri 로 사용할 수 없는 경우 제공되어야 합니다.

ignore_mlflow_metadata

True 인 경우 모델의 메타데이터를 레지스트리의 모델 오브젝트로 가져오지 않습니다. 기본값: False

ignore_mlflow_dependencies

True 인 경우 모델 메타데이터의 종속성이 무시되는데, 이는 Snowflake 웨어하우스에서 패키지 가용성 제한으로 인해 유용합니다. 기본값: False

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

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')
Copy

중요

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

이 정보를 사용하여 다음과 같이 모델을 호출할 수 있습니다.

import pandas as pd
remote_prediction = lmv.run(pd.DataFrame(["Hello, how are you?"], columns=["inputs"]))
Copy

사용법 노트

  • 많은 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.\""}]
    
    Copy

레지스트리가 대상 메서드의 서명을 알도록 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.", ""],
        ]
    )
)
Copy

결과:

0  [{"label": "negative", "score": 0.8106237053871155}, {"label": "neutral", "score": 0.16587384045124054}]
1  [{"label": "neutral", "score": 0.9263970851898193}, {"label": "positive", "score": 0.05286872014403343}]
Copy