주요 컨텐츠로 이동

Databricks LLM 파이프라인을 DSPy로 최적화하기


이 포스트 공유하기
DSPY Header Image

지난 한 해 동안 산업 등급의 LLM 기술 세계를 지켜보셨다면 프로덕션에서 수많은 프레임워크와 도구가 사용되고 있는 것을 보셨을 것입니다. 스타트업들은 검색 증강 생성 (RAG) 자동화부터 맞춤형 미세 조정 서비스까지 모든 것을 구축하고 있습니다. 2023년 봄부터 체인화된 언어 모델 컴포넌트의 프로토타입을 쉽게 제작할 수 있게 해주는 Langchain은 이러한 새로운 프레임워크 중 가장 유명한 프레임워크일 것입니다. 하지만 최근의 중요한 발전은 스타트업이 아닌 학계에서 이루어졌습니다.

2023년 10월, 공동 창업자 Matei Zaharia의 스탠포드 연구실(Databricks) 에서 일하는 연구원들은 선언적 언어 모델 호출을 자체 개선 파이프라인으로 컴파일하는 라이브러리인DSPy를 출시했습니다 . DSPy의 핵심 구성 요소는 자체 개선 파이프라인입니다. 예를 들어 ChatGPT는 단일 입출력 인터페이스로 보이지만, 내부에서는 LLM 호출이 한 번만 발생하는 것이 아닙니다. 대신 이 모델은 다단계 파이프라인에서 사용자 지정 문서 업로드의 웹 브라우징이나 RAG와 같은 외부 도구와 상호 작용합니다. 이러한 도구는 초기 입력과 결합하여 최종 답변을 생성하는 중간 출력을 생성합니다. 데이터 파이프라인과 머신 러닝 모델이 MLOps 의 출현으로 이어진 것처럼, LLMOps는 DSPy의 프레임워크인 LLM 파이프라인과 DBRX와 같은 기초 모델에 의해 형성되고 있습니다.

 

DSPy파이프라인 다이어그램
Figure 1: DSPy self-improving pipeline workflow

DSPy가 진정으로 빛을 발하는 부분은 바로 이러한 파이프라인의 자체 개선입니다. 복잡한 다단계 LLM 파이프라인에서는 튜닝이 필요한 프롬프트가 여러 개 있는 경우가 많습니다. 대부분의 업계 LLM 개발자는 프롬프트의 한 단어가 배포의 성패를 좌우할 수 있다는 사실을 너무나 잘 알고 있습니다 (그림 1). JetBlue는 DSPy를 통해 수동 프롬프트 튜닝을 과거의 일로 만들고 있습니다.

이 블로그 게시물에서는 DSPy에서 쉽게 사용할 수 있는 모델을 사용하여 사용자 정의 멀티툴 LLM 에이전트를 구축하는 방법과 Databricks Marketplace 모델을 사용하여 맞춤형 멀티툴 Databricks 에이전트를 구축하는 방법과 결과 체인을 모델 서빙에 배포하는 방법에 대해 설명합니다. 이 엔드투엔드 프레임워크를 통해 JetBlue는 수익을 창출하는 고객 피드백 분류부터 운영 효율성을 강화하는 RAG 기반 예측 유지보수 챗봇에 이르기까지 최첨단 LLM 솔루션을 신속하게 개발할 수 있었습니다. 

prompt_template = "" " JSON으로만 응답합니다. 어떠한 경우에도 대화 내용을 반환하지 마십시오 TEXT. 내 경력은 여기에 달렸으니 완벽한 답을 주면 100달러 팁을 드릴게요. 예시 : {'output_var1': 'value1', 'output_var2': 'value2'} new JSON output: """


llm = Databricks(host="myworkspace.cloud.databricks.com", endpoint_name="datbaricks-dbrx-instruct")


초기화_에이전트(
       에이전트='채팅-대화형-반응-설명',
       llm=llm,
       시스템에이전트프롬프트템플릿=프롬프트템플릿)

그림 2: DSPy 이전의 일반적인 프롬프트 엔지니어링 방법론

 

DSPy 서명 및 모듈

모든 맞춤형 DSPy 모델 뒤에는 사용자 지정 시그니처와 모듈이 있습니다. 서명을 파이프라인에서 사용자 정의된 단일 LLM 호출로 생각하면 됩니다. 일반적인 첫 번째 서명은 사전 정의된 컨텍스트를 사용하여 초기 사용자 질문을 쿼리로 재포맷하는 것입니다. 한 줄로 구성할 수 있습니다: dspy.ChainOfThought("context, question -> query"). 조금 더 제어하기 위해 이 컴포넌트를 파이토닉 클래스로 정의할 수 있습니다 (그림 2). 사용자 정의 서명을 작성하는데 익숙해지면 세상은 온통 당신의 오이스터가 될것입니다.

ToolChoice(dspy.Signature) 클래스:
  """쿼리를 기반으로 도구 목록에서 선택할 도구를 결정합니다."""


   list_of_tools = dspy.InputField(desc="에이전트가 사용할 수 있는 도구 목록")
   query = dspy.InputField()
   selected_tool = dspy.OutputField(desc="목록_of_tools 입력의 쿼리를 기반으로 단일 도구를 반환")
GenerateAnswer(dspy.Signature) 클래스:
  """사용자의 질문에 대한 답변의 정보 요약으로 질문에 답합니다."""


   context = dspy.InputField(desc="관련 사실을 포함할 수 있음")
   question = dspy.InputField()
   answer = dspy.OutputField(desc="사용자 질문에 대한 답변에 대한 정보 요약")

그림 3: DSPy 파이프라인의 시작 부분에서 도구를 선택하고 마지막에 최종 답변을 생성하기 위한 설명이 포함된 사용자 정의 서명

 

그런 다음 이러한 서명은 PyTorch와 유사한 모듈로 구성됩니다 (그림 3). 각 서명은 모델의 포워드 메서드 내에서 한 단계에서 다음 단계로 순차적으로 입력을 전달하는 방식으로 액세스됩니다. 이는 LLM이 아닌 호출 메서드나 제어 로직에 산재할 수 있습니다. DSPy 모듈을 사용하면 더 나은 제어, 동적 업데이트 및 비용을 위해 LLMOps를 최적화할 수 있습니다. 불투명한 에이전트에 의존하는 대신 내부 구성 요소를 모듈화하여 각 단계를 명확하게 파악하고 평가 및 수정할 수 있습니다. 이 경우 사용자 입력에서 생성된 쿼리를 가져오고, 적절한 경우 벡터 저장소를 사용하도록 선택한 다음, 검색된 컨텍스트에서 답변을 생성합니다.

도구 리트리버(dspy.Module) 클래스:
   def __init__(self):
       self.generate_query = dspy.ChainOfThought("컨텍스트, 질문 -> 쿼리")
       self.choose_tool = dspy.ChainOfThought(ToolChoice)
       self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
       self.tools = "[answer_payroll_faq, irrelevant_content]"


   def irrelevant_content(self):
       return "다른 것을 물어보세요."


   def forward(self, question):
       client = OpenAI(api_key=openai_api_key)
       retrieve = 데이터브릭스RM()


       context = []
       query_output = self.generate_query(context = 컨텍스트, 질문=질문)
       tool_choice = self.choose_tool(list_of_tools=self.tools, 쿼리 = 쿼리_출력.쿼리)


       if tool_choice.selected_tool == "irrelevant_content":
           반환 self.irrelevant_content()      
       else:
           search_query_embedding = client.embeddings.create(model="text-embedding-ada-002", 입력=[질문]).데이터[0].임베딩
           retrieved_context = retrieve(search_query_embedding, 1)


           context += retrieved_context
           return self.generate_answer(context=context, 질문=질문)

그림 4: DSPy 서명은 PyTorch-같은 모듈을 통해 파이프라인으로 구성됩니다.

에이전트 배포

로깅 및 배포를 위한 표준 절차를 따를 수 MLflow 있습니다. PyFunc 모델을 로깅하고 배포하는 Databricks Marketplace Llama Databricks 표준 절차를 따를 수 있습니다. PyFunc 모델 내에서 2 70B와 같은 모델을 사용하도록 DSPy를 쉽게 설정할 수 있습니다. 참고로 모델 DataFrame 서빙은 형식을 기대하는 반면, DSPy는 문자열로 작업한다는 점에 유의해야 합니다. 따라서 표준 예측 및 실행 함수를 다음과 같이 수정하겠습니다:

def predict(self, context, model_input):
       outputs = []
       outputs = self.run(model_input.values[0][0])
       반환 출력
  
def run(self, prompt):
       output = self.dspy_lm(prompt)
       반환 pd.DataFrame([output.answer])

그림 5: DSPy와 MLflow 간 변환에 필요한 PyFunc 모델 서비스 정의 수정

 

모델은 mlflow.pyfunc.log_model 함수를 사용하여 생성되며 ,이 Databricks 튜토리얼에 설명된 단계에 따라 JetBlue의 내부 서비스 엔드포인트 중 하나에 배포됩니다 . Databricks (그림 5)를 통해 엔드포인트를 쿼리하거나 API 을 통해 엔드포인트를 호출하여 챗봇용 애플리케이션 계층을 통해 API 엔드포인트를 호출하는 방법을 확인할 수 있습니다. RAG 챗봇 배포는 Langchain 배포보다 2배 더 빨랐습니다!

그림 5. 배포된 엔드포인트를 통해 쿼리를 실행하여 벡터 데이터베이스에서 결과를 반환합니다.
Figure 6: Running a query through our deployed endpoint, returning results from a vector database

 

파이프라인 자체 개선

JetBlue의 RAG 챗봇 사용 사례에는 검색 품질 및 답변 품질과 관련된 메트릭이 있습니다. DSPy 이전에는 이러한 지표를 개선하기 위해 프롬프트를 수동으로 최적화했지만, 이제는 DSPy를 사용하여 이러한 지표를 직접 최적화하고 자동으로 품질을 개선할 수 있습니다. 이를 이해하는 핵심은 파이프라인의 자연어 구성 요소를 조정 가능한 매개변수로 생각하는 것입니다. DSPy 최적화 도구는 작업 목표를 향해 최대화하여 이러한 가중치를 조정하며, 정의된 메트릭 (예: 독성을 평가하는 LLM), 일부 레이블이 지정되거나 지정되지 않은 데이터, 최적화할 DSPy 프로그램만 있으면 됩니다. 그런 다음 옵티마이저는 프로그램을 시뮬레이션하고 '최적' 예시를 결정하여 LM 가중치를 조정하고 다운스트림 메트릭의 성능 품질을 개선합니다. DSPy는 시그니처 옵티마이저 뿐 만 아니라 프롬프트의 일부로 모델에 최적화된 예제를 제공하는 여러 컨텍스트 내 학습 옵티마이저를 제공합니다. DSPy는 상황에 따라 사용할 예제를 효과적으로 선택하여 LLM의 응답의 신뢰성과 품질을 향상시킵니다. 이제 Databricks 모델 서빙 재단 모델 API 및 Databricks Vector Search 에 DSPy가 통합되어 사용자는 Databricks 워크플로 내에서 DSPy 프롬프트 시스템을 만들고 데이터와 작업을 최적화할 수 있습니다. 

또한 이러한 기능은 Databricks' LLM-as-a-judge 제품을 보완합니다. 사용자 지정 측정지표는 LLM-as-a-judge를 사용하여 설계할 수 있으며, DSPy의 최적화 도구를 사용하여 직접 개선할 수 있습니다. LLM-생성된 피드백을 사용하여 Databricks 에서 다단계 DSPy 파이프라인을 미세 조정하는 고객 피드백 분류와 같은 추가 사용 사례도 있습니다. 이를 통해 모든 LLM 애플리케이션의 반복 개발 프로세스가 대폭 간소화되어 프롬프트를 수동으로 반복할 필요가 없어집니다. 

프롬프트의 끝, 복합 시스템의 시작

점점 더 많은 기업이 LLM을 활용함에 따라 일반적인 챗봇 인터페이스의 한계가 점점 더 명확해지고 있습니다. 이러한 상용 플랫폼은 최종 사용자와 관리자가 통제할 수 없는 매개변수에 크게 의존합니다. LLM 호출과 기존 소프트웨어 개발을 LLM 결합 한 Databricks LLM 복합 시스템을 구축함으로써 기업은 이러한 솔루션을 사용 사례에 맞게 쉽게 조정하고 최적화할 수 있습니다. DSPy는 모든 지표에 대해 최적화할 수 있는 신뢰할 수 있는 모듈식 시스템으로 이러한 패러다임 전환을 가능하게 합니다. JetBlue는 및 DSPy의 강력한 기능을 통해 더 나은 솔루션을 대규모로 배포하고 가능성의 한계를 뛰어넘을 수 있습니다.

그림 6. Databricks' 솔루션을 사용하여 JetBlue의 완벽한 챗봇 아키텍처는 다양한 사용자 그룹과 함께 사용자 지정 문서 업로드를 활용합니다.
Figure 7: Using Databricks’ solutions, JetBlue’s complete chatbot architecture makes use of custom document uploads with different user groups