플랫폼은 실험 추적과 모델 레지스트리의 뒤편에 MLflow 를 씁니다. 플랫폼 밖(노트북, 사내 GPU 서버, CI)에서 돈 학습도 표준 MLflow 파이썬 클라이언트 그대로 플랫폼에 기록할 수 있습니다. 필요한 것은 두 가지뿐입니다.

  • 추적 주소: https://<플랫폼 주소>/mlflow
  • MLflow 토큰: 테넌트에 묶인 토큰. 이 토큰이 곧 테넌트 경계라서, 코드에 테넌트 설정이나 X-Tenant 헤더가 필요 없습니다

토큰으로 기록한 실험 · run · 등록 모델은 그 토큰의 테넌트에만 보이고, 기록하는 즉시 플랫폼의 실험 · 모델 레지스트리 화면에 나타납니다.

1. 토큰 발급 (화면)

  1. 오른쪽 위 아바타 → 계정 설정MLflow 토큰 으로 갑니다. DEVELOPER 이상이면 발급할 수 있습니다.
  2. 토큰 이름(선택)과 ③ 만료 일수를 정하고 발급 을 누릅니다. ① 토큰은 이때 한 번만 보입니다. ② 이 서버의 추적 주소가 채워진 export 명령을 그대로 복사해 쓰면 됩니다.
    MLflow 토큰 발급 직후: ① 토큰은 한 번만 보인다 ② 추적 주소가 채워진 export 명령 ③ 만료 일수

아래 목록에서 토큰별 발급 · 만료 · 마지막 사용 시각을 보고, 새어 나간 것 같으면 회수 합니다. 회수한 토큰의 요청은 401 로 거절됩니다. 목록의 training:… 토큰은 플랫폼이 학습 실행마다 발급하고 끝나면 회수한 것입니다.

1-b. 토큰 발급 (API)

CI 처럼 화면을 쓸 수 없으면 API 로 발급합니다.

API=https://mlops.example.com
JWT=$(curl -sS -X POST "$API/auth/jwt/login" \
  --data-urlencode "username=you@example.com" \
  --data-urlencode "password=<your-password>" | jq -r .access_token)

curl -sS -X POST "$API/api/v1/mlflow/tokens" \
  -H "Authorization: Bearer $JWT" -H "X-Tenant: DEMO" \
  -H 'Content-Type: application/json' \
  -d '{"name": "ci-train", "expires_in_days": 30}'
{"id": "9d32c814-…", "token": "<secret>", "tenant": "DEMO", "workspace": "demo",
 "tracking_uri": "https://mlops.example.com/mlflow"}

expires_in_days 를 빼면 무기한 토큰입니다. 무기한 토큰은 회수하기 전까지 계속 유효하니 꼭 필요한 곳에만 쓰세요.

2. 환경 변수

export MLFLOW_TRACKING_URI=https://mlops.example.com/mlflow
export MLFLOW_TRACKING_TOKEN=<발급한 토큰>

토큰은 코드나 저장소에 적지 말고 환경 변수나 시크릿 관리 도구로 넣으세요. 연결 확인:

import mlflow
print(mlflow.get_tracking_uri())
for exp in mlflow.search_experiments():     # 이 테넌트의 실험만 보인다
    print(exp.experiment_id, exp.name)

3. 기록하기

아래는 촬영 스택에 실제로 기록해 본 코드입니다(MLflow 3.13.0). 플랫폼 밖에서는 set_experiment() 로 실험 이름을 정해도 됩니다. 이 호출을 막는 곳은 플랫폼 학습 컨테이너 안뿐입니다.

import mlflow
import pandas as pd
from mlflow.models import infer_signature

mlflow.set_experiment("docs-mlflow-direct")          # 없으면 만든다

with mlflow.start_run(run_name="baseline") as run:
    mlflow.log_params({"epochs": 3, "lr": 0.001})
    for epoch in range(3):
        mlflow.log_metrics({"train/loss": 1.0 / (epoch + 1),
                            "eval/accuracy": 0.5 + 0.1 * epoch}, step=epoch)
    mlflow.log_text("hello", "notes/summary.txt")     # 아무 파일이나 아티팩트로

    class Echo(mlflow.pyfunc.PythonModel):
        def predict(self, context, model_input, params=None):
            return model_input

    df = pd.DataFrame({"x": [1.0]})
    info = mlflow.pyfunc.log_model(name="model", python_model=Echo(),
                                   signature=infer_signature(df, df))
  • step 을 주면 run 상세의 메트릭 탭에 곡선이 그려집니다.
  • 기록한 run 은 플랫폼 실험 화면에 바로 보입니다.
노트북에서 MLflow 로 기록한 run 이 플랫폼의 실험 화면에 그대로 보인다

4. 모델 레지스트리에 등록하기

방법코드언제
로깅과 동시에mlflow.pyfunc.log_model(..., registered_model_name="mnist-cnn")늘 등록할 때
로깅 뒤에 조건부로mlflow.register_model(info.model_uri, "mnist-cnn")검증 지표가 기준을 넘을 때만 등록
플랫폼 화면에서run 상세의 모델 등록기록은 코드로, 등록 판단은 사람이
mv = mlflow.register_model(info.model_uri, "docs-mlflow-direct")
print(mv.name, mv.version)          # docs-mlflow-direct 1
  • register_model() 에는 log_model() 이 돌려준 info.model_uri(models:/m-…)를 그대로 넘기세요. MLflow 3 은 로깅된 모델을 run 아티팩트 밖에 두므로 runs:/<run>/model 을 짐작하면 실패할 수 있습니다.
  • 가중치 파일만 아티팩트로 올린 뒤 MlflowClient().create_model_version(source="runs:/…/weights/best.pt") 로 등록하는 옛 방법도 등록은 됩니다. 하지만 MLmodel 이 없어 서빙 이미지를 만들 수 없습니다. 배포까지 갈 모델이면 pyfunc.log_model 로 남기세요.

스테이지

코드로 직접 등록한 버전의 스테이지는 None 입니다(실제로 확인). 플랫폼 학습이 자동 등록한 버전은 Staging 으로 올라갑니다. Production 승격은 API 로 하지 말고 플랫폼 화면의 승격 요청 → 승인 절차로 하세요. 승격 이력이 승인·감사 기록으로 남아야 하기 때문입니다.

문제 해결

증상원인과 조치
401 / 403토큰이 없거나 만료 · 회수됨. MLflow 토큰 에서 상태를 보고 다시 발급. MLFLOW_TRACKING_TOKEN 이 실행 프로세스까지 전달되는지 확인
기록은 됐는데 화면에 안 보임다른 테넌트의 토큰으로 기록함. 토큰 발급 때의 테넌트와 화면의 테넌트가 같은지 확인
사내 프록시 뒤에서 연결 실패NO_PROXY 에 플랫폼 호스트를 넣거나 HTTPS_PROXY 설정 확인
아티팩트 업로드 실패서버의 오브젝트 스토리지 연결 문제일 수 있습니다. 운영자에게 알리세요

2026-09-21 기준 플랫폼에 맞춰 작성했습니다.

© Geo-MLOps