Notice
Recent Posts
Recent Comments
Link
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Tags
more
Archives
Today
Total
관리 메뉴

archive

[기사 스크랩] 1년 동안 LLM과 함께 구축하며 배운 점 본문

ML_AI/AI Tool 정리

[기사 스크랩] 1년 동안 LLM과 함께 구축하며 배운 점

안정민 2024. 8. 13. 00:46

1년 동안 LLM과 함께 구축하며 배운 점 | GeekNews (hada.io)

 

1년 동안 LLM과 함께 구축하며 배운 점 | GeekNews

대규모 언어 모델(LLM)을 사용한 개발이 흥미로운 시기임지난 1년 동안 LLM이 실제 애플리케이션에 "충분히 좋은" 수준이 되었으며, 매년 더 좋아지고 저렴해지고 있음소셜 미디어의 데모와 함께,

news.hada.io

 

 


1. 전술적 관점 : LLM 사용의 핵심

(1) 전술 1 : 프롬프팅

 

기본 프롬프팅 기술을 최대한 활용하는 것에 집중

-> N-shot 프롬프트 + 문맥 내 학습, 사고의 연쇄, 관련 리소스 제공

전술 설명
N-shot Prompting
+
문맥 내 학습

● n-shot이란 n개의 예시를 프롬프트로 모델에게 전달하는 것을 의미

● zero shot은 모델에게 작업을 설명하고 아무런 예시를 제공하지 않아, 모델은 사전 훈련된 지식을 바탕으로 새로운 작업을 수행해야하는 것

● 반면 n-shot의 경우 모델에게 여러 예시를 제공하여 작업을 더 잘 이해할 수 있도록 하는 방식, 예시의 수는 일반적으로 적게 제공되며, 모델의 일반화 능력을 강조

ex)
문장이 긍정적인지 부정적인지 판단하세요:
예시: 1. '나는 이 영화가 좋았어요.' -> 긍정적 2. '이 음식은 별로였어요.' -> 부정적 3. '오늘 날씨가 좋네요.' -> 긍정적
문장: '내일도 날씨가 좋으면 좋겠어요.'

● N이 너무 낮으면 모델이 과적합되어 일반화 능력이 저하될 수 있음
● 경험적으로 N>=5 를 목표로 하고, 수십 개까지 사용되는 것을 두려워하지 말 것
● 예시는 예상되는 입력 분포를 대표해야 한다
● 전체 입출력 쌍을 제공할 필요는 없으며, 많은 경우 원하는 출력의 예시로 충분하다

사고의 연쇄
(Chain of Thought, CoT) 프롬프팅



● CoT 프롬프팅이란, LLM이 최종 답변을 반환하기 전에 사고 과정을 설명하도록 장려하는 것
● LLM에게 메모리에서 모든 것을 수행할 필요가 없도록 스케치 패드를 제공하는 것
● 원래의 접근 방식은 단순히 "단계별로 구현해보자"라는 문구를 지침의 일부로 추가하는 것 -> 구체화하게 됨
● 1~2 문장으로 구체성을 추가하면 환각 발생률이 상당히 감소하는 경우가 많음
● 그러나 최근에는 이 기술이 믿는 만큼 강력한 지에 대해 의문이 제기가 되고 있음
● 또한 CoT가 사용될 때 추론 중에 정확히 어떤 일이 일어나는 지에 대한 상당한 논쟁이 있음
그럼에도 불구하고 가능한 경우 실험해 볼만한 기술임

ex) 예시 프롬프트 :
철수가 가지고 있는 사과의 총 개수를 아래에 주어지는 단계에 따라 분석해 계산해 봅시다.

1. 철수는 처음에 12개의 사과를 가지고 있습니다.
2. 철수는 친구에게 4개의 사과를 줍니다. 
3. 남은 사과의 수는 12 - 4입니다.
4. 철수는 남은 사과의 절반을 먹습니다. 남은 사과의 수는 (12 - 4) / 2입니다.
5. 따라서 철수가 가지고 있는 사과의 수는 (12 - 4) - (12 - 4) / 2입니다.


ex) 예시 모델 답변
1. 처음에 철수는 12개의 사과를 가지고 있습니다.
2. 친구에게 4개의 사과를 주었으므로, 남은 사과는 12 - 4 = 8개입니다.
3. 남은 사과의 절반을 먹으므로, 8 / 2 = 4개를 먹습니다.
4. 따라서 철수가 가지고 있는 사과는 8 - 4 = 4개입니다.


관련 리소스 제공
● 관련 리소스 제공 == 모델 지식 기반 확장 & 환각 저하 & 사용자 신뢰 증가 를 불러오는 강력한 매커니즘

● RAG (검색 증강 생성, Retreival Augmented Generation) 를 통해 수행되는 경우가 많음

● 모델에 응답에 직접 활용할 수 있는 텍스트 스니펫을 제공하는 것은 필수적인 기술임

● 관련 리소스를 제공할 때는 단순히 포함시키는 것으로는 충분하지 않음
-모델에게 리소스 사용을 우선시하고, 직접 참조하며, 때로는 리소스가 충분하지 않을 때 언급하도록 지시하는 것을 잊지 말아야 함

●이는 에이전트 응답을 리소스 corpus에 Ground 하는 것에 큰 도움이 된다

 

  입력과 출력의 구조화

구조화 된 입력과 출력 → 모델이 입력을 더 잘 이해하고 다운스트림 시스템과 안정적으로 통합할 수 있는 출력을 반환

구분  설명
입력 구조화
 입력에 직렬화 형식을 추가

→ 컨텍스트와 토큰 간 관계
→ 특정 토큰에 대한 추가 메타 데이터 (유형 등) 또는 요청

등을 모델 학습 데이터에서 유사한 예시와 관련시키는 것에 도움이 될 수 있음

구조화 된 입력을 사용할 때는 각 LLM 제품군마다 선호하는 방식이 있다는 점에 유의

ex)
  • Claude는 <xml>을 선호하는 반면 GPT는 Markdown과 JSON을 선호함
  • XML을 사용하면 <response> 태그를 제공하여 Claude의 응답을 미리 채울 수도 있음
출력 구조화
 구조화 된 출력은 유사한 목적을 수행하지만, 시스템의 다운스트림 구성요소로의 통합을 단순화함

 

 

  작고 한 가지 일을 잘 하는 프롬프트를 만들 것

소프트웨어에서 흔한 안티패턴/코드스멜 은 모든 것을 수행하는 단일 클래스나 함수인 "God Object"이다.

이는 프롬프트에도 동일하게 적용된다

더보기

위 문장은 소프트웨어 개발에서 "God Object"가 문제를 일으키듯이, 프롬프트 설계에서도 비슷한 문제가 발생할 수 있음을 설명하고 있습니다. 이를 이해하기 위해 먼저 "God Object"와 그에 해당하는 프롬프트 설계 문제를 자세히 설명하겠습니다.

God Object란?

  • 정의: 소프트웨어 설계에서 "God Object"는 모든 기능과 책임을 한 곳에 집중시킨 단일 클래스나 객체를 의미합니다. 이 객체는 프로그램 내의 다양한 역할과 기능을 처리하려고 하며, 종종 지나치게 복잡하고 비대해집니다.
  • 문제점:
    1. 유지보수 어려움: 너무 많은 책임이 집중되어 있어 수정이나 기능 추가 시 코드의 다른 부분에 영향을 미칠 가능성이 큽니다.
    2. 재사용성 저하: 너무 구체적이고 많은 기능을 포함하고 있어, 다른 컨텍스트에서 재사용하기 어렵습니다.
    3. 이해의 어려움: 코드가 복잡해져 개발자가 전체 구조를 이해하고 작업하기 어렵습니다.

프롬프트에서의 God Object 문제

  • 프롬프트 설계에서의 적용: 프롬프트 설계에서도 "God Object"와 같은 문제가 발생할 수 있습니다. 이는 모든 것을 처리하려고 하는 복잡하고 포괄적인 프롬프트가 존재할 때 나타납니다.
  • 문제점:
    1. 비효율적인 추론: 너무 많은 정보를 한 번에 제공하면 모델이 중요 정보를 제대로 이해하지 못하고 비효율적으로 동작할 수 있습니다.
    2. 불명확한 지시: 프롬프트가 너무 복잡하거나 모호하면 모델이 정확한 요구사항을 이해하기 어려워져 잘못된 결과를 반환할 수 있습니다.
    3. 유연성 부족: 특정 상황에 맞춘 포괄적인 프롬프트는 다른 문제나 컨텍스트에 맞게 쉽게 수정되기 어렵습니다.

비유와 적용

  • 비유: "God Object"는 단일 클래스나 함수에 너무 많은 책임을 집중시키는 것이 문제인 것처럼, 프롬프트에서도 모든 것을 처리하려는 지나치게 복잡한 명령이나 지시가 문제를 일으킬 수 있습니다.
  • 적용: 프롬프트를 설계할 때도 단순화하고 구체적인 지시를 주어 모델이 쉽게 이해하고 작업할 수 있도록 해야 합니다. 각 프롬프트는 명확한 목적과 범위를 가져야 하며, 필요할 경우 여러 단계로 나누어 사고의 연쇄(CoT)를 적용하여 모델이 단계적으로 문제를 해결하도록 유도할 수 있습니다.

해결 방안

  1. 모듈화: 프롬프트를 단순화하고 특정한 목표에 맞게 모듈화하여 설계합니다. 이를 통해 각 프롬프트가 명확한 역할을 수행하게 할 수 있습니다.
  2. 단계적 접근: CoT를 활용하여 문제를 단계적으로 접근하게 합니다. 이를 통해 각 단계에서 명확한 중간 결과를 도출하고 전체 문제 해결 과정을 개선할 수 있습니다.
  3. 명확하고 간결한 지시: 각 프롬프트가 수행해야 할 작업을 명확하고 간결하게 작성하여 모델이 정확한 요구사항을 이해할 수 있도록 합니다.

위와 같은 설명을 통해 소프트웨어 설계의 "God Object" 문제와 프롬프트 설계에서의 유사한 문제를 이해하고, 이를 해결하기 위한 방법을 고려할 수 있습니다.

프롬프트는 일반적으로 간단하게 시작

- 몇 문장의 지침, 몇 가지 예시로 시작할 수 있음

- 그러나 성능을 개선하고 더 많은 edge case를 처리하려고 하면서 복잡성이 증가 ( 더 많은 지침과 다단계 추론, 수십 개의 예시가 추가)

-이렇게 된다면 일반적이고 직관적인 입력에 대한 성능이 오히려 저하됨 (GoDaddy는 이 문제를 LLM 구축에서 얻은 교훈 중 1위로 선정하였음)

 

-시스템과 코드를 단순하게 유지하려고 노력하는 것처럼, 프롬프트도 마찬가지

 

-결과적으로 단일 프롬프트를 여러 개의 단순하고 집중적이며 이해하기 쉬운 프롬프트로 분할

-이렇게 분할하면 각 프롬프트를 개별적으로 반복하고 평가할 수 있음

 

 

● 컨텍스트 토큰 만들기

에이전트에 실제로 전송해야 하는 컨텍스트의 양에 대한 가정을 재고하고 도전해야

모델에 전송되는 최종 프롬프트를 가지고 와서 모든 컨텍스트 구성, 메타 프롬프팅, RAG 결과와 함께 빈 페이지에 배치하고 읽어보는 것이 컨텍스트를 재고하는 것에 도움이 된다

→중복, 자가 모순적인 언어 및 형식이 잘못된 부분을 발견할 수 있음

 

 

(2) 전술 2: 정보 검색 / RAG

정보 검색 방법은 제공된 컨텍스트에 LLM을 ground 시키며 문맥 내 학습에 사용된다

이는 미세조정 파인튜닝보다 적은 노력과 비용이 들면서 성능을 개선할 수 있는 방법임

RAG는 검색된 문서의 관련성, 밀도 및 세부 정보 만큼만 좋음

 

  RAG 출력의 품질은 검색된 문서의 품질에 따라 달라지며, 몇 가지 요소를 고려할 수 있음

- 1. 관련성

일반적으로 "평균역순위(MRR)" 혹은 "정규화된 할인 누적 이득 (NDCG)"와 같은 순위 지표로 정량화

이들은 관련 문서를 더 높이, 관련 없는 문서를 더 낮게 순위를 매기는 시스템의 성능을 측정함

ex) 영화 리뷰 요약을 생성하기 위해 사용자 요약을 검색하는 경우, 특정 영화에 대한 리뷰를 더 높이 순위를 매기고 다른 영화에 대한 리뷰는 제외하는 것이 좋음

전통적인 추천 시스템과 마찬가지로 검색된 항목의 순위는 LLM이 다운스트림 작업을 수행하는 방식에 상당한 영향을 미침

영향을 측정하려면 검색된 항목을 섞은 상태에서 RAG 기반 작업을 실행해 보고, RAG 출력이 어떻게 수행이 되는 지 확인할 것

 

- 2. 정보 밀도

두 문서가 동일하게 관련된 경우, 더 간결하고, 관련 없는 세부 정보가 적은 문서를 선호해야 함

ex) 영화 대본과 모든 사용자 리뷰를 광범위한 의미에서 관련이 있다고 간주할 수 있음

 

- 3. 문서에 제공된 세부 정보 수준

 

 

●  키워드 검색을 잊지 말고, 기준선과 하이브리드 검색에 사용할 것

임베딩 기반 RAG 데모가 널리 퍼져 있기 때문에 정보 검색 분야의 수십년 간의 연구와 솔루션을 잊기 쉬움

→ 임베딩은 정말 강력한 도구이지만, 만능은 아니다

 

키워드 기반 검색의 장점

- 임베딩은 높은 수준의 의미론적 유사성을 포착하는 것에는 탁월하지만, 사용자가 이름, 두문자어, 또는 ID를 검색할 때와 같이 더 구체적이고 키워드 기반의 쿼리에는 어려움을 겪을 수 있음

 

 

●  새로운 지식에 대해서는 파인튜닝보다 RAG를 선호

RAG가 학습 중에 접한 지식과 완전히 새로운 지식 모두에 대해 파인튜닝보다 지속적으로 우수한 성능을 보였음

 

→지속적인 사전 학습니아 미세조정에 비해 검색 인덱스를 최신 상태로 유지하는 것이 더 쉽고 저렴

→검색 인덱스에 유해하거나 편향된 내용이 있는 경우 쉽게 삭제 및 수정이 가능함

→여러 조직을 위해 RAG 시스템을 호스팅하는 경우, 검색 인덱스를 분할하여 각 조직이 자체 인덱스의 문서만 검색할 수 있도록 할 수 있음 (한 조직의 정보를 실수로 다른 조직에 노출하지 않게 되어 보안에 대한 성능도 보장하게 됨)

 

 

장문 컨텍스트 모델이 RAG를 쓸모없게 만들지는 않을 것이다

Gemini 1.5가 최대 1000만 토큰 크기의 컨텍스트 윈도우를 제공하며 일부에서는 RAG의 미래에 의문을 제기

- 1000만 토큰 컨텍스트 윈도우는 기존 RAG 프레임워크 대부분을 불필요하게 만듦

- 데이터를 컨텍스트에 넣고 평소처럼 모델과 대화하기만 하면 된다

- 1000만 컨텍스트 가 RAG를 죽일 수도 있다는 것

 

그러나 !

→ 1000만 토큰의 컨텍스트 윈도우가 있더라도 모델에 입력할 정보를 선택하는 방법이 여전히 필요함

→ 좁은 바늘구멍 평가를 넘어서 모델이 그렇게 큰 컨텍스트에 대해 효과적으로 추론할 수 있다는 것을 아직 증명 X

→ 따라서 좋은 검색 없이는 주의를 분산시키는 정보로 모델을 압도하거나 무관한 정보로 컨텍스트 윈도우를 채울 위험이 있음

비용 문제가 존재

Transformer의 추론 비용은 컨텍스트 길이에 따라 제곱으로 증가

 

따라서 RAG는 컨텍스트 윈도우의 크기가 커질 수록 여전히 유용하게 작동할 것이기 때문에,

크기가 큰 컨텍스트 윈도우가 발명이 되었다 하더라도 RAG를 쓰레기통으로 가져가지 말자.

 

 

 

(3) 전술 3: 워크플로우 튜닝 및 최적화

LLM에 프롬프트를 주는 것은 시작에 불과함

LLM을 최대한 활용하려면 단일 프롬프트를 넘어 워크플로우를 수용해야함

ex) 복잡한 단일 작업을 여러 개의 더 간단한 작업으로 어떻게 분할할 수 있을까?

ex) 파인튜닝이나 캐싱이 성능 향상과 지연 및 비용 감소에 도움이 되는 시점은 언제인가?

**워크플로우 (Workflow)  란? 
LLM(대규모 언어 모델)을 효과적으로 활용하기 위한 일련의 작업 절차나 프로세스를 의미
LLM을 사용할 때 단순히 하나의 질문이나 요청을 던지는 것 이상으로, 여러 단계로 구성된 작업 흐름을 통해 더 복잡한 작업이나 프로젝트를 수행하는 것
워크플로우를 통해 LLM을 활용하면, 더 복잡하고 심층적인 작업을 수행 가능, 이는 단순히 하나의 질문에 대한 답변을 얻는 것을 넘어, 보다 체계적이고 연속적인 작업이 가능해짐을 의미

 

단계별 multiturn "Flow"는 큰 성능 향상을 제공 가능

하나의 큰 프롬프트를 여러 개의 작은 프롬프트로 분해함으로써 더 나은 결과를 얻을 수 있음이 증명되었음

ex) GPT-4 단일 프롬프트 → 다단계 워크 플로우 전환 : 19% 에서 44%로 정확도를 높임

 

워크플로우에는 다음이 포함된다

문제에 대한 숙고 공개테스트에 대한 추론 가능한 솔루션 생성
가능한 솔루션 순위 매기기 합성테스트 생성 공개 및 합성 테스트에 대한 솔루션 반복

 

** 명확한 목표를 가진 작은 작업은 최상의 에이전트 또는 흐름 프롬프트를 만든다 **

** LLM 에이전트란?

입력받은 정보를 바탕으로 작업을 수행하거나 결정을 내리는 자율적인 개체
  1. 가상 비서: Siri, Alexa, Google Assistant와 같은 가상 비서는 에이전트의 대표적인 예시입니다. 이들은 음성 명령을 이해하고, 자연어를 처리하며, 관련된 응답이나 행동을 제공합니다. 예를 들어, 사용자가 Alexa에게 좋아하는 노래를 재생해달라고 요청하면, 이를 처리하고 음악 스트리밍 서비스와 상호작용하여 노래를 재생합니다.
  2. 고객 지원 봇: 많은 기업들은 고객 문의를 처리하기 위해 채팅봇 형태의 에이전트를 사용합니다. 이 봇들은 고객의 질문을 이해하고 답변을 제공하며, 복잡한 문제는 인간 에이전트에게 전달할 수 있습니다. 예를 들어, 전자상거래 웹사이트의 고객 지원 봇은 사용자가 주문을 추적하고, 반품을 처리하며, 제품 관련 질문에 답변할 수 있도록 도와줍니다.
  3. 자동 콘텐츠 생성: 에이전트는 자율적으로 콘텐츠를 생성할 수도 있습니다. OpenAI의 GPT-3와 같은 도구는 사용자로부터 받은 프롬프트를 기반으로 기사, 코드, 심지어 시까지 작성할 수 있습니다. 이러한 에이전트는 LLM에 내장된 방대한 지식을 활용하여 인간의 글쓰기와 유사한 고품질의 콘텐츠를 생성합니다.
  4. 언어 번역: 번역 에이전트는 LLM을 사용하여 한 언어에서 다른 언어로 텍스트를 변환하며, 원래 의미를 유지합니다. Google 번역과 같은 서비스는 이러한 에이전트를 사용하여 실시간 번역을 제공하고, 다양한 언어 간의 의사소통을 용이하게 합니다.
  5. 개인화된 학습 도우미: 교육 기술 분야에서 에이전트는 개인화된 튜터 역할을 할 수 있으며, 학생 개개인의 학습 스타일과 속도에 맞춰 조정됩니다. 에이전트는 설명을 제공하고, 질문에 답하며, 학습을 강화하기 위해 퀴즈를 제공할 수 있습니다.
단순히 LLM API를 연결한 것이 아니라, CoT를 바탕으로 생각하고, 스스로 정답 여부도 체크하고, Guardrail 등의 기능을 활용하여 이상한 오답을 방지하고, tool을 호출할 줄도 아는 목적성 LLM

https://drfirst.tistory.com/entry/LLM-%EC%97%90%EC%9D%B4%EC%A0%84%ED%8A%B8llm-agent-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-%EC%BD%94%EB%93%9C%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-feat-prompt-engineering

 

 

시도해 볼 만한 워크플로우들

가능한한 엄격하게 지정된 명시적 계획 단계 미리 정의된 계획 중에서는 선택하는 것 (명시성) 을 고려할 것
원래 사용자 프롬프트를 에이전트 프롬프트로 다시 작성 이 과정에서는 정보 손실이 발생할 수 있으므로 주의해야함
선형 체인, DAG 및 상태 머신으로서의 에이전트 동작 다양한 종속성과 논리 관계는 서로 다른 규모에 더 적합하거나 덜 적합할 수 있음
다양한 작업 아키텍처에서 성능 최적화를 이끌어낼 수 있을까?
계획 검증 계획에는 최종 결과물이 잘 작동하도록 다른 에이전트의 응답을 평가하는 방법에 대한 지침을 포함할 수 있음
고정된 업스트림 상태로 프롬프트 엔지니어링 에이전트 프롬프트가 이전에 발생할 수 있는 다양한 변형에 대해 평가되는지 확인할 것

 

 

현재로써는 결정론적 워크플로우에 우선순위를 둘 것

LLM의 비결정론적 특성은 배포에 어려움을 준다

유망한 접근 방식은 "결정론적 계획은 생성하고, 이를 구조화되고 재현 가능한 방식으로 실행하는 에이전트 시스템"을 가지는 것이다.

즉, 첫 번째 단계에서는 상위수준의 목표나 프롬프트가 주어지면 에이전트가 계획을 생성하고, 그런 다음, 계획이 결정론적으로 실행, 이를 통해 각 단계를 보다 예측 가능하고 신뢰할 수 있게 만들 수 있음

 

이러한 접근 방식을 가지게 되면...

→ 생성된 계획은 에이전트에 프롬프트 제공, 미세조정을 위한 few-shot sample로 활용 가능

→ 시스템이 더 신뢰 가능해져서 테스트와 디버깅이 쉬워짐

→ 생성된 계획은 비순환 그래프 (DAG)로 표현될 수 있으며, 정적 프롬프트에 비해 이해하기 쉽고 적응력이 뛰어

 

결국 신뢰할 수 있고 작동하는 에이전트의 핵심은

보다 구조화되고 결정론적인 접근 방식을 채택하고

프롬프트를 개선하고 모델을 파인튜닝하기 위한 데이터를 수집하는 데에서 발견될 가능성이 높음

 

 

●  temperature 매개변수 이상의 다양한 출력 얻기

 

 

 

● 캐싱은 과소평가되고 있음

 

 

●  파인 튜닝이 필요한 시점

 

 

 

 

(4) 전술 4: 평가 및 모니터링

 

 

 

 

 


 

참고

https://www.comworld.co.kr/news/articleView.html?idxno=51174

 

 

'ML_AI > AI Tool 정리' 카테고리의 다른 글

torch.nn.Module  (0) 2024.11.15
[기사 스크랩] Grounding LLMs  (0) 2024.08.10
GGUF (Georgi Gerganov Unified Format)  (0) 2024.07.03
2024년 5월 중순 이후의 최신 LLM 모델 정리  (0) 2024.07.03
Langchain, LangServe  (0) 2024.07.03