Code in

아이랑 프로젝트 (2) GPT3, Magenta js로 사용하기 본문

프로젝트_AI랑

아이랑 프로젝트 (2) GPT3, Magenta js로 사용하기

heyhmin 2021. 5. 15. 15:31

프로젝트 소개

아이랑 프로젝트는 AI의 창작능력과 관련한 산학 프로젝트이다.

 

AI의 발전에 따라 그 창작능력에 대한 연구가 많은 곳에서 진행되어왔다.

 

과연 AI는 인간과 비슷한 창작능력을 가질 수 있을까?

 

우리 팀에서는 이에 대한 해답으로 아이랑 프로젝트, AI로 동요 작사작곡하기 를 진행하고 있다.

 

작사에는 가장 성능이 좋다고 판단한 GPT-3를 사용하였고,

작곡에는 구글의 Magenta 프로젝트의 chord-pitches-improv를 사용하였다.

 

Magenta는 LSTM(RNN)을 사용한다.

Cell-state가 있고, 이를 반복적으로 업데이트 하는 것이다.

 

GPT-3는 In-context learning을 하는 meta learning을 진행하였다.

zero-shot, one-shot, few-shot의 방식을 확인했다고 한다.

 

zero-shot : Task-description + prompt

one-shot : Task-description + example + prompt

few-shot : Task-description + examples + prompts

해당 Figure는 GPT-3 논문에서 확인할 수 있다.

 

 

현재 진행상황

지난 학기와 겨울방학까지 작사, 작곡에 대한 연구를 마무리하였다.

작사의 경우 Few shot learning을 사용하기 위해 prompt에 theme 문장과 예시들을 사용하기로 하였다.

( task description + examples + prompt )

 

작사의 validation을 위해서는 표절률을 사용하기로 하였다.

이 때, 표절률을 낮추기 위해서 frequency penalty를 주기로 하였다.

 

frequency penalty는 반복되는 단어가 나오는 것에 대한 패널티(부정적인 값)을 부과하여 표절을 방지하는 것이다.

패널티는 가능한 단어들의 숫자를 줄이기 때문에 temperature를 높이는 것과 유사한 효과를 보인다.

하여 temperature를 0.5 정도로 낮추기로 하였다.

frequencyPenalty와 temperature를 확인할 수 있다.

 

프로젝트에서 작사 연구를 하며 얻은 GPT-3의 동요 작사 결과이다.

꽃이 피어오면
흰눈이 내리는 봄빛처럼
너를 사랑해

피어나는 봄빛이
사람들을 사로잡아
웃음꽃이 피고 있어요

아침이 오면 꽃이 피어오고 뻗은 꽃은
언제나 이렇게 아침을 축하하고 싶어

꽃이 움직여 봄빛이 나는 아침에
꽃이 들어와 웃고 있는 아침
봄꽃이 피는 밤 햇살이 가득한 아침에

구름에 사는 봄빛이
흘러내리는 골짜기에
꽃이 피어오르고

꽃이 소리쳐 노래하는 밤
하늘 위에 피는 별처럼
미소를 걸고 있는 꽃망울

내게 전해요

 

작사 결과물은 정말 놀랍다.

굉장히 시적이고 아름다운 문장들을 AI, GPT-3가 생성할 수 있음을 알 수 있다.

 

 

 

작곡에 대한 연구는 다른 분들이 진행해주셨고,

최종적으로 chord-pitches-improv를 사용하고 16 stepe per chord, 기존 동요들의 chords을 사용하기로 하였다.

 

작곡 결과물의 악보 변환 이미지 1
작곡 결과물의 악보 변환 이미지 2
작곡 결과물의 악보 변환 이미지 3

 

 

 

처음에는 작사와 작곡의 연동을 진행하고자 했다.

이를 위해 각각의 결과들을 비교하였고, 작곡의 steps과 작사의 max_tokens의 연관성을 파악하였다.

: steps / 5 * 3 = max_tokens

완전히 일치하지는 않지만 해당 수식을 적용하면 적절한 길이를 얻어 연동을 진행할 수 있다.

 

실제 구현 시에는 각각을 연동하지 않고 따로 보여주기로 하였다.

 

기술내용

이번 학기에 주로 진행한 웹페이지에 기능 구현을 하는 방법에 대해 설명하고자 한다.

 

GPT-3는 웹페이지에 어떻게 구현할 수 있을까?

 

이는 openAI 웹페이지의 document를 보면 알 수 있다. (developer-quickstart/community-libraries)

Javascript/Node를 사용하는 것을 미리 구현해 놓은 것들이 있으니 이를 사용하여 쉽게 진행할 수 있다.

 

참고로 구현되어 있는 것들을 사용하지 않아도,

GPT-3 url에 complete(response)를 요청하면 되는 것이기 때문에 쉽게 GPT-3를 사용할 수 있다.

 

우리는 openai-api를 사용하기로 했다.

 

진행 순서는 다음과 같다.

 

[서버]

1. API_KEY ( openAI에 신청하여 받을 수 있다 ) 를 입력하여 연결을 진행한다. 

2. 자바스크립트의 async를 사용하여 GPT-3의 결과값을 받는다.

3. 결과값의 불필요한 단어들을 삭제한다.

4. 최종 결과를 시간데이터를 제목에 담고 있는 파일로 저장한다.

5. 원하는 파일(들)을 가상 주소로 보내서 출력한다.

 

이 때, 미리 동요와 관련된 prompts를 정리하여 2번에 사용하였다.

 

[프론트]

1. 원하는 파일(들)을 가상 주소에서 받아온다.

2. 적절한 div에 출력한다.

 

Magenta는 웹페이지에 어떻게 구현할 수 있을까?

 

일단 마젠타 공식페이지의 블로그 글들을 읽자.

https://magenta.tensorflow.org/js-announce

우리가 이미 연구한 방식을 적절히 응용할 수 있는 코드 펜을 사용하기로 했다.

 

"Mindless Improv"를 직접 에러없이 사용한 다음, 해당 코드들을 우리가 원하는 방식으로 바꾼다.

로컬에서 실행이 잘 되지 않아 다른 깃허브를 참고하여 많은 api들을 추가로 사용하였다.

 

실행방법

GPT3 - 코드 설명, 결과

 

[서버]

먼저, GPT-3을 저장할 폴더를 만들어보자

이처럼 openai라는 이름의 폴더를 만들었다. 

 

가장 쉬운 prompts set을 만들어 보자. prompt.js 파일을 openai 폴더 내부에 생성한다.

theme 문장을 입력하고, 동요 가사들을 키워드인 input과 세부가사 output으로 나누어 입력한다.

 

매번 다른 prompts를 사용할 수 있도록 random 함수도 사용한다.

 

export 를 사용하여 최종 prompts를 받을 수 있는 함수를 다른 파일에서 사용할 수 있도록 한다.

prompt.js 전체 코드는 깃허브에서 확인할 수 있다!

 

 

 

 

다음으로 get.lyrics.js 파일을 생성한다. 이 파일에서는 실제 결과물 얻어 저장할 것이다.

 

저장을 위해 미리 lyricResult 폴더를 만든다.

get.lyrics.js에서는

파일저장을 위한 fs, prompts를 받아오는 selectedPrompts, AI결과를 받아오는 apenai-api가 필요하다.

이후 API KEY를 입력하도록 한다. (openAI 홈페이지 에서 확인할 수 있다.)

 

API KEY를 사용하여 OpenAI를 생성한다.

GPT-3에 결과물을 요청한다! 미리 연구한 파라미터들과 함께 prompt를 넘겨준다.

생성된 결과물을 저장한다. 저장하기 전에 결과물에 들어있는 불필요한 값들을 제거해준다.

파일을 생성할 때 파일 이름으로 날짜와 시간값을 사용한다.

Max token 값은 180 ~ 220으로 하였다. 한글 기준으로 대략 3 token이 1개의 글자를 생성한다.

이후에는 필요하면 export를 사용하여 결과물을 넘겨줄 수 있다.

하지만 파일 저장을 했으니 파일을 읽어보자.

 

 

 

 

read.file.js를 생성한다.

파일을 읽기 위해 path, fs를 불러온다.

경로를 미리 설정한다.

그리고 해당 폴더에 있는 파일들의 이름을 모두 읽어온다.

가장 최근에 생성된 파일의 이름은 쉽게 얻을 수 있다.

각 파일들의 내용을 저장한다.

파일들의 이름과 내용을 합쳐서 반환해보자.

lyric 구조를 먼저 생성한다.
각 파일들의 이름과 내용을 함께 저장한다.

export 할 때 모든 variables를 반환할 수 있지만, 구현 방법에 따라 몇 가지만 사용할 가능성이 높다.

모든 variables를 반환한다. 주로 allLyric, recentLyric을 사용할 것이기 때문에 그 외의 것들은 제외하여도 좋다.

이후 라우팅을 진행할 때 각 값을 전달할 수 있다.

 

 

 

[프론트]

이제 API_URL에서 전달된 allLyric 혹은 recentLyric을 읽어보자.

이처럼 리액트에서 axios를 사용하여 /api/test/all에 출력된 allLyric 혹은 recentLyric을 읽을 수 있다.

 

 

하나의 가사 파일을 읽을 때는 title, content로 받을 수 있고

여러 가사 파일들을 읽을 때는 list와 loading boolean 값을 사용해야 한다.

읽은 값으로 setState를 진행한다.

 

사용할 때는 각각 다음처럼 사용할 수 있다.

이러한 방식을 잘 활용할 수 있는 웹페이지를 디자인하여 사용해보자!

 

현재 우리 프로젝트는 웹 UI를 더 수정해야 한다...

 

 

 

 

Magenta - 코드 설명, 결과

앞서 소개한 마젠타 블로그와 깃허브의 script 목록을 사용하여 기본 구조를 갖춘다. 

동요 코드들을 정리한다.

랜덤하게 chords를 받을 수 있도록 랜덤 함수를 만들어 놓는다.

버튼을 누를때마다 chords를 갱신할 수 있도록 한다.

선택된 코드 구성을 따를 수 있도록 for문을 돌린다.

이렇게 하면 미리 정의한 동요 코드들과 같게 구성된 AI의 작곡 내용을 들을 수 있다.

 

현재 상태로 웹페이지의 기능 구현을 마무리할 경우, 저장이 안되는 것이 아쉬울 것이다.

 

하여 현재 기능 구현이 대략적으로 완료되었으나

더 사용자 친화적으로 하고자 결과물 저장 및 악기 변경을 진행하고 있다.

 

 

 

관련 깃허브 소개 - 실행방법, 결과

앞서 Magenta와 관련되어 언급했던 참고한 깃허브이다.

https://github.com/loganstillings/MelodyGenerator

깃 클론을 한 다음, npm install, start를 진행하여 사용할 수 있다.

실행하면 피아노가 나오고, 건반을 꾹 누르고 있으면 AI가 생성한 곡을 들을 수 있다.

 

이외에도 마젠타에서 제공하는 web demo들을 사용할 수 있는데, npm serve를 사용해야 할 수 도 있다.

package.json의 scripts를 잘 확인하고 실행하자.

 

 

마무리

동요 작사작곡이라는 주제이기 때문에 작사의 Prompt, 작곡의 chords를 동요 데이터에서 가져왔다.

 

편안한 코드chord 진행의 곡들을 들으면서,

그리고 시적인 작사 결과를 확인하면서 프로젝트를 할 수 있어서 좋다.

 

주제를 정말 잘 정한 것 같다.

 

프로젝트가 잘 마무리 되었으면 좋겠다.

 

 

관련 깃허브

1. https://github.com/heyhmin/airangwebtest1

2. https://github.com/heyhmin/chordpitchesusingtest

3. https://github.com/danbom/AIrang

Comments