GPT-4o(o"는 "omni"를 의미)는 텍스트, 오디오 및 비디오 입력을 조합하여 처리하도록 설계되었으며 텍스트, 오디오 및 이미지 형식의 출력을 생성할 수 있습니다.
Background
GPT-4o 이전에는 세 가지 개별 모델로 작동하는 음성 모드를 사용하여 ChatGPT와 상호작용할 수 있었습니다. GPT-4o는 이러한 기능을 텍스트, 시각, 오디오에 걸쳐 학습된 단일 모델로 통합합니다. 이러한 통합 접근 방식은 텍스트, 시각, 청각 등 모든 입력이 동일한 신경망에 의해 일관되게 처리되도록 보장합니다.
Current API Capabilities
현재 API는 {text, image} 입력만 지원하며 {text} 출력은 gpt-4-turbo와 동일한 모달리티입니다. 오디오를 포함한 추가 모달리티는 곧 도입될 예정입니다. 이 가이드는 텍스트, 이미지 및 동영상 이해를 위한 GPT-4o 사용을 시작하는 데 도움이 될 것입니다.
Setup Environments
%pip install --upgrade openai --quiet
import os
from dotenv import load_dotenv
!echo "OPENAI_API_KEY=<Your OpenAI_API_Key>" >> .env
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
Chat Completion
첫 번째 요청에 대해 모델에 간단한 {text} 입력으로 시작해 보겠습니다. 첫 번째 요청에는 system 메시지와 user 메시지를 모두 사용하며, assistant 역할로부터 응답을 받겠습니다.
from openai import OpenAI
MODEL="gpt-4o"
client = OpenAI()
completion = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": "너는 유용한 assistant 이다. 수학 숙제를 도와줘!"}, # <-- This is the system message that provides context to the model
{"role": "user", "content": "안녕! (2+2)*8을 풀어줄래?"} # <-- This is the user message for which the model will generate a response
]
)
print("Assistant: " + completion.choices[0].message.content)
Assistant: 물론이죠! 주어진 식 (2+2)*8을 풀어봅시다.
1. 먼저 괄호 안의 계산을 합니다: 2 + 2 = 4
2. 그 다음으로 4에 8을 곱합니다: 4 * 8 = 32
따라서 (2+2)*8의 값은 32입니다.
Image Processing
GPT-4o는 이미지를 직접 처리하고 이미지를 기반으로 지능적인 조치를 취할 수 있습니다. 두 가지 형식으로 이미지를 제공할 수 있습니다:
Base64 Encoded
URL
from IPython.display import Image, display, Audio, Markdown
import base64
# 피타고라스 문제 이미지를 웹에서 불러오기
!wget https://www.wikihow.com/images/thumb/a/a9/Use-the-Pythagorean-Theorem-Step-3-Version-3.jpg/v4-728px-Use-the-Pythagorean-Theorem-Step-3-Version-3.jpg -O ./images/triangle.png
IMAGE_PATH = "images/triangle.png"
# Preview image for context
display(Image(IMAGE_PATH))
Base64 Image Processing
# Open the image file and encode it as a base64 string
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode("utf-8")
base64_image = encode_image(IMAGE_PATH)
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": "너는 마크다운으로 답을하는 유용한 assistant 이다. 수학 숙제를 도와줘!"},
{"role": "user", "content": [
{"type": "text", "text": "b의 값을 구해주고 계산 방법을 설명해줘"},
{"type": "image_url", "image_url": {
"url": f"data:image/png;base64,{base64_image}"}
}
]}
],
temperature=0.0,
)
print(response.choices[0].message.content)
이 문제는 피타고라스의 정리를 사용하여 풀 수 있습니다. 피타고라스의 정리는 직각삼각형에서 빗변의 제곱이 다른 두 변의 제곱의 합과 같다는 것을 말합니다. 수식으로 표현하면 다음과 같습니다:
\[ c^2 = a^2 + b^2 \]
여기서 \( c \)는 빗변, \( a \)와 \( b \)는 직각을 이루는 두 변입니다. 주어진 값을 대입하면:
\[ 5^2 = 3^2 + b^2 \]
이를 계산하면:
\[ 25 = 9 + b^2 \]
다음으로, \( b^2 \)를 구하기 위해 양변에서 9를 뺍니다:
\[ 25 - 9 = b^2 \]
\[ 16 = b^2 \]
마지막으로, \( b \)를 구하기 위해 양변의 제곱근을 구합니다:
\[ b = \sqrt{16} \]
\[ b = 4 \]
따라서, \( b \)의 값은 4입니다.
주어진 삼각형은 직각삼각형입니다. 직각삼각형에서 피타고라스의 정리를 사용하여 \(b\)의 값을 구할 수 있습니다. 피타고라스의 정리는 다음과 같습니다:
\[ c^2 = a^2 + b^2 \]
여기서 \(a = 3\), \(c = 5\)입니다. \(b\)를 구하기 위해 식을 정리해보겠습니다.
\[ 5^2 = 3^2 + b^2 \]
\[ 25 = 9 + b^2 \]
\[ 25 - 9 = b^2 \]
\[ 16 = b^2 \]
\[ b = \sqrt{16} \]
\[ b = 4 \]
따라서 \(b\)의 값은 4입니다.
이제 삼각형의 넓이를 구해보겠습니다. 직각삼각형의 넓이는 다음과 같이 구할 수 있습니다:
\[ \text{넓이} = \frac{1}{2} \times \text{밑변} \times \text{높이} \]
여기서 밑변은 \(a = 3\), 높이는 \(b = 4\)입니다.
\[ \text{넓이} = \frac{1}{2} \times 3 \times 4 \]
\[ \text{넓이} = \frac{1}{2} \times 12 \]
\[ \text{넓이} = 6 \]
따라서 이 삼각형의 넓이는 6입니다.
Video Processing
API로 동영상을 직접 전송할 수는 없지만, 프레임을 샘플링한 다음 이미지로 제공하면 GPT-4o는 동영상을 이해할 수 있습니다. 이 작업은 GPT-4 터보보다 더 잘 수행됩니다.API의 GPT-4o는 아직 오디오 인을 지원하지 않으므로(2024년 5월 기준), 제공된 비디오의 오디오와 비주얼을 모두 처리하기 위해 GPT-4o와 Whisper를 함께 사용하여 두 가지 사용 사례를 보여드리겠습니다:
기본 동영상 처리를 위해 두 가지 파이썬 패키지인 opencv-python과 moviepy를 사용하겠습니다.
이를 위해서는 ffmpeg가 필요하므로 미리 설치하세요. MacOS의 경우 brew install ffmpeg, LinuxOS는 sudo apt install ffmpeg를 실행해야 할 수 있습니다.
Video Preprocess: Frames & Audio
Video 전처리는 두가지 Component 요소인 Frames(연속적인 이미지 프레임)과 Audio(음성)를 처리해야 합니다.
import cv2
from moviepy.editor import VideoFileClip
import time
import base64
# We'll be using the OpenAI DevDay Keynote Recap video. You can review the video here: https://www.youtube.com/watch?v=h02ti0Bl6zk
VIDEO_PATH = "data/OpenAI DevDay Keynote Recap.mp4"
def process_video(video_path, seconds_per_frame=2):
base64Frames = []
base_video_path, _ = os.path.splitext(video_path)
video = cv2.VideoCapture(video_path)
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
fps = video.get(cv2.CAP_PROP_FPS)
frames_to_skip = int(fps * seconds_per_frame)
curr_frame=0
# Loop through the video and extract frames at specified sampling rate
while curr_frame < total_frames - 1:
video.set(cv2.CAP_PROP_POS_FRAMES, curr_frame)
success, frame = video.read()
if not success:
break
_, buffer = cv2.imencode(".jpg", frame)
base64Frames.append(base64.b64encode(buffer).decode("utf-8"))
curr_frame += frames_to_skip
video.release()
# Extract audio from video
audio_path = f"{base_video_path}.mp3"
clip = VideoFileClip(video_path)
clip.audio.write_audiofile(audio_path, bitrate="32k")
clip.audio.close()
clip.close()
print(f"Extracted {len(base64Frames)} frames")
print(f"Extracted audio to {audio_path}")
return base64Frames, audio_path
# Extract 1 frame per second. You can adjust the `seconds_per_frame` parameter to change the sampling rate
base64Frames, audio_path = process_video(VIDEO_PATH, seconds_per_frame=1)
## Display the frames and audio for context
display_handle = display(None, display_id=True)
for img in base64Frames:
display_handle.update(Image(data=base64.b64decode(img.encode("utf-8")), width=600))
time.sleep(0.025)
Audio(audio_path)
예제1. Summarization
이제 비디오 프레임과 오디오를 모두 확보했으므로 몇 가지 다른 테스트를 실행하여 비디오 요약을 생성하여 다양한 양식으로 모델을 사용한 결과를 비교해 보겠습니다. 모델이 비디오의 전체 컨텍스트를 사용할 수 있으므로 시각 및 오디오 입력의 컨텍스트를 모두 사용하여 생성된 요약이 가장 정확할 것으로 예상할 수 있습니다.
Visual Summary
Audio Summary
Visual + Audio Summary
1. Visual Summary
Visual summary(시각적 요약)은 비디오의 프레임만 모델에 전송하여 생성됩니다. 프레임만 있으면 모델은 시각적인 측면을 포착할 수 있지만 화자가 설명한 세부 사항은 놓칠 수 있습니다.
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": "너는 동영상 요약을 생성합니다. 동영상의 요약을 한글로 번역해서 마크다운으로 대답해줘"},
{"role": "user", "content": [
"These are the frames from the video.",
*map(lambda x: {"type": "image_url",
"image_url": {"url": f'data:image/jpg;base64,{x}', "detail": "low"}}, base64Frames)
],
}
],
temperature=0,
)
print(response.choices[0].message.content)
이 비디오는 OpenAI DevDay의 주요 내용을 요약한 것입니다.
1. **시작**: "OpenAI DevDay"라는 텍스트로 시작합니다.
2. **키노트 요약**: "Keynote Recap"이라는 텍스트가 나타납니다.
3. **행사 장소**: OpenAI DevDay 행사 장소의 외부와 내부 모습이 보여집니다.
4. **발표 시작**: 발표자가 무대에 올라와 "OpenAI DevDay"라는 배경 앞에서 발표를 시작합니다.
5. **GPT-4 Turbo**: 발표자는 GPT-4 Turbo에 대해 설명합니다.
6. **JSON 모드**: JSON 모드의 활성화와 기능 호출의 변화에 대해 설명합니다.
7. **기능 설명**: 다양한 기능(예: 스레딩, 검색, 코드 인터프리터, 함수 호출 등)에 대해 설명합니다.
8. **DALL-E 3**: DALL-E 3와 관련된 내용이 소개됩니다.
9. **커스텀 모델**: 커스텀 모델에 대한 설명이 이어집니다.
10. **API**: API와 관련된 내용이 소개됩니다.
11. **마무리**: 발표자는 "Build with natural language"라는 메시지로 마무리합니다.
이 비디오는 OpenAI DevDay에서 발표된 주요 기능과 업데이트를 요약하여 보여줍니다.
2. Audio Summary
Audio summary(음성 요약)은 모델에 오디오 대본을 전송하여 생성됩니다. 오디오만 있으면 모델은 오디오 콘텐츠에 편향되어 프레젠테이션과 시각 자료가 제공하는 맥락을 놓칠 가능성이 높습니다.
GPT-4o에 대한 {audio} 입력은 현재 제공되지 않아 기존의 whisper-1 모델을 사용하여 오디오를 처리했습니다.
# Transcribe the audio
transcription = client.audio.transcriptions.create(
model="whisper-1",
file=open(audio_path, "rb"),
)
## OPTIONAL: Uncomment the line below to print the transcription
#print("Transcript: ", transcription.text + "\n\n")
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content":"""너는 자막의 요약본을 생성합니다. 제공된 자막의 요약을 한글로 작성하고 마크다운으로 응답해줘."""},
{"role": "user", "content": [
{"type": "text", "text": f"The audio transcription is: {transcription.text}"}
],
}
],
temperature=0,
)
print(response.choices[0].message.content)
# 요약
첫 번째 OpenAI Dev Day에서 GPT-4 Turbo 모델을 출시했습니다. 이 모델은 최대 128,000 토큰의 컨텍스트를 지원하며, JSON 모드와 여러 함수 호출 기능을 제공합니다. 또한, 외부 문서나 데이터베이스에서 지식을 가져올 수 있는 검색 기능도 도입되었습니다. GPT-4 Turbo는 2023년 4월까지의 세계 지식을 포함하고 있으며, Dolly 3, GPT-4 Turbo with Vision, 새로운 Text-to-Speech 모델도 API에 추가되었습니다.
새로운 프로그램인 Custom Models를 통해 기업 맞춤형 모델을 제작할 수 있으며, 토큰 사용량 한도도 두 배로 늘렸습니다. GPT-4 Turbo는 GPT-4보다 비용이 3배 저렴합니다. GPTs는 특정 목적에 맞춘 Chat GPT의 버전으로, 코딩 없이 대화로 프로그래밍할 수 있습니다. GPT Store도 곧 출시될 예정입니다.
Assistance API는 지속적인 대화 스레드, 내장 검색, 코드 인터프리터 등을 포함합니다. 이 기술을 통해 더 나은 미래를 함께 만들어 나가기를 기대합니다.
3. Audio + Visual Summary
오디오+비주얼 요약(Audio + Visual summary)은 비디오의 비주얼과 오디오를 한 번에 모델에 전송하여 생성됩니다. 이 두 가지를 모두 전송하면 모델이 전체 동영상을 한 번에 인식할 수 있으므로 요약이 더 잘 될 것으로 예상됩니다.
## Generate a summary with visual and audio
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content":"""너는 동영상 요약을 생성합니다. 제공된 동영상의 요약과 대본을 한글로 번역하고 마크다운으로 응답해줘."""},
{"role": "user", "content": [
"These are the frames from the video.",
*map(lambda x: {"type": "image_url",
"image_url": {"url": f'data:image/jpg;base64,{x}', "detail": "low"}}, base64Frames),
{"type": "text", "text": f"The audio transcription is: {transcription.text}"}
],
}
],
temperature=0,
)
print(response.choices[0].message.content)
### 요약
OpenAI Dev Day에서 새로운 모델인 GPT-4 Turbo가 발표되었습니다. 이 모델은 최대 128,000 토큰의 컨텍스트를 지원하며, JSON 모드와 여러 함수 호출 기능을 포함하고 있습니다. 또한, 외부 문서나 데이터베이스에서 지식을 가져올 수 있는 검색 기능이 추가되었습니다. GPT-4 Turbo는 2023년 4월까지의 세계 지식을 가지고 있으며, Dolly 3, GPT-4 Turbo with Vision, 새로운 텍스트-음성 변환 모델이 API에 추가되었습니다. 새로운 프로그램인 Custom Models도 발표되었으며, 연구자들이 특정 용도에 맞는 맞춤형 모델을 개발하는 데 도움을 줄 것입니다. GPT-4 Turbo는 기존 GPT-4보다 3배 저렴하며, 토큰 처리 속도도 두 배로 증가했습니다. GPTs라는 새로운 기능도 소개되었으며, 이는 특정 목적에 맞춘 ChatGPT의 맞춤형 버전입니다. GPTs는 코딩 없이 대화만으로도 프로그래밍할 수 있으며, 개인용 또는 공개용으로 공유할 수 있습니다. Assistance API도 발표되었으며, 이는 지속적인 스레드, 검색 기능, 코드 인터프리터 등을 포함합니다. OpenAI는 이 기술을 통해 새로운 미래를 함께 만들어 나가기를 기대하고 있습니다.
### 대본 번역
```markdown
환영합니다. OpenAI Dev Day에 오신 것을 환영합니다. 오늘 우리는 새로운 모델인 GPT-4 Turbo를 출시합니다. GPT-4 Turbo는 최대 128,000 토큰의 컨텍스트를 지원합니다. 우리는 JSON 모드라는 새로운 기능을 도입했으며, 이는 모델이 유효한 JSON으로 응답하도록 보장합니다. 이제 여러 함수를 한 번에 호출할 수 있으며, 일반적으로 지침을 더 잘 따를 것입니다. 우리는 이 모델들이 더 나은 세계 지식을 얻을 수 있기를 원합니다. 그래서 우리는 플랫폼에서 검색 기능을 출시합니다. 외부 문서나 데이터베이스에서 지식을 가져와서 여러분이 구축하는 것에 통합할 수 있습니다. GPT-4 Turbo는 2023년 4월까지의 세계 지식을 가지고 있으며, 우리는 시간이 지남에 따라 이를 계속 개선할 것입니다. Dolly 3, GPT-4 Turbo with Vision, 새로운 텍스트-음성 변환 모델이 오늘 API에 추가됩니다. 오늘 우리는 Custom Models라는 새로운 프로그램을 출시합니다. Custom Models를 통해 연구자들이 특정 용도에 맞는 맞춤형 모델을 개발하는 데 도움을 줄 것입니다. 우리는 모든 기존 GPT-4 고객에게 분당 토큰 수를 두 배로 늘려 더 많은 작업을 쉽게 할 수 있도록 하고, API 계정 설정에서 직접 한도 및 할당량 변경을 요청할 수 있습니다. GPT-4 Turbo는 GPT-4보다 상당히 저렴하며, 프롬프트 토큰은 3배, 완료 토큰은 2배 저렴합니다. 우리는 GPTs를 소개하게 되어 기쁩니다. GPTs는 특정 목적에 맞춘 ChatGPT의 맞춤형 버전입니다. 이들은 지침, 확장된 지식, 행동을 결합하여 더 유용할 수 있습니다. 우리는 많은 사람들이 GPT를 구축하고 싶어하지만 코딩을 모른다는 것을 알고 있습니다. 우리는 대화만으로도 GPT를 프로그래밍할 수 있도록 만들었습니다. 개인용 GPT를 만들 수 있으며, 링크를 통해 누구나 사용할 수 있도록 공개할 수 있습니다. 또는 ChatGPT Enterprise를 사용 중이라면 회사 전용 GPT를 만들 수 있습니다. 이달 말에 GPT Store를 출시할 예정입니다. 이것이 여러분의 GPT이며, 여러분이 무엇을 만들지 기대됩니다. 우리는 같은 개념을 API로 가져오고 있습니다. Assistance API는 지속적인 스레드를 포함하여 긴 대화 기록을 처리할 필요가 없으며, 내장된 검색 기능, 코드 인터프리터, 샌드박스 환경에서 작동하는 Python 인터프리터, 개선된 함수 호출을 포함합니다. 지능이 모든 곳에 통합되면서 우리는 모두 필요할 때마다 초능력을 가지게 될 것입니다. 이 기술로 여러분이 무엇을 할지 기대되며, 우리가 함께 만들어갈 새로운 미래를 발견하기를 기대합니다. 내년에 다시 오시길 바랍니다. 오늘 출시한 것이 우리가 지금 여러분을 위해 만들고 있는 것에 비해 매우 소박해 보일 것입니다. 여러분이 하는 모든 일에 감사드립니다. 오늘 여기 와주셔서 감사합니다.
```
예제 2: Question & Answering
Q&A에서는 이전과 동일한 개념을 사용하여 처리된 동영상에 대해 질문하면서 입력 양식 결합의 이점을 보여주기 위해 동일한 3가지 테스트를 실행합니다:
Visual Q&A
Audio Q&A
Visual + Audio Q&A
QUESTION = "Question: 샘 알트먼은 왜 창문을 올리고 라디오를 켜는 것에 대한 예를 들었어?"
1. Visual Q&A
qa_visual_response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": "동영상을 사용하여 제공된 질문의 답을 한글로 번역하고 마크다운으로 응답하세요."},
{"role": "user", "content": [
"These are the frames from the video.",
*map(lambda x: {"type": "image_url", "image_url": {"url": f'data:image/jpg;base64,{x}', "detail": "low"}}, base64Frames),
QUESTION
],
}
],
temperature=0,
)
print("Visual QA:\n" + qa_visual_response.choices[0].message.content)
Visual QA:
샘 알트먼은 창문을 올리고 라디오를 켜는 예를 들어서, GPT-4 Turbo의 기능 호출 기능을 설명하기 위해 사용했습니다. 이 예시는 자연어 명령을 보다 구체적인 함수 호출로 변환하는 과정을 보여주며, 새로운 기능이 어떻게 더 나은 제어와 정확성을 제공하는지를 강조합니다.
Audio QA:
샘 알트먼은 창문을 올리고 라디오를 켜는 것에 대한 예를 들지 않았습니다.
3. Visual + Audio Q&A
qa_both_response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content":"""동영상과 녹취록을 사용하여 제공된 질문을 한글로 답해줘."""},
{"role": "user", "content": [
"These are the frames from the video.",
*map(lambda x: {"type": "image_url",
"image_url": {"url": f'data:image/jpg;base64,{x}', "detail": "low"}}, base64Frames),
{"type": "text", "text": f"The audio transcription is: {transcription.text}"},
QUESTION
],
}
],
temperature=0,
)
print("Both QA:\n" + qa_both_response.choices[0].message.content)
Both QA:
샘 알트먼은 창문을 올리고 라디오를 켜는 예를 들어, 새로운 기능 호출 기능을 설명하기 위해 사용했습니다. 이 기능은 여러 함수를 한 번에 호출할 수 있게 하며, 모델이 지시 사항을 더 잘 따를 수 있도록 개선되었습니다. 예를 들어, "창문을 올리고 라디오를 켜줘"라는 명령을 주면, 이전에는 두 개의 별도 함수 호출로 처리되었지만, 이제는 한 번에 처리할 수 있게 되었습니다.