Whisper๊ฐ ๋ญ๋ฐ?
Whisper๋ ์์ฆ ChatGPT๋ก ํซํ OpenAI์์ ๊ฐ๋ฐํ ์๋ ์์ฑ ์ธ์ ๋ชจ๋ธ์ด๋ค. ์์ฑ์ ํ
์คํธ๋ก ๋ณํํ๋ STT(Speech-to-Text) ๊ธฐ์ ์ ํ์ฉํ์ฌ, ๋ํ ์์ฑ ํ์ผ์ ํ
์คํธ๋ก ์ ์ฅํ ์ ์๋ค.
OpenAI๋ ์ฌํด 3์ 1์ผ GPT-3.5-turbo ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ํ Whisper API๋ฅผ ์ถ์ํ์๋ค. API๊ฐ ์ ๊ณต๋๊ธฐ ์ด์ ์ Whisper๋ฅผ ์ฌ์ฉํ๊ธฐ๊ฐ ๋ถํธํ์ง๋ง, ์ด์ ๊ณ ์ฑ๋ฅ ๋ชจ๋ธ(Large-v2)์ ์ฝ๊ฐ์ ๊ธ์ก์ ์ง๋ถํ๊ณ ์ด์ฉํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ค์ด ์ฌ์ฉํ๊ธฐ์ ํธ์์ฑ์ด ์ข์์ก๋ค. ๊ทธ๋์ ๊ฐ๋จํ๊ฒ ์คํ๋ง ๋ถํธ๋ฅผ ํ์ฉํด์ Whisper API๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ๋ค.
์ฐ์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ค์ด๊ฐ๊ธฐ ์ ์, ๊ฐ๋จํ๊ฒ ๋ช ๊ฐ๋ง ์ง๊ณ ๋์ด๊ฐ ๋ณด์.
๋ณดํต STT ๊ธฐ์ ์ WER(Word Error Rate), CER(Character Error Rate)๋ก ์ ํ๋๋ฅผ ํ๋ณํ๋ค.
์ธก์ ๊ฐ์ด ์์์๋ก ์ ํ๋๋ ๋์ ๊ฒ์ธ๋ฐ, ์๋ ์ฌ์ง์ Large-v2 ๋ชจ๋ธ๋ก ์ธ์ด๋ณ WER๋ฅผ ์ธก์ ํ ๊ทธ๋ํ์ด๋ค.
ํ๊ตญ์ด๋ ๋๋ฆ ๊ทธ๋๋ ์ ๋ฐฉํ ๋ชจ์ต์ด๋ค. ํผํฌ๋จผ์ค๊ฐ ๋ง์ด ์ข์ง ์์ง๋ง, ํ๊ท ๋ณด๋ค๋ ์ด์์ ๋ณด์ฌ์ฃผ๊ณ ์๋ค.
๊ทธ๋๋ ์๋ ๊ณต์ ์ด๋ฏธ์ง์์ ๋ํ ์์๋ก ํ๊ธ์ ๋ณด์ฌ์ฃผ๊ณ ์๋ค๋ ๊ฑด ์ข ๋ ์ ๋ขฐ๋ฅผ ๊ฐ๊ฒ ํ๋ ํฌ์ธํธ์๋ค. (์ด๋ฏธ ๋ ChatGPT ๋๋ฌธ์ ์์ฒญ๋ ์ ๋ขฐ๋ฅผ ํ๊ณ ์๋ ์ค)
Whisper API๋ ์ ๋ฃ? ๋ฌด๋ฃ?
๊ทธ๋ฆฌ๊ณ ์์์ ์ ๊น ๋งํ์ง๋ง, Whisper API๋ ๋ฌด๋ฃ๊ฐ ์๋๋ค. OpenAI์ API Key๋ฅผ ๋ฐ๊ธ๋ฐ์ ์ฌ์ฉ ํ์๋ง๋ค ํฌ๋ ๋ง์ ์ฐจ๊ฐ๋๊ฒ ๋๋๋ฐ, Whisper์ ๊ฒฝ์ฐ 1๋ถ๋น 0.006๋ฌ๋ฌ, ํ๊ตญ ๋์ผ๋ก ์ฝ 8์ ์ ๋์ด๋ค.
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฌ์ฉ๋ฒ์ ๋ํด ์์๋ณด์.
Whisper API๋ฅผ ์คํ๋ง ๋ถํธ์ ์ ์ฉํ๊ธฐ
1. OpenAI API Key ๋ฐ๊ธ
์ฐ์ Whisper API๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ OpenAI์ API Key๋ฅผ ๋ฐ๊ธ๋ฐ์์ผ ํ๋ค.
https://platform.openai.com/account/api-keys
์ ๊ณต์ ํํ์ด์ง ๋งํฌ๋ก ๋ค์ด๊ฐ์ ๋ก๊ทธ์ธ ํ, 'Create new secret key' ๋ฒํผ์ ๋๋ฅด๋ฉด ์๋ก์ด key๋ฅผ ๋ฐ๊ธ๋ฐ์ ์ ์๋ค.
์์ ๊ฐ์ด ์๋ก์ด ํค๊ฐ ๋ฐ๊ธ๋๊ณ , ๋ค๋ง ์ฃผ์ํ ์ ์ ํ๋ฒ ๋ฐ๊ธ๋ ํค๋ ์ฌํ์ธ์ด ๋ถ๊ฐ๋ฅํ๋ฏ๋ก, ์ ์ผ ์์คํ ๊ณณ์ ์ ๊ฐ์ถฐ๋์์ผ ํ๋ค. (๊ทธ๋๋ ํค๋ฅผ ์์์ ๊ฒฝ์ฐ์ ๋ค์ ์์ฑํ๋ฉด ๋๋ ๊ฒ ๊ฐ๋ค.)
์ถ๊ฐ๋ก, ์ ํ์ด์ง ์ข์ธก ๋ฉ๋ด์ Usage ํญ์ผ๋ก ๋ค์ด๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ ํฌ๋ ๋ง์ด ์๋์ง ํ์ธํด์ผ ํ๋ค. ๋ ๊ฐ์ ๊ฒฝ์ฐ์ ์ฒ์ ๋ฌด๋ฃ๋ก ์ ๊ณตํ๋ ํฌ๋ ๋ง์ด ์ ํจ๊ธฐ๊ฐ์ด ์ง๋ ์ฌ์ฉ์ ๋ชปํ๊ฒ ๋์ด(์ ํจ๊ธฐ๊ฐ 3๊ฐ์ ๋๋ฌด ์งง๋ค) 5๋ฌ๋ฌ๋ฅผ ๊ฒฐ์ ํ์๋ค.
2. ํ๋ก์ ํธ ์์ฑ
์ด์ ์คํ๋ง ๋ถํธ ํ๋ก์ ํธ๋ฅผ ์์ฑํด ๋ณด์.
๊ฐ๋ตํ๊ฒ ์ฝ๋๋ฅผ ์ค๋ช
ํ๋ ค ํ๋ค. ์ฝ๋ ์ ์ฒด๋ ๊ธ ๋งจ ์๋ ๊นํ๋ธ ๋งํฌ์์ ํ์ธ ๊ฐ๋ฅํ๋ค.
์คํ๋ง ๋ถํธ 2.7.8, java 11์ ์ฌ์ฉํ๊ณ , Spring cloud์ OpenFeign์ ์ฌ์ฉํ์ฌ Whisper API ํธ์ถ์ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋๋ก ํ์๋ค.
์๋๋ build.gradle ์ฝ๋์ด๋ค.
// build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.8'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'com.eastshine'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '11'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2021.0.3")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
์ฐ์ application.yml์ ์๋์ ๊ฐ์ด OpenAI Config๋ฅผ ์์ฑํด์ผ ํ๋ค.
api-key์๋ ์์์ ๋ฐ๊ธ๋ฐ์ key๊ฐ์ ๋ฃ์ด์ฃผ๋๋ก ํ๋ค.
// application.yml
openai-service:
api-key: (OpenAI์์ ๋ฐ๊ธ๋ฐ์ Key ์์ฑ)
gpt-model: gpt-3.5-turbo
audio-model: whisper-1
http-client:
read-timeout: 3000
connect-timeout: 3000
urls:
base-url: https://api.openai.com/v1
chat-url: /chat/completions
create-transcription-url: /audio/transcriptions
API ํธ์ถ์ ํต์ฌ์ด ๋๋ ๊ณณ์ OpenFeign์ ํ์ฉํ์ฌ ์ธํฐํ์ด์ค๋ก ์์ฑํ๋ค.
// OpenAIClient.java
@FeignClient(
name = "openai-service",
url = "${openai-service.urls.base-url}",
configuration = OpenAIClientConfig.class
)
public interface OpenAIClient {
@PostMapping(value = "${openai-service.urls.create-transcription-url}", headers = {"Content-Type=multipart/form-data"})
WhisperTranscriptionResponse createTranscription(@ModelAttribute WhisperTranscriptionRequest whisperTranscriptionRequest);
}
Service ๋ ์ด์ด์์ API์ ํธ์ถํ์ฌ Audioํ์ผ์ ์์ฒญ ๋ณด๋ด๋ฉด Text๋ก ๋ฐํํด ์ฃผ๋๋ก ํ๋ค.
// OpenAIClientService.java
@RequiredArgsConstructor
@Service
public class OpenAIClientService {
private final OpenAIClient openAIClient;
private final OpenAIClientConfig openAIClientConfig;
public WhisperTranscriptionResponse createTranscription(TranscriptionRequest transcriptionRequest){
WhisperTranscriptionRequest whisperTranscriptionRequest = WhisperTranscriptionRequest.builder()
.model(openAIClientConfig.getAudioModel())
.file(transcriptionRequest.getFile())
.build();
return openAIClient.createTranscription(whisperTranscriptionRequest);
}
}
Controller ๋ ์ด์ด์์๋ REST API๋ก ๊ตฌํํ๋ค.
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/api")
public class WhisperController {
private final OpenAIClientService openAIClientService;
@PostMapping(value = "/transcription", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public WhisperTranscriptionResponse createTranscription(@ModelAttribute TranscriptionRequest transcriptionRequest){
return openAIClientService.createTranscription(transcriptionRequest);
}
}
3. ์์ฑ ์ํ
์, ์ด์ ๊ตฌํ์ ๋คํ๋ค๋ฉด ์ค์ ์๋ํ๋์ง ์์๋ณด์.
๋ด๊ฐ ์ง์ ๋
น์ํด์ ๋ฃ์ด๋ด๋ ๋์ง๋ง, ์ข ๋ ์ค์ ์ ๊ฐ๊น์ด ์์ฑ์ ์ฐพ๊ธฐ ์ํด ์ธํฐ๋ท์ ๊ฒ์ํ๋ ์ค, ai hub๋ผ๋ ๊ณณ์์ ์์ฃผ ๋ฐฉ๋ํ ์์ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๊ณ ์๋ค๋ ๊ฒ์ ์ฐพ์๋ค. ํ์ ๊ฐ์
์ ํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ฌด๋ฃ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. (๋ฌผ๋ก ์์
์ ์ธ ์ฉ๋ ์ด์ธ์๋ง)
https://www.aihub.or.kr/
๋๋ Whisper์ ์ฑ๋ฅ์ด ๊ถ๊ธํ๊ธฐ๋ ํด์ ๊นจ๋ํ ์์ง์ด ์๋ ์ ์์ง ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด๋ณด๊ณ ์ถ์๋ค. ๊ทธ๋์ ์๋ '์ ์์ง ์ ํ๋ง ์์ฑ์ธ์ ๋ฐ์ดํฐ'๋ฅผ ๋ค์ด๋ก๋ํ์๋ค. ์ด๊ฒ๋ง ์ฉ๋์ด ๋ฌด๋ ค 236GB๋ ๋ผ์ ๊ฐ๋น์ด ์๋๊ธฐ์ ์์ฃผ ์ผ๋ถ๋ง ๋ฐ์์ ์งํํ๋ค.
4. ํฌ์คํธ๋งจ(Postman)์ผ๋ก ์์ฑํ์ผ ์ ์ก
์ ai hub์์ ๋ฐ์ ์์ฑํ์ผ๋ค์ ์ค์ ์๋ด์ฌ์ ๊ณ ๊ฐ์ ๋ชฉ์๋ฆฌ๊ฐ ๋ด๊ฒจ์์๋ค.
๊ทธ์ค ํ๋๋ฅผ ์์๋ก ์ ํํ๊ณ , ๊ทธ ์์ฑํ์ผ์ ๋ด์ฉ์ ์ด๋ฌ๋ค.
''์ ๊ทธ๋ฌ๋ฉด ์ด ์ ํฌ๊ฐ ์ง๊ธ ์ปจ์คํ ์์ฝ ๊ฐ๋ฅํ ๋จ์ ์ค์ผ์ค์ด ์ด๋ฒ ์ฃผ ๊ธ์์ผ ๋๋ ๋ค์ ์ฃผ ์ค (๋ฒ๋ฒ ) ๋ค์ ์ฃผ์ค์ผ๋ก ์ค์ผ์ค์ด ๋จ์ ์์ผ์๊ฑฐ๋ ์. ํน์ ๊ด์ฐฎ์ผ์ ๋ ์ง๊ฐ ์์ผ์ค๊น์?"
์๋ด์ฌ๊ฐ ์์ฒ๋ผ ๋งํ ๋ด์ฉ์ด ๋ด๊ฒจ์์๋ค. ์ด์ ์ด ํ์ผ์ ํฌ์คํธ๋งจ์ผ๋ก ์ ์กํด ๋ณผ ์ฐจ๋ก๋ค.
์์ ๊ฐ์ด ์์ฑํ์ผ๊ณผ ๋ชจ๋ธ๋ช
์ ์์ฒญ์ผ๋ก ๋ณด๋ด์ฃผ์๋๋ text์ผ๋ก ์์ฑ ํ์ผ ๋ด์ฉ์ ์๋ตํด ์ฃผ์๋ค..! ์์ง์ด ์ ์ข์๋ฐ๋ ๋ถ๊ตฌํ๊ณ ๋๋ฆ ์ ๋ณํํ ๊ฒ ๊ฐ์๋ค. (์ปจ์คํ
์ ์ฝ์ํธ๋ผ๊ณ ์
๋ ฅ๋ ๊ฑฐ ๋นผ๊ณ ๋)
๋ง์น๋ฉฐ
STT ๊ธฐ์ ์ ์ง์ํ๋ API๋ Whisper ๋ง๊ณ ๋ ๋ง์ด ์กด์ฌํ์ง๋ง, ChatGPT์ ์์ฃผ ํ์ํํ ์ฑ๋ฅ์ ์ ์ฐ๊ณ ์๊ณ , ์ ์๊ธฐ ๋๋ฌธ์ Whisper์ ์ฑ๋ฅ๋ ๊ถ๊ธํ์๋ค. ๋ช ๋ฒ ๋๋ ค๋ณด์ง ๋ชปํ์ง๋ง ๋๋ฆ ํ๋ฅญํ๊ฒ ๋ณํํ๋ ๊ฒ์ ๋ณด๊ณ ๋์ด ๋ง์์ผ๋ฉด ์๊ฐ ์์ด ๊ณ์ ๋๋ ค๋ณด๋ฉด์ ํ๊ตญ์ด WER๋ ์ง์ ์ธก์ ํด๋ณด๊ณ ์ถ์ง๋ง ๊ทธ๊ฑด ๋ค์ ๊ธฐํ๋ก..
์ฐธ๊ณ
https://openai.com/research/whisper
https://betterprogramming.pub/integrating-chatgpt-and-whisper-apis-into-spring-boot-microservice-5545e2ea44fc
์ฝ๋ ์ ๋ฌธ Github ๋งํฌ
https://github.com/eastshine12/whisper-api
'๐ป ๊ฐ๋ฐ > ๐ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Security ๋ด๋ถ ํ๋ฆ ์ดํดํ๊ธฐ (0) | 2024.02.13 |
---|