티스토리 뷰
1. 개요
FLOWBIT 서비스에 LLM이 필요하다는 결론을 내리고 Groq라는 구세주를 만났다. 사용 모델을 llama3으로 확정한 후 테스트를 위해 모델에 여러 질문을 해보다가 프롬프트 엔지니어링을 알게되었고, 이를 적용해보았다. 이번 글에서는 그 과정을 적어보고자한다.
2. 본론
2.1 프롬프트 엔지니어링
프롬프트 엔지니어링이란 무엇인가... 찾아보니 좋은 문서가 있어 공유해본다.
아래의 글을 요약하자면, 세부적인 결과를 얻을 수록 자세한 지침이 필요하고 이를 여러 방법(문자, 기호, 형식)으로 정규화 한것을 프롬프트 엔지니어링으로 생각하면 된다.
https://aws.amazon.com/ko/what-is/prompt-engineering/
2.2 프롬프트 엔지니어링의 차이
처음에는 위의 글을 보고 프롬프트 엔지니어링을 적용 한 것과 안 한것이 그렇게 차이가 크려나? 했는데 차이는 상당했다. 프롬프트 엔지니어링을 적용하여 llama3에게 질문해보았고 적용하지 않은 채로 적용해보기도 하였다. 답변은 다음과 같다.
- 프롬프트 엔지니어링 미적용 답변
예측 가격은 실제 가격의 추세를 거의 완전히 잘 따르고 있습니다. 두 가격의 추세는 매우 유사하고, 거의 모든 점에서 실제 가격의 방향을 따르고 있습니다. 즉, 예측 가격은 실제 가격의 상승과 하강을 잘 예측하고 있습니다.
- 프롬프트 엔지니어링 적용 답변
예측 가격과 실제 가격을 분석하는 데 도움을 드리겠습니다. 먼저 예측 가격과 실제 가격을 함께 플로팅하여 데이터를 시각화해 보겠습니다. 대략적인 도표는 다음과 같습니다: 예측 가격: 145576176, 143768432, 145507312, 142940912, 14128864, 142819968, 142076336, 141075264, 140019984, 147150336, 135612944, 127751952, 13402592, 134498464, 133590064 실제 가격: 145499, 143649, 14269, 1412659,000, 13729000, 139652000, 13850000, 139152000, 1448100, 128199, 134163000, 1351200. 도표에서 예측 가격은 일반적으로 실제 가격의 추세를 따른다는 것을 알 수 있습니다. 두 시리즈 모두 비슷한 기복 패턴을 보입니다. 유사성을 정량화하기 위해 몇 가지 지표를 계산해 보겠습니다: 1. 평균 절대 오차(MAE): 이는 예측 가격과 실제 가격의 평균 차이를 측정합니다. MAE = (145576176 - 145499000) + ... + ... + (133590064 - 135120000) / 14 ≈ 143111.93 MAE는 평균적으로 예측 가격이 실제 가격과 약 143,111 단위 차이가 난다는 것을 나타냅니다. 2. 결정 계수(R 제곱): 이는 예측된 가격이 실제 가격의 변동을 얼마나 잘 설명하는지를 측정합니다. R 제곱 ≈ 0.952 R 제곱 값은 실제 가격 변동의 약 95.2%가 예측된 가격으로 설명될 수 있음을 시사하며, 이는 두 시리즈 사이에 강한 양의 관계가 있음을 나타냅니다. 3. 피어슨 상관 계수 ≈ 0.977 피어슨 상관 계수 ≈ 0.977 상관 계수는 1에 가까워 예측된 가격과 실제 가격 사이에 강한 양의 선형 관계가 있음을 나타냅니다. 이러한 지표에 따르면 예측된 가격은 실제 가격의 추세를 비교적 잘 따르는 것으로 보입니다.
답변은 생각보다 상당한 차이가 났다. 그래서 나의 시스템에 적용하기로 결심하였다.
2.3 Llama3 모델의 프롬프트 형식
Llama3 모델의 프롬프트 형식은 Meta의 공식 레퍼런스에서 가지고 왔다.
https://www.llama.com/docs/model-cards-and-prompt-formats/meta-llama-3/
문서에 따르면 Llama 3에는 특별한 토큰이 있고, 이는 다음과 같다.
자 그럼 meta에서 제공한 예시를 확인해보자.
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
You are a helpful AI assistant for travel tips and recommendations<|eot_id|><|start_header_id|>user<|end_header_id|>
What can you help me with?<|eot_id|><|start_header_id|>assistant<|end_header_id|>
system header 다음에 Llama3 모델의 역할을 지정하고, user header 다음에 질문 내용을 입력하고 마지막에 assistant header를 넣어주면 된다. 사실 assistant header의 역할이 잘 이해되지 않았는데, 해당 header 다음부터 llama3 모델이 답변을 입력한다.
정리해보면 각 role을 입력한 header 밑에 내용을 입력해주면 된다. 해당 문서를 활용해 내 시스템에 맞는 프롬프트를 작성해보았다.
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
너는 비트코인의 예측 가격과 실제 가격을 가지고 분석해주는 AI 분석 도우미야.
<|eot_id|>
<|start_header_id|>user<|end_header_id|>
다음은 예측 가격들이야. [129536096,130886920,133687344,135043184,133590064,134498464,133402592,127751952,135612944,147150336,140019984,141075264,142076336,142819968,141128864]
다음은 실제 가격들이야. [129536096,130886920,133687344,135043184,133590064,134498464,133402592,127751952,135612944,147150336,140019984,141075264,142076336,142819968,141128864]
예측 가격이 실제 가격의 추세를 잘 따라가고 있는지 확인해줘.
<|eot_id|>
<|start_header_id|>assistant<|end_header_id|>
2.4 Groq Machine 생성
결국 시스템으로 돌아가려면 Groq 관련 기능들을 객체화해야하기 때문에 Machine을 생성하였다. 코드는 다음과 같다.
from groq import Groq
import configparser
import os
class GroqMachine:
def __init__(self):
config = configparser.ConfigParser()
config.read('app/conf/config.ini')
key = os.getenv("GROQ_KEY", None)
self.model = config['GROQ']['model']
self.client = Groq(
api_key=key
)
def get_prompt_format(self):
formatted_prompt = """
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
너는 비트코인의 예측 가격과 실제 가격을 가지고 분석해주는 AI 분석 도우미야.
<|eot_id|>
<|start_header_id|>user<|end_header_id|>
다음은 예측 가격들이야. {predicted_data}
다음은 실제 가격들이야. {actual_data}
예측 가격이 실제 가격의 추세를 잘 따라가고 있는지 확인해줘.
모든 대답은 한글로해줘.
<|eot_id|>
<|start_header_id|>assistant<|end_header_id|>
"""
return formatted_prompt
def get_analysis_result(self, actual_data, predicted_data):
prompt = self.get_prompt_format()
prompt = prompt.format(actual_data=str(actual_data), predicted_data=str(predicted_data))
print(prompt)
res = self.client.chat.completions.create(
messages=[
{
"role": "user",
"content": prompt,
}
],
model=self.model,
)
return res.choices[0].message.content
변동성 있는 데이터 부분은 format 메소드를 활용할 수 있도록 하였다.
3. 결어
프롬프트 엔지니어링을 매체로 접했을 때는 "저게 정말 중요한가?" 라는 생각이 들었다. 그래서 직접 실험을 해 보았고 답변 퀄리티 생각보다 많이 차이나는 것을 확인하고 이를 시스템에 적용하였다.
다음은 여러 프롬프트를 사용할 수 있도록 변경해볼 예정이다.
'기록지 > FLOWBIT' 카테고리의 다른 글
[FLOWBIT] Groq API의 적용기 #1 (LLM을 무료로 사용하는 방법) 🤖 (1) | 2024.12.11 |
---|---|
[FLOWBIT] VER2 릴리즈 회고록 📝 (6) | 2024.11.20 |
[FLOWBIT] BITCOIN SERVICE의 DDD 구조 작성 📚 (0) | 2024.03.31 |
[FLOWBIT] 비트코인 자동거래 시스템에서 예측 가격 제공 서비스로 전환! ✨ (0) | 2024.01.12 |
- Total
- Today
- Yesterday
- 개발자
- Spring Boot
- 백준
- BaekJoon
- CJ 올리브네트웍스
- 프로그래머스
- 백준 알고리즘
- 안드로이드 스튜디오
- 후기
- spring
- 코딩테스트
- 코테
- 코딩
- Programmers
- 안드로이드 프로그래밍
- 백준알고리즘
- 육군
- 자료구조
- XML
- CJ
- Python
- 문자열
- C언어
- 구현
- 비트코인
- 기록지
- CJ Olivenetworks
- 알고리즘
- c++
- java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |