라이브러리 사용
- 정식 지원 ⇒ Python, NodeJS
- 따라서 AWS Lambda 활용
모델 선택의 고민
추천 사유 요약에 대한 목적에 맞게 모델을 변경하며 적합한 모델을 heuristic
하게 찾아감.
1. text-davinci-003
- 엄청엄청 느림…!
2. gpt-4
- 한번의 API 호출 ⇒ 10.95s
request_input = ' '.join(event) + " 이 문장들을 정확히 하나의 문장으로 요약해줘. 그리고 항상 '~해요'체로 끝나도록 요약해줘."
response = openai.ChatCompletion.create(
# 사용 모델
model="gpt-4",
messages=[
{"role": "user", "content": request_input}
]
)

3. gpt-3.5-turbo
- 한번의 API 호출 ⇒ 3.41s
- “~해요”체로 요약하지 않는 경우가 빈번함
request_input = ' '.join(event) + " 이 문장들을 정확히 하나의 문장으로 요약해줘. 그리고 항상 '~해요'체로 끝나도록 요약해줘."
response = openai.ChatCompletion.create(
# 사용 모델
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": request_input}
]
)

🧟♀️
프롬프트 엔지니어링
🧟♀️
response = openai.ChatCompletion.create(
# 사용 모델
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "항상 '해요'체로 끝나도록 요약해줘"},
# 사전 학습
{"role": "user", "content": "블랙톤 휠은 차량의 드라이브 편의성을 높여줍니다. 고급 차량의 필수 액세서리로 꼽히는 이유가 있습니다. 이 문장을 고객에게 추천하듯이 하나의 문장으로 요약해줘."},
{"role": "assistant", "content": "차량의 드라이브 편의성을 높여주는 고급 차량의 필수 액세서리에요."},
{"role": "user", "content": request_input}
]
)

Spring에서 API 호출
- 사용자에게 두 개의 옵션을 추천해주어야 하기 때문에, 2번의 OpenAI API를 호출해야 했음
1. 동기 호출 by OpenFeign
- API 2번 호출 시 3.542s + 알파 (쿼리시간) 예상함

⇒ 예상과 일치
⇒ 하지만 아직도 너무 느리다.!!!!!!!!!!
2. 비동기 호출 by OpenFeign
ComletableFuture
객체를 사용해서 비동기로 OpenAI API 2번 호출
- concurrent package에서
WorkStealingPool
쓰레드 풀 생성
- 아래 LOG에서 서로 다른 쓰레드에서 동작한 것을 확인할 수 있음
👉🏼
👉🏼
ComletableFuture 객체
Future
객체의 한계점을 극복- 예외 처리 불가
- 여러 Future 조합 불가능
- runAsync
- 반환값이 없는 경우
- 비동기로 작업 실행 콜
- supplyAsync
- 반환값이 있는 경우
- 비동기로 작업 실행 콜
- exeptionally
- 발생한 에러를 받아서 예외를 처리함
- 함수형 인터페이스 Function을 파라미터로 받음
Executor
- 개발자가 하나하나
Thread
를 관리하기 힘듦
- 따라서 쓰레드를 만들고 관리하는 작업을
Executor
에게 역할 위임
👉🏼
Executor
의 역할- 생성 : application에서 사용될 Thread를 만들거나, 쓰레드 풀을 통해 관리합니다.
- 관리 : Thread 생명 주기 관리
- 작업 처리 및 실행 : Thread로 작업을 수행하기 위한 API 제공
Executors
Executor
를 생성하는 팩토리 역할
Thread Pool
을 손쉽게 생성
Thread Pool
newFixedThreadPool()
- 고정된 쓰레드의 개수를 갖는 쓰레드 풀을 생성합니다.
- ExecutorService 인터페이스를 구현한 ThreadPoolExecutor 객체가 생성됩니다.
newCachedThredPool()
- 필요할 때 필요한 만큼의 쓰레드를 풀 생성합니다. (고정X)
- 이미 생성된 쓰레드가 있다면 이를 재활용 할 수 있습니다.
- 60초 동안 사용되지 않으면 쓰레드를 종료시킵니다.
newWorkstealingpool()
- 인자를 통해 병렬 처리 레벨을 지정합니다.
- 인자를 지정하지 않으면 현재 시스템의 core 프로세스 개수 기반으로 pool 사이즈가 할당됩니다.
WorkStealingPool
- 소프티어 부트캠프 WAS 구현 미션에서 백엔드 마스터님이
concurrent package
에 대해 간단하게 가르쳐주셨고, 당시에 따로 학습을 했었음! ⇒ https://dmansp.tistory.com/69
- 현재 시스템의 core 프로레스 개수 기반으로 pool 사이즈를 할당하는 것이 확장성에 용이할 것이라 판단하여 결정