Skip to main content
원문: Introducing MLflow Tracing (2024-06-10)
작성자: MLflow 메인테이너
MLflow의 강력한 새 기능인 MLflow Tracing의 출시를 발표하게 되어 기쁩니다. 이 기능은 GenAI 애플리케이션에 포괄적인 계측(instrumentation) 기능을 제공하여, 간단한 채팅 인터페이스부터 복잡한 다단계 RAG(Retrieval Augmented Generation) 애플리케이션에 이르기까지 모델과 워크플로우의 실행에 대한 심층적인 인사이트를 얻을 수 있게 합니다.
참고: MLflow Tracing은 버전 2.14.0 이상이 필요합니다.

MLflow Tracing이란?

MLflow Tracing은 애플리케이션에서 트레이싱을 활성화하기 위한 다양한 방법을 제공합니다:
  • LangChain을 통한 자동 트레이싱: mlflow.langchain.autolog()을 활성화하는 것만으로 완전히 자동화된 LangChain 통합을 사용할 수 있습니다.
  • 고수준 Fluent API를 통한 수동 트레이스 계측: 데코레이터, 함수 래퍼, 컨텍스트 매니저를 사용하는 fluent API로 최소한의 코드 수정만으로 트레이싱을 적용할 수 있습니다.
  • 저수준 Client API를 통한 트레이싱: MLflow client API는 기록되는 데이터에 대한 스레드 안전(thread-safe)하고 세밀한 제어를 제공합니다.

MLflow Tracing 시작하기

LangChain 자동 트레이싱

MLflow Tracing을 시작하는 가장 쉬운 방법은 LangChain과의 기본 제공 통합을 사용하는 것입니다. autologging을 활성화하면, 체인에서 호출 API를 실행할 때 트레이스가 자동으로 활성 MLflow 실험에 기록됩니다.
import os
from langchain.prompts import PromptTemplate
from langchain_openai import OpenAI
import mlflow

assert "OPENAI_API_KEY" in os.environ, "Please set your OPENAI_API_KEY environment variable."

mlflow.set_experiment("LangChain Tracing")
mlflow.langchain.autolog(log_models=True, log_input_examples=True)

llm = OpenAI(temperature=0.7, max_tokens=1000)

prompt_template = "Imagine you are {person}, and you are answering a question: {question}"

chain = prompt_template | llm

chain.invoke({"person": "Richard Feynman", "question": "Why should we colonize Mars?"})
chain.invoke({"person": "Linus Torvalds", "question": "Can I set everyone's access to sudo?"})
체인을 호출한 후 MLflow UI에서 LangChain Tracing 실험으로 이동하면 다음과 같은 화면을 볼 수 있습니다: Traces in UI

Fluent API를 통한 수동 트레이싱

보다 세밀한 제어가 필요한 경우, MLflow의 fluent API를 사용하여 코드를 수동으로 계측할 수 있습니다. 이 접근 방식을 사용하면 기존 코드를 최소한으로 변경하면서 상세한 트레이스 데이터를 캡처할 수 있습니다.

Trace 데코레이터

trace 데코레이터는 함수의 입력과 출력을 캡처합니다:
import mlflow

mlflow.set_experiment("Tracing Demo")

@mlflow.trace
def some_function(x, y, z=2):
    return x + (y - z)

some_function(2, 4)

컨텍스트 핸들러

import mlflow

@mlflow.trace
def first_func(x, y=2):
    return x + y

@mlflow.trace
def second_func(a, b=3):
    return a * b

def do_math(a, x, operation="add"):
    with mlflow.start_span(name="Math") as span:
        span.set_inputs({"a": a, "x": x})
        span.set_attributes({"mode": operation})
        first = first_func(x)
        second = second_func(a)
        result = first + second if operation == "add" else first - second
        span.set_outputs({"result": result})
        return result

do_math(8, 3, "add")

Client API를 통한 포괄적 트레이싱

고급 사용 사례의 경우, MLflow client API는 트레이스 관리에 대한 세밀한 제어를 제공합니다. 이 API를 사용하면 트레이스를 프로그래밍 방식으로 생성, 조작, 검색할 수 있으며, 구현 전반에 걸쳐 추가적인 복잡성을 감수해야 합니다.

Client API로 트레이스 시작 및 관리

from mlflow import MlflowClient

client = MlflowClient()

# 새 트레이스 시작
root_span = client.start_trace("my_trace")
request_id = root_span.request_id

# 자식 스팬 생성
child_span = client.start_span(
    name="child_span",
    request_id=request_id,
    parent_id=root_span.span_id,
    inputs={"input_key": "input_value"},
    attributes={"attribute_key": "attribute_value"},
)

# 자식 스팬 종료
client.end_span(
    request_id=child_span.request_id,
    span_id=child_span.span_id,
    outputs={"output_key": "output_value"},
    attributes={"custom_attribute": "value"},
)

# 루트 스팬(트레이스) 종료
client.end_trace(
    request_id=request_id,
    outputs={"final_output_key": "final_output_value"},
    attributes={"token_usage": "1174"},
)

트레이싱 심화

MLflow Tracing은 단순한 함수 트레이싱부터 복잡한 비동기 워크플로우에 이르기까지 다양한 사용 사례를 지원하도록 유연하고 강력하게 설계되었습니다. 가이드를 읽고, API 문서를 검토하고, 오늘 바로 LangChain 통합으로 시작해 보세요.

함께 해주세요

MLflow Tracing의 도입은 머신러닝 워크플로우를 관리하기 위한 포괄적인 도구를 제공하겠다는 우리의 미션에서 중요한 이정표입니다. 이 새로운 기능이 열어주는 가능성에 대해 기대하고 있으며, 여러분의 피드백과 기여를 기다립니다. 지식 공유에 열정을 가진 커뮤니티 분들을 초대합니다. 튜토리얼 작성, 사용 사례 공유, 피드백 제공 등 모든 기여가 MLflow 커뮤니티를 풍요롭게 합니다. 더 많은 업데이트를 기대해 주세요. 늘 그렇듯이, 즐거운 코딩 되세요!

참고 자료