Papermill을 사용해 Jupyter Notebook에 파라미터 주입하기(feat. airflow)
- Papermill Jupyter Notebook(노트북 파라미터화)에 대한 내용과 Airflow에서 활용하는 방법에 대해 작성한 글입니다
- jupyter notebook run with parameter, run jupyter notebook with parameters, execute notebook with the custom arguments
Papermill
- [Github], [Document]
- 다음과 같은 상황이 발생할 경우가 있음
- 1) Jupyter Notebook에서 데이터 분석 또는 머신러닝 모델링
- 2) 두 작업을 반복적으로 실행해야 할 경우, Python Script로 다시 파일을 수정
- 3) Crontab, Airflow 등에 반복 작업을 실행
- 1)와 2) 사이에서 스크립트로 변환하는 작업에 시간이 적게 소요될 수도 있지만, 노트북 환경에 익숙한 사람은 오래 걸릴 수 있음(필요시 Class화를 해야할 필요도 있음)
- Jupyter Notebook을 특정 값만 파라미터로 바꿔서 실행할 수 있는 것이 바로 Papermill
- 기능
- Parameterize notebooks(노트북을 파라미터화)
- Execute notebooks(노트북 실행)
- Python, R, Julia, Scala 등에서 사용 가능
- 활용 예시
- Jupyter Notebook에서 데이터 분석 레포트를 생성할 때, 일자만 파라미터로 받아서 => DB에서 그 일자를 토대로 쿼리를 날리고 => 레포트 작성(시각화 등)
- A Notebook을 실행하고 B Notebook을 실행하고 싶은 경우 Airflow와 같이 사용하면 Notebook끼리 workflow를 실행할 수 있음
Papermill 설치
기본 설치
pip3 isntall papermill
AWS S3, GCP GCS, Azure 등을 사용하고 싶은 경우
pip3 install 'papermill[all]'
필요한 것만 설치하고 싶다면
pip3 install 'papermill[s3]'
pip3 install 'papermill[gcs]'
pip3 install 'papermill[azure]'
데이터 및 Notebook 파일 준비
- BigQuery Public Dataset에 있는
austin_bikeshare.bikeshare_trips
데이터 중 2019년 11월 1일 이후 데이터만 가져와서 사용- 소스코드와 csv 파일은 Github에 있음
- 데이터를 가져와서 하는 일은 다음과 같다(일종의 레포트라고 생각)
- 특정 일자의 시간대별 사용량 line plot 그리기
- 특정 일자의 구독자 타입(subscriber_type) bar plot 그리기
- 특정 일자의 start_station_id 사용량 bar plot 그리기
- 특정 일자의 시간대별 start_station_id 사용량 heatmap 그리기
papermill_example.ipynb
으로 생성하고, 이 파일을 Template Notebook이라 부를 예정
- In [2]은 read_csv지만 실제 활용할 땐 데이터베이스에서 데이터를 가져오는 부분
- In [3]는 시간 관련 값을 추출하는 부분
- In [4]는 date 변수를 저장
- 이 In [4]를 파라미터화하면 된다
- In [5]는 date를 필터링하는 부분
Papermill 실행하기
- 1) 파라미터를 저장할 Cell에 Tag 달기
- 1-1) View - Cell Toolbar - Tags 클릭
- 1-2) Parameters라고 입력하고 Add tag
- 이제 Parameters Tag가 달린 곳에 있는 date를 덮어쓸 수 있음
- 2) Papermill 실행하기
- 1) Python API를 사용하는 방법과 2) CLI에서 하는 방법 2가지가 있음
- 1) Python API
- 별도의 Notebok(또는 스크립트 파일)에서 아래 코드 실행
import papermill as pm pm.execute_notebook( 'papermill_example.ipynb', # Template Notebook 'papermill_example_output.ipynb', # Template를 사용해 Output이 저장되는 Notebook parameters = dict(date='2019-11-07') # 파라미터 주입 )
- 만약 Template notebook에 parameters tag가 없다면(태그를 지워보고 실행해보길), Warning 메세지가 출력된다(그래도 그냥 실행된다)
2) CLI
papermill papermill_example.ipynb papermill_example_output.ipynb -p date '2019-11-07'
- 실행하고, Output Notebook(
papermill_example_output.ipynb
)을 보면 다음과 같이 되어있다- injected-parameters Tag가 있는 Cell이 추가되었고, In [7]을 보면 start_date가 2019-11-07임을 알 수 있다
Papermill 기타 옵션 및 작동 방식
- 기타 옵션
- 공식 문서엔 잘 작성되지 않은 것들이 있음
- Python API와 CLI에서 사용할 수 있는 옵션이 살짝 다름
- 예를 들면 CLI에선 파라미터를 yaml으로 받을 수 있고, Python API는 불가능(2020.3.8 기준)
- Python API 기타 옵션
input_path : str Path to input notebook output_path : str Path to save executed notebook parameters : dict, optional Arbitrary keyword arguments to pass to the notebook parameters engine_name : str, optional Name of execution engine to use request_save_on_cell_execute : bool, optional Request save notebook after each cell execution autosave_cell_every : int, optional How often in seconds to save in the middle of long cell executions prepare_only : bool, optional Flag to determine if execution should occur or not kernel_name : str, optional Name of kernel to execute the notebook against progress_bar : bool, optional Flag for whether or not to show the progress bar. log_output : bool, optional Flag for whether or not to write notebook output to the configured logger start_timeout : int, optional Duration in seconds to wait for kernel start-up report_mode : bool, optional Flag for whether or not to hide input. cwd : str, optional Working directory to use when executing the notebook
- CLI 기타 옵션
Options: -p, --parameters TEXT... Parameters to pass to the parameters cell. -r, --parameters_raw TEXT... Parameters to be read as raw string. -f, --parameters_file TEXT Path to YAML file containing parameters. -y, --parameters_yaml TEXT YAML string to be used as parameters. -b, --parameters_base64 TEXT Base64 encoded YAML string as parameters. --inject-input-path Insert the path of the input notebook as PAPERMILL_INPUT_PATH as a notebook parameter. --inject-output-path Insert the path of the output notebook as PAPERMILL_OUTPUT_PATH as a notebook parameter. --inject-paths Insert the paths of input/output notebooks as PAPERMILL_INPUT_PATH/PAPERMILL_OUTPUT_PATH as notebook parameters. --engine TEXT The execution engine name to use in evaluating the notebook. --request-save-on-cell-execute / --no-request-save-on-cell-execute Request save notebook after each cell execution --autosave-cell-every INTEGER How often in seconds to autosave the notebook during long cell executions (0 to disable) --prepare-only / --prepare-execute Flag for outputting the notebook without execution, but with parameters applied. -k, --kernel TEXT Name of kernel to run. --cwd TEXT Working directory to run notebook in. --progress-bar / --no-progress-bar Flag for turning on the progress bar. --log-output / --no-log-output Flag for writing notebook output to the configured logger. --stdout-file FILENAME File to write notebook stdout output to. --stderr-file FILENAME File to write notebook stderr output to. --log-level [NOTSET|DEBUG|INFO|WARNING|ERROR|CRITICAL] Set log level --start-timeout, --start_timeout INTEGER Time in seconds to wait for kernel to start. --execution-timeout INTEGER Time in seconds to wait for each cell before failing execution (default: forever) --report-mode / --no-report-mode Flag for hiding input. --version Flag for displaying the version. -h, --help Show this message and exit.
- 작동 방식
- parameters 셀을 찾고, 그 밑 셀에 injected-parameters라는 Tag를 가지는 새 셀을 삽입함(사용자가 지정한 값이 저장됨)
- injected parameters 아래 셀을 실행
- 주의할 점 : 주입되는 파라미터만 저장되기 때문에, 파라미터 저장하는 셀과 실행하는 셀을 나누는 것이 좋음
- parameters Tag Cell에 파라미터 저장과 연산이 같이 있으면 안된다는 의미
- Notebook에서 date=’2019-11-05’와
filter_df = df[df['start_date'].astype(str) == date]
을 같은 Cell에 두고 Papermill을 실행시켜보면 왜 나눠야 하는지 알 수 있음
- 정리
- Notebook 파일 작성
- Notebook에 파라미터만 저장하는 Cell 지정
- Cell에 Tag 추가
- Papermill 실행
- Voila와 결합해 사용할 수 있을듯
- Notebook으로 모델링하는 파일과 그걸 받아 Serving을 쉽게 할 수 있도록 만들 수 있을듯
궁금해서 시도한 내용
- 궁금한 점
- 1) 다양한 Tag로 작성해도 파라미터가 주입되나?
- X. 첫 parameters만 사용 가능
- 2) 파일 저장하지 않고 노트북만 실행시킬 수 있는지?
- Notebook 안에서 모델을 훈련해서 저장하는 작업만 있다면 추가적으로 Notebook을 생성하지 않아도 됨
- X. output_path를 지정하지 않으면 Error 발생
- 로그 확인용으로 datetime으로 저장시키거나, 로깅을 따로 한다면 하나의 notebook 파일로 저장하면 될 듯
- 1) 다양한 Tag로 작성해도 파라미터가 주입되나?
Papermill 기타
- Conda를 사용할 경우 kernel이 없다고 오류가 발생할 수 있음
- Jupyter Lab에서 사용할 경우엔 위에서 설명한 방식을 사용하지 않음
- Metadata를 수정
- Document에 나와있음
- Cloud Storage 지원
Airflow에서 Papermill으로 Notebook 실행하기
- Airflow에 대해 궁금하다면 Apache Airflow - Workflow 관리 도구(1) 참고
- Apache Airflow 1.10.6부터 PapermillOperator가 추가됨
- Airflow에 익숙하면, Operator 사용은 어렵지 않음
- PapermillOperator 활용
- 예제 파일
from airflow import DAG from airflow.providers.papermill.operators.papermill import PapermillOperator default_args = { 'owner': 'kyle', 'start_date': '2019-11-05', 'end_date': '2019-11-10' } with DAG( dag_id='example_papermill_operator', default_args=default_args, schedule_interval='0 0 * * *', ) as dag: run_this = PapermillOperator( task_id="run_example_notebook", input_nb="papermill_example.ipynb", output_nb="papermill_example_output_.ipynb", parameters={"date": "" } )
참고 자료
- Papermill Github
- Notebooks as Functions with Papermill, Netflix Video : Youtube 영상
- Apache Airflow - Workflow 관리 도구(1)
- Ai pipelines powered by jupyter notebooks
- Introduction to Papermill
- Automated reports with Jupyter Notebooks (using Jupytext and Papermill)
카일스쿨 유튜브 채널을 만들었습니다. 데이터 분석, 커리어에 대한 내용을 공유드릴 예정입니다.
PM을 위한 데이터 리터러시 강의를 만들었습니다. 문제 정의, 지표, 실험 설계, 문화 만들기, 로그 설계, 회고 등을 담은 강의입니다
이 글이 도움이 되셨거나 의견이 있으시면 댓글 남겨주셔요.