Data Clean Rooms의 ML Jobs
Data Clean Rooms의 ML Jobs
ML Jobs는 콜라보레이터가 Collaboration Data Clean Rooms 안에서 복잡하고 리소스 집약적인 머신러닝 워크플로를 실행할 수 있게 해줘요.
본문
기능 — 일반 공개(Generally Available)
현재 지원 리전: 이 리전들에서 사용할 수 있어요.
정부 및 VPS 배포에서는 사용할 수 없어요.
개요
ML Jobs는 콜라보레이터가 Collaboration Data Clean Rooms 안에서 복잡하고 리소스 집약적인 머신러닝 워크플로를 실행할 수 있게 해줘요. 표준 웨어하우스에서 Python 코드를 UDF나 저장 프로시저로 실행하는 대신, ML Jobs는 격리된 컨테이너 환경에서 전체 ML 워크로드를 실행해요. 이를 통해 광고, 리테일 미디어, 측정 분야의 콜라보레이터들이 어떤 당사자에게도 원시 사용자 수준 데이터를 노출하지 않고 결합된 데이터로 모델을 학습시킬 수 있어요.
ML Jobs는 기존 콜라보레이션 스펙과 템플릿 제출 워크플로를 확장해요. 템플릿 제공자는 아티팩트를 스테이징하고 ML Jobs 코드 스펙을 등록한 다음 승인을 위해 템플릿을 제출해요. 분석 실행자는 템플릿을 검토·승인한 뒤 자신의 컴퓨트 풀에서 ML Jobs를 실행해요.
이점
- 단순화된 개발: Python 스크립트를 스테이징하고 pip 의존성을 지정해요. Docker 이미지를 빌드하거나 관리할 필요가 없어요.
- 분산 학습: GPU 지원으로 여러 노드에서 워크로드를 실행해 학습과 추론을 가속화해요. XGBoost, LightGBM, PyTorch용 Snowflake 분산 트레이너는 컴퓨트 풀 노드에 걸쳐 자동으로 확장돼요.
- 하이퍼파라미터 최적화: 내장 HPO API(
snowflake.ml.modeling.tune)로 베이지안 최적화, 랜덤 서치, 그리드 서치를 사용해요. 추가 의존성 없이 병렬 트라이얼을 실행해요. - 다중 파일 프로젝트: 여러 모듈, 라이브러리, 모델 아티팩트가 있는 전체 프로젝트 디렉토리를 스테이징해요.
- 유연한 컴퓨트: 워크로드에 맞게 컴퓨트 풀 크기와 인스턴스 패밀리를 선택해요.
- 작업 모니터링: 컨테이너 로그, 상태 확인, 결과 검색으로 진행 상황을 추적해요.
ML Jobs 기능에 대한 더 자세한 내용은 Snowflake ML Jobs를 참고하세요.
사용 사례
ML Jobs는 광고, 리테일 미디어, 금융 서비스 및 기타 업종에 걸친 다양한 사용 사례를 지원해요:
- 룩얼라이크 모델링: 시드 오디언스로 분류기를 학습시키고 노출 및 캠페인 데이터 전반의 사용자를 점수화해요. CTV, 리테일 미디어 네트워크(RMN), 디지털 광고에 적용할 수 있어요.
- 측정 및 증분(Incrementality): 콜라보레이터 간 광고 노출을 구매 또는 전환 데이터와 조인해 매출 상승(sales lift) 연구와 증분 모델을 실행해요. 분산 HPO를 사용해 캠페인별 상승 모델 하이퍼파라미터를 자동으로 최적화해요.
- 어트리뷰션 모델링: 원시 사용자 수준 데이터를 노출하지 않고 여러 데이터 소스의 캠페인 로그, 노출, 전환 이벤트에서 멀티 터치 어트리뷰션 모델을 구축해요.
- 성향 스코어링: 여러 당사자의 광고 노출, 참여, 거래 피처를 사용해 구매 성향, 이탈 위험, 평생 가치(LTV)로 사용자 모집단을 점수화해요.
- 오디언스 세분화: 게시자, 광고주, 데이터 제공자의 결합된 노출 로그, CRM 데이터, 행동 신호에 ML 기법을 사용해 사용자를 클러스터링하고 세분화해요.
- 분산 모델 학습: 컴퓨트 풀의 여러 노드와 GPU에 걸쳐 자동으로 확장되는 Snowflake 분산 트레이너(XGBoost, LightGBM, PyTorch)로 대형 모델을 학습시켜요.
- 커스텀 ML 워크플로: 독점 모델, 사전 학습된 모델 추론, 캠페인·사용자 데이터의 피처 엔지니어링을 포함해 안전한 클린룸 환경 안에서 모든 컨테이너화된 Python ML 워크로드를 실행해요.
요구 사항
- 콜라보레이션의 두 계정 모두 최신 버전의 Snowflake Data Clean Rooms 환경이 설치되어 있어야 해요.
- 분석 실행자는 ML Jobs를 실행할 수 있는 컴퓨트 풀이 있어야 해요. GPU 가속 워크로드에는 GPU 컴퓨트 풀이 필요해요. GPU 가용성은 리전별로 달라져요. 문제 해결 안내의 컴퓨트 풀 오류를 참고하세요.
ML Jobs 코드 스펙
ML Jobs 코드 스펙은 컴퓨트 풀에서 실행되는 하나 이상의 컨테이너화된 ML 워크로드를 정의해요. stage_code_dir 요구 사항과 image_tag 옵션을 포함한 전체 필드 참조는 ML Jobs 코드 스펙을 참고하세요.
사용자 흐름: 템플릿 제공자
템플릿 제공자는 콜라보레이션에서 실행할 ML Job 스펙과 템플릿을 정의하고 제출해요.
1. 아티팩트 스테이징
코드, 모델 파일, 비공개 라이브러리를 내부 스테이지에 스테이징해요. 스테이지는 디렉토리가 활성화되어 있어야 하고 Snowflake 관리 암호화를 사용해야 해요:
CREATE STAGE IF NOT EXISTS my_db.public.ml_stage
DIRECTORY = (ENABLE = TRUE)
ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE');
SnowSQL 또는 Snowflake CLI를 사용해 Python 스크립트를 업로드해요:
PUT file://train.py @my_db.public.ml_stage/ml_project/ AUTO_COMPRESS=FALSE OVERWRITE=TRUE;
PUT file://score.py @my_db.public.ml_stage/ml_project/ AUTO_COMPRESS=FALSE OVERWRITE=TRUE;
업로드 후 콜라보레이션이 파일에 접근할 수 있도록 스테이지 디렉토리를 새로 고쳐요:
ALTER STAGE my_db.public.ml_stage REFRESH;
2. ML Jobs 코드 스펙 등록
스테이징된 아티팩트를 참조하는 ML Jobs 코드 스펙을 등록해요. 코드 스펙에는 최소 하나의 ML job 정의가 있는 ml_jobs 섹션이 포함되어야 해요:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_CODE_SPEC(
$$
api_version: 2.0.0
spec_type: code_spec
name: my_ml_model
version: V0
ml_jobs:
- name: my_train_job
entrypoint: train.py
stage_code_dir: '@my_db.public.ml_stage/ml_project'
image_tag: "2.9.0"
pip_requirements:
- pandas
- xgboost
- scikit-learn
$$);
팁
image_tag필드는 선택 사항이에요. 생략하면 콜라보레이션은 최신 사용 가능한 런타임 이미지를 사용해요. 이미지는 코드 스펙이 콜라보레이션에 추가될 때와 이후 각 패치 때 다시 평가돼요. 코드 스펙이 안정적이고 알려진 라이브러리 집합으로 실행되도록 하려면image_tag를 특정 버전으로 고정(pin)하세요. 사용 가능한 버전 목록은 Container Runtime 릴리스를, 전체 필드 참조는 ML Jobs 코드 스펙을 참고하세요.
전체 필드 참조는 ML Jobs 코드 스펙을 참고하세요.
3. 템플릿 등록
파이프라인의 각 단계에 대해 템플릿을 등록해요. 각 템플릿은 코드 스펙에서 생성된 ML job 프로시저를 호출해요:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
$$
api_version: 2.0.0
spec_type: template
name: my_train_template
version: V0
type: sql_analysis
parameters:
- name: compute_pool
description: Name of the compute pool to run the ML job on.
type: string
required: true
code_specs:
- <code_spec_id>
template: |
call cleanroom.my_ml_model$my_train_job(
{{ compute_pool }}, {{ num_instances | default(1) }}, {{ warehouse | default(\"APP_WH\") }},
OBJECT_CONSTRUCT('source_table', ARRAY_CONSTRUCT({{ source_table[0] }}, {{ source_table[1] }}))::VARCHAR
)
$$);
4. 승인을 위해 템플릿 제출
표준 템플릿 승인 흐름을 사용해 템플릿을 콜라보레이션에 제출해 승인받아요. 콜라보레이터는 해시를 사용해 코드와 아티팩트를 검증해 규정 준수를 확인해요.
5. 필요에 따라 코드 업데이트
코드가 발전함에 따라 ML Jobs 코드 스펙을 업데이트하고 재승인을 위해 다시 제출해요. 코드 스펙을 업데이트하려면 version 필드를 변경하고 업데이트된 YAML로 REGISTER_CODE_SPEC을 다시 호출해요. 재등록하면 콘텐츠 해시가 자동으로 재계산돼요.
참고
2026년 6월 18일 릴리스(Clean Rooms API 버전 16.3) 이전에 등록된 ML Jobs 코드 스펙은 콘텐츠 해시가 없어 콜라보레이션에 추가할 수 없어요. 해결 단계는 ML Jobs 문제 해결을 참고하세요.
사용자 흐름: 분석 실행자
분석 실행자는 콜라보레이션 내에서 ML Job을 검토·승인·실행해요.
1. 템플릿 검토 및 승인
템플릿 승인 요청을 검토하고 아티팩트를 검사해요. 해시를 사용해 코드와 아티팩트를 검증해 규정 준수를 확인해요. 대기 중인 템플릿을 승인해요.
참고
코드 리뷰가 필요하면 오프라인으로 수행해야 해요.
2. 컴퓨트 풀 설정
ML Jobs는 웨어하우스 대신 컴퓨트 풀의 컨테이너에서 실행돼요. 설치된 클린룸 애플리케이션용 컴퓨트 풀을 만드세요:
USE ROLE ACCOUNTADMIN;
CREATE COMPUTE POOL my_ml_pool
FOR APPLICATION <installed_app_name>
MIN_NODES = 1
MAX_NODES = 1
INSTANCE_FAMILY = CPU_X64_XS -- minimum size; increase for production workloads
AUTO_RESUME = TRUE;
GRANT USAGE ON COMPUTE POOL my_ml_pool
TO APPLICATION <installed_app_name>;
GRANT USAGE ON WAREHOUSE APP_WH
TO APPLICATION <installed_app_name>;
3. ML Job 실행
템플릿으로 COLLABORATION.RUN을 호출하고 파라미터로 컴퓨트 풀 이름을 전달해요. 호출은 job ID를 반환해요:
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN(
'my_collaboration',
$$
api_version: 2.0.0
spec_type: analysis
template: <template_id>
template_configuration:
arguments:
compute_pool: my_ml_pool
$$
);
template 값은 템플릿 ID로, 템플릿 이름과 버전을 밑줄로 이어 붙인 값이에요. 예를 들어 my_train_template이라는 이름과 v1 버전으로 템플릿을 등록했다면 템플릿 ID는 my_train_template_v1이에요.
4. ML Job 모니터링
RUN_ML_JOB_ACTION을 사용해 로그, 상태, 결과를 확인해요. COLLABORATION.RUN이 반환한 job ID와 수행할 작업(action)을 담은 YAML 스펙을 전달해요:
-- Check job status.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN_ML_JOB_ACTION(
'my_collaboration',
$$
api_version: 2.0.0
spec_type: ml_job_action
job_id: <job_id>
action: get_status
$$
);
-- Check container logs for progress.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN_ML_JOB_ACTION(
'my_collaboration',
$$
api_version: 2.0.0
spec_type: ml_job_action
job_id: <job_id>
action: get_logs
$$
);
-- Get the result once the job completes.
CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.RUN_ML_JOB_ACTION(
'my_collaboration',
$$
api_version: 2.0.0
spec_type: ml_job_action
job_id: <job_id>
action: get_result
$$
);
action 필드는 대소문자를 구분하지 않아요. 유효한 작업은:
-
get_status— 작업의 현재 실행 상태를 반환해요. 가능한 값:PENDING,RUNNING,DONE,FAILED. 작업이 완료되는 시점을 알려면 이 작업을 폴링하세요. -
get_logs— 컨테이너의 stdout/stderr 출력을 반환해요. 진행 상황 모니터링, 오류 디버깅, 스크립트 print 문 보기에 사용해요. 코드 스펙에서allow_monitoring이true이고 콜라보레이션 소유자가ALLOW_ML_JOBS_MONITORING을 비활성화하지 않은 경우에만 사용할 수 있어요.get_logs는SYSTEM$GET_SERVICE_LOGS를 통해 출력을 가져와요. 기본적으로 가장 최근 컨테이너 출력(최대 최근 로그 라인 100KB)만 반환해요. 따라서 오래 실행되는 작업 로그의 앞부분이 누락될 수 있고, 작업 서비스가 만료된 후에는 로그를 사용할 수 없게 될 수 있어요.완전하고 영구 유지되는 로그를 검색하려면 계정 이벤트 테이블을 쿼리하세요. Snowflake는 모든 컨테이너 stdout/stderr를 거기에 저장해요. 컨테이너 로그 게시 및 접근과 이벤트 테이블 컬럼 참조를 확인하세요.
-
get_result— 완료 후 작업의 반환 값을 반환해요. 데이터를 직접 반환하지 않고 클린룸 테이블에 쓰는 스크립트의 경우 NULL을 반환해요.get_result를 호출하기 전에 먼저get_status를 확인해 작업이DONE인지 확인하세요.
이 작업들은 기본 Snowflake ML Jobs 관리 API에 매핑돼요. 작업 수명 주기와 상태 값에 대한 자세한 내용은 Snowflake ML Jobs를 참고하세요.
참고
로그 접근(
get_logs)은 기본적으로true(활성화)인ALLOW_ML_JOBS_MONITORING콜라보레이션 구성으로 제어돼요. 오직 콜라보레이션 소유자만 변경할 수 있고, 소유자의 설정만 콜라보레이션에 적용돼요. 로그 접근을 비활성화하거나 다시 활성화하려면 소유자가 SET_CONFIGURATION을 호출해요:-- Disable ML Jobs log access for the collaboration. CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.SET_CONFIGURATION( 'my_collaboration', 'ALLOW_ML_JOBS_MONITORING', 'false' );비활성화하면
get_logs는 오류를 반환하지만get_status와get_result는 여전히 작동해요.
5. 결과 활성화
표준 활성화 템플릿 흐름을 사용해 출력 오디언스나 측정 지표를 콜라보레이터 또는 제3자에게 활성화해요.
예시
팁과 패턴
일반적인 ML Jobs 오류(템플릿 호출 패턴, 컴퓨트 풀 문제) 문제 해결은 Collaboration Data Clean Rooms 문제 해결 — ML Jobs를 참고하세요.
런타임 이미지 업그레이드와 패치
콜라보레이션 패치가 실행되면 기본 ML 런타임 이미지는 현재 Snowflake Data Clean Rooms API 릴리스를 반영해요. 고정된 image_tag 값은 변경 없이 보존돼요.
- 미지정
image_tag: 코드 스펙이 콜라보레이션에 추가될 때 해석되는 최신 사용 가능한 런타임 이미지를 사용해요. 기존 코드 스펙에서 새 기본 이미지를 받으려면 코드 스펙을 콜라보레이션에 다시 추가하세요. - 고정된
image_tag: 고정 값은 패치 전체에서 항상 변경 없이 보존돼요. 안정적이고 알려진 라이브러리 집합으로 실행하려면image_tag를 고정하세요.
image_tag 필드 참조는 ML Jobs 코드 스펙을, 사용 가능한 버전 목록은 Container Runtime 릴리스를 참고하세요.
개발 워크플로
Snowflake Data Clean Rooms 밖의 표준 Snowflake 환경에서도 동일한 Python 스크립트와 컨테이너 런타임을 사용해 전체 ML Job 워크플로를 빌드하고 테스트할 수 있어요. 그러면 콜라보레이션의 템플릿 승인 워크플로를 통해 각 변경을 밀어 넣지 않고도 일반 개발 환경에서 빠르게 반복할 수 있어요.
스크립트를 빌드하고 테스트한 뒤, 고정된 image_tag가 있는 코드 스펙으로 스크립트를 콜라보레이션에 가져와요. 이미지 버전을 고정하면 개발하고 테스트한 정확한 의존성 집합이 고정되어, 워크로드가 콜라보레이션 안에서 동일하게 실행돼요. image_tag 필드 참조는 ML Jobs 코드 스펙을 참고하세요.
콜라보레이터 데이터 접근
인라인 SQL을 실행하는 UDF나 프로시저 템플릿과 달리, ML Jobs 스크립트는 cleanroom.source_table_0을 직접 참조할 수 없어요. 그 뷰는 ML Jobs 실행 시 생성되지 않기 때문이에요.
대신 OBJECT_CONSTRUCT를 사용해 args 파라미터로 소스 테이블 참조를 컨테이너에 전달해요:
template: |
call cleanroom.my_ml_model$my_train_job(
{{ compute_pool }}, {{ num_instances | default(1) }}, {{ warehouse | default("APP_WH") }},
OBJECT_CONSTRUCT('source_table', ARRAY_CONSTRUCT({{ source_table[0] }}, {{ source_table[1] }}))::VARCHAR
)
Python 스크립트에서 args JSON에서 소스 테이블 참조를 읽어요:
import argparse, json
from snowflake.snowpark.context import get_active_session
parser = argparse.ArgumentParser()
parser.add_argument("--args", type=str, default="{}")
args = json.loads(parser.parse_args().args)
session = get_active_session()
source_tables = args.get("source_table", [])
df = session.table(source_tables[0]).to_pandas()
활성화용 결과 작성
활성화가 작동하려면 스코어링 스크립트가 활성화 템플릿이 읽는 클린룸 테이블에 결과를 써야 해요. 스코어링 스크립트에서 session.create_dataframe(df).write.save_as_table("cleanroom.<table_name>", mode="overwrite")를 사용하고, 활성화 템플릿에 같은 테이블을 참조하세요:
template: |
BEGIN
CREATE OR REPLACE TABLE cleanroom.activation_data_<results> AS
SELECT <columns>
FROM cleanroom.<table_written_by_score>;
RETURN '<results>';
END;
분산 학습으로 확장
대형 데이터셋(수천만 행 이상)에서는 단일 노드 학습 대신 Snowflake 분산 트레이너를 사용하세요. ML Jobs 컨테이너 런타임에는 분산 트레이너가 자동으로 사용하는 Ray 클러스터가 포함돼 있어요.
분산 학습을 사용할 때: 모델을 학습하는 데 필요한 메모리나 컴퓨트 요구 사항이 단일 컴퓨트 풀 노드(고메모리 CPU 노드 또는 대형 GPU 노드)에서 지원할 수 있는 범위를 넘을 때, 분산 학습은 여러 노드로 스케일 아웃하는 데 도움을 줘요.
코드 변경: 원시 XGBoost를 분산 트레이너로 교체해요:
# Instead of:
import xgboost
model = xgboost.train(params, dtrain, num_rounds)
# Use the distributed trainer:
from snowflake.ml.modeling.distributors import XGBoostDistributor
from snowflake.ml.data.data_connector import DataConnector
train_connector = DataConnector.from_dataframe(session.table(source_tables[0]))
distributor = XGBoostDistributor(
params={"objective": "binary:logistic", "max_depth": 6, "eta": 0.1},
num_boost_round=100,
label_column="LABEL",
)
model = distributor.train(train_connector)
템플릿 변경: 다중 노드용 num_instances를 늘려요:
template: |
call cleanroom.my_ml_model$my_train_job(
{{ compute_pool }},
{{ num_instances | default(2) }},
{{ warehouse | default("APP_WH") }},
OBJECT_CONSTRUCT('source_table', ARRAY_CONSTRUCT({{ source_table[0] }}))::VARCHAR
)
num_instances 파라미터는 작업이 실행되는 컴퓨트 풀 노드 수를 제어해요. 분산 트레이너는 사용 가능한 모든 노드를 자동으로 발견해 사용해요. 그에 맞게 컴퓨트 풀 크기를 조정하세요:
CREATE COMPUTE POOL my_distributed_pool
FOR APPLICATION <installed_app_name>
MIN_NODES = 4
MAX_NODES = 4
INSTANCE_FAMILY = GPU_NV_S -- or CPU_X64_L for CPU training
AUTO_RESUME = TRUE;
자세한 내용은 분산 학습을 참고하세요.