티스토리 뷰
12월 초에 chatGPT를 처음 안 이후 꾸준히 써왔는데, 최근 갑자기 주목받으면서 특정 시간대 사람들이 몰려서 접속하기도 힘들고 자주 연결이 끊어지기 시작했다.
편하게 쓰고 싶은 마음에, 무슨 방법이 없을까 하다가 OpenAI에서 제공하는 API를 찾게 되었고, 바로 사용해봤다.
이런 저런 문제가 있어 오래걸렸지만, 결과도 괜찮게 나오고, EC2에 배포했는데도 생각보다는 응답이 빨랐다.
처음 설계는 AWS EC2 + Docker로 배포하려고 했지만, 어떤 이유에서인지 Docker에 코드를 올린 후, Tomcat에서 배포가 안됐다. 그래서 일단 AWS EC2만으로 배포해 사용해봤다.
제목에는 ChatGPT API라 작성했지만, 정확히는 OpenAI에서 제공하는 통합 API다. 때문에 학습 관련 API도 다수 존재한다.
내가 관심있는건 간단한 질답을 하는 수준이었고, 다행히 Docs가 잘되있어서 빠르게 결과를 볼 수 있었다.
질답 외에도 문자열 수정, 이미지 생성 API도 사용해봤다.
1. API Key 발급 받기
가장 먼저 해야하는 것은 OpenAPI에서 API Key를 발급받는 것이다.
OpenAPI 홈페이지 접속해 회원가입까지 진행한다.(이 글을 검색해 볼 정도면 ChatGPT가 OpenAPI에서 만든 것 정도는 알고 있으리라 생각한다)
로그인 후 우측 상단의 Personal을 클릭하면 아래와 같은 메뉴가 나오는데 View API keys를 클릭한다.
그러면 API keys 페이지가 나오는데 여기서 키 생성!
발급 받은 키를 다시 볼 수 없으니 잘 모셔 놓자.
다른 브라우저에서는 될 수 있는데(확인 안해봤음) 크롬에서는 안된다.
2. 모델 선택
요청 생성 전에 어떤 모델에게 질문을 보낼 것인지 선택해야 한다. 본인의 GPT 사용 용도에 따라 모델을 잘 선택해야한다. 그리고 속도와 정확한 답변은 보통 반비례한다.
모델은 크게 두 분류로 나눠지며, 생각보다 다양한 모델들이 있다.
2.1. GPT-3 모델
자연어를 이해하고 생성하는 모델. Davinci는 가장 유능한 모델이고, Ada는 가장 빠른 모델. 빠를 수록 기대 성능은 떨어진다.
- text-davinci-003 : 가장 유능한 GPT-3 모델. 다른 모델이 할 수 있는 모든 작업을 수행할 수 있으며, 종종 더 높은 품질, 더 긴 출력 및 더 나은 지침 준수로 수행한다.
- text-curie-001 : Davinci보다는 덜 유능하지만 빠르고 cost가 낮다.
- text-babbage-001 : 간단한 작업이 가능하고 매우 빠르고 cost가 더 낮다.
- text-ada-001 : 매우 간단한 작업이 가능하고, GPT-3 시리즈에서 가장 빠른 모델이며 cost가 가장 낮다.
2.2. Codex
2023.2.5 기준 베타 모델. 코드를 이해하고 생성할 수 있는 GPT-3 모델의 자손(descendants). 학습 모델에 자연어와 GitHub의 수십억줄의 코드가 혼재한다고 한다.
JavaScript, Go, Perl, PHP, Ruby, Swift, TypeScript, SQL, 심지어 Shell을 포함한 12개 이상의 언어에 능숙하며, Python을 가장 잘 이해/생성한다고 한다.
현재는 두 개의 모델이 있다.
- code-davinci-002 : 가장 유능한 Codex 모델. 자연어를 코드로 변환한다. 코드를 완성하는 것 외에도 코드를 중간에 삽입해 완성하는 기능도 지원한다.
- code-cushman-001 : Davinci와 거의 비슷하지만 약간 더 빠르다. 이러한 속도를 이점으로 실시간성이 필요한 곳에 사용하는게 바람직하다.
2.3. 모델 상태를 확인하는 API
GET https://api.openai.com/v1/models/{model}
{model}에 알고 있는 모델의 이름을 넣어도되고 전체 모델을 받아보고 싶으면 models까지만 작성한다.
그럼 아래와 같은 response를 받게 된다.
{
"id": "text-davinci-003",
"object": "model",
"owned_by": "openai",
"permission": [...]
}
모델 명 등 생략됐지만 permission 아래에 수많은 추가 정보가 있다. 그 중에서 주목할 값은 is_blocked인데, 이 값이 "true"이면 현재 그 모델은 사용 불가라는 것을 의미한다.
CURL 요청테스트 :
curl https://api.openai.com/v1/models/text-davinci-003 \
-H 'Authorization: Bearer YOUR_API_KEY'
3. API 요청하기
앞서 언급했지만, 내가 관심있는 부분은 질답을 주고 받는 것이다. 때문에 모델을 파인튜닝(fine tuning)하는 API는 생략한다.
모델을 튜닝 하는 API들을 제외하면 대표적인 API로는 Completions(질답), Edit(수정), Images(이미지 생성)가 있다.
3.1. Completions
질답을 주고받는 API 이다.
CURL로 간단하게 요청 테스트를 해볼 수 있다.
curl https://api.openai.com/v1/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-d '{
"model": "text-davinci-003",
"prompt": "Say this is a test",
"max_tokens": 7,
"temperature": 0
}'
파라미터를 알아보면
- model : 어떤 GPT 모델을 사용할지 지정
- prompt : 질문할 문장
- max_tokens : 응답의 컨텍스트 길이
- temerature : 얼마나 창의적인 답을 작성하도록 할지 지정하는 값. 클수록 창의적이고 작을수록 잘 정의된 답을 제출한다.
이 외에도 몇 가지 파라미터가 있으나 모두 사용하지 않아도 응답이 잘 생성된다. 추가적인 응답을 확인하고 싶으면, 여기 에서 확인하자.
그런데, CURL로 만드는건 결과를 받아 볼 수는 있지만, 변수를 바로바로 적용하기도 어렵고, 재사용성도 떨어진다.
스프링 프레임워크의 RestTemplate으로 만들어보자.
PostMan이나 다른 툴로 변경해서 써도 상관없으니 용도나 목적에 맞춰서 사용하도록 하자.
3.1.1 RestTemplate으로 API 요청하기
@Value("${apikey}")
private String API_KEY;
private static final String ENDPOINT = "https://api.openai.com/v1/completions";
public String generateText(String prompt, float temperature, int maxTokens) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + API_KEY);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model","text-davinci-003");
requestBody.put("prompt", prompt);
requestBody.put("temperature", temperature);
requestBody.put("max_tokens", maxTokens);
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.postForEntity(ENDPOINT, requestEntity, Map.class);
return response.toString();
}
질문
generateText("what is penguin?", 1.0f, 1000);
응답(choice 아래에 있는 text)
"Penguins are a group of aquatic, flightless birds They are found almost exclusively in the Southern Hemisphere, with only one species, the Galapagos penguin, found north of the equator Penguins are highly adapted for life in the water and are found on every continent in the Southern Hemisphere, except for Australia and New Zealand Penguins have streamlined bodies and flippers for swimming, and their black-and-white plumage provides effective camouflage"
질문이 구체적이지 않을 경우와, max_tokens 값이 크고 temperature의 값이 1에 가까울수록 느려진다. 또한 한글로 질문을 작성하면 답변이 더 느려지니 주의하자.
API KEY는 본인이 발급 받은 값으로 치환해서 사용하자.
(위 코드는 GitHub에 올리기 위해 API KEY를 xml로 빼서 사용했다)
주의할점
추가적으로 주의할 점은 GitHub에 API KEY를 올리면, 기존 Key가 중지되고 재발급되니 주의하자.
3.2 Edit
Edit은 입력 문자열과 그 문자열에 어떤 조치를 취하고 싶은지를 입력하면 그 조치가 적용된 문자열을 return 주는 API다.
CURL 요청테스트 :
curl https://api.openai.com/v1/edits \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-d '{
"model": "text-davinci-edit-001",
"input": "What day of the wek is it?",
"instruction": "Fix the spelling mistakes"
}'
3.2.1 RestTemplate으로 API 요청하기
public String editText(String prompt, String instruction) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + API_KEY);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model","text-davinci-edit-001");
requestBody.put("input", prompt);
requestBody.put("instruction", instruction);
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.postForEntity(EDIT_ENDPOINT, requestEntity, Map.class);
Map<String, Object> responseBody = response.getBody();
return responseBody.toString();
}
질문
editText("I will went to school tomrrw.", "Fix the spelling mistakes");
응답(choice 아래에 있는 text)
"I will go to school tomorrow."
생각보다 썩 수정을 잘해주는 것 같지는 않다. 파라미터를 세부 조정해가면서 맞춰야 겠지만 일단을 사용해보는데 의의를 뒀다.
3.3 Images
Images는 문자열을 받고, 이미지를 return해주는 API다. base64 포맷과 url 두 종류로 값을 return한다.
CURL 요청테스트 :
curl https://api.openai.com/v1/images/generations \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-d '{
"prompt": "A cute baby sea otter",
"n": 2,
"size": "1024x1024"
}'
3.3.1 RestTemplate으로 API 요청하기
public String makeImages(String prompt) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + API_KEY);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("prompt", prompt);
requestBody.put("size","1024x1024");
requestBody.put("n", 1);
requestBody.put("response_format", "url");
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.postForEntity(IMAGES_ENDPOINT, requestEntity, Map.class);
Map<String, Object> responseBody = response.getBody();
return responseBody.toString();
}
질문
editImages("sleeping penguin");
응답(url을 브라우저에 붙여넣는다)
url : https://oaidalleapiprodscus.blob.core.windows.net/private/org-GbVASL6oLIhz7KbwJmy0ig4T/user-J438M60flJjB83j8gKWlZaBF/img-e4UhS6oxT0Sk5wBbmTbZygRD.png?st=2023-02-05T10%3A36%3A44Z&se=2023-02-05T12%3A36%3A44Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2023-02-04T13%3A56%3A24Z&ske=2023-02-05T13%3A56%3A24Z&sks=b&skv=2021-08-06&sig=HcH3af%2BdoE9YKVxcTObI7Bdeq0tIqpruXPUHQl9kLJU%3D
생각보다 그림을 너무 잘 그려준다. 달리에서 충분히 학습하고 테스트를 해본 결과 인가 싶다. 단점은 한글을 넣으면 이상한걸 그려줄 때가 많다는 것이다...
4. 마치며
AI가 많이 발전했다는 느낌을 받았다. 사용하기에 따라 범용성 넘치는 API들을 무료로 제공해주는 것도 대단한 것 같다.(물론 언제 유료가 될지 모르지만)
chatGPT와 비교해서 몇 가지 안되는 것도 있는데, completion에서는 chatGPT처럼 이전에 준 질문을 기억하고 있는 것 같지는 않았다.
일단은 스프링 프레임워크로 EC2에 배포까지 진행해봤다.
'개발 > chatGPT' 카테고리의 다른 글
Chat GPT API에서 이전 대화 기억하게 하기 (9) | 2023.06.25 |
---|---|
Chat GPT의 입력 Token 수를 세보자(Jtokkit 소개) (0) | 2023.05.24 |
Chat GPT API에서 사용하는 SSE(Server-Sent Events) 뜯어보기 (2) | 2023.05.14 |
ChatGPT API의 새기능? chat API를 써보자 - 2 (프롬프트와 SSE) (1) | 2023.05.13 |
ChatGPT API의 새기능? chat API를 써보자 - 1 (간단 사용법) (0) | 2023.04.24 |
- Total
- Today
- Yesterday
- EKS
- OpenFeign
- serverless
- JWT
- 스프링부트
- OpenAI
- 오블완
- elasticsearch
- springboot
- Log
- Elastic cloud
- docker
- terraform
- AWS
- 티스토리챌린지
- openAI API
- lambda
- CloudFront
- Kotlin
- MySQL
- GIT
- ChatGPT
- Spring
- S3
- 후쿠오카
- cache
- 람다
- AWS EC2
- java
- AOP
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |