AI 모델 및 플랫폼
MLflow를 사용한 대규모 언어 모델 추적: 완벽한 가이드
대규모 언어 모델(Large Language Models, LLM)이 복잡성과 규모가 증가함에 따라 성능, 실험, 배포를 추적하는 것이 점점 더 어려워지고 있습니다. 이것이 MLflow가 등장하는 곳입니다. MLflow는 기계 학습 모델의 전체 생명주기를 관리하는 포괄적인 플랫폼을 제공하며, LLM도 포함됩니다.
이 심층 가이드에서는 LLM을 추적, 평가, 배포하기 위해 MLflow를 활용하는 방법을 탐구할 것입니다. 환경 설정에서부터 고급 평가 기술까지, 코드 예제와 모범 사례를 포함하여 모든 것을 다룰 것입니다.
환경 설정
LLM을 MLflow로 추적하기 전에, 개발 환경을 설정해야 합니다. MLflow와 몇 가지 주요 라이브러리를 설치해야 합니다.
pip install mlflow>=2.8.1 pip install openai pip install chromadb==0.4.15 pip install langchain==0.0.348 pip install tiktoken pip install 'mlflow[genai]' pip install databricks-sdk --upgrade
설치 후, 모든 라이브러리가 올바르게 로드되었는지 확인하기 위해 Python 환경을 다시 시작하는 것이 좋습니다. Jupyter 노트북에서 다음을 사용할 수 있습니다.
import mlflow
import chromadb
<p>print(f"MLflow 버전: {mlflow.__version__}")
print(f"ChromaDB 버전: {chromadb.__version__}")
이것은 주요 라이브러리 버전을 확인합니다.
MLflow의 LLM 추적 기능 이해
MLflow의 LLM 추적 시스템은 기존 추적 기능을 확장하여 LLM의 고유한 측면을 위한 기능을 추가합니다. 주요 구성 요소를 분해해 보겠습니다.
실행 및 실험
MLflow에서 “실행”은 모델 코드의 단일 실행을 나타내며, “실험”은 관련된 실행의 모음입니다. LLM의 경우, 실행은 단일 쿼리 또는 모델에 의해 처리되는 일괄 처리된 프롬프트를 나타낼 수 있습니다.
추적의 핵심 구성 요소
- 매개변수: LLM의 입력 구성입니다. 예를 들어, 온도, top_k 또는 max_tokens와 같은 매개변수입니다.
mlflow.log_param()또는mlflow.log_params()를 사용하여 이러한 매개변수를 로깅할 수 있습니다. - 메트릭: LLM의 성능을 정량적으로 측정하는 값입니다. 예를 들어, 정확도, 대기 시간 또는 사용자 정의 점수와 같은 메트릭입니다.
mlflow.log_metric()또는mlflow.log_metrics()를 사용하여 이러한 메트릭을 추적할 수 있습니다. - 예측: LLM의 경우, 입력된 프롬프트와 모델의 출력을 모두 로깅하는 것이 중요합니다. MLflow는 이러한 값을 CSV 형식의 아티팩트로 저장합니다.
- 아티팩트: 실행과 관련된 추가 파일 또는 데이터입니다. 예를 들어, 모델 체크포인트, 시각화 또는 데이터셋 샘플입니다.
mlflow.log_artifact()를 사용하여 이러한 아티팩트를 저장할 수 있습니다.
LLM 실행을 로깅하는 기본 예를 살펴보겠습니다.
이 예제는 매개변수, 메트릭 및 입력/출력을 테이블 아티팩트로 로깅하는 것을示합니다.
import mlflow
import openai
<p>def query_llm(prompt, max_tokens=100):
response = openai.Completion.create(
engine="text-davinci-002",
prompt=prompt,
max_tokens=max_tokens
)
return response.choices[0].text.strip()</p>
<p>with mlflow.start_run():
prompt = "기계 학습의 개념을 간단하게 설명해 주세요."</p>
<p># 매개변수 로깅
mlflow.log_param("model", "text-davinci-002")
mlflow.log_param("max_tokens", 100)</p>
<p># LLM 쿼리 및 결과 로깅
result = query_llm(prompt)
mlflow.log_metric("response_length", len(result))</p>
<p># 프롬프트 및 응답 로깅
mlflow.log_table("prompt_responses", {"prompt": [prompt], "response": [result]})</p>
<p>print(f"응답: {result}")
MLflow를 사용한 LLM 배포
MLflow는 강력한 LLM 배포 기능을 제공하여 모델을 프로덕션 환경에서 제공하는 것을 쉽게합니다. MLflow의 배포 기능을 사용하여 LLM을 배포하는 방법을 살펴보겠습니다.
엔드포인트 생성
먼저, MLflow의 배포 클라이언트를 사용하여 LLM에 대한 엔드포인트를 생성합니다.
import mlflow
from mlflow.deployments import get_deploy_client
<p># 배포 클라이언트 초기화
client = get_deploy_client("databricks")</p>
<p># 엔드포인트 구성 정의
endpoint_name = "llm-endpoint"
endpoint_config = {
"served_entities": [{
"name": "gpt-model",
"external_model": {
"name": "gpt-3.5-turbo",
"provider": "openai",
"task": "llm/v1/completions",
"openai_config": {
"openai_api_type": "azure",
"openai_api_key": "{{secrets/scope/openai_api_key}}",
"openai_api_base": "{{secrets/scope/openai_api_base}}",
"openai_deployment_name": "gpt-35-turbo",
"openai_api_version": "2023-05-15",
},
},
}],
}</p>
<p># 엔드포인트 생성
client.create_endpoint(name=endpoint_name, config=endpoint_config)
이 코드는 Azure OpenAI를 사용하는 GPT-3.5-turbo 모델에 대한 엔드포인트를 설정합니다. Databricks 시크릿을 사용한 보안 API 키 관리를 주목하세요.
엔드포인트 테스트
엔드포인트가 생성되면 테스트할 수 있습니다.
<div class="relative flex flex-col rounded-lg">
<p>response = client.predict(
endpoint=endpoint_name,
inputs={"prompt": "신경망의 개념을 간단하게 설명해 주세요.", "max_tokens": 100,}
)</p>
print(response)
이것은 배포된 모델에 프롬프트를 보내고 생성된 응답을 반환합니다.
MLflow를 사용한 LLM 평가
평가는 LLM의 성능과 동작을 이해하는 데 중요합니다. MLflow는 내장 및 사용자 정의 메트릭을 포함하여 LLM을 평가하기 위한 포괄적인 도구를 제공합니다.
LLM 평가를 위한 준비
LLM을 mlflow.evaluate()로 평가하려면, 모델이 다음 형식 중 하나여야 합니다.
- MLflow pyfunc 모델 인스턴스 또는_logged MLflow 모델을 가리키는 URI
- 입력 문자열을 받아 단일 문자열을 반환하는 Python 함수
- MLflow 배포 엔드포인트 URI
- 모델=None으로 설정하고 평가 데이터에 모델 출력을 포함
logged MLflow 모델을 사용하는 예를 살펴보겠습니다.
import mlflow
import openai
<p>with mlflow.start_run():
system_prompt = "다음 질문에 간단하게 대답해 주세요."
logged_model_info = mlflow.openai.log_model(
model="gpt-3.5-turbo",
task=openai.chat.completions,
artifact_path="model",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": "{question}"},
],
)</p>
<p># 평가 데이터 준비
eval_data = pd.DataFrame({
"question": ["기계 학습이 무엇인가요?", "신경망을 설명해 주세요."],
"ground_truth": [
"기계 학습은 명시적인 프로그래밍 없이 경험에서 학습하고 개선할 수 있는 인공 지능의 하위 집합입니다.",
"신경망은 생물학적 신경망에서 영감을 받은 컴퓨팅 시스템으로, 정보를 처리하고 전달하는 상호 연결된 노드로 구성됩니다.",
]
})</p>
<p># 모델 평가
results = mlflow.evaluate(
logged_model_info.model_uri,
eval_data,
targets="ground_truth",
model_type="question-answering",
)</p>
<p>print(f"평가 메트릭: {results.metrics}")
이 예제는 OpenAI 모델을 로깅하고, 평가 데이터를 준비하고, MLflow의 내장 메트릭을 사용하여 질문-답변 작업을 평가합니다.
사용자 정의 평가 메트릭
MLflow는 사용자 정의 메트릭을 정의하여 LLM을 평가할 수 있습니다. 응답의 전문성을 평가하는 사용자 정의 메트릭을 생성하는 예를 살펴보겠습니다.
from mlflow.metrics.genai import EvaluationExample, make_genai_metric
<p>professionalism = make_genai_metric(
name="professionalism",
definition="공식적이고 적절한 의사소통 스타일의 척도.",
grading_prompt=(
"답변의 전문성을 0-4의 척도에서 평가해 주세요.\n"
"0: 매우 캐주얼 또는 부적절\n"
"1: 캐주얼하지만 존중\n"
"2: 중간 정도 공식적\n"
"3: 전문적이고 적절\n"
"4: 매우 공식적이고 전문적"
),
examples=[
EvaluationExample(
input="기계 학습이 무엇인가요?",
output="기계 학습은 인공 지능의 하위 집합으로, 명시적인 프로그래밍 없이 경험에서 학습하고 개선할 수 있습니다.",
score=4,
justification="답변은 공식적이고 전문적입니다.",
),
],
model="openai:/gpt-3.5-turbo-16k",
parameters={"temperature": 0.0},
aggregations=["mean", "variance"],
greater_is_better=True,
)</p>
<p># 사용자 정의 메트릭을 평가에 사용
results = mlflow.evaluate(
logged_model_info.model_uri,
eval_data,
targets="ground_truth",
model_type="question-answering",
extra_metrics=[professionalism]
)</p>
<p>print(f"전문성 점수: {results.metrics['professionalism_mean']}")
이 사용자 정의 메트릭은 GPT-3.5-turbo를 사용하여 응답의 전문성을 평가합니다. 이는 LLM 자체를 평가에 사용하는 방법을 보여줍니다.
고급 LLM 평가 기술
LLM이 더 복잡해짐에 따라, 평가 기술도 더 복잡해지고 있습니다. MLflow를 사용하여 고급 평가 방법을 살펴보겠습니다.
검색-증강 생성(RAG) 평가
RAG 시스템은 검색 기반 및 생성 모델의 강점을 결합합니다. RAG 시스템을 평가하려면 검색 및 생성 구성 요소를 모두 평가해야 합니다. MLflow를 사용하여 RAG 시스템을 설정하고 평가하는 방법을 살펴보겠습니다.
from langchain.document_loaders import WebBaseLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI
<p># 문서 로드 및 전처리
loader = WebBaseLoader(["https://mlflow.org/docs/latest/index.html"])
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)</p>
<p># 벡터 저장소 생성
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(texts, embeddings)</p>
<p># RAG 체인 생성
llm = OpenAI(temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vectorstore.as_retriever(),
return_source_documents=True
)</p>
<p># 평가 함수
def evaluate_rag(question):
result = qa_chain({"query": question})
return result["result"], [doc.page_content for doc in result["source_documents"]]</p>
<p># 평가 데이터 준비
eval_questions = [
"기계 학습이 무엇인가요?",
"기계 학습의 주요 구성 요소는 무엇인가요?",
"신경망을 설명해 주세요.",
]</p>
<p># MLflow로 평가
with mlflow.start_run():
for question in eval_questions:
answer, sources = evaluate_rag(question)</p>
<p>mlflow.log_param(f"question", question)
mlflow.log_metric("num_sources", len(sources))
mlflow.log_text(answer, f"answer_{question}.txt")</p>
<p>for i, source in enumerate(sources):
mlflow.log_text(source, f"source_{question}_{i}.txt")</p>
<p># 사용자 정의 메트릭 로깅
mlflow.log_metric("avg_sources_per_question", sum(len(evaluate_rag(q)[1]) for q in eval_questions) / len(eval_questions))
이 예제는 LangChain과 Chroma를 사용하여 RAG 시스템을 설정하고, MLflow로 평가합니다.
문서 분할 전략 평가
문서를 분할하는 방법은 RAG 성능에 크게 영향을 미칠 수 있습니다. MLflow를 사용하여 다양한 문서 분할 전략을 평가하는 방법을 살펴보겠습니다.
import mlflow
from langchain.text_splitter import CharacterTextSplitter, TokenTextSplitter
<p>def evaluate_chunking_strategy(documents, chunk_size, chunk_overlap, splitter_class):
splitter = splitter_class(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
chunks = splitter.split_documents(documents)</p>
<p>with mlflow.start_run():
mlflow.log_param("chunk_size", chunk_size)
mlflow.log_param("chunk_overlap", chunk_overlap)
mlflow.log_param("splitter_class", splitter_class.__name__)</p>
<p>mlflow.log_metric("num_chunks", len(chunks))
mlflow.log_metric("avg_chunk_length", sum(len(chunk.page_content) for chunk in chunks) / len(chunks))</p>
<p># 검색 성능 평가(간소화)
correct_retrievals = sum(1 for _ in range(100) if simulate_retrieval(chunks))
mlflow.log_metric("retrieval_accuracy", correct_retrievals / 100)</p>
<p># 다양한 전략 평가
for chunk_size in [500, 1000, 1500]:
for chunk_overlap in [0, 50, 100]:
for splitter_class in [CharacterTextSplitter, TokenTextSplitter]:
evaluate_chunking_strategy(documents, chunk_size, chunk_overlap, splitter_class)</p>
<p># 결과 비교
best_run = mlflow.search_runs(order_by=["metrics.retrieval_accuracy DESC"]).iloc[0]
print(f"최적의 분할 전략: {best_run['params.splitter_class']} with size {best_run['params.chunk_size']} and overlap {best_run['params.chunk_overlap']}")
이 스크립트는 다양한 분할 크기, 중복 및 분할 방법의 조합을 평가하고, 결과를 MLflow로 로깅하여 쉽게 비교할 수 있습니다.
LLM 평가 결과 시각화
MLflow는 다양한 방법으로 LLM 평가 결과를 시각화할 수 있습니다. 다음은 몇 가지 기술입니다.
MLflow UI 사용
평가를 실행한 후, MLflow UI를 사용하여 결과를 시각화할 수 있습니다.
- MLflow UI 시작:
mlflow ui - 웹 브라우저에서
http://localhost:5000으로 이동 - 실험과 실행을 선택하여 메트릭, 매개변수 및 아티팩트를 xem
사용자 정의 시각화
Matplotlib 또는 Plotly와 같은 라이브러리를 사용하여 평가 결과의 사용자 정의 시각화를 생성할 수 있습니다. 그런 다음 이러한 시각화를 아티팩트로 로깅할 수 있습니다.
import matplotlib.pyplot as plt
import mlflow
<p>def plot_metric_comparison(metric_name, run_ids):
plt.figure(figsize=(10, 6))
for run_id in run_ids:
run = mlflow.get_run(run_id)
metric_values = mlflow.get_metric_history(run_id, metric_name)
plt.plot([m.step for m in metric_values], [m.value for m in metric_values], label=run.data.tags.get("mlflow.runName", run_id))</p>
<p>plt.title(f"{metric_name} 비교")
plt.xlabel("단계")
plt.ylabel(metric_name)
plt.legend()</p>
<p># 플롯 저장 및 로깅
plt.savefig(f"{metric_name}_comparison.png")
mlflow.log_artifact(f"{metric_name}_comparison.png")</p>
<p># 사용법
with mlflow.start_run():
plot_metric_comparison("answer_relevance", ["run_id_1", "run_id_2", "run_id_3"])
이 함수는 특정 메트릭을 여러 실행에 걸쳐 비교하는 선 그래프를 생성하고, 이를 아티팩트로 로깅합니다.














