본문 바로가기
새로운, 신나게/MLFlow, 공부하는 중

[MLflow 완전정복 #5] Tracking URI와 Experiment — 기록하기 전에 정해야 할 두 가지

by DoubleS2 2026. 9. 5.

MLflow 완전정복 다섯 번째 편. 지난 편에서 서버 띄우다 한참 헤맸는데, 그 답이 강의 자료 두 번째 슬라이드에 그냥 적혀 있었습니다.
이번 편은 기록을 남기기 전에 반드시 정해야 하는 두 가지 — Tracking URI Experiment 이야기예요.

📎 출처: 이 글은 인프런 강의 「실리콘밸리 엔지니어와 함께하는 MLflow」의 영문 강의 자료를 수강 후, 제가 공부하며 이해한 방향으로 한국어로 재구성한 것입니다.


🎯 1. 이번 편은 "기록하기 전" 이야기

이번 챕터에서 배우는 함수는 딱 네 개입니다. 그런데 넷 다 실제로 뭘 기록하는 함수는 아닙니다.

  • set_tracking_uri() — 기록을 어디로 보낼지 정한다
  • get_tracking_uri() — 지금 어디로 보내고 있는지 확인한다
  • set_experiment()  어느 서랍에 넣을지 정한다
  • get_experiment() — 그 서랍 정보를 조회한다

강의 자료 첫 장은 이렇게 시작합니다.

"MLflow는 파라미터·메트릭·아티팩트·모델을 추적하는 로깅 함수들을 제공하며, 이는 MLflow Tracking API의 일부다."

 

 log_param(), log_metric() 같은 진짜 기록 함수는 다음 편이고,

이번 편은 그걸 쓰기 전에 자리를 잡아두는 내용이에요.

 

💡 내가 이해한 방향 — 종이에 글 쓰기 전에 "어느 노트에, 몇 번째 칸에" 쓸지 정하는 단계라고 이해했어요. 별거 아닌 것 같은데, 이걸 안 정하면 기록은 남는데 어디 남았는지 모르는 상태가 됩니다. 지난 편의 제가 그랬어요.


📍 2. Tracking URI — "어디에 쓸 건가"

강의 자료의 설명은 두 줄인데, 필요한 말은 다 들어 있습니다.

  • MLflow 클라이언트를 특정 트래킹 서버에 연결할 때 필수적(essential)이다 — 로컬이든, 원격이든, 클라우드든
  • 기본 동작 — 이 함수를 명시적으로 호출하지 않으면, MLflow는 현재 작업 디렉토리의 mlruns 폴더(로컬 파일 저장소)를 쓴다

제가 지난 편에서 한참 헤맸던 이유가 저 두 번째 줄에 있었습니다.

MLflow는 URI를 안 정해줘도 에러를 내지 않아요. 그냥 조용히 내 폴더에 쌓습니다. 그래서 이런 일이 벌어집니다.

  • 서버는 멀쩡히 돌고 있고
  • 스크립트도 에러 없이 잘 끝나고
  • 그런데 웹 UI엔 아무것도 안 보이는

실패했는데 실패한 티가 안 나니까, 어디서부터 봐야 할지를 모릅니다. 자료가 알려주는 URI는 세 종류예요.

종류 형태 언제
로컬 파일 file:/path/to/mlruns 혼자 잠깐 돌려볼 때 (기본값)
원격 서버 http://<server-address>:5000 우리 케이스 (Docker로 띄운 서버)
클라우드 s3://<bucket-name>/mlruns 팀·운영 환경

 

강의 코드는 URI를 환경변수에서 꺼내 읽는 방식으로 짜여 있습니다.

import os
import mlflow

# 환경변수에서 읽어온다. 값이 없으면 두 번째 인자인 ""(빈 문자열)
mlflow.set_tracking_uri(uri=os.getenv("MLFLOW_TRACKING_URI", ""))

# 지금 어디로 보내는 중인지 확인
print(f"Current Tracking URI: {mlflow.get_tracking_uri()}")

 

이 환경변수가 없으면 ""가 대신 쓰이고, 그 순간 로컬 폴더 행입니다. 그래서 실행할 때 이렇게 앞에 붙여줘야 해요.

MLFLOW_TRACKING_URI=http://localhost:5001 python3 logging_functions.py

 

그리고 get_tracking_uri()는 사실상 디버깅용입니다.

실행하자마자 이 줄이 먼저 찍히니까, 주소가 맞는지 여기서 바로 걸러낼 수 있어요.

💡 내가 이해한 방향 — 혼자 공부할 땐 로컬 폴더도 괜찮습니다. 문제는 팀이 되는 순간이에요. 내 맥의 mlruns 폴더는 아무도 못 봅니다. 동료 결과와 비교할 수도 없고요. 로컬 폴더에서 공용 서버로 갈아타는 스위치가 딱 이 한 줄이라서, 1편에서 재현성이니 협업이니 했던 이야기가 결국 이 한 줄이었구나 싶었어요.


🗂️ 3. Experiment — "어느 서랍에 넣을 건가"

자료의 정의는 한 줄입니다. 

 

"Experiment는 런(run)의 논리적 묶음이다." 

 

같은 프로젝트·유스케이스에 속한 런들을 한데 정리해주는 개념이에요.

 

왜 필요하냐면 — 런이 생각보다 훨씬 빨리 쌓이기 때문입니다. 하이퍼파라미터 하나 바꿔서 20번 돌리면 런이 20개예요.

서랍이 없으면 어제 돌린 이미지 분류 런과 오늘 돌린 추천 모델 런이 한 화면에 뒤섞입니다. 

게다가 이름은 kindly-loon-220 같은 랜덤 작명이고요.

 

자료가 정리한 Experiment의 네 가지 특징입니다.

특징 설명
Logical Grouping 실험은 런을 담는 컨테이너. 하이퍼파라미터를 바꿔가며 돌린 런들을 한 실험에 묶는다
Experiment Metadata 고유 ID 이름을 가지며, artifact location이 파일이 저장될 위치를 지정
Runs 각 실험은 여러 런을 담고, 런 1개 = ML 워크플로 1회 실행
Lifecycle Stages active / deleted 상태. active만 UI에 보이고, deleted는 명시적으로 조회해야 나온다

그리고 set_experiment()의 설명에서 제일 중요한 문장은 이거였어요.

  • Sets or creates — 이미 있으면 그걸 쓰고, 없으면 새로 만든다
  • Scope — 이 함수를 호출한 뒤에 시작되는 모든 런은 이 실험 아래에 기록된다

두 번째가 핵심입니다. set_experiment()은 한 번만 불러두면 됩니다. 그 뒤에 만드는 런들은 따로 지정하지 않아도 알아서 그 서랍으로 들어가요. get_experiment()는 바꾸지 않고 조회만 합니다. set_은 바꾸고 get_은 확인만 — Tracking URI 때랑 똑같아요.

💡 내가 이해한 방향 — Lifecycle의 deleted가 의외로 실용적이었어요. UI에서 실험을 지워도 DB에서 진짜 사라지는 게 아니라 딱지가 붙어 숨겨질 뿐이더라고요. 지난 편 README에서 봤던 mlflow runs list --view all의 그 all이, 바로 이 숨겨진 것까지 보겠다는 뜻이었어요. 지난 편엔 그냥 지나쳤는데, 이제야 왜 있는 옵션인지 알겠더라고요.


🧑‍💻 4. 코드 한 편으로 따라가기

강의 예제 logging_functions.py는 서랍 만들기 → 런 3개 넣기 → 나중에 하나 더 넣기 흐름입니다. 핵심만 추리면 이래요.

# ① 서랍 만들기 (없으면 생성, 있으면 그거 사용)
experiment = mlflow.set_experiment("new_experiment")
print(f"Experiment ID: {experiment.experiment_id}")

# ② 같은 서랍에 런 3개 넣기
for i in range(3):
    with mlflow.start_run():
        mlflow.log_param("iteration", i)
        mlflow.log_metric("accuracy", 0.8 + i * 0.05)
        with open("example.txt", "w") as f:
            f.write("This is an example artifact.")
        mlflow.log_artifact("example.txt")      # 파일 첨부

# ③ 나중에 같은 서랍에 하나 더 (ID로 직접 지정)
with mlflow.start_run(experiment_id=experiment.experiment_id):
    mlflow.log_param("new_param", 100)
    mlflow.log_metric("new_metric", 0.95)      # log_artifact 없음

 

실행하면 터미널에 이렇게 찍힙니다.

Current Tracking URI: http://localhost:5001
INFO mlflow.tracking.fluent: Experiment with name 'new_experiment'
     does not exist. Creating a new experiment.
Experiment ID: 2
Experiment Name: new_experiment
Artifact Location: mlflow-artifacts:/2
Lifecycle Stage: active

Logged run under experiment 'new_experiment'
🏃 View run kindly-loon-220 at: http://localhost:5001/#/experiments/2/runs/830cfd...
🧪 View experiment at: http://localhost:5001/#/experiments/2
... (3번 반복) ...
Logged run under experiment ID 2
🏃 View run hilarious-croc-255 at: ...

 

여기서 처음에 헷갈렸던 게 출력 순서였어요.

 

내가 쓴 print가 먼저 나오고, 🏃 링크가 나중에 나옵니다. 

MLflow는 with 블록을 빠져나가는 순간 "이 런 끝났습니다, 여기서 보세요"라며 링크를 찍어주기 때문이에요.

 

그리고 반복문은 3번인데 런은 4개가 됩니다.

③번 블록이 반복문 바깥에 있어서 그래요. start_run() 한 번 = 런 하나입니다. 서버에 실제로 들어간 결과를 보면 이렇습니다.

 

이름 파라미터 지표 첨부파일
kindly-loon-220 iteration 0 accuracy 0.8 example.txt
blushing-fish-498 iteration 1 accuracy 0.85 example.txt
intrigued-colt-494 iteration 2 accuracy 0.9 example.txt
hilarious-croc-255 new_param 100 new_metric 0.95

 

숫자가 0.8 → 0.85 → 0.9 → 0.95로 이어지는 것처럼 보이지만, 마지막은 이름이 다른 지표입니다.

반복문의 accuracy는 range(3)이라 0.9에서 끝나고, 0.95는 마지막 블록에 손으로 써넣은 new_metric이에요.

엑셀로 치면 아예 다른 열입니다.

💡 내가 이해한 방향 — 마지막 런에만 첨부파일이 없는 이유는 간단합니다. 그 블록에 log_artifact 줄이 없어서예요. 그런데 그 순간에도 example.txt는 폴더에 멀쩡히 있었어요. 파일이 폴더에 있는 것과, 그 파일이 런에 붙는 건 완전히 별개였어요. 택배도 상자만 싸놓으면 안 가잖아요. 접수를 해야 갑니다. MLflow도 내가 시킨 것만 기록해요. 안 시키면 에러도 경고도 없이 그냥 없습니다.


🔍 5. 내 출력이 강의 자료와 다른 이유

강의 자료의 예시 출력과 제 화면을 나란히 놓으면 두 줄이 다릅니다.

# 강의 자료
Current Tracking URI: http://0.0.0.0:5000
Artifact Location:    /mlflow/mlruns/2

# 내 화면
Current Tracking URI: http://localhost:5001
Artifact Location:    mlflow-artifacts:/2

틀린 게 아니라 실행 위치와 서버 설정이 달라서입니다.

  • URI가 다른 이유 — 강사님은 컨테이너 안에서 실행해 내부 주소가 그대로 보이고, 저는 컨테이너 밖(맥)에서 실행해 포트 매핑 주소를 씁니다
  • Artifact Location이 다른 이유 — 지난 편에서 --serve-artifacts로 바꿔뒀기 때문입니다. 폴더 경로가 아니라 mlflow-artifacts:/라는 형태로 나오는 게 "창고에 직접 들어가지 않고 접수처에 맡긴다"는 뜻이에요

처음엔 뭘 잘못 건드린 줄 알았는데, 지난 편에서 고쳐둔 설정이 그대로 살아 있다는 뜻이었습니다. "컨테이너 안과 밖은 다른 세상"이라는 4편 이야기가 여기까지 이어지네요.


✍️ 마무리 & 다음 단계

이번 편을 한 문장으로 줄이면 이렇습니다.

MLflow에게 기록을 시키기 전에 어느 서버로(Tracking URI), 어느 서랍에(Experiment) 보낼지 먼저 알려줘야 한다.

안 알려주면 에러도 없이 다른 데 저장된다.

 

한참 헤맸던 문제의 답이 강의 자료에 이미 적혀 있었다는 게 이번 편에서 제일 민망했던 부분이에요.

삽질하고 나서 다시 보니 그제야 그 문장이 눈에 들어오더라고요.

순서는 뒤바뀌었지만, 다음부터는 뭐가 안 보이면 URI부터 확인하게 될 것 같습니다.

 

다음 편은 실제로 기록하는 함수들입니다.

👉 다음 편 → [#6] log_param·log_metric·log_artifact 제대로 쓰기 (강의 진도에 따라 제목은 바뀔 수 있어요)

📎 출처: 이 글은 인프런 「실리콘밸리 엔지니어와 함께하는 MLflow」 강의의 영문 자료를 수강 후, 개인 학습 목적으로 이해한 방향에 따라 한국어로 재구성한 것입니다. 잘못 이해한 부분이 있다면 댓글로 알려주세요. 🙏