이해하기
새로운 프로젝트 주제를 아직 정하지 못해서 kakao developers의 KoGPT를 사용해봤다.
활용 방법에 따르면 아래 요소를 답변을 할 수 있다고 한다.
- 제시된 문장의 긍정, 부정 등 속성 판단 및 분류
- 긴 문장의 주요 내용을 한 줄로 요약
- 결론이 없는 문장을 추론하여 결론 예측
- 질문에 맥락을 고려하여 답변
- 주어진 문장의 다음 내용 생성
기본적으로 KoGPT에 요청을 보내려면 몇가지 파라미터가 필요한데 내가 이해한 바로는 아래와 같다.
prompt : 프롬프트, KoGPT에 전달할 제시어, 과제 설명, 예시, 입력이 필요하다.
max_tokens : KoGPT가 처리할 수 있는 문자열의 최소 단위를 Token이라고 하는데, 토큰 수가 많아지면 처리에 지연시간이 발생하고, max_tokens으로 응답 문자열 길이를 조절할 수 있다.
top_p : 후보 토큰의 수에 영향을 미치는 파라미터
temperature : KoGPT 모델이 후보 토큰을 선택할 때 그 선택에 대한 불확실성을 조절하는 파라미터
- 온도 값이 높으면 토큰 간의 선택 확률이 균등해져서 더 다양한 후보 토큰을 선택하게 됨
-> 더 창의적이고 다양한 답변을 생성
- 온도 값이 낮으면 반대로 선택 확률 차이가 커져 가능성이 높은 후보 토큰을 선택
-> 고정적인 답변을 구성
아래는 예시이다.
// 프롬프트
어느덧 가을이 성큼 다가왔다. 구름 한 점 없이 새파랗고 드높은 하늘을 바라보고 있노라면 어디선가 선선한 바람이 불어온다.
// 결과
// temperature를 0.1로 지정한 경우
가을은 천고마비의 계절이다. 하늘은 높고 말은 살찐다는 뜻이다. 가을은 식욕의 계절이다. 가을에는 식욕이 ...
// temperature를 0.3으로 지정한 경우
가을은 여행하기 좋은 계절이다. 선선한 바람을 쐬며 걷다 보면 어디선가 알싸한 풀 향기가 풍겨온다. 가을에 ...
// temperature를 1.0으로 지정한 경우
이번 가을에는 무슨 옷을 입어야 할 지 고민을 날려버릴 가을 패션 아이템은 무엇이 있을까? 유행을 따르는 것도 좋지만 ...
n : 생성된 답변의 개수 (1~16개)
까지 사용되는 파라미터는 5가지가 전부이고 prompt, max_tokens만 필수 파라미터이다.
요약해서 설명하자면,
prompt을 가지고 요청을 보내고, 그에 대한 응답으로 후보 토큰들을 받을 수 있다.
그 후보 토큰을 temperature으로 고정된 후보 토큰을 선택할 지, 다양한 후보 토큰을 선택할 지 비율을 정할 수 있다.
그리고, top_p를 이용해 상위 확률(Top Probability)을 정해 내림차순으로 답변 구성에 필요한 토큰들을 추려낸다.
마지막으로 선택된 토큰의 응답 문자열 길이를 조절할 수 있는 파라미터가 max_token인 것.
자세한 내용은 KoGPT 설명을 참고
(https://developers.kakao.com/docs/latest/ko/kogpt/common)
사용해보기
REST API 문서에 따르면 Post 형식으로 https://api.kakaobrain.com/v1/inference/kogpt/generation에 요청을 보내면 결과를 받을 수 있다.
아래는 공식 문서의 Python으로 호출하는 예제이다.
# coding=utf8
# REST API 호출에 필요한 라이브러리
import requests
import json
# [내 애플리케이션] > [앱 키] 에서 확인한 REST API 키 값 입력
REST_API_KEY = '${REST_API_KEY}'
# KoGPT API 호출을 위한 메서드 선언
# 각 파라미터 기본값으로 설정
def kogpt_api(prompt, max_tokens = 1, temperature = 1.0, top_p = 1.0, n = 1):
r = requests.post(
'https://api.kakaobrain.com/v1/inference/kogpt/generation',
json = {
'prompt': prompt,
'max_tokens': max_tokens,
'temperature': temperature,
'top_p': top_p,
'n': n
},
headers = {
'Authorization': 'KakaoAK ' + REST_API_KEY,
'Content-Type': 'application/json'
}
)
# 응답 JSON 형식으로 변환
response = json.loads(r.content)
return response
# KoGPT에게 전달할 명령어 구성
prompt = '''인간처럼 생각하고, 행동하는 '지능'을 통해 인류가 이제까지 풀지 못했던'''
# 파라미터를 전달해 kogpt_api()메서드 호출
response = kogpt_api(
prompt = prompt,
max_tokens = 32,
temperature = 1.0,
top_p = 1.0,
n = 3
)
print(response)
이걸 나는 자바로 사용하고 싶어서 자바로 다시 작성해봤다.
아 참고로 스프링 부트, 롬복이 빌드되어 있다. 이 환경에서 사용할거라서 이렇게 작성했다.
package com.oh3g.Project_B;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
@Slf4j
@SpringBootApplication
public class test {
@Data
public static class RequestBody {
private String prompt;
private int max_tokens;
private double temperature = 1;
private double top_p = 1;
private int n = 1;
}
@Data
public static class ResponseBody {
private String id;
private Generation[] generations;
private Usage usage;
}
@Data
public static class Generation {
private String text;
private int tokens;
}
@Data
public static class Usage {
private int prompt_tokens;
private int generated_tokens;
private int total_tokens;
}
public static void main(String[] args) {
String apiUrl = "https://api.kakaobrain.com/v1/inference/kogpt/generation";
String restApiKey = "========================";
RequestBody requestBody = new RequestBody();
requestBody.setPrompt("인간처럼 생각하고, 행동하는 '지능'을 통해 인류가 이제까지 풀지 못했던");
requestBody.setMax_tokens(64);
requestBody.setTemperature(0.7);
requestBody.setTop_p(0.8);
log.info(requestBody.toString());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "KakaoAK " + restApiKey);
HttpEntity<RequestBody> requestEntity = new HttpEntity<>(requestBody, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.postForEntity(apiUrl, requestEntity, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
String responseBody = responseEntity.getBody();
try {
ObjectMapper objectMapper = new ObjectMapper();
ResponseBody pasrsedBody = objectMapper.readValue(responseBody, ResponseBody.class);
log.info("ID: {}", pasrsedBody.getId());
for (Generation generation : pasrsedBody.getGenerations()) {
log.info("Text: {}", generation.getText());
log.info("Tokens: {}", generation.getTokens());
}
log.info("Prompt Tokens: {}", pasrsedBody.getUsage().getPrompt_tokens());
log.info("Generated Tokens: {}", pasrsedBody.getUsage().getGenerated_tokens());
log.info("Total Tokens: {}", pasrsedBody.getUsage().getTotal_tokens());
} catch (Exception e) {
log.error("Error occurred while parsing response body: {}", e.getMessage());
}
} else {
System.err.println("Error: " + responseEntity.getStatusCodeValue());
}
}
}
코드는 긴데 사실 로그 보기 편하라고 긴거고 알맹이는 어렵지 않다.
응답은 아래와 같이 나온다.
20:36:15.159 [main] INFO com.oh3g.Project_B.test -- test.RequestBody(prompt=인간처럼 생각하고, 행동하는 '지능'을 통해 인류가 이제까지 풀지 못했던, max_tokens=32, temperature=1.0, top_p=1.0, n=1)
20:36:16.915 [main] INFO com.oh3g.Project_B.test -- ID: 182d8218-4aed-4b10-8fe4-xxxxxxxxxxxx
20:36:16.917 [main] INFO com.oh3g.Project_B.test -- Text: 숙제인 세상에 대한 물음과 그 해답을 누구나 이해할 수 있을 뿐만 아니라 사용 할 수있다. 멀더요원이었
20:36:16.917 [main] INFO com.oh3g.Project_B.test -- Tokens: 32
20:36:16.917 [main] INFO com.oh3g.Project_B.test -- Prompt Tokens: 22
20:36:16.917 [main] INFO com.oh3g.Project_B.test -- Generated Tokens: 32
20:36:16.917 [main] INFO com.oh3g.Project_B.test -- Total Tokens: 54
생각보다 좋은지는 잘 모르겠다.
그 외 파라미터 조절로 긍정 부정도 분류해보자 일부러 마지막 문장은 애매하게 써봤다. 궁금하잖아~
20:41:43.434 [main] INFO com.oh3g.Project_B.test -- test.RequestBody(prompt=상품 후기를 긍정 또는 부정으로 분류합니다.
가격대비좀 부족한게많은듯=부정
재구매 친구들이 좋은 향 난다고 해요=긍정
ㅠㅠ약간 후회가 됩니다..=부정
이전에 먹고 만족해서 재구매합니다=긍정
이 가격에 이 퀄리티면.. 저는 잘 모르겠네요=, max_tokens=1, temperature=0.4, top_p=1.0, n=1)
20:41:44.293 [main] INFO com.oh3g.Project_B.test -- ID: 5329b59b-3bce-4142-a8ed-xxx
20:41:44.294 [main] INFO com.oh3g.Project_B.test -- Text: 부정
20:41:44.294 [main] INFO com.oh3g.Project_B.test -- Tokens: 1
20:41:44.294 [main] INFO com.oh3g.Project_B.test -- Prompt Tokens: 71
20:41:44.294 [main] INFO com.oh3g.Project_B.test -- Generated Tokens: 1
20:41:44.294 [main] INFO com.oh3g.Project_B.test -- Total Tokens: 72
KoGPT는 부정으로 체크해줬다. 근데 내가 봐도 부정인거 같은 느낌이긴 하다.
REST API 문서의 예시는 이것 말고도 뉴스 요약, 질문 답변, 말투 변경, 채팅 등 다양하게 조정이 가능하다.
자세한건 링크 참고 (https://developers.kakao.com/docs/latest/ko/kogpt/rest-api#request)
아무튼 사용해보려고 이것저것 작성해봤는데 좀 애매하다.
주어진 프롬프트에서 결과를 내오는 형식인 것 같아서 사용하게 된다면 조금 제한된 사용이 되지 않을까.