1️⃣DSPy

DSPy 소개

DSPy는 특히 LM이 파이프라인 내에서 한 번 이상 사용되는 경우 LM 프롬프트와 가중치를 알고리즘적으로 최적화하기 위한 프레임워크입니다.

일반적인 LLM에서 프롬프트 최적화 단점

DSPy 없이 LM을 사용하여 복잡한 시스템을 구축하려면 일반적으로 다음과 같이 해야 합니다:

  1. 문제를 단계로 세분화하고

  2. 각 단계가 개별적으로 잘 작동할 때까지 LM을 잘 프롬프트하고

  3. 단계가 함께 잘 작동하도록 조정하고

  4. 합성 예제를 생성하여 각 단계를 조정하고

  5. 이러한 예제를 사용하여 작은 LM을 미세 조정하여 비용을 절감해야 합니다.

현재는 파이프라인, LM 또는 데이터를 변경할 때마다 모든 프롬프트(또는 미세 조정 단계)를 변경해야 하므로 어렵고 번거롭습니다.

DSPy 사용의 이점

이를 보다 체계적이고 훨씬 더 강력하게 만들기 위해 DSPy는 두 가지 작업을 수행합니다.

  1. 프로그램 (module)의 흐름과 각 단계의 매개변수(LM 프롬프트 및 가중치)를 분리합니다.

  2. DSPy는 최대화하려는 metric에 따라 LM 호출의 프롬프트 및/또는 가중치를 조정할 수 있는 LM 기반 알고리즘인 새로운 optimizer 도구를 도입합니다.

DSPy는 GPT-3.5 또는 GPT-4와 같은 강력한 모델과 T5-base 또는 Llama2-13b와 같은 로컬 모델을 일상적으로 학습하여 작업에서 훨씬 더 높은 품질을 갖거나 특정 실패 패턴을 피하는 등 훨씬 더 안정적인 작업을 수행할 수 있도록 합니다.

DSPy 옵티마이저는 동일한 프로그램을 각 LM에 대해 서로 다른 명령어, 짧은 프롬프트 및/또는 가중치 업데이트(미세 조정)로 '컴파일'합니다. 이는 데이터로부터 학습할 수 있는 더 큰 시스템의 최적화 가능한 부분으로서 LM과 그 프롬프트가 배경으로 사라지는 새로운 패러다임입니다. 프롬프트가 줄어들고 점수가 높아지며 LM으로 어려운 작업을 보다 체계적으로 해결할 수 있습니다.

Neural Netwoks와 같은 방식

신경망을 구축할 때는 수작업으로 튜닝한 플로트 목록 위에 수동으로 for-loop를 작성하지 않습니다. 대신 PyTorch와 같은 프레임워크를 사용하여 레이어(예: 컨볼루션 또는 드롭아웃)를 구성한 다음 최적화 도구(예: SGD 또는 Adam)를 사용하여 네트워크의 파라미터를 학습할 수 있습니다.

DSPy는 문자열 기반 프롬프트 트릭을 대체할 수 있는 적절한 범용 모듈(예: ChainOfThought, ReAct 등)을 제공합니다. 프롬프트 해킹과 일회성 합성 데이터 생성기를 대체하기 위해 DSPy는 프로그램에서 매개변수를 업데이트하는 알고리즘인 일반 최적화 도구(BootstrapFewShotWithRandomSearch 또는 MIPRO)도 제공합니다. 코드, 데이터, 어설션 또는 메트릭을 수정할 때마다 프로그램을 다시 컴파일하면 변경 사항에 맞는 새롭고 효과적인 프롬프트를 DSPy가 생성합니다.

DSPy와 LLM

"선언적 자기 개선 언어 프로그램"의 줄임말인 DSPy는 대규모 언어 모델(LLM) 과 검색 모델(RM)을 통합하여 복잡한 작업을 처리하는 데 앞장서고 있습니다.

스탠포드 NLP의 혁신적인 인재들이 개발한 DSPy는 "기초 모델을 사용한 프로그래밍"의 새로운 시대를 예고합니다. 이 프레임워크는 프로그래밍 중심 접근 방식을 강조함으로써 기존의 프롬프트 기법을 뛰어넘어 LM 기반 파이프라인 개발을 보다 체계적이고 효율적인 프로그래밍 패러다임으로 전환합니다.

DSPy의 signatures는 프로그래밍 우선 방법론을 옹호함으로써 LLM 기반 애플리케이션의 내재된 취약성을 해결하는 것입니다. 이러한 전환을 통해 전체 파이프라인을 당면한 작업의 미묘한 차이에 맞게 동적으로 재컴파일할 수 있으므로 지속적인 수동 프롬프트 조정이 필요하지 않습니다.

핵심 기능:

  • 시뮬레이션 및 명령어: DSPy는 주어진 입력에 대한 코드 실행을 꼼꼼하게 시뮬레이션하여 자동화된 컴파일러로 프로그램의 선언적 단계를 통해 LM을 안내합니다.

  • 파이토닉의 우아함: 컴포저블 및 선언적 모듈을 모두 제공하는 DSPy는 LM을 지시하는 데 익숙한 Python 구문을 도입하여 직관적이고 간소화된 프로그래밍 관행을 위한 기반을 마련합니다.

프로그래밍을 중시하는 사고방식을 함양 함으로써 DSPy는 기본 모델을 애플리케이션에 통합하는 작업을 간소화할 뿐만 아니라 LM 기반 솔루션의 적응성과 효율성을 크게 향상시킵니다.

DSPy는 GPT-3.5 또는 GPT-4와 같은 강력한 모델과 T5-base 또는 Llama2-13b와 같은 로컬 모델을 일상적으로 학습하여 작업에서 훨씬 더 높은 품질과 특정 장애 패턴을 피하는 등 훨씬 더 안정적인 작업을 수행할 수 있도록 합니다.

DSPy로 LM 기반 애플리케이션을 구축하는 워크플로우는 다음과 같습니다. 신경망을 훈련하는 워크플로우를 떠올리게 합니다:

DSPy로 LLM 기반 앱을 빌드하는 워크플로. 크레딧

  1. 데이터 세트 수집: 파이프라인을 개선하기 위해 다양한 입출력 예제(예: 질문-답변 쌍)를 수집합니다.

  2. DSPy 프로그램 개발: signaturesmodules을 사용해 프로그램의 논리를 만들고, 특정 작업을 처리하기 위한 정보의 흐름을 자세히 설명합니다.

  3. 유효성 검사 로직 설정: 유효성 검사 metric과 최적화 도구(teleprmpters)를 기반으로 프로그램을 개선하기 위한 기준을 만듭니다.

  4. DSPy로 컴파일하기: 훈련 데이터세트, 프로그램, 최적화 도구 및 유효성 검사 메트릭을 통합하여 프로그램을 개선(예: 신속한 최적화 또는 미세 조정을 통해)하는 DSPy 컴파일러를 활용하세요.

  5. 지속적으로 개선: 데이터 세트, 프로그램 또는 유효성 검사 로직을 개선하는 반복적인 주기에 참여하여 파이프라인의 원하는 성능 수준을 달성하세요.

DSPy 및 기타 프레임워크

대규모 언어 모델(LLM)로 작업하는 많은 사람들의 툴킷에서 LangChain과 LlamaIndex와 같은 혁신은 고유한 문제를 해결하고 모델 기능을 향상시키며 자리를 잡았습니다. 하지만 복잡한 로직이 포함된 작업을 탐색하거나 특정 요구에 맞게 모델을 사용자 정의하는 것은 여전히 어려운 과제일 수 있습니다.

LLM과 상호 작용하는 방식을 간소화하기 위한 새로운 접근 방식인 DSPy를 소개합니다. 프로그래밍 우선의 사고방식을 수용함으로써 DSPy는 기존에 복잡한 프롬프트 작성이나 집중적인 모델 조정이 필요했던 작업을 간소화하고자 합니다. 언어 모델로 구동되는 애플리케이션을 제작하는 편리한 조력자라고 생각하시면 됩니다.

LangChain은 복잡한 문제를 관리 가능한 덩어리로 분해하여 DSPy의 기능을 개선하는 구조화된 결과물을 생성하는 데 특화되어 있으며, 섬유를 더 정확하게 발견하는 것과 같은 까다로운 작업에 집중할 수 있습니다.

방대한 데이터 세트에서 정확한 정보를 선별하고 검색하는 기능을 강화하여 주목받는 LlamaIndex는 상세하고 정확한 데이터 탐색을 위해 언어 모델의 잠재력을 최대한 활용하고자 하는 사람들에게 없어서는 안 될 지원군이 될 것입니다.

반대로 DSPy는 수동 프롬프트 제작의 필요성을 줄임으로써 빛을 발합니다. 이 툴킷을 사용하면 모든 언어 모델을 특정 목표를 추적하도록 미세 조정할 수 있으므로 모델을 더욱 다양하게 활용하고 새로운 과제나 데이터 세트에 맞게 조정할 수 있습니다.

데이터 과학자가 신경망을 배치하고 레이어와 최적화 도구를 사용해 로직을 원활하게 내장하는 딥 러닝 분야의 확고한 선두주자인 PyTorch를 떠올리게 하는 것도 DSPy의 특징 중 하나입니다. ChainOfThought 또는 Retrieve와 같은 요소를 포함한 DSPy의 툴킷도 비슷한 방식으로 작동하며, 선택한 메트릭에 부합하도록 프롬프트를 조정하고 맞춤화합니다.

DSPy 프로그래밍 모델

DSPy는 언어 모델 애플리케이션의 효율성과 효과를 높이는 것을 목표로 하는 구조화된 프로그래밍 중심 접근 방식을 도입한 것이 핵심입니다. 다음은 DSPy 프로그래밍 모델의 세 가지 기본 구성 요소와 개발 프로세스를 혁신하는 방법에 대해 자세히 살펴봅니다:

  • Signatures: 프롬프트 추상화 및 미세 조정

  • Modules: 프롬프트 기술 추상화하기

  • Teleprompters: 임의의 파이프라인에 대한 프롬프트 자동화하기

Signatures

DSPy에서는 대규모 언어 모델(LLM)에 작업을 위임할 때 signatures이라고 하는 것을 통해 예상되는 동작의 개요를 설명합니다.

DSPy의 서명은 본질적으로 모듈의 예상 입력/출력 역학을 지정하는 컨트랙트입니다. 이는 작업에 사용할 특정 프롬프트를 지시하는 것에서 벗어나 LM이 달성해야 하는 것에 초점을 맞추고 있습니다.

함수 서명이 입력 및 출력 매개변수와 그 유형을 상세히 설명하는 방식으로 작동하는 것과 유사하게, DSPy 서명은 병렬 개념으로 작동하지만 몇 가지 주목할 만한 차이점이 있습니다:

  • 주로 매개변수를 설명하는 기존의 함수 서명과 달리, DSPy 서명은 모듈의 동작을 능동적으로 형성하고 관리합니다.

  • '질문'과 '답변' 또는 'sql_query'와 'python_code'와 같은 요소를 구분하여 의미적 역할을 명확하게 전달하기 때문에 DSPy 서명에 사용되는 용어가 매우 중요합니다.

DSPy 서명 활용의 가치

요약하자면: DSPy 서명을 활용하면 LM 상호 작용을 효과적인 프롬프트로 최적화하거나 자동 미세 조정을 용이하게 하는 모듈식 간소화 코드를 만들 수 있습니다.

세부적인 관점: 기존에는 정교하고 취약한 프롬프트 엔지니어링이나 미세 조정을 위한 특정 데이터 세트를 생성하여 LM에 작업을 부과했습니다. 서명을 작성하는 DSPy의 접근 방식은 보다 체계적이고 유연하며 반복 가능한 방법을 제공합니다. DSPy 컴파일러는 현재 사용 중인 데이터와 설정된 파이프라인을 기반으로 최적화된 프롬프트를 만들거나 윤곽이 잡힌 서명을 위해 특별히 LM을 미세 조정하는 작업을 수행합니다. 이 과정은 창의력이 아닌 광범위한 실험과 직접적인 메트릭 최적화를 통해 프롬프트 생성에서 인간의 능력을 뛰어넘는 경우가 많습니다.

DSPy 서명 구현하기

서명은 입력과 출력의 역할을 나타내는 명명된 인수를 사용하여 문자열로 간결하게 표현할 수 있습니다.

DSPy 서명은 수기로 작성하는 프롬프트를 대체합니다.

서명은 최소한의 형태로 된 입력 및 출력 필드의 튜플입니다.

최소 DSPy 서명의 구조

예를 들어

  • 질문 답변은 "question -> answer"으로 표현할 수 있습니다.

  • 감정 분류는 "sentence -> sentiment"으로 표현할 수 있습니다.

  • 요약은 "document -> summary"으로 표현할 수 있습니다.

또한 서명은 다음과 같은 여러 입력/출력을 수용할 수 있습니다:

  • 검색 증강 질문 답변:"context, question -> answer".

  • 추론을 통한 객관식 질문 답변:"question, choices -> reasoning, selection".

팁: 필드 이름을 지을 때는 의미론적으로 의미 있는지 확인하세요. 그러나 초기에는 단순함이 핵심이므로 조기에 용어를 지나치게 최적화하는 것은 피하세요. 요약의 경우 "document -> summary", ""text -> gist" 또는 "long_context -> tldr"과 같은 설명자는 충분히 명확합니다. DSPy 컴파일러는 LM과의 상호 작용을 최적화하기 위해 이러한 용어를 다듬는 데 능숙합니다.

예시: 요약


document = """이 21세 선수는 해머스에서 7경기에 출전했고 지난 시즌 안도란의 FC 루스트랭과의 유로파리그 예선 라운드 경기에서 팀의 유일한 골을 넣었습니다."""이 선수는 지난 시즌 해머스에서 7경기에 출전했고 유로파리그 예선 라운드 경기에서 팀의 유일한 골을 넣었습니다. 이승우는 지난 시즌 리그 1에서 블랙풀과 콜체스터 유나이티드에서 두 차례 임대를 경험했습니다. 그는 맨유에서 두 골을 넣었지만 강등을 막지 못했습니다. 승격된 타이크와 이승우의 계약 기간은 아직 공개되지 않았습니다. 모든 최신 축구 이적 소식은 전용 페이지에서 확인하세요.""" 

summarize = dspy.ChainOfThought('document -> summary')
response = summarize(document=document) 
print(response.summary)

출력:

21세의 이승우는 지난 시즌 웨스트햄에서 7경기에 출전해 1골을 넣었습니다. 리그 원에서는 블랙풀과 콜체스터 유나이티드에서 임대 생활을 하며 두 골을 넣었습니다. 현재 반슬리와 계약을 체결했지만 계약 기간은 공개되지 않았습니다.

많은 DSPy 모듈(dspy.Predict 제외)은 내부적으로 서명을 확장하여 보조 정보를 반환합니다.

예를 들어 ,dspy.ChainOfThought는 출력 요약을 생성하기 전에 LLM의 추론을 포함하는 근거 필드도 추가합니다.

print("Rationale:", response.rationale)

출력:

근거: 요약을 작성하세요. 이승우의 웨스트햄에서의 활약, 리그 원에서의 임대 생활, 반슬리와의 새로운 계약에 대한 핵심 사항을 강조해야 합니다. 또한 그의 계약 기간이 공개되지 않았다는 점도 언급해야 합니다.

SignatureOptimizer와 같은 DSPy의 일부 옵티마이저는 이 간단한 docstring 문자열을 가져와서 필요한 경우 더 효과적인 변형을 생성할 수 있습니다.

class Emotion(dspy.Signature): 
	"""슬픔, 기쁨, 사랑, 분노, 공포, 놀라움 중에서 감정을 분류합니다.""" 
	sentence = dspy.InputField() 
	sentiment = dspy.OutputField() 
	
sentence = "거대한 스포트라이트가 내 눈을 가리기 시작할 때 나는 조금 취약한 느낌을 받기 시작했습니다" # from dair-ai/emotion 

classify = dspy.Predict(Emotion) 
classify(sentence=sentence)

출력:

Prediction(sentiment='Fear')

Modules

DSPy 모듈은 LLM(대규모 언어 모델)을 활용하는 프로그램을 구성하기 위한 기본 구성 요소 역할을 합니다.

"당신의 임무는 ..." 또는 "당신은 ..."과 같은 문구로 프롬프트를 시작하거나 "단계별로 생각해 봅시다"와 같은 단서를 사용하여 연쇄적 사고 접근 방식을 사용하거나 "아무것도 지어내지 마세요" 또는 "주어진 맥락만 사용하세요"와 같은 지침으로 프롬프트를 마무리하는등 모델에게 메시지를 전달하는 다양한 기술에 대해 이미 알고 계실 것입니다.

DSPy 모듈은 이러한 프롬프트 전략을 캡슐화하기 위해 템플릿과 매개변수로 설계되었습니다. 기본적으로 프롬프트, 미세 조정, 증강 및 추론 방법을 적용하여 특정 작업에 맞게 DSPy 서명을 조정하는 역할을 합니다.

dspy.Predict 또는 dspy.ChainOfThought와 같은 사전 정의된 모듈을 어떻게 활용할 수 있나요?

다른 모든 DSPy 모듈의 기반이 되는 핵심 모듈인 dspy.Predict부터 시작하세요.

DSPy의 특정 모듈이 어떻게 동작해야 하는지를 간략하게 설명하는 선언인 [DSPy Signatures]에 대해 어느 정도 이해하고 있다고 가정합니다.모듈을 구현하려면 먼저 특정 서명으로 모듈을 정의합니다. 그런 다음 제공된 입력 인수를 사용하여 모듈을 실행한 다음 지정된 출력 필드에서 결과를 검색합니다.

sentence = "it's a charming and often affecting journey." 

# 1) Declare with a signature.
classify = dspy.Predict('sentence -> sentiment')

# 2) Call with input argument(s). 
response = classify(sentence=sentence)

# 3) Access the output.
print(response.sentiment)

출력:

Positive

모듈을 선언할 때 모듈에 구성 키를 전달할 수 있습니다.아래에서는 n=5를 전달하여 5개의 완성을 요청합니다. temperaturemax_len 등을 전달할 수도 있습니다.

dspy.ChainOfThought를 사용해 보겠습니다. 대부분의 경우 dspy.Predict 대신 dspy.ChainOfThought를 사용하면 품질이 향상됩니다.

question = "What's something great about the ColBERT retrieval model?"

# 1) Declare with a signature, and pass some config.
classify = dspy.ChainOfThought('question -> answer', n=5)

# 2) Call with input argument.
response = classify(question=question)

# 3) Access the outputs.
response.completions.answer

출력:

['콜버트 검색 모델의 가장 큰 장점은 다른 모델에 비해 효율성과 효과성이 뛰어나다는 점입니다, '대용량 문서 컬렉션에서 관련 정보를 효율적으로 검색할 수 있습니다.', '다른 모델에 비해 뛰어난 성능과 효과성, '콜버트 검색 모델의 장점은 다른 모델에 비해 성능이 뛰어나고 사전 학습된 언어 모델을 효율적으로 사용할 수 있다는 점입니다.', '콜버트 검색 모델의 장점은 다른 모델에 비해 성능이 뛰어나고 사전 학습된 언어 모델을 효율적으로 사용할 수 있다는 점입니다.', '콜버트 검색 모델의 장점은 다른 모델에 비해 효율성과 정확성이 뛰어나다는 점입니다.', '콜버트 검색 모델의 장점은 다른 모델에 비해 효율성과 정확성이 뛰어나다는 점입니다.', '콜버트 검색 모델의 한 가지 장점은 사용자 피드백을 통합하고 복잡한 쿼리를 지원하는 능력입니다.']

ChainOfThought module로 signature "context, question -> answer"의 초기 구현

추가로 어떤 DSPy 모듈이 존재하며 어떻게 활용되나요?

이 둘의 작동 방식은 매우 유사하며, 주로 서명을 구현하는 방식에서 차이가 있습니다!

  • dspy.Predict: 서명을 변경하지 않고 직접 활용하는 기본 예측 모듈입니다. 지침 저장, 데모, LM 업데이트와 같은 필수 학습 프로세스를 관리합니다.

  • dspy.ChainOfThought: 이 모듈은 LM이 서명과 일치하는 응답을 생성하기 전에 순차적이고 단계적인 방식으로 정보를 처리하도록 안내합니다.

  • dspy.ProgramOfThought: LM이 서명에 따라 응답을 결정하는 코드를 생성하도록 지시합니다.

  • dspy.ReAct: 지정된 서명의 요구 사항을 충족하기 위해 도구를 사용할 수 있는 에이전트 역할을 합니다.

  • dspy.MultiChainComparison: 이 모듈은 결정적인 예측에 도달하기 위해 ChainOfThought 프로세스의 여러 결과를 평가할 수 있습니다.

다음과 같은 기능을 닮은 모듈도 있습니다:

  • dspy.majority: 간단한 투표 메커니즘을 실행하여 예측 그룹에서 가장 일반적인 답변을 식별하고 반환합니다.

Optimizer(formely Teleprompters)

DSPy 최적화 프로그램은 정확도 등 지정된 메트릭을 향상시키기 위해 프롬프트와 언어 모델(LM) 가중치를 포함하여 DSPy 프로그램의 설정을 조정하도록 설계되었습니다.

DSPy에는 각각 다른 접근 방식을 사용하는 다양한 내장 옵티마이저가 있습니다. 기본적으로 DSPy 최적화 도구에는 세 가지 주요 구성 요소가 필요합니다:

  1. DSPy 프로그램: dspy.Predict와 같은 간단한 단일 모듈부터 여러 모듈이 함께 작동하는 보다 정교한 설정까지 다양합니다 .

  2. 선택한 메트릭: 점수를 할당하여 프로그램의 출력을 평가하는 함수로, 점수가 높을수록 더 나은 성능을 나타냅니다.

  3. 훈련 입력 세트: 불완전할 수 있는 적은 양(약 5~10개의 예제)이라도(해당 출력 없이 프로그램에 대한 입력으로만 구성) 충분할 수 있습니다.

DSPy는 제한된 데이터로 작업할 수 있기 때문에 작은 데이터 집합으로 시작해도 인상적인 결과를 얻을 수 있습니다. 그러나 더 큰 데이터 세트에 액세스할 수 있는 경우 DSPy는 이를 활용하여 더 나은 결과를 얻을 수 있습니다.

사용 가능한 모든 최적화 도구는 를통해 액세스할 수 있습니다:

dspy.teleprompt import *.

DSPy에서 사용 가능한 옵티마이저

DSPy 컴파일러

DSPy 컴파일러는 LM 유형에 따라 전략을 조정하여 품질 개선 또는 비용 절감과 같은 특정 메트릭에 맞게 프로그램을 최적화함으로써 프로그램의 효율성을 향상시킵니다:

  • LLM 용: 고품질의 작업별 몇 샷짜리 프롬프트를 생성합니다.

  • 소규모 LM 용: 정밀한 자동 미세 조정에 중점을 둡니다.

이 컴파일러는 프롬프트, 미세 조정, 추론 및 보강을 지능적으로 결합하여 프로그램 모듈을 개선합니다. 신경망 훈련과 유사한 지속적인 모듈 개선을 위해 이러한 인사이트를 사용하여 다양한 반복을 시뮬레이션합니다.

예를 들어, 초기 ChainOfThought 프롬프트는 모든 LM의 기본 작업 소개 역할을 하지만 최적이 아닐 수 있습니다. DSPy 컴파일러는 이러한 프롬프트를 미세 조정하여 수동 조정을 생략하고 적은 노력으로 프로그램 성능을 최적화합니다.

DSPy 컴파일러가 초기 프롬프트를 최적화하는 방법. 크레딧

DSPy를 사용한 멀티홉 질문 답변

문제 설명: 복잡한 QA(질문 답변) 작업의 영역에서는 단일 검색 쿼리에 의존하는 것이 부적절하다는 것이 종종 증명됩니다. 이러한 한계는 문학 작품을 기반으로 특정 인물의 출생지를 파악하는 것과 같이 다각적인 정보 검색이 필요한 경우 특히 두드러집니다. 예를 들어, '다시 시작'을 쓴 작가의 출생 도시를 찾아야 하는 경우, 간단한 검색 쿼리로 '제레미 맥키넌'을 작가로 정확히 찾아낼 수 있지만 이후 그의 출생지를 찾는 데는 실패할 수 있습니다.

이러한 복잡성을 해결하기 위해 검색 증강 자연어 처리(NLP) 분야에서는 GoldEn(Qi 외, 2019), Baleen(Khattab 외, 2021) 같은 혁신으로 대표되는 멀티홉 검색 시스템이 개발되고 있습니다.

전체 노트북은 여기에서액세스할 수 있습니다 .

DSPy 라이브러리 설치부터 시작하세요.

pip 설치 dspy-ai

이 사용 사례에서는 ChatGPT 3.5를 사용하겠습니다.

다음으로, 데이터 세트를 로드합니다. 일반적으로 멀티홉 방식으로 답변되는 복잡한 질문-답변 쌍의 모음인 HotPotQA 데이터 세트를 사용하겠습니다.

이제 서명을 작성합니다. 컨텍스트와 질문을 입력으로 받고 답변을 출력으로 제공하는 GenerateAnswer 서명을 만드는 것부터 시작하겠습니다.

이제 필요한 서명이 준비되었으니 파이프라인 구축을 시작할 수 있습니다!

보시다시피, init 메서드는 몇 가지 주요 하위 모듈을 정의합니다:

generate_query: 각 홉마다 GenerateSearchQuery 서명이 있는 dspy.ChainOfThought 예측자가 하나씩 있습니다.

retrieve: 이 모듈은 dspy.Retrieve 모듈을 통해 정의된 ColBERT RM 검색 인덱스에 대해 생성된 쿼리를 사용하여 검색을 수행합니다.

generate_answer: 이 dspy.Predict 모듈은 최종 답변을 생성하기 위해 GenerateAnswer 서명과 함께 사용됩니다.

포워드 방식은 이러한 하위 모듈을 간단한 제어 흐름에 사용합니다.

  • 먼저 self.max_hops까지 반복합니다.

  • 각 반복에서 self.generate_query[hop]의 예측자를 사용하여 검색 쿼리를 생성합니다.

  • 이 쿼리를 사용하여 상위 k개의 구절을 검색하겠습니다.

  • (중복 제거된) 구절을 컨텍스트 누적기에 추가합니다.

  • 루프가 끝나면 self.generate_answer를 사용해 답을 생성합니다.

  • 검색된 컨텍스트와 예상 답변이 포함된 예측을 반환합니다.

이 프로그램을 제로 샷(컴파일되지 않은 상태) 설정으로 실행해 보겠습니다.

이는 반드시 성능이 나쁘다는 것을 의미하는 것이 아니라 최소한의 지침으로 하위 작업을 이해하는 데 기본 LM의 신뢰성에 직접적으로 병목 현상이 발생한다는 의미입니다. 가장 쉽고 표준적인 작업(예: 인기 있는 엔터티에 대한 간단한 질문에 대한 답변)에 가장 비싸고 강력한 모델(예: GPT-4)을 사용할 때는 이러한 문제가 발생하지 않는 경우가 많습니다.

출력:

질문: 데이비드 그레고리가 물려받은 성의 층수는 몇 층인가요? 예상 답변: 검색된 문맥(잘린) 5개: ['데이비드 그레고리(의사) | 데이비드 그레고리(1625년 12월 20일 - 1720년)는 스코틀랜드의 의사이자 발명가였습니다. 그의 성은 스코틀랜드의 원래 철자인 그레고리로 표기되기도 합니다. 그는 킨을 물려받았다...', '세인트 그레고리 호텔 | 세인트 그레고리 호텔은 미국 워싱턴 D.C. 시내에 위치한 부티크 호텔입니다. 2000 년에 설립 된이 9 층짜리 호텔에는 54 개의 객실을 포함하여 155 개의 객실이 있습니다...', '칼 D. 그레고리 협동 조합 집 | 칼 D. 그레고리 협동 조합 집은 미시간 대학교의 협동 조합 협의회 회원입니다. 1617 Washtenaw에 서 있는 구조물은 기원...', '킨에어디 성 | 킨에어디 성은 스코틀랜드 애버딘셔 에버처더에서 남쪽으로 2마일 떨어진 5층과 가렛이 있는 타워 하우스입니다. 다른 이름은 올드 킨에어디....', '킨에어드 성, 브레친 | 킨에어드 성은 스코틀랜드 앵거스에 있는 15세기 성입니다. 이 성은 600년 이상 카네기 가문, 수테스크 백작의 고향이었어요....', 'Kinnaird Head | 킨에어드 헤드(스코틀랜드 게일어: "An Ceann Àrd", "높은 곶")는 스코틀랜드 동해안 애버딘셔의 프레이저버그 마을 내에 북해로 돌출된 곶이에요...']

그러나 제로 샷 접근 방식은 보다 전문적인 작업, 새로운 도메인/설정, 보다 효율적인(또는 개방형) 모델에는 금방 부족해집니다.

이 문제를 해결하기 위해 DSPy는 컴파일 기능을 제공합니다. 멀티홉(SimplifiedBaleen) 프로그램을 컴파일해 보겠습니다.

먼저 컴파일을 위한 유효성 검사 로직을 정의해 보겠습니다:

예측된 답이 정답과 일치합니다. 검색된 문맥에 정답이 포함되어 있습니다. 생성된 쿼리 중 래블링이 없는 경우(즉, 길이가 100자를 초과하는 쿼리가 없는 경우). 생성된 쿼리 중 대략적으로 반복되는 쿼리가 없습니다(즉, 이전 쿼리의 F1 점수가 0.8 이상인 쿼리가 없음).

DSPy에서 가장 기본적인 텔레프롬프터 중 하나인 BootstrapFewShot을사용하여 파이프라인의 예측자를 최적화하는 몇 가지 예시를 살펴보겠습니다.

이제 평가 함수를 정의하고 컴파일되지 않은 Baleen 파이프라인과 컴파일된 파이프라인의 성능을 비교해 보겠습니다. 이 데브셋은 완전히 신뢰할 수 있는 벤치마크는 아니지만 이 튜토리얼에 사용하는 데 도움이 됩니다.

출력:

결론

결론적으로, 이 글에서는 언어 모델 프롬프트와 가중치의 알고리즘 향상을 위한 최첨단 프레임워크인 DSPy에 대해 살펴보았습니다. 특히 검색 증강 생성(RAG) 작업에서 대규모 언어 모델(LLM) 애플리케이션을 혁신할 수 있는 잠재력을 강조하면서 DSPy의 기능에 대해 자세히 살펴봤습니다.

직관적인 Python 구문을 특징으로 하는 DSPy의 사용자 경험은 PyTorch를 사용하는 것과 유사합니다. 이 프로세스에는 훈련 데이터 세트 설정, 모델과 유사한 DSPy 프로그램 정의, 맞춤형 유효성 검사 로직 구현, 프로그램 컴파일, 지속적인 개선 및 개선 과정 등이 포함됩니다.

Reference

Last updated